Skip to content

Commit a3eeac9

Browse files
amjadmahmAmjad MahmoodAmjad Mahmood
authored
DSI-8870: Integration Tests > Change Name (#216)
Co-authored-by: Amjad Mahmood <amjad.mahmood@education.gov.uk> Co-authored-by: Amjad Mahmood <amjad.m@hotmail.co.uk>
1 parent 2b81766 commit a3eeac9

2 files changed

Lines changed: 297 additions & 1 deletion

File tree

src/Dfe.SignIn.Core.UseCases/Users/ChangeNameUseCase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public override async Task<ChangeNameResponse> InvokeAsync(
4343

4444
await interaction.DispatchAsync(
4545
new WriteToAuditRequest {
46-
EventCategory = AuditEventCategoryNames.ChangeJobTitle,
46+
EventCategory = AuditEventCategoryNames.ChangeName,
4747
Message = $"Successfully changed users name to {user.FirstName} {user.LastName}",
4848
UserId = context.Request.UserId,
4949
}
Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
using System.Net;
2+
using System.Net.Http.Json;
3+
using Dfe.SignIn.Core.Contracts.Audit;
4+
using Dfe.SignIn.Core.Contracts.Users;
5+
using Dfe.SignIn.Core.Entities.Directories;
6+
using Dfe.SignIn.Gateways.EntityFramework;
7+
using Dfe.SignIn.InternalApi.Contracts;
8+
using Dfe.SignIn.TestHelpers.Integration.Data;
9+
using Dfe.SignIn.TestHelpers.Integration.Extensions;
10+
using Microsoft.EntityFrameworkCore;
11+
using Microsoft.Extensions.DependencyInjection;
12+
using Assert = Xunit.Assert;
13+
14+
namespace Dfe.SignIn.InternalApi.IntegrationTests.Endpoints.Users;
15+
16+
[Trait("Category", "Integration")]
17+
public class ChangeNameTests : InternalApiIntegrationEndpointTestBase
18+
{
19+
private const string endpoint = "interaction/Users.ChangeName";
20+
21+
public ChangeNameTests(InternalApiWebApplicationFactory factory)
22+
: base(factory)
23+
{
24+
}
25+
26+
[Fact]
27+
public async Task ChangeName_ReturnsSuccess_UpdatesDb_AndWritesAudit_WhenUserExists()
28+
{
29+
var (authenticatedClient, auditMock) = this.CreateClientWithAuditMock();
30+
31+
var expectedFirstName = "Jane";
32+
var expectedLastName = "Smith";
33+
var user = EntityFaker.User
34+
.RuleFor(x => x.FirstName, (_, _) => "John")
35+
.RuleFor(x => x.LastName, (_, _) => "Doe")
36+
.Generate();
37+
38+
await this.InsertEntityAsync<DbDirectoriesContext, UserEntity>(user);
39+
40+
var request = new ChangeNameRequest {
41+
UserId = user.Sub,
42+
FirstName = expectedFirstName,
43+
LastName = expectedLastName
44+
};
45+
46+
var response = await authenticatedClient.PostAsJsonAsync(endpoint, request);
47+
48+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
49+
50+
var body = await response.Content.ReadFromJsonAsync<InteractionResponse<ChangeNameResponse>>();
51+
Assert.NotNull(body);
52+
Assert.NotNull(body.Data);
53+
54+
await using var assertionScope = this.WebAppFactory.Services.CreateAsyncScope();
55+
var assertionDbContext = assertionScope.ServiceProvider.GetRequiredService<DbDirectoriesContext>();
56+
var updatedUser = await assertionDbContext.Users.SingleAsync(x => x.Sub == user.Sub);
57+
Assert.Equal(expectedFirstName, updatedUser.FirstName);
58+
Assert.Equal(expectedLastName, updatedUser.LastName);
59+
60+
var auditRequest = auditMock.CapturedRequest;
61+
Assert.NotNull(auditRequest);
62+
Assert.Equal(AuditEventCategoryNames.ChangeName, auditRequest.EventCategory);
63+
Assert.Equal($"Successfully changed users name to {expectedFirstName} {expectedLastName}", auditRequest.Message);
64+
Assert.Equal(user.Sub, auditRequest.UserId);
65+
}
66+
67+
[Fact]
68+
public async Task ChangeName_Returns404_WhenUserDoesNotExist()
69+
{
70+
var authenticatedClient = this.CreateClient().WithAuthentication();
71+
72+
var request = new ChangeNameRequest {
73+
UserId = Guid.NewGuid(),
74+
FirstName = "Jane",
75+
LastName = "Smith"
76+
};
77+
78+
var response = await authenticatedClient.PostAsJsonAsync(endpoint, request);
79+
80+
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
81+
}
82+
83+
[Fact]
84+
public async Task ChangeName_Returns401_WhenUnauthenticated()
85+
{
86+
var anonymousClient = this.CreateClient();
87+
88+
var request = new ChangeNameRequest {
89+
UserId = Guid.NewGuid(),
90+
FirstName = "Jane",
91+
LastName = "Smith"
92+
};
93+
94+
var response = await anonymousClient.PostAsJsonAsync(endpoint, request);
95+
96+
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
97+
}
98+
99+
[Fact]
100+
public async Task ChangeName_DoesNotWriteAuditEvent_WhenNameIsUnchanged()
101+
{
102+
var (authenticatedClient, auditMock) = this.CreateClientWithAuditMock();
103+
104+
var firstName = "John";
105+
var lastName = "Doe";
106+
var user = EntityFaker.User
107+
.RuleFor(x => x.FirstName, (_, _) => firstName)
108+
.RuleFor(x => x.LastName, (_, _) => lastName)
109+
.Generate();
110+
111+
await this.InsertEntityAsync<DbDirectoriesContext, UserEntity>(user);
112+
113+
var request = new ChangeNameRequest {
114+
UserId = user.Sub,
115+
FirstName = firstName,
116+
LastName = lastName
117+
};
118+
119+
var response = await authenticatedClient.PostAsJsonAsync(endpoint, request);
120+
121+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
122+
123+
var body = await response.Content.ReadFromJsonAsync<InteractionResponse<ChangeNameResponse>>();
124+
Assert.NotNull(body);
125+
Assert.NotNull(body.Data);
126+
127+
await using var assertionScope = this.WebAppFactory.Services.CreateAsyncScope();
128+
var assertionDbContext = assertionScope.ServiceProvider.GetRequiredService<DbDirectoriesContext>();
129+
var updatedUser = await assertionDbContext.Users.SingleAsync(x => x.Sub == user.Sub);
130+
Assert.Equal(firstName, updatedUser.FirstName);
131+
Assert.Equal(lastName, updatedUser.LastName);
132+
133+
var auditRequest = auditMock.CapturedRequest;
134+
Assert.Null(auditRequest);
135+
}
136+
137+
[Fact]
138+
public async Task ChangeName_NormalisesWhitespaceBeforeSaving()
139+
{
140+
var (authenticatedClient, auditMock) = this.CreateClientWithAuditMock();
141+
142+
var newFirstName = "Jane Mary"; // Intentional extra spaces
143+
var expectedFirstName = "Jane Mary";
144+
var newLastName = "Smith Jones"; // Intentional extra spaces
145+
var expectedLastName = "Smith Jones";
146+
var user = EntityFaker.User.Generate();
147+
148+
await this.InsertEntityAsync<DbDirectoriesContext, UserEntity>(user);
149+
150+
var request = new ChangeNameRequest {
151+
UserId = user.Sub,
152+
FirstName = newFirstName,
153+
LastName = newLastName
154+
};
155+
156+
var response = await authenticatedClient.PostAsJsonAsync(endpoint, request);
157+
158+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
159+
160+
var body = await response.Content.ReadFromJsonAsync<InteractionResponse<ChangeNameResponse>>();
161+
Assert.NotNull(body);
162+
Assert.NotNull(body.Data);
163+
164+
await using var assertionScope = this.WebAppFactory.Services.CreateAsyncScope();
165+
var assertionDbContext = assertionScope.ServiceProvider.GetRequiredService<DbDirectoriesContext>();
166+
var updatedUser = await assertionDbContext.Users.SingleAsync(x => x.Sub == user.Sub);
167+
Assert.Equal(expectedFirstName, updatedUser.FirstName);
168+
Assert.Equal(expectedLastName, updatedUser.LastName);
169+
}
170+
171+
[Fact]
172+
public async Task ChangeName_LeavesOtherUsersUnchanged()
173+
{
174+
var (authenticatedClient, auditMock) = this.CreateClientWithAuditMock();
175+
176+
var newFirstName = "Jane";
177+
var newLastName = "Smith";
178+
var users = EntityFaker.User.Generate(3);
179+
180+
await this.InsertEntitiesAsync<DbDirectoriesContext, UserEntity>(users);
181+
182+
var userToUpdate = users[1];
183+
184+
var request = new ChangeNameRequest {
185+
UserId = userToUpdate.Sub,
186+
FirstName = newFirstName,
187+
LastName = newLastName
188+
};
189+
190+
var response = await authenticatedClient.PostAsJsonAsync(endpoint, request);
191+
192+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
193+
194+
var body = await response.Content.ReadFromJsonAsync<InteractionResponse<ChangeNameResponse>>();
195+
Assert.NotNull(body);
196+
Assert.NotNull(body.Data);
197+
198+
await using var assertionScope = this.WebAppFactory.Services.CreateAsyncScope();
199+
var assertionDbContext = assertionScope.ServiceProvider.GetRequiredService<DbDirectoriesContext>();
200+
201+
var userSubs = users.Select(u => u.Sub).ToList();
202+
var assertionUsers = await assertionDbContext.Users
203+
.Where(x => userSubs.Contains(x.Sub))
204+
.ToListAsync();
205+
206+
var updatedUser = assertionUsers.Single(x => x.Sub == userToUpdate.Sub);
207+
Assert.Equal(newFirstName, updatedUser.FirstName);
208+
Assert.Equal(newLastName, updatedUser.LastName);
209+
210+
var unchangedUsers = assertionUsers.Where(x => x.Sub != userToUpdate.Sub).ToList();
211+
foreach (var unchangedUser in unchangedUsers) {
212+
Assert.NotEqual(newFirstName, unchangedUser.FirstName);
213+
Assert.NotEqual(newLastName, unchangedUser.LastName);
214+
}
215+
}
216+
217+
[Theory]
218+
[InlineData("")]
219+
[InlineData("Jane!!!")]
220+
public async Task ChangeName_Returns400_WhenFirstNameIsInvalid(string invalidFirstName)
221+
{
222+
var (authenticatedClient, _) = this.CreateClientWithAuditMock();
223+
var user = EntityFaker.User.Generate();
224+
await this.InsertEntityAsync<DbDirectoriesContext, UserEntity>(user);
225+
226+
var request = new ChangeNameRequest {
227+
UserId = user.Sub,
228+
FirstName = invalidFirstName,
229+
LastName = "Smith"
230+
};
231+
232+
var response = await authenticatedClient.PostAsJsonAsync(endpoint, request);
233+
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
234+
}
235+
236+
[Theory]
237+
[InlineData("")]
238+
[InlineData("Smith!!!")]
239+
public async Task ChangeName_Returns400_WhenLastNameIsInvalid(string invalidLastName)
240+
{
241+
var (authenticatedClient, _) = this.CreateClientWithAuditMock();
242+
var user = EntityFaker.User.Generate();
243+
await this.InsertEntityAsync<DbDirectoriesContext, UserEntity>(user);
244+
245+
var request = new ChangeNameRequest {
246+
UserId = user.Sub,
247+
FirstName = "Jane",
248+
LastName = invalidLastName
249+
};
250+
251+
var response = await authenticatedClient.PostAsJsonAsync(endpoint, request);
252+
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
253+
}
254+
255+
[Fact]
256+
public async Task ChangeName_Returns400_WhenFirstNameExceedsMaxLength()
257+
{
258+
var (authenticatedClient, auditMock) = this.CreateClientWithAuditMock();
259+
260+
var longFirstName = new string('A', 61);
261+
var user = EntityFaker.User.Generate();
262+
263+
await this.InsertEntityAsync<DbDirectoriesContext, UserEntity>(user);
264+
265+
var request = new ChangeNameRequest {
266+
UserId = user.Sub,
267+
FirstName = longFirstName,
268+
LastName = "Smith"
269+
};
270+
271+
var response = await authenticatedClient.PostAsJsonAsync(endpoint, request);
272+
273+
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
274+
}
275+
276+
[Fact]
277+
public async Task ChangeName_Returns400_WhenLastNameExceedsMaxLength()
278+
{
279+
var (authenticatedClient, auditMock) = this.CreateClientWithAuditMock();
280+
281+
var longLastName = new string('A', 61);
282+
var user = EntityFaker.User.Generate();
283+
284+
await this.InsertEntityAsync<DbDirectoriesContext, UserEntity>(user);
285+
286+
var request = new ChangeNameRequest {
287+
UserId = user.Sub,
288+
FirstName = "Jane",
289+
LastName = longLastName
290+
};
291+
292+
var response = await authenticatedClient.PostAsJsonAsync(endpoint, request);
293+
294+
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
295+
}
296+
}

0 commit comments

Comments
 (0)