Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class SyncCorrespondenceStatusEventTests : MigrationTestBase
internal const string syncCorrespondenceStatusEventUrl = $"{migrateCorrespondenceControllerBaseUrl}/correspondence/syncStatusEvent";
private readonly Guid _defaultUserPartyUuid = new Guid("358C48B4-74A7-461F-A86F-48801DEEC920");
private readonly Guid _defaultUserUuid = new Guid("2607D808-29EC-4BD8-B89F-B9D14BDE634C");
private readonly Guid _secondUserPartyUuid = new Guid("AE985685-5D8F-45E0-AE00-240F5F5C60C5");
private readonly Guid _secondUserPartyUuid = new Guid("AE985685-5D8F-45E0-AE00-240F5F5C60C5");
private readonly Guid _secondUserUuid = new Guid("AE985685-5D8F-45E0-AE00-240F5F5C60C5");

public SyncCorrespondenceStatusEventTests(CustomWebApplicationFactory factory) : base(factory)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ public async Task NotAvailable_ReadAndConfirmed_OK()
_correspondenceStatusRepositoryMock
.Setup(x => x.AddCorrespondenceStatus(It.IsAny<CorrespondenceStatusEntity>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(Guid.NewGuid());
_altinnRegisterServiceMock
.Setup(x => x.LookUpPartyByPartyUuid(_defaultUserPartyUuid, It.IsAny<CancellationToken>()))
.ReturnsAsync(new Party { PartyUuid = _defaultUserPartyUuid, SSN = _defaultUserPartySSN, PartyTypeName = PartyType.Person });

// Act
var result = await _handler.Process(request, null, CancellationToken.None);
Expand Down Expand Up @@ -237,6 +240,10 @@ public async Task NotAvailable_SecondReadSameTime_HandledAsDuplicate()
_correspondenceRepositoryMock
.Setup(x => x.GetCorrespondenceByIdForSync(correspondenceId, CorrespondenceSyncType.StatusEvents, It.IsAny<CancellationToken>()))
.ReturnsAsync(correspondence);
_altinnRegisterServiceMock
.Setup(x => x.LookUpPartyByPartyUuid(_defaultUserPartyUuid, It.IsAny<CancellationToken>()))
.ReturnsAsync(new Party { PartyUuid = _defaultUserPartyUuid, SSN = _defaultUserPartySSN, PartyTypeName = PartyType.Person });

// Act
var result = await _handler.Process(request, null, CancellationToken.None);

Expand Down Expand Up @@ -431,6 +438,9 @@ public async Task NotAvailable_SecondRead2SecondsLater_Updated()
_correspondenceStatusRepositoryMock
.Setup(x => x.AddCorrespondenceStatus(It.IsAny<CorrespondenceStatusEntity>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(Guid.NewGuid());
_altinnRegisterServiceMock
.Setup(x => x.LookUpPartyByPartyUuid(_defaultUserPartyUuid, It.IsAny<CancellationToken>()))
.ReturnsAsync(new Party { PartyUuid = _defaultUserPartyUuid, SSN = _defaultUserPartySSN, PartyTypeName = PartyType.Person });

// Act
var result = await _handler.Process(request, null, CancellationToken.None);
Expand Down Expand Up @@ -461,7 +471,7 @@ public async Task NotAvailable_SecondRead2SecondsLater_Updated()
}

[Fact]
public async Task Available_ReadAndConfirmed_OK()
public async Task Available_ReadAndConfirmedByOtherUser_OK()
{
// Arrange
var correspondence = new CorrespondenceEntityBuilder()
Expand All @@ -471,6 +481,9 @@ public async Task Available_ReadAndConfirmed_OK()
.Build();
var correspondenceId = correspondence.Id;
var recipient = correspondence.Recipient;
Guid otherUserPartyUuid = Guid.NewGuid();
string otherUserSSN = "13018054321";
string otherUserPartyIdentifier = $"{UrnConstants.PersonIdAttribute}:{otherUserSSN}";
DateTimeOffset readTime = DateTimeOffset.UtcNow;
DateTimeOffset confirmedTime = DateTimeOffset.UtcNow;
var request = new SyncCorrespondenceStatusEventRequest
Expand All @@ -482,13 +495,13 @@ public async Task Available_ReadAndConfirmed_OK()
{
Status = CorrespondenceStatus.Read,
StatusChanged = readTime,
PartyUuid = _defaultUserPartyUuid
PartyUuid = otherUserPartyUuid
},
new CorrespondenceStatusEntity
{
Status = CorrespondenceStatus.Confirmed,
StatusChanged = confirmedTime,
PartyUuid = _defaultUserPartyUuid
PartyUuid = otherUserPartyUuid
}
}
};
Expand All @@ -500,6 +513,9 @@ public async Task Available_ReadAndConfirmed_OK()
_correspondenceStatusRepositoryMock
.Setup(x => x.AddCorrespondenceStatus(It.IsAny<CorrespondenceStatusEntity>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(Guid.NewGuid());
_altinnRegisterServiceMock
.Setup(x => x.LookUpPartyByPartyUuid(otherUserPartyUuid, It.IsAny<CancellationToken>()))
.ReturnsAsync(new Party { PartyUuid = otherUserPartyUuid, SSN = otherUserSSN, PartyTypeName = PartyType.Person });

// Act
var result = await _handler.Process(request, null, CancellationToken.None);
Expand All @@ -519,7 +535,7 @@ public async Task Available_ReadAndConfirmed_OK()
e.CorrespondenceId == correspondenceId &&
e.Status == CorrespondenceStatus.Read &&
e.StatusChanged == readTime &&
e.PartyUuid == _defaultUserPartyUuid &&
e.PartyUuid == otherUserPartyUuid &&
e.SyncedFromAltinn2 != null),
It.IsAny<CancellationToken>()),
Times.Once);
Expand All @@ -528,7 +544,7 @@ public async Task Available_ReadAndConfirmed_OK()
e.CorrespondenceId == correspondenceId &&
e.Status == CorrespondenceStatus.Confirmed &&
e.StatusChanged == confirmedTime &&
e.PartyUuid == _defaultUserPartyUuid &&
e.PartyUuid == otherUserPartyUuid &&
e.SyncedFromAltinn2 != null),
It.IsAny<CancellationToken>()),
Times.Once);
Expand All @@ -538,9 +554,9 @@ public async Task Available_ReadAndConfirmed_OK()
VerifyAltinnEventEnqueued(correspondenceId, AltinnEventType.CorrespondenceReceiverRead, recipient);
VerifyAltinnEventEnqueued(correspondenceId, AltinnEventType.CorrespondenceReceiverConfirmed, recipient);
// Verify background jobs Dialogporten activities
VerifyDialogportenServiceCreateInformationActivityEnqueued(correspondenceId, DialogportenActorType.Recipient, DialogportenTextType.CorrespondenceConfirmed, recipient);
VerifyDialogportenServiceCreateConfirmedActivityEnqueued(correspondenceId, DialogportenActorType.Recipient, otherUserPartyIdentifier);
VerifyDialogportenServicePatchCorrespondenceDialogToConfirmedEnqueued(correspondenceId);
VerifyDialogportenServiceCreateOpenedActivityEnqueued(correspondenceId);
VerifyDialogportenServiceCreateOpenedActivityEnqueued(correspondenceId, otherUserPartyIdentifier);

