Skip to content

Commit

Permalink
MLPAB-1743: Create a new LPA as a supporter (#1017)
Browse files Browse the repository at this point in the history
  • Loading branch information
acsauk authored Feb 7, 2024
1 parent 5fb3e36 commit b3f1714
Show file tree
Hide file tree
Showing 25 changed files with 908 additions and 159 deletions.
12 changes: 12 additions & 0 deletions cypress/e2e/supporter/dashboard.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
describe('Dashboard', () => {
beforeEach(() => {
cy.visit('/fixtures/supporter?redirect=/supporter-dashboard&organisation=1');
});

it('can create a new LPA', () => {
cy.checkA11yApp();
cy.contains('button', 'Make a new LPA').click();

cy.url().should('contain', '/your-details');
});
});
8 changes: 7 additions & 1 deletion internal/app/donor_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,14 @@ func (s *donorStore) Get(ctx context.Context) (*actor.DonorProvidedDetails, erro
return nil, errors.New("donorStore.Get requires LpaID and SessionID")
}

sk := donorKey(data.SessionID)

if data.OrganisationID != "" {
sk = organisationKey(data.OrganisationID)
}

var donor *actor.DonorProvidedDetails
err = s.dynamoClient.One(ctx, lpaKey(data.LpaID), donorKey(data.SessionID), &donor)
err = s.dynamoClient.One(ctx, lpaKey(data.LpaID), sk, &donor)
return donor, err
}

Expand Down
32 changes: 25 additions & 7 deletions internal/app/donor_store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,16 +116,34 @@ func TestDonorStoreGetAnyWhenDataStoreError(t *testing.T) {
}

func TestDonorStoreGet(t *testing.T) {
ctx := page.ContextWithSessionData(context.Background(), &page.SessionData{LpaID: "an-id", SessionID: "456"})
testCases := map[string]struct {
sessionData *page.SessionData
expectedSK string
}{
"donor": {
sessionData: &page.SessionData{LpaID: "an-id", SessionID: "456"},
expectedSK: "#DONOR#456",
},
"organisation": {
sessionData: &page.SessionData{LpaID: "an-id", SessionID: "456", OrganisationID: "789"},
expectedSK: "ORGANISATION#789",
},
}

dynamoClient := newMockDynamoClient(t)
dynamoClient.ExpectOne(ctx, "LPA#an-id", "#DONOR#456", &actor.DonorProvidedDetails{LpaID: "an-id"}, nil)
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
ctx := page.ContextWithSessionData(context.Background(), tc.sessionData)

donorStore := &donorStore{dynamoClient: dynamoClient, uuidString: func() string { return "10100000" }}
dynamoClient := newMockDynamoClient(t)
dynamoClient.ExpectOne(ctx, "LPA#an-id", tc.expectedSK, &actor.DonorProvidedDetails{LpaID: "an-id"}, nil)

lpa, err := donorStore.Get(ctx)
assert.Nil(t, err)
assert.Equal(t, &actor.DonorProvidedDetails{LpaID: "an-id"}, lpa)
donorStore := &donorStore{dynamoClient: dynamoClient, uuidString: func() string { return "10100000" }}

lpa, err := donorStore.Get(ctx)
assert.Nil(t, err)
assert.Equal(t, &actor.DonorProvidedDetails{LpaID: "an-id"}, lpa)
})
}
}

func TestDonorStoreGetWithSessionMissing(t *testing.T) {
Expand Down
43 changes: 37 additions & 6 deletions internal/app/organisation_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ type organisationStore struct {
now func() time.Time
}

func (s *organisationStore) Create(ctx context.Context, name string) error {
func (s *organisationStore) Create(ctx context.Context, name string) (*actor.Organisation, error) {
data, err := page.SessionDataFromContext(ctx)
if err != nil {
return err
return nil, err
}

if data.SessionID == "" {
return errors.New("organisationStore.Create requires SessionID")
return nil, errors.New("organisationStore.Create requires SessionID")
}

organisationID := s.uuidString()
Expand All @@ -38,7 +38,7 @@ func (s *organisationStore) Create(ctx context.Context, name string) error {
}

if err := s.dynamoClient.Create(ctx, organisation); err != nil {
return fmt.Errorf("error creating organisation: %w", err)
return nil, fmt.Errorf("error creating organisation: %w", err)
}

member := &actor.Member{
Expand All @@ -48,10 +48,10 @@ func (s *organisationStore) Create(ctx context.Context, name string) error {
}

if err := s.dynamoClient.Create(ctx, member); err != nil {
return fmt.Errorf("error creating organisation member: %w", err)
return nil, fmt.Errorf("error creating organisation member: %w", err)
}

return nil
return organisation, nil
}

func (s *organisationStore) Get(ctx context.Context) (*actor.Organisation, error) {
Expand Down Expand Up @@ -98,6 +98,37 @@ func (s *organisationStore) CreateMemberInvite(ctx context.Context, organisation
return nil
}

func (s *organisationStore) CreateLPA(ctx context.Context, organisationID string) (*actor.DonorProvidedDetails, error) {
data, err := page.SessionDataFromContext(ctx)
if err != nil {
return nil, err
}

if data.SessionID == "" {
return nil, errors.New("donorStore.Create requires SessionID")
}

lpaID := s.uuidString()

donor := &actor.DonorProvidedDetails{
PK: lpaKey(lpaID),
SK: organisationKey(organisationID),
LpaID: lpaID,
CreatedAt: s.now(),
Version: 1,
}

if donor.Hash, err = donor.GenerateHash(); err != nil {
return nil, err
}

if err := s.dynamoClient.Create(ctx, donor); err != nil {
return nil, err
}

return donor, err
}

func organisationKey(s string) string {
return "ORGANISATION#" + s
}
Expand Down
74 changes: 71 additions & 3 deletions internal/app/organisation_store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,15 @@ func TestOrganisationStoreCreate(t *testing.T) {

organisationStore := &organisationStore{dynamoClient: dynamoClient, now: testNowFn, uuidString: func() string { return "a-uuid" }}

err := organisationStore.Create(ctx, "A name")
organisation, err := organisationStore.Create(ctx, "A name")
assert.Nil(t, err)
assert.Equal(t, &actor.Organisation{
PK: "ORGANISATION#a-uuid",
SK: "ORGANISATION#a-uuid",
ID: "a-uuid",
CreatedAt: testNow,
Name: "A name",
}, organisation)
}

func TestOrganisationStoreCreateWithSessionMissing(t *testing.T) {
Expand All @@ -47,8 +54,9 @@ func TestOrganisationStoreCreateWithSessionMissing(t *testing.T) {
t.Run(name, func(t *testing.T) {
organisationStore := &organisationStore{}

err := organisationStore.Create(ctx, "A name")
organisation, err := organisationStore.Create(ctx, "A name")
assert.Error(t, err)
assert.Nil(t, organisation)
})
}
}
Expand Down Expand Up @@ -84,8 +92,9 @@ func TestOrganisationStoreCreateWhenErrors(t *testing.T) {
dynamoClient := makeMockDynamoClient(t)
organisationStore := &organisationStore{dynamoClient: dynamoClient, now: testNowFn, uuidString: func() string { return "a-uuid" }}

err := organisationStore.Create(ctx, "A name")
organisation, err := organisationStore.Create(ctx, "A name")
assert.ErrorIs(t, err, expectedError)
assert.Nil(t, organisation)
})
}
}
Expand Down Expand Up @@ -211,3 +220,62 @@ func TestOrganisationStoreCreateMemberInviteWhenErrors(t *testing.T) {
err := organisationStore.CreateMemberInvite(ctx, &actor.Organisation{}, "[email protected]", "abcde")
assert.ErrorIs(t, err, expectedError)
}

func TestOrganisationStoreCreateLPA(t *testing.T) {
ctx := page.ContextWithSessionData(context.Background(), &page.SessionData{SessionID: "an-id"})
expectedDonor := &actor.DonorProvidedDetails{
PK: "LPA#a-uuid",
SK: "ORGANISATION#an-id",
LpaID: "a-uuid",
CreatedAt: testNow,
Version: 1,
}
expectedDonor.Hash, _ = expectedDonor.GenerateHash()

dynamoClient := newMockDynamoClient(t)
dynamoClient.EXPECT().
Create(ctx, expectedDonor).
Return(nil)

organisationStore := &organisationStore{dynamoClient: dynamoClient, now: testNowFn, uuidString: func() string { return "a-uuid" }}

donor, err := organisationStore.CreateLPA(ctx, "an-id")

assert.Nil(t, err)
assert.Equal(t, expectedDonor, donor)
}

func TestOrganisationStoreCreateLPAWithSessionMissing(t *testing.T) {
ctx := page.ContextWithSessionData(context.Background(), &page.SessionData{SessionID: ""})

organisationStore := &organisationStore{dynamoClient: nil, now: testNowFn, uuidString: func() string { return "a-uuid" }}

_, err := organisationStore.CreateLPA(ctx, "an-id")

assert.NotNil(t, err)
}

func TestOrganisationStoreCreateLPAMissingSessionID(t *testing.T) {
ctx := context.Background()

organisationStore := &organisationStore{dynamoClient: nil, now: testNowFn, uuidString: func() string { return "a-uuid" }}

_, err := organisationStore.CreateLPA(ctx, "an-id")

assert.Equal(t, page.SessionMissingError{}, err)
}

func TestOrganisationStoreCreateLPAWhenDynamoError(t *testing.T) {
ctx := page.ContextWithSessionData(context.Background(), &page.SessionData{SessionID: "an-id"})

dynamoClient := newMockDynamoClient(t)
dynamoClient.EXPECT().
Create(ctx, mock.Anything).
Return(expectedError)

organisationStore := &organisationStore{dynamoClient: dynamoClient, now: testNowFn, uuidString: func() string { return "a-uuid" }}

_, err := organisationStore.CreateLPA(ctx, "an-id")

assert.Equal(t, expectedError, err)
}
5 changes: 3 additions & 2 deletions internal/page/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ import (
)

type SessionData struct {
SessionID string
LpaID string
SessionID string
LpaID string
OrganisationID string
}

type SessionMissingError struct{}
Expand Down
16 changes: 12 additions & 4 deletions internal/page/donor/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -436,22 +436,30 @@ func makeLpaHandle(mux *http.ServeMux, store sesh.Store, defaultOptions page.Han
appData.ActorType = actor.TypeDonor
appData.AppPublicURL = appPublicURL

donorSession, err := sesh.Login(store, r)
loginSession, err := sesh.Login(store, r)
if err != nil {
http.Redirect(w, r, page.Paths.Start.Format(), http.StatusFound)
return
}

appData.SessionID = donorSession.SessionID()

appData.SessionID = loginSession.SessionID()
sessionData, err := page.SessionDataFromContext(ctx)

if err == nil {
sessionData.SessionID = appData.SessionID
ctx = page.ContextWithSessionData(ctx, sessionData)

appData.LpaID = sessionData.LpaID
} else {
ctx = page.ContextWithSessionData(ctx, &page.SessionData{SessionID: appData.SessionID, LpaID: appData.LpaID})
sessionData = &page.SessionData{SessionID: appData.SessionID, LpaID: appData.LpaID}
ctx = page.ContextWithSessionData(ctx, sessionData)
}

if loginSession.OrganisationID != "" {
appData.IsSupporter = true
appData.OrganisationName = loginSession.OrganisationName

sessionData.OrganisationID = loginSession.OrganisationID
}

appData.Page = path.Format(appData.LpaID)
Expand Down
Loading

0 comments on commit b3f1714

Please sign in to comment.