Skip to content

Commit

Permalink
Add contextual LPA for view LPA
Browse files Browse the repository at this point in the history
  • Loading branch information
hawx committed Sep 20, 2024
1 parent 899903e commit c80ac5a
Show file tree
Hide file tree
Showing 45 changed files with 1,348 additions and 435 deletions.
25 changes: 25 additions & 0 deletions cmd/mlpa/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
"github.com/stretchr/testify/assert"
)

var htmlTagRe = regexp.MustCompile("<.+?>")

func TestAwsRegion(t *testing.T) {
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/task" {
Expand Down Expand Up @@ -141,6 +143,21 @@ func TestTranslationVariablesMustMatch(t *testing.T) {
}
}

func TestTranslationContentMustMatch(t *testing.T) {
en := loadTranslations("../../lang/en.json")
cy := loadTranslations("../../lang/cy.json")

mustMatch := map[string]string{
"yourLegalRightsAndResponsibilitiesContent:property-and-affairs": "yourLegalRightsAndResponsibilitiesContent:property-and-affairs:h3",
"yourLegalRightsAndResponsibilitiesContent:personal-welfare": "yourLegalRightsAndResponsibilitiesContent:personal-welfare:h3",
}

for a, b := range mustMatch {
assert.Equal(t, stripHTML(en[a]), stripHTML(en[b]))
assert.Equal(t, stripHTML(cy[a]), stripHTML(cy[b]))
}
}

