From 9dcc35eb0a76fbac14a66d3bff00c28a948c3172 Mon Sep 17 00:00:00 2001 From: Joshua Hawxwell Date: Wed, 14 Aug 2024 12:20:31 +0100 Subject: [PATCH] Add page for voucher to confirm own name --- internal/actor/type.go | 4 + internal/lpastore/lpa.go | 11 ++ internal/lpastore/lpadata/lpa.go | 6 +- internal/lpastore/lpadata/voucher.go | 10 ++ internal/lpastore/resolving_service.go | 9 ++ internal/lpastore/resolving_service_test.go | 24 ++++ internal/page/fixtures/voucher.go | 10 +- internal/templatefn/paths.go | 11 +- internal/voucher/mock_DynamoClient_test.go | 47 ++++++++ internal/voucher/path.go | 1 + internal/voucher/store.go | 6 + internal/voucher/store_test.go | 18 +++ .../voucher/voucherpage/confirm_your_name.go | 45 +++++++ .../voucherpage/confirm_your_name_test.go | 112 ++++++++++++++++++ .../voucherpage/mock_VoucherStore_test.go | 47 ++++++++ internal/voucher/voucherpage/register.go | 5 + internal/voucher/voucherpage/register_test.go | 9 +- web/template/layout/buttons.gohtml | 2 + web/template/layout/page.gohtml | 2 +- web/template/voucher/confirm_your_name.gohtml | 32 +++++ 20 files changed, 404 insertions(+), 7 deletions(-) create mode 100644 internal/lpastore/lpadata/voucher.go create mode 100644 internal/voucher/voucherpage/confirm_your_name.go create mode 100644 internal/voucher/voucherpage/confirm_your_name_test.go create mode 100644 web/template/voucher/confirm_your_name.gohtml diff --git a/internal/actor/type.go b/internal/actor/type.go index 35b9449e21..794e15ccb5 100644 --- a/internal/actor/type.go +++ b/internal/actor/type.go @@ -16,6 +16,10 @@ const ( TypeVoucher ) +func (t Type) IsVoucher() bool { + return t == TypeVoucher +} + func (t Type) String() string { switch t { case TypeDonor: diff --git a/internal/lpastore/lpa.go b/internal/lpastore/lpa.go index 7ca2ef6691..f005151f0e 100644 --- a/internal/lpastore/lpa.go +++ b/internal/lpastore/lpa.go @@ -474,6 +474,16 @@ func FromDonorProvidedDetails(l *donordata.Provided) *lpadata.Lpa { }) } + var voucher lpadata.Voucher + if v := l.Voucher; v.Allowed { + voucher = lpadata.Voucher{ + UID: v.UID, + FirstNames: v.FirstNames, + LastName: v.LastName, + Email: v.Email, + } + } + return &lpadata.Lpa{ LpaID: l.LpaID, LpaUID: l.LpaUID, @@ -523,6 +533,7 @@ func FromDonorProvidedDetails(l *donordata.Provided) *lpadata.Lpa { LastName: l.Correspondent.LastName, Email: l.Correspondent.Email, }, + Voucher: voucher, } } diff --git a/internal/lpastore/lpadata/lpa.go b/internal/lpastore/lpadata/lpa.go index e3de66d9f8..9fd20a0e1c 100644 --- a/internal/lpastore/lpadata/lpa.go +++ b/internal/lpastore/lpadata/lpa.go @@ -55,9 +55,13 @@ type Lpa struct { // cannot-register. CannotRegister bool - // Correspondent is set using the data set by the donor for online + // Correspondent is set using the data provided by the donor for online // applications, but is not set for paper applications. Correspondent Correspondent + + // Voucher is set using the data provided by the donor for online + // applications, but is not set for paper applications. + Voucher Voucher } func (l *Lpa) CorrespondentEmail() string { diff --git a/internal/lpastore/lpadata/voucher.go b/internal/lpastore/lpadata/voucher.go new file mode 100644 index 0000000000..0b44b5451b --- /dev/null +++ b/internal/lpastore/lpadata/voucher.go @@ -0,0 +1,10 @@ +package lpadata + +import "github.com/ministryofjustice/opg-modernising-lpa/internal/actor/actoruid" + +type Voucher struct { + UID actoruid.UID + FirstNames string + LastName string + Email string +} diff --git a/internal/lpastore/resolving_service.go b/internal/lpastore/resolving_service.go index e278684665..673029be87 100644 --- a/internal/lpastore/resolving_service.go +++ b/internal/lpastore/resolving_service.go @@ -103,6 +103,15 @@ func (s *ResolvingService) merge(lpa *lpadata.Lpa, donor *donordata.Provided) *l Email: donor.Correspondent.Email, } + if donor.Voucher.Allowed { + lpa.Voucher = lpadata.Voucher{ + UID: donor.Voucher.UID, + FirstNames: donor.Voucher.FirstNames, + LastName: donor.Voucher.LastName, + Email: donor.Voucher.Email, + } + } + // copy the relationship as it isn't stored in the lpastore. lpa.CertificateProvider.Relationship = donor.CertificateProvider.Relationship diff --git a/internal/lpastore/resolving_service_test.go b/internal/lpastore/resolving_service_test.go index b515ba2eef..97bb60eebd 100644 --- a/internal/lpastore/resolving_service_test.go +++ b/internal/lpastore/resolving_service_test.go @@ -40,6 +40,7 @@ func TestResolvingServiceGet(t *testing.T) { RetrievedAt: time.Now(), }, Correspondent: donordata.Correspondent{Email: "x"}, + Voucher: donordata.Voucher{Allowed: true, Email: "y"}, }, resolved: &lpadata.Lpa{ LpaID: "1", @@ -61,6 +62,7 @@ func TestResolvingServiceGet(t *testing.T) { }, Donor: lpadata.Donor{Channel: lpadata.ChannelOnline}, Correspondent: lpadata.Correspondent{Email: "x"}, + Voucher: lpadata.Voucher{Email: "y"}, }, }, "online with no lpastore record": { @@ -84,6 +86,8 @@ func TestResolvingServiceGet(t *testing.T) { Status: identity.StatusConfirmed, RetrievedAt: time.Date(2020, time.January, 2, 12, 13, 14, 5, time.UTC), }, + Correspondent: donordata.Correspondent{Email: "x"}, + Voucher: donordata.Voucher{Allowed: true, Email: "y"}, }, error: ErrNotFound, expected: &lpadata.Lpa{ @@ -108,6 +112,8 @@ func TestResolvingServiceGet(t *testing.T) { Attorneys: []lpadata.Attorney{{FirstNames: "c"}}, TrustCorporation: lpadata.TrustCorporation{Name: "d"}, }, + Correspondent: lpadata.Correspondent{Email: "x"}, + Voucher: lpadata.Voucher{Email: "y"}, }, }, "online with all false": { @@ -144,6 +150,24 @@ func TestResolvingServiceGet(t *testing.T) { Donor: lpadata.Donor{Channel: lpadata.ChannelPaper}, }, }, + "voucher not allowed": { + donor: &donordata.Provided{ + SK: dynamo.LpaOwnerKey(dynamo.OrganisationKey("S")), + LpaID: "1", + LpaUID: "M-1111", + Voucher: donordata.Voucher{Email: "y"}, + }, + resolved: &lpadata.Lpa{ + LpaID: "1", + }, + expected: &lpadata.Lpa{ + LpaOwnerKey: dynamo.LpaOwnerKey(dynamo.OrganisationKey("S")), + LpaID: "1", + LpaUID: "M-1111", + IsOrganisationDonor: true, + Donor: lpadata.Donor{Channel: lpadata.ChannelOnline}, + }, + }, } for name, tc := range testcases { diff --git a/internal/page/fixtures/voucher.go b/internal/page/fixtures/voucher.go index 1d6528976b..711fa4576f 100644 --- a/internal/page/fixtures/voucher.go +++ b/internal/page/fixtures/voucher.go @@ -56,7 +56,11 @@ func Voucher(tmpl template.Template, shareCodeStore *sharecode.Store, donorStore Attorneys: []donordata.Attorney{makeAttorney(attorneyNames[0])}, } donorDetails.Voucher = donordata.Voucher{ - UID: actoruid.New(), + UID: actoruid.New(), + FirstNames: "Vivian", + LastName: "Vaughn", + Email: testEmail, + Allowed: true, } if shareCode != "" { @@ -69,6 +73,10 @@ func Voucher(tmpl template.Template, shareCodeStore *sharecode.Store, donorStore } } + if err := donorStore.Put(appcontext.ContextWithSession(r.Context(), &appcontext.Session{SessionID: donorSessionID, LpaID: donorDetails.LpaID}), donorDetails); err != nil { + return err + } + http.Redirect(w, r, page.PathVoucherStart.Format(), http.StatusFound) return nil } diff --git a/internal/templatefn/paths.go b/internal/templatefn/paths.go index 9f8e687d88..a39b41a06a 100644 --- a/internal/templatefn/paths.go +++ b/internal/templatefn/paths.go @@ -6,6 +6,7 @@ import ( "github.com/ministryofjustice/opg-modernising-lpa/internal/donor" "github.com/ministryofjustice/opg-modernising-lpa/internal/page" "github.com/ministryofjustice/opg-modernising-lpa/internal/supporter" + "github.com/ministryofjustice/opg-modernising-lpa/internal/voucher" ) type attorneyPaths struct { @@ -92,7 +93,10 @@ type supporterPaths struct { } type voucherPaths struct { - Login page.Path + Login page.Path + Start page.Path + TaskList voucher.Path + YourName voucher.Path } type appPaths struct { @@ -315,7 +319,10 @@ var paths = appPaths{ }, Voucher: voucherPaths{ - Login: page.PathVoucherLogin, + Login: page.PathVoucherLogin, + Start: page.PathVoucherStart, + TaskList: voucher.PathTaskList, + YourName: voucher.PathYourName, }, HealthCheck: healthCheckPaths{ diff --git a/internal/voucher/mock_DynamoClient_test.go b/internal/voucher/mock_DynamoClient_test.go index 8927e29c6f..b2f91ca337 100644 --- a/internal/voucher/mock_DynamoClient_test.go +++ b/internal/voucher/mock_DynamoClient_test.go @@ -71,6 +71,53 @@ func (_c *mockDynamoClient_One_Call) RunAndReturn(run func(context.Context, dyna return _c } +// Put provides a mock function with given fields: ctx, v +func (_m *mockDynamoClient) Put(ctx context.Context, v interface{}) error { + ret := _m.Called(ctx, v) + + if len(ret) == 0 { + panic("no return value specified for Put") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, interface{}) error); ok { + r0 = rf(ctx, v) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// mockDynamoClient_Put_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Put' +type mockDynamoClient_Put_Call struct { + *mock.Call +} + +// Put is a helper method to define mock.On call +// - ctx context.Context +// - v interface{} +func (_e *mockDynamoClient_Expecter) Put(ctx interface{}, v interface{}) *mockDynamoClient_Put_Call { + return &mockDynamoClient_Put_Call{Call: _e.mock.On("Put", ctx, v)} +} + +func (_c *mockDynamoClient_Put_Call) Run(run func(ctx context.Context, v interface{})) *mockDynamoClient_Put_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(interface{})) + }) + return _c +} + +func (_c *mockDynamoClient_Put_Call) Return(_a0 error) *mockDynamoClient_Put_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *mockDynamoClient_Put_Call) RunAndReturn(run func(context.Context, interface{}) error) *mockDynamoClient_Put_Call { + _c.Call.Return(run) + return _c +} + // WriteTransaction provides a mock function with given fields: ctx, transaction func (_m *mockDynamoClient) WriteTransaction(ctx context.Context, transaction *dynamo.Transaction) error { ret := _m.Called(ctx, transaction) diff --git a/internal/voucher/path.go b/internal/voucher/path.go index 1038d4e569..8ceb257710 100644 --- a/internal/voucher/path.go +++ b/internal/voucher/path.go @@ -11,6 +11,7 @@ import ( const ( PathTaskList = Path("/task-list") PathConfirmYourName = Path("/confirm-your-name") + PathYourName = Path("/your-name") PathVerifyDonorDetails = Path("/verify-donor-details") PathConfirmYourIdentity = Path("/confirm-your-identity") PathSignTheDeclaration = Path("/sign-the-declaration") diff --git a/internal/voucher/store.go b/internal/voucher/store.go index bf845513aa..3d1940fb47 100644 --- a/internal/voucher/store.go +++ b/internal/voucher/store.go @@ -15,6 +15,7 @@ import ( type DynamoClient interface { One(ctx context.Context, pk dynamo.PK, sk dynamo.SK, v interface{}) error + Put(ctx context.Context, v interface{}) error WriteTransaction(ctx context.Context, transaction *dynamo.Transaction) error } @@ -78,3 +79,8 @@ func (s *Store) Get(ctx context.Context) (*voucherdata.Provided, error) { return &provided, err } + +func (s *Store) Put(ctx context.Context, provided *voucherdata.Provided) error { + provided.UpdatedAt = s.now() + return s.dynamoClient.Put(ctx, provided) +} diff --git a/internal/voucher/store_test.go b/internal/voucher/store_test.go index cc5aae8283..384bf07e68 100644 --- a/internal/voucher/store_test.go +++ b/internal/voucher/store_test.go @@ -192,3 +192,21 @@ func TestVoucherStoreGetOnError(t *testing.T) { _, err := store.Get(ctx) assert.Equal(t, expectedError, err) } + +func TestVoucherStorePut(t *testing.T) { + ctx := context.Background() + now := time.Now() + + dynamoClient := newMockDynamoClient(t) + dynamoClient.EXPECT(). + Put(ctx, &voucherdata.Provided{PK: dynamo.LpaKey("123"), SK: dynamo.VoucherKey("456"), LpaID: "123", UpdatedAt: now}). + Return(expectedError) + + store := &Store{ + dynamoClient: dynamoClient, + now: func() time.Time { return now }, + } + + err := store.Put(ctx, &voucherdata.Provided{PK: dynamo.LpaKey("123"), SK: dynamo.VoucherKey("456"), LpaID: "123"}) + assert.Equal(t, expectedError, err) +} diff --git a/internal/voucher/voucherpage/confirm_your_name.go b/internal/voucher/voucherpage/confirm_your_name.go new file mode 100644 index 0000000000..24f6546564 --- /dev/null +++ b/internal/voucher/voucherpage/confirm_your_name.go @@ -0,0 +1,45 @@ +package voucherpage + +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/lpastore/lpadata" + "github.com/ministryofjustice/opg-modernising-lpa/internal/task" + "github.com/ministryofjustice/opg-modernising-lpa/internal/validation" + "github.com/ministryofjustice/opg-modernising-lpa/internal/voucher" + "github.com/ministryofjustice/opg-modernising-lpa/internal/voucher/voucherdata" +) + +type confirmYourNameData struct { + App appcontext.Data + Errors validation.List + Lpa *lpadata.Lpa +} + +func ConfirmYourName(tmpl template.Template, lpaStoreResolvingService LpaStoreResolvingService, voucherStore VoucherStore) Handler { + return func(appData appcontext.Data, w http.ResponseWriter, r *http.Request, provided *voucherdata.Provided) error { + if r.Method == http.MethodPost { + if provided.Tasks.ConfirmYourName.NotStarted() { + provided.Tasks.ConfirmYourName = task.StateInProgress + + if err := voucherStore.Put(r.Context(), provided); err != nil { + return err + } + } + + return voucher.PathTaskList.Redirect(w, r, appData, appData.LpaID) + } + + lpa, err := lpaStoreResolvingService.Get(r.Context()) + if err != nil { + return err + } + + return tmpl(w, &confirmYourNameData{ + App: appData, + Lpa: lpa, + }) + } +} diff --git a/internal/voucher/voucherpage/confirm_your_name_test.go b/internal/voucher/voucherpage/confirm_your_name_test.go new file mode 100644 index 0000000000..fc62e451b5 --- /dev/null +++ b/internal/voucher/voucherpage/confirm_your_name_test.go @@ -0,0 +1,112 @@ +package voucherpage + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/ministryofjustice/opg-modernising-lpa/internal/lpastore/lpadata" + "github.com/ministryofjustice/opg-modernising-lpa/internal/task" + "github.com/ministryofjustice/opg-modernising-lpa/internal/voucher" + "github.com/ministryofjustice/opg-modernising-lpa/internal/voucher/voucherdata" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" +) + +func TestGetConfirmYourName(t *testing.T) { + voucherProvidedDetails := &voucherdata.Provided{LpaID: "lpa-id"} + + 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"}, + }, nil) + + template := newMockTemplate(t) + template.EXPECT(). + Execute(w, &confirmYourNameData{ + App: testAppData, + Lpa: &lpadata.Lpa{ + Voucher: lpadata.Voucher{FirstNames: "V"}, + }, + }). + Return(nil) + + err := ConfirmYourName(template.Execute, lpaStoreResolvingService, nil)(testAppData, w, r, voucherProvidedDetails) + resp := w.Result() + + assert.Nil(t, err) + assert.Equal(t, http.StatusOK, resp.StatusCode) +} + +func TestGetConfirmYourNameWhenLpaStoreResolvingServiceErrors(t *testing.T) { + w := httptest.NewRecorder() + r, _ := http.NewRequest(http.MethodGet, "/", nil) + + donor := &lpadata.Lpa{} + + lpaStoreResolvingService := newMockLpaStoreResolvingService(t) + lpaStoreResolvingService.EXPECT(). + Get(r.Context()). + Return(donor, expectedError) + + err := ConfirmYourName(nil, lpaStoreResolvingService, nil)(testAppData, w, r, nil) + + assert.Equal(t, expectedError, err) +} + +func TestGetConfirmYourNameWhenTemplateErrors(t *testing.T) { + w := httptest.NewRecorder() + r, _ := http.NewRequest(http.MethodGet, "/", nil) + + lpaStoreResolvingService := newMockLpaStoreResolvingService(t) + lpaStoreResolvingService.EXPECT(). + Get(r.Context()). + Return(&lpadata.Lpa{}, nil) + + template := newMockTemplate(t) + template.EXPECT(). + Execute(w, mock.Anything). + Return(expectedError) + + err := ConfirmYourName(template.Execute, lpaStoreResolvingService, nil)(testAppData, w, r, &voucherdata.Provided{}) + + assert.Equal(t, expectedError, err) +} + +func TestPostConfirmYourName(t *testing.T) { + w := httptest.NewRecorder() + r, _ := http.NewRequest(http.MethodPost, "/", nil) + + voucherStore := newMockVoucherStore(t) + voucherStore.EXPECT(). + Put(r.Context(), &voucherdata.Provided{ + LpaID: "lpa-id", + Tasks: voucherdata.Tasks{ConfirmYourName: task.StateInProgress}, + }). + Return(nil) + + err := ConfirmYourName(nil, nil, 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")) +} + +func TestPostConfirmYourNameWhenStoreErrors(t *testing.T) { + w := httptest.NewRecorder() + r, _ := http.NewRequest(http.MethodPost, "/", nil) + + voucherStore := newMockVoucherStore(t) + voucherStore.EXPECT(). + Put(r.Context(), mock.Anything). + Return(expectedError) + + err := ConfirmYourName(nil, nil, voucherStore)(testAppData, w, r, &voucherdata.Provided{LpaID: "lpa-id"}) + assert.Equal(t, expectedError, err) +} diff --git a/internal/voucher/voucherpage/mock_VoucherStore_test.go b/internal/voucher/voucherpage/mock_VoucherStore_test.go index 03a9535032..8a4c65bdde 100644 --- a/internal/voucher/voucherpage/mock_VoucherStore_test.go +++ b/internal/voucher/voucherpage/mock_VoucherStore_test.go @@ -141,6 +141,53 @@ func (_c *mockVoucherStore_Get_Call) RunAndReturn(run func(context.Context) (*vo return _c } +// Put provides a mock function with given fields: ctx, provided +func (_m *mockVoucherStore) Put(ctx context.Context, provided *voucherdata.Provided) error { + ret := _m.Called(ctx, provided) + + if len(ret) == 0 { + panic("no return value specified for Put") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *voucherdata.Provided) error); ok { + r0 = rf(ctx, provided) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// mockVoucherStore_Put_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Put' +type mockVoucherStore_Put_Call struct { + *mock.Call +} + +// Put is a helper method to define mock.On call +// - ctx context.Context +// - provided *voucherdata.Provided +func (_e *mockVoucherStore_Expecter) Put(ctx interface{}, provided interface{}) *mockVoucherStore_Put_Call { + return &mockVoucherStore_Put_Call{Call: _e.mock.On("Put", ctx, provided)} +} + +func (_c *mockVoucherStore_Put_Call) Run(run func(ctx context.Context, provided *voucherdata.Provided)) *mockVoucherStore_Put_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*voucherdata.Provided)) + }) + return _c +} + +func (_c *mockVoucherStore_Put_Call) Return(_a0 error) *mockVoucherStore_Put_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *mockVoucherStore_Put_Call) RunAndReturn(run func(context.Context, *voucherdata.Provided) error) *mockVoucherStore_Put_Call { + _c.Call.Return(run) + return _c +} + // newMockVoucherStore creates a new instance of mockVoucherStore. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func newMockVoucherStore(t interface { diff --git a/internal/voucher/voucherpage/register.go b/internal/voucher/voucherpage/register.go index b45f38764c..8a079fdaf8 100644 --- a/internal/voucher/voucherpage/register.go +++ b/internal/voucher/voucherpage/register.go @@ -63,6 +63,7 @@ type ShareCodeStore interface { type VoucherStore interface { Create(ctx context.Context, shareCode sharecodedata.Link, email string) (*voucherdata.Provided, error) Get(ctx context.Context) (*voucherdata.Provided, error) + Put(ctx context.Context, provided *voucherdata.Provided) error } type DashboardStore interface { @@ -95,6 +96,8 @@ func Register( handleVoucher(voucher.PathTaskList, None, TaskList(tmpls.Get("task_list.gohtml"), lpaStoreResolvingService)) + handleVoucher(voucher.PathConfirmYourName, None, + ConfirmYourName(tmpls.Get("confirm_your_name.gohtml"), lpaStoreResolvingService, voucherStore)) } type handleOpt byte @@ -113,6 +116,7 @@ func makeHandle(mux *http.ServeMux, store SessionStore, errorHandler page.ErrorH appData := appcontext.DataFromContext(ctx) appData.Page = path.Format() appData.CanGoBack = opt&CanGoBack != 0 + appData.ActorType = actor.TypeVoucher if opt&RequireSession != 0 { session, err := store.Login(r) @@ -139,6 +143,7 @@ func makeVoucherHandle(mux *http.ServeMux, store SessionStore, errorHandler page appData := appcontext.DataFromContext(ctx) appData.CanGoBack = opt&CanGoBack != 0 + appData.ActorType = actor.TypeVoucher appData.LpaID = r.PathValue("id") appData.Page = path.Format(appData.LpaID) diff --git a/internal/voucher/voucherpage/register_test.go b/internal/voucher/voucherpage/register_test.go index bf34bf79e3..5882b617a3 100644 --- a/internal/voucher/voucherpage/register_test.go +++ b/internal/voucher/voucherpage/register_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/ministryofjustice/opg-go-common/template" + "github.com/ministryofjustice/opg-modernising-lpa/internal/actor" "github.com/ministryofjustice/opg-modernising-lpa/internal/appcontext" "github.com/ministryofjustice/opg-modernising-lpa/internal/page" "github.com/ministryofjustice/opg-modernising-lpa/internal/sesh" @@ -38,6 +39,7 @@ func TestMakeHandle(t *testing.T) { assert.Equal(t, appcontext.Data{ Page: "/path", CanGoBack: false, + ActorType: actor.TypeVoucher, SessionID: "cmFuZG9t", }, appData) assert.Equal(t, w, hw) @@ -68,6 +70,7 @@ func TestMakeHandleRequireSessionExistingSession(t *testing.T) { assert.Equal(t, appcontext.Data{ Page: "/path", CanGoBack: true, + ActorType: actor.TypeVoucher, SessionID: "cmFuZG9t", }, appData) assert.Equal(t, w, hw) @@ -130,10 +133,11 @@ func TestMakeHandleNoSessionRequired(t *testing.T) { handle := makeHandle(mux, nil, nil) handle("/path", None, func(appData appcontext.Data, hw http.ResponseWriter, hr *http.Request) error { assert.Equal(t, appcontext.Data{ - Page: "/path", + Page: "/path", + ActorType: actor.TypeVoucher, }, appData) assert.Equal(t, w, hw) - assert.Equal(t, r.WithContext(appcontext.ContextWithData(r.Context(), appcontext.Data{Page: "/path"})), hr) + assert.Equal(t, r.WithContext(appcontext.ContextWithData(r.Context(), appcontext.Data{Page: "/path", ActorType: actor.TypeVoucher})), hr) hw.WriteHeader(http.StatusTeapot) return nil }) @@ -167,6 +171,7 @@ func TestMakeVoucherHandleExistingSession(t *testing.T) { assert.Equal(t, appcontext.Data{ Page: "/voucher/lpa-id/task-list", CanGoBack: true, + ActorType: actor.TypeVoucher, SessionID: "cmFuZG9t", LpaID: "lpa-id", }, appData) diff --git a/web/template/layout/buttons.gohtml b/web/template/layout/buttons.gohtml index d0318e12a5..502851ed20 100644 --- a/web/template/layout/buttons.gohtml +++ b/web/template/layout/buttons.gohtml @@ -4,6 +4,8 @@ {{ $path = global.Paths.CertificateProvider.TaskList }} {{ else if or .app.IsAttorneyType }} {{ $path = global.Paths.Attorney.TaskList }} + {{ else if .app.ActorType.IsVoucher }} + {{ $path = global.Paths.Voucher.TaskList }} {{ end }} {{ if .link }} diff --git a/web/template/layout/page.gohtml b/web/template/layout/page.gohtml index d6bbc1d5b2..d012b82a4f 100644 --- a/web/template/layout/page.gohtml +++ b/web/template/layout/page.gohtml @@ -3,7 +3,7 @@ - {{ if .Errors }}Error: {{ end }} {{ if not (eq .App.Page global.Paths.Start global.Paths.CertificateProviderStart global.Paths.Attorney.Start global.Paths.Supporter.Start) }}{{ block "pageTitle" . }}{{ end }} - {{ end }}{{ tr .App "serviceName" }} + {{ if .Errors }}Error: {{ end }} {{ if not (eq .App.Page global.Paths.Start global.Paths.CertificateProviderStart global.Paths.Attorney.Start global.Paths.Supporter.Start global.Paths.Voucher.Start) }}{{ block "pageTitle" . }}{{ end }} - {{ end }}{{ tr .App "serviceName" }} diff --git a/web/template/voucher/confirm_your_name.gohtml b/web/template/voucher/confirm_your_name.gohtml new file mode 100644 index 0000000000..d94fe46eda --- /dev/null +++ b/web/template/voucher/confirm_your_name.gohtml @@ -0,0 +1,32 @@ +{{ template "page" . }} + +{{ define "pageTitle" }}{{ tr .App "confirmYourName" }}{{ end }} + +{{ define "main" }} +
+
+

{{ tr .App "confirmYourName" }}

+ +

{{ trFormat .App "thisIsTheNameDonorProvidedForYou" "DonorFullName" .Lpa.Donor.FullName }}

+ +
+ {{ template "summary-row" (summaryRow .App "firstNames" + .Lpa.Voucher.FirstNames + (fromLink .App global.Paths.Voucher.YourName "#f-first-names") + "" true true) }} + + {{ template "summary-row" (summaryRow .App "lastName" + .Lpa.Voucher.LastName + (fromLink .App global.Paths.Voucher.YourName "#f-last-name") + "" true true) }} +
+ + {{ template "warning" (content .App "thisNameMustMatchYourConfirmIdentityDetailsWarning") }} + +
+ {{ template "buttons" (button .App "continue") }} + {{ template "csrf-field" . }} +
+
+
+{{ end }}