From ba36d99a45057952970b87d885931597d2d3b3db Mon Sep 17 00:00:00 2001 From: Joshua Hawxwell Date: Mon, 9 Dec 2024 09:08:39 +0000 Subject: [PATCH] Show progress banner when LPA is submitted --- cypress/e2e/donor/dashboard.cy.js | 6 +- cypress/e2e/donor/progress.cy.js | 8 ++ cypress/e2e/donor/view-lpa.cy.js | 2 +- cypress/e2e/donor/withdraw-lpa.cy.js | 2 +- internal/donor/donorpage/progress.go | 16 ++- internal/donor/donorpage/progress_test.go | 119 +++++++++++++++--- internal/donor/donorpage/register.go | 2 +- .../witnessing_as_certificate_provider.go | 1 + ...witnessing_as_certificate_provider_test.go | 2 + internal/page/fixtures/donor.go | 6 +- lang/cy.json | 4 +- lang/en.json | 4 +- web/template/dashboard.gohtml | 2 +- web/template/fixtures.gohtml | 1 - 14 files changed, 145 insertions(+), 30 deletions(-) diff --git a/cypress/e2e/donor/dashboard.cy.js b/cypress/e2e/donor/dashboard.cy.js index 59cc88e2b7..9cf1746bb9 100644 --- a/cypress/e2e/donor/dashboard.cy.js +++ b/cypress/e2e/donor/dashboard.cy.js @@ -23,7 +23,7 @@ describe('Dashboard', () => { }); }) - context('with completed LPA', () => { + context('with submitted LPA', () => { it('completed LPAs have a track progress button', () => { Cypress.on('uncaught:exception', () => { // TODO: remove this if this test works without, it is a problem @@ -51,11 +51,11 @@ describe('Dashboard', () => { context('with statutory waiting period LPA', () => { it('shows the correct options', () => { - cy.visit('/fixtures?redirect=&progress=submitted'); + cy.visit('/fixtures?redirect=&progress=statutoryWaitingPeriod'); cy.contains('Property and affairs'); cy.contains('Sam Smith'); - cy.contains('strong', 'In progress'); + cy.contains('strong', 'Waiting period'); cy.get('.app-dashboard-row a').should('have.length', 3); cy.contains('a', 'View LPA'); cy.contains('a', 'Track LPA progress'); diff --git a/cypress/e2e/donor/progress.cy.js b/cypress/e2e/donor/progress.cy.js index 46ffb9938d..5546460a1d 100644 --- a/cypress/e2e/donor/progress.cy.js +++ b/cypress/e2e/donor/progress.cy.js @@ -65,4 +65,12 @@ describe('Progress', () => { cy.contains('Important:').should('not.exist'); cy.visitLpa('/progress'); }); + + it('shows a notification when the lpa is submitted', () => { + cy.visit('/fixtures?redirect=/progress&progress=signTheLpa'); + cy.checkA11yApp(); + cy.contains('Important:') + cy.contains('1 notification from OPG'); + cy.contains('You’ve submitted your LPA to the Office of the Public Guardian'); + }); }); diff --git a/cypress/e2e/donor/view-lpa.cy.js b/cypress/e2e/donor/view-lpa.cy.js index 9f0d70d6ea..a9d1618154 100644 --- a/cypress/e2e/donor/view-lpa.cy.js +++ b/cypress/e2e/donor/view-lpa.cy.js @@ -34,7 +34,7 @@ describe('View LPA', () => { describe('when signed by everyone', () => { beforeEach(() => { - cy.visit('/fixtures?redirect=/view-lpa&attorneys=trust-corporation&progress=submitted'); + cy.visit('/fixtures?redirect=/view-lpa&attorneys=trust-corporation&progress=statutoryWaitingPeriod'); }); it('shows all signatures', () => { diff --git a/cypress/e2e/donor/withdraw-lpa.cy.js b/cypress/e2e/donor/withdraw-lpa.cy.js index eee84a23f3..bc727b4804 100644 --- a/cypress/e2e/donor/withdraw-lpa.cy.js +++ b/cypress/e2e/donor/withdraw-lpa.cy.js @@ -1,6 +1,6 @@ describe('Withdraw LPA', () => { it('can be withdrawn', () => { - cy.visit('/fixtures?redirect=&progress=submitted'); + cy.visit('/fixtures?redirect=&progress=statutoryWaitingPeriod'); cy.contains('Sam Smith'); cy.contains('a', 'Withdraw LPA').click(); diff --git a/internal/donor/donorpage/progress.go b/internal/donor/donorpage/progress.go index 75b6fbb6a3..0e779c4d47 100644 --- a/internal/donor/donorpage/progress.go +++ b/internal/donor/donorpage/progress.go @@ -1,11 +1,13 @@ package donorpage import ( + "errors" "net/http" "github.com/ministryofjustice/opg-go-common/template" "github.com/ministryofjustice/opg-modernising-lpa/internal/appcontext" "github.com/ministryofjustice/opg-modernising-lpa/internal/donor/donordata" + "github.com/ministryofjustice/opg-modernising-lpa/internal/dynamo" "github.com/ministryofjustice/opg-modernising-lpa/internal/task" "github.com/ministryofjustice/opg-modernising-lpa/internal/validation" ) @@ -23,7 +25,7 @@ type progressData struct { InfoNotifications []progressNotification } -func Progress(tmpl template.Template, lpaStoreResolvingService LpaStoreResolvingService, progressTracker ProgressTracker) Handler { +func Progress(tmpl template.Template, lpaStoreResolvingService LpaStoreResolvingService, progressTracker ProgressTracker, certificateProviderStore CertificateProviderStore) Handler { return func(appData appcontext.Data, w http.ResponseWriter, r *http.Request, donor *donordata.Provided) error { lpa, err := lpaStoreResolvingService.Get(r.Context()) if err != nil { @@ -43,6 +45,18 @@ func Progress(tmpl template.Template, lpaStoreResolvingService LpaStoreResolving }) } + if lpa.Submitted && lpa.CertificateProvider.SignedAt.IsZero() { + _, err := certificateProviderStore.GetAny(r.Context()) + if errors.Is(err, dynamo.NotFoundError{}) { + data.InfoNotifications = append(data.InfoNotifications, progressNotification{ + Heading: "youveSubmittedYourLpaToOpg", + Body: "opgIsCheckingYourLpa", + }) + } else if err != nil { + return err + } + } + return tmpl(w, data) } } diff --git a/internal/donor/donorpage/progress_test.go b/internal/donor/donorpage/progress_test.go index 37888d0935..94c286d706 100644 --- a/internal/donor/donorpage/progress_test.go +++ b/internal/donor/donorpage/progress_test.go @@ -4,8 +4,11 @@ import ( "net/http" "net/http/httptest" "testing" + "time" + "github.com/ministryofjustice/opg-modernising-lpa/internal/certificateprovider/certificateproviderdata" "github.com/ministryofjustice/opg-modernising-lpa/internal/donor/donordata" + "github.com/ministryofjustice/opg-modernising-lpa/internal/dynamo" "github.com/ministryofjustice/opg-modernising-lpa/internal/lpastore/lpadata" "github.com/ministryofjustice/opg-modernising-lpa/internal/task" "github.com/stretchr/testify/assert" @@ -14,19 +17,25 @@ import ( func TestGetProgress(t *testing.T) { testCases := map[string]struct { - provided *donordata.Provided - infoNotifications []progressNotification + donor *donordata.Provided + setupCertificateProviderStore func(*mockCertificateProviderStore_GetAny_Call) + lpa *lpadata.Lpa + infoNotifications []progressNotification }{ "none": { - provided: &donordata.Provided{LpaUID: "lpa-uid"}, + donor: &donordata.Provided{LpaUID: "lpa-uid"}, + lpa: &lpadata.Lpa{LpaUID: "lpa-uid"}, }, + + // you have chosen to confirm your identity at a post office "going to the post office": { - provided: &donordata.Provided{ + donor: &donordata.Provided{ LpaUID: "lpa-uid", Tasks: donordata.Tasks{ ConfirmYourIdentity: task.IdentityStatePending, }, }, + lpa: &lpadata.Lpa{LpaUID: "lpa-uid"}, infoNotifications: []progressNotification{ { Heading: "youHaveChosenToConfirmYourIdentityAtPostOffice", @@ -34,6 +43,62 @@ func TestGetProgress(t *testing.T) { }, }, }, + "confirmed identity": { + donor: &donordata.Provided{ + LpaUID: "lpa-uid", + Tasks: donordata.Tasks{ + ConfirmYourIdentity: task.IdentityStateCompleted, + }, + }, + lpa: &lpadata.Lpa{LpaUID: "lpa-uid"}, + }, + + // you've submitted your lpa to the opg + "submitted": { + donor: &donordata.Provided{ + LpaUID: "lpa-uid", + SubmittedAt: time.Now(), + }, + lpa: &lpadata.Lpa{ + LpaUID: "lpa-uid", + Submitted: true, + }, + setupCertificateProviderStore: func(call *mockCertificateProviderStore_GetAny_Call) { + call.Return(nil, dynamo.NotFoundError{}) + }, + infoNotifications: []progressNotification{ + { + Heading: "youveSubmittedYourLpaToOpg", + Body: "opgIsCheckingYourLpa", + }, + }, + }, + "submitted and certificate provider started": { + donor: &donordata.Provided{ + LpaUID: "lpa-uid", + SubmittedAt: time.Now(), + }, + lpa: &lpadata.Lpa{ + LpaUID: "lpa-uid", + Submitted: true, + }, + setupCertificateProviderStore: func(call *mockCertificateProviderStore_GetAny_Call) { + call.Return(&certificateproviderdata.Provided{}, nil) + }, + }, + "submitted and certificate provider finished": { + donor: &donordata.Provided{ + LpaUID: "lpa-uid", + SubmittedAt: time.Now(), + }, + lpa: &lpadata.Lpa{ + LpaUID: "lpa-uid", + Submitted: true, + CertificateProvider: lpadata.CertificateProvider{ + SignedAt: time.Now(), + }, + }, + }, } for name, tc := range testCases { @@ -41,29 +106,32 @@ func TestGetProgress(t *testing.T) { w := httptest.NewRecorder() r, _ := http.NewRequest(http.MethodGet, "/", nil) - lpa := &lpadata.Lpa{LpaUID: "lpa-uid"} - lpaStoreResolvingService := newMockLpaStoreResolvingService(t) lpaStoreResolvingService.EXPECT(). Get(r.Context()). - Return(lpa, nil) + Return(tc.lpa, nil) progressTracker := newMockProgressTracker(t) progressTracker.EXPECT(). - Progress(lpa). + Progress(tc.lpa). Return(task.Progress{DonorSigned: task.ProgressTask{Done: true}}) + certificateProviderStore := newMockCertificateProviderStore(t) + if tc.setupCertificateProviderStore != nil { + tc.setupCertificateProviderStore(certificateProviderStore.EXPECT().GetAny(r.Context())) + } + template := newMockTemplate(t) template.EXPECT(). Execute(w, &progressData{ App: testAppData, - Donor: tc.provided, + Donor: tc.donor, Progress: task.Progress{DonorSigned: task.ProgressTask{Done: true}}, InfoNotifications: tc.infoNotifications, }). Return(nil) - err := Progress(template.Execute, lpaStoreResolvingService, progressTracker)(testAppData, w, r, tc.provided) + err := Progress(template.Execute, lpaStoreResolvingService, progressTracker, certificateProviderStore)(testAppData, w, r, tc.donor) resp := w.Result() assert.Nil(t, err) @@ -78,10 +146,33 @@ func TestGetProgressWhenLpaStoreClientErrors(t *testing.T) { lpaStoreResolvingService := newMockLpaStoreResolvingService(t) lpaStoreResolvingService.EXPECT(). - Get(r.Context()). + Get(mock.Anything). + Return(nil, expectedError) + + err := Progress(nil, lpaStoreResolvingService, nil, nil)(testAppData, w, r, &donordata.Provided{LpaUID: "lpa-uid"}) + assert.Equal(t, expectedError, err) +} + +func TestGetProgressWhenCertificateProviderStoreErrors(t *testing.T) { + w := httptest.NewRecorder() + r, _ := http.NewRequest(http.MethodGet, "/", nil) + + lpaStoreResolvingService := newMockLpaStoreResolvingService(t) + lpaStoreResolvingService.EXPECT(). + Get(mock.Anything). + Return(&lpadata.Lpa{Submitted: true}, nil) + + progressTracker := newMockProgressTracker(t) + progressTracker.EXPECT(). + Progress(mock.Anything). + Return(task.Progress{DonorSigned: task.ProgressTask{Done: true}}) + + certificateProviderStore := newMockCertificateProviderStore(t) + certificateProviderStore.EXPECT(). + GetAny(mock.Anything). Return(nil, expectedError) - err := Progress(nil, lpaStoreResolvingService, nil)(testAppData, w, r, &donordata.Provided{LpaUID: "lpa-uid"}) + err := Progress(nil, lpaStoreResolvingService, progressTracker, certificateProviderStore)(testAppData, w, r, &donordata.Provided{LpaUID: "lpa-uid"}) assert.Equal(t, expectedError, err) } @@ -91,7 +182,7 @@ func TestGetProgressOnTemplateError(t *testing.T) { lpaStoreResolvingService := newMockLpaStoreResolvingService(t) lpaStoreResolvingService.EXPECT(). - Get(r.Context()). + Get(mock.Anything). Return(&lpadata.Lpa{}, nil) progressTracker := newMockProgressTracker(t) @@ -104,6 +195,6 @@ func TestGetProgressOnTemplateError(t *testing.T) { Execute(w, mock.Anything). Return(expectedError) - err := Progress(template.Execute, lpaStoreResolvingService, progressTracker)(testAppData, w, r, &donordata.Provided{LpaUID: "lpa-uid"}) + err := Progress(template.Execute, lpaStoreResolvingService, progressTracker, nil)(testAppData, w, r, &donordata.Provided{LpaUID: "lpa-uid"}) assert.Equal(t, expectedError, err) } diff --git a/internal/donor/donorpage/register.go b/internal/donor/donorpage/register.go index c44e63c132..b778650bf5 100644 --- a/internal/donor/donorpage/register.go +++ b/internal/donor/donorpage/register.go @@ -462,7 +462,7 @@ func Register( Guidance(tmpls.Get("you_have_submitted_your_lpa.gohtml"))) handleWithDonor(donor.PathProgress, page.None, - Progress(tmpls.Get("progress.gohtml"), lpaStoreResolvingService, progressTracker)) + Progress(tmpls.Get("progress.gohtml"), lpaStoreResolvingService, progressTracker, certificateProviderStore)) handleWithDonor(donor.PathUploadEvidenceSSE, page.None, UploadEvidenceSSE(documentStore, 3*time.Minute, 2*time.Second, time.Now)) diff --git a/internal/donor/donorpage/witnessing_as_certificate_provider.go b/internal/donor/donorpage/witnessing_as_certificate_provider.go index df4874e53e..98476c15f5 100644 --- a/internal/donor/donorpage/witnessing_as_certificate_provider.go +++ b/internal/donor/donorpage/witnessing_as_certificate_provider.go @@ -57,6 +57,7 @@ func WitnessingAsCertificateProvider( if data.Errors.None() { provided.Tasks.SignTheLpa = task.StateCompleted + provided.SubmittedAt = now() provided.WitnessCodeLimiter = nil if provided.WitnessedByCertificateProviderAt.IsZero() { diff --git a/internal/donor/donorpage/witnessing_as_certificate_provider_test.go b/internal/donor/donorpage/witnessing_as_certificate_provider_test.go index a9a43a2b45..706a3408e1 100644 --- a/internal/donor/donorpage/witnessing_as_certificate_provider_test.go +++ b/internal/donor/donorpage/witnessing_as_certificate_provider_test.go @@ -99,6 +99,7 @@ func TestPostWitnessingAsCertificateProvider(t *testing.T) { CertificateProviderCodes: donordata.WitnessCodes{{Code: "1234", Created: testNow}}, CertificateProvider: donordata.CertificateProvider{FirstNames: "Fred"}, WitnessedByCertificateProviderAt: testNow, + SubmittedAt: testNow, Tasks: donordata.Tasks{ PayForLpa: task.PaymentStateCompleted, SignTheLpa: task.StateCompleted, @@ -158,6 +159,7 @@ func TestPostWitnessingAsCertificateProviderWhenPaymentPending(t *testing.T) { CertificateProvider: donordata.CertificateProvider{Email: "name@example.com"}, CertificateProviderCodes: donordata.WitnessCodes{{Code: "1234", Created: testNow}}, WitnessedByCertificateProviderAt: testNow, + SubmittedAt: testNow, Tasks: donordata.Tasks{ PayForLpa: task.PaymentStatePending, SignTheLpa: task.StateCompleted, diff --git a/internal/page/fixtures/donor.go b/internal/page/fixtures/donor.go index c6a6568320..57afc5708a 100644 --- a/internal/page/fixtures/donor.go +++ b/internal/page/fixtures/donor.go @@ -60,7 +60,6 @@ var progressValues = []string{ "signTheLpa", "signedByCertificateProvider", "signedByAttorneys", - "submitted", "statutoryWaitingPeriod", // end states "registered", @@ -477,6 +476,7 @@ func updateLPAProgress( donorDetails.SignedAt = time.Date(2023, time.January, 2, 3, 4, 5, 6, time.UTC) donorDetails.WitnessedByCertificateProviderAt = time.Date(2023, time.January, 2, 3, 4, 5, 6, time.UTC) donorDetails.Tasks.SignTheLpa = task.StateCompleted + donorDetails.SubmittedAt = time.Date(2023, time.January, 2, 3, 4, 5, 6, time.UTC) } var certificateProviderUID actoruid.UID @@ -586,10 +586,6 @@ func updateLPAProgress( } } - if data.Progress >= slices.Index(progressValues, "submitted") { - donorDetails.SubmittedAt = time.Now() - } - if data.Progress >= slices.Index(progressValues, "statutoryWaitingPeriod") { fns = append(fns, func(ctx context.Context, client *lpastore.Client, _ *lpadata.Lpa) error { return client.SendStatutoryWaitingPeriod(ctx, donorDetails.LpaUID) diff --git a/lang/cy.json b/lang/cy.json index 04432c0874..b0e219e59c 100644 --- a/lang/cy.json +++ b/lang/cy.json @@ -1500,5 +1500,7 @@ "other": "{{.PluralCount}} Welsh" }, "youHaveChosenToConfirmYourIdentityAtPostOffice": "Welsh", - "whenYouHaveConfirmedAtPostOfficeReturnToTaskList": "Welsh" + "whenYouHaveConfirmedAtPostOfficeReturnToTaskList": "Welsh", + "youveSubmittedYourLpaToOpg": "Welsh", + "opgIsCheckingYourLpa": "Welsh" } diff --git a/lang/en.json b/lang/en.json index 9152548bf4..a3fa01ea60 100644 --- a/lang/en.json +++ b/lang/en.json @@ -1396,5 +1396,7 @@ "other": "{{.PluralCount}} notifications from OPG" }, "youHaveChosenToConfirmYourIdentityAtPostOffice": "You have chosen to confirm your identity at a Post Office", - "whenYouHaveConfirmedAtPostOfficeReturnToTaskList": "When you have confirmed your identity at a Post Office, return to your task list for the steps you must take to complete this process." + "whenYouHaveConfirmedAtPostOfficeReturnToTaskList": "When you have confirmed your identity at a Post Office, return to your task list for the steps you must take to complete this process.", + "youveSubmittedYourLpaToOpg": "You’ve submitted your LPA to the Office of the Public Guardian (OPG)", + "opgIsCheckingYourLpa": "OPG is checking your LPA. We will contact you if there is anything you need to do." } diff --git a/web/template/dashboard.gohtml b/web/template/dashboard.gohtml index 528ff7f0b0..2646e8591f 100644 --- a/web/template/dashboard.gohtml +++ b/web/template/dashboard.gohtml @@ -52,7 +52,7 @@ {{ else if .Item.Lpa.Status.IsRegistered }} - {{ else if .Item.Lpa.Submitted }} + {{ else if .Item.Lpa.Status.IsStatutoryWaitingPeriod }}
{{ tr .App "viewLpa" }} {{ tr .App "trackLpaProgress" }} diff --git a/web/template/fixtures.gohtml b/web/template/fixtures.gohtml index 0dd75b492c..ce78f951fe 100644 --- a/web/template/fixtures.gohtml +++ b/web/template/fixtures.gohtml @@ -66,7 +66,6 @@ (item "signTheLpa" "Sign the LPA") (item "signedByCertificateProvider" "Signed by certificate provider") (item "signedByAttorneys" "Signed by attorneys") - (item "submitted" "Submitted") (item "statutoryWaitingPeriod" "Statutory waiting period" "orDivider" "1") (item "withdrawn" "Withdrawn") (item "certificateProviderOptedOut" "Certificate provider opted out (post signing)")