From 9cf79d837d28632316b398eef036b04991e582e3 Mon Sep 17 00:00:00 2001 From: Joshua Hawxwell Date: Thu, 30 Jan 2025 12:50:00 +0000 Subject: [PATCH] Handle priority-correspondence-sent --- cmd/event-received/sirius_event_handler.go | 28 +++++++ .../sirius_event_handler_test.go | 74 +++++++++++++++++++ .../donor/you-cannot-sign-your-lpa-yet.cy.js | 12 ++- internal/donor/donordata/provided.go | 7 +- internal/donor/donordata/provided_test.go | 4 +- internal/donor/donorpage/progress.go | 10 +++ internal/donor/donorpage/progress_test.go | 26 +++++++ 7 files changed, 154 insertions(+), 7 deletions(-) diff --git a/cmd/event-received/sirius_event_handler.go b/cmd/event-received/sirius_event_handler.go index f92133a323..2c44fb9288 100644 --- a/cmd/event-received/sirius_event_handler.go +++ b/cmd/event-received/sirius_event_handler.go @@ -73,6 +73,9 @@ func (h *siriusEventHandler) Handle(ctx context.Context, factory factory, cloudW case "certificate-provider-submission-completed": return handleCertificateProviderSubmissionCompleted(ctx, cloudWatchEvent, factory) + case "priority-correspondence-sent": + return handlePriorityCorrespondenceSent(ctx, factory.DynamoClient(), cloudWatchEvent, factory.Now()) + default: return fmt.Errorf("unknown sirius event") } @@ -316,3 +319,28 @@ func handleCertificateProviderSubmissionCompleted(ctx context.Context, event *ev return nil } + +type priorityCorrespondenceSentEvent struct { + UID string `json:"uid"` + SentDate time.Time `json:"sentDate"` +} + +func handlePriorityCorrespondenceSent(ctx context.Context, client dynamodbClient, event *events.CloudWatchEvent, now func() time.Time) error { + var v priorityCorrespondenceSentEvent + if err := json.Unmarshal(event.Detail, &v); err != nil { + return fmt.Errorf("failed to unmarshal detail: %w", err) + } + + donor, err := getDonorByLpaUID(ctx, client, v.UID) + if err != nil { + return fmt.Errorf("failed to get lpa: %w", err) + } + + donor.PriorityCorrespondenceSentAt = v.SentDate + + if err := putDonor(ctx, donor, now, client); err != nil { + return fmt.Errorf("failed to update lpa: %w", err) + } + + return nil +} diff --git a/cmd/event-received/sirius_event_handler_test.go b/cmd/event-received/sirius_event_handler_test.go index f74762d4ce..bd3076f44f 100644 --- a/cmd/event-received/sirius_event_handler_test.go +++ b/cmd/event-received/sirius_event_handler_test.go @@ -1332,3 +1332,77 @@ func TestHandleCertificateProviderSubmissionCompletedWhenAppDataFactoryErrors(t err := handler.Handle(ctx, factory, certificateProviderSubmissionCompletedEvent) assert.Equal(t, expectedError, err) } + +func TestHandlePriorityCorrespondenceSent(t *testing.T) { + event := &events.CloudWatchEvent{ + DetailType: "priority-correspondence-sent", + Detail: json.RawMessage(`{"uid":"M-1111-2222-3333","sentAt":"2024-01-18T00:00:00.000Z"}`), + } + + updated := &donordata.Provided{PK: dynamo.LpaKey("123"), SK: dynamo.LpaOwnerKey(dynamo.DonorKey("456")), UpdatedAt: testNow} + updated.UpdateHash() + + client := newMockDynamodbClient(t) + client.EXPECT(). + OneByUID(ctx, "M-1111-2222-3333", mock.Anything). + Return(nil). + SetData(dynamo.Keys{PK: dynamo.LpaKey("123"), SK: dynamo.DonorKey("456")}) + client.EXPECT(). + One(ctx, dynamo.LpaKey("123"), dynamo.DonorKey("456"), mock.Anything). + Return(nil). + SetData(donordata.Provided{PK: dynamo.LpaKey("123"), SK: dynamo.LpaOwnerKey(dynamo.DonorKey("456"))}) + client.EXPECT(). + Put(ctx, updated). + Return(nil) + + factory := newMockFactory(t) + factory.EXPECT(). + DynamoClient(). + Return(client) + factory.EXPECT(). + Now(). + Return(testNowFn) + + handler := &siriusEventHandler{} + err := handler.Handle(ctx, factory, event) + + assert.Nil(t, err) +} + +func TestHandlePriorityCorrespondenceSentWhenGetError(t *testing.T) { + event := &events.CloudWatchEvent{ + DetailType: "priority-correspondence-sent", + Detail: json.RawMessage(`{"uid":"M-1111-2222-3333","sentAt":"2024-01-18T00:00:00.000Z"}`), + } + + client := newMockDynamodbClient(t) + client.EXPECT(). + OneByUID(ctx, "M-1111-2222-3333", mock.Anything). + Return(expectedError) + + err := handlePriorityCorrespondenceSent(ctx, client, event, testNowFn) + assert.ErrorIs(t, err, expectedError) +} + +func TestHandlePriorityCorrespondenceSentWhenPutError(t *testing.T) { + event := &events.CloudWatchEvent{ + DetailType: "priority-correspondence-sent", + Detail: json.RawMessage(`{"uid":"M-1111-2222-3333","sentAt":"2024-01-18T00:00:00.000Z"}`), + } + + client := newMockDynamodbClient(t) + client.EXPECT(). + OneByUID(ctx, "M-1111-2222-3333", mock.Anything). + Return(nil). + SetData(dynamo.Keys{PK: dynamo.LpaKey("123"), SK: dynamo.DonorKey("456")}) + client.EXPECT(). + One(ctx, dynamo.LpaKey("123"), dynamo.DonorKey("456"), mock.Anything). + Return(nil). + SetData(donordata.Provided{PK: dynamo.LpaKey("123"), SK: dynamo.LpaOwnerKey(dynamo.DonorKey("456"))}) + client.EXPECT(). + Put(ctx, mock.Anything). + Return(expectedError) + + err := handlePriorityCorrespondenceSent(ctx, client, event, testNowFn) + assert.ErrorIs(t, err, expectedError) +} diff --git a/cypress/e2e/donor/you-cannot-sign-your-lpa-yet.cy.js b/cypress/e2e/donor/you-cannot-sign-your-lpa-yet.cy.js index f28ed6e620..4004960cb4 100644 --- a/cypress/e2e/donor/you-cannot-sign-your-lpa-yet.cy.js +++ b/cypress/e2e/donor/you-cannot-sign-your-lpa-yet.cy.js @@ -4,13 +4,15 @@ describe('You cannot sign your LPA yet', () => { cy.visit('/fixtures?redirect=/choose-attorneys-summary&progress=peopleToNotifyAboutYourLpa'); cy.contains('.govuk-summary-card', 'Jessie Jones').contains('a', 'Change').click(); - cy.get('#f-date-of-birth-year').clear().type(today.getFullYear() - 1) + cy.get('#f-date-of-birth-year').clear(); + cy.get('#f-date-of-birth-year').type(today.getFullYear() - 1); cy.contains('button', 'Save and continue').click() cy.contains('button', 'Save and continue').click() cy.visitLpa('/choose-replacement-attorneys-summary') cy.contains('.govuk-summary-card', 'Blake Buckley').contains('a', 'Change').click(); - cy.get('#f-date-of-birth-year').clear().type(today.getFullYear() - 1) + cy.get('#f-date-of-birth-year').clear(); + cy.get('#f-date-of-birth-year').type(today.getFullYear() - 1); cy.contains('button', 'Save and continue').click() cy.contains('button', 'Save and continue').click() cy.contains('a', 'Return to task list').click() @@ -22,14 +24,16 @@ describe('You cannot sign your LPA yet', () => { cy.contains('.govuk-summary-list__row', 'Jessie Jones').contains('a', 'Change').click(); cy.url().should('contain', '/choose-attorneys') - cy.get('#f-date-of-birth-year').clear().type("2000") + cy.get('#f-date-of-birth-year').clear(); + cy.get('#f-date-of-birth-year').type("2000"); cy.contains('button', 'Save and continue').click() cy.url().should('contain', '/you-cannot-sign-your-lpa-yet') cy.contains('.govuk-summary-list__row', 'Blake Buckley').contains('a', 'Change').click(); cy.url().should('contain', '/choose-replacement-attorneys') - cy.get('#f-date-of-birth-year').clear().type("2000") + cy.get('#f-date-of-birth-year').clear(); + cy.get('#f-date-of-birth-year').type("2000"); cy.contains('button', 'Save and continue').click() cy.url().should('contain', '/task-list') }); diff --git a/internal/donor/donordata/provided.go b/internal/donor/donordata/provided.go index fb881a6aeb..a104ae3283 100644 --- a/internal/donor/donordata/provided.go +++ b/internal/donor/donordata/provided.go @@ -181,9 +181,14 @@ type Provided struct { // VoucherInvitedAt records when the invite is sent to the voucher to vouch. VoucherInvitedAt time.Time `checkhash:"-"` - // MoreEvidenceRequiredAt records when a request for further information on an exemption/remission was received. + // MoreEvidenceRequiredAt records when a request for further information on an + // exemption/remission was received. MoreEvidenceRequiredAt time.Time `checkhash:"-"` + // PriorityCorrespondenceSentAt records when a caseworker sent a letter to the + // donor informing them of a problem. + PriorityCorrespondenceSentAt time.Time `checkhash:"-"` + // HasSeenSuccessfulVouchBanner records if the donor has seen the progress tracker successful vouch banner HasSeenSuccessfulVouchBanner bool `checkhash:"-"` diff --git a/internal/donor/donordata/provided_test.go b/internal/donor/donordata/provided_test.go index 64f3dd1dc1..115dbaa7f2 100644 --- a/internal/donor/donordata/provided_test.go +++ b/internal/donor/donordata/provided_test.go @@ -217,14 +217,14 @@ func TestGenerateHash(t *testing.T) { } // DO change this value to match the updates - const modified uint64 = 0xe3bd213ba882ed4f + const modified uint64 = 0x44d4ab7efe0264f8 // DO NOT change these initial hash values. If a field has been added/removed // you will need to handle the version gracefully by modifying // (*Provided).HashInclude and adding another testcase for the new // version. testcases := map[uint8]uint64{ - 0: 0x3730007cdf45a8cd, + 0: 0x48b67658eed0ea5c, } for version, initial := range testcases { diff --git a/internal/donor/donorpage/progress.go b/internal/donor/donorpage/progress.go index 6493672e2c..5d684b4055 100644 --- a/internal/donor/donorpage/progress.go +++ b/internal/donor/donorpage/progress.go @@ -254,6 +254,16 @@ func Progress(tmpl template.Template, lpaStoreResolvingService LpaStoreResolving }) } + if !lpa.Status.IsRegistered() && !donor.PriorityCorrespondenceSentAt.IsZero() { + data.InfoNotifications = append(data.InfoNotifications, progressNotification{ + Heading: appData.Localizer.T("thereIsAProblemWithYourLpa"), + Body: appData.Localizer.Format( + "weContactedYouOnWithGuidanceAboutWhatToDoNext", + map[string]any{"ContactedDate": appData.Localizer.FormatDate(donor.PriorityCorrespondenceSentAt)}, + ), + }) + } + return tmpl(w, data) } } diff --git a/internal/donor/donorpage/progress_test.go b/internal/donor/donorpage/progress_test.go index cd04d52921..2398632892 100644 --- a/internal/donor/donorpage/progress_test.go +++ b/internal/donor/donorpage/progress_test.go @@ -655,6 +655,32 @@ func TestGetProgress(t *testing.T) { return l }, }, + "priority correspondence sent": { + donor: &donordata.Provided{ + PriorityCorrespondenceSentAt: testNow, + }, + lpa: &lpadata.Lpa{}, + setupCertificateProviderStore: certificateProviderStoreNotFound, + infoNotifications: []progressNotification{ + {Heading: "H", Body: "B"}, + }, + setupLocalizer: func(t *testing.T) *mockLocalizer { + l := newMockLocalizer(t) + l.EXPECT().T("thereIsAProblemWithYourLpa").Return("H") + l.EXPECT().Format("weContactedYouOnWithGuidanceAboutWhatToDoNext", map[string]any{"ContactedDate": "translated date"}).Return("B") + l.EXPECT().FormatDate(testNow).Return("translated date") + return l + }, + }, + "priority correspondence sent registered": { + donor: &donordata.Provided{ + PriorityCorrespondenceSentAt: testNow, + }, + lpa: &lpadata.Lpa{ + Status: lpadata.StatusRegistered, + }, + setupCertificateProviderStore: certificateProviderStoreNotFound, + }, } for name, tc := range testCases {