diff --git a/cypress/e2e/voucher/confirm-your-identity.cy.js b/cypress/e2e/voucher/confirm-your-identity.cy.js index 863cca8ad7..7ca05b0651 100644 --- a/cypress/e2e/voucher/confirm-your-identity.cy.js +++ b/cypress/e2e/voucher/confirm-your-identity.cy.js @@ -26,6 +26,28 @@ describe('Confirm your identity', () => { cy.contains('I’m vouching for someone'); }); + it('warns when matches another actor', () => { + cy.visitLpa('/your-name'); + cy.get('#f-first-names').clear().type('Charlie'); + cy.get('#f-last-name').clear().type('Cooper'); + cy.contains('button', 'Save and continue').click(); + cy.contains('button', 'Continue').click(); + cy.visitLpa('/confirm-your-identity'); + + cy.checkA11yApp(); + cy.contains('a', 'Continue').click(); + cy.contains('label', 'Charlie Cooper').click(); + cy.contains('button', 'Continue').click(); + + cy.url().should('contain', '/confirm-allowed-to-vouch'); + cy.checkA11yApp(); + cy.contains('Your confirmed identity details match someone'); + + cy.contains('label', 'Yes').click(); + cy.contains('button', 'Continue').click(); + cy.get('ul li:nth-child(3)').should('contain', 'Completed'); + }); + it('can fail', () => { cy.contains('a', 'Continue').click(); cy.contains('label', 'Sam Smith').click(); diff --git a/cypress/e2e/voucher/confirm-your-name.cy.js b/cypress/e2e/voucher/confirm-your-name.cy.js index 6228508e5f..2aabd6bad7 100644 --- a/cypress/e2e/voucher/confirm-your-name.cy.js +++ b/cypress/e2e/voucher/confirm-your-name.cy.js @@ -40,6 +40,27 @@ describe('Confirm your name', () => { cy.url().should('contain', '/confirm-allowed-to-vouch'); cy.checkA11yApp(); + cy.contains('surname matches your surname'); + + cy.contains('label', 'Yes').click(); + cy.contains('button', 'Continue').click(); + cy.get('ul li:first-child').should('contain', 'Completed'); + }); + + it('warns when name matches another actor', () => { + cy.contains('div', 'Vivian').contains('a', 'Change').click(); + + cy.url().should('contain', '/your-name') + cy.checkA11yApp(); + cy.get('#f-first-names').clear().type('Charlie'); + cy.get('#f-last-name').clear().type('Cooper'); + cy.contains('button', 'Save and continue').click(); + + cy.contains('button', 'Continue').click(); + + cy.url().should('contain', '/confirm-allowed-to-vouch'); + cy.checkA11yApp(); + cy.contains('You have entered a name that matches someone'); cy.contains('label', 'Yes').click(); cy.contains('button', 'Continue').click(); diff --git a/internal/voucher/path.go b/internal/voucher/path.go index 9932e70172..f8af7da661 100644 --- a/internal/voucher/path.go +++ b/internal/voucher/path.go @@ -2,7 +2,6 @@ package voucher import ( "net/http" - "strings" "github.com/ministryofjustice/opg-modernising-lpa/internal/appcontext" "github.com/ministryofjustice/opg-modernising-lpa/internal/voucher/voucherdata" @@ -47,7 +46,7 @@ func (p Path) Redirect(w http.ResponseWriter, r *http.Request, appData appcontex func (p Path) CanGoTo(provided *voucherdata.Provided) bool { switch p { case PathYourName: - return !provided.Tasks.ConfirmYourIdentity.IsCompleted() + return provided.Tasks.ConfirmYourIdentity.IsNotStarted() case PathVerifyDonorDetails: return provided.Tasks.ConfirmYourName.IsCompleted() && @@ -66,17 +65,3 @@ func (p Path) CanGoTo(provided *voucherdata.Provided) bool { return true } } - -func CanGoTo(provided *voucherdata.Provided, url string) bool { - path, _, _ := strings.Cut(url, "?") - if path == "" { - return false - } - - if strings.HasPrefix(path, "/voucher/") { - _, voucherPath, _ := strings.Cut(strings.TrimPrefix(path, "/voucher/"), "/") - return Path("/" + voucherPath).CanGoTo(provided) - } - - return true -} diff --git a/internal/voucher/path_test.go b/internal/voucher/path_test.go index 67ba6129df..e9798b6209 100644 --- a/internal/voucher/path_test.go +++ b/internal/voucher/path_test.go @@ -49,53 +49,48 @@ func TestPathRedirectWhenFrom(t *testing.T) { func TestCanGoTo(t *testing.T) { testcases := map[string]struct { provided *voucherdata.Provided - url string + path Path expected bool }{ - "empty path": { - provided: &voucherdata.Provided{}, - url: "", - expected: false, - }, "unexpected path": { provided: &voucherdata.Provided{}, - url: "/whatever", + path: Path("/whatever"), expected: true, }, "unrestricted path": { provided: &voucherdata.Provided{}, - url: PathTaskList.Format("123"), + path: PathTaskList, expected: true, }, "your name": { provided: &voucherdata.Provided{}, - url: PathYourName.Format("123"), + path: PathYourName, expected: true, }, "your name when identity completed": { provided: &voucherdata.Provided{ Tasks: voucherdata.Tasks{ConfirmYourIdentity: task.StateCompleted}, }, - url: PathYourName.Format("123"), + path: PathYourName, expected: false, }, "verify donor details": { provided: &voucherdata.Provided{}, - url: PathVerifyDonorDetails.Format("123"), + path: PathVerifyDonorDetails, expected: false, }, "verify donor details when previous task completed": { provided: &voucherdata.Provided{ Tasks: voucherdata.Tasks{ConfirmYourName: task.StateCompleted}, }, - url: PathVerifyDonorDetails.Format("123"), + path: PathVerifyDonorDetails, expected: true, }, "verify donor details when already verified": { provided: &voucherdata.Provided{ Tasks: voucherdata.Tasks{ConfirmYourName: task.StateCompleted, VerifyDonorDetails: task.StateCompleted}, }, - url: PathVerifyDonorDetails.Format("123"), + path: PathVerifyDonorDetails, expected: false, }, "confirm your identity": { @@ -104,7 +99,7 @@ func TestCanGoTo(t *testing.T) { ConfirmYourName: task.StateCompleted, }, }, - url: PathConfirmYourIdentity.Format("123"), + path: PathConfirmYourIdentity, expected: false, }, "confirm your identity when previous task completed": { @@ -114,7 +109,7 @@ func TestCanGoTo(t *testing.T) { VerifyDonorDetails: task.StateCompleted, }, }, - url: PathConfirmYourIdentity.Format("123"), + path: PathConfirmYourIdentity, expected: true, }, "sign the declaration": { @@ -124,7 +119,7 @@ func TestCanGoTo(t *testing.T) { VerifyDonorDetails: task.StateCompleted, }, }, - url: PathSignTheDeclaration.Format("123"), + path: PathSignTheDeclaration, expected: false, }, "sign the declaration when previous task completed": { @@ -135,14 +130,14 @@ func TestCanGoTo(t *testing.T) { ConfirmYourIdentity: task.StateCompleted, }, }, - url: PathSignTheDeclaration.Format("123"), + path: PathSignTheDeclaration, expected: true, }, } for name, tc := range testcases { t.Run(name, func(t *testing.T) { - assert.Equal(t, tc.expected, CanGoTo(tc.provided, tc.url)) + assert.Equal(t, tc.expected, tc.path.CanGoTo(tc.provided)) }) } } diff --git a/internal/voucher/voucherpage/confirm_allowed_to_vouch.go b/internal/voucher/voucherpage/confirm_allowed_to_vouch.go index 7228bbc058..09dcfa4497 100644 --- a/internal/voucher/voucherpage/confirm_allowed_to_vouch.go +++ b/internal/voucher/voucherpage/confirm_allowed_to_vouch.go @@ -3,6 +3,7 @@ package voucherpage import ( "errors" "net/http" + "strings" "github.com/ministryofjustice/opg-go-common/template" "github.com/ministryofjustice/opg-modernising-lpa/internal/appcontext" @@ -20,6 +21,7 @@ type confirmAllowedToVouchData struct { Form *form.YesNoForm Lpa *lpadata.Lpa SurnameMatchesDonor bool + MatchIdentity bool } func ConfirmAllowedToVouch(tmpl template.Template, lpaStoreResolvingService LpaStoreResolvingService, voucherStore VoucherStore) Handler { @@ -33,7 +35,8 @@ func ConfirmAllowedToVouch(tmpl template.Template, lpaStoreResolvingService LpaS App: appData, Form: form.NewYesNoForm(form.YesNoUnknown), Lpa: lpa, - SurnameMatchesDonor: provided.LastName == lpa.Donor.LastName, + SurnameMatchesDonor: strings.EqualFold(provided.LastName, lpa.Donor.LastName), + MatchIdentity: provided.Tasks.ConfirmYourIdentity.IsInProgress(), } if r.Method == http.MethodPost { @@ -45,7 +48,12 @@ func ConfirmAllowedToVouch(tmpl template.Template, lpaStoreResolvingService LpaS return errors.New("// TODO there should be a page here but it hasn't been built yet") } - provided.Tasks.ConfirmYourName = task.StateCompleted + if provided.Tasks.ConfirmYourIdentity.IsInProgress() { + provided.Tasks.ConfirmYourIdentity = task.StateCompleted + } else { + provided.Tasks.ConfirmYourName = task.StateCompleted + } + if err := voucherStore.Put(r.Context(), provided); err != nil { return err } diff --git a/internal/voucher/voucherpage/confirm_allowed_to_vouch_test.go b/internal/voucher/voucherpage/confirm_allowed_to_vouch_test.go index 8850b206c8..765ee95e77 100644 --- a/internal/voucher/voucherpage/confirm_allowed_to_vouch_test.go +++ b/internal/voucher/voucherpage/confirm_allowed_to_vouch_test.go @@ -18,33 +18,96 @@ import ( ) func TestGetConfirmAllowedToVouch(t *testing.T) { - w := httptest.NewRecorder() - r, _ := http.NewRequest(http.MethodGet, "/", nil) - - lpaStoreResolvingService := newMockLpaStoreResolvingService(t) - lpaStoreResolvingService.EXPECT(). - Get(r.Context()). - Return(&lpadata.Lpa{ - Voucher: lpadata.Voucher{FirstNames: "V", LastName: "W"}, - }, nil) - - template := newMockTemplate(t) - template.EXPECT(). - Execute(w, &confirmAllowedToVouchData{ - App: testAppData, - Form: form.NewYesNoForm(form.YesNoUnknown), - Lpa: &lpadata.Lpa{ + testcases := map[string]struct { + lpa *lpadata.Lpa + provided *voucherdata.Provided + data *confirmAllowedToVouchData + }{ + "actor matches": { + lpa: &lpadata.Lpa{ Voucher: lpadata.Voucher{FirstNames: "V", LastName: "W"}, }, - SurnameMatchesDonor: true, - }). - Return(nil) + provided: &voucherdata.Provided{ + LpaID: "lpa-id", + FirstNames: "V", + LastName: "W", + }, + data: &confirmAllowedToVouchData{ + App: testAppData, + Form: form.NewYesNoForm(form.YesNoUnknown), + Lpa: &lpadata.Lpa{ + Voucher: lpadata.Voucher{FirstNames: "V", LastName: "W"}, + }, + }, + }, + "surname matches donor": { + lpa: &lpadata.Lpa{ + Donor: lpadata.Donor{FirstNames: "A", LastName: "W"}, + Voucher: lpadata.Voucher{FirstNames: "V", LastName: "W"}, + }, + provided: &voucherdata.Provided{ + LpaID: "lpa-id", + FirstNames: "V", + LastName: "W", + }, + data: &confirmAllowedToVouchData{ + App: testAppData, + Form: form.NewYesNoForm(form.YesNoUnknown), + Lpa: &lpadata.Lpa{ + Donor: lpadata.Donor{FirstNames: "A", LastName: "W"}, + Voucher: lpadata.Voucher{FirstNames: "V", LastName: "W"}, + }, + SurnameMatchesDonor: true, + }, + }, + "matches actor after identity": { + lpa: &lpadata.Lpa{ + Donor: lpadata.Donor{FirstNames: "A", LastName: "W"}, + Voucher: lpadata.Voucher{FirstNames: "V", LastName: "W"}, + }, + provided: &voucherdata.Provided{ + LpaID: "lpa-id", + FirstNames: "V", + LastName: "W", + Tasks: voucherdata.Tasks{ + ConfirmYourIdentity: task.StateInProgress, + }, + }, + data: &confirmAllowedToVouchData{ + App: testAppData, + Form: form.NewYesNoForm(form.YesNoUnknown), + Lpa: &lpadata.Lpa{ + Donor: lpadata.Donor{FirstNames: "A", LastName: "W"}, + Voucher: lpadata.Voucher{FirstNames: "V", LastName: "W"}, + }, + SurnameMatchesDonor: true, + MatchIdentity: true, + }, + }, + } + + for name, tc := range testcases { + t.Run(name, func(t *testing.T) { + w := httptest.NewRecorder() + r, _ := http.NewRequest(http.MethodGet, "/", nil) - err := ConfirmAllowedToVouch(template.Execute, lpaStoreResolvingService, nil)(testAppData, w, r, &voucherdata.Provided{LpaID: "lpa-id"}) - resp := w.Result() + lpaStoreResolvingService := newMockLpaStoreResolvingService(t) + lpaStoreResolvingService.EXPECT(). + Get(r.Context()). + Return(tc.lpa, nil) - assert.Nil(t, err) - assert.Equal(t, http.StatusOK, resp.StatusCode) + template := newMockTemplate(t) + template.EXPECT(). + Execute(w, tc.data). + Return(nil) + + err := ConfirmAllowedToVouch(template.Execute, lpaStoreResolvingService, nil)(testAppData, w, r, tc.provided) + resp := w.Result() + + assert.Nil(t, err) + assert.Equal(t, http.StatusOK, resp.StatusCode) + }) + } } func TestGetConfirmAllowedToVouchWhenLpaStoreResolvingServiceErrors(t *testing.T) { @@ -83,33 +146,39 @@ func TestGetConfirmAllowedToVouchWhenTemplateErrors(t *testing.T) { } func TestPostConfirmAllowedToVouch(t *testing.T) { - f := url.Values{ - form.FieldNames.YesNo: {form.Yes.String()}, + testcases := map[task.State]voucherdata.Tasks{ + task.StateNotStarted: voucherdata.Tasks{ConfirmYourName: task.StateCompleted}, + task.StateInProgress: voucherdata.Tasks{ConfirmYourIdentity: task.StateCompleted}, } - w := httptest.NewRecorder() - r, _ := http.NewRequest(http.MethodPost, "/", strings.NewReader(f.Encode())) - r.Header.Add("Content-Type", page.FormUrlEncoded) - - lpaStoreResolvingService := newMockLpaStoreResolvingService(t) - lpaStoreResolvingService.EXPECT(). - Get(r.Context()). - Return(&lpadata.Lpa{Donor: lpadata.Donor{LastName: "Smith"}}, nil) - - voucherStore := newMockVoucherStore(t) - voucherStore.EXPECT(). - Put(r.Context(), &voucherdata.Provided{ - LpaID: "lpa-id", - Tasks: voucherdata.Tasks{ConfirmYourName: task.StateCompleted}, - }). - Return(nil) - - err := ConfirmAllowedToVouch(nil, lpaStoreResolvingService, voucherStore)(testAppData, w, r, &voucherdata.Provided{LpaID: "lpa-id"}) - resp := w.Result() - - assert.Nil(t, err) - assert.Equal(t, http.StatusFound, resp.StatusCode) - assert.Equal(t, voucher.PathTaskList.Format("lpa-id"), resp.Header.Get("Location")) + for taskState, tasks := range testcases { + t.Run(taskState.String(), func(t *testing.T) { + f := url.Values{ + form.FieldNames.YesNo: {form.Yes.String()}, + } + + w := httptest.NewRecorder() + r, _ := http.NewRequest(http.MethodPost, "/", strings.NewReader(f.Encode())) + r.Header.Add("Content-Type", page.FormUrlEncoded) + + lpaStoreResolvingService := newMockLpaStoreResolvingService(t) + lpaStoreResolvingService.EXPECT(). + Get(r.Context()). + Return(&lpadata.Lpa{Donor: lpadata.Donor{LastName: "Smith"}}, nil) + + voucherStore := newMockVoucherStore(t) + voucherStore.EXPECT(). + Put(r.Context(), &voucherdata.Provided{LpaID: "lpa-id", Tasks: tasks}). + Return(nil) + + err := ConfirmAllowedToVouch(nil, lpaStoreResolvingService, voucherStore)(testAppData, w, r, &voucherdata.Provided{LpaID: "lpa-id", Tasks: voucherdata.Tasks{ConfirmYourIdentity: taskState}}) + resp := w.Result() + + assert.Nil(t, err) + assert.Equal(t, http.StatusFound, resp.StatusCode) + assert.Equal(t, voucher.PathTaskList.Format("lpa-id"), resp.Header.Get("Location")) + }) + } } func TestPostConfirmAllowedToVouchWhenNo(t *testing.T) { diff --git a/internal/voucher/voucherpage/confirm_your_name.go b/internal/voucher/voucherpage/confirm_your_name.go index e7d43b6c71..fe8b9cbd2b 100644 --- a/internal/voucher/voucherpage/confirm_your_name.go +++ b/internal/voucher/voucherpage/confirm_your_name.go @@ -2,6 +2,7 @@ package voucherpage import ( "net/http" + "strings" "github.com/ministryofjustice/opg-go-common/template" "github.com/ministryofjustice/opg-modernising-lpa/internal/appcontext" @@ -45,7 +46,8 @@ func ConfirmYourName(tmpl template.Template, lpaStoreResolvingService LpaStoreRe provided.FirstNames = firstNames provided.LastName = lastName - if lastName == lpa.Donor.LastName || !provided.NameMatches(lpa).IsNone() { + if !provided.Tasks.ConfirmYourName.IsCompleted() && + (strings.EqualFold(lastName, lpa.Donor.LastName) || !provided.NameMatches(lpa).IsNone()) { redirect = voucher.PathConfirmAllowedToVouch state = task.StateInProgress } diff --git a/internal/voucher/voucherpage/identity_with_one_login_callback.go b/internal/voucher/voucherpage/identity_with_one_login_callback.go index 143903309f..4bc49588a0 100644 --- a/internal/voucher/voucherpage/identity_with_one_login_callback.go +++ b/internal/voucher/voucherpage/identity_with_one_login_callback.go @@ -45,7 +45,12 @@ func IdentityWithOneLoginCallback(oneLoginClient OneLoginClient, sessionStore Se } provided.IdentityUserData = userData - provided.Tasks.ConfirmYourIdentity = task.StateCompleted + if provided.NameMatches(lpa).IsNone() { + provided.Tasks.ConfirmYourIdentity = task.StateCompleted + } else { + provided.Tasks.ConfirmYourIdentity = task.StateInProgress + } + if err := voucherStore.Put(r.Context(), provided); err != nil { return err } @@ -66,6 +71,10 @@ func IdentityWithOneLoginCallback(oneLoginClient OneLoginClient, sessionStore Se return voucher.PathUnableToConfirmIdentity.Redirect(w, r, appData, appData.LpaID) } - return voucher.PathOneLoginIdentityDetails.Redirect(w, r, appData, appData.LpaID) + if provided.Tasks.ConfirmYourIdentity.IsCompleted() { + return voucher.PathOneLoginIdentityDetails.Redirect(w, r, appData, appData.LpaID) + } + + return voucher.PathConfirmAllowedToVouch.Redirect(w, r, appData, appData.LpaID) } } diff --git a/internal/voucher/voucherpage/identity_with_one_login_callback_test.go b/internal/voucher/voucherpage/identity_with_one_login_callback_test.go index 5b5556ff53..a09f4c1e3c 100644 --- a/internal/voucher/voucherpage/identity_with_one_login_callback_test.go +++ b/internal/voucher/voucherpage/identity_with_one_login_callback_test.go @@ -23,56 +23,85 @@ import ( func TestGetIdentityWithOneLoginCallback(t *testing.T) { now := time.Now() - w := httptest.NewRecorder() - r, _ := http.NewRequest(http.MethodGet, "/?code=a-code", nil) - userInfo := onelogin.UserInfo{CoreIdentityJWT: "an-identity-jwt"} userData := identity.UserData{Status: identity.StatusConfirmed, FirstNames: "John", LastName: "Doe", RetrievedAt: now} - updatedVoucher := &voucherdata.Provided{ - LpaID: "lpa-id", - FirstNames: "John", - LastName: "Doe", - IdentityUserData: userData, - Tasks: voucherdata.Tasks{ConfirmYourIdentity: task.StateCompleted}, + testcases := map[string]struct { + lpa *lpadata.Lpa + updatedVoucher *voucherdata.Provided + redirect voucher.Path + }{ + "confirmed": { + lpa: &lpadata.Lpa{LpaUID: "lpa-uid", Voucher: lpadata.Voucher{FirstNames: "John", LastName: "Doe"}}, + updatedVoucher: &voucherdata.Provided{ + LpaID: "lpa-id", + FirstNames: "John", + LastName: "Doe", + IdentityUserData: userData, + Tasks: voucherdata.Tasks{ConfirmYourIdentity: task.StateCompleted}, + }, + redirect: voucher.PathOneLoginIdentityDetails, + }, + "matches other actor": { + lpa: &lpadata.Lpa{ + LpaUID: "lpa-uid", + Donor: lpadata.Donor{FirstNames: "John", LastName: "Doe"}, + Voucher: lpadata.Voucher{FirstNames: "John", LastName: "Doe"}, + }, + updatedVoucher: &voucherdata.Provided{ + LpaID: "lpa-id", + FirstNames: "John", + LastName: "Doe", + IdentityUserData: userData, + Tasks: voucherdata.Tasks{ConfirmYourIdentity: task.StateInProgress}, + }, + redirect: voucher.PathConfirmAllowedToVouch, + }, } - voucherStore := newMockVoucherStore(t) - voucherStore.EXPECT(). - Put(r.Context(), updatedVoucher). - Return(nil) - - lpaStoreResolvingService := newMockLpaStoreResolvingService(t) - lpaStoreResolvingService.EXPECT(). - Get(r.Context()). - Return(&lpadata.Lpa{LpaUID: "lpa-uid", Voucher: lpadata.Voucher{FirstNames: "John", LastName: "Doe"}}, nil) - - sessionStore := newMockSessionStore(t) - sessionStore.EXPECT(). - OneLogin(r). - Return(&sesh.OneLoginSession{State: "a-state", Nonce: "a-nonce", Redirect: "/redirect"}, nil) - - oneLoginClient := newMockOneLoginClient(t) - oneLoginClient.EXPECT(). - Exchange(r.Context(), "a-code", "a-nonce"). - Return("id-token", "a-jwt", nil) - oneLoginClient.EXPECT(). - UserInfo(r.Context(), "a-jwt"). - Return(userInfo, nil) - oneLoginClient.EXPECT(). - ParseIdentityClaim(r.Context(), userInfo). - Return(userData, nil) + for name, tc := range testcases { + t.Run(name, func(t *testing.T) { + w := httptest.NewRecorder() + r, _ := http.NewRequest(http.MethodGet, "/?code=a-code", nil) - err := IdentityWithOneLoginCallback(oneLoginClient, sessionStore, voucherStore, lpaStoreResolvingService, nil, "www.example.com")(testAppData, w, r, &voucherdata.Provided{ - LpaID: "lpa-id", - FirstNames: "John", - LastName: "Doe", - }) - resp := w.Result() + lpaStoreResolvingService := newMockLpaStoreResolvingService(t) + lpaStoreResolvingService.EXPECT(). + Get(r.Context()). + Return(tc.lpa, nil) + + voucherStore := newMockVoucherStore(t) + voucherStore.EXPECT(). + Put(r.Context(), tc.updatedVoucher). + Return(nil) + + sessionStore := newMockSessionStore(t) + sessionStore.EXPECT(). + OneLogin(r). + Return(&sesh.OneLoginSession{State: "a-state", Nonce: "a-nonce", Redirect: "/redirect"}, nil) + + oneLoginClient := newMockOneLoginClient(t) + oneLoginClient.EXPECT(). + Exchange(r.Context(), "a-code", "a-nonce"). + Return("id-token", "a-jwt", nil) + oneLoginClient.EXPECT(). + UserInfo(r.Context(), "a-jwt"). + Return(userInfo, nil) + oneLoginClient.EXPECT(). + ParseIdentityClaim(r.Context(), userInfo). + Return(userData, nil) + + err := IdentityWithOneLoginCallback(oneLoginClient, sessionStore, voucherStore, lpaStoreResolvingService, nil, "www.example.com")(testAppData, w, r, &voucherdata.Provided{ + LpaID: "lpa-id", + FirstNames: "John", + LastName: "Doe", + }) + resp := w.Result() - assert.Nil(t, err) - assert.Equal(t, http.StatusFound, resp.StatusCode) - assert.Equal(t, voucher.PathOneLoginIdentityDetails.Format("lpa-id"), resp.Header.Get("Location")) + assert.Nil(t, err) + assert.Equal(t, http.StatusFound, resp.StatusCode) + assert.Equal(t, tc.redirect.Format("lpa-id"), resp.Header.Get("Location")) + }) + } } func TestGetIdentityWithOneLoginCallbackWhenFailedIdentityCheck(t *testing.T) { diff --git a/internal/voucher/voucherpage/register.go b/internal/voucher/voucherpage/register.go index d5448a4e40..43a9c7c85a 100644 --- a/internal/voucher/voucherpage/register.go +++ b/internal/voucher/voucherpage/register.go @@ -208,7 +208,7 @@ func makeVoucherHandle(mux *http.ServeMux, store SessionStore, errorHandler page return } - if !voucher.CanGoTo(provided, r.URL.String()) { + if !path.CanGoTo(provided) { voucher.PathTaskList.Redirect(w, r, appData, provided.LpaID) return } diff --git a/internal/voucher/voucherpage/task_list.go b/internal/voucher/voucherpage/task_list.go index b14fb9d562..7a8bf96e8e 100644 --- a/internal/voucher/voucherpage/task_list.go +++ b/internal/voucher/voucherpage/task_list.go @@ -32,7 +32,10 @@ func TaskList(tmpl template.Template, lpaStoreResolvingService LpaStoreResolving } confirmYourIdentityPath := voucher.PathConfirmYourIdentity - if provided.Tasks.ConfirmYourIdentity.IsCompleted() { + switch provided.Tasks.ConfirmYourIdentity { + case task.StateInProgress: + confirmYourIdentityPath = voucher.PathConfirmAllowedToVouch + case task.StateCompleted: confirmYourIdentityPath = voucher.PathOneLoginIdentityDetails } diff --git a/internal/voucher/voucherpage/task_list_test.go b/internal/voucher/voucherpage/task_list_test.go index 95890da05d..f6fcc5de64 100644 --- a/internal/voucher/voucherpage/task_list_test.go +++ b/internal/voucher/voucherpage/task_list_test.go @@ -29,6 +29,26 @@ func TestGetTaskList(t *testing.T) { return items }, }, + "identity in progress": { + lpa: &lpadata.Lpa{ + LpaID: "lpa-id", + Donor: lpadata.Donor{FirstNames: "John", LastName: "Smith"}, + }, + voucher: &voucherdata.Provided{ + Tasks: voucherdata.Tasks{ + ConfirmYourName: task.StateCompleted, + VerifyDonorDetails: task.StateCompleted, + ConfirmYourIdentity: task.StateInProgress, + }, + }, + expected: func(items []taskListItem) []taskListItem { + items[0].State = task.StateCompleted + items[1].State = task.StateCompleted + items[2].State = task.StateInProgress + items[2].Path = voucher.PathConfirmAllowedToVouch + return items + }, + }, "completed": { lpa: &lpadata.Lpa{ LpaID: "lpa-id", diff --git a/lang/cy.json b/lang/cy.json index 5445036afc..e595a8c844 100644 --- a/lang/cy.json +++ b/lang/cy.json @@ -1351,5 +1351,6 @@ "thankYou": "Welsh", "youHaveVouchedFor": "Welsh {{.DonorFullNamePossessive}}", "voucherThankYouContent": "

Welsh {{.DonorFirstNamesPossessive}}

", - "youHaveEnteredNameWhichMatchesSomeone": "Welsh {{.DonorFullNamePossessive}}" + "youHaveEnteredNameWhichMatchesSomeone": "Welsh {{.DonorFullNamePossessive}}", + "yourConfirmedIdentityDetailsMatchSomeone": "Welsh {{.DonorFullNamePossessive}}" } diff --git a/lang/en.json b/lang/en.json index 3ff1db8624..712070c654 100644 --- a/lang/en.json +++ b/lang/en.json @@ -1280,5 +1280,6 @@ "thankYou": "Thank you", "youHaveVouchedFor": "You have vouched for {{.DonorFullNamePossessive}} identity.", "voucherThankYouContent": "

You do not need to do anything else.

{{.DonorFirstNamesPossessive}} vouching request will no longer appear on your dashboard.

You can print this page out for your records if you wish, or close this browsing window.

", - "youHaveEnteredNameWhichMatchesSomeone": "You have entered a name that matches someone named on {{.DonorFullNamePossessive}} lasting power of attorney (LPA)." + "youHaveEnteredNameWhichMatchesSomeone": "You have entered a name that matches someone named on {{.DonorFullNamePossessive}} lasting power of attorney (LPA).", + "yourConfirmedIdentityDetailsMatchSomeone": "Your confirmed identity details match someone named on {{.DonorFullNamePossessive}} lasting power of attorney (LPA)." } diff --git a/web/template/voucher/confirm_allowed_to_vouch.gohtml b/web/template/voucher/confirm_allowed_to_vouch.gohtml index 78be805a02..7bbc9727b9 100644 --- a/web/template/voucher/confirm_allowed_to_vouch.gohtml +++ b/web/template/voucher/confirm_allowed_to_vouch.gohtml @@ -10,7 +10,10 @@

{{ tr .App "confirmThatYouAreAllowedToVouch" }}

- {{ if .SurnameMatchesDonor }} + {{ if .MatchIdentity }} + {{ trFormat .App "yourConfirmedIdentityDetailsMatchSomeone" + "DonorFullNamePossessive" (possessive .App .Lpa.Donor.FullName) }} + {{ else if .SurnameMatchesDonor }} {{ trFormat .App "theDonorsLastNameMatchesYours" "DonorFullNamePossessive" (possessive .App .Lpa.Donor.FullName) }} {{ else }} diff --git a/web/template/voucher/confirm_your_name.gohtml b/web/template/voucher/confirm_your_name.gohtml index 849d77f50d..6d54baa398 100644 --- a/web/template/voucher/confirm_your_name.gohtml +++ b/web/template/voucher/confirm_your_name.gohtml @@ -3,7 +3,7 @@ {{ define "pageTitle" }}{{ tr .App "confirmYourName" }}{{ end }} {{ define "main" }} - {{ $canChange := not .Tasks.ConfirmYourIdentity.IsCompleted }} + {{ $canChange := .Tasks.ConfirmYourIdentity.IsNotStarted }}