20#include <boost/test/unit_test.hpp>
31nlohmann::json providerMetadataJson(
const wxString& aAuthType = wxS(
"oauth2" ) )
33 nlohmann::json auth = { {
"type", aAuthType.ToStdString() } };
35 if( aAuthType == wxS(
"oauth2" ) )
37 auth[
"metadata_url"] =
"https://provider.example.test/.well-known/oauth-authorization-server";
38 auth[
"client_id"] =
"kicad-desktop";
39 auth[
"scopes"] = nlohmann::json::array( {
"openid",
"parts.read" } );
42 return nlohmann::json{
43 {
"provider_name",
"Acme Parts" },
44 {
"provider_version",
"1.0.0" },
45 {
"api_base_url",
"https://provider.example.test/api" },
46 {
"panel_url",
"https://provider.example.test/app" },
47 {
"session_bootstrap_url",
"https://provider.example.test/session/bootstrap" },
50 { {
"web_ui_v1",
true },
52 {
"direct_downloads_v1",
true },
53 {
"inline_payloads_v1",
true } } },
54 {
"max_download_bytes", 10485760 },
55 {
"supported_asset_types", nlohmann::json::array( {
"symbol",
"footprint",
"3dmodel" } ) },
56 {
"parts", { {
"endpoint_template",
"/v1/parts/{part_id}" } } }
64 std::optional<REMOTE_PROVIDER_METADATA> metadata =
67 if( !metadata.has_value() )
68 throw std::runtime_error( error.ToStdString() );
74nlohmann::json authServerMetadataJson()
76 return nlohmann::json{ {
"issuer",
"https://provider.example.test" },
77 {
"authorization_endpoint",
"https://provider.example.test/oauth/authorize" },
78 {
"token_endpoint",
"https://provider.example.test/oauth/token" },
79 {
"revocation_endpoint",
"https://provider.example.test/oauth/revoke" } };
82nlohmann::json manifestJson()
84 return nlohmann::json{
85 {
"part_id",
"acme-res-10k" },
86 {
"display_name",
"10k Resistor" },
87 {
"summary",
"10k 0603 thick film resistor" },
88 {
"license",
"CC-BY-4.0" },
89 {
"assets", nlohmann::json::array(
90 { { {
"asset_type",
"symbol" },
91 {
"name",
"acme-res-10k.kicad_sym" },
92 {
"content_type",
"application/x-kicad-symbol" },
93 {
"size_bytes", 2048 },
94 {
"sha256",
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" },
95 {
"download_url",
"https://provider.example.test/downloads/acme-res-10k.kicad_sym" },
96 {
"required",
true } },
97 { {
"asset_type",
"footprint" },
98 {
"name",
"R_0603.pretty" },
99 {
"content_type",
"application/x-kicad-footprint" },
100 {
"size_bytes", 4096 },
101 {
"sha256",
"abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789" },
102 {
"download_url",
"https://provider.example.test/downloads/R_0603.pretty" },
103 {
"required",
false } } } ) }
108wxString dumpJson(
const nlohmann::json& aJson )
110 return wxString::FromUTF8( aJson.dump().c_str() );
119 std::vector<wxString> requestedUrls;
125 wxUnusedVar( aError );
126 requestedUrls.push_back( aRequest.
url );
128 aResponse.
body = dumpJson( providerMetadataJson() );
135 BOOST_REQUIRE( client.DiscoverProvider( wxString(
"https://provider.example.test" ), metadata, error ) );
138 wxString(
"https://provider.example.test/.well-known/kicad-remote-provider" ) );
150 wxUnusedVar( aError );
152 wxString(
"https://provider.example.test/.well-known/oauth-authorization-server" ) );
154 aResponse.
body = dumpJson( authServerMetadataJson() );
161 BOOST_REQUIRE( client.FetchOAuthServerMetadata( metadata, authMetadata, error ) );
163 wxString(
"https://provider.example.test/oauth/authorize" ) );
164 BOOST_CHECK_EQUAL( authMetadata.token_endpoint, wxString(
"https://provider.example.test/oauth/token" ) );
175 wxUnusedVar( aError );
178 wxString(
"https://provider.example.test/api/v1/parts/acme-res-10k" ) );
180 aResponse.
body = dumpJson( manifestJson() );
187 BOOST_REQUIRE( client.FetchManifest( metadata, wxString(
"acme-res-10k" ), wxString(), manifest, error ) );
189 BOOST_REQUIRE_EQUAL( manifest.assets.size(), 2U );
192 wxString(
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" ) );
193 BOOST_CHECK( manifest.assets.front().required );
201 oauth.
token_endpoint = wxString(
"https://provider.example.test/oauth/token" );
207 wxUnusedVar( aError );
210 BOOST_CHECK( aRequest.
body.Contains( wxString(
"grant_type=authorization_code" ) ) );
211 BOOST_CHECK( aRequest.
body.Contains( wxString(
"code=test-code" ) ) );
213 aResponse.
body = dumpJson( {
214 {
"access_token",
"access-123" },
215 {
"refresh_token",
"refresh-123" },
216 {
"token_type",
"Bearer" },
217 {
"scope",
"openid parts.read" },
218 {
"expires_in", 3600 }
225 session.redirect_uri = wxString(
"http://127.0.0.1:9000/oauth/callback" );
226 session.code_verifier = wxString(
"verifier" );
230 BOOST_REQUIRE( client.ExchangeAuthorizationCode( oauth, session, wxString(
"test-code" ), tokens, error ) );
239 oauth.
token_endpoint = wxString(
"https://provider.example.test/oauth/token" );
245 wxUnusedVar( aError );
246 BOOST_CHECK( aRequest.
body.Contains( wxString(
"grant_type=refresh_token" ) ) );
247 BOOST_CHECK( aRequest.
body.Contains( wxString(
"refresh_token=refresh-123" ) ) );
249 aResponse.
body = dumpJson( {
250 {
"access_token",
"access-456" },
251 {
"refresh_token",
"refresh-456" },
252 {
"token_type",
"Bearer" },
253 {
"scope",
"openid parts.read" },
254 {
"expires_in", 3600 }
261 BOOST_REQUIRE( client.RefreshAccessToken( oauth, wxString(
"kicad-desktop" ),
262 wxString(
"refresh-123" ), tokens, error ) );
276 wxUnusedVar( aError );
277 BOOST_CHECK( aRequest.
body.Contains( wxString(
"token=access-123" ) ) );
279 aResponse.
body = wxString(
"{}" );
284 BOOST_CHECK( client.RevokeToken( oauth, wxString(
"kicad-desktop" ), wxString(
"access-123" ), error ) );
REMOTE_PROVIDER_HTTP_METHOD method
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(DiscoveryFetchesWellKnownMetadata)
BOOST_CHECK_EQUAL(result, "25.4")