Skip to content

Commit b564a6a

Browse files
authored
Fixed issue with fake auth where roles and claims was not available through a cascading parameter of Task<AuthenticationState>
* Switched from using FakeIdentity and FakePrincipal to using built in types * Updated changelog * Code cleanup * Added IAsyncDisposable to TestServiceProvider (#292) * Update main.yml * Updated SourceFileFinder dependency version * workflow updates
1 parent 7d22cb5 commit b564a6a

File tree

9 files changed

+81
-221
lines changed

9 files changed

+81
-221
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ List of any bug fixes.
134134

135135
- When an element, found in the DOM tree using the `Find()`, method was removed because of an event handler trigger on it, e.g. an `cut.Find("button").Click()` event trigger method, an `ElementNotFoundException` was thrown. Reported by [@nickmuller](https://github.com/nickmuller) in [#251](https://github.com/egil/bUnit/issues/251).
136136

137+
- In the built-in fake authentication system in bUnit, roles and claims were not available in components through the a cascading parameter of type `Task<AuthenticationState>`. Reported by [@AFAde](https://github.com/AFAde) in [#253](https://github.com/egil/bUnit/discussions/253) and fixed in [#291](https://github.com/egil/bUnit/pull/291) by [@egil](https://github.com/egil).
138+
137139
## [1.0.0-beta 11] - 2020-10-26
138140

139141
The following section list all changes in beta-11.

src/bunit.web/TestDoubles/Authorization/FakeAuthenticationStateProvider.cs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,15 @@ private static AuthenticationState CreateAuthenticationState(
9999
IEnumerable<string>? roles = null,
100100
IEnumerable<Claim>? claims = null)
101101
{
102-
var identity = new FakeIdentity { Name = username };
103-
var testPrincipal = new FakePrincipal { Identity = identity, Roles = roles ?? Array.Empty<string>() };
104-
var principal = new ClaimsPrincipal(testPrincipal);
102+
roles = roles ?? Array.Empty<string>();
103+
claims = claims ?? Array.Empty<Claim>();
105104

106-
if (claims is not null && claims.Any())
107-
{
108-
principal.AddIdentity(new ClaimsIdentity(claims));
109-
}
105+
var usernameClaim = new Claim(ClaimsIdentity.DefaultNameClaimType, username);
106+
var roleClaims = roles.Select(x => new Claim(ClaimsIdentity.DefaultRoleClaimType, x));
107+
var allClaims = roleClaims.Concat(claims).Prepend(usernameClaim);
108+
109+
var identity = new ClaimsIdentity(claims: allClaims, authenticationType: "bUnit Fake Authentication");
110+
var principal = new ClaimsPrincipal(identity);
110111

111112
return new AuthenticationState(principal);
112113
}
@@ -117,7 +118,7 @@ private static AuthenticationState CreateAuthenticationState(
117118
/// <returns>Instance of AuthenticationState for an unauthenticated user.</returns>
118119
private static AuthenticationState CreateUnauthenticationState()
119120
{
120-
var principal = new ClaimsPrincipal(new FakePrincipal());
121+
var principal = new ClaimsPrincipal(new ClaimsIdentity());
121122
return new AuthenticationState(principal);
122123
}
123124
}

src/bunit.web/TestDoubles/Authorization/FakeIdentity.cs

Lines changed: 0 additions & 47 deletions
This file was deleted.

src/bunit.web/TestDoubles/Authorization/FakePrincipal.cs

Lines changed: 0 additions & 36 deletions
This file was deleted.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
@using Microsoft.AspNetCore.Components.Authorization
2+
3+
<p>@isInRole</p>
4+
5+
@code {
6+
private bool isInRole;
7+
8+
[Parameter] public string ExpectedRole { get; set; } = string.Empty;
9+
10+
[CascadingParameter] public Task<AuthenticationState> AuthenticationStateTask { get; set; } = default!;
11+
12+
protected override async Task OnInitializedAsync()
13+
{
14+
var authenticationState = await AuthenticationStateTask;
15+
isInRole = authenticationState.User.IsInRole(ExpectedRole);
16+
}
17+
}

tests/bunit.web.tests/TestDoubles/Authorization/AuthorizationTest.cs

Lines changed: 43 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,16 @@
55

66
namespace Bunit.TestDoubles.Authorization
77
{
8-
public class AuthorizationTest
8+
public class AuthorizationTest : TestContext
99
{
1010
[Fact(DisplayName = "AuthorizeView with unauthenticated user")]
1111
public void Test001()
1212
{
1313
// Arrange
14-
using var ctx = new TestContext();
15-
ctx.AddTestAuthorization();
14+
this.AddTestAuthorization();
1615

1716
// Act
18-
var cut = ctx.RenderComponent<SimpleAuthView>();
17+
var cut = RenderComponent<SimpleAuthView>();
1918

2019
// Assert
2120
cut.MarkupMatches("Not authorized?");
@@ -25,12 +24,11 @@ public void Test001()
2524
public void Test002()
2625
{
2726
// arrange
28-
using var ctx = new TestContext();
29-
var authContext = ctx.AddTestAuthorization();
27+
var authContext = this.AddTestAuthorization();
3028
authContext.SetAuthorized("TestUser", AuthorizationState.Authorized);
3129

3230
// act
33-
var cut = ctx.RenderComponent<SimpleAuthView>();
31+
var cut = RenderComponent<SimpleAuthView>();
3432

3533
// assert
3634
cut.MarkupMatches("Authorized!");
@@ -40,12 +38,11 @@ public void Test002()
4038
public void Test003()
4139
{
4240
// arrange
43-
using var ctx = new TestContext();
44-
var authContext = ctx.AddTestAuthorization();
41+
var authContext = this.AddTestAuthorization();
4542
authContext.SetAuthorized("TestUser", AuthorizationState.Unauthorized);
4643

4744
// act
48-
var cut = ctx.RenderComponent<SimpleAuthView>();
45+
var cut = RenderComponent<SimpleAuthView>();
4946

5047
// assert
5148
cut.MarkupMatches("Not authorized?");
@@ -55,11 +52,10 @@ public void Test003()
5552
public void Test004()
5653
{
5754
// arrange
58-
using var ctx = new TestContext();
59-
var authContext = ctx.AddTestAuthorization();
55+
var authContext = this.AddTestAuthorization();
6056

6157
// start off unauthenticated.
62-
var cut = ctx.RenderComponent<SimpleAuthView>();
58+
var cut = RenderComponent<SimpleAuthView>();
6359
cut.MarkupMatches("Not authorized?");
6460

6561
// act
@@ -75,12 +71,11 @@ public void Test004()
7571
public void Test005()
7672
{
7773
// arrange
78-
using var ctx = new TestContext();
79-
var authContext = ctx.AddTestAuthorization();
74+
var authContext = this.AddTestAuthorization();
8075
authContext.SetAuthorized("TestUser005", AuthorizationState.Authorized);
8176

8277
// start off unauthenticated.
83-
var cut = ctx.RenderComponent<SimpleAuthView>();
78+
var cut = RenderComponent<SimpleAuthView>();
8479
cut.MarkupMatches("Authorized!");
8580

8681
// act
@@ -95,11 +90,8 @@ public void Test005()
9590
[Fact(DisplayName = "AuthorizeView rendering without authorization services registered")]
9691
public void Test006()
9792
{
98-
// arrange
99-
using var ctx = new TestContext();
100-
10193
// act
102-
var ex = Assert.Throws<MissingFakeAuthorizationException>(() => ctx.RenderComponent<SimpleAuthView>());
94+
var ex = Assert.Throws<MissingFakeAuthorizationException>(() => RenderComponent<SimpleAuthView>());
10395

10496
// assert
10597
Assert.Equal("AuthenticationStateProvider", ex.ServiceName);
@@ -110,12 +102,11 @@ public void Test006()
110102
public void Test007()
111103
{
112104
// arrange
113-
using var ctx = new TestContext();
114-
var authContext = ctx.AddTestAuthorization();
105+
var authContext = this.AddTestAuthorization();
115106
authContext.SetAuthorized("TestUser").SetPolicies("ContentViewer");
116107

117108
// act
118-
var cut = ctx.RenderComponent<SimpleAuthViewWithPolicy>();
109+
var cut = RenderComponent<SimpleAuthViewWithPolicy>();
119110

120111
// assert
121112
cut.MarkupMatches("Authorized for content viewers.");
@@ -125,11 +116,10 @@ public void Test007()
125116
public void Test008()
126117
{
127118
// arrange
128-
using var ctx = new TestContext();
129-
var authContext = ctx.AddTestAuthorization();
119+
var authContext = this.AddTestAuthorization();
130120
authContext.SetAuthorized("TestUser");
131121
// act
132-
var cut = ctx.RenderComponent<SimpleAuthViewWithPolicy>();
122+
var cut = RenderComponent<SimpleAuthViewWithPolicy>();
133123

134124
// assert
135125
cut.MarkupMatches("");
@@ -139,12 +129,11 @@ public void Test008()
139129
public void Test0081()
140130
{
141131
// arrange
142-
using var ctx = new TestContext();
143-
var authContext = ctx.AddTestAuthorization();
132+
var authContext = this.AddTestAuthorization();
144133
authContext.SetAuthorized("TestUser").SetPolicies("OtherPolicy");
145134

146135
// act
147-
var cut = ctx.RenderComponent<SimpleAuthViewWithPolicy>();
136+
var cut = RenderComponent<SimpleAuthViewWithPolicy>();
148137

149138
// assert
150139
cut.MarkupMatches("");
@@ -154,12 +143,11 @@ public void Test0081()
154143
public void Test009()
155144
{
156145
// arrange
157-
using var ctx = new TestContext();
158-
var authContext = ctx.AddTestAuthorization();
146+
var authContext = this.AddTestAuthorization();
159147
authContext.SetAuthorized("TestUser").SetRoles("Admin");
160148

161149
// act
162-
var cut = ctx.RenderComponent<SimpleAuthViewWithRole>();
150+
var cut = RenderComponent<SimpleAuthViewWithRole>();
163151

164152
// assert
165153
cut.MarkupMatches("Authorized content for admins.");
@@ -169,12 +157,11 @@ public void Test009()
169157
public void Test010()
170158
{
171159
// arrange
172-
using var ctx = new TestContext();
173-
var authContext = ctx.AddTestAuthorization();
160+
var authContext = this.AddTestAuthorization();
174161
authContext.SetAuthorized("TestUser");
175162

176163
// act
177-
var cut = ctx.RenderComponent<SimpleAuthViewWithRole>();
164+
var cut = RenderComponent<SimpleAuthViewWithRole>();
178165

179166
// assert
180167
cut.MarkupMatches("");
@@ -184,12 +171,11 @@ public void Test010()
184171
public void Test011()
185172
{
186173
// arrange
187-
using var ctx = new TestContext();
188-
var authContext = ctx.AddTestAuthorization();
174+
var authContext = this.AddTestAuthorization();
189175
authContext.SetAuthorized("TestUser").SetRoles("NotAdmin");
190176

191177
// act
192-
var cut = ctx.RenderComponent<SimpleAuthViewWithRole>();
178+
var cut = RenderComponent<SimpleAuthViewWithRole>();
193179

194180
// assert
195181
cut.MarkupMatches("");
@@ -199,12 +185,11 @@ public void Test011()
199185
public void Test012()
200186
{
201187
// arrange
202-
using var ctx = new TestContext();
203-
var authContext = ctx.AddTestAuthorization();
188+
var authContext = this.AddTestAuthorization();
204189
authContext.SetAuthorizing();
205190

206191
// act
207-
var cut = ctx.RenderComponent<SimpleAuthView>();
192+
var cut = RenderComponent<SimpleAuthView>();
208193

209194
// assert
210195
cut.MarkupMatches("Authorizing...");
@@ -215,14 +200,13 @@ public void Test013()
215200
{
216201
// arrange
217202
var userId = new Guid("{5d5fa9c1-abf9-4ed6-8fb0-3365382b629c}");
218-
using var ctx = new TestContext();
219-
var authContext = ctx.AddTestAuthorization();
203+
var authContext = this.AddTestAuthorization();
220204
var emailClaim = new Claim(ClaimTypes.Email, "[email protected]");
221205
var uuidClaim = new Claim(ClaimTypes.Sid, userId.ToString());
222206
authContext.SetAuthorized("TestUser").SetClaims(uuidClaim, emailClaim);
223207

224208
// act
225-
var cut = ctx.RenderComponent<SimpleAuthViewWithClaims>();
209+
var cut = RenderComponent<SimpleAuthViewWithClaims>();
226210

227211
// assert
228212
cut.MarkupMatches(@$"<div>Authorized!</div>
@@ -236,16 +220,28 @@ public void Test013()
236220
public void Test014()
237221
{
238222
// arrange
239-
using var ctx = new TestContext();
240-
var authContext = ctx.AddTestAuthorization();
223+
var authContext = this.AddTestAuthorization();
241224
authContext.SetAuthorized("TestUser");
242225

243226
// act
244-
var cut = ctx.RenderComponent<SimpleAuthViewWithClaims>();
227+
var cut = RenderComponent<SimpleAuthViewWithClaims>();
245228

246229
// assert
247230
cut.MarkupMatches(@$"<div>Authorized!</div>
248231
<div>Name: TestUser</div>");
249232
}
233+
234+
[Fact(DisplayName = "IsInRole can resolve role assigned to auth context")]
235+
public void Test020()
236+
{
237+
var role = "myTestRole";
238+
var authCtx = this.AddTestAuthorization();
239+
authCtx.SetAuthorized("FooBar");
240+
authCtx.SetRoles(role);
241+
242+
var cut = RenderComponent<AuthCascading>(ps => ps.Add(p => p.ExpectedRole, role));
243+
244+
cut.MarkupMatches("<p>True</p>");
245+
}
250246
}
251247
}

0 commit comments

Comments
 (0)