mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 04:53:11 +00:00
feat(team-members): report whether the re-invite after an email change was emailed
This commit is contained in:
parent
f491d4c721
commit
b50cd5f5df
3 changed files with 26 additions and 4 deletions
|
|
@ -25,7 +25,10 @@ public class TeamMemberCreatedDTO
|
|||
public required IReadOnlyList<string> ServiceAreas { get; init; }
|
||||
public bool PendingRegistration { get; init; }
|
||||
|
||||
/// <summary>Set only on create: false means the member exists but the invite email failed; re-invite from their details.</summary>
|
||||
/// <summary>
|
||||
/// Set only when an invite was emailed: on create, and on an update that changed a pending member's email.
|
||||
/// False means the invite email failed; re-invite from their details.
|
||||
/// </summary>
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public bool? InviteEmailSent { get; init; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -239,10 +239,11 @@ public sealed class TeamMemberService : ITeamMemberService
|
|||
}
|
||||
|
||||
// An invite sent to the old address, and any code confirmed through it, must not register the new one.
|
||||
bool? inviteEmailSent = null;
|
||||
if (emailChanged && user.PendingRegistration == true)
|
||||
await _inviteService.ReissueAsync(user, cancellationToken);
|
||||
inviteEmailSent = await _inviteService.ReissueAsync(user, cancellationToken);
|
||||
|
||||
return await OperationSuccessAsync(user, caller, cancellationToken);
|
||||
return await OperationSuccessAsync(user, caller, cancellationToken, inviteEmailSent);
|
||||
}
|
||||
|
||||
private static void ApplyName(ApplicationUser user, string fullName)
|
||||
|
|
@ -277,7 +278,8 @@ public sealed class TeamMemberService : ITeamMemberService
|
|||
private async Task<TeamMemberOperationOutcomeDTO> OperationSuccessAsync(
|
||||
ApplicationUser user,
|
||||
ClaimsPrincipal caller,
|
||||
CancellationToken cancellationToken)
|
||||
CancellationToken cancellationToken,
|
||||
bool? inviteEmailSent = null)
|
||||
{
|
||||
var roles = await _userManager.GetRolesAsync(user);
|
||||
var profile = await _permissionService.GetProfileAsync(user.Id, caller, cancellationToken);
|
||||
|
|
@ -295,6 +297,7 @@ public sealed class TeamMemberService : ITeamMemberService
|
|||
Phone = user.Contact ?? user.PhoneNumber,
|
||||
ServiceAreas = areas,
|
||||
PendingRegistration = user.PendingRegistration == true,
|
||||
InviteEmailSent = inviteEmailSent,
|
||||
Status = user.UniqueName ?? "Active",
|
||||
IsAccountOwner = user.IsAccountOwner,
|
||||
Permissions = profile?.Value?.Permissions ?? Array.Empty<TeamPermissionValueDTO>()
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ public sealed class TeamMemberInviteLifecycleTests
|
|||
|
||||
var updated = await UpdateAsync(host, userId, CorrectedEmail, role: "admin");
|
||||
Assert.True(updated.Success, updated.Error);
|
||||
Assert.True(updated.Member!.InviteEmailSent);
|
||||
|
||||
Assert.Equal(TeamMemberRegistrationStatus.InvalidInvite,
|
||||
(await host.RegistrationAsync(service => service.ResolveAsync(oldToken, CancellationToken.None))).Status);
|
||||
|
|
@ -59,6 +60,20 @@ public sealed class TeamMemberInviteLifecycleTests
|
|||
Assert.Equal(TeamMemberRegistrationStatus.Ok, (await CompleteAsync(host, newToken)).Status);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ChangingAPendingMembersEmail_ReportsWhenTheNewInviteCouldNotBeEmailed()
|
||||
{
|
||||
await using var host = await TeamMemberInviteTestHost.CreateAsync();
|
||||
var (userId, _) = await host.AddPendingMemberAsync(Email);
|
||||
host.Sent.Succeeds = false;
|
||||
|
||||
var updated = await UpdateAsync(host, userId, CorrectedEmail, role: "dispatcher");
|
||||
|
||||
Assert.True(updated.Success, updated.Error);
|
||||
Assert.Equal(CorrectedEmail, updated.Member!.Email);
|
||||
Assert.False(updated.Member.InviteEmailSent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task EditingAPendingMemberWithoutChangingTheirEmail_KeepsTheirInvite()
|
||||
{
|
||||
|
|
@ -69,6 +84,7 @@ public sealed class TeamMemberInviteLifecycleTests
|
|||
var updated = await UpdateAsync(host, userId, Email.ToUpperInvariant(), role: "dispatcher");
|
||||
|
||||
Assert.True(updated.Success, updated.Error);
|
||||
Assert.Null(updated.Member!.InviteEmailSent);
|
||||
Assert.Equal(emailsBefore, host.Sent.Messages.Count);
|
||||
var invite = Assert.Single(await host.InvitesAsync(userId));
|
||||
Assert.Null(invite.RevokedAt);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue