Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MLPAB-2416 MLPAB-2417 Trust corporation opt-out #256

Merged
merged 2 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 0 additions & 39 deletions internal/shared/lpa.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package shared

import (
"slices"
"time"
)

Expand All @@ -27,44 +26,6 @@ type LpaInit struct {
CertificateProviderNotRelatedConfirmedAt *time.Time `json:"certificateProviderNotRelatedConfirmedAt,omitempty"`
}

func (l *Lpa) GetAttorney(uid string) (Attorney, bool) {
idx := slices.IndexFunc(l.Attorneys, func(a Attorney) bool { return a.UID == uid })
if idx == -1 {
return Attorney{}, false
}

return l.Attorneys[idx], true
}

func (l *Lpa) PutAttorney(attorney Attorney) {
idx := slices.IndexFunc(l.Attorneys, func(a Attorney) bool { return a.UID == attorney.UID })
if idx == -1 {
l.Attorneys = append(l.Attorneys, attorney)
} else {
l.Attorneys[idx] = attorney
}
}

func (l *Lpa) ActiveAttorneys() (attorneys []Attorney) {
for _, a := range l.Attorneys {
if a.Status == AttorneyStatusActive {
attorneys = append(attorneys, a)
}
}

return attorneys
}

func (l *Lpa) ActiveTrustCorporations() (trustCorporations []TrustCorporation) {
for _, tc := range l.TrustCorporations {
if tc.Status == AttorneyStatusActive {
trustCorporations = append(trustCorporations, tc)
}
}

return trustCorporations
}

type Lpa struct {
LpaInit
Uid string `json:"uid"`
Expand Down
111 changes: 0 additions & 111 deletions internal/shared/lpa_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,114 +19,3 @@ func TestLpaInitMarshalJSON(t *testing.T) {
data, _ := json.Marshal(LpaInit{})
assert.JSONEq(t, expected, string(data))
}

func TestAttorneysGet(t *testing.T) {
testCases := map[string]struct {
attorneys []Attorney
expectedAttorney Attorney
uid string
expectedFound bool
}{
"found": {
attorneys: []Attorney{
{Person: Person{UID: "abc", FirstNames: "a"}},
{Person: Person{UID: "xyz", FirstNames: "b"}},
},
expectedAttorney: Attorney{Person: Person{UID: "xyz", FirstNames: "b"}},
uid: "xyz",
expectedFound: true,
},
"not found": {
attorneys: []Attorney{
{Person: Person{UID: "abc", FirstNames: "a"}},
{Person: Person{UID: "xyz", FirstNames: "b"}},
},
expectedAttorney: Attorney{},
uid: "not-a-match",
expectedFound: false,
},
}

for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
lpa := &Lpa{LpaInit: LpaInit{Attorneys: tc.attorneys}}
a, found := lpa.GetAttorney(tc.uid)

assert.Equal(t, tc.expectedFound, found)
assert.Equal(t, tc.expectedAttorney, a)
})
}
}

func TestAttorneysPut(t *testing.T) {
testCases := map[string]struct {
attorneys []Attorney
expectedAttorneys []Attorney
updatedAttorney Attorney
}{
"does not exist": {
attorneys: []Attorney{
{Person: Person{UID: "abc", FirstNames: "a"}},
},
expectedAttorneys: []Attorney{
{Person: Person{UID: "abc", FirstNames: "a"}},
{Person: Person{UID: "xyz", FirstNames: "b"}},
},
updatedAttorney: Attorney{Person: Person{UID: "xyz", FirstNames: "b"}},
},
"exists": {
attorneys: []Attorney{
{Person: Person{UID: "abc", FirstNames: "a"}},
{Person: Person{UID: "xyz", FirstNames: "b"}},
},
expectedAttorneys: []Attorney{
{Person: Person{UID: "abc", FirstNames: "a"}},
{Person: Person{UID: "xyz", FirstNames: "z"}},
},
updatedAttorney: Attorney{Person: Person{UID: "xyz", FirstNames: "z"}},
},
}

for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
lpa := &Lpa{LpaInit: LpaInit{Attorneys: tc.attorneys}}
lpa.PutAttorney(tc.updatedAttorney)

assert.Equal(t, tc.expectedAttorneys, lpa.Attorneys)
})
}
}

func TestActiveAttorneys(t *testing.T) {
lpa := &Lpa{LpaInit: LpaInit{
Attorneys: []Attorney{
{Person: Person{FirstNames: "a"}},
{Person: Person{FirstNames: "b"}, Status: AttorneyStatusActive},
{Person: Person{FirstNames: "c"}, Status: AttorneyStatusReplacement},
{Person: Person{FirstNames: "d"}, Status: AttorneyStatusRemoved},
{Person: Person{FirstNames: "e"}, Status: AttorneyStatusActive},
},
}}

assert.Equal(t, []Attorney{
{Person: Person{FirstNames: "b"}, Status: AttorneyStatusActive},
{Person: Person{FirstNames: "e"}, Status: AttorneyStatusActive},
}, lpa.ActiveAttorneys())
}

