diff --git a/.github/workflows/publish-nuget.yml b/.github/workflows/publish-nuget.yml index fac826d..8e61048 100644 --- a/.github/workflows/publish-nuget.yml +++ b/.github/workflows/publish-nuget.yml @@ -8,6 +8,6 @@ on: jobs: publish-nuget: name: Publish to NuGet - uses: Lombiq/GitHub-Actions/.github/workflows/publish-nuget.yml@dev + uses: Lombiq/GitHub-Actions/.github/workflows/publish-nuget.yml@issue/OSOE-925 secrets: API_KEY: ${{ secrets.DEFAULT_NUGET_PUBLISH_API_KEY }} diff --git a/.github/workflows/validate-nuget-publish.yml b/.github/workflows/validate-nuget-publish.yml index 9f8979c..f0fd6be 100644 --- a/.github/workflows/validate-nuget-publish.yml +++ b/.github/workflows/validate-nuget-publish.yml @@ -9,4 +9,4 @@ on: jobs: validate-nuget-publish: name: Validate NuGet Publish - uses: Lombiq/GitHub-Actions/.github/workflows/validate-nuget-publish.yml@dev + uses: Lombiq/GitHub-Actions/.github/workflows/validate-nuget-publish.yml@issue/OSOE-925 diff --git a/Lombiq.OrchardCoreApiClient.Tester/Lombiq.OrchardCoreApiClient.Tester.csproj b/Lombiq.OrchardCoreApiClient.Tester/Lombiq.OrchardCoreApiClient.Tester.csproj index c169f60..2778aac 100644 --- a/Lombiq.OrchardCoreApiClient.Tester/Lombiq.OrchardCoreApiClient.Tester.csproj +++ b/Lombiq.OrchardCoreApiClient.Tester/Lombiq.OrchardCoreApiClient.Tester.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net10.0 diff --git a/Lombiq.OrchardCoreApiClient.Tester/Recipes/Lombiq.OrchardCoreApiClient.Tester.OpenId.recipe.json b/Lombiq.OrchardCoreApiClient.Tester/Recipes/Lombiq.OrchardCoreApiClient.Tester.OpenId.recipe.json index 5cd13d4..468804c 100644 --- a/Lombiq.OrchardCoreApiClient.Tester/Recipes/Lombiq.OrchardCoreApiClient.Tester.OpenId.recipe.json +++ b/Lombiq.OrchardCoreApiClient.Tester/Recipes/Lombiq.OrchardCoreApiClient.Tester.OpenId.recipe.json @@ -18,8 +18,7 @@ "OrchardCore.OpenId.Management", "OrchardCore.OpenId.Server", "OrchardCore.OpenId.Validation", - "OrchardCore.Taxonomies", - "OrchardCore.Tenants" + "OrchardCore.Taxonomies" ] }, { diff --git a/Lombiq.OrchardCoreApiClient.Tests.UI/CompatibilitySuppressions.xml b/Lombiq.OrchardCoreApiClient.Tests.UI/CompatibilitySuppressions.xml index bade594..8af156c 100644 --- a/Lombiq.OrchardCoreApiClient.Tests.UI/CompatibilitySuppressions.xml +++ b/Lombiq.OrchardCoreApiClient.Tests.UI/CompatibilitySuppressions.xml @@ -2,10 +2,7 @@ - CP0002 - M:Lombiq.OrchardCoreApiClient.Tests.UI.Extensions.TestCaseUITestContextExtensions.TestTenantsOrchardCoreApiClientBehaviorAsync(Lombiq.Tests.UI.Services.UITestContext,System.String,System.String,System.String) - lib/net8.0/Lombiq.OrchardCoreApiClient.Tests.UI.dll - lib/net8.0/Lombiq.OrchardCoreApiClient.Tests.UI.dll - true + PKV006 + net8.0 \ No newline at end of file diff --git a/Lombiq.OrchardCoreApiClient.Tests.UI/Extensions/TestCaseUITestContextExtensions.cs b/Lombiq.OrchardCoreApiClient.Tests.UI/Extensions/TestCaseUITestContextExtensions.cs index 079fd84..2cffa72 100644 --- a/Lombiq.OrchardCoreApiClient.Tests.UI/Extensions/TestCaseUITestContextExtensions.cs +++ b/Lombiq.OrchardCoreApiClient.Tests.UI/Extensions/TestCaseUITestContextExtensions.cs @@ -9,10 +9,14 @@ using OpenQA.Selenium; using OrchardCore.Autoroute.Models; using OrchardCore.ContentManagement; +using OrchardCore.Data; using OrchardCore.Taxonomies.Models; +using Refit; using Shouldly; using System; using System.Linq; +using System.Net; +using System.Net.Http.Json; using System.Text.Json; using System.Threading.Tasks; using Xunit; @@ -29,6 +33,7 @@ public static async Task TestOrchardCoreApiClientBehaviorAsync( string clientSecret = null, string featureProfile = null) { + await context.EnableTenantsFeatureDirectlyAsync(); await context.TestTenantsOrchardCoreApiClientBehaviorAsync( new ApiClientBehaviorTestModel { @@ -103,10 +108,12 @@ public static async Task TestTenantsOrchardCoreApiClientBehaviorAsync( { context.Configuration.TestOutputHelper.WriteLineTimestampedAndDebug("Using local test settings for creating tenant."); var databaseProvider = context.Configuration.UseSqlServer - ? "SqlConnection" - : "Sqlite"; + ? DatabaseProviderValue.SqlConnection + : DatabaseProviderValue.Sqlite; createApiModel.DatabaseProvider = databaseProvider; createApiModel.ConnectionString = context.SqlServerRunningContext?.ConnectionString; + setupApiModel.DatabaseProvider = databaseProvider; + setupApiModel.ConnectionString = context.SqlServerRunningContext?.ConnectionString; createApiModel.RequestUrlHost = string.Empty; editModel.RequestUrlHost = string.Empty; } @@ -230,14 +237,37 @@ private static async Task TestTenantCreateAsync( using (var response = await apiClient.OrchardCoreApi.CreateAsync(createApiModel)) { await context.AssertLogsAsync(); - response.Error.ShouldBeNull( - $"Tenant creation failed with status code {response.StatusCode}. Content: {response.Error?.Content}\n" + - $"Request: {response.RequestMessage}\nDriver URL: {context.Driver.Url}"); + CheckResponse(response, "creation", context); context.Configuration.TestOutputHelper.WriteLineTimestampedAndDebug("Tenant creation response had no errors."); // Check if response URL is valid, and visit it (should be the tenant setup page and not 404 error). - var responseUrl = new Uri(response.Content); + if (!Uri.TryCreate(response.Content, UriKind.Absolute, out var responseUrl)) + { + context.Configuration.TestOutputHelper.WriteLineTimestampedAndDebug( + $"Couldn't parse response URL ({response.Content}).\n" + JsonSerializer.Serialize(new + { + response.Content, + response.ContentHeaders, + response.Error, + response.Headers, + response.IsSuccessful, + response.IsSuccessStatusCode, + response.ReasonPhrase, + response.StatusCode, + response.Version, + RequestMessage = new + { + response.RequestMessage?.Content, + response.RequestMessage?.Headers, + response.RequestMessage?.Version, + response.RequestMessage?.Method, + response.RequestMessage?.RequestUri, + response.RequestMessage?.VersionPolicy, + }, + })); + } + context.Configuration.TestOutputHelper.WriteLineTimestampedAndDebug("Trying to go to the tenant setup page: " + responseUrl); await context.GoToAbsoluteUrlAsync(responseUrl); } @@ -275,9 +305,7 @@ private static async Task TestTenantSetupAsync( context.Configuration.TestOutputHelper.WriteLineTimestampedAndDebug("Initiating tenant setup..."); using (var response = await apiClient.OrchardCoreApi.SetupAsync(setupApiModel)) { - response.Error.ShouldBeNull( - $"Tenant setup failed with status code {response.StatusCode}. Content: {response.Error?.Content}\n" + - $"Request: {response.RequestMessage}\nDriver URL: {context.Driver.Url}"); + CheckResponse(response, "setup", context); } context.Configuration.TestOutputHelper.WriteLineTimestampedAndDebug("Now going to the tenant landing page to assert the setup."); @@ -302,9 +330,7 @@ private static async Task TestTenantEditAsync( context.Configuration.TestOutputHelper.WriteLineTimestampedAndDebug("Editing the tenant..."); using (var response = await apiClient.OrchardCoreApi.EditAsync(editModel)) { - response.Error.ShouldBeNull( - $"Tenant edit failed with status code {response.StatusCode}. Content: {response.Error?.Content}\n" + - $"Request: {response.RequestMessage}\nDriver URL: {context.Driver.Url}"); + CheckResponse(response, "edit", context); } if (checkOnAdmin) @@ -328,9 +354,7 @@ private static async Task TestTenantEditAsync( using (var response = await apiClient.OrchardCoreApi.EditAsync(editModel)) { - response.Error.ShouldBeNull( - $"Tenant edit (with name change) failed with status code {response.StatusCode}. Content: {response.Error?.Content}\n" + - $"Request: {response.RequestMessage}\nDriver URL: {context.Driver.Url}"); + CheckResponse(response, "edit (with name change)", context); } if (checkOnAdmin) @@ -365,9 +389,7 @@ private static async Task TestTenantDisableAsync( using (var response = await apiClient.OrchardCoreApi.DisableAsync(editModel.Name)) { - response.Error.ShouldBeNull( - $"Tenant disable failed with status code {response.StatusCode}. Content: {response.Error?.Content}\n" + - $"Request: {response.RequestMessage}\nDriver URL: {context.Driver.Url}"); + CheckResponse(response, "disable", context); } if (checkOnAdmin) @@ -395,7 +417,7 @@ await ReliabilityHelper.DoWithRetriesOrFailAsync( // The tenant can remain running for a while even after having been disabled. Waiting a bit here to see // if it gets unstuck. - if (response.StatusCode == System.Net.HttpStatusCode.BadRequest && + if (response.StatusCode == HttpStatusCode.BadRequest && response.Error?.Content?.Contains($"The tenant '{editModel.Name}' should be 'Disabled' or 'Uninitialized'.") == true) { context.Configuration.TestOutputHelper.WriteLineTimestampedAndDebug( @@ -404,9 +426,7 @@ await ReliabilityHelper.DoWithRetriesOrFailAsync( return false; } - response.Error.ShouldBeNull( - $"Tenant remove failed with status code {response.StatusCode}. Content: {response.Error?.Content}\n" + - $"Request: {response.RequestMessage}\nDriver URL: {context.Driver.Url}"); + CheckResponse(response, "remove", context); return true; }, @@ -530,4 +550,17 @@ private static ApiClientSettings CreateApiClientSettings(UITestContext context, DisableCertificateValidation = true, }; } + + private static void CheckResponse(ApiResponse response, string taskName, UITestContext context) + { + var request = response.RequestMessage?.ToString() ?? ""; + if (response.RequestMessage?.Content is JsonContent jsonContent) + { + request += "\nJSON Content: " + JsonSerializer.Serialize(jsonContent.Value); + } + + response.Error.ShouldBeNull( + $"Tenant {taskName} failed with status code {response.StatusCode}. Content: {response.Error?.Content}\n" + + $"Request: {request}\nDriver URL: {context.Driver.Url}"); + } } diff --git a/Lombiq.OrchardCoreApiClient.Tests.UI/Lombiq.OrchardCoreApiClient.Tests.UI.csproj b/Lombiq.OrchardCoreApiClient.Tests.UI/Lombiq.OrchardCoreApiClient.Tests.UI.csproj index 91cf465..3d79376 100644 --- a/Lombiq.OrchardCoreApiClient.Tests.UI/Lombiq.OrchardCoreApiClient.Tests.UI.csproj +++ b/Lombiq.OrchardCoreApiClient.Tests.UI/Lombiq.OrchardCoreApiClient.Tests.UI.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 @@ -21,7 +21,7 @@ - + diff --git a/Lombiq.OrchardCoreApiClient.Tests.UI/Recipes/Lombiq.OrchardCoreApiClient.Tests.UI.OpenId.recipe.json b/Lombiq.OrchardCoreApiClient.Tests.UI/Recipes/Lombiq.OrchardCoreApiClient.Tests.UI.OpenId.recipe.json index 7c79db1..267e26b 100644 --- a/Lombiq.OrchardCoreApiClient.Tests.UI/Recipes/Lombiq.OrchardCoreApiClient.Tests.UI.OpenId.recipe.json +++ b/Lombiq.OrchardCoreApiClient.Tests.UI/Recipes/Lombiq.OrchardCoreApiClient.Tests.UI.OpenId.recipe.json @@ -15,8 +15,7 @@ "OrchardCore.OpenId", "OrchardCore.OpenId.Management", "OrchardCore.OpenId.Server", - "OrchardCore.OpenId.Validation", - "OrchardCore.Tenants" + "OrchardCore.OpenId.Validation" ] }, // In this sample we must use "ASP.NET Core Data Protection" access token format (which doesn't use encryption), diff --git a/Lombiq.OrchardCoreApiClient/CompatibilitySuppressions.xml b/Lombiq.OrchardCoreApiClient/CompatibilitySuppressions.xml new file mode 100644 index 0000000..8af156c --- /dev/null +++ b/Lombiq.OrchardCoreApiClient/CompatibilitySuppressions.xml @@ -0,0 +1,8 @@ + + + + + PKV006 + net8.0 + + \ No newline at end of file diff --git a/Lombiq.OrchardCoreApiClient/Interfaces/IOrchardCoreApi.cs b/Lombiq.OrchardCoreApiClient/Interfaces/IOrchardCoreApi.cs index 8cb5e2b..3d90947 100644 --- a/Lombiq.OrchardCoreApiClient/Interfaces/IOrchardCoreApi.cs +++ b/Lombiq.OrchardCoreApiClient/Interfaces/IOrchardCoreApi.cs @@ -9,7 +9,7 @@ namespace Lombiq.OrchardCoreApiClient.Interfaces; [SuppressMessage( "Design", "CA1040:Avoid empty interfaces", - Justification = "This is a base interface used to identify all Orchard Core API interfaces May be extended in the future.")] + Justification = "This is a base interface used to identify all Orchard Core API interfaces. May be extended in the future.")] public interface IOrchardCoreApi { } diff --git a/Lombiq.OrchardCoreApiClient/Lombiq.OrchardCoreApiClient.csproj b/Lombiq.OrchardCoreApiClient/Lombiq.OrchardCoreApiClient.csproj index 14c7ca5..7e7a74a 100644 --- a/Lombiq.OrchardCoreApiClient/Lombiq.OrchardCoreApiClient.csproj +++ b/Lombiq.OrchardCoreApiClient/Lombiq.OrchardCoreApiClient.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 $(DefaultItemExcludes);.git* @@ -25,7 +25,7 @@ - + @@ -37,7 +37,7 @@ - +