// Should not trigger any additional Dialogporten changes or background jobs
_backgroundJobClientMock.VerifyNoOtherCalls();
Expand Down Expand Up @@ -1556,6 +1572,8 @@ public async Task Available_ReadAndConfirmed_ReversedOrderInRequest_OK()
var recipient = correspondence.Recipient;
DateTimeOffset readTime = DateTimeOffset.UtcNow.AddSeconds(-30);
DateTimeOffset confirmedTime = DateTimeOffset.UtcNow;

// urn:altinn:person:identifier-no:12018012345
var request = new SyncCorrespondenceStatusEventRequest
{
CorrespondenceId = correspondenceId,
Expand Down Expand Up @@ -1583,6 +1601,9 @@ public async Task Available_ReadAndConfirmed_ReversedOrderInRequest_OK()
_correspondenceStatusRepositoryMock
.Setup(x => x.AddCorrespondenceStatus(It.IsAny<CorrespondenceStatusEntity>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(Guid.NewGuid());
_altinnRegisterServiceMock
.Setup(x => x.LookUpPartyByPartyUuid(_defaultUserPartyUuid, It.IsAny<CancellationToken>()))
.ReturnsAsync(new Party { PartyUuid = _defaultUserPartyUuid, SSN = _defaultUserPartySSN, PartyTypeName = PartyType.Person });

// Act
var result = await _handler.Process(request, null, CancellationToken.None);
Expand Down Expand Up @@ -1611,9 +1632,9 @@ public async Task Available_ReadAndConfirmed_ReversedOrderInRequest_OK()
VerifyAltinnEventEnqueued(correspondenceId, AltinnEventType.CorrespondenceReceiverRead, recipient);
VerifyAltinnEventEnqueued(correspondenceId, AltinnEventType.CorrespondenceReceiverConfirmed, recipient);
// Verify background jobs Dialogporten activities
VerifyDialogportenServiceCreateInformationActivityEnqueued(correspondenceId, DialogportenActorType.Recipient, DialogportenTextType.CorrespondenceConfirmed, recipient);
VerifyDialogportenServicePatchCorrespondenceDialogToConfirmedEnqueued(correspondenceId);
VerifyDialogportenServiceCreateOpenedActivityEnqueued(correspondenceId);
VerifyDialogportenServiceCreateConfirmedActivityEnqueued(correspondenceId, DialogportenActorType.Recipient, _defaultUserPartyIdentifier);
VerifyDialogportenServiceCreateOpenedActivityEnqueued(correspondenceId, _defaultUserPartyIdentifier);

// Should not trigger any additional Dialogporten changes or background jobs
_backgroundJobClientMock.VerifyNoOtherCalls();
Expand Down Expand Up @@ -2117,17 +2138,10 @@ private void VerifyStorageDeletionScheduled()
It.Is<Job>(job => job.Method.Name == nameof(IStorageRepository.PurgeAttachment)), It.IsAny<EnqueuedState>()));
}

