Skip to content

Commit 88c99cb

Browse files
committed
Add tests for org config
1 parent aa3117d commit 88c99cb

2 files changed

Lines changed: 131 additions & 1 deletion

File tree

src/Auth0Net.DependencyInjection/HttpClient/Auth0TokenHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
3333
{
3434
var audience = _handlerConfig.Audience ?? _handlerConfig.AudienceResolver?.Invoke(request) ?? throw new ArgumentException("Audience cannot be computed");
3535

36-
var org = _accessor.Organization ?? _handlerConfig.Organization ?? _handlerConfig.AudienceResolver?.Invoke(request);
36+
var org = _accessor.Organization ?? _handlerConfig.Organization ?? _handlerConfig.OrganizationResolver?.Invoke(request);
3737
var token = await _cache.GetTokenAsync(audience, org, cancellationToken);
3838

3939
request.Headers.Authorization = new AuthenticationHeaderValue(Scheme, token);

tests/Auth0Net.DependencyInjection.Tests/OrganizationAccessorTests.cs

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,136 @@ public async Task TokenHandler_AccessorOrganizationTakesPrecedenceOverConfig()
6363
.MustHaveHappenedOnceExactly();
6464
}
6565

66+
[Fact]
67+
public async Task TokenHandler_UsesOrganizationResolver_WhenAccessorAndConfigAreEmpty()
68+
{
69+
var cache = A.Fake<IAuth0TokenCache>();
70+
A.CallTo(() => cache.GetTokenAsync(A<string>._, A<string?>._, A<CancellationToken>._))
71+
.Returns("access-token");
72+
73+
var accessor = new HttpClientOrganizationAccessor();
74+
var config = new Auth0TokenHandlerConfig
75+
{
76+
Audience = "api://test",
77+
OrganizationResolver = _ => "org-from-resolver"
78+
};
79+
80+
using var invoker = BuildInvoker(cache, config, accessor);
81+
await invoker.SendAsync(new HttpRequestMessage(HttpMethod.Get, "https://example.com"), CancellationToken.None);
82+
83+
A.CallTo(() => cache.GetTokenAsync("api://test", "org-from-resolver", A<CancellationToken>._))
84+
.MustHaveHappenedOnceExactly();
85+
}
86+
87+
[Fact]
88+
public async Task TokenHandler_ConfigOrganizationTakesPrecedenceOverResolver()
89+
{
90+
var cache = A.Fake<IAuth0TokenCache>();
91+
A.CallTo(() => cache.GetTokenAsync(A<string>._, A<string?>._, A<CancellationToken>._))
92+
.Returns("access-token");
93+
94+
var accessor = new HttpClientOrganizationAccessor();
95+
var config = new Auth0TokenHandlerConfig
96+
{
97+
Audience = "api://test",
98+
Organization = "org-from-config",
99+
OrganizationResolver = _ => "org-from-resolver"
100+
};
101+
102+
using var invoker = BuildInvoker(cache, config, accessor);
103+
await invoker.SendAsync(new HttpRequestMessage(HttpMethod.Get, "https://example.com"), CancellationToken.None);
104+
105+
A.CallTo(() => cache.GetTokenAsync("api://test", "org-from-config", A<CancellationToken>._))
106+
.MustHaveHappenedOnceExactly();
107+
}
108+
109+
[Fact]
110+
public async Task TokenHandler_AccessorTakesPrecedenceOverResolver()
111+
{
112+
var cache = A.Fake<IAuth0TokenCache>();
113+
A.CallTo(() => cache.GetTokenAsync(A<string>._, A<string?>._, A<CancellationToken>._))
114+
.Returns("access-token");
115+
116+
var accessor = new HttpClientOrganizationAccessor { Organization = "org-from-accessor" };
117+
var config = new Auth0TokenHandlerConfig
118+
{
119+
Audience = "api://test",
120+
OrganizationResolver = _ => "org-from-resolver"
121+
};
122+
123+
using var invoker = BuildInvoker(cache, config, accessor);
124+
await invoker.SendAsync(new HttpRequestMessage(HttpMethod.Get, "https://example.com"), CancellationToken.None);
125+
126+
A.CallTo(() => cache.GetTokenAsync("api://test", "org-from-accessor", A<CancellationToken>._))
127+
.MustHaveHappenedOnceExactly();
128+
}
129+
130+
[Fact]
131+
public async Task TokenHandler_OrganizationResolver_ReceivesHttpRequestMessage()
132+
{
133+
var cache = A.Fake<IAuth0TokenCache>();
134+
A.CallTo(() => cache.GetTokenAsync(A<string>._, A<string?>._, A<CancellationToken>._))
135+
.Returns("access-token");
136+
137+
HttpRequestMessage? capturedRequest = null;
138+
139+
var accessor = new HttpClientOrganizationAccessor();
140+
var config = new Auth0TokenHandlerConfig
141+
{
142+
Audience = "api://test",
143+
OrganizationResolver = req =>
144+
{
145+
capturedRequest = req;
146+
return "org-resolved";
147+
}
148+
};
149+
150+
using var invoker = BuildInvoker(cache, config, accessor);
151+
var request = new HttpRequestMessage(HttpMethod.Get, "https://example.com/api/resource");
152+
await invoker.SendAsync(request, CancellationToken.None);
153+
154+
Assert.NotNull(capturedRequest);
155+
Assert.Equal("https://example.com/api/resource", capturedRequest.RequestUri!.ToString());
156+
}
157+
158+
[Fact]
159+
public async Task TokenHandler_OrganizationResolver_ReturnsNull_PassesNullToCache()
160+
{
161+
var cache = A.Fake<IAuth0TokenCache>();
162+
A.CallTo(() => cache.GetTokenAsync(A<string>._, A<string?>._, A<CancellationToken>._))
163+
.Returns("access-token");
164+
165+
var accessor = new HttpClientOrganizationAccessor();
166+
var config = new Auth0TokenHandlerConfig
167+
{
168+
Audience = "api://test",
169+
OrganizationResolver = _ => null
170+
};
171+
172+
using var invoker = BuildInvoker(cache, config, accessor);
173+
await invoker.SendAsync(new HttpRequestMessage(HttpMethod.Get, "https://example.com"), CancellationToken.None);
174+
175+
A.CallTo(() => cache.GetTokenAsync("api://test", null, A<CancellationToken>._))
176+
.MustHaveHappenedOnceExactly();
177+
}
178+
179+
[Fact]
180+
public async Task TokenHandler_NoOrganizationConfigured_PassesNullToCache()
181+
{
182+
var cache = A.Fake<IAuth0TokenCache>();
183+
A.CallTo(() => cache.GetTokenAsync(A<string>._, A<string?>._, A<CancellationToken>._))
184+
.Returns("access-token");
185+
186+
var accessor = new HttpClientOrganizationAccessor();
187+
var config = new Auth0TokenHandlerConfig { Audience = "api://test" };
188+
189+
using var invoker = BuildInvoker(cache, config, accessor);
190+
await invoker.SendAsync(new HttpRequestMessage(HttpMethod.Get, "https://example.com"), CancellationToken.None);
191+
192+
A.CallTo(() => cache.GetTokenAsync("api://test", null, A<CancellationToken>._))
193+
.MustHaveHappenedOnceExactly();
194+
}
195+
66196
private static HttpMessageInvoker BuildInvoker(
67197
IAuth0TokenCache cache,
68198
Auth0TokenHandlerConfig config,

0 commit comments

Comments
 (0)