Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/api-e2e-mssql-multitenant.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ jobs:
- name: Copy admin api common folder to docker context
run: cp -r ../EdFi.Ods.AdminApi.Common ../../Docker/Application

- name: Copy health check service folder to docker context
run: cp -r ../EdFi.Ods.AdminApi.HealthCheck ../../Docker/Application

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could simplify all of this switching the Dockerfile to use the new "additional contexts" feature, which allows accessing files from a different parent directory.

Let's do that as a separate work item though, rather than allowing scope creep on this.

- name: Copy nuget config to docker context
run: cp ../NuGet.Config ../../Docker/Application

Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/api-e2e-mssql-singletenant.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ jobs:
- name: Copy admin api common folder to docker context
run: cp -r ../EdFi.Ods.AdminApi.Common ../../Docker/Application

- name: Copy health check service folder to docker context
run: cp -r ../EdFi.Ods.AdminApi.HealthCheck ../../Docker/Application

- name: Copy nuget config to docker context
run: cp ../NuGet.Config ../../Docker/Application

Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/api-e2e-pgsql-multitenant.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ jobs:
- name: Copy admin api common folder to docker context
run: cp -r ../EdFi.Ods.AdminApi.Common ../../Docker/Application

- name: Copy health check service folder to docker context
run: cp -r ../EdFi.Ods.AdminApi.HealthCheck ../../Docker/Application

- name: Copy nuget config to docker context
run: cp ../NuGet.Config ../../Docker/Application

Expand Down
1 change: 1 addition & 0 deletions .github/workflows/api-e2e-pgsql-singletenant.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ jobs:
cp -r ../EdFi.Ods.AdminApi ../../Docker/Application
cp -r ../EdFi.Ods.AdminApi.AdminConsole ../../Docker/Application
cp -r ../EdFi.Ods.AdminApi.Common ../../Docker/Application
cp -r ../EdFi.Ods.AdminApi.HealthCheck ../../Docker/Application

- name: Copy nuget config to docker context
run: cp ../NuGet.Config ../../Docker/Application
Expand Down
24 changes: 24 additions & 0 deletions Application/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,29 @@

<!-- System -->
<PackageVersion Include="System.Formats.Asn1" Version="9.0.0" />

<!-- Quartz-->
<PackageVersion Include="Quartz" Version="3.14.0" />
<PackageVersion Include="Quartz.Extensions.DependencyInjection" Version="3.14.0" />
<PackageVersion Include="Quartz.Extensions.Hosting" Version="3.14.0" />

