Skip to content

Commit

Permalink
Merge pull request #52 from trade-tariff/FPO-294-Storing-email-data
Browse files Browse the repository at this point in the history
Fpo 294 storing email data
  • Loading branch information
mkayad authored Jul 2, 2024
2 parents 56049af + d44d5da commit 3c9b0cb
Show file tree
Hide file tree
Showing 20 changed files with 247 additions and 29 deletions.
16 changes: 8 additions & 8 deletions .bin/seed.sh
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ create_customer_api_key() {
create_user() {
id=$1
organisationId=$2
status=$3
emailAddress=$3

# create the dynnamodb item
aws dynamodb put-item \
Expand All @@ -104,7 +104,7 @@ create_user() {
--table-name "$USERS_TABLE_NAME" --item "{
\"UserId\": {\"S\": \"$id\"},
\"OrganisationId\": {\"S\": \"$organisationId\"},
\"Status\": {\"S\": \"$status\"},
\"EmailAddress\": {\"S\": \"$emailAddress\"},
\"CreatedAt\": {\"S\": \"$createdAt\"},
\"UpdatedAt\": {\"S\": \"$createdAt\"}
}"
Expand All @@ -119,9 +119,9 @@ create_customer_api_key "HUBPC7NFHXS6H3LKZCEW" "$usagePlanId" "VitXWo4eiEphvzqR:
create_customer_api_key "HUBP4NMDNBUKZ168SQTL" "$usagePlanId" "CBsaehhd3Q/qDusw:yGfSGJgPtL8xMMpN9SFc+s+ZZXugnA1DOeu8A7HofaOR7qZMYN5pTZtjFs3HBM29ER4KA2tj9OnoKjUC" false

create_table_without_range_key "$USERS_TABLE_NAME" "UserId"
create_user "1234" "local-development" "Unregistered"
create_user "2345" "local-development" "Unregistered"
create_user "3456" "local-development" "Unregistered"
create_user "4567" "local-development" "Unregistered"
create_user "4442615091686901" "A55244BE-486B-489F-B3DE-2B87EE471B82" "Authorised"
create_user "5580468525832191" "08961382-2C50-42B7-B8BE-7D143FCAA101" "Authorised"
create_user "1234" "local-development" "abcd@test.com"
create_user "2345" "local-development" ""
create_user "3456" "local-development" "test@test.com"
create_user "4567" "local-development" ""
create_user "4442615091686901" "A55244BE-486B-489F-B3DE-2B87EE471B82" "abc@test.com"
create_user "5580468525832191" "08961382-2C50-42B7-B8BE-7D143FCAA101" "xyz@test.com"
2 changes: 1 addition & 1 deletion .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export ORGANISATIONS_TABLE_NAME=Organisations
export PORT=5001
export REST_API_ID=amaanxvxk5
export REST_STAGE_NAME=development
export USAGE_PLAN_ID=vjk8cctv0e
export USAGE_PLAN_ID=xi6vv266pr
export USAGE_PLAN_LIST_PAGINATION_LIMIT=100
export USAGE_PLAN_PER_FPO_BURST_LIMIT=100
export USAGE_PLAN_PER_FPO_RATE_LIMIT=100
Expand Down
60 changes: 55 additions & 5 deletions spec/controllers/userControllerSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ describe('UserController', () => {
let organisationRepository: jasmine.SpyObj<OrganisationRepository>
let controller: UserController
let getUserResult: Promise<User | null>
let updateUserResult: Promise<User | null>
let getOrganisationResult: Promise<Organisation | null>
let createOrganisationResult: Promise<Organisation | null>
let updateOrganisationResult: Promise<Organisation | null>
Expand All @@ -30,6 +31,7 @@ describe('UserController', () => {
it('returns the user', async () => {
user = new User()
user.OrganisationId = 'organisationId'
user.EmailAddress = 'abc@test.com'
organisation = new Organisation()
getUserResult = Promise.resolve(user)
getOrganisationResult = Promise.resolve(null)
Expand Down Expand Up @@ -119,13 +121,61 @@ describe('UserController', () => {
await controller.create(req, res)

expect(userRepository.createUser).toHaveBeenCalledWith('id', 'organisationId')
expect(organisationRepository.getOrganisation).toHaveBeenCalledWith('organisationId')
expect(organisationRepository.createOrganisation).toHaveBeenCalledWith('organisationId')
expect(res.statusCode).toBe(201)
expect(res.data).toEqual({ ...user.toJson(), Status: organisation.Status })
})
})

describe('updateUser', () => {
it('returns updated user', async () => {
user = new User()
user.UserId = 'userId'
user.OrganisationId = 'organisationId'
getUserResult = Promise.resolve(user)
updateUserResult = Promise.resolve(user)
getOrganisationResult = Promise.resolve(null)
createOrganisationResult = Promise.resolve(organisation)
updateOrganisationResult = Promise.resolve(organisation)
userRepository = jasmine.createSpyObj('UserRepository', {
createUser: Promise.resolve(user),
GetUser: getUserResult,
updateUser: updateUserResult
})

organisationRepository = jasmine.createSpyObj('OrganisationRepository', {
getOrganisation: getOrganisationResult,
createOrganisation: createOrganisationResult,
updateOrganisation: updateOrganisationResult
})
userRepository.updateUser.bind(userRepository)
userRepository.createUser.bind(userRepository)
organisationRepository.getOrganisation.bind(organisationRepository)
organisationRepository.createOrganisation.bind(organisationRepository)
organisationRepository.updateOrganisation.bind(organisationRepository)
controller = new UserController(userRepository, organisationRepository)
req = {
params: { userId: 'userId' },
body: { emailAddress: 'emailAddress' }
} as any
const res = {
status: function (code: number) {
this.statusCode = code
return this
},
json: function (data: any) {
this.data = data
return this
}
} as any

// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
await controller.update(req, res)
expect(userRepository.updateUser).toHaveBeenCalledWith('userId', 'emailAddress')
expect(res.statusCode).toBe(200)
expect(res.data).toEqual({ userId: 'userId' })
})
})

describe('updateOrganisation', () => {
it('returns updated organisation', async () => {
user = new User()
Expand All @@ -150,7 +200,7 @@ describe('UserController', () => {
controller = new UserController(userRepository, organisationRepository)
req = {
params: { organisationId: 'organisationId' },
body: { applicationReference: 'reference', status: 'status' }
body: { applicationReference: 'reference', status: 'status', organisationName: 'organisationName', eoriNumber: 'eoriNumber', ukAcsReference: 'ukAcsReference' }
} as any
const res = {
status: function (code: number) {
Expand All @@ -165,8 +215,8 @@ describe('UserController', () => {

// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
await controller.updateOrganisation(req, res)
expect(organisationRepository.updateOrganisation).toHaveBeenCalledWith('organisationId', 'reference', 'status')
expect(res.statusCode).toBe(201)
expect(organisationRepository.updateOrganisation).toHaveBeenCalledWith('organisationId', 'reference', 'status', 'organisationName', 'eoriNumber', 'ukAcsReference')
expect(res.statusCode).toBe(200)
expect(res.data).toEqual({ organisationId: 'organisationId' })
})
})
Expand Down
12 changes: 12 additions & 0 deletions spec/models/organisationSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ describe('Organisation', () => {
it('returns a Organisation instance', () => {
const item = {
OrganisationId: 'the-id',
OrganisationName: 'the-organisation-name',
EoriNumber: 'the-eori-number',
UkAcsReference: 'the-uk-acs-reference',
CreatedAt: new Date().toISOString(),
UpdatedAt: new Date().toISOString(),
Saved: false
Expand All @@ -76,13 +79,19 @@ describe('Organisation', () => {
it('returns a plain object', () => {
const organisation = new Organisation()
organisation.OrganisationId = 'the-id'
organisation.OrganisationName = 'the-organisation-name'
organisation.EoriNumber = 'the-eori-number'
organisation.UkAcsReference = 'the-uk-acs-reference'

const actual = organisation.toItem()
expect(actual).toEqual({
OrganisationId: 'the-id',
Description: organisation.Description,
Status: organisation.Status,
ApplicationReference: organisation.ApplicationReference,
OrganisationName: organisation.OrganisationName,
EoriNumber: organisation.EoriNumber,
UkAcsReference: organisation.UkAcsReference,
CreatedAt: organisation.CreatedAt,
UpdatedAt: organisation.UpdatedAt
})
Expand All @@ -101,6 +110,9 @@ describe('Organisation', () => {
Description: organisation.Description,
Status: organisation.Status,
ApplicationReference: organisation.ApplicationReference,
OrganisationName: organisation.OrganisationName,
EoriNumber: organisation.EoriNumber,
UkAcsReference: organisation.UkAcsReference,
CreatedAt: organisation.CreatedAt,
UpdatedAt: organisation.UpdatedAt
})
Expand Down
4 changes: 4 additions & 0 deletions spec/models/userSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ describe('User', () => {
const item = {
UserId: 'the-id',
OrganisationId: 'yodel',
EmailAddress: '',
CreatedAt: new Date().toISOString(),
UpdatedAt: new Date().toISOString(),
Saved: false
Expand All @@ -79,11 +80,13 @@ describe('User', () => {
const user = new User()
user.UserId = 'the-id'
user.OrganisationId = 'the-fpo-id'
user.EmailAddress = 'abc@hmrc.gov.uk'

const actual = user.toItem()
expect(actual).toEqual({
UserId: 'the-id',
OrganisationId: 'the-fpo-id',
EmailAddress: 'abc@hmrc.gov.uk',
CreatedAt: user.CreatedAt,
UpdatedAt: user.UpdatedAt
})
Expand All @@ -100,6 +103,7 @@ describe('User', () => {
expect(actual).toEqual({
UserId: 'the-id',
OrganisationId: '',
EmailAddress: '',
CreatedAt: user.CreatedAt,
UpdatedAt: user.UpdatedAt
})
Expand Down
4 changes: 4 additions & 0 deletions spec/operations/getOrganisationSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ describe('GetOrganisation', () => {
OrganisationId: { S: 'organisationId' },
Description: { S: 'description' },
Status: { S: 'Unregistered' },
ApplicationReference: { S: 'ApplicationReference' },
OrganisationName: { S: 'OrganisationName' },
EoriNumber: { S: 'EoriNumber' },
UkAcsReference: { S: 'UkAcsReference' },
CreatedAt: { S: new Date().toISOString() },
UpdatedAt: { S: new Date().toISOString() }
},
Expand Down
1 change: 1 addition & 0 deletions spec/operations/getUserSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ describe('GetUser', () => {
UserId: { S: 'userId' },
Status: { S: 'Unregistered' },
OrganisationId: { S: 'organisationId' },
EmailAddress: { S: 'abc@test.com' },
CreatedAt: { S: new Date().toISOString() },
UpdatedAt: { S: new Date().toISOString() }
},
Expand Down
2 changes: 1 addition & 1 deletion spec/operations/updateOrganisationSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe('CreateOrganisation', () => {
})

it('updates existing organisation', async () => {
await updateOrganisation.call('organisationId', 'reference', 'status')
await updateOrganisation.call('organisationId', 'reference', 'status', 'organisationName', 'eoriNumber', 'uk')
expect(dynamodbClient.send).toHaveBeenCalledTimes(1)
})
})
25 changes: 25 additions & 0 deletions spec/operations/updateUserSpec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import 'jasmine'
import { type DynamoDBClient } from '@aws-sdk/client-dynamodb'
import { UpdateUser } from '../../src/operations/updateUser'

describe('CreateUser', () => {
let dynamodbClient: jasmine.SpyObj<DynamoDBClient>
let updateUser: UpdateUser

beforeEach(() => {
const dynamodbResult = {
$metadata: {
httpStatusCode: 201
}
}

dynamodbClient = jasmine.createSpyObj('DynamoDBClient', { send: Promise.resolve(dynamodbResult) })

updateUser = new UpdateUser(dynamodbClient)
})

it('updates existing User', async () => {
await updateUser.call('UserId', 'emailAddress')
expect(dynamodbClient.send).toHaveBeenCalledTimes(1)
})
})
6 changes: 3 additions & 3 deletions spec/repositories/organisationRepositorySpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ describe('OrganisationRepository', () => {
it('calls updateOperation', async () => {
const organisation: Organisation = new Organisation()

await mockUpdateOperation.call(organisation.OrganisationId, organisation.ApplicationReference, organisation.Status)
await repository.updateOrganisation(organisation.OrganisationId, organisation.ApplicationReference, organisation.Status)
expect(mockUpdateOperation.call).toHaveBeenCalledWith(organisation.OrganisationId, organisation.ApplicationReference, organisation.Status)
await mockUpdateOperation.call(organisation.OrganisationId, organisation.ApplicationReference, organisation.Status, organisation.OrganisationName, organisation.EoriNumber, organisation.UkAcsReference)
await repository.updateOrganisation(organisation.OrganisationId, organisation.ApplicationReference, organisation.Status, organisation.OrganisationName, organisation.EoriNumber, organisation.UkAcsReference)
expect(mockUpdateOperation.call).toHaveBeenCalledWith(organisation.OrganisationId, organisation.ApplicationReference, organisation.Status, organisation.OrganisationName, organisation.EoriNumber, organisation.UkAcsReference)
})
})
})
26 changes: 25 additions & 1 deletion spec/repositories/userRepositorySpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@ import { UserRepository } from '../../src/repositories/userRepository'

import { type CreateUser } from '../../src/operations/createUser'
import { type GetUser } from '../../src/operations/getUser'
import { type UpdateUser } from '../../src/operations/updateUser'

import { User } from '../../src/models/user'

describe('UserRepository', () => {
const dynamodbClient: DynamoDBClient = new DynamoDBClient({ region: 'us-west-2' })
const mockCreateOperation: jasmine.SpyObj<CreateUser> = jasmine.createSpyObj('CreateUser', ['call'])
const mockGetOperation: jasmine.SpyObj<GetUser> = jasmine.createSpyObj('GetUser', ['call'])
const mockUpdateOperation: jasmine.SpyObj<UpdateUser> = jasmine.createSpyObj('UpdateUser', ['call'])
const repository: UserRepository = new UserRepository(
dynamodbClient,
mockCreateOperation,
mockGetOperation
mockGetOperation,
mockUpdateOperation
)

describe('createUser', () => {
Expand Down Expand Up @@ -44,6 +47,7 @@ describe('UserRepository', () => {

result.UserId = 'id'
result.OrganisationId = 'groupId'
result.EmailAddress = 'abc@hmrc.gov.uk'

mockGetOperation.call.and.returnValue(Promise.resolve(result))
})
Expand All @@ -54,7 +58,27 @@ describe('UserRepository', () => {
expect(actual).toEqual(jasmine.any(User))
expect(actual?.UserId).toEqual('id')
expect(actual?.OrganisationId).toEqual('groupId')
expect(actual?.EmailAddress).toEqual('abc@hmrc.gov.uk')
expect(mockGetOperation.call).toHaveBeenCalledWith('id')
})
})

describe('updateUser', () => {
beforeEach(() => {
const result: User = new User()

result.UserId = 'id'
result.EmailAddress = 'abc@hmrc.gov.uk'

mockUpdateOperation.call.and.returnValue(Promise.resolve())
})

it('calls updateUser', async () => {
const user: User = new User()
user.EmailAddress = 'abc@hmrc.gov.uk'
await mockUpdateOperation.call(user.UserId, user.EmailAddress)
await repository.updateUser(user.UserId, user.EmailAddress)
expect(mockUpdateOperation.call).toHaveBeenCalledWith(user.UserId, user.EmailAddress)
})
})
})
25 changes: 23 additions & 2 deletions src/controllers/usersController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,33 @@ export class UserController {
res.status(201).json({ ...user.toJson(), Status: status })
}

async update (req: Request, res: Response): Promise<void> {
const userId = req.params.userId
const emailAddress = req.body.emailAddress as string

await this.userRepository.updateUser(userId, emailAddress)
res.status(200).json({ userId })
}

async updateOrganisation (req: Request, res: Response): Promise<void> {
const organisationId = req.params.organisationId
const reference = req.body.applicationReference as string
const status = req.body.status as string
const organisationName = req.body.organisationName as string
const eoriNumber = req.body.eoriNumber as string
const ukAcsReference = req.body.ukAcsReference as string

await this.organisationRepository.updateOrganisation(organisationId, reference, status, organisationName, eoriNumber, ukAcsReference)
res.status(200).json({ organisationId })
}

await this.organisationRepository.updateOrganisation(organisationId, reference, status)
res.status(201).json({ organisationId })
async getOrganisation (req: Request, res: Response): Promise<void> {
const organisationId = req.params.organisationId
const organisation = await this.organisationRepository.getOrganisation(organisationId)
if (organisation === null) {
res.status(404).json({ message: 'organisation not found' })
} else {
res.status(200).json({ ...organisation.toJson() })
}
}
}
Loading

0 comments on commit 3c9b0cb

Please sign in to comment.