Skip to content

Commit

Permalink
Fixed reliability of notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
jezzsantos committed Apr 18, 2024
1 parent 8526735 commit 6bb8c06
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 12 deletions.
6 changes: 2 additions & 4 deletions src/EndUsersApplication/EndUsersApplication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,8 @@ public async Task<Result<RegisteredEndUser, Error>> RegisterPersonAsync(ICallerC
}

var notified = await _notificationsService.NotifyReRegistrationCourtesyAsync(context,
unregisteredUser.Id,
unregisteredUserProfile.EmailAddress, unregisteredUserProfile.DisplayName,
unregisteredUserProfile.Timezone, unregisteredUserProfile.Address.CountryCode,
cancellationToken);
unregisteredUser.Id, unregisteredUserProfile.EmailAddress, unregisteredUserProfile.DisplayName,
unregisteredUserProfile.Timezone, unregisteredUserProfile.Address.CountryCode, cancellationToken);
if (!notified.IsSuccessful)
{
return notified.Error;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,53 @@ public async Task WhenRegisterPersonAsyncAndAlreadyExists_ThenDoesNothing()
It.IsAny<CancellationToken>()));
}

[Fact]
public async Task WhenAuthenticateAsyncAndSendingEmailFails_ThenReturnsError()
{
var registeredAccount = new RegisteredEndUser
{
Id = "auserid",
Profile = new UserProfileWithDefaultMembership
{
Id = "anid",
UserId = "auserid",
Classification = UserProfileClassification.Person,
Name = new PersonName
{
FirstName = "aname"
},
DisplayName = "adisplayname",
EmailAddress = "[email protected]"
}
};
_endUsersService.Setup(uas => uas.RegisterPersonPrivateAsync(It.IsAny<ICallerContext>(),
It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<bool>(), It.IsAny<CancellationToken>()))
.Returns(Task.FromResult<Result<RegisteredEndUser, Error>>(registeredAccount));
_repository.Setup(s => s.FindCredentialsByUserIdAsync(It.IsAny<Identifier>(), It.IsAny<CancellationToken>()))
.Returns(Task.FromResult<Result<Optional<PasswordCredentialRoot>, Error>>(Optional<PasswordCredentialRoot>
.None));
_notificationsService.Setup(ns =>
ns.NotifyPasswordRegistrationConfirmationAsync(It.IsAny<ICallerContext>(), It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(Error.Unexpected());

var result = await _application.RegisterPersonAsync(_caller.Object, "aninvitationtoken", "afirstname",
"alastname", "[email protected]", "apassword", "atimezone", "acountrycode", true, CancellationToken.None);

result.Should().BeError(ErrorCode.Unexpected);
_repository.Verify(s => s.SaveAsync(It.IsAny<PasswordCredentialRoot>(), It.IsAny<CancellationToken>()),
Times.Never);
_notificationsService.Verify(ns =>
ns.NotifyPasswordRegistrationConfirmationAsync(_caller.Object, "[email protected]", "adisplayname",
"averificationtoken", It.IsAny<CancellationToken>()));
_endUsersService.Verify(eus => eus.RegisterPersonPrivateAsync(_caller.Object, "aninvitationtoken",
"[email protected]", "afirstname", "alastname", "atimezone", "acountrycode", true,
It.IsAny<CancellationToken>()));
}

[Fact]
public async Task WhenRegisterPersonAsyncAndNotExists_ThenCreatesAndSendsConfirmation()
{
Expand Down
21 changes: 13 additions & 8 deletions src/IdentityApplication/PasswordCredentialsApplication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -321,19 +321,24 @@ private async Task<Result<PasswordCredential, Error>> RegisterPersonInternalAsyn
return initiated.Error;
}

var updated = await _repository.SaveAsync(credentials, cancellationToken);
if (!updated.IsSuccessful)
var notified = await _notificationsService.NotifyPasswordRegistrationConfirmationAsync(context,
credentials.Registration.Value.EmailAddress,
credentials.Registration.Value.Name, credentials.Verification.Token, cancellationToken);
if (!notified.IsSuccessful)
{
return updated.Error;
return notified.Error;
}

await _notificationsService.NotifyPasswordRegistrationConfirmationAsync(context,
updated.Value.Registration.Value.EmailAddress,
updated.Value.Registration.Value.Name, updated.Value.Verification.Token, cancellationToken);
var saved = await _repository.SaveAsync(credentials, cancellationToken);
if (!saved.IsSuccessful)
{
return saved.Error;
}

_recorder.TraceInformation(context.ToCall(), "Password credentials created for {UserId}", updated.Value.UserId);
credentials = saved.Value;
_recorder.TraceInformation(context.ToCall(), "Password credentials created for {UserId}", credentials.UserId);

return updated.Value.ToCredential(user);
return credentials.ToCredential(user);
}

/// <summary>
Expand Down
6 changes: 6 additions & 0 deletions src/SaaStack.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -330,13 +330,19 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Method/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="When" Suffix="" Style="AaBb_AaBb"&gt;&lt;ExtraRule Prefix="" Suffix="" Style="AaBb" /&gt;&lt;ExtraRule Prefix="Setup" Suffix="" Style="AaBb" /&gt;&lt;ExtraRule Prefix="Configure" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Property/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"&gt;&lt;ExtraRule Prefix="Configure" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=76f79b1e_002Dece7_002D4df2_002Da322_002D1bd7fea25eb7/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Any" Description="Local functions"&gt;&lt;ElementKinds&gt;&lt;Kind Name="LOCAL_FUNCTION" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"&gt;&lt;ExtraRule Prefix="Configure" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=8284009d_002De743_002D4d89_002D9402_002Da5bf9a89b657/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Any" Description="Methods"&gt;&lt;ElementKinds&gt;&lt;Kind Name="METHOD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="When" Suffix="" Style="AaBb_AaBb"&gt;&lt;ExtraRule Prefix="" Suffix="" Style="AaBb" /&gt;&lt;ExtraRule Prefix="Setup" Suffix="" Style="AaBb" /&gt;&lt;ExtraRule Prefix="Configure" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=8b8504e3_002Df0be_002D4c14_002D9103_002Dc732f2bddc15/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Any" Description="Enum members"&gt;&lt;ElementKinds&gt;&lt;Kind Name="ENUM_MEMBER" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"&gt;&lt;ExtraRule Prefix="" Suffix="" Style="AaBb_AaBb" /&gt;&lt;/Policy&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=a0b4bc4d_002Dd13b_002D4a37_002Db37e_002Dc9c6864e4302/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Any" Description="Types and namespaces"&gt;&lt;ElementKinds&gt;&lt;Kind Name="NAMESPACE" /&gt;&lt;Kind Name="CLASS" /&gt;&lt;Kind Name="STRUCT" /&gt;&lt;Kind Name="ENUM" /&gt;&lt;Kind Name="DELEGATE" /&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/=c85a0503_002D4de2_002D40f1_002D9cd6_002Da4054c05d384/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Any" Description="Properties"&gt;&lt;ElementKinds&gt;&lt;Kind Name="PROPERTY" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"&gt;&lt;ExtraRule Prefix="Configure" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;&lt;/Policy&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/Filtering/FileMasksToExclude/=src_002FApplication_002EInterfaces_002FResources_002F_002A_002E_002A/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/Filtering/FileMasksToExclude/=src_002FCommon_002FAnnotations_002Ecs/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/Filtering/HideAutoProperties/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<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_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:Int64 x:Key="/Default/Environment/UnitTesting/ParallelProcessesCount/@EntryValue">10</s:Int64>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/QuickList/=F0CA621CDF5AB24282D8CDC11C520997/@KeyIndexDefined">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/QuickList/=F0CA621CDF5AB24282D8CDC11C520997/Entry/=0F0850FC1FE1104DB503D10E2A76D620/@KeyIndexDefined">True</s:Boolean>
Expand Down

0 comments on commit 6bb8c06

Please sign in to comment.