Skip to content

Commit

Permalink
MLPAB-1740 Add page to enter an organisation or company name (#972)
Browse files Browse the repository at this point in the history
* Add page to enter an organisation or company name
* Remove the word 'account' from the start page
  • Loading branch information
hawx authored Jan 22, 2024
1 parent 3e172ba commit 72ec064
Show file tree
Hide file tree
Showing 19 changed files with 649 additions and 11 deletions.
12 changes: 12 additions & 0 deletions cypress/e2e/supporter/enter-organisation-name.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
describe('Enter group name', () => {
beforeEach(() => {
cy.visit('/fixtures/supporter?redirect=/enter-the-name-of-your-organisation-or-company');
});

it('can be started', () => {
cy.get('#f-name').type('My name' + Math.random());
cy.contains('button', 'Continue').click();

cy.url().should('contain', '/organisation-or-company-created');
});
});
26 changes: 26 additions & 0 deletions internal/actor/organisation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package actor

import "time"

// An Organisation contains users associated with a set of permissions that work on the
// same set of LPAs.
type Organisation struct {
PK, SK string
// CreatedAt is when the Organisation was created
CreatedAt time.Time
// UpdatedAt is when the Organisation was last updated
UpdatedAt time.Time
// ID is a unique identifier for the Organisation
ID string
// Name of the Organisation, this is unique across all Organisations
Name string
}

// A Member is the association of a OneLogin user with an Organisation.
type Member struct {
PK, SK string
// CreatedAt is when the Member was created
CreatedAt time.Time
// UpdatedAt is when the Member was last updated
UpdatedAt time.Time
}
4 changes: 4 additions & 0 deletions internal/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ func App(
shareCodeStore := &shareCodeStore{dynamoClient: lpaDynamoClient}
dashboardStore := &dashboardStore{dynamoClient: lpaDynamoClient}
evidenceReceivedStore := &evidenceReceivedStore{dynamoClient: lpaDynamoClient}
organisationStore := &organisationStore{dynamoClient: lpaDynamoClient, now: time.Now, uuidString: uuid.NewString}

shareCodeSender := page.NewShareCodeSender(shareCodeStore, notifyClient, appPublicURL, random.String)
witnessCodeSender := page.NewWitnessCodeSender(donorStore, notifyClient)
Expand All @@ -123,6 +124,8 @@ func App(
fixtures.CertificateProvider(tmpls.Get("certificate_provider_fixtures.gohtml"), sessionStore, shareCodeSender, donorStore, certificateProviderStore))
handleRoot(paths.AttorneyFixtures, None,
fixtures.Attorney(tmpls.Get("attorney_fixtures.gohtml"), sessionStore, shareCodeSender, donorStore, certificateProviderStore, attorneyStore))
handleRoot(paths.SupporterFixtures, None,
fixtures.Supporter(sessionStore))
handleRoot(paths.DashboardFixtures, None,
fixtures.Dashboard(tmpls.Get("dashboard_fixtures.gohtml"), sessionStore, shareCodeSender, donorStore, certificateProviderStore, attorneyStore))
handleRoot(paths.YourLegalRightsAndResponsibilities, None,
Expand All @@ -147,6 +150,7 @@ func App(
supporterTmpls,
oneLoginClient,
sessionStore,
organisationStore,
notFoundHandler,
errorHandler,
)
Expand Down
58 changes: 58 additions & 0 deletions internal/app/organisation_store.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package app

import (
"context"
"errors"
"fmt"
"time"

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

type organisationStore struct {
dynamoClient DynamoClient
uuidString func() string
now func() time.Time
}

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

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

organisationID := s.uuidString()

organisation := &actor.Organisation{
PK: organisationKey(organisationID),
SK: organisationKey(organisationID),
ID: organisationID,
Name: name,
CreatedAt: s.now(),
}

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

member := &actor.Member{
PK: organisationKey(organisationID),
SK: subKey(data.SessionID),
CreatedAt: s.now(),
}

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

return nil
}

func organisationKey(s string) string {
return "ORGANISATION#" + s
}
91 changes: 91 additions & 0 deletions internal/app/organisation_store_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package app

import (
"context"
"testing"

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

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

dynamoClient := newMockDynamoClient(t)
dynamoClient.EXPECT().
Create(ctx, &actor.Organisation{
PK: "ORGANISATION#a-uuid",
SK: "ORGANISATION#a-uuid",
ID: "a-uuid",
CreatedAt: testNow,
Name: "A name",
}).
Return(nil)
dynamoClient.EXPECT().
Create(ctx, &actor.Member{
PK: "ORGANISATION#a-uuid",
SK: "#SUB#an-id",
CreatedAt: testNow,
}).
Return(nil)

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

err := organisationStore.Create(ctx, "A name")
assert.Nil(t, err)
}

func TestOrganisationStoreCreateWithSessionMissing(t *testing.T) {
ctx := context.Background()
organisationStore := &organisationStore{dynamoClient: nil, now: testNowFn}

err := organisationStore.Create(ctx, "A name")
assert.Equal(t, page.SessionMissingError{}, err)
}

func TestOrganisationStoreCreateWithMissingSessionID(t *testing.T) {
ctx := page.ContextWithSessionData(context.Background(), &page.SessionData{})
organisationStore := &organisationStore{dynamoClient: nil, now: testNowFn}

err := organisationStore.Create(ctx, "A name")
assert.Error(t, err)
}

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

testcases := map[string]func(*testing.T) *mockDynamoClient{
"organisation": func(t *testing.T) *mockDynamoClient {
dynamoClient := newMockDynamoClient(t)
dynamoClient.EXPECT().
Create(ctx, mock.Anything).
Return(expectedError)

return dynamoClient
},
"member": func(t *testing.T) *mockDynamoClient {
dynamoClient := newMockDynamoClient(t)
dynamoClient.EXPECT().
Create(ctx, mock.Anything).
Return(nil).
Once()
dynamoClient.EXPECT().
Create(ctx, mock.Anything).
Return(expectedError)

return dynamoClient
},
}

for name, makeMockDynamoClient := range testcases {
t.Run(name, func(t *testing.T) {
dynamoClient := makeMockDynamoClient(t)
organisationStore := &organisationStore{dynamoClient: dynamoClient, now: testNowFn, uuidString: func() string { return "a-uuid" }}

err := organisationStore.Create(ctx, "A name")
assert.ErrorIs(t, err, expectedError)
})
}
}
26 changes: 26 additions & 0 deletions internal/page/fixtures/supporter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package fixtures

import (
"net/http"

"github.com/ministryofjustice/opg-modernising-lpa/internal/page"
"github.com/ministryofjustice/opg-modernising-lpa/internal/random"
"github.com/ministryofjustice/opg-modernising-lpa/internal/sesh"
)

func Supporter(sessionStore sesh.Store) page.Handler {
return func(appData page.AppData, w http.ResponseWriter, r *http.Request) error {
var (
redirect = r.FormValue("redirect")

supporterSub = random.String(16)
)

if err := sesh.SetLoginSession(sessionStore, r, w, &sesh.LoginSession{Sub: supporterSub, Email: testEmail}); err != nil {
return err
}

http.Redirect(w, r, "/supporter/"+redirect, http.StatusFound)
return nil
}
}
12 changes: 8 additions & 4 deletions internal/page/paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ type SupporterPaths struct {
Login Path
LoginCallback Path

YourOrganisation SupporterPath
EnterOrganisationName SupporterPath
OrganisationCreated SupporterPath
}

type AppPaths struct {
Expand All @@ -193,6 +194,7 @@ type AppPaths struct {
Root Path
SignOut Path
Start Path
SupporterFixtures Path
YourLegalRightsAndResponsibilities Path

AboutPayment LpaPath
Expand Down Expand Up @@ -334,7 +336,8 @@ var Paths = AppPaths{
Login: "/supporter-login",
LoginCallback: "/supporter-login-callback",

YourOrganisation: "/your-organisation",
EnterOrganisationName: "/enter-the-name-of-your-organisation-or-company",
OrganisationCreated: "/organisation-or-company-created",
},

HealthCheck: HealthCheckPaths{
Expand Down Expand Up @@ -425,6 +428,7 @@ var Paths = AppPaths{
SignTheLpaOnBehalf: "/sign-the-lpa-on-behalf",
SignYourLpa: "/sign-your-lpa",
Start: "/start",
SupporterFixtures: "/fixtures/supporter",
TaskList: "/task-list",
UploadEvidence: "/upload-evidence",
UploadEvidenceSSE: "/upload-evidence-sse",
Expand All @@ -438,12 +442,12 @@ var Paths = AppPaths{
WitnessingAsCertificateProvider: "/witnessing-as-certificate-provider",
WitnessingAsIndependentWitness: "/witnessing-as-independent-witness",
WitnessingYourSignature: "/witnessing-your-signature",
YouHaveSubmittedYourLpa: "/you-have-submitted-your-lpa",
YouCannotSignYourLpaYet: "/you-cannot-sign-your-lpa-yet",
YouHaveSubmittedYourLpa: "/you-have-submitted-your-lpa",
YourAddress: "/your-address",
YourAuthorisedSignatory: "/your-authorised-signatory",
YourDetails: "/your-details",
YourDateOfBirth: "/your-date-of-birth",
YourDetails: "/your-details",
YourIndependentWitness: "/your-independent-witness",
YourIndependentWitnessAddress: "/your-independent-witness-address",
YourIndependentWitnessMobile: "/your-independent-witness-mobile",
Expand Down
59 changes: 59 additions & 0 deletions internal/page/supporter/enter_organisation_name.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package supporter

import (
"net/http"

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

type enterOrganisationNameData struct {
App page.AppData
Errors validation.List
Form *enterOrganisationNameForm
}

func EnterOrganisationName(tmpl template.Template, organisationStore OrganisationStore) Handler {
return func(appData page.AppData, w http.ResponseWriter, r *http.Request) error {
data := &enterOrganisationNameData{
App: appData,
Form: &enterOrganisationNameForm{},
}

if r.Method == http.MethodPost {
data.Form = readEnterOrganisationNameForm(r)
data.Errors = data.Form.Validate()

if !data.Errors.Any() {
if err := organisationStore.Create(r.Context(), data.Form.Name); err != nil {
return err
}

return page.Paths.Supporter.OrganisationCreated.Redirect(w, r, appData)
}
}

return tmpl(w, data)
}
}

type enterOrganisationNameForm struct {
Name string
}

func readEnterOrganisationNameForm(r *http.Request) *enterOrganisationNameForm {
return &enterOrganisationNameForm{
Name: page.PostFormString(r, "name"),
}
}

func (f *enterOrganisationNameForm) Validate() validation.List {
var errors validation.List

errors.String("name", "fullOrganisationOrCompanyName", f.Name,
validation.Empty(),
validation.StringTooLong(100))

return errors
}
Loading

0 comments on commit 72ec064

Please sign in to comment.