<!-- Health Check Service-->
<PackageVersion Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<PackageVersion Include="Microsoft.CodeAnalysis" Version="4.12.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.CodeStyle" Version="4.12.0" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="9.0.0" />
<PackageVersion Include="Polly" Version="8.5.2" />
<PackageVersion Include="Polly.Contrib.WaitAndRetry" Version="1.1.1" />
<PackageVersion Include="Serilog" Version="4.1.0" />
<PackageVersion Include="Serilog.Extensions.Hosting" Version="8.0.0" />
<PackageVersion Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageVersion Include="Serilog.Enrichers.Environment" Version="3.0.1" />
<PackageVersion Include="Serilog.Expressions" Version="5.0.0" />
<PackageVersion Include="Serilog.Formatting.Compact" Version="3.0.0" />
<PackageVersion Include="Serilog.Sinks.File" Version="6.0.0" />
<PackageVersion Include="System.Text.Encodings.Web" Version="9.0.0" />
</ItemGroup>
</Project>
20 changes: 20 additions & 0 deletions Application/Ed-Fi-ODS-AdminApi.sln
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EdFi.Ods.AdminApi.Common.Un
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EdFi.Ods.AdminApi.AdminConsole.UnitTests", "EdFi.Ods.AdminApi.AdminConsole.UnitTests\EdFi.Ods.AdminApi.AdminConsole.UnitTests.csproj", "{7C919128-B651-4756-8625-A8F7882FA9A4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EdFi.Ods.AdminApi.HealthCheck", "EdFi.Ods.AdminApi.HealthCheck\EdFi.Ods.AdminApi.HealthCheck.csproj", "{243D1BB9-7E56-7439-D4DF-438EF9A8692F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EdFi.Ods.AdminApi.HealthCheck.UnitTests", "EdFi.Ods.AdminApi.HealthCheck.UnitTests\EdFi.Ods.AdminApi.HealthCheck.UnitTests.csproj", "{9CF7B5C5-92F6-A980-A213-71B14729F0A0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -102,6 +106,22 @@ Global
{7C919128-B651-4756-8625-A8F7882FA9A4}.Release|Any CPU.Build.0 = Release|Any CPU
{7C919128-B651-4756-8625-A8F7882FA9A4}.Release|x64.ActiveCfg = Release|Any CPU
{7C919128-B651-4756-8625-A8F7882FA9A4}.Release|x64.Build.0 = Release|Any CPU
{243D1BB9-7E56-7439-D4DF-438EF9A8692F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{243D1BB9-7E56-7439-D4DF-438EF9A8692F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{243D1BB9-7E56-7439-D4DF-438EF9A8692F}.Debug|x64.ActiveCfg = Debug|Any CPU
{243D1BB9-7E56-7439-D4DF-438EF9A8692F}.Debug|x64.Build.0 = Debug|Any CPU
{243D1BB9-7E56-7439-D4DF-438EF9A8692F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{243D1BB9-7E56-7439-D4DF-438EF9A8692F}.Release|Any CPU.Build.0 = Release|Any CPU
{243D1BB9-7E56-7439-D4DF-438EF9A8692F}.Release|x64.ActiveCfg = Release|Any CPU
{243D1BB9-7E56-7439-D4DF-438EF9A8692F}.Release|x64.Build.0 = Release|Any CPU
{9CF7B5C5-92F6-A980-A213-71B14729F0A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9CF7B5C5-92F6-A980-A213-71B14729F0A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9CF7B5C5-92F6-A980-A213-71B14729F0A0}.Debug|x64.ActiveCfg = Debug|Any CPU
{9CF7B5C5-92F6-A980-A213-71B14729F0A0}.Debug|x64.Build.0 = Debug|Any CPU
{9CF7B5C5-92F6-A980-A213-71B14729F0A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9CF7B5C5-92F6-A980-A213-71B14729F0A0}.Release|Any CPU.Build.0 = Release|Any CPU
{9CF7B5C5-92F6-A980-A213-71B14729F0A0}.Release|x64.ActiveCfg = Release|Any CPU
{9CF7B5C5-92F6-A980-A213-71B14729F0A0}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
5 changes: 5 additions & 0 deletions Application/Ed-Fi-ODS-AdminApi.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ See the LICENSE and NOTICES files in the project root for more information.</s:S
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=LocalConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PublicFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=15b5b1f1_002D457c_002D4ca6_002Db278_002D5615aedc07d3/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static readonly fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=53eecf85_002Dd821_002D40e8_002Dac97_002Dfdb734542b84/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Instance" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Instance fields (not private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=70345118_002D4b40_002D4ece_002D937c_002Dbbeb7a0b2e70/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Static fields (not private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=a4f433b8_002Dabcd_002D4e55_002Da08f_002D82e78cef0f0c/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Any" Description="Local constants"&gt;&lt;ElementKinds&gt;&lt;Kind Name="LOCAL_CONSTANT" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FBLOCK_005FSCOPE_005FCONSTANT/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FBLOCK_005FSCOPE_005FFUNCTION/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FBLOCK_005FSCOPE_005FVARIABLE/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
Expand Down Expand Up @@ -188,6 +192,7 @@ See the LICENSE and NOTICES files in the project root for more information.</s:S
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=edfi/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Encryptor/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public interface IInstanceRequestModel
ICollection<OdsInstanceDerivativeModel>? OdsInstanceDerivatives { get; }

byte[]? Credentials { get; }
public string? Status { get; set; }
string? Status { get; set; }
}

public class OdsInstanceContextModel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ public interface IAdminConsoleTenantsService
Task<TenantModel?> GetTenantByTenantIdAsync(int tenantId);
}

public class TenantService(IOptionsSnapshot<AppSettingsFile> options,
IMemoryCache memoryCache) : IAdminConsoleTenantsService
public class TenantService(IOptionsMonitor<AppSettingsFile> options, IMemoryCache memoryCache)
: IAdminConsoleTenantsService
{
private const string ADMIN_DB_KEY = "EdFi_Admin";
protected AppSettingsFile _appSettings = options.Value;
protected AppSettingsFile _appSettings = options.CurrentValue;
private readonly IMemoryCache _memoryCache = memoryCache;
private static readonly ILog _log = LogManager.GetLogger(typeof(TenantService));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public void BuildForVersions(string authorizationPolicy, params AdminApiVersions
{
builder.WithResponseCode(400, FeatureCommonConstants.BadRequestResponseDescription);
}

foreach (var action in _routeOptions)
{
action(builder);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="FakeItEasy" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="NUnit" />
<PackageReference Include="NUnit3TestAdapter" />
<PackageReference Include="NUnit.Analyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Shouldly" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\EdFi.Ods.AdminApi.HealthCheck\EdFi.Ods.AdminApi.HealthCheck.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// SPDX-License-Identifier: Apache-2.0
// Licensed to the Ed-Fi Alliance under one or more agreements.
// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0.
// See the LICENSE and NOTICES files in the project root for more information.

using System.Net;
using EdFi.Ods.AdminApi.HealthCheck.Helpers;
using EdFi.Ods.AdminApi.HealthCheck.Infrastructure;
using EdFi.Ods.AdminApi.HealthCheck.Features.OdsApi;
using FakeItEasy;
using NUnit.Framework;
using Shouldly;

namespace EdFi.Ods.AdminApi.HealthCheck.UnitTests.Features.OdsApi;

public class Given_an_ods_api
{
[TestFixture]
public class When_HealthCheckData_is_returned_from_api : Given_an_ods_api
{
private IOdsApiClient _odsApiClient;
private OdsApiCaller _odsApiCaller;

[SetUp]
public void SetUp()
{
_odsApiClient = A.Fake<IOdsApiClient>();

var adminApiInstance = Testing.AdminApiInstances.First();

var httpResponse1 = new HttpResponseMessage(HttpStatusCode.OK);
httpResponse1.Headers.Add(Constants.TotalCountHeader, "3");

var httpResponse2 = new HttpResponseMessage(HttpStatusCode.OK);
httpResponse2.Headers.Add(Constants.TotalCountHeader, "8");

var httpResponse3 = new HttpResponseMessage(HttpStatusCode.OK);
httpResponse3.Headers.Add(Constants.TotalCountHeader, "5");

A.CallTo(() => _odsApiClient.OdsApiGet(A<string>.Ignored, A<string>.Ignored, A<string>.Ignored, "http://www.myserver.com/data/v3/ed-fi/firstEndPoint?offset=0&limit=0&totalCount=true"))
.Returns(new ApiResponse(HttpStatusCode.OK, string.Empty, httpResponse1.Headers));

A.CallTo(() => _odsApiClient.OdsApiGet(A<string>.Ignored, A<string>.Ignored, A<string>.Ignored, "http://www.myserver.com/data/v3/ed-fi/secondEndpoint?offset=0&limit=0&totalCount=true"))
.Returns(new ApiResponse(HttpStatusCode.OK, string.Empty, httpResponse2.Headers));

A.CallTo(() => _odsApiClient.OdsApiGet(A<string>.Ignored, A<string>.Ignored, A<string>.Ignored, "http://www.myserver.com/data/v3/ed-fi/thirdEndPoint?offset=0&limit=0&totalCount=true"))
.Returns(new ApiResponse(HttpStatusCode.OK, string.Empty, httpResponse3.Headers));

_odsApiCaller = new OdsApiCaller(_odsApiClient, new AppSettingsOdsApiEndpoints(Testing.GetOdsApiSettings()));
}

[Test]
public async Task should_return_stronglytyped_healthCheck_data()
{
var healthCheckData = await _odsApiCaller.GetHealthCheckDataAsync(Testing.AdminApiInstances.First());
healthCheckData.ShouldBeEquivalentTo(Testing.HealthCheckData);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// SPDX-License-Identifier: Apache-2.0
// Licensed to the Ed-Fi Alliance under one or more agreements.
// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0.
// See the LICENSE and NOTICES files in the project root for more information.

using System.Net;
using System.Net.Http.Headers;
using System.Text;
using EdFi.Ods.AdminApi.HealthCheck.Features.OdsApi;
using EdFi.Ods.AdminApi.HealthCheck.Helpers;
using EdFi.Ods.AdminApi.HealthCheck.Infrastructure;
using FakeItEasy;
using Microsoft.Extensions.Logging;
using NUnit.Framework;
using Shouldly;

namespace EdFi.Ods.AdminApi.HealthCheck.UnitTests.Features.OdsApi;

public class Given_an_ods_environment_with_single_tenant
{
private ILogger<OdsApiClient> _logger;

[SetUp]
public void SetUp()
{
_logger = A.Fake<ILogger<OdsApiClient>>();
}

public class When_HealthCheck_data_is_requested : Given_an_ods_environment_with_single_tenant
{
[Test]
public async Task should_return_successfully()
{
var httpClient = A.Fake<IAppHttpClient>();
var adminApiInstance = Testing.AdminApiInstances.First();
var encodedKeySecret = Encoding.ASCII.GetBytes($"{adminApiInstance.ClientId}:{adminApiInstance.ClientSecret}");
var headers = new HttpResponseMessage().Headers;
headers.Add(Constants.TotalCountHeader, "5");

A.CallTo(() => httpClient.SendAsync(
adminApiInstance.OauthUrl, HttpMethod.Post, A<FormUrlEncodedContent>.Ignored, new AuthenticationHeaderValue("Basic", Convert.ToBase64String(encodedKeySecret))))
.Returns(new ApiResponse(HttpStatusCode.OK, "{ \"access_token\": \"123\"}"));

A.CallTo(() => httpClient.SendAsync(adminApiInstance.ResourceUrl, HttpMethod.Get, null as StringContent, new AuthenticationHeaderValue("bearer", "123")))
.Returns(new ApiResponse(HttpStatusCode.OK, string.Empty, headers));

var odsApiClient = new OdsApiClient(httpClient, _logger, Testing.GetAppSettings());

var response = await odsApiClient.OdsApiGet(
adminApiInstance.OauthUrl, adminApiInstance.ClientId, adminApiInstance.ClientSecret, adminApiInstance.ResourceUrl);

response.Headers.ShouldNotBeNull();
response.Headers.Any(o => o.Key == Constants.TotalCountHeader).ShouldBe(true);
response.Headers.GetValues(Constants.TotalCountHeader).First().ShouldBe("5");
}
}

public class When_HealthCheck_data_is_requested_without_token : Given_an_ods_environment_with_single_tenant
{
[Test]
public async Task InternalServerError_is_returned()
{
var httpClient = A.Fake<IAppHttpClient>();
var adminApiInstance = Testing.AdminApiInstances.First();
var encodedKeySecret = Encoding.ASCII.GetBytes($"{adminApiInstance.ClientId}:{adminApiInstance.ClientSecret}");

var headers = new HttpResponseMessage().Headers;
headers.Add(Constants.TotalCountHeader, "5");

A.CallTo(() => httpClient.SendAsync(
adminApiInstance.OauthUrl, HttpMethod.Post, A<FormUrlEncodedContent>.Ignored, new AuthenticationHeaderValue("Basic", Convert.ToBase64String(encodedKeySecret))))
.Returns(new ApiResponse(HttpStatusCode.InternalServerError, string.Empty));

A.CallTo(() => httpClient.SendAsync(adminApiInstance.ResourceUrl, HttpMethod.Get, null as StringContent, new AuthenticationHeaderValue("bearer", "123")))
.Returns(new ApiResponse(HttpStatusCode.OK, string.Empty, headers));

var odsApiClient = new OdsApiClient(httpClient, _logger, Testing.GetAppSettings());

var response = await odsApiClient.OdsApiGet(adminApiInstance.OauthUrl, adminApiInstance.ClientId, adminApiInstance.ClientSecret, adminApiInstance.ResourceUrl);

response.StatusCode.ShouldBe(HttpStatusCode.InternalServerError);
}
}
}
Loading
Loading