func TestActiveTrustCorporations(t *testing.T) {
lpa := &Lpa{LpaInit: LpaInit{
TrustCorporations: []TrustCorporation{
{Name: "a"},
{Name: "b", Status: AttorneyStatusActive},
{Name: "c", Status: AttorneyStatusReplacement},
{Name: "d", Status: AttorneyStatusRemoved},
{Name: "e", Status: AttorneyStatusActive},
},
}}

assert.Equal(t, []TrustCorporation{
{Name: "b", Status: AttorneyStatusActive},
{Name: "e", Status: AttorneyStatusActive},
}, lpa.ActiveTrustCorporations())
}
21 changes: 10 additions & 11 deletions lambda/update/attorney_opt_out.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,18 @@ type AttorneyOptOut struct {
}

func (c AttorneyOptOut) Apply(lpa *shared.Lpa) []shared.FieldError {
attorney, ok := lpa.GetAttorney(c.AttorneyUID)
if !ok {
return []shared.FieldError{{Source: "/type", Detail: "attorney not found"}}
for i := range lpa.Attorneys {
if lpa.Attorneys[i].UID == c.AttorneyUID {
if lpa.Attorneys[i].SignedAt != nil && !lpa.Attorneys[i].SignedAt.IsZero() {
return []shared.FieldError{{Source: "/type", Detail: "attorney cannot opt out after signing"}}
}

lpa.Attorneys[i].Status = shared.AttorneyStatusRemoved
return nil
}
}

if attorney.SignedAt != nil && !attorney.SignedAt.IsZero() {
return []shared.FieldError{{Source: "/type", Detail: "attorney cannot opt out after signing"}}
}

attorney.Status = shared.AttorneyStatusRemoved
lpa.PutAttorney(attorney)

return nil
return []shared.FieldError{{Source: "/type", Detail: "attorney not found"}}
}

func validateAttorneyOptOut(update shared.Update) (AttorneyOptOut, []shared.FieldError) {
Expand Down
22 changes: 22 additions & 0 deletions lambda/update/attorney_opt_out_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,28 @@ func TestAttorneyOptOutApply(t *testing.T) {
},
},
},
"successful apply to replacement": {
lpa: &shared.Lpa{
Status: shared.LpaStatusInProgress,
LpaInit: shared.LpaInit{
Attorneys: []shared.Attorney{
{Person: shared.Person{UID: "a"}, Status: shared.AttorneyStatusActive},
{Person: shared.Person{UID: "b"}, Status: shared.AttorneyStatusReplacement},
{Person: shared.Person{UID: "c"}, Status: shared.AttorneyStatusActive},
},
},
},
expectedLpa: &shared.Lpa{
Status: shared.LpaStatusInProgress,
LpaInit: shared.LpaInit{
Attorneys: []shared.Attorney{
{Person: shared.Person{UID: "a"}, Status: shared.AttorneyStatusActive},
{Person: shared.Person{UID: "b"}, Status: shared.AttorneyStatusRemoved},
{Person: shared.Person{UID: "c"}, Status: shared.AttorneyStatusActive},
},
},
},
},
"not found": {
lpa: &shared.Lpa{
Status: shared.LpaStatusInProgress,
Expand Down
39 changes: 39 additions & 0 deletions lambda/update/trust_corporation_opt_out.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package main

import (
"github.com/ministryofjustice/opg-data-lpa-store/internal/shared"
"github.com/ministryofjustice/opg-data-lpa-store/internal/validate"
)

type TrustCorporationOptOut struct {
trustCorporationUID string
}

func (c TrustCorporationOptOut) Apply(lpa *shared.Lpa) []shared.FieldError {
for i := range lpa.TrustCorporations {
if lpa.TrustCorporations[i].UID == c.trustCorporationUID {
if len(lpa.TrustCorporations[i].Signatories) > 0 && !lpa.TrustCorporations[i].Signatories[0].SignedAt.IsZero() {
return []shared.FieldError{{Source: "/type", Detail: "trust corporation cannot opt out after signing"}}
}

lpa.TrustCorporations[i].Status = shared.AttorneyStatusRemoved
return nil
}
}

return []shared.FieldError{{Source: "/type", Detail: "trust corporation not found"}}
}

func validateTrustCorporationOptOut(update shared.Update) (TrustCorporationOptOut, []shared.FieldError) {
if len(update.Changes) > 0 {
return TrustCorporationOptOut{}, []shared.FieldError{{Source: "/changes", Detail: "expected empty"}}
}

author := update.Author.Details()

if errs := validate.UUID("/author", author.UID); len(errs) > 0 {
return TrustCorporationOptOut{}, errs
}

return TrustCorporationOptOut{trustCorporationUID: author.UID}, nil
}
Loading
Loading