private void VerifyDialogportenServiceCreateInformationActivityEnqueued(Guid correspondenceId, DialogportenActorType actorType, DialogportenTextType dpTextType, string recipient)
{
_backgroundJobClientMock.Verify(x => x.Create(
It.Is<Job>(job => job.Method.Name == nameof(IDialogportenService.CreateConfirmedActivity) && (Guid)job.Args[0] == correspondenceId && (DialogportenActorType)job.Args[1] == actorType),
It.IsAny<IState>()));
}

private void VerifyDialogportenServiceCreateConfirmedActivityEnqueued(Guid correspondenceId, DialogportenActorType actorType, string recipient)
private void VerifyDialogportenServiceCreateConfirmedActivityEnqueued(Guid correspondenceId, DialogportenActorType actorType, string partyUrn)
{
_backgroundJobClientMock.Verify(x => x.Create(
It.Is<Job>(job => job.Method.Name == nameof(IDialogportenService.CreateConfirmedActivity) && (Guid)job.Args[0] == correspondenceId && (DialogportenActorType)job.Args[1] == actorType),
It.Is<Job>(job => job.Method.Name == nameof(IDialogportenService.CreateConfirmedActivity) && (Guid)job.Args[0] == correspondenceId && (DialogportenActorType)job.Args[1] == actorType && (string)job.Args[3] == partyUrn),
It.IsAny<IState>()));
}

Expand Down Expand Up @@ -2186,10 +2200,10 @@ private void VerifySoftDeleteUpdateForDialogportenEnqueued(Guid correspondenceId
}
}

private void VerifyDialogportenServiceCreateOpenedActivityEnqueued(Guid correspondenceId)
private void VerifyDialogportenServiceCreateOpenedActivityEnqueued(Guid correspondenceId, string partyUrn)
{
_backgroundJobClientMock.Verify(x => x.Create(
It.Is<Job>(job => job.Method.Name == nameof(IDialogportenService.CreateOpenedActivity) && (Guid)job.Args[0] == correspondenceId),
It.Is<Job>(job => job.Method.Name == nameof(IDialogportenService.CreateOpenedActivity) && (Guid)job.Args[0] == correspondenceId && (string)job.Args[3] == partyUrn),
It.IsAny<EnqueuedState>()));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,29 @@ private async Task ProcessStatusEvent(SyncCorrespondenceStatusEventRequest reque
case CorrespondenceStatus.Confirmed:
{
var patchJobId = backgroundJobClient.Enqueue<IDialogportenService>((dialogportenService) => dialogportenService.PatchCorrespondenceDialogToConfirmed(request.CorrespondenceId, CancellationToken.None));
backgroundJobClient.ContinueJobWith<IDialogportenService>(patchJobId, (dialogportenService) => dialogportenService.CreateConfirmedActivity(request.CorrespondenceId, DialogportenActorType.Recipient, eventToExecute.StatusChanged), JobContinuationOptions.OnlyOnSucceededState); // Set the operationtime to the time the status was changed in Altinn 2
if (!enduserIdByPartyUuid.TryGetValue(eventToExecute.PartyUuid, out var endUserId))
{
logger.LogWarning("Skipping updating dialog for Confirm for correspondence {CorrespondenceId} at {StatusChanged} due to missing Dialogporten enduserId for party {PartyUuid}.", correspondence.Id, eventToExecute.StatusChanged, eventToExecute.PartyUuid);
}
else
{
backgroundJobClient.ContinueJobWith<IDialogportenService>(patchJobId, (dialogportenService) => dialogportenService.CreateConfirmedActivity(request.CorrespondenceId, DialogportenActorType.Recipient, eventToExecute.StatusChanged, endUserId), JobContinuationOptions.OnlyOnSucceededState); // Set the operationtime to the time the status was changed in Altinn 2
}
backgroundJobClient.Enqueue<IEventBus>((eventBus) => eventBus.Publish(AltinnEventType.CorrespondenceReceiverConfirmed, correspondence.ResourceId, correspondence.Id.ToString(), "correspondence", correspondence.Sender, CancellationToken.None));
break;
}

case CorrespondenceStatus.Read:
{
backgroundJobClient.Enqueue<IDialogportenService>((dialogportenService) => dialogportenService.CreateOpenedActivity(correspondence.Id, DialogportenActorType.Recipient, eventToExecute.StatusChanged));

if (!enduserIdByPartyUuid.TryGetValue(eventToExecute.PartyUuid, out var endUserId))
{
logger.LogWarning("Skipping updating dialog for Read for correspondence {CorrespondenceId} at {StatusChanged} due to missing Dialogporten enduserId for party {PartyUuid}.", correspondence.Id, eventToExecute.StatusChanged, eventToExecute.PartyUuid);
}
else
{
backgroundJobClient.Enqueue<IDialogportenService>((dialogportenService) => dialogportenService.CreateOpenedActivity(correspondence.Id, DialogportenActorType.Recipient, eventToExecute.StatusChanged, endUserId));
}
backgroundJobClient.Enqueue<IEventBus>((eventBus) => eventBus.Publish(AltinnEventType.CorrespondenceReceiverRead, correspondence.ResourceId, correspondence.Id.ToString(), "correspondence", correspondence.Sender, CancellationToken.None));
break;
}
Expand Down Expand Up @@ -303,7 +318,7 @@ private async Task<Dictionary<Guid, string>> GetDialogPortenEndUserIdsForEvents(
var enduserIdByPartyUuid = new Dictionary<Guid, string>();

var partyUuidsToLookup = (statusEventsToExecute ?? Enumerable.Empty<CorrespondenceStatusEntity>())
.Where(e => e.Status == CorrespondenceStatus.Archived) // Only Archived status events require Dialogporten enduserId
.Where(e => e.Status == CorrespondenceStatus.Read || e.Status == CorrespondenceStatus.Confirmed || e.Status == CorrespondenceStatus.Archived) // Only Read, Confirm, Archived status events require Dialogporten enduserId/urn
.Select(e => e.PartyUuid)
.Distinct();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ public class AltinnRegisterDevService : IAltinnRegisterService
private readonly Guid _digdirPartyUuid = new Guid("36E2BCC6-D5B8-4399-AA90-4AFEB2D1A0BF");
private readonly int _delegatedUserPartyid = 100;
private readonly Guid _delegatedUserPartyUuid = new Guid("358C48B4-74A7-461F-A86F-48801DEEC920");

private readonly int _secondUserPartyId = 200;
private readonly Guid _secondUserPartyUuid = new Guid("AE985685-5D8F-45E0-AE00-240F5F5C60C5");

public Task<int?> LookUpPartyId(string identificationId, CancellationToken cancellationToken)
{
if (IdentificationIDRegex.IsMatch(identificationId.WithoutPrefix()))
Expand Down Expand Up @@ -116,6 +118,20 @@ public class AltinnRegisterDevService : IAltinnRegisterService
PartyUuid = _delegatedUserPartyUuid,
};
}
else if (partyUuid == _secondUserPartyUuid)
{
party = new Party
{
PartyId = _secondUserPartyId,
OrgNumber = "",
SSN = "01027845678",
Resources = new List<string>(),
PartyTypeName = PartyType.Person,
UnitType = "Person",
Name = "Annen test bruker",
PartyUuid = _secondUserPartyUuid,
};
}

return Task.FromResult<Party?>(party);
}
Expand Down
Loading