func loadTranslations(path string) map[string]string {
data, err := os.ReadFile(path)
if err != nil {
Expand All @@ -152,3 +169,11 @@ func loadTranslations(path string) map[string]string {

return v
}

func TestStripHTML(t *testing.T) {
assert.Equal(t, "<X>Hey<X><X>link<X><X>", stripHTML(`<h1 class="what">Hey</h1><div>link</div><input />`))
}

func stripHTML(s string) string {
return htmlTagRe.ReplaceAllString(s, "<X>")
}
51 changes: 51 additions & 0 deletions cypress/e2e/donor/view-lpa.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
describe('View LPA', () => {
describe('when signed by donor', () => {
beforeEach(() => {
cy.visit('/fixtures?redirect=/view-lpa&progress=signTheLpa');
});

it('shows the actors', () => {
cy.contains('Donor: Sam Smith');
cy.contains('Certificate provider: Charlie Cooper');
cy.contains('Attorney: Jessie Jones');
cy.contains('Attorney: Robin Redcar');
cy.contains('Replacement attorney: Blake Buckley');
cy.contains('Replacement attorney: Taylor Thompson');
cy.contains('Person to notify: Jordan Jefferson');
cy.contains('Person to notify: Danni Davies');
});

it('shows the decisions', () => {
cy.contains('Whether or not I have mental capacity to make a particular decision myself');
cy.contains('Jointly and severally - your attorneys can make decisions both on their own or together');
cy.contains('All together, as soon as one of your attorneys can no longer act. They will be able to make decisions jointly and severally with any attorney who is continuing to act.');
cy.contains('My attorneys must not sell my home unless, in my doctor’s opinion, I can no longer live independently');
});

it('contains the donor signature', () => {
cy.contains('Signed by Sam Smith on: 2 January 2023');
cy.contains('Witnessed by Charlie Cooper on: 2 January 2023');
});

it('does not contain other signatures', () => {
cy.contains('Attorney signature').should('not.exist');
});
});

describe('when signed by everyone', () => {
beforeEach(() => {
cy.visit('/fixtures?redirect=/view-lpa&attorneys=trust-corporation&progress=submitted');
});

it('shows all signatures', () => {
cy.contains('Signed by Sam Smith on: 2 January 2023');
cy.contains('Witnessed by Charlie Cooper on: 2 January 2023');
cy.contains('Signed by Charlie Cooper on: 5 January 2023');
cy.contains('Signed by Jessie Jones on: 12 January 2023');
cy.contains('Signed by Robin Redcar on: 12 January 2023');
cy.contains('Signed by A Sign on: 17 January 2023');
cy.contains('Signed by Blake Buckley on: 12 January 2023');
cy.contains('Signed by Taylor Thompson on: 12 January 2023');
});
});
});
165 changes: 84 additions & 81 deletions docker/mock-lpa-store/lpa-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,99 +5,102 @@ const pathParts = context.request.path.split('/');
const lpaUID = pathParts[2]

switch (context.request.method) {
case 'GET': {
if (pathParts.length == 3 && pathParts[1] == 'lpas') {
const lpa = lpaStore.load(lpaUID);
if (lpa) {
respond().withContent(lpa);
} else {
respond().withStatusCode(404);
}
} else {
respond();
case 'GET': {
if (pathParts.length == 3 && pathParts[1] == 'lpas') {
const lpa = lpaStore.load(lpaUID);
if (lpa) {
respond().withContent(lpa);
} else {
respond().withStatusCode(404);
}
} else {
respond();
}
break;
}
break;
}
case 'PUT': {
let lpa = JSON.parse(context.request.body);
lpa.uid = lpaUID;
lpa.updatedAt = new Date(Date.now()).toISOString();
lpaStore.save(lpaUID, JSON.stringify(lpa));
respond();
break;
}
case 'POST': {
if (context.request.path == '/lpas') {
let uids = JSON.parse(context.request.body).uids;
let lpas = uids.map(uid => lpaStore.load(uid)).reduce((list, lpa) => lpa ? list.concat([JSON.parse(lpa)]) : list, []);

respond().withContent(JSON.stringify({ lpas: lpas }));
} else {
let update = JSON.parse(context.request.body);
let lpa = JSON.parse(lpaStore.load(lpaUID));
if (!lpa) {
respond().withStatusCode(404);
case 'PUT': {
let lpa = JSON.parse(context.request.body);
lpa.uid = lpaUID;
lpa.updatedAt = new Date(Date.now()).toISOString();
lpaStore.save(lpaUID, JSON.stringify(lpa));
respond();
break;
}
lpa.updatedAt = new Date(Date.now()).toISOString();
}
case 'POST': {
if (context.request.path == '/lpas') {
let uids = JSON.parse(context.request.body).uids;
let lpas = uids.map(uid => lpaStore.load(uid)).reduce((list, lpa) => lpa ? list.concat([JSON.parse(lpa)]) : list, []);

switch (update.type) {
case 'ATTORNEY_SIGN': {
const keyParts = update.changes[0].key.split('/');
const idx = parseInt(keyParts[2]);
respond().withContent(JSON.stringify({ lpas: lpas }));
} else {
let update = JSON.parse(context.request.body);
let lpa = JSON.parse(lpaStore.load(lpaUID));
if (!lpa) {
respond().withStatusCode(404);
break;
}
lpa.updatedAt = new Date(Date.now()).toISOString();

if (lpa.attorneys && idx < lpa.attorneys.length) {
lpa.attorneys[idx].signedAt = lpa.signedAt;
}
break;
}
case 'TRUST_CORPORATION_SIGN': {
const keyParts = update.changes[0].key.split('/');
const idx = parseInt(keyParts[2]);
switch (update.type) {
case 'ATTORNEY_SIGN': {
const keyParts = update.changes[0].key.split('/');
const idx = parseInt(keyParts[2]);
const signedAt = update.changes.find(x => x.key.includes('signedAt')).new;

if (lpa.trustCorporations && idx < lpa.trustCorporations.length) {
lpa.trustCorporations[idx].signatories = [{ signedAt: lpa.signedAt }];
}
break;
}
case 'CERTIFICATE_PROVIDER_SIGN':
lpa.certificateProvider.signedAt = lpa.signedAt;
break;
if (lpa.attorneys && idx < lpa.attorneys.length) {
lpa.attorneys[idx].signedAt = signedAt;
}
break;
}
case 'TRUST_CORPORATION_SIGN': {
const keyParts = update.changes[0].key.split('/');
const idx = parseInt(keyParts[2]);
const signedAt = update.changes.find(x => x.key.includes('signedAt')).new;

if (lpa.trustCorporations && idx < lpa.trustCorporations.length) {
lpa.trustCorporations[idx].signatories = [{ firstNames: "A", lastName: "Sign", signedAt: signedAt }];
}
break;
}
case 'CERTIFICATE_PROVIDER_SIGN':
const signedAt = update.changes.find(x => x.key.includes('signedAt')).new;
lpa.certificateProvider.signedAt = signedAt;
break;

case 'PERFECT':
lpa.status = 'perfect';
break;
case 'PERFECT':
lpa.status = 'perfect';
break;

case 'REGISTER':
if (lpa.status === 'perfect') {
lpa.status = 'registered';
lpa.registrationDate = new Date(Date.now()).toISOString();
}
break;
case 'REGISTER':
if (lpa.status === 'perfect') {
lpa.status = 'registered';
lpa.registrationDate = new Date(Date.now()).toISOString();
}
break;

case 'CERTIFICATE_PROVIDER_OPT_OUT':
lpa.status = 'cannot-register';
break;
case 'CERTIFICATE_PROVIDER_OPT_OUT':
lpa.status = 'cannot-register';
break;

case 'DONOR_WITHDRAW_LPA':
lpa.status = 'withdrawn';
break;
case 'DONOR_WITHDRAW_LPA':
lpa.status = 'withdrawn';
break;

case 'ATTORNEY_OPT_OUT':
const idx = lpa.attorneys.findIndex(item => item.uid === update.subject)
case 'ATTORNEY_OPT_OUT':
const idx = lpa.attorneys.findIndex(item => item.uid === update.subject)

if (idx >= 0 && lpa.attorneys[idx].signedAt != '') {
lpa.attorneys[idx].status = 'removed'
}
break;
if (idx >= 0 && lpa.attorneys[idx].signedAt != '') {
lpa.attorneys[idx].status = 'removed'
}
break;

}
}

lpaStore.save(lpaUID, JSON.stringify(lpa));
respond();
lpaStore.save(lpaUID, JSON.stringify(lpa));
respond();
}
break;
}
break;
}
default:
respond();
default:
respond();
}
4 changes: 4 additions & 0 deletions internal/actor/actor.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ type Actor struct {
FirstNames string
LastName string
}

func (a Actor) FullName() string {
return a.FirstNames + " " + a.LastName
}
11 changes: 11 additions & 0 deletions internal/actor/actor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package actor

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestActorFullName(t *testing.T) {
assert.Equal(t, "John Smith", Actor{FirstNames: "John", LastName: "Smith"}.FullName())
}
7 changes: 6 additions & 1 deletion internal/donor/donordata/authorised_signatory.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package donordata

import "fmt"
import (
"fmt"

"github.com/ministryofjustice/opg-modernising-lpa/internal/actor/actoruid"
)

// AuthorisedSignatory contains details of the person who will sign the LPA on the donor's behalf
type AuthorisedSignatory struct {
UID actoruid.UID
FirstNames string
LastName string
}
Expand Down
2 changes: 2 additions & 0 deletions internal/donor/donordata/independent_witness.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package donordata
import (
"fmt"

"github.com/ministryofjustice/opg-modernising-lpa/internal/actor/actoruid"
"github.com/ministryofjustice/opg-modernising-lpa/internal/place"
)

// IndependentWitness contains details of the person who will also witness the signing of the LPA
type IndependentWitness struct {
UID actoruid.UID
FirstNames string
LastName string
HasNonUKMobile bool
Expand Down
8 changes: 4 additions & 4 deletions internal/donor/donordata/provided_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ func TestGenerateHash(t *testing.T) {
}

// DO change this value to match the updates
const modified uint64 = 0xfd5454f5d9c33092
const modified uint64 = 0x3556b423a27f17b8

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

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

// DO change this value to match the updates
const modified uint64 = 0xaca608ad8e0a588d
const modified uint64 = 0x51d901b0a335d248

// 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: 0xc354aa0f0c97e090,
0: 0x8681da14cea4a7f4,
}

for version, initial := range testcases {
Expand Down
7 changes: 5 additions & 2 deletions internal/donor/donorpage/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ func Register(

handleWithDonor := makeLpaHandle(rootMux, sessionStore, errorHandler, donorStore)

handleWithDonor(donor.PathViewLPA, page.None,
ViewLpa(tmpls.Get("view_lpa.gohtml"), lpaStoreClient))

handleWithDonor(donor.PathDeleteThisLpa, page.None,
DeleteLpa(tmpls.Get("delete_this_lpa.gohtml"), donorStore))
handleWithDonor(donor.PathWithdrawThisLpa, page.None,
Expand Down Expand Up @@ -335,9 +338,9 @@ func Register(
handleWithDonor(donor.PathGettingHelpSigning, page.CanGoBack,
Guidance(tmpls.Get("getting_help_signing.gohtml")))
handleWithDonor(donor.PathYourAuthorisedSignatory, page.CanGoBack,
YourAuthorisedSignatory(tmpls.Get("your_authorised_signatory.gohtml"), donorStore))
YourAuthorisedSignatory(tmpls.Get("your_authorised_signatory.gohtml"), donorStore, actoruid.New))
handleWithDonor(donor.PathYourIndependentWitness, page.CanGoBack,
YourIndependentWitness(tmpls.Get("your_independent_witness.gohtml"), donorStore))
YourIndependentWitness(tmpls.Get("your_independent_witness.gohtml"), donorStore, actoruid.New))
handleWithDonor(donor.PathYourIndependentWitnessMobile, page.CanGoBack,
YourIndependentWitnessMobile(tmpls.Get("your_independent_witness_mobile.gohtml"), donorStore))
handleWithDonor(donor.PathYourIndependentWitnessAddress, page.CanGoBack,
Expand Down
Loading

0 comments on commit c80ac5a

Please sign in to comment.