diff --git a/.codecov.yml b/.codecov.yml index baa2d04f27..d79020ef33 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -9,6 +9,8 @@ coverage: - "./internal/identity/yoti*" - "./internal/telemetry" - "./internal/page/fixtures.go" + - "./internal/page/attorney_fixtures.go" + - "./internal/page/certificate_provider_fixtures.go" - "./internal/page/testing_start.go" - "./cmd/mlpa/main.go" - "./cmd/mock-notify/main.go" diff --git a/cypress/e2e/attorney/confirm-your-details.cy.js b/cypress/e2e/attorney/confirm-your-details.cy.js index f4fa6e108f..ce493c1216 100644 --- a/cypress/e2e/attorney/confirm-your-details.cy.js +++ b/cypress/e2e/attorney/confirm-your-details.cy.js @@ -2,7 +2,7 @@ import { TestMobile } from '../../support/e2e'; describe('Confirm your details', () => { beforeEach(() => { - cy.visit('/testing-start?redirect=/mobile-number&lpa.attorneys=1&attorneyProvided=1&loginAs=attorney'); + cy.visit('/fixtures/attorney?redirect=/mobile-number'); cy.get('#f-mobile').type(TestMobile); cy.contains('Continue').click(); diff --git a/cypress/e2e/attorney/legal-rights-and-responsibilities.cy.js b/cypress/e2e/attorney/legal-rights-and-responsibilities.cy.js index 782a56b85c..f27a5eac59 100644 --- a/cypress/e2e/attorney/legal-rights-and-responsibilities.cy.js +++ b/cypress/e2e/attorney/legal-rights-and-responsibilities.cy.js @@ -1,6 +1,6 @@ describe('Legal rights and responsibilities', () => { it('can continue to next page', () => { - cy.visit('/testing-start?redirect=/legal-rights-and-responsibilities&lpa.complete=1&lpa.attorneys=1&lpa.signedByDonor=1&attorneyProvided=1&loginAs=attorney'); + cy.visit('/fixtures/attorney?redirect=/legal-rights-and-responsibilities'); cy.contains('h1', "Your legal rights and responsibilities") diff --git a/cypress/e2e/attorney/mobile-number.cy.js b/cypress/e2e/attorney/mobile-number.cy.js index a08c370e7d..5698c32067 100644 --- a/cypress/e2e/attorney/mobile-number.cy.js +++ b/cypress/e2e/attorney/mobile-number.cy.js @@ -2,7 +2,7 @@ import { TestMobile } from "../../support/e2e"; describe('Mobile number', () => { beforeEach(() => { - cy.visit('/testing-start?lpa.complete=1&attorneyProvided=1&redirect=/mobile-number&loginAs=attorney'); + cy.visit('/fixtures/attorney?redirect=/mobile-number'); }); it('can be completed', () => { diff --git a/cypress/e2e/attorney/read-the-lpa.cy.js b/cypress/e2e/attorney/read-the-lpa.cy.js index 4a80e11046..8058ef60a5 100644 --- a/cypress/e2e/attorney/read-the-lpa.cy.js +++ b/cypress/e2e/attorney/read-the-lpa.cy.js @@ -1,6 +1,6 @@ describe('Read the LPA', () => { it('displays the LPA details with actor specific content', () => { - cy.visit('/testing-start?redirect=/read-the-lpa&lpa.complete=1&attorneyProvided=1&loginAs=attorney'); + cy.visit('/fixtures/attorney?redirect=/read-the-lpa'); cy.contains('dt', "When attorneys can use the LPA") cy.contains('dt', "Attorney names") diff --git a/cypress/e2e/attorney/sign.cy.js b/cypress/e2e/attorney/sign.cy.js index 6c2a1c653f..a551839096 100644 --- a/cypress/e2e/attorney/sign.cy.js +++ b/cypress/e2e/attorney/sign.cy.js @@ -1,7 +1,7 @@ describe('Sign', () => { describe('as an attorney', () => { beforeEach(() => { - cy.visit('/testing-start?cookiesAccepted=1&redirect=/sign&lpa.complete=1&attorneyProvided=1&asCertificateProvider=certified&loginAs=attorney'); + cy.visit('/fixtures/attorney?redirect=/sign&progress=signedByCertificateProvider'); }); it('can be signed', () => { @@ -31,7 +31,7 @@ describe('Sign', () => { describe('as a replacement attorney', () => { beforeEach(() => { - cy.visit('/testing-start?cookiesAccepted=1&redirect=/sign&lpa.complete=1&withReplacementAttorney=1&lpa.signedByDonor=1&asCertificateProvider=certified&replacementAttorneyProvided=1&loginAs=attorney'); + cy.visit('/fixtures/attorney?redirect=/sign&is-replacement=1&progress=signedByCertificateProvider'); }); it('can be signed', () => { diff --git a/cypress/e2e/attorney/task-list.cy.js b/cypress/e2e/attorney/task-list.cy.js index bfe0ba4cc6..0ffb72f277 100644 --- a/cypress/e2e/attorney/task-list.cy.js +++ b/cypress/e2e/attorney/task-list.cy.js @@ -1,6 +1,6 @@ describe('Task list', () => { beforeEach(() => { - cy.visit('/testing-start?redirect=/task-list&lpa.complete=1&attorneyProvided=1&loginAs=attorney'); + cy.visit('/fixtures/attorney?redirect=/task-list'); }); it('shows tasks', () => { diff --git a/cypress/e2e/attorney/trust-corporation.cy.js b/cypress/e2e/attorney/trust-corporation.cy.js index 44990969a9..b89a0afde0 100644 --- a/cypress/e2e/attorney/trust-corporation.cy.js +++ b/cypress/e2e/attorney/trust-corporation.cy.js @@ -1,8 +1,8 @@ -const { TestMobile } = require("../../support/e2e"); +const { TestMobile, TestEmail } = require("../../support/e2e"); describe('As a trust corporation', () => { beforeEach(() => { - cy.visit('/testing-start?redirect=/attorney-start&lpa.complete=1&lpa.trustCorporation=complete&useTestShareCode=1&sendAttorneyShare=1&lpa.signedByDonor=1&asCertificateProvider=certified'); + cy.visit('/fixtures/attorney?redirect=/attorney-start&is-trust-corporation=1&progress=signedByCertificateProvider&use-test-code=1&email=' + TestEmail); // start cy.contains('a', 'Start').click(); @@ -25,11 +25,11 @@ describe('As a trust corporation', () => { // confirm your company details cy.contains(TestMobile); cy.contains('Confirm your company details'); - cy.contains('My company'); + cy.contains('First Choice Trust Corporation Ltd.'); cy.contains('555555555'); cy.contains('simulate-delivered@notifications.service.gov.uk'); - cy.contains('123 Fake Street'); - cy.contains('FF1 1FF'); + cy.contains('2 RICHMOND PLACE'); + cy.contains('B14 7ED'); cy.contains('button', 'Continue').click(); // read the lpa @@ -59,7 +59,7 @@ describe('As a trust corporation', () => { cy.contains('button', 'Continue').click(); // what happens next - cy.contains('My company has formally agreed to be an attorney'); + cy.contains('First Choice Trust Corporation Ltd. has formally agreed to be an attorney'); cy.contains('a', 'Go to your dashboard'); }); @@ -89,7 +89,7 @@ describe('As a trust corporation', () => { cy.contains('button', 'Submit signature').click(); // what happens next - cy.contains('My company has formally agreed to be an attorney'); + cy.contains('First Choice Trust Corporation Ltd. has formally agreed to be an attorney'); cy.contains('a', 'Go to your dashboard'); }); @@ -119,7 +119,7 @@ describe('As a trust corporation', () => { cy.contains('button', 'Continue').click(); // what happens next - cy.contains('My company has formally agreed to be an attorney'); + cy.contains('First Choice Trust Corporation Ltd. has formally agreed to be an attorney'); cy.contains('a', 'Go to your dashboard'); }); }); diff --git a/cypress/e2e/attorney/what-happens-when-you-sign-the-lpa.cy.js b/cypress/e2e/attorney/what-happens-when-you-sign-the-lpa.cy.js index 40f20c8bb7..bacb14007f 100644 --- a/cypress/e2e/attorney/what-happens-when-you-sign-the-lpa.cy.js +++ b/cypress/e2e/attorney/what-happens-when-you-sign-the-lpa.cy.js @@ -1,6 +1,6 @@ describe('What happens when you sign the LPA', () => { it('as a property and affairs attorney', () => { - cy.visit('/testing-start?redirect=/what-happens-when-you-sign-the-lpa&lpa.complete=1&attorneyProvided=1&lpa.signedByDonor=1&asCertificateProvider=certified&loginAs=attorney'); + cy.visit('/fixtures/attorney?redirect=/what-happens-when-you-sign-the-lpa&progress=signedByCertificateProvider'); cy.contains('h1', "What happens when you sign the LPA") cy.contains('p', "you’re officially saying that you want to be an attorney on") @@ -13,7 +13,7 @@ describe('What happens when you sign the LPA', () => { }); it('as a personal welfare attorney', () => { - cy.visit('/testing-start?redirect=/what-happens-when-you-sign-the-lpa&lpa.complete=1&attorneyProvided=1&lpa.type=hw&loginAs=attorney'); + cy.visit('/fixtures/attorney?redirect=/what-happens-when-you-sign-the-lpa&lpa-type=hw&progress=signedByCertificateProvider'); cy.contains('p', "you’re officially saying that you want to be an attorney on") cy.contains('li', "their personal and medical care") @@ -21,7 +21,7 @@ describe('What happens when you sign the LPA', () => { }); it('as a property and affairs replacement attorney', () => { - cy.visit('/testing-start?redirect=/what-happens-when-you-sign-the-lpa&lpa.complete=1&replacementAttorneyProvided=1&loginAs=attorney'); + cy.visit('/fixtures/attorney?redirect=/what-happens-when-you-sign-the-lpa&progress=signedByCertificateProvider&is-replacement=1'); cy.contains('p', "you’re saying that you want to be a replacement attorney") cy.contains('li', "make decisions about their money or property") @@ -29,7 +29,7 @@ describe('What happens when you sign the LPA', () => { }); it('as a personal welfare replacement attorney', () => { - cy.visit('/testing-start?redirect=/what-happens-when-you-sign-the-lpa&lpa.complete=1&replacementAttorneyProvided=1&lpa.type=hw&loginAs=attorney'); + cy.visit('/fixtures/attorney?redirect=/what-happens-when-you-sign-the-lpa&lpa-type=hw&progress=signedByCertificateProvider&is-replacement=1'); cy.contains('p', "you’re saying that you want to be a replacement attorney ") cy.contains('li', "their personal and medical care") diff --git a/cypress/e2e/certificate-provider/certificate-provided.cy.js b/cypress/e2e/certificate-provider/certificate-provided.cy.js index bb504c0003..0bd88af17e 100644 --- a/cypress/e2e/certificate-provider/certificate-provided.cy.js +++ b/cypress/e2e/certificate-provider/certificate-provided.cy.js @@ -1,6 +1,6 @@ describe('Certificate provided', () => { beforeEach(() => { - cy.visit('/testing-start?redirect=/certificate-provided&loginAs=certificate-provider'); + cy.visit('/fixtures/certificate-provider?redirect=/certificate-provided'); }); it('has a button to the dashboard', () => { diff --git a/cypress/e2e/certificate-provider/confirm-your-details.cy.js b/cypress/e2e/certificate-provider/confirm-your-details.cy.js index a2ad906ada..1d9c4e3e2b 100644 --- a/cypress/e2e/certificate-provider/confirm-your-details.cy.js +++ b/cypress/e2e/certificate-provider/confirm-your-details.cy.js @@ -1,6 +1,6 @@ describe('Confirm your details', () => { it('shows details', () => { - cy.visit('/testing-start?redirect=/enter-date-of-birth&lpa.certificateProvider=1&asCertificateProvider=1&loginAs=certificate-provider'); + cy.visit('/fixtures/certificate-provider?redirect=/enter-date-of-birth'); cy.get('#f-date-of-birth').type('1'); cy.get('#f-date-of-birth-month').type('2'); @@ -20,8 +20,8 @@ describe('Confirm your details', () => { cy.url().should('contain', '/your-role'); }); - it('redirects to tasklist when details have already been confirmed', () => { - cy.visit('/testing-start?redirect=/confirm-your-details&lpa.certificateProvider=1&asCertificateProvider=1&cp.confirmYourDetails=1&loginAs=certificate-provider'); + it('redirects to tasklist when LPA has already been witnessed', () => { + cy.visit('/fixtures/certificate-provider?redirect=/confirm-your-details&progress=signedByDonor'); cy.url().should('contain', '/confirm-your-details'); cy.checkA11yApp(); @@ -32,8 +32,8 @@ describe('Confirm your details', () => { cy.contains('li', 'Confirm your details').should('contain', 'Completed'); }); - it('redirects to tasklist when LPA has already been witnessed', () => { - cy.visit('/testing-start?redirect=/confirm-your-details&lpa.certificateProvider=1&asCertificateProvider=1&lpa.signedByDonor=1&loginAs=certificate-provider'); + it('redirects to tasklist when details have already been confirmed', () => { + cy.visit('/fixtures/certificate-provider?redirect=/confirm-your-details&progress=detailsConfirmed'); cy.url().should('contain', '/confirm-your-details'); cy.checkA11yApp(); diff --git a/cypress/e2e/certificate-provider/enter-date-of-birth.cy.js b/cypress/e2e/certificate-provider/enter-date-of-birth.cy.js index e3491277ca..864afe842f 100644 --- a/cypress/e2e/certificate-provider/enter-date-of-birth.cy.js +++ b/cypress/e2e/certificate-provider/enter-date-of-birth.cy.js @@ -1,6 +1,6 @@ describe('Enter date of birth', () => { beforeEach(() => { - cy.visit('/testing-start?redirect=/enter-date-of-birth&asCertificateProvider=1&loginAs=certificate-provider'); + cy.visit('/fixtures/certificate-provider?redirect=/enter-date-of-birth'); }); it('can be completed', () => { diff --git a/cypress/e2e/certificate-provider/enter-reference-number.cy.js b/cypress/e2e/certificate-provider/enter-reference-number.cy.js index 8f474e666e..57dd54ef28 100644 --- a/cypress/e2e/certificate-provider/enter-reference-number.cy.js +++ b/cypress/e2e/certificate-provider/enter-reference-number.cy.js @@ -1,7 +1,11 @@ +const { TestEmail } = require("../../support/e2e"); + describe('Enter reference number', () => { - it('can enter a valid reference number', { pageLoadTimeout: 6000 }, () => { - cy.visit('/testing-start?lpa.complete=1&startCpFlowDonorHasPaid=1&useTestShareCode=1'); + beforeEach(() => { + cy.visit('/fixtures/certificate-provider?redirect=/certificate-provider-start&use-test-code=1&email=' + TestEmail); + }); + it('can enter a valid reference number', { pageLoadTimeout: 6000 }, () => { cy.contains('a', 'Start').click() cy.checkA11yApp(); @@ -13,8 +17,6 @@ describe('Enter reference number', () => { }); it('errors when empty number', () => { - cy.visit('/testing-start?lpa.complete=1&startCpFlowDonorHasPaid=1&useTestShareCode=1'); - cy.contains('a', 'Start').click() cy.checkA11yApp(); @@ -29,8 +31,6 @@ describe('Enter reference number', () => { }); it('errors when incorrect code', () => { - cy.visit('/testing-start?lpa.complete=1&startCpFlowDonorHasPaid=1&useTestShareCode=1'); - cy.contains('a', 'Start').click() cy.checkA11yApp(); @@ -46,8 +46,6 @@ describe('Enter reference number', () => { }); it('errors when incorrect code length', () => { - cy.visit('/testing-start?lpa.complete=1&startCpFlowDonorHasPaid=1&useTestShareCode=1'); - cy.contains('a', 'Start').click() cy.checkA11yApp(); diff --git a/cypress/e2e/certificate-provider/provide-certificate.cy.js b/cypress/e2e/certificate-provider/provide-certificate.cy.js index 2630143bba..e254c9f7ae 100644 --- a/cypress/e2e/certificate-provider/provide-certificate.cy.js +++ b/cypress/e2e/certificate-provider/provide-certificate.cy.js @@ -1,6 +1,6 @@ describe('Provide the certificate', () => { beforeEach(() => { - cy.visit('/testing-start?redirect=/provide-certificate&lpa.complete=1&asCertificateProvider=1&loginAs=certificate-provider'); + cy.visit('/fixtures/certificate-provider?redirect=/provide-certificate&progress=signedByDonor'); }); it('can provide the certificate', () => { diff --git a/cypress/e2e/certificate-provider/read-the-lpa.cy.js b/cypress/e2e/certificate-provider/read-the-lpa.cy.js index c844999863..cea28ba724 100644 --- a/cypress/e2e/certificate-provider/read-the-lpa.cy.js +++ b/cypress/e2e/certificate-provider/read-the-lpa.cy.js @@ -1,7 +1,7 @@ describe('Read the LPA', () => { describe('when the LPA is signed', () => { beforeEach(() => { - cy.visit('/testing-start?redirect=/read-the-lpa&lpa.complete=1&asCertificateProvider=1&loginAs=certificate-provider'); + cy.visit('/fixtures/certificate-provider?redirect=/read-the-lpa&progress=signedByDonor'); }); it('displays the LPA details and goes to provide certificate', () => { @@ -18,7 +18,7 @@ describe('Read the LPA', () => { describe('when the LPA is not yet signed', () => { beforeEach(() => { - cy.visit('/testing-start?redirect=/read-the-lpa&lpa.certificateProvider=1&lpa.yourDetails=1&asCertificateProvider=1&loginAs=certificate-provider'); + cy.visit('/fixtures/certificate-provider?redirect=/read-the-lpa'); }); it('displays the LPA details and goes to task list', () => { diff --git a/cypress/e2e/certificate-provider/select-your-identity-options.cy.js b/cypress/e2e/certificate-provider/select-your-identity-options.cy.js index 6f7296a2a9..515543768b 100644 --- a/cypress/e2e/certificate-provider/select-your-identity-options.cy.js +++ b/cypress/e2e/certificate-provider/select-your-identity-options.cy.js @@ -1,6 +1,6 @@ describe('Select your identity options', () => { beforeEach(() => { - cy.visit('/testing-start?redirect=/select-your-identity-options&lpa.complete=1&asCertificateProvider=1&loginAs=certificate-provider'); + cy.visit('/fixtures/certificate-provider?redirect=/select-your-identity-options'); }); it('can select on first page', () => { diff --git a/cypress/e2e/certificate-provider/start.cy.js b/cypress/e2e/certificate-provider/start.cy.js index 09b98cbbd8..a3a0e8d605 100644 --- a/cypress/e2e/certificate-provider/start.cy.js +++ b/cypress/e2e/certificate-provider/start.cy.js @@ -1,6 +1,6 @@ describe('Start', () => { beforeEach(() => { - cy.visit('/testing-start?startCpFlowDonorHasPaid=1'); + cy.visit('/certificate-provider-start'); }); it('can be completed', () => { diff --git a/cypress/e2e/certificate-provider/task-list.cy.js b/cypress/e2e/certificate-provider/task-list.cy.js index 0ef382b088..a553899a02 100644 --- a/cypress/e2e/certificate-provider/task-list.cy.js +++ b/cypress/e2e/certificate-provider/task-list.cy.js @@ -1,6 +1,6 @@ describe('Task list', () => { beforeEach(() => { - cy.visit('/testing-start?redirect=/task-list&lpa.complete=1&asCertificateProvider=1&loginAs=certificate-provider'); + cy.visit('/fixtures/certificate-provider?redirect=/task-list&progress=signedByDonor'); }); it('shows tasks', () => { diff --git a/cypress/e2e/certificate-provider/who-is-eligible.cy.js b/cypress/e2e/certificate-provider/who-is-eligible.cy.js index f78ab56cd3..6e9ead5023 100644 --- a/cypress/e2e/certificate-provider/who-is-eligible.cy.js +++ b/cypress/e2e/certificate-provider/who-is-eligible.cy.js @@ -1,6 +1,6 @@ describe('Who is eligible', () => { beforeEach(() => { - cy.visit('/testing-start?redirect=/certificate-provider-who-is-eligible&loginAs=certificate-provider'); + cy.visit('/fixtures/certificate-provider?redirect=/certificate-provider-who-is-eligible'); }); it('can continue', () => { diff --git a/internal/app/app.go b/internal/app/app.go index cd7b33e789..5aaa2d35ef 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -99,7 +99,7 @@ func App( rootMux := http.NewServeMux() - rootMux.Handle(paths.TestingStart.String(), page.TestingStart(sessionStore, donorStore, random.String, shareCodeSender, localizer, certificateProviderStore, attorneyStore, logger, time.Now)) + rootMux.Handle(paths.TestingStart.String(), page.TestingStart(sessionStore, donorStore, random.String, localizer, certificateProviderStore, attorneyStore, logger, time.Now)) handleRoot := makeHandle(rootMux, errorHandler, sessionStore) @@ -109,6 +109,10 @@ func App( page.SignOut(logger, sessionStore, oneLoginClient, appPublicURL)) handleRoot(paths.Fixtures, None, page.Fixtures(tmpls.Get("fixtures.gohtml"))) + handleRoot(paths.CertificateProviderFixtures, None, + page.CertificateProviderFixtures(tmpls.Get("certificate_provider_fixtures.gohtml"), sessionStore, shareCodeSender, donorStore, certificateProviderStore)) + handleRoot(paths.AttorneyFixtures, None, + page.AttorneyFixtures(tmpls.Get("attorney_fixtures.gohtml"), sessionStore, shareCodeSender, donorStore, certificateProviderStore, attorneyStore)) handleRoot(paths.YourLegalRightsAndResponsibilities, None, page.Guidance(tmpls.Get("your_legal_rights_and_responsibilities_general.gohtml"))) handleRoot(page.Paths.Start, None, diff --git a/internal/app/dashboard_store.go b/internal/app/dashboard_store.go index 11a5da56bd..7bf14c2957 100644 --- a/internal/app/dashboard_store.go +++ b/internal/app/dashboard_store.go @@ -11,6 +11,7 @@ import ( "github.com/ministryofjustice/opg-modernising-lpa/internal/actor" "github.com/ministryofjustice/opg-modernising-lpa/internal/dynamo" "github.com/ministryofjustice/opg-modernising-lpa/internal/page" + "golang.org/x/exp/maps" ) // An lpaLink is used to join an actor to an LPA. @@ -131,6 +132,11 @@ func (s *dashboardStore) GetAll(ctx context.Context) (donor, attorney, certifica } if entry, ok := attorneyMap[attorneyProvidedDetails.LpaID]; ok { + if attorneyProvidedDetails.IsReplacement && !entry.Lpa.SubmittedAt.IsZero() { + delete(attorneyMap, attorneyProvidedDetails.LpaID) + continue + } + entry.Attorney = attorneyProvidedDetails attorneyMap[attorneyProvidedDetails.LpaID] = entry continue @@ -154,13 +160,8 @@ func (s *dashboardStore) GetAll(ctx context.Context) (donor, attorney, certifica } } - for _, value := range certificateProviderMap { - certificateProvider = append(certificateProvider, value) - } - - for _, value := range attorneyMap { - attorney = append(attorney, value) - } + certificateProvider = maps.Values(certificateProviderMap) + attorney = maps.Values(attorneyMap) byUpdatedAt := func(a, b page.LpaAndActorTasks) int { if a.Lpa.UpdatedAt.After(b.Lpa.UpdatedAt) { diff --git a/internal/app/dashboard_store_test.go b/internal/app/dashboard_store_test.go index 743f8a5688..d96bd24cbd 100644 --- a/internal/app/dashboard_store_test.go +++ b/internal/app/dashboard_store_test.go @@ -14,20 +14,23 @@ import ( ) func TestDashboardStoreGetAll(t *testing.T) { - lpa0 := &page.Lpa{ID: "0", UID: "M", UpdatedAt: time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC), SK: donorKey("an-id"), PK: lpaKey("0")} - lpa123 := &page.Lpa{ID: "123", UID: "M", UpdatedAt: time.Date(2001, time.January, 1, 0, 0, 0, 0, time.UTC), SK: donorKey("an-id"), PK: lpaKey("123")} + sessionID := "an-id" + aTime := time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC) + + lpa0 := &page.Lpa{ID: "0", UID: "M", UpdatedAt: aTime, SK: donorKey(sessionID), PK: lpaKey("0")} + lpa123 := &page.Lpa{ID: "123", UID: "M", UpdatedAt: aTime, SK: donorKey(sessionID), PK: lpaKey("123")} lpa456 := &page.Lpa{ID: "456", UID: "M", SK: donorKey("another-id"), PK: lpaKey("456")} lpa456CpProvidedDetails := &actor.CertificateProviderProvidedDetails{ - LpaID: "456", Tasks: actor.CertificateProviderTasks{ConfirmYourDetails: actor.TaskCompleted}, SK: certificateProviderKey("an-id"), + LpaID: "456", Tasks: actor.CertificateProviderTasks{ConfirmYourDetails: actor.TaskCompleted}, SK: certificateProviderKey(sessionID), } lpa789 := &page.Lpa{ID: "789", UID: "M", SK: donorKey("different-id"), PK: lpaKey("789")} lpa789AttorneyProvidedDetails := &actor.AttorneyProvidedDetails{ - LpaID: "789", Tasks: actor.AttorneyTasks{ConfirmYourDetails: actor.TaskInProgress}, SK: attorneyKey("an-id"), + LpaID: "789", Tasks: actor.AttorneyTasks{ConfirmYourDetails: actor.TaskInProgress}, SK: attorneyKey(sessionID), } - lpaNoUID := &page.Lpa{ID: "999", UpdatedAt: time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC), SK: donorKey("an-id"), PK: lpaKey("0")} + lpaNoUID := &page.Lpa{ID: "999", UpdatedAt: aTime, SK: donorKey(sessionID), PK: lpaKey("0")} lpaSignedByCp := &page.Lpa{ID: "signed-by-cp", UID: "M", SK: donorKey("another-id"), PK: lpaKey("signed-by-cp")} lpaSignedByCpProvidedDetails := &actor.CertificateProviderProvidedDetails{ - LpaID: "signed-by-cp", SK: certificateProviderKey("an-id"), Certificate: actor.Certificate{AgreeToStatement: true}, + LpaID: "signed-by-cp", SK: certificateProviderKey(sessionID), Certificate: actor.Certificate{AgreeToStatement: true}, } testCases := map[string][]map[string]types.AttributeValue{ @@ -56,7 +59,7 @@ func TestDashboardStoreGetAll(t *testing.T) { for name, attributeValues := range testCases { t.Run(name, func(t *testing.T) { - ctx := page.ContextWithSessionData(context.Background(), &page.SessionData{SessionID: "an-id"}) + ctx := page.ContextWithSessionData(context.Background(), &page.SessionData{SessionID: sessionID}) dynamoClient := newMockDynamoClient(t) dynamoClient.ExpectAllForActor(ctx, "#SUB#an-id", @@ -92,6 +95,44 @@ func TestDashboardStoreGetAll(t *testing.T) { } } +func TestDashboardStoreGetAllSubmittedForAttorneys(t *testing.T) { + sessionID := "an-id" + aTime := time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC) + + lpaSubmitted := &page.Lpa{ID: "submitted", UID: "M", SK: donorKey("another-id"), PK: lpaKey("submitted"), SubmittedAt: aTime} + lpaSubmittedAttorneyDetails := &actor.AttorneyProvidedDetails{LpaID: "submitted", SK: attorneyKey(sessionID)} + lpaSubmittedReplacement := &page.Lpa{ID: "submitted-replacement", UID: "M", SK: donorKey("another-id"), PK: lpaKey("submitted-replacement"), SubmittedAt: aTime} + lpaSubmittedReplacementAttorneyDetails := &actor.AttorneyProvidedDetails{LpaID: "submitted-replacement", SK: attorneyKey(sessionID), IsReplacement: true} + ctx := page.ContextWithSessionData(context.Background(), &page.SessionData{SessionID: sessionID}) + + dynamoClient := newMockDynamoClient(t) + dynamoClient.ExpectAllForActor(ctx, "#SUB#an-id", + []lpaLink{ + {PK: "LPA#submitted", SK: "#SUB#an-id", DonorKey: "#DONOR#another-id", ActorType: actor.TypeAttorney}, + {PK: "LPA#submitted-replacement", SK: "#SUB#an-id", DonorKey: "#DONOR#another-id", ActorType: actor.TypeAttorney}, + }, nil) + dynamoClient.ExpectAllByKeys(ctx, []dynamo.Key{ + {PK: "LPA#submitted", SK: "#DONOR#another-id"}, + {PK: "LPA#submitted", SK: "#ATTORNEY#an-id"}, + {PK: "LPA#submitted-replacement", SK: "#DONOR#another-id"}, + {PK: "LPA#submitted-replacement", SK: "#ATTORNEY#an-id"}, + }, []map[string]types.AttributeValue{ + makeAttributeValueMap(lpaSubmitted), + makeAttributeValueMap(lpaSubmittedAttorneyDetails), + makeAttributeValueMap(lpaSubmittedReplacement), + makeAttributeValueMap(lpaSubmittedReplacementAttorneyDetails), + }, nil) + + dashboardStore := &dashboardStore{dynamoClient: dynamoClient} + + _, attorney, _, err := dashboardStore.GetAll(ctx) + assert.Nil(t, err) + + assert.Equal(t, []page.LpaAndActorTasks{ + {Lpa: lpaSubmitted, Attorney: lpaSubmittedAttorneyDetails}, + }, attorney) +} + func makeAttributeValueMap(i interface{}) map[string]types.AttributeValue { result, _ := attributevalue.MarshalMap(i) return result diff --git a/internal/page/attorney_fixtures.go b/internal/page/attorney_fixtures.go new file mode 100644 index 0000000000..24061610cd --- /dev/null +++ b/internal/page/attorney_fixtures.go @@ -0,0 +1,264 @@ +package page + +import ( + "encoding/base64" + "net/http" + "slices" + "time" + + "github.com/ministryofjustice/opg-go-common/template" + "github.com/ministryofjustice/opg-modernising-lpa/internal/actor" + "github.com/ministryofjustice/opg-modernising-lpa/internal/date" + "github.com/ministryofjustice/opg-modernising-lpa/internal/form" + "github.com/ministryofjustice/opg-modernising-lpa/internal/place" + "github.com/ministryofjustice/opg-modernising-lpa/internal/random" + "github.com/ministryofjustice/opg-modernising-lpa/internal/sesh" + "github.com/ministryofjustice/opg-modernising-lpa/internal/validation" +) + +type attorneyFixturesData struct { + App AppData + Errors validation.List +} + +func AttorneyFixtures( + tmpl template.Template, + sessionStore sesh.Store, + shareCodeSender *ShareCodeSender, + donorStore DonorStore, + certificateProviderStore CertificateProviderStore, + attorneyStore AttorneyStore, +) Handler { + const ( + testEmail = "simulate-delivered@notifications.service.gov.uk" + testMobile = "07700900000" + ) + + type Name struct { + Firstnames, Lastname string + } + + var ( + progressValues = []string{ + "signedByCertificateProvider", + "signedByAttorney", + "submitted", + "registered", + } + attorneyNames = []Name{ + {Firstnames: "Jessie", Lastname: "Jones"}, + {Firstnames: "Robin", Lastname: "Redcar"}, + {Firstnames: "Leslie", Lastname: "Lewis"}, + {Firstnames: "Ashley", Lastname: "Alwinton"}, + {Firstnames: "Frankie", Lastname: "Fernandes"}, + } + replacementAttorneyNames = []Name{ + {Firstnames: "Blake", Lastname: "Buckley"}, + {Firstnames: "Taylor", Lastname: "Thompson"}, + {Firstnames: "Marley", Lastname: "Morris"}, + {Firstnames: "Alex", Lastname: "Abbott"}, + {Firstnames: "Billie", Lastname: "Blair"}, + } + ) + + makeAttorney := func(name Name) actor.Attorney { + return actor.Attorney{ + ID: name.Firstnames + name.Lastname, + FirstNames: name.Firstnames, + LastName: name.Lastname, + Email: testEmail, + DateOfBirth: date.New("2000", "1", "2"), + Address: place.Address{ + Line1: "2 RICHMOND PLACE", + Line2: "KINGS HEATH", + Line3: "WEST MIDLANDS", + TownOrCity: "BIRMINGHAM", + Postcode: "B14 7ED", + }, + } + } + + makeTrustCorporation := func(name string) actor.TrustCorporation { + return actor.TrustCorporation{ + Name: name, + CompanyNumber: "555555555", + Email: testEmail, + Address: place.Address{ + Line1: "2 RICHMOND PLACE", + Line2: "KINGS HEATH", + Line3: "WEST MIDLANDS", + TownOrCity: "BIRMINGHAM", + Postcode: "B14 7ED", + }, + } + } + + return func(appData AppData, w http.ResponseWriter, r *http.Request) error { + var ( + isReplacement = r.FormValue("is-replacement") == "1" + isTrustCorporation = r.FormValue("is-trust-corporation") == "1" + lpaType = r.FormValue("lpa-type") + progress = slices.Index(progressValues, r.FormValue("progress")) + email = r.FormValue("email") + redirect = r.FormValue("redirect") + ) + + if r.Method != http.MethodPost && redirect == "" { + return tmpl(w, &attorneyFixturesData{App: appData}) + } + + if lpaType == "hw" && isTrustCorporation { + return tmpl(w, &attorneyFixturesData{App: appData, Errors: validation.With("", validation.CustomError{Label: "Can't add a trust corporation to a personal welfare LPA"})}) + } + + var ( + donorSub = random.String(16) + attorneySub = random.String(16) + certificateProviderSub = random.String(16) + donorSessionID = base64.StdEncoding.EncodeToString([]byte(donorSub)) + certificateProviderSessionID = base64.StdEncoding.EncodeToString([]byte(certificateProviderSub)) + attorneySessionID = base64.StdEncoding.EncodeToString([]byte(attorneySub)) + ) + + if err := sesh.SetLoginSession(sessionStore, r, w, &sesh.LoginSession{Sub: attorneySub, Email: testEmail}); err != nil { + return err + } + + lpa, err := donorStore.Create(ContextWithSessionData(r.Context(), &SessionData{SessionID: donorSessionID})) + if err != nil { + return err + } + + var ( + donorCtx = ContextWithSessionData(r.Context(), &SessionData{SessionID: donorSessionID, LpaID: lpa.ID}) + certificateProviderCtx = ContextWithSessionData(r.Context(), &SessionData{SessionID: certificateProviderSessionID, LpaID: lpa.ID}) + attorneyCtx = ContextWithSessionData(r.Context(), &SessionData{SessionID: attorneySessionID, LpaID: lpa.ID}) + ) + + lpa.Donor = actor.Donor{ + FirstNames: "Sam", + LastName: "Smith", + Address: place.Address{ + Line1: "1 RICHMOND PLACE", + Line2: "KINGS HEATH", + Line3: "WEST MIDLANDS", + TownOrCity: "BIRMINGHAM", + Postcode: "B14 7ED", + }, + Email: testEmail, + DateOfBirth: date.New("2000", "1", "2"), + ThinksCanSign: actor.Yes, + CanSign: form.Yes, + } + lpa.Type = LpaTypePropertyFinance + if lpaType == "hw" && !isTrustCorporation { + lpa.Type = LpaTypeHealthWelfare + } + + lpa.Attorneys = actor.Attorneys{ + Attorneys: []actor.Attorney{makeAttorney(attorneyNames[0])}, + TrustCorporation: makeTrustCorporation("First Choice Trust Corporation Ltd."), + } + lpa.ReplacementAttorneys = actor.Attorneys{ + Attorneys: []actor.Attorney{makeAttorney(replacementAttorneyNames[0])}, + TrustCorporation: makeTrustCorporation("Second Choice Trust Corporation Ltd."), + } + + if email != "" { + if isTrustCorporation { + if isReplacement { + lpa.ReplacementAttorneys.TrustCorporation.Email = email + } else { + lpa.Attorneys.TrustCorporation.Email = email + } + } + if isReplacement { + lpa.ReplacementAttorneys.Attorneys[0].Email = email + } else { + lpa.Attorneys.Attorneys[0].Email = email + } + } + + var attorneyID string + if !isTrustCorporation { + if isReplacement { + attorneyID = lpa.ReplacementAttorneys.Attorneys[0].ID + } else { + attorneyID = lpa.Attorneys.Attorneys[0].ID + } + } + + certificateProvider, err := certificateProviderStore.Create(certificateProviderCtx, donorSessionID) + if err != nil { + return err + } + + certificateProvider.Certificate = actor.Certificate{Agreed: time.Now()} + + attorney, err := attorneyStore.Create(attorneyCtx, donorSessionID, attorneyID, isReplacement, isTrustCorporation) + if err != nil { + return err + } + + if progress >= slices.Index(progressValues, "signedByCertificateProvider") { + lpa.SignedAt = time.Now() + } + if progress >= slices.Index(progressValues, "signedByAttorney") { + attorney.Mobile = testMobile + attorney.Tasks.ConfirmYourDetails = actor.TaskCompleted + attorney.Tasks.ReadTheLpa = actor.TaskCompleted + attorney.Tasks.SignTheLpa = actor.TaskCompleted + + if isTrustCorporation { + attorney.WouldLikeSecondSignatory = form.No + attorney.AuthorisedSignatories = [2]actor.TrustCorporationSignatory{{ + FirstNames: "A", + LastName: "Sign", + ProfessionalTitle: "Assistant to the signer", + Confirmed: time.Now(), + }} + } else { + attorney.Confirmed = time.Now() + } + } + if progress >= slices.Index(progressValues, "submitted") { + lpa.SubmittedAt = time.Now() + } + if progress >= slices.Index(progressValues, "registered") { + lpa.RegisteredAt = time.Now() + } + + if err := donorStore.Put(donorCtx, lpa); err != nil { + return err + } + if err := certificateProviderStore.Put(certificateProviderCtx, certificateProvider); err != nil { + return err + } + if err := attorneyStore.Put(attorneyCtx, attorney); err != nil { + return err + } + + // should only be used in tests as otherwise people can read their emails... + if r.FormValue("use-test-code") == "1" { + useTestCode = true + } + + if email != "" { + shareCodeSender.SendAttorneys(donorCtx, AppData{ + SessionID: donorSessionID, + LpaID: lpa.ID, + Localizer: appData.Localizer, + }, lpa) + + return AppData{}.Redirect(w, r, nil, Paths.Attorney.Start.Format()) + } + + if redirect == "" { + redirect = Paths.Dashboard.Format() + } else { + redirect = "/attorney/" + lpa.ID + redirect + } + + return AppData{}.Redirect(w, r, nil, redirect) + } +} diff --git a/internal/page/certificate_provider_fixtures.go b/internal/page/certificate_provider_fixtures.go new file mode 100644 index 0000000000..cd4104a264 --- /dev/null +++ b/internal/page/certificate_provider_fixtures.go @@ -0,0 +1,201 @@ +package page + +import ( + "encoding/base64" + "net/http" + "slices" + "time" + + "github.com/ministryofjustice/opg-go-common/template" + "github.com/ministryofjustice/opg-modernising-lpa/internal/actor" + "github.com/ministryofjustice/opg-modernising-lpa/internal/date" + "github.com/ministryofjustice/opg-modernising-lpa/internal/form" + "github.com/ministryofjustice/opg-modernising-lpa/internal/notify" + "github.com/ministryofjustice/opg-modernising-lpa/internal/place" + "github.com/ministryofjustice/opg-modernising-lpa/internal/random" + "github.com/ministryofjustice/opg-modernising-lpa/internal/sesh" + "github.com/ministryofjustice/opg-modernising-lpa/internal/validation" +) + +type certificateProviderFixturesData struct { + App AppData + Errors validation.List +} + +func CertificateProviderFixtures( + tmpl template.Template, + sessionStore sesh.Store, + shareCodeSender *ShareCodeSender, + donorStore DonorStore, + certificateProviderStore CertificateProviderStore, +) Handler { + const ( + testEmail = "simulate-delivered@notifications.service.gov.uk" + testMobile = "07700900000" + ) + + type Name struct { + Firstnames, Lastname string + } + + var ( + progressValues = []string{ + "paid", + "signedByDonor", + "detailsConfirmed", + } + attorneyNames = []Name{ + {Firstnames: "Jessie", Lastname: "Jones"}, + {Firstnames: "Robin", Lastname: "Redcar"}, + {Firstnames: "Leslie", Lastname: "Lewis"}, + {Firstnames: "Ashley", Lastname: "Alwinton"}, + {Firstnames: "Frankie", Lastname: "Fernandes"}, + } + ) + + makeAttorney := func(name Name) actor.Attorney { + return actor.Attorney{ + ID: name.Firstnames + name.Lastname, + FirstNames: name.Firstnames, + LastName: name.Lastname, + Email: testEmail, + DateOfBirth: date.New("2000", "1", "2"), + Address: place.Address{ + Line1: "2 RICHMOND PLACE", + Line2: "KINGS HEATH", + Line3: "WEST MIDLANDS", + TownOrCity: "BIRMINGHAM", + Postcode: "B14 7ED", + }, + } + } + + return func(appData AppData, w http.ResponseWriter, r *http.Request) error { + var ( + lpaType = r.FormValue("lpa-type") + progress = slices.Index(progressValues, r.FormValue("progress")) + email = r.FormValue("email") + redirect = r.FormValue("redirect") + ) + + if r.Method != http.MethodPost && redirect == "" { + return tmpl(w, &certificateProviderFixturesData{App: appData}) + } + + var ( + donorSub = random.String(16) + certificateProviderSub = random.String(16) + donorSessionID = base64.StdEncoding.EncodeToString([]byte(donorSub)) + certificateProviderSessionID = base64.StdEncoding.EncodeToString([]byte(certificateProviderSub)) + ) + + if err := sesh.SetLoginSession(sessionStore, r, w, &sesh.LoginSession{Sub: certificateProviderSub, Email: testEmail}); err != nil { + return err + } + + lpa, err := donorStore.Create(ContextWithSessionData(r.Context(), &SessionData{SessionID: donorSessionID})) + if err != nil { + return err + } + + var ( + donorCtx = ContextWithSessionData(r.Context(), &SessionData{SessionID: donorSessionID, LpaID: lpa.ID}) + certificateProviderCtx = ContextWithSessionData(r.Context(), &SessionData{SessionID: certificateProviderSessionID, LpaID: lpa.ID}) + ) + + lpa.Donor = actor.Donor{ + FirstNames: "Sam", + LastName: "Smith", + Address: place.Address{ + Line1: "1 RICHMOND PLACE", + Line2: "KINGS HEATH", + Line3: "WEST MIDLANDS", + TownOrCity: "BIRMINGHAM", + Postcode: "B14 7ED", + }, + Email: testEmail, + DateOfBirth: date.New("2000", "1", "2"), + ThinksCanSign: actor.Yes, + CanSign: form.Yes, + } + lpa.Type = LpaTypePropertyFinance + if lpaType == "hw" { + lpa.Type = LpaTypeHealthWelfare + } + + lpa.Attorneys = actor.Attorneys{ + Attorneys: []actor.Attorney{makeAttorney(attorneyNames[0]), makeAttorney(attorneyNames[1])}, + } + + lpa.CertificateProvider = actor.CertificateProvider{ + FirstNames: "Charlie", + LastName: "Cooper", + Email: testEmail, + Mobile: testMobile, + Relationship: actor.Personally, + RelationshipLength: "gte-2-years", + CarryOutBy: actor.Online, + Address: place.Address{ + Line1: "5 RICHMOND PLACE", + Line2: "KINGS HEATH", + Line3: "WEST MIDLANDS", + TownOrCity: "BIRMINGHAM", + Postcode: "B14 7ED", + }, + } + + if email != "" { + lpa.CertificateProvider.Email = email + } + + certificateProvider, err := certificateProviderStore.Create(certificateProviderCtx, donorSessionID) + if err != nil { + return err + } + + if progress >= slices.Index(progressValues, "paid") { + lpa.PaymentDetails = append(lpa.PaymentDetails, Payment{ + PaymentReference: random.String(12), + PaymentId: random.String(12), + }) + lpa.Tasks.PayForLpa = actor.PaymentTaskCompleted + } + if progress >= slices.Index(progressValues, "signedByDonor") { + lpa.SignedAt = time.Now() + } + if progress >= slices.Index(progressValues, "detailsConfirmed") { + certificateProvider.DateOfBirth = date.New("1990", "1", "2") + certificateProvider.Tasks.ConfirmYourDetails = actor.TaskCompleted + } + + if err := donorStore.Put(donorCtx, lpa); err != nil { + return err + } + if err := certificateProviderStore.Put(certificateProviderCtx, certificateProvider); err != nil { + return err + } + + // should only be used in tests as otherwise people can read their emails... + if r.FormValue("use-test-code") == "1" { + useTestCode = true + } + + if email != "" { + shareCodeSender.SendCertificateProvider(donorCtx, notify.CertificateProviderInviteEmail, AppData{ + SessionID: donorSessionID, + LpaID: lpa.ID, + Localizer: appData.Localizer, + }, true, lpa) + + return AppData{}.Redirect(w, r, nil, Paths.CertificateProviderStart.Format()) + } + + if redirect == "" { + redirect = Paths.Dashboard.Format() + } else { + redirect = "/certificate-provider/" + lpa.ID + redirect + } + + return AppData{}.Redirect(w, r, nil, redirect) + } +} diff --git a/internal/page/fixtures.go b/internal/page/fixtures.go index 38c9bd1c1b..badaea5a07 100644 --- a/internal/page/fixtures.go +++ b/internal/page/fixtures.go @@ -6,7 +6,6 @@ import ( "net/url" "github.com/ministryofjustice/opg-go-common/template" - "github.com/ministryofjustice/opg-modernising-lpa/internal/actor" "github.com/ministryofjustice/opg-modernising-lpa/internal/validation" ) @@ -28,67 +27,6 @@ func Fixtures(tmpl template.Template) Handler { var values url.Values switch data.Form.Journey { - case "attorney": - values = url.Values{ - "useTestShareCode": {"1"}, - "sendAttorneyShare": {"1"}, - "lpa.complete": {"1"}, - "lpa.attorneys": {"2"}, - "lpa.attorneysAct": {actor.JointlyAndSeverally.String()}, - "lpa.replacementAttorneys": {"2"}, - "lpa.replacementAttorneysAct": {actor.Jointly.String()}, - "lpa.type": {data.Form.Type}, - "lpa.restrictions": {"1"}, - "redirect": {Paths.Attorney.Start.Format()}, - "lpa.progress": {r.FormValue("lpa.progress")}, - } - - switch data.Form.SendTo { - case "replacement-attorney": - if data.Form.Email != "" { - values.Add("lpa.replacementAttorneyEmail", data.Form.Email) - } - case "trust-corporation": - values.Add("lpa.trustCorporation", "complete") - if data.Form.Email != "" { - values.Add("lpa.trustCorporationEmail", data.Form.Email) - } - case "replacement-trust-corporation": - values.Add("lpa.replacementTrustCorporation", "complete") - if data.Form.Email != "" { - values.Add("lpa.replacementTrustCorporationEmail", data.Form.Email) - } - default: - if data.Form.Email != "" { - values.Add("lpa.attorneyEmail", data.Form.Email) - } - } - - if data.Form.Signed != "" { - values.Add("lpa.signedByDonor", "1") - values.Add("asCertificateProvider", "certified") - } - - case "certificate-provider": - values = url.Values{ - "useTestShareCode": {"1"}, - data.Form.DonorPaid: {"1"}, - } - - if data.Form.Email != "" { - values.Add("lpa.certificateProviderEmail", data.Form.Email) - } - - if data.Form.DonorPaid != "" { - values.Add("startCpFlowDonorHasPaid", "1") - } else { - values.Add("startCpFlowDonorHasNotPaid", "1") - } - - if data.Form.Signed != "" { - values.Add("lpa.signedByDonor", "1") - } - case "donor": values = url.Values{ "lpa.type": {data.Form.Type}, @@ -154,7 +92,6 @@ type fixturesForm struct { IdAndSign string CompleteAll string Email string - DonorPaid string SendTo string Signed string Type string @@ -178,7 +115,6 @@ func readFixtures(r *http.Request) *fixturesForm { IdAndSign: PostFormString(r, "confirm-id-and-sign"), CompleteAll: PostFormString(r, "complete-all-sections"), Email: PostFormString(r, "email"), - DonorPaid: PostFormString(r, "donor-paid"), SendTo: PostFormString(r, "send-to"), Signed: PostFormString(r, "signed"), Type: PostFormString(r, "type"), diff --git a/internal/page/paths.go b/internal/page/paths.go index 9b00d94029..fa406ec820 100644 --- a/internal/page/paths.go +++ b/internal/page/paths.go @@ -104,6 +104,8 @@ type AppPaths struct { Root Path SignOut Path Fixtures Path + AttorneyFixtures Path + CertificateProviderFixtures Path YourLegalRightsAndResponsibilities Path CertificateProviderStart Path Start Path @@ -259,10 +261,12 @@ var Paths = AppPaths{ AboutPayment: "/about-payment", ApplicationReason: "/application-reason", AreYouApplyingForADifferentFeeType: "/are-you-applying-for-a-different-fee-type", + AttorneyFixtures: "/fixtures/attorney", AuthRedirect: "/auth/redirect", CanEvidenceBeUploaded: "/can-evidence-be-uploaded", CertificateProviderAddress: "/certificate-provider-address", CertificateProviderDetails: "/certificate-provider-details", + CertificateProviderFixtures: "/fixtures/certificate-provider", CertificateProviderOptOut: "/certificate-provider-opt-out", CertificateProviderStart: "/certificate-provider-start", CheckYouCanSign: "/check-you-can-sign", diff --git a/internal/page/testing_start.go b/internal/page/testing_start.go index 02c8ee0912..d3fa010d41 100644 --- a/internal/page/testing_start.go +++ b/internal/page/testing_start.go @@ -13,13 +13,12 @@ import ( "github.com/ministryofjustice/opg-modernising-lpa/internal/form" "github.com/ministryofjustice/opg-modernising-lpa/internal/identity" "github.com/ministryofjustice/opg-modernising-lpa/internal/localize" - "github.com/ministryofjustice/opg-modernising-lpa/internal/notify" "github.com/ministryofjustice/opg-modernising-lpa/internal/place" "github.com/ministryofjustice/opg-modernising-lpa/internal/random" "github.com/ministryofjustice/opg-modernising-lpa/internal/sesh" ) -func TestingStart(store sesh.Store, donorStore DonorStore, randomString func(int) string, shareCodeSender shareCodeSender, localizer Localizer, certificateProviderStore CertificateProviderStore, attorneyStore AttorneyStore, logger *logging.Logger, now func() time.Time) http.HandlerFunc { +func TestingStart(store sesh.Store, donorStore DonorStore, randomString func(int) string, localizer Localizer, certificateProviderStore CertificateProviderStore, attorneyStore AttorneyStore, logger *logging.Logger, now func() time.Time) http.HandlerFunc { const ( testEmail = "simulate-delivered@notifications.service.gov.uk" testMobile = "07700900000" @@ -473,24 +472,17 @@ func TestingStart(store sesh.Store, donorStore DonorStore, randomString func(int } var ( - completeLpa = r.FormValue("lpa.complete") != "" - cookiesAccepted = r.FormValue("cookiesAccepted") != "" - useTestShareCode = r.FormValue("useTestShareCode") != "" - withShareCodeSession = r.FormValue("withShareCodeSession") != "" - startCpFlowDonorHasPaid = r.FormValue("startCpFlowDonorHasPaid") != "" - startCpFlowDonorHasNotPaid = r.FormValue("startCpFlowDonorHasNotPaid") != "" - asCertificateProvider = r.FormValue("asCertificateProvider") - cpConfirmYourDetailsComplete = r.FormValue("cp.confirmYourDetails") != "" - fresh = r.FormValue("fresh") != "" - asAttorney = r.FormValue("attorneyProvided") != "" - asReplacementAttorney = r.FormValue("replacementAttorneyProvided") != "" - sendAttorneyShare = r.FormValue("sendAttorneyShare") != "" - redirect = r.FormValue("redirect") - paymentComplete = r.FormValue("lpa.paid") != "" - progress = r.FormValue("lpa.progress") + completeLpa = r.FormValue("lpa.complete") != "" + cookiesAccepted = r.FormValue("cookiesAccepted") != "" + asCertificateProvider = r.FormValue("asCertificateProvider") + fresh = r.FormValue("fresh") != "" + asAttorney = r.FormValue("attorneyProvided") != "" + redirect = r.FormValue("redirect") + paymentComplete = r.FormValue("lpa.paid") != "" + progress = r.FormValue("lpa.progress") ) - completeSectionOne := completeLpa || startCpFlowDonorHasNotPaid || startCpFlowDonorHasPaid || paymentComplete + completeSectionOne := completeLpa || paymentComplete lpa := buildLpa(ContextWithSessionData(r.Context(), &SessionData{SessionID: donorSessionID}), lpaOptions{ hasDonorDetails: r.FormValue("lpa.yourDetails") != "" || completeSectionOne, @@ -508,7 +500,7 @@ func TestingStart(store sesh.Store, donorStore DonorStore, randomString func(int certificateProviderActOnline: r.FormValue("lpa.certificateProviderActOnline") != "", peopleToNotify: parseCount(r.FormValue("lpa.peopleToNotify"), completeSectionOne), checked: r.FormValue("lpa.checkAndSend") != "" || completeSectionOne, - paid: paymentComplete || startCpFlowDonorHasPaid || completeLpa, + paid: paymentComplete || completeLpa, idConfirmedAndSigned: r.FormValue("lpa.confirmIdentityAndSign") != "" || completeLpa, certificateProviderEmail: r.FormValue("lpa.certificateProviderEmail"), attorneyEmail: r.FormValue("lpa.attorneyEmail"), @@ -564,24 +556,6 @@ func TestingStart(store sesh.Store, donorStore DonorStore, randomString func(int }) } - if useTestShareCode { - shareCodeSender.UseTestCode() - } - - if withShareCodeSession { - sesh.SetShareCode(store, r, w, &sesh.ShareCodeSession{LpaID: lpa.ID, Identity: false}) - } - - if startCpFlowDonorHasPaid || startCpFlowDonorHasNotPaid { - shareCodeSender.SendCertificateProvider(donorCtx, notify.CertificateProviderInviteEmail, AppData{ - SessionID: donorSessionID, - LpaID: lpa.ID, - Localizer: localizer, - }, false, lpa) - - redirect = Paths.CertificateProviderStart.Format() - } - if signedByCertificateProvider || asCertificateProvider != "" { currentCtx := certificateProviderCtx @@ -626,7 +600,7 @@ func TestingStart(store sesh.Store, donorStore DonorStore, randomString func(int } } - if signedByCertificateProvider || cpConfirmYourDetailsComplete { + if signedByCertificateProvider { certificateProvider.Mobile = testMobile certificateProvider.Email = testEmail certificateProvider.DateOfBirth = date.New("2000", "1", "2") @@ -674,23 +648,6 @@ func TestingStart(store sesh.Store, donorStore DonorStore, randomString func(int } } - if asReplacementAttorney { - id := lpa.ReplacementAttorneys.Attorneys[0].ID - - _, err := attorneyStore.Create(attorneyCtx, attorneySessionID, id, true, false) - if err != nil { - logger.Print("asReplacementAttorney:", err) - } - } - - if sendAttorneyShare { - shareCodeSender.SendAttorneys(donorCtx, AppData{ - SessionID: donorSessionID, - LpaID: lpa.ID, - Localizer: localizer, - }, lpa) - } - random.UseTestCode = true lang := localize.En diff --git a/lang/cy.json b/lang/cy.json index 489e3b2240..9ec2ad7cc2 100644 --- a/lang/cy.json +++ b/lang/cy.json @@ -815,5 +815,6 @@ "enterYourCompanyPhoneNumberOptional": "Welsh", "youCanChooseToTellUsYourCompanyPhoneNumber": "Welsh", "enterYourCompanyPhoneNumberHint": "Welsh", - "errorCompanyPhoneNumber": "Welsh" + "errorCompanyPhoneNumber": "Welsh", + "lpaNumber": "Welsh" } diff --git a/lang/en.json b/lang/en.json index e0add4adda..0349e6dd1a 100644 --- a/lang/en.json +++ b/lang/en.json @@ -671,7 +671,7 @@ "yourRoleAsCertificateProviderContent": "

Meet and talk with the donor to confirm you have no concerns

The donor, {{ .DonorFullName }}, should get in touch with you to arrange a face-to-face meeting.

By the end of your meeting, you’ll need to have confidence that:

You may wish to take some notes about your conversation. If we ever have any concerns, we may ask you to tell us more about the conversation you had with {{ .DonorFirstNames }}.

Witness the donor signing their LPA

You must witness {{ .DonorFirstNames }} signing their LPA in person.

If they sign on paper, you will need to sign on paper to witness their signature.

If they sign their LPA online, you’ll be sent a code via text message, which you’ll need to provide to {{ .DonorFirstNames }}. This is how you’ll prove you’ve witnessed their signature.

Provide your certificate online

Once you’ve spoken to {{ .DonorFirstNames }}, you’ll need to ‘provide your certificate’ by signing online.

", "goToYourTaskList": "Go to your task list", "iTrustCorporationConfirmTheseStatements": "I am authorised to sign on behalf of {{.TrustCorporationName}} acting as an attorney. I confirm these statements are true and understand that ticking this box acts as my legal signature.", - "signAsTrustCorporationWhenCapacityLostBullet": "The company can make decisionsa and act only when this LPA has been registered and only when the donor does not have mental capacity.", + "signAsTrustCorporationWhenCapacityLostBullet": "The company can make decisions and act only when this LPA has been registered and only when the donor does not have mental capacity.", "signAsTrustCorporationWhenRegisteredBullet": "The company can make decisions and act only when this LPA has been registered.", "signAsTrustCorporationBullets": "
  • On behalf of the company, I have read this lasting power of attorney (LPA) or had it read to me. This includes the company’s legal rights and responsibilities.
  • The company has a duty to act based on the principles of the Mental Capacity Act 2005 and with consideration of the Mental Capacity Act Code of Practice.
  • The company must make decisions and act in the best interests of the donor.
  • The company must take into account any restrictions and conditions set out in this LPA.
  • ", "professionalTitle": "Professional title", @@ -771,5 +771,6 @@ "enterYourCompanyPhoneNumberOptional": "Enter your company’s phone number (optional)", "youCanChooseToTellUsYourCompanyPhoneNumber": "You can choose to tell us your company’s phone number in case we ever need to contact you.", "enterYourCompanyPhoneNumberHint": "For example, 07700 900 982 or 01632 960000.", - "errorCompanyPhoneNumber": "Enter a valid phone number" + "errorCompanyPhoneNumber": "Enter a valid phone number", + "lpaNumber": "LPA number" } diff --git a/web/template/attorney_fixtures.gohtml b/web/template/attorney_fixtures.gohtml new file mode 100644 index 0000000000..7d2e7e6a91 --- /dev/null +++ b/web/template/attorney_fixtures.gohtml @@ -0,0 +1,85 @@ +{{ template "page" . }} + +{{ define "pageTitle" }}Attorney fixtures{{ end }} + +{{ define "main" }} +
    +
    +

    Attorney fixtures

    + +
    +

    Entering an email will cause a reference code to be sent and redirect you to the start page. Leave it blank to be signed in and taken to the dashboard instead.

    + {{ template "input" (input . "email" "email" "" "classes" "govuk-input--width-20" "type" "email" "spellcheck" "false" "autocomplete" "email") }} + +
    +
    + As +
    +
    + + +
    +
    + + +
    +
    +
    +
    + +
    +
    + LPA type +
    +
    + + +
    +
    + + +
    +
    +
    +
    + +
    + Progress +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    + +
    + +
    + {{ template "csrf-field" . }} +
    +
    +
    +{{ end }} diff --git a/web/template/attorney_what_happens_when_you_sign.gohtml b/web/template/attorney_what_happens_when_you_sign.gohtml index c757b9c41a..f5ec571a84 100644 --- a/web/template/attorney_what_happens_when_you_sign.gohtml +++ b/web/template/attorney_what_happens_when_you_sign.gohtml @@ -11,7 +11,7 @@ {{ if .Lpa.Type.IsHealthWelfare }} {{ if and .App.IsReplacementAttorney .App.IsTrustCorporation }} - {{ trFormatHtml .App "whatHappensWhenYouSignTheLpaContentReplacementTrustCorporationPw" "DonorFullNamePossessive" $donorFullNamePossessive "TrustCorporationName" .Lpa.Attorneys.TrustCorporation.Name }} + {{ trFormatHtml .App "whatHappensWhenYouSignTheLpaContentReplacementTrustCorporationPw" "DonorFullNamePossessive" $donorFullNamePossessive "TrustCorporationName" .Lpa.ReplacementAttorneys.TrustCorporation.Name }} {{ else if .App.IsTrustCorporation }} {{ trFormatHtml .App "whatHappensWhenYouSignTheLpaContentTrustCorporationPw" "DonorFullNamePossessive" $donorFullNamePossessive "TrustCorporationName" .Lpa.Attorneys.TrustCorporation.Name }} {{ else if .App.IsReplacementAttorney }} @@ -29,7 +29,7 @@ {{ end }} {{ else }} {{ if and .App.IsReplacementAttorney .App.IsTrustCorporation }} - {{ trFormatHtml .App "whatHappensWhenYouSignTheLpaContentReplacementTrustCorporationPa" "DonorFullNamePossessive" $donorFullNamePossessive "TrustCorporationName" .Lpa.Attorneys.TrustCorporation.Name }} + {{ trFormatHtml .App "whatHappensWhenYouSignTheLpaContentReplacementTrustCorporationPa" "DonorFullNamePossessive" $donorFullNamePossessive "TrustCorporationName" .Lpa.ReplacementAttorneys.TrustCorporation.Name }} {{ else if .App.IsTrustCorporation }} {{ trFormatHtml .App "whatHappensWhenYouSignTheLpaContentTrustCorporationPa" "DonorFullNamePossessive" $donorFullNamePossessive "TrustCorporationName" .Lpa.Attorneys.TrustCorporation.Name }} {{ else if .App.IsReplacementAttorney }} diff --git a/web/template/certificate_provider_fixtures.gohtml b/web/template/certificate_provider_fixtures.gohtml new file mode 100644 index 0000000000..b3d56538a5 --- /dev/null +++ b/web/template/certificate_provider_fixtures.gohtml @@ -0,0 +1,48 @@ +{{ template "page" . }} + +{{ define "pageTitle" }}Fixtures{{ end }} + +{{ define "main" }} +
    +
    +

    Certificate provider fixtures

    + +

    Starting this flow will send an email with reference code to the email entered below. If you don't care about seeing the email then leave the field blank.

    + +
    + {{ template "input" (input . "email" "email" "" "classes" "govuk-input--width-20" "type" "email" "spellcheck" "false" "autocomplete" "email") }} + +
    + Progress +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    + +
    + +
    + {{ template "csrf-field" . }} +
    +
    +
    +{{ end }} diff --git a/web/template/fixtures.gohtml b/web/template/fixtures.gohtml index 04c03e1ff8..b2b715b007 100644 --- a/web/template/fixtures.gohtml +++ b/web/template/fixtures.gohtml @@ -9,8 +9,8 @@ @@ -138,129 +138,6 @@ {{ template "csrf-field" . }} -
    -

    Certificate provider journey

    -

    Starting this flow will send an email with reference code to the email entered below. If you don't care about seeing the email then leave the field blank.

    - -
    - {{ template "input" (input . "email" "email" "" "classes" "govuk-input--width-20" "type" "email" "spellcheck" "false" "autocomplete" "email") }} - - {{ template "error-message" (errorMessage . "cp-flow-has-donor-paid") }} - -
    -
    -
    - - -
    -
    - - -
    -
    -
    - -
    - -
    - {{ template "csrf-field" . }} -
    - -
    -

    Attorney journey

    -

    Starting this flow will send an email with reference code to the email entered below. If you don't care about seeing the email then leave the field blank.

    - -
    - {{ template "input" (input . "email" "email" "" "classes" "govuk-input--width-20" "type" "email" "spellcheck" "false" "autocomplete" "email") }} - -
    -
    - - Send email to - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    -
    -
    - -
    -
    - - LPA type - -
    -
    - - -
    -
    - - -
    -
    -
    -
    - -
    - -

    LPA

    -
    -
    -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    -
    -
    - -
    - -
    - {{ template "csrf-field" . }} -
    -

    Dashboard