Skip to content

Commit

Permalink
MLPAB-1877: Add what is vouching page (#1316)
Browse files Browse the repository at this point in the history
  • Loading branch information
acsauk authored Jun 27, 2024
1 parent b09a681 commit 1ec000c
Show file tree
Hide file tree
Showing 9 changed files with 236 additions and 7 deletions.
34 changes: 34 additions & 0 deletions cypress/e2e/donor/what-is-vouching.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
describe('what is vouching', () => {
beforeEach(() => {
cy.visit('/fixtures?redirect=/what-is-vouching&progress=payForTheLpa')
cy.url().should('contain', '/what-is-vouching')
cy.checkA11yApp()
})

it('can confirm has a voucher', () => {
cy.get('input[name="yes-no"]').check('yes', { force: true });
cy.contains('button', 'Save and continue').click();

cy.url().should('contain', '/enter-voucher')
})

it('can confirm has not got a voucher', () => {
cy.get('input[name="yes-no"]').check('no', { force: true });
cy.contains('button', 'Save and continue').click();

cy.url().should('contain', '/task-list')
})

it('errors when option not selected', () => {
cy.contains('button', 'Save and continue').click();

cy.url().should('contain', '/what-is-vouching')
cy.checkA11yApp()

cy.get('.govuk-error-summary').within(() => {
cy.contains('Select yes if you know someone and they have agreed to vouch for you');
});

cy.contains('.govuk-error-message', 'Select yes if you know someone and they have agreed to vouch for you');
})
})
2 changes: 2 additions & 0 deletions internal/actor/donor_provided.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ type DonorProvidedDetails struct {
// Version is the number of times the LPA has been updated (auto-incremented on PUT)
Version int `hash:"-"`

// HasAVoucher indicates if the donor knows someone who can vouch for them
HasAVoucher form.YesNo
// Voucher is a person the donor has nominated to vouch for their identity
Voucher Voucher

Expand Down
8 changes: 4 additions & 4 deletions internal/actor/donor_provided_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ func TestGenerateHash(t *testing.T) {
}

// DO change this value to match the updates
const modified uint64 = 0x1544481895e4a269
const modified uint64 = 0x489c8d6c0bf0060

// DO NOT change these initial hash values. If a field has been added/removed
// you will need to handle the version gracefully by modifying
// (*DonorProvidedDetails).HashInclude and adding another testcase for the new
// version.
testcases := map[uint8]uint64{
0: 0xfc629cb12d4374fb,
0: 0x9ff13a8f95ca2df8,
}

for version, initial := range testcases {
Expand Down Expand Up @@ -91,13 +91,13 @@ func TestGenerateCheckedHash(t *testing.T) {
}

// DO change this value to match the updates
const modified uint64 = 0xb4f40b404256ad9
const modified uint64 = 0x4cbba4134d45f904

// DO NOT change these initial hash values. If a field has been added/removed
// you will need to handle the version gracefully by modifying
// toCheck.HashInclude and adding another testcase for the new version.
testcases := map[uint8]uint64{
0: 0xf9b8a8058a8f224a,
0: 0xadda078438d084b2,
}

for version, initial := range testcases {
Expand Down
2 changes: 1 addition & 1 deletion internal/page/donor/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ func Register(
handleWithDonor(page.Paths.UnableToConfirmIdentity, page.None,
Guidance(tmpls.Get("unable_to_confirm_identity.gohtml")))
handleWithDonor(page.Paths.WhatIsVouching, page.CanGoBack,
Guidance(tmpls.Get("unable_to_confirm_identity.gohtml")))
WhatIsVouching(tmpls.Get("what_is_vouching.gohtml"), donorStore))
handleWithDonor(page.Paths.EnterVoucher, page.CanGoBack,
EnterVoucher(tmpls.Get("enter_voucher.gohtml"), donorStore))
handleWithDonor(page.Paths.ConfirmPersonAllowedToVouch, page.CanGoBack,
Expand Down
47 changes: 47 additions & 0 deletions internal/page/donor/what_is_vouching.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package donor

import (
"net/http"

"github.com/ministryofjustice/opg-go-common/template"
"github.com/ministryofjustice/opg-modernising-lpa/internal/actor"
"github.com/ministryofjustice/opg-modernising-lpa/internal/form"
"github.com/ministryofjustice/opg-modernising-lpa/internal/page"
"github.com/ministryofjustice/opg-modernising-lpa/internal/validation"
)

type whatIsVouchingData struct {
App page.AppData
Errors validation.List
Form *form.YesNoForm
}

func WhatIsVouching(tmpl template.Template, donorStore DonorStore) Handler {
return func(appData page.AppData, w http.ResponseWriter, r *http.Request, donor *actor.DonorProvidedDetails) error {
data := &whatIsVouchingData{
App: appData,
Form: form.NewYesNoForm(donor.HasAVoucher),
}

if r.Method == http.MethodPost {
f := form.ReadYesNoForm(r, "yesIfHaveSomeoneCanVouchForYou")
data.Errors = f.Validate()

if data.Errors.None() {
donor.HasAVoucher = f.YesNo
if err := donorStore.Put(r.Context(), donor); err != nil {
return err
}

if donor.HasAVoucher.IsYes() {
return page.Paths.EnterVoucher.Redirect(w, r, appData, donor)
} else {
// temp until no flow built
return page.Paths.TaskList.Redirect(w, r, appData, donor)
}
}
}

return tmpl(w, data)
}
}
102 changes: 102 additions & 0 deletions internal/page/donor/what_is_vouching_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package donor

import (
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"

"github.com/ministryofjustice/opg-modernising-lpa/internal/actor"
"github.com/ministryofjustice/opg-modernising-lpa/internal/form"
"github.com/ministryofjustice/opg-modernising-lpa/internal/page"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)

func TestGetWhatIsVouching(t *testing.T) {
w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodGet, "/", nil)

template := newMockTemplate(t)
template.EXPECT().
Execute(w, &whatIsVouchingData{
App: testAppData,
Form: &form.YesNoForm{
YesNo: form.Yes,
FieldName: form.FieldNames.YesNo,
Options: form.YesNoValues,
},
}).
Return(nil)

err := WhatIsVouching(template.Execute, nil)(testAppData, w, r, &actor.DonorProvidedDetails{HasAVoucher: form.Yes})

assert.Nil(t, err)
}

func TestGetWhatIsVouchingWhenTemplateError(t *testing.T) {
w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodGet, "/", nil)

template := newMockTemplate(t)
template.EXPECT().
Execute(mock.Anything, mock.Anything).
Return(expectedError)

err := WhatIsVouching(template.Execute, nil)(testAppData, w, r, &actor.DonorProvidedDetails{})

assert.Error(t, err)
}

func TestPostWhatIsVouching(t *testing.T) {
testcases := map[form.YesNo]string{
form.Yes: page.Paths.EnterVoucher.Format("lpa-id"),
form.No: page.Paths.TaskList.Format("lpa-id"),
}

for yesNo, path := range testcases {
t.Run(yesNo.String(), func(t *testing.T) {
f := url.Values{
"yes-no": {yesNo.String()},
}

w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(f.Encode()))
r.Header.Add("Content-Type", page.FormUrlEncoded)

donorStore := newMockDonorStore(t)
donorStore.EXPECT().
Put(r.Context(), &actor.DonorProvidedDetails{LpaID: "lpa-id", HasAVoucher: yesNo}).
Return(nil)

err := WhatIsVouching(nil, donorStore)(testAppData, w, r, &actor.DonorProvidedDetails{LpaID: "lpa-id"})
resp := w.Result()

assert.Nil(t, err)
assert.Equal(t, http.StatusFound, resp.StatusCode)
assert.Equal(t, path, resp.Header.Get("Location"))
})
}
}

func TestPostWhatIsVouchingWhenDonorStoreError(t *testing.T) {
f := url.Values{
"yes-no": {form.Yes.String()},
}

w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(f.Encode()))
r.Header.Add("Content-Type", page.FormUrlEncoded)

donorStore := newMockDonorStore(t)
donorStore.EXPECT().
Put(mock.Anything, mock.Anything).
Return(expectedError)

err := WhatIsVouching(nil, donorStore)(testAppData, w, r, &actor.DonorProvidedDetails{LpaID: "lpa-id"})
resp := w.Result()

assert.Error(t, err)
assert.Equal(t, http.StatusOK, resp.StatusCode)
}
8 changes: 7 additions & 1 deletion lang/cy.json
Original file line number Diff line number Diff line change
Expand Up @@ -1222,5 +1222,11 @@
"payingNoFee": "Welsh",
"payingHalfFee": "Welsh",
"aRepeatApplicationDiscount": "Welsh",
"aHardshipApplication": "Welsh"
"aHardshipApplication": "Welsh",
"whatIsVouching": "Welsh",
"whatIsVouchingContent": "<p class=\"govuk-body\">Welsh</p><h2 class=\"govuk-heading-m\">Welsh</h2><p class=\"govuk-body\">Welsh:</p><ul class=\"govuk-list govuk-list--bullet\"><li>Welsh</li><li>Welsh</li><li>Welsh</li><li>Welsh</li></ul><h2 class=\"govuk-heading-m\">Welsh</h2><p class=\"govuk-body\">Welsh:</p><ul class=\"govuk-list govuk-list--bullet\"><li>Welsh</li><li>Welsh</li><li>Welsh</li><li>Welsh</li></ul><h2 class=\"govuk-heading-m\">Welsh</h2><p class=\"govuk-body\">Welsh</p><p class=\"govuk-body\">Welsh:</p><ul class=\"govuk-list govuk-list--bullet\"><li>Welsh</li><li>Welsh</li><li>Welsh</li></ul><p class=\"govuk-body\">Welsh</p>",
"isThereSomeoneWhoCanVouchForYou": "Welsh",
"yesIKnowSomeone": "Welsh",
"noIDoNotKnowSomeone": "Welsh",
"yesIfHaveSomeoneCanVouchForYou": "Welsh"
}
8 changes: 7 additions & 1 deletion lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1154,5 +1154,11 @@
"payingNoFee": "paying no fee (exemption)",
"payingHalfFee": "paying a half fee (remission)",
"aRepeatApplicationDiscount": "a repeat application discount",
"aHardshipApplication": "a hardship application (fee waiver)"
"aHardshipApplication": "a hardship application (fee waiver)",
"whatIsVouching": "What is vouching?",
"whatIsVouchingContent": "<p class=\"govuk-body\">Vouching allows someone you know well to confirm your identity.</p><h2 class=\"govuk-heading-m\">Who can vouch for you</h2><p class=\"govuk-body\">The person you ask to vouch for you must:</p><ul class=\"govuk-list govuk-list--bullet\"><li>be aged 18 or over</li><li>be able to confirm their own identity</li><li>have known you for at least 2 years</li><li>be willing to sign a declaration</li></ul><h2 class=\"govuk-heading-m\">Who cannot vouch for you</h2><p class=\"govuk-body\">The person you choose cannot be:</p><ul class=\"govuk-list govuk-list--bullet\"><li>someone named on your LPA, including yourself</li><li>in a relationship with you</li><li>a member of your family</li><li>living at the same address as you</li></ul><h2 class=\"govuk-heading-m\">How the person will vouch for you</h2><p class=\"govuk-body\">You must ask the person if they are willing to vouch for you first. If they are willing, they will need to confirm their own identity using GOV.UK One Login.</p><p class=\"govuk-body\">They will need either:</p><ul class=\"govuk-list govuk-list--bullet\"><li>a National Insurance number</li><li>a UK passport</li><li>a UK driving licence</li></ul><p class=\"govuk-body\">We will then ask them to sign a declaration and confirm your identity.</p>",
"isThereSomeoneWhoCanVouchForYou": "Is there someone who can vouch for you?",
"yesIKnowSomeone": "Yes, I know someone and they have agreed to vouch for me",
"noIDoNotKnowSomeone": "No, I do not know someone who can vouch for me",
"yesIfHaveSomeoneCanVouchForYou": "yes if you know someone and they have agreed to vouch for you"
}
32 changes: 32 additions & 0 deletions web/template/donor/what_is_vouching.gohtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{{ template "page" . }}

{{ define "pageTitle" }}{{ tr .App "whatIsVouching" }}{{ end }}

{{ define "main" }}
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<form novalidate method="post">
<h1 class="govuk-heading-xl">{{ tr .App "whatIsVouching" }}</h1>

{{ trHtml .App "whatIsVouchingContent" }}

<div class="govuk-form-group {{ if .Errors.Has .Form.FieldName }}govuk-form-group--error{{ end }}">
<fieldset class="govuk-fieldset">
<legend class="govuk-fieldset__legend govuk-fieldset__legend--m">{{ tr .App "isThereSomeoneWhoCanVouchForYou" }}</legend>

{{ template "error-message" (errorMessage . .Form.FieldName) }}

{{ template "radios" (items . .Form.FieldName .Form.YesNo.String
(item .Form.Options.Yes.String "yesIKnowSomeone")
(item .Form.Options.No.String "noIDoNotKnowSomeone")
) }}
</fieldset>
</div>

{{ template "buttons" (button .App "saveAndContinue") }}

{{ template "csrf-field" . }}
</form>
</div>
</div>
{{ end }}

0 comments on commit 1ec000c

Please sign in to comment.