Skip to content

Commit

Permalink
Merge pull request #1690 from ministryofjustice/MLPAB-2019-attorney-r…
Browse files Browse the repository at this point in the history
…eminders

MLPAB-2019 Send reminders to attorneys when they haven't signed
  • Loading branch information
hawx authored Dec 19, 2024
2 parents b9bcd96 + 9abd42b commit 32d8084
Show file tree
Hide file tree
Showing 37 changed files with 2,195 additions and 85 deletions.
3 changes: 1 addition & 2 deletions cmd/event-received/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"github.com/ministryofjustice/opg-modernising-lpa/internal/lpastore"
"github.com/ministryofjustice/opg-modernising-lpa/internal/lpastore/lpadata"
"github.com/ministryofjustice/opg-modernising-lpa/internal/notify"
"github.com/ministryofjustice/opg-modernising-lpa/internal/random"
"github.com/ministryofjustice/opg-modernising-lpa/internal/scheduled"
"github.com/ministryofjustice/opg-modernising-lpa/internal/search"
"github.com/ministryofjustice/opg-modernising-lpa/internal/secrets"
Expand Down Expand Up @@ -167,7 +166,7 @@ func (f *Factory) ShareCodeSender(ctx context.Context) (ShareCodeSender, error)
return nil, err
}

f.shareCodeSender = sharecode.NewSender(sharecode.NewStore(f.dynamoClient), notifyClient, f.appPublicURL, random.String, event.NewClient(f.cfg, f.eventBusName), certificateprovider.NewStore(f.dynamoClient))
f.shareCodeSender = sharecode.NewSender(sharecode.NewStore(f.dynamoClient), notifyClient, f.appPublicURL, event.NewClient(f.cfg, f.eventBusName), certificateprovider.NewStore(f.dynamoClient), scheduled.NewStore(f.dynamoClient))
}

return f.shareCodeSender, nil
Expand Down
22 changes: 18 additions & 4 deletions cmd/event-received/sirius_event_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ func handleDonorSubmissionCompleted(ctx context.Context, client dynamodbClient,
Create(donor).
Create(scheduled.Event{
PK: dynamo.ScheduledDayKey(donor.CertificateProviderInvitedAt.AddDate(0, 3, 1)),
SK: dynamo.ScheduledKey(donor.CertificateProviderInvitedAt.AddDate(0, 3, 1), int(scheduled.ActionRemindCertificateProviderToComplete)),
SK: dynamo.ScheduledKey(donor.CertificateProviderInvitedAt.AddDate(0, 3, 1), uuidString()),
CreatedAt: now(),
At: donor.CertificateProviderInvitedAt.AddDate(0, 3, 1),
Action: scheduled.ActionRemindCertificateProviderToComplete,
Expand Down Expand Up @@ -276,12 +276,12 @@ func handleCertificateProviderSubmissionCompleted(ctx context.Context, event *ev
return err
}

donor, err := lpaStoreClient.Lpa(ctx, v.UID)
lpa, err := lpaStoreClient.Lpa(ctx, v.UID)
if err != nil {
return fmt.Errorf("failed to retrieve lpa: %w", err)
}

if donor.CertificateProvider.Channel.IsPaper() {
if lpa.CertificateProvider.Channel.IsPaper() {
shareCodeSender, err := factory.ShareCodeSender(ctx)
if err != nil {
return err
Expand All @@ -292,9 +292,23 @@ func handleCertificateProviderSubmissionCompleted(ctx context.Context, event *ev
return err
}

if err := shareCodeSender.SendAttorneys(ctx, appData, donor); err != nil {
dynamoClient := factory.DynamoClient()

donor, err := getDonorByLpaUID(ctx, dynamoClient, v.UID)
if err != nil {
return fmt.Errorf("failed to get donor: %w", err)
}

now := factory.Now()
donor.AttorneysInvitedAt = now()

if err := shareCodeSender.SendAttorneys(ctx, appData, lpa); err != nil {
return fmt.Errorf("failed to send share codes to attorneys: %w", err)
}

if err := putDonor(ctx, donor, now, dynamoClient); err != nil {
return fmt.Errorf("failed to put donor: %w", err)
}
}

return nil
Expand Down
129 changes: 128 additions & 1 deletion cmd/event-received/sirius_event_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,7 @@ func TestHandleDonorSubmissionCompleted(t *testing.T) {
},
scheduled.Event{
PK: dynamo.ScheduledDayKey(testNow.AddDate(0, 3, 1)),
SK: dynamo.ScheduledKey(testNow.AddDate(0, 3, 1), int(scheduled.ActionRemindCertificateProviderToComplete)),
SK: dynamo.ScheduledKey(testNow.AddDate(0, 3, 1), testUuidString),
CreatedAt: testNow,
At: testNow.AddDate(0, 3, 1),
Action: scheduled.ActionRemindCertificateProviderToComplete,
Expand Down Expand Up @@ -1034,11 +1034,31 @@ func TestHandleCertificateProviderSubmissionCompleted(t *testing.T) {
},
}

updatedDonor := &donordata.Provided{
PK: dynamo.LpaKey("an-lpa"),
UpdatedAt: testNow,
AttorneysInvitedAt: testNow,
}
updatedDonor.UpdateHash()

lpaStoreClient := newMockLpaStoreClient(t)
lpaStoreClient.EXPECT().
Lpa(ctx, "M-1111-2222-3333").
Return(lpa, nil)

dynamoClient := newMockDynamodbClient(t)
dynamoClient.EXPECT().
OneByUID(ctx, "M-1111-2222-3333", mock.Anything).
Return(nil).
SetData(&donordata.Provided{PK: dynamo.LpaKey("an-lpa"), SK: dynamo.LpaOwnerKey(dynamo.DonorKey("a-donor"))})
dynamoClient.EXPECT().
One(ctx, dynamo.LpaKey("an-lpa"), dynamo.DonorKey("a-donor"), mock.Anything).
Return(nil).
SetData(&donordata.Provided{PK: dynamo.LpaKey("an-lpa")})
dynamoClient.EXPECT().
Put(ctx, updatedDonor).
Return(nil)

shareCodeSender := newMockShareCodeSender(t)
shareCodeSender.EXPECT().
SendAttorneys(ctx, appData, lpa).
Expand All @@ -1054,6 +1074,12 @@ func TestHandleCertificateProviderSubmissionCompleted(t *testing.T) {
factory.EXPECT().
AppData().
Return(appData, nil)
factory.EXPECT().
DynamoClient().
Return(dynamoClient)
factory.EXPECT().
Now().
Return(testNowFn)

handler := &siriusEventHandler{}
err := handler.Handle(ctx, factory, certificateProviderSubmissionCompletedEvent)
Expand Down Expand Up @@ -1110,6 +1136,91 @@ func TestHandleCertificateProviderSubmissionCompletedWhenLpaStoreErrors(t *testi
assert.Equal(t, fmt.Errorf("failed to retrieve lpa: %w", expectedError), err)
}

func TestHandleCertificateProviderSubmissionCompletedWhenDonorGetErrors(t *testing.T) {
lpaStoreClient := newMockLpaStoreClient(t)
lpaStoreClient.EXPECT().
Lpa(ctx, "M-1111-2222-3333").
Return(&lpadata.Lpa{
CertificateProvider: lpadata.CertificateProvider{
Channel: lpadata.ChannelPaper,
},
}, nil)

dynamoClient := newMockDynamodbClient(t)
dynamoClient.EXPECT().
OneByUID(mock.Anything, mock.Anything, mock.Anything).
Return(expectedError)

shareCodeSender := newMockShareCodeSender(t)

factory := newMockFactory(t)
factory.EXPECT().
LpaStoreClient().
Return(lpaStoreClient, nil)
factory.EXPECT().
ShareCodeSender(ctx).
Return(shareCodeSender, nil)
factory.EXPECT().
AppData().
Return(appcontext.Data{}, nil)
factory.EXPECT().
DynamoClient().
Return(dynamoClient)

handler := &siriusEventHandler{}
err := handler.Handle(ctx, factory, certificateProviderSubmissionCompletedEvent)
assert.ErrorIs(t, err, expectedError)
}

func TestHandleCertificateProviderSubmissionCompletedWhenDonorPutErrors(t *testing.T) {
lpaStoreClient := newMockLpaStoreClient(t)
lpaStoreClient.EXPECT().
Lpa(ctx, "M-1111-2222-3333").
Return(&lpadata.Lpa{
CertificateProvider: lpadata.CertificateProvider{
Channel: lpadata.ChannelPaper,
},
}, nil)

dynamoClient := newMockDynamodbClient(t)
dynamoClient.EXPECT().
OneByUID(mock.Anything, mock.Anything, mock.Anything).
Return(nil).
SetData(&donordata.Provided{PK: dynamo.LpaKey("an-lpa"), SK: dynamo.LpaOwnerKey(dynamo.DonorKey("a-donor"))})
dynamoClient.EXPECT().
One(mock.Anything, mock.Anything, mock.Anything, mock.Anything).
Return(nil)
dynamoClient.EXPECT().
Put(mock.Anything, mock.Anything).
Return(expectedError)

shareCodeSender := newMockShareCodeSender(t)
shareCodeSender.EXPECT().
SendAttorneys(ctx, mock.Anything, mock.Anything).
Return(nil)

factory := newMockFactory(t)
factory.EXPECT().
LpaStoreClient().
Return(lpaStoreClient, nil)
factory.EXPECT().
ShareCodeSender(ctx).
Return(shareCodeSender, nil)
factory.EXPECT().
AppData().
Return(appcontext.Data{}, nil)
factory.EXPECT().
DynamoClient().
Return(dynamoClient)
factory.EXPECT().
Now().
Return(testNowFn)

handler := &siriusEventHandler{}
err := handler.Handle(ctx, factory, certificateProviderSubmissionCompletedEvent)
assert.ErrorIs(t, err, expectedError)
}

func TestHandleCertificateProviderSubmissionCompletedWhenShareCodeSenderErrors(t *testing.T) {
lpaStoreClient := newMockLpaStoreClient(t)
lpaStoreClient.EXPECT().
Expand All @@ -1120,6 +1231,16 @@ func TestHandleCertificateProviderSubmissionCompletedWhenShareCodeSenderErrors(t
},
}, nil)

dynamoClient := newMockDynamodbClient(t)
dynamoClient.EXPECT().
OneByUID(ctx, "M-1111-2222-3333", mock.Anything).
Return(nil).
SetData(&donordata.Provided{PK: dynamo.LpaKey("an-lpa"), SK: dynamo.LpaOwnerKey(dynamo.DonorKey("a-donor"))})
dynamoClient.EXPECT().
One(ctx, dynamo.LpaKey("an-lpa"), dynamo.DonorKey("a-donor"), mock.Anything).
Return(nil).
SetData(&donordata.Provided{PK: dynamo.LpaKey("an-lpa")})

shareCodeSender := newMockShareCodeSender(t)
shareCodeSender.EXPECT().
SendAttorneys(ctx, mock.Anything, mock.Anything).
Expand All @@ -1135,6 +1256,12 @@ func TestHandleCertificateProviderSubmissionCompletedWhenShareCodeSenderErrors(t
factory.EXPECT().
AppData().
Return(appcontext.Data{}, nil)
factory.EXPECT().
DynamoClient().
Return(dynamoClient)
factory.EXPECT().
Now().
Return(testNowFn)

handler := &siriusEventHandler{}
err := handler.Handle(ctx, factory, certificateProviderSubmissionCompletedEvent)
Expand Down
3 changes: 3 additions & 0 deletions cmd/schedule-runner/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/cloudwatch"
"github.com/ministryofjustice/opg-modernising-lpa/internal/attorney"
"github.com/ministryofjustice/opg-modernising-lpa/internal/certificateprovider"
"github.com/ministryofjustice/opg-modernising-lpa/internal/donor"
"github.com/ministryofjustice/opg-modernising-lpa/internal/dynamo"
Expand Down Expand Up @@ -94,6 +95,7 @@ func handleRunSchedule(ctx context.Context) error {
scheduledStore := scheduled.NewStore(dynamoClient)
donorStore := donor.NewStore(dynamoClient, eventClient, logger, searchClient)
certificateProviderStore := certificateprovider.NewStore(dynamoClient)
attorneyStore := attorney.NewStore(dynamoClient)
lpaStoreResolvingService := lpastore.NewResolvingService(donorStore, lpaStoreClient)

if Tag == "" {
Expand All @@ -108,6 +110,7 @@ func handleRunSchedule(ctx context.Context) error {
scheduledStore,
donorStore,
certificateProviderStore,
attorneyStore,
lpaStoreResolvingService,
notifyClient,
eventClient,
Expand Down
3 changes: 2 additions & 1 deletion cmd/scheduled-task-adder/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/ministryofjustice/opg-modernising-lpa/internal/donor/donordata"
"github.com/ministryofjustice/opg-modernising-lpa/internal/dynamo"
"github.com/ministryofjustice/opg-modernising-lpa/internal/identity"
"github.com/ministryofjustice/opg-modernising-lpa/internal/random"
"github.com/ministryofjustice/opg-modernising-lpa/internal/scheduled"
)

Expand Down Expand Up @@ -93,7 +94,7 @@ func handleAddScheduledTasks(ctx context.Context, taskCountEvent TaskCountEvent)
TargetLpaOwnerKey: donor.SK,
LpaUID: lpaUID,
PK: dynamo.ScheduledDayKey(now),
SK: dynamo.ScheduledKey(now, int(scheduled.ActionExpireDonorIdentity)),
SK: dynamo.ScheduledKey(now, random.UuidString()),
}

items = append(items, donor, event)
Expand Down
2 changes: 1 addition & 1 deletion internal/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func App(
scheduledStore := scheduled.NewStore(lpaDynamoClient)
progressTracker := task.ProgressTracker{Localizer: localizer}

shareCodeSender := sharecode.NewSender(shareCodeStore, notifyClient, appPublicURL, random.String, eventClient, certificateProviderStore)
shareCodeSender := sharecode.NewSender(shareCodeStore, notifyClient, appPublicURL, eventClient, certificateProviderStore, scheduledStore)
witnessCodeSender := donor.NewWitnessCodeSender(donorStore, certificateProviderStore, notifyClient, localizer)

lpaStoreResolvingService := lpastore.NewResolvingService(donorStore, lpaStoreClient)
Expand Down
49 changes: 49 additions & 0 deletions internal/attorney/mock_DynamoClient_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions internal/attorney/mock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"errors"

"github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
"github.com/ministryofjustice/opg-modernising-lpa/internal/dynamo"
"github.com/stretchr/testify/mock"
Expand All @@ -15,6 +16,13 @@ var (
expectedError = errors.New("err")
)

func (c *mockDynamoClient_AllByPartialSK_Call) SetData(data any) {
c.Run(func(_ context.Context, _ dynamo.PK, _ dynamo.SK, v any) {
b, _ := attributevalue.Marshal(data)
attributevalue.Unmarshal(b, v)
})
}

func (m *mockDynamoClient) ExpectOne(ctx, pk, sk, data interface{}, err error) {
m.
On("One", ctx, pk, sk, mock.Anything).
Expand Down
Loading

0 comments on commit 32d8084

Please sign in to comment.