From fd92688ef69e8375591a3a533a6c4b9f16ca3757 Mon Sep 17 00:00:00 2001 From: Joshua Hawxwell Date: Thu, 21 Nov 2024 14:06:04 +0000 Subject: [PATCH] Allow certificate provider to continue when identity does not match --- .../confirm-your-identity.cy.js | 55 +++++--- .../donor/you-cannot-sign-your-lpa-yet.cy.js | 4 +- .../identity_with_one_login_callback.go | 17 ++- .../identity_with_one_login_callback_test.go | 26 ++-- .../one_login_identity_details.go | 50 ------- .../one_login_identity_details_test.go | 130 ------------------ .../certificateproviderpage/register.go | 6 +- .../certificateproviderpage/task_list.go | 8 +- .../certificateproviderpage/task_list_test.go | 4 +- .../unable_to_confirm_identity.go | 38 ----- .../unable_to_confirm_identity_test.go | 85 ------------ internal/certificateprovider/path.go | 5 +- internal/templatefn/paths.go | 4 +- lang/cy.json | 4 +- lang/en.json | 4 +- .../identity_details.gohtml | 51 +++++++ .../onelogin_identity_details.gohtml | 20 --- .../unable_to_confirm_identity.gohtml | 18 --- web/template/donor/identity_details.gohtml | 2 +- web/template/layout/identity-details.gohtml | 13 +- .../voucher/one_login_identity_details.gohtml | 2 +- 21 files changed, 137 insertions(+), 409 deletions(-) delete mode 100644 internal/certificateprovider/certificateproviderpage/one_login_identity_details.go delete mode 100644 internal/certificateprovider/certificateproviderpage/one_login_identity_details_test.go delete mode 100644 internal/certificateprovider/certificateproviderpage/unable_to_confirm_identity.go delete mode 100644 internal/certificateprovider/certificateproviderpage/unable_to_confirm_identity_test.go create mode 100644 web/template/certificateprovider/identity_details.gohtml delete mode 100644 web/template/certificateprovider/onelogin_identity_details.gohtml delete mode 100644 web/template/certificateprovider/unable_to_confirm_identity.gohtml diff --git a/cypress/e2e/certificate-provider/confirm-your-identity.cy.js b/cypress/e2e/certificate-provider/confirm-your-identity.cy.js index 220bdd29f7..3ea73c661a 100644 --- a/cypress/e2e/certificate-provider/confirm-your-identity.cy.js +++ b/cypress/e2e/certificate-provider/confirm-your-identity.cy.js @@ -8,45 +8,57 @@ describe('confirm your identity', () => { .click(); }) - it('can see details of a successful ID check', () => { + it('can see details when successful', () => { cy.contains('button', 'Continue').click() cy.get('[name="user"]').check('certificate-provider', { force: true }) cy.contains('button', 'Continue').click() - cy.url().should('contain', '/one-login-identity-details'); + cy.url().should('contain', '/identity-details'); cy.checkA11yApp(); cy.contains('Charlie') cy.contains('Cooper') cy.contains('2 January 1990') - cy.contains('button', 'Continue').click() - - cy.url().should('contain', '/read-the-lpa'); - cy.checkA11yApp(); - cy.contains('a', 'Return to task list').click() cy.url().should('contain', '/task-list'); - cy.contains('li', 'Confirm your identity').should('contain', 'Completed').click(); - cy.url().should('contain', '/read-the-lpa'); + cy.url().should('contain', '/identity-details'); + cy.contains('You have successfully confirmed your identity'); }) - it('can see next steps when failing an ID check', () => { + it('can see details when not matched', () => { cy.contains('button', 'Continue').click() - cy.get('[name="return-code"]').check('T', { force: true }) + cy.get('[name="user"]').check('donor', { force: true }) cy.contains('button', 'Continue').click() - cy.url().should('contain', '/unable-to-confirm-identity'); + cy.url().should('contain', '/identity-details'); cy.checkA11yApp(); + cy.contains('Charlie') + cy.contains('Cooper') + cy.contains('2 January 1990') + + cy.contains('a', 'Return to task list').click() + + cy.url().should('contain', '/task-list'); + cy.contains('li', 'Confirm your identity').should('contain', 'Pending').click(); + + cy.url().should('contain', '/identity-details'); + cy.contains('Some of the details on the LPA do not match'); + }) + + it('can see next steps when failing', () => { + cy.contains('button', 'Continue').click() + cy.get('[name="return-code"]').check('T', { force: true }) + cy.contains('button', 'Continue').click() - cy.url().should('contain', '/read-the-lpa'); + cy.url().should('contain', '/identity-details'); cy.checkA11yApp(); cy.contains('a', 'Return to task list').click() @@ -54,21 +66,17 @@ describe('confirm your identity', () => { cy.url().should('contain', '/task-list'); cy.contains('li', 'Confirm your identity').should('contain', 'Completed').click(); - cy.url().should('contain', '/read-the-lpa'); + cy.url().should('contain', '/identity-details'); + cy.contains('You were not able to confirm your identity'); }) - it('can see next steps when has insufficient evidence for ID', () => { + it('can see next steps when has insufficient evidence', () => { cy.contains('button', 'Continue').click() cy.get('[name="return-code"]').check('X', { force: true }) cy.contains('button', 'Continue').click() - cy.url().should('contain', '/unable-to-confirm-identity'); - cy.checkA11yApp(); - - cy.contains('button', 'Continue').click() - - cy.url().should('contain', '/read-the-lpa'); + cy.url().should('contain', '/identity-details'); cy.checkA11yApp(); cy.contains('a', 'Return to task list').click() @@ -76,7 +84,8 @@ describe('confirm your identity', () => { cy.url().should('contain', '/task-list'); cy.contains('li', 'Confirm your identity').should('contain', 'Completed').click(); - cy.url().should('contain', '/read-the-lpa'); + cy.url().should('contain', '/identity-details'); + cy.contains('You were not able to confirm your identity'); }) it('can go to the post office ', () => { @@ -98,5 +107,7 @@ describe('confirm your identity', () => { .should('contain', 'Pending') .find('a') .click(); + + cy.url().should('contain', '/completing-your-identity-confirmation'); }); }) 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 3e7ce209b3..e9842617a5 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 @@ -18,14 +18,14 @@ describe('You cannot sign your LPA yet', () => { cy.contains('a', 'Check and send to your certificate provider').click() cy.url().should('contain', '/you-cannot-sign-your-lpa-yet') - cy.contains('dt', 'Jessie Jones’ date of birth').parent().contains('a', 'Change').click(); + cy.contains('.govuk-summary-list__row', 'Jessie Jones’ date of birth').contains('a', 'Change').click(); cy.url().should('contain', '/choose-attorneys') cy.get('#f-date-of-birth-year').clear().type("2000") cy.contains('button', 'Save and continue').click() cy.url().should('contain', '/you-cannot-sign-your-lpa-yet') - cy.contains('dt', 'Blake Buckley’s date of birth').parent().contains('a', 'Change').click(); + cy.contains('.govuk-summary-list__row', 'Blake Buckley’s date of birth').contains('a', 'Change').click(); cy.url().should('contain', '/choose-replacement-attorneys') cy.get('#f-date-of-birth-year').clear().type("2000") diff --git a/internal/certificateprovider/certificateproviderpage/identity_with_one_login_callback.go b/internal/certificateprovider/certificateproviderpage/identity_with_one_login_callback.go index 47003f0c5b..ca6e301911 100644 --- a/internal/certificateprovider/certificateproviderpage/identity_with_one_login_callback.go +++ b/internal/certificateprovider/certificateproviderpage/identity_with_one_login_callback.go @@ -11,12 +11,13 @@ import ( "github.com/ministryofjustice/opg-modernising-lpa/internal/lpastore/lpadata" "github.com/ministryofjustice/opg-modernising-lpa/internal/notify" "github.com/ministryofjustice/opg-modernising-lpa/internal/page" + "github.com/ministryofjustice/opg-modernising-lpa/internal/task" ) func IdentityWithOneLoginCallback(oneLoginClient OneLoginClient, sessionStore SessionStore, certificateProviderStore CertificateProviderStore, notifyClient NotifyClient, lpaStoreClient LpaStoreClient, eventClient EventClient, appPublicURL string) Handler { return func(appData appcontext.Data, w http.ResponseWriter, r *http.Request, certificateProvider *certificateproviderdata.Provided, lpa *lpadata.Lpa) error { if certificateProvider.CertificateProviderIdentityConfirmed(lpa.CertificateProvider.FirstNames, lpa.CertificateProvider.LastName) { - return certificateprovider.PathOneLoginIdentityDetails.Redirect(w, r, appData, certificateProvider.LpaID) + return certificateprovider.PathIdentityDetails.Redirect(w, r, appData, certificateProvider.LpaID) } if r.FormValue("error") == "access_denied" { @@ -46,7 +47,13 @@ func IdentityWithOneLoginCallback(oneLoginClient OneLoginClient, sessionStore Se certificateProvider.IdentityUserData = userData - if err = certificateProviderStore.Put(r.Context(), certificateProvider); err != nil { + if userData.Status.IsConfirmed() && !certificateProvider.CertificateProviderIdentityConfirmed(lpa.CertificateProvider.FirstNames, lpa.CertificateProvider.LastName) { + certificateProvider.Tasks.ConfirmYourIdentity = task.IdentityStatePending + } else { + certificateProvider.Tasks.ConfirmYourIdentity = task.IdentityStateCompleted + } + + if err := certificateProviderStore.Put(r.Context(), certificateProvider); err != nil { return err } @@ -55,7 +62,7 @@ func IdentityWithOneLoginCallback(oneLoginClient OneLoginClient, sessionStore Se return err } - return certificateprovider.PathOneLoginIdentityDetails.Redirect(w, r, appData, certificateProvider.LpaID) + return certificateprovider.PathIdentityDetails.Redirect(w, r, appData, certificateProvider.LpaID) } if certificateProvider.IdentityUserData.Status.IsConfirmed() || certificateProvider.IdentityUserData.Status.IsFailed() { @@ -78,7 +85,7 @@ func IdentityWithOneLoginCallback(oneLoginClient OneLoginClient, sessionStore Se } if certificateProvider.IdentityUserData.Status.IsConfirmed() { - return certificateprovider.PathOneLoginIdentityDetails.Redirect(w, r, appData, certificateProvider.LpaID) + return certificateprovider.PathIdentityDetails.Redirect(w, r, appData, certificateProvider.LpaID) } if lpa.SignedForDonor() { @@ -93,6 +100,6 @@ func IdentityWithOneLoginCallback(oneLoginClient OneLoginClient, sessionStore Se } } - return certificateprovider.PathUnableToConfirmIdentity.Redirect(w, r, appData, certificateProvider.LpaID) + return certificateprovider.PathIdentityDetails.Redirect(w, r, appData, certificateProvider.LpaID) } } diff --git a/internal/certificateprovider/certificateproviderpage/identity_with_one_login_callback_test.go b/internal/certificateprovider/certificateproviderpage/identity_with_one_login_callback_test.go index 9f2d7aa6df..d77f8d374c 100644 --- a/internal/certificateprovider/certificateproviderpage/identity_with_one_login_callback_test.go +++ b/internal/certificateprovider/certificateproviderpage/identity_with_one_login_callback_test.go @@ -19,6 +19,7 @@ import ( "github.com/ministryofjustice/opg-modernising-lpa/internal/onelogin" "github.com/ministryofjustice/opg-modernising-lpa/internal/page" "github.com/ministryofjustice/opg-modernising-lpa/internal/sesh" + "github.com/ministryofjustice/opg-modernising-lpa/internal/task" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) @@ -34,6 +35,7 @@ func TestGetIdentityWithOneLoginCallback(t *testing.T) { updatedCertificateProvider := &certificateproviderdata.Provided{ IdentityUserData: userData, LpaID: "lpa-id", + Tasks: certificateproviderdata.Tasks{ConfirmYourIdentity: task.IdentityStateCompleted}, } certificateProviderStore := newMockCertificateProviderStore(t) @@ -67,7 +69,7 @@ func TestGetIdentityWithOneLoginCallback(t *testing.T) { assert.Nil(t, err) assert.Equal(t, http.StatusFound, resp.StatusCode) - assert.Equal(t, certificateprovider.PathOneLoginIdentityDetails.Format("lpa-id"), resp.Header.Get("Location")) + assert.Equal(t, certificateprovider.PathIdentityDetails.Format("lpa-id"), resp.Header.Get("Location")) } func TestGetIdentityWithOneLoginCallbackWhenIdentityMismatched(t *testing.T) { @@ -85,6 +87,7 @@ func TestGetIdentityWithOneLoginCallbackWhenIdentityMismatched(t *testing.T) { LpaID: "lpa-id", UID: actorUID, IdentityUserData: userData, + Tasks: certificateproviderdata.Tasks{ConfirmYourIdentity: task.IdentityStatePending}, }). Return(nil) @@ -125,7 +128,7 @@ func TestGetIdentityWithOneLoginCallbackWhenIdentityMismatched(t *testing.T) { assert.Nil(t, err) assert.Equal(t, http.StatusFound, resp.StatusCode) - assert.Equal(t, certificateprovider.PathOneLoginIdentityDetails.Format("lpa-id"), resp.Header.Get("Location")) + assert.Equal(t, certificateprovider.PathIdentityDetails.Format("lpa-id"), resp.Header.Get("Location")) } func TestGetIdentityWithOneLoginCallbackWhenIdentityMismatchedEventErrors(t *testing.T) { @@ -178,6 +181,7 @@ func TestGetIdentityWithOneLoginCallbackWhenIdentityCheckFailed(t *testing.T) { updatedCertificateProvider := &certificateproviderdata.Provided{ IdentityUserData: userData, LpaID: "lpa-id", + Tasks: certificateproviderdata.Tasks{ConfirmYourIdentity: task.IdentityStateCompleted}, } certificateProviderStore := newMockCertificateProviderStore(t) @@ -245,7 +249,7 @@ func TestGetIdentityWithOneLoginCallbackWhenIdentityCheckFailed(t *testing.T) { assert.Nil(t, err) assert.Equal(t, http.StatusFound, resp.StatusCode) - assert.Equal(t, certificateprovider.PathUnableToConfirmIdentity.Format("lpa-id"), resp.Header.Get("Location")) + assert.Equal(t, certificateprovider.PathIdentityDetails.Format("lpa-id"), resp.Header.Get("Location")) } func TestGetIdentityWithOneLoginCallbackWhenSendingEmailError(t *testing.T) { @@ -255,14 +259,9 @@ func TestGetIdentityWithOneLoginCallbackWhenSendingEmailError(t *testing.T) { userInfo := onelogin.UserInfo{CoreIdentityJWT: "an-identity-jwt"} userData := identity.UserData{Status: identity.StatusFailed} - updatedCertificateProvider := &certificateproviderdata.Provided{ - IdentityUserData: userData, - LpaID: "lpa-id", - } - certificateProviderStore := newMockCertificateProviderStore(t) certificateProviderStore.EXPECT(). - Put(mock.Anything, updatedCertificateProvider). + Put(mock.Anything, mock.Anything). Return(nil) sessionStore := newMockSessionStore(t) @@ -361,12 +360,15 @@ func TestGetIdentityWithOneLoginCallbackWhenIdentityNotConfirmed(t *testing.T) { certificateProviderStore: func(t *testing.T) *mockCertificateProviderStore { certificateProviderStore := newMockCertificateProviderStore(t) certificateProviderStore.EXPECT(). - Put(context.Background(), &certificateproviderdata.Provided{LpaID: "lpa-id"}). + Put(context.Background(), &certificateproviderdata.Provided{ + LpaID: "lpa-id", + Tasks: certificateproviderdata.Tasks{ConfirmYourIdentity: task.IdentityStateCompleted}, + }). Return(nil) return certificateProviderStore }, - expectedRedirectURL: certificateprovider.PathUnableToConfirmIdentity.Format("lpa-id"), + expectedRedirectURL: certificateprovider.PathIdentityDetails.Format("lpa-id"), expectedStatus: http.StatusFound, }, "errored on parse": { @@ -531,5 +533,5 @@ func TestGetIdentityWithOneLoginCallbackWhenReturning(t *testing.T) { assert.Nil(t, err) assert.Equal(t, http.StatusFound, resp.StatusCode) - assert.Equal(t, certificateprovider.PathOneLoginIdentityDetails.Format("lpa-id"), resp.Header.Get("Location")) + assert.Equal(t, certificateprovider.PathIdentityDetails.Format("lpa-id"), resp.Header.Get("Location")) } diff --git a/internal/certificateprovider/certificateproviderpage/one_login_identity_details.go b/internal/certificateprovider/certificateproviderpage/one_login_identity_details.go deleted file mode 100644 index 910aa9110f..0000000000 --- a/internal/certificateprovider/certificateproviderpage/one_login_identity_details.go +++ /dev/null @@ -1,50 +0,0 @@ -package certificateproviderpage - -import ( - "net/http" - - "github.com/ministryofjustice/opg-go-common/template" - "github.com/ministryofjustice/opg-modernising-lpa/internal/appcontext" - "github.com/ministryofjustice/opg-modernising-lpa/internal/certificateprovider" - "github.com/ministryofjustice/opg-modernising-lpa/internal/certificateprovider/certificateproviderdata" - "github.com/ministryofjustice/opg-modernising-lpa/internal/lpastore/lpadata" - "github.com/ministryofjustice/opg-modernising-lpa/internal/task" - "github.com/ministryofjustice/opg-modernising-lpa/internal/validation" -) - -type oneLoginIdentityDetailsData struct { - App appcontext.Data - Errors validation.List - Provided *certificateproviderdata.Provided - DonorFullName string -} - -func OneLoginIdentityDetails(tmpl template.Template, certificateProviderStore CertificateProviderStore) Handler { - return func(appData appcontext.Data, w http.ResponseWriter, r *http.Request, certificateProvider *certificateproviderdata.Provided, lpa *lpadata.Lpa) error { - data := &oneLoginIdentityDetailsData{ - App: appData, - Provided: certificateProvider, - DonorFullName: lpa.Donor.FullName(), - } - - if r.Method == http.MethodPost { - if certificateProvider.CertificateProviderIdentityConfirmed( - lpa.CertificateProvider.FirstNames, - lpa.CertificateProvider.LastName, - ) { - certificateProvider.Tasks.ConfirmYourIdentity = task.IdentityStateCompleted - - if err := certificateProviderStore.Put(r.Context(), certificateProvider); err != nil { - return err - } - - return certificateprovider.PathReadTheLpa.Redirect(w, r, appData, certificateProvider.LpaID) - } else { - // TODO: will be changed in MLPAB-2234 - return certificateprovider.PathConfirmYourIdentity.Redirect(w, r, appData, certificateProvider.LpaID) - } - } - - return tmpl(w, data) - } -} diff --git a/internal/certificateprovider/certificateproviderpage/one_login_identity_details_test.go b/internal/certificateprovider/certificateproviderpage/one_login_identity_details_test.go deleted file mode 100644 index ff0ebd7ea2..0000000000 --- a/internal/certificateprovider/certificateproviderpage/one_login_identity_details_test.go +++ /dev/null @@ -1,130 +0,0 @@ -package certificateproviderpage - -import ( - "net/http" - "net/http/httptest" - "testing" - - "github.com/ministryofjustice/opg-modernising-lpa/internal/certificateprovider" - "github.com/ministryofjustice/opg-modernising-lpa/internal/certificateprovider/certificateproviderdata" - "github.com/ministryofjustice/opg-modernising-lpa/internal/date" - "github.com/ministryofjustice/opg-modernising-lpa/internal/identity" - "github.com/ministryofjustice/opg-modernising-lpa/internal/lpastore/lpadata" - "github.com/ministryofjustice/opg-modernising-lpa/internal/task" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" -) - -func TestGetOneLoginIdentityDetails(t *testing.T) { - r := httptest.NewRequest(http.MethodGet, "/", nil) - w := httptest.NewRecorder() - - certificateProvider := &certificateproviderdata.Provided{ - IdentityUserData: identity.UserData{Status: identity.StatusConfirmed, FirstNames: "a", LastName: "b"}, - LpaID: "lpa-id", - } - - lpa := &lpadata.Lpa{ - LpaUID: "lpa-uid", - CertificateProvider: lpadata.CertificateProvider{FirstNames: "a", LastName: "b"}, - Donor: lpadata.Donor{FirstNames: "c", LastName: "d"}, - } - - template := newMockTemplate(t) - template.EXPECT(). - Execute(w, &oneLoginIdentityDetailsData{ - App: testAppData, - Provided: certificateProvider, - DonorFullName: "c d", - }). - Return(nil) - - err := OneLoginIdentityDetails(template.Execute, nil)(testAppData, w, r, certificateProvider, lpa) - resp := w.Result() - - assert.Nil(t, err) - assert.Equal(t, http.StatusOK, resp.StatusCode) -} - -func TestGetOneLoginIdentityDetailsWhenTemplateErrors(t *testing.T) { - r := httptest.NewRequest(http.MethodGet, "/", nil) - w := httptest.NewRecorder() - - template := newMockTemplate(t) - template.EXPECT(). - Execute(mock.Anything, mock.Anything). - Return(expectedError) - - err := OneLoginIdentityDetails(template.Execute, nil)(testAppData, w, r, &certificateproviderdata.Provided{}, &lpadata.Lpa{}) - resp := w.Result() - - assert.Equal(t, expectedError, err) - assert.Equal(t, http.StatusOK, resp.StatusCode) -} - -func TestPostOneLoginIdentityDetails(t *testing.T) { - r := httptest.NewRequest(http.MethodPost, "/", nil) - w := httptest.NewRecorder() - - updatedCertificateProvider := &certificateproviderdata.Provided{ - IdentityUserData: identity.UserData{Status: identity.StatusConfirmed, FirstNames: "a", LastName: "b", DateOfBirth: date.New("2000", "1", "1")}, - LpaID: "lpa-id", - DateOfBirth: date.New("2000", "1", "1"), - Tasks: certificateproviderdata.Tasks{ConfirmYourIdentity: task.IdentityStateCompleted}, - } - - lpa := &lpadata.Lpa{LpaUID: "lpa-uid", CertificateProvider: lpadata.CertificateProvider{FirstNames: "a", LastName: "b"}} - - certificateProviderStore := newMockCertificateProviderStore(t) - certificateProviderStore.EXPECT(). - Put(r.Context(), updatedCertificateProvider). - Return(nil) - - err := OneLoginIdentityDetails(nil, certificateProviderStore)(testAppData, w, r, &certificateproviderdata.Provided{ - IdentityUserData: identity.UserData{Status: identity.StatusConfirmed, FirstNames: "a", LastName: "b", DateOfBirth: date.New("2000", "1", "1")}, - DateOfBirth: date.New("2000", "1", "1"), - LpaID: "lpa-id", - }, lpa) - resp := w.Result() - - assert.Nil(t, err) - assert.Equal(t, http.StatusFound, resp.StatusCode) - assert.Equal(t, certificateprovider.PathReadTheLpa.Format("lpa-id"), resp.Header.Get("Location")) -} - -func TestPostOneLoginIdentityDetailsWhenDetailsDoNotMatch(t *testing.T) { - r := httptest.NewRequest(http.MethodPost, "/", nil) - w := httptest.NewRecorder() - - lpa := &lpadata.Lpa{LpaUID: "lpa-uid", CertificateProvider: lpadata.CertificateProvider{FirstNames: "x", LastName: "y"}} - - err := OneLoginIdentityDetails(nil, nil)(testAppData, w, r, &certificateproviderdata.Provided{ - IdentityUserData: identity.UserData{Status: identity.StatusConfirmed, FirstNames: "a", LastName: "b", DateOfBirth: date.New("2000", "1", "1")}, - DateOfBirth: date.New("2000", "1", "1"), - LpaID: "lpa-id", - }, lpa) - resp := w.Result() - - assert.Nil(t, err) - assert.Equal(t, http.StatusFound, resp.StatusCode) - assert.Equal(t, certificateprovider.PathConfirmYourIdentity.Format("lpa-id"), resp.Header.Get("Location")) -} - -func TestPostOneLoginIdentityDetailsWhenCertificateProviderStoreErrors(t *testing.T) { - r := httptest.NewRequest(http.MethodPost, "/", nil) - w := httptest.NewRecorder() - - certificateProviderStore := newMockCertificateProviderStore(t) - certificateProviderStore.EXPECT(). - Put(mock.Anything, mock.Anything). - Return(expectedError) - - err := OneLoginIdentityDetails(nil, certificateProviderStore)(testAppData, w, r, &certificateproviderdata.Provided{ - IdentityUserData: identity.UserData{FirstNames: "a", LastName: "b", DateOfBirth: date.New("2000", "1", "1"), Status: identity.StatusConfirmed}, - DateOfBirth: date.New("2000", "1", "1"), - }, &lpadata.Lpa{CertificateProvider: lpadata.CertificateProvider{FirstNames: "a", LastName: "b"}}) - resp := w.Result() - - assert.Equal(t, expectedError, err) - assert.Equal(t, http.StatusOK, resp.StatusCode) -} diff --git a/internal/certificateprovider/certificateproviderpage/register.go b/internal/certificateprovider/certificateproviderpage/register.go index 9e384d3a17..9feea8581f 100644 --- a/internal/certificateprovider/certificateproviderpage/register.go +++ b/internal/certificateprovider/certificateproviderpage/register.go @@ -174,10 +174,8 @@ func Register( IdentityWithOneLogin(oneLoginClient, sessionStore, random.String)) handleCertificateProvider(certificateprovider.PathIdentityWithOneLoginCallback, page.None, IdentityWithOneLoginCallback(oneLoginClient, sessionStore, certificateProviderStore, notifyClient, lpaStoreClient, eventClient, appPublicURL)) - handleCertificateProvider(certificateprovider.PathOneLoginIdentityDetails, page.None, - OneLoginIdentityDetails(tmpls.Get("onelogin_identity_details.gohtml"), certificateProviderStore)) - handleCertificateProvider(certificateprovider.PathUnableToConfirmIdentity, page.None, - UnableToConfirmIdentity(tmpls.Get("unable_to_confirm_identity.gohtml"), certificateProviderStore)) + handleCertificateProvider(certificateprovider.PathIdentityDetails, page.None, + Guidance(tmpls.Get("identity_details.gohtml"))) handleCertificateProvider(certificateprovider.PathReadTheLpa, page.None, ReadTheLpa(tmpls.Get("read_the_lpa.gohtml"), certificateProviderStore)) diff --git a/internal/certificateprovider/certificateproviderpage/task_list.go b/internal/certificateprovider/certificateproviderpage/task_list.go index 3f9fded984..ff274fd891 100644 --- a/internal/certificateprovider/certificateproviderpage/task_list.go +++ b/internal/certificateprovider/certificateproviderpage/task_list.go @@ -34,9 +34,13 @@ func TaskList(tmpl template.Template) Handler { case task.IdentityStateInProgress: identityTaskPage = certificateprovider.PathHowWillYouConfirmYourIdentity case task.IdentityStatePending: - identityTaskPage = certificateprovider.PathCompletingYourIdentityConfirmation + if provided.IdentityUserData.CheckedAt.IsZero() { + identityTaskPage = certificateprovider.PathCompletingYourIdentityConfirmation + } else { + identityTaskPage = certificateprovider.PathIdentityDetails + } case task.IdentityStateCompleted: - identityTaskPage = certificateprovider.PathReadTheLpa + identityTaskPage = certificateprovider.PathIdentityDetails } confirmYourDetailsPage := certificateprovider.PathEnterDateOfBirth diff --git a/internal/certificateprovider/certificateproviderpage/task_list_test.go b/internal/certificateprovider/certificateproviderpage/task_list_test.go index 4f4c95fc35..f460d43766 100644 --- a/internal/certificateprovider/certificateproviderpage/task_list_test.go +++ b/internal/certificateprovider/certificateproviderpage/task_list_test.go @@ -93,7 +93,7 @@ func TestGetTaskList(t *testing.T) { items[0].State = task.StateCompleted items[0].Path = certificateprovider.PathConfirmYourDetails items[1].IdentityState = task.IdentityStateCompleted - items[1].Path = certificateprovider.PathReadTheLpa + items[1].Path = certificateprovider.PathIdentityDetails items[2].State = task.StateCompleted return items @@ -118,7 +118,7 @@ func TestGetTaskList(t *testing.T) { items[0].State = task.StateCompleted items[0].Path = certificateprovider.PathConfirmYourDetails items[1].IdentityState = task.IdentityStateCompleted - items[1].Path = certificateprovider.PathReadTheLpa + items[1].Path = certificateprovider.PathIdentityDetails items[2].State = task.StateCompleted return items diff --git a/internal/certificateprovider/certificateproviderpage/unable_to_confirm_identity.go b/internal/certificateprovider/certificateproviderpage/unable_to_confirm_identity.go deleted file mode 100644 index a290a8220a..0000000000 --- a/internal/certificateprovider/certificateproviderpage/unable_to_confirm_identity.go +++ /dev/null @@ -1,38 +0,0 @@ -package certificateproviderpage - -import ( - "net/http" - - "github.com/ministryofjustice/opg-go-common/template" - "github.com/ministryofjustice/opg-modernising-lpa/internal/appcontext" - "github.com/ministryofjustice/opg-modernising-lpa/internal/certificateprovider" - "github.com/ministryofjustice/opg-modernising-lpa/internal/certificateprovider/certificateproviderdata" - "github.com/ministryofjustice/opg-modernising-lpa/internal/lpastore/lpadata" - "github.com/ministryofjustice/opg-modernising-lpa/internal/task" - "github.com/ministryofjustice/opg-modernising-lpa/internal/validation" -) - -type unableToConfirmIdentityData struct { - App appcontext.Data - Donor lpadata.Donor - Errors validation.List -} - -func UnableToConfirmIdentity(tmpl template.Template, certificateProviderStore CertificateProviderStore) Handler { - return func(appData appcontext.Data, w http.ResponseWriter, r *http.Request, certificateProvider *certificateproviderdata.Provided, lpa *lpadata.Lpa) error { - if r.Method == http.MethodPost { - certificateProvider.Tasks.ConfirmYourIdentity = task.IdentityStateCompleted - - if err := certificateProviderStore.Put(r.Context(), certificateProvider); err != nil { - return err - } - - return certificateprovider.PathReadTheLpa.Redirect(w, r, appData, certificateProvider.LpaID) - } - - return tmpl(w, &unableToConfirmIdentityData{ - App: appData, - Donor: lpa.Donor, - }) - } -} diff --git a/internal/certificateprovider/certificateproviderpage/unable_to_confirm_identity_test.go b/internal/certificateprovider/certificateproviderpage/unable_to_confirm_identity_test.go deleted file mode 100644 index 7acf159b37..0000000000 --- a/internal/certificateprovider/certificateproviderpage/unable_to_confirm_identity_test.go +++ /dev/null @@ -1,85 +0,0 @@ -package certificateproviderpage - -import ( - "net/http" - "net/http/httptest" - "testing" - - "github.com/ministryofjustice/opg-modernising-lpa/internal/certificateprovider" - "github.com/ministryofjustice/opg-modernising-lpa/internal/certificateprovider/certificateproviderdata" - "github.com/ministryofjustice/opg-modernising-lpa/internal/lpastore/lpadata" - "github.com/ministryofjustice/opg-modernising-lpa/internal/task" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" -) - -func TestGetUnableToConfirmIdentity(t *testing.T) { - r := httptest.NewRequest(http.MethodGet, "/", nil) - w := httptest.NewRecorder() - - template := newMockTemplate(t) - template.EXPECT(). - Execute(w, &unableToConfirmIdentityData{ - App: testAppData, - Donor: lpadata.Donor{FirstNames: "a"}, - }). - Return(nil) - - err := UnableToConfirmIdentity(template.Execute, nil)(testAppData, w, r, nil, &lpadata.Lpa{Donor: lpadata.Donor{FirstNames: "a"}}) - resp := w.Result() - - assert.Nil(t, err) - assert.Equal(t, http.StatusOK, resp.StatusCode) -} - -func TestGetUnableToConfirmIdentityWhenTemplateErrors(t *testing.T) { - r := httptest.NewRequest(http.MethodGet, "/", nil) - w := httptest.NewRecorder() - - template := newMockTemplate(t) - template.EXPECT(). - Execute(mock.Anything, mock.Anything). - Return(expectedError) - - err := UnableToConfirmIdentity(template.Execute, nil)(testAppData, w, r, nil, &lpadata.Lpa{}) - resp := w.Result() - - assert.Equal(t, expectedError, err) - assert.Equal(t, http.StatusOK, resp.StatusCode) -} - -func TestPostUnableToConfirmIdentity(t *testing.T) { - r := httptest.NewRequest(http.MethodPost, "/", nil) - w := httptest.NewRecorder() - - certificateProviderStore := newMockCertificateProviderStore(t) - certificateProviderStore.EXPECT(). - Put(r.Context(), &certificateproviderdata.Provided{ - LpaID: "lpa-id", - Tasks: certificateproviderdata.Tasks{ConfirmYourIdentity: task.IdentityStateCompleted}, - }). - Return(nil) - - err := UnableToConfirmIdentity(nil, certificateProviderStore)(testAppData, w, r, &certificateproviderdata.Provided{LpaID: "lpa-id"}, nil) - resp := w.Result() - - assert.Nil(t, err) - assert.Equal(t, http.StatusFound, resp.StatusCode) - assert.Equal(t, certificateprovider.PathReadTheLpa.Format("lpa-id"), resp.Header.Get("Location")) -} - -func TestPostUnableToConfirmIdentityWhenCertificateProviderStoreErrors(t *testing.T) { - r := httptest.NewRequest(http.MethodPost, "/", nil) - w := httptest.NewRecorder() - - certificateProviderStore := newMockCertificateProviderStore(t) - certificateProviderStore.EXPECT(). - Put(mock.Anything, mock.Anything). - Return(expectedError) - - err := UnableToConfirmIdentity(nil, certificateProviderStore)(testAppData, w, r, &certificateproviderdata.Provided{}, nil) - resp := w.Result() - - assert.Equal(t, expectedError, err) - assert.Equal(t, http.StatusOK, resp.StatusCode) -} diff --git a/internal/certificateprovider/path.go b/internal/certificateprovider/path.go index a3dc9ca97b..1345cb622c 100644 --- a/internal/certificateprovider/path.go +++ b/internal/certificateprovider/path.go @@ -19,12 +19,11 @@ const ( PathHowWillYouConfirmYourIdentity = Path("/how-will-you-confirm-your-identity") PathIdentityWithOneLogin = Path("/identity-with-one-login") PathIdentityWithOneLoginCallback = Path("/identity-with-one-login-callback") - PathOneLoginIdentityDetails = Path("/one-login-identity-details") + PathIdentityDetails = Path("/identity-details") PathProvideCertificate = Path("/provide-certificate") PathReadTheLpa = Path("/read-the-lpa") PathReadTheDraftLpa = Path("/read-the-draft-lpa") PathTaskList = Path("/task-list") - PathUnableToConfirmIdentity = Path("/unable-to-confirm-identity") PathWhatHappensNext = Path("/what-happens-next") PathWhatIsYourHomeAddress = Path("/what-is-your-home-address") PathWhoIsEligible = Path("/certificate-provider-who-is-eligible") @@ -58,7 +57,7 @@ func (p Path) CanGoTo(certificateProvider *certificateproviderdata.Provided, lpa PathHowWillYouConfirmYourIdentity, PathIdentityWithOneLogin, PathIdentityWithOneLoginCallback, - PathOneLoginIdentityDetails: + PathIdentityDetails: return lpa.Paid && lpa.SignedForDonor() && certificateProvider.Tasks.ConfirmYourDetails.IsCompleted() diff --git a/internal/templatefn/paths.go b/internal/templatefn/paths.go index f1ff697304..0844b39d2c 100644 --- a/internal/templatefn/paths.go +++ b/internal/templatefn/paths.go @@ -53,7 +53,6 @@ type certificateProviderPaths struct { ReadTheDraftLpa certificateprovider.Path ReadTheLpa certificateprovider.Path TaskList certificateprovider.Path - UnableToConfirmIdentity certificateprovider.Path WhatHappensNext certificateprovider.Path WhatIsYourHomeAddress certificateprovider.Path WhoIsEligible certificateprovider.Path @@ -261,12 +260,11 @@ var paths = appPaths{ IdentityWithOneLogin: certificateprovider.PathIdentityWithOneLogin, IdentityWithOneLoginCallback: certificateprovider.PathIdentityWithOneLoginCallback, ProveYourIdentity: certificateprovider.PathConfirmYourIdentity, - OneLoginIdentityDetails: certificateprovider.PathOneLoginIdentityDetails, + OneLoginIdentityDetails: certificateprovider.PathIdentityDetails, ProvideCertificate: certificateprovider.PathProvideCertificate, ReadTheLpa: certificateprovider.PathReadTheLpa, ReadTheDraftLpa: certificateprovider.PathReadTheDraftLpa, TaskList: certificateprovider.PathTaskList, - UnableToConfirmIdentity: certificateprovider.PathUnableToConfirmIdentity, WhatHappensNext: certificateprovider.PathWhatHappensNext, WhatIsYourHomeAddress: certificateprovider.PathWhatIsYourHomeAddress, WhoIsEligible: certificateprovider.PathWhoIsEligible, diff --git a/lang/cy.json b/lang/cy.json index 3a2c0c8086..470555ceb0 100644 --- a/lang/cy.json +++ b/lang/cy.json @@ -1518,5 +1518,7 @@ "howYouWouldLikeToContinue": "Welsh", "enterYourPostcode": "Rhowch eich cod post", "selectYourAddress": "Dewiswch eich cyfeiriad", - "confirmYourAddress": "Cadarnhewch eich cyfeiriad" + "confirmYourAddress": "Cadarnhewch eich cyfeiriad", + "someOfTheDetailsOnTheLpaDoNotMatch": "Welsh", + "yourDetailsCannotBeUpdatedAsAlreadySigned": "

Welsh {{.DonorFullName}}

Welsh

Welsh

" } diff --git a/lang/en.json b/lang/en.json index fe1e856e3d..bfaa6ebc7b 100644 --- a/lang/en.json +++ b/lang/en.json @@ -1410,5 +1410,7 @@ "howYouWouldLikeToContinue": "how you would like to continue", "confirmYourAddress": "Confirm your address", "selectYourAddress": "Select your address", - "enterYourPostcode": "Enter your postcode" + "enterYourPostcode": "Enter your postcode", + "someOfTheDetailsOnTheLpaDoNotMatch": "Some of the details on the LPA do not match your confirmed identity details", + "yourDetailsCannotBeUpdatedAsAlreadySigned": "

Your details on the LPA cannot be updated to match your confirmed identity details. This is because {{.DonorFullName}} has already signed the LPA.

Someone at the Office of the Public Guardian (OPG) will compare your identity details. You will be updated soon.

While your details are being reviewed, you can continue to provide your certificate for this LPA if you wish.

" } diff --git a/web/template/certificateprovider/identity_details.gohtml b/web/template/certificateprovider/identity_details.gohtml new file mode 100644 index 0000000000..13ff5b8738 --- /dev/null +++ b/web/template/certificateprovider/identity_details.gohtml @@ -0,0 +1,51 @@ +{{ template "page" . }} + +{{ define "pageTitle" }} + {{ tr .App "yourIdentityConfirmedWithOneLogin" }} +{{ end }} + +{{ define "main" }} +
+
+ {{ $match := .CertificateProvider.Tasks.ConfirmYourIdentity.IsCompleted }} + + {{ if not .CertificateProvider.IdentityUserData.Status.IsConfirmed }} + {{ template "notification-banner" ( notificationBanner .App "important" (trHtml .App "youHaveBeenUnableToConfirmYourIdentity") "heading" ) }} + + {{ trFormatHtml .App "certificateProviderFailedIDContent" "DonorFullName" .Lpa.Donor.FullName "DonorFirstNames" .Lpa.Donor.FirstNames }} + {{ else }} + {{ if $match }} + {{ template "notification-banner" (notificationBanner .App "success" (trFormatHtml .App "youHaveSuccessfullyConfirmedYourIdentitySuccess:certificate-provider" "DonorFullName" .Lpa.Donor.FullName) "success" "contents" ) }} + {{ else }} + {{ template "notification-banner" (notificationBanner .App "important" (trFormatHtml .App "someOfTheDetailsOnTheLpaDoNotMatch") "heading") }} + +

{{ tr .App "detailsYouHaveGivenUs" }}

+ +
+ {{ template "summary-row" (staticSummaryRow .App "dateOfBirth" (formatDate .App .CertificateProvider.DateOfBirth)) }} +
+ +

{{ tr .App "detailsTheDonorHasGivenAboutYou" }}

+ +
+ {{ with .Lpa.CertificateProvider }} + {{ template "summary-row" (staticSummaryRow $.App "firstNames" .FirstNames) }} + {{ template "summary-row" (staticSummaryRow $.App "lastName" .LastName) }} + {{ template "address-summary-row" (staticSummaryRow $.App "address" .Address) }} + {{ end }} +
+ {{ end }} + + {{ template "identity-details" (card .App .CertificateProvider.IdentityUserData) }} + + {{ if not $match }} +

{{ tr .App "whatHappensNext" }}

+ + {{ trFormatHtml .App "yourDetailsCannotBeUpdatedAsAlreadySigned" "DonorFullName" .Lpa.Donor.FullName }} + {{ end }} + {{ end }} + + {{ template "button" (button .App "returnToTaskList" "link" (global.Paths.CertificateProvider.TaskList.Format .App.LpaID)) }} +
+
+{{ end }} diff --git a/web/template/certificateprovider/onelogin_identity_details.gohtml b/web/template/certificateprovider/onelogin_identity_details.gohtml deleted file mode 100644 index df311e346e..0000000000 --- a/web/template/certificateprovider/onelogin_identity_details.gohtml +++ /dev/null @@ -1,20 +0,0 @@ -{{ template "page" . }} - -{{ define "pageTitle" }} - {{ tr .App "yourIdentityConfirmedWithOneLogin" }} -{{ end }} - -{{ define "main" }} -
-
- {{ template "notification-banner" (notificationBanner .App "success" (trFormatHtml .App "youHaveSuccessfullyConfirmedYourIdentitySuccess:certificate-provider" "DonorFullName" .DonorFullName) "success" "contents" ) }} - - {{ template "identity-details" . }} - -
- {{ template "buttons" (button .App "continue") }} - {{ template "csrf-field" . }} -
-
-
-{{ end }} diff --git a/web/template/certificateprovider/unable_to_confirm_identity.gohtml b/web/template/certificateprovider/unable_to_confirm_identity.gohtml deleted file mode 100644 index 8eca04f0f0..0000000000 --- a/web/template/certificateprovider/unable_to_confirm_identity.gohtml +++ /dev/null @@ -1,18 +0,0 @@ -{{ template "page" . }} - -{{ define "pageTitle" }}{{ tr .App "youHaveBeenUnableToConfirmYourIdentity" }}{{ end }} - -{{ define "main" }} -
-
- {{ template "notification-banner" ( notificationBanner .App "important" (trHtml .App "youHaveBeenUnableToConfirmYourIdentity") "heading" ) }} - - {{ trFormatHtml .App "certificateProviderFailedIDContent" "DonorFullName" .Donor.FullName "DonorFirstNames" .Donor.FirstNames }} - -
- {{ template "buttons" (button .App "continue") }} - {{ template "csrf-field" . }} -
-
-
-{{ end }} diff --git a/web/template/donor/identity_details.gohtml b/web/template/donor/identity_details.gohtml index 7dd24b3dc9..a6bf97be61 100644 --- a/web/template/donor/identity_details.gohtml +++ b/web/template/donor/identity_details.gohtml @@ -65,7 +65,7 @@ {{ end }} - {{ template "identity-details" . }} + {{ template "identity-details" (card .App .Provided.IdentityUserData) }} {{ if .DetailsMatch }} {{ template "button" (button .App "returnToTaskList" "link" (global.Paths.TaskList.Format .Provided.LpaID)) }} diff --git a/web/template/layout/identity-details.gohtml b/web/template/layout/identity-details.gohtml index 0d7564b640..822b3e1fb1 100644 --- a/web/template/layout/identity-details.gohtml +++ b/web/template/layout/identity-details.gohtml @@ -1,19 +1,14 @@ {{ define "identity-details" }} - {{ $fullName := (printf "%s %s" .Provided.IdentityUserData.FirstNames .Provided.IdentityUserData.LastName) }} -

{{ tr .App "yourConfirmedIdentityDetails" }}

- {{ template "summary-row" (summaryRow .App "firstNames" .Provided.IdentityUserData.FirstNames "" $fullName false true ) }} - - {{ template "summary-row" (summaryRow .App "lastName" .Provided.IdentityUserData.LastName "" $fullName false true ) }} - - {{ template "summary-row" (summaryRow .App "dateOfBirth" (formatDate .App .Provided.IdentityUserData.DateOfBirth) "" $fullName false true ) }} - - {{ template "address-summary-row" (summaryRow $.App "address" .Provided.IdentityUserData.CurrentAddress "" $fullName false true ) }} + {{ template "summary-row" (staticSummaryRow .App "firstNames" .Item.FirstNames) }} + {{ template "summary-row" (staticSummaryRow .App "lastName" .Item.LastName) }} + {{ template "summary-row" (staticSummaryRow .App "dateOfBirth" (formatDate .App .Item.DateOfBirth)) }} + {{ template "address-summary-row" (staticSummaryRow $.App "address" .Item.CurrentAddress) }}
diff --git a/web/template/voucher/one_login_identity_details.gohtml b/web/template/voucher/one_login_identity_details.gohtml index cbd58f9500..fded6a877a 100644 --- a/web/template/voucher/one_login_identity_details.gohtml +++ b/web/template/voucher/one_login_identity_details.gohtml @@ -9,7 +9,7 @@
{{ template "notification-banner" (notificationBanner .App "success" (trHtml .App "youHaveSuccessfullyConfirmedYourIdentitySuccess:voucher") "success" "contents" ) }} - {{ template "identity-details" . }} + {{ template "identity-details" (card .App .Provided.IdentityUserData) }}
{{ template "buttons" (button .App "continue" "link" (global.Paths.Voucher.TaskList.Format .App.LpaID)) }}