Mercurial > hg > orthanc
diff UnitTestsSources/RestApiTests.cpp @ 2884:497a637366b4 db-changes
integration mainline->db-changes
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 12 Oct 2018 15:18:10 +0200 |
parents | 0e1b79bc4a2d |
children | 22524fd06225 |
line wrap: on
line diff
--- a/UnitTestsSources/RestApiTests.cpp Thu Oct 29 11:25:45 2015 +0100 +++ b/UnitTestsSources/RestApiTests.cpp Fri Oct 12 15:18:10 2018 +0200 @@ -1,7 +1,8 @@ /** * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2018 Osimis S.A., Belgium * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -34,15 +35,18 @@ #include "gtest/gtest.h" #include <ctype.h> +#include <boost/lexical_cast.hpp> +#include <algorithm> #include "../Core/ChunkedBuffer.h" #include "../Core/HttpClient.h" #include "../Core/Logging.h" +#include "../Core/SystemToolbox.h" #include "../Core/RestApi/RestApi.h" -#include "../Core/Uuid.h" #include "../Core/OrthancException.h" #include "../Core/Compression/ZlibCompressor.h" #include "../Core/RestApi/RestApiHierarchy.h" +#include "../Core/HttpServer/HttpContentNegociation.h" using namespace Orthanc; @@ -62,15 +66,22 @@ ASSERT_FALSE(c.IsVerbose()); #if UNIT_TESTS_WITH_HTTP_CONNEXIONS == 1 + // The "http://www.orthanc-server.com/downloads/third-party/" does + // not automatically redirect to HTTPS, so we cas use it even if the + // OpenSSL/HTTPS support is disabled in curl + const std::string BASE = "http://www.orthanc-server.com/downloads/third-party/"; + Json::Value v; - c.SetUrl("http://www.montefiore.ulg.ac.be/~jodogne/Orthanc/Configuration.json"); + c.SetUrl(BASE + "Product.json"); + c.Apply(v); - ASSERT_TRUE(v.isMember("StorageDirectory")); + ASSERT_TRUE(v.type() == Json::objectValue); + ASSERT_TRUE(v.isMember("Description")); #endif } -#if UNIT_TESTS_WITH_HTTP_CONNEXIONS == 1 && ORTHANC_SSL_ENABLED == 1 +#if UNIT_TESTS_WITH_HTTP_CONNEXIONS == 1 && ORTHANC_ENABLE_SSL == 1 /** The HTTPS CA certificates for BitBucket were extracted as follows: @@ -97,12 +108,12 @@ TEST(HttpClient, Ssl) { - Toolbox::WriteFile(BITBUCKET_CERTIFICATES, "UnitTestsResults/bitbucket.cert"); + SystemToolbox::WriteFile(BITBUCKET_CERTIFICATES, "UnitTestsResults/bitbucket.cert"); /*{ std::string s; - Toolbox::ReadFile(s, "/usr/share/ca-certificates/mozilla/WoSign.crt"); - Toolbox::WriteFile(s, "UnitTestsResults/bitbucket.cert"); + SystemToolbox::ReadFile(s, "/usr/share/ca-certificates/mozilla/WoSign.crt"); + SystemToolbox::WriteFile(s, "UnitTestsResults/bitbucket.cert"); }*/ HttpClient c; @@ -277,7 +288,7 @@ const IHttpHandler::Arguments& components, const UriComponents& trailing) { - return resource.Handle(*reinterpret_cast<RestApiGetCall*>(NULL)); + return resource.Handle(*(RestApiGetCall*) NULL); } }; } @@ -335,3 +346,300 @@ ASSERT_TRUE(HandleGet(root, "/hello2/a/b")); ASSERT_EQ(testValue, 4); } + + + + + +namespace +{ + class AcceptHandler : public Orthanc::HttpContentNegociation::IHandler + { + private: + std::string type_; + std::string subtype_; + + public: + AcceptHandler() + { + Reset(); + } + + void Reset() + { + Handle("nope", "nope"); + } + + const std::string& GetType() const + { + return type_; + } + + const std::string& GetSubType() const + { + return subtype_; + } + + virtual void Handle(const std::string& type, + const std::string& subtype) + { + type_ = type; + subtype_ = subtype; + } + }; +} + + +TEST(RestApi, HttpContentNegociation) +{ + // Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1 + + AcceptHandler h; + + { + Orthanc::HttpContentNegociation d; + d.Register("audio/mp3", h); + d.Register("audio/basic", h); + + ASSERT_TRUE(d.Apply("audio/*; q=0.2, audio/basic")); + ASSERT_EQ("audio", h.GetType()); + ASSERT_EQ("basic", h.GetSubType()); + + ASSERT_TRUE(d.Apply("audio/*; q=0.2, audio/nope")); + ASSERT_EQ("audio", h.GetType()); + ASSERT_EQ("mp3", h.GetSubType()); + + ASSERT_FALSE(d.Apply("application/*; q=0.2, application/pdf")); + + ASSERT_TRUE(d.Apply("*/*; application/*; q=0.2, application/pdf")); + ASSERT_EQ("audio", h.GetType()); + } + + // "This would be interpreted as "text/html and text/x-c are the + // preferred media types, but if they do not exist, then send the + // text/x-dvi entity, and if that does not exist, send the + // text/plain entity."" + const std::string T1 = "text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c"; + + { + Orthanc::HttpContentNegociation d; + d.Register("text/plain", h); + d.Register("text/html", h); + d.Register("text/x-dvi", h); + ASSERT_TRUE(d.Apply(T1)); + ASSERT_EQ("text", h.GetType()); + ASSERT_EQ("html", h.GetSubType()); + } + + { + Orthanc::HttpContentNegociation d; + d.Register("text/plain", h); + d.Register("text/x-dvi", h); + d.Register("text/x-c", h); + ASSERT_TRUE(d.Apply(T1)); + ASSERT_EQ("text", h.GetType()); + ASSERT_EQ("x-c", h.GetSubType()); + } + + { + Orthanc::HttpContentNegociation d; + d.Register("text/plain", h); + d.Register("text/x-dvi", h); + d.Register("text/x-c", h); + d.Register("text/html", h); + ASSERT_TRUE(d.Apply(T1)); + ASSERT_EQ("text", h.GetType()); + ASSERT_TRUE(h.GetSubType() == "x-c" || h.GetSubType() == "html"); + } + + { + Orthanc::HttpContentNegociation d; + d.Register("text/plain", h); + d.Register("text/x-dvi", h); + ASSERT_TRUE(d.Apply(T1)); + ASSERT_EQ("text", h.GetType()); + ASSERT_EQ("x-dvi", h.GetSubType()); + } + + { + Orthanc::HttpContentNegociation d; + d.Register("text/plain", h); + ASSERT_TRUE(d.Apply(T1)); + ASSERT_EQ("text", h.GetType()); + ASSERT_EQ("plain", h.GetSubType()); + } +} + + +TEST(WebServiceParameters, Serialization) +{ + { + Json::Value v = Json::arrayValue; + v.append("http://localhost:8042/"); + + WebServiceParameters p(v); + ASSERT_FALSE(p.IsAdvancedFormatNeeded()); + + Json::Value v2; + p.Serialize(v2, false, true); + ASSERT_EQ(v, v2); + + WebServiceParameters p2(v2); + ASSERT_EQ("http://localhost:8042/", p2.GetUrl()); + ASSERT_TRUE(p2.GetUsername().empty()); + ASSERT_TRUE(p2.GetPassword().empty()); + ASSERT_TRUE(p2.GetCertificateFile().empty()); + ASSERT_TRUE(p2.GetCertificateKeyFile().empty()); + ASSERT_TRUE(p2.GetCertificateKeyPassword().empty()); + ASSERT_FALSE(p2.IsPkcs11Enabled()); + } + + { + Json::Value v = Json::arrayValue; + v.append("http://localhost:8042/"); + v.append("user"); + v.append("pass"); + + WebServiceParameters p(v); + ASSERT_FALSE(p.IsAdvancedFormatNeeded()); + ASSERT_EQ("http://localhost:8042/", p.GetUrl()); + ASSERT_EQ("user", p.GetUsername()); + ASSERT_EQ("pass", p.GetPassword()); + ASSERT_TRUE(p.GetCertificateFile().empty()); + ASSERT_TRUE(p.GetCertificateKeyFile().empty()); + ASSERT_TRUE(p.GetCertificateKeyPassword().empty()); + ASSERT_FALSE(p.IsPkcs11Enabled()); + + Json::Value v2; + p.Serialize(v2, false, true); + ASSERT_EQ(v, v2); + + p.Serialize(v2, false, false /* no password */); + WebServiceParameters p2(v2); + ASSERT_EQ(Json::arrayValue, v2.type()); + ASSERT_EQ(3u, v2.size()); + ASSERT_EQ("http://localhost:8042/", v2[0u].asString()); + ASSERT_EQ("user", v2[1u].asString()); + ASSERT_TRUE(v2[2u].asString().empty()); + } + + { + Json::Value v = Json::arrayValue; + v.append("http://localhost:8042/"); + + WebServiceParameters p(v); + ASSERT_FALSE(p.IsAdvancedFormatNeeded()); + p.SetPkcs11Enabled(true); + ASSERT_TRUE(p.IsAdvancedFormatNeeded()); + + Json::Value v2; + p.Serialize(v2, false, true); + WebServiceParameters p2(v2); + + ASSERT_EQ(Json::objectValue, v2.type()); + ASSERT_EQ(3u, v2.size()); + ASSERT_EQ("http://localhost:8042/", v2["Url"].asString()); + ASSERT_TRUE(v2["Pkcs11"].asBool()); + ASSERT_EQ(Json::objectValue, v2["HttpHeaders"].type()); + ASSERT_EQ(0u, v2["HttpHeaders"].size()); + } + + { + Json::Value v = Json::arrayValue; + v.append("http://localhost:8042/"); + + WebServiceParameters p(v); + ASSERT_FALSE(p.IsAdvancedFormatNeeded()); + p.SetClientCertificate("a", "b", "c"); + ASSERT_TRUE(p.IsAdvancedFormatNeeded()); + + Json::Value v2; + p.Serialize(v2, false, true); + WebServiceParameters p2(v2); + + ASSERT_EQ(Json::objectValue, v2.type()); + ASSERT_EQ(6u, v2.size()); + ASSERT_EQ("http://localhost:8042/", v2["Url"].asString()); + ASSERT_EQ("a", v2["CertificateFile"].asString()); + ASSERT_EQ("b", v2["CertificateKeyFile"].asString()); + ASSERT_EQ("c", v2["CertificateKeyPassword"].asString()); + ASSERT_FALSE(v2["Pkcs11"].asBool()); + ASSERT_EQ(Json::objectValue, v2["HttpHeaders"].type()); + ASSERT_EQ(0u, v2["HttpHeaders"].size()); + } + + { + Json::Value v = Json::arrayValue; + v.append("http://localhost:8042/"); + + WebServiceParameters p(v); + ASSERT_FALSE(p.IsAdvancedFormatNeeded()); + p.AddHttpHeader("a", "b"); + p.AddHttpHeader("c", "d"); + ASSERT_TRUE(p.IsAdvancedFormatNeeded()); + + Json::Value v2; + p.Serialize(v2, false, true); + WebServiceParameters p2(v2); + + ASSERT_EQ(Json::objectValue, v2.type()); + ASSERT_EQ(3u, v2.size()); + ASSERT_EQ("http://localhost:8042/", v2["Url"].asString()); + ASSERT_FALSE(v2["Pkcs11"].asBool()); + ASSERT_EQ(Json::objectValue, v2["HttpHeaders"].type()); + ASSERT_EQ(2u, v2["HttpHeaders"].size()); + ASSERT_EQ("b", v2["HttpHeaders"]["a"].asString()); + ASSERT_EQ("d", v2["HttpHeaders"]["c"].asString()); + + std::set<std::string> a; + p2.ListHttpHeaders(a); + ASSERT_EQ(2u, a.size()); + ASSERT_TRUE(a.find("a") != a.end()); + ASSERT_TRUE(a.find("c") != a.end()); + + std::string s; + ASSERT_TRUE(p2.LookupHttpHeader(s, "a")); ASSERT_EQ("b", s); + ASSERT_TRUE(p2.LookupHttpHeader(s, "c")); ASSERT_EQ("d", s); + ASSERT_FALSE(p2.LookupHttpHeader(s, "nope")); + } +} + + +TEST(WebServiceParameters, UserProperties) +{ + Json::Value v = Json::nullValue; + + { + WebServiceParameters p; + p.SetUrl("http://localhost:8042/"); + ASSERT_FALSE(p.IsAdvancedFormatNeeded()); + + ASSERT_THROW(p.AddUserProperty("Url", "nope"), OrthancException); + p.AddUserProperty("Hello", "world"); + p.AddUserProperty("a", "b"); + ASSERT_TRUE(p.IsAdvancedFormatNeeded()); + + p.Serialize(v, false, true); + + p.ClearUserProperties(); + ASSERT_FALSE(p.IsAdvancedFormatNeeded()); + } + + { + WebServiceParameters p(v); + ASSERT_TRUE(p.IsAdvancedFormatNeeded()); + ASSERT_TRUE(p.GetHttpHeaders().empty()); + + std::set<std::string> tmp; + p.ListUserProperties(tmp); + ASSERT_EQ(2u, tmp.size()); + ASSERT_TRUE(tmp.find("a") != tmp.end()); + ASSERT_TRUE(tmp.find("Hello") != tmp.end()); + ASSERT_TRUE(tmp.find("hello") == tmp.end()); + + std::string s; + ASSERT_TRUE(p.LookupUserProperty(s, "a")); ASSERT_TRUE(s == "b"); + ASSERT_TRUE(p.LookupUserProperty(s, "Hello")); ASSERT_TRUE(s == "world"); + ASSERT_FALSE(p.LookupUserProperty(s, "hello")); + } +}