Skip to content
Draft
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
6 changes: 6 additions & 0 deletions app/data-sources/rural-payments/RuralPaymentsCustomer.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ export class RuralPaymentsCustomer extends RuralPayments {
return response._data
}

async customerEmailExistsByEmailAddress(emailAddress) {
const response = await this.get(`person/${emailAddress}/validateEmail`)

return response._data
}

async getPersonBusinessesByPersonId(personId) {
const personBusinessSummaries = await this.get(
// Currently requires and empty search parameter or it returns 500 error
Expand Down
10 changes: 10 additions & 0 deletions app/graphql/resolvers/customer/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,15 @@ export const Query = {
const personId = await retrievePersonIdByCRN(crn, dataSources)

return { crn, personId }
},

async customerEmail(__, { emailAddress }, { dataSources }) {
const results =
await dataSources.ruralPaymentsCustomer.customerEmailExistsByEmailAddress(emailAddress)

return {
emailAddress,
addressInUse: results.emailDuplicated
}
}
}
17 changes: 17 additions & 0 deletions app/graphql/types/customer/customer.gql
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,20 @@ type CustomerBusiness {
"""
permissionGroups: [ActivePermissionGroup] @on @excludeFromList
}

"""
Customer email details.

Data source: Rural Payments Portal
"""
type CustomerEmail {
"""
The email address.
"""
emailAddress: String!

"""
Indicates if the address is already associated with a customer
"""
addressInUse: Boolean!
}
10 changes: 10 additions & 0 deletions app/graphql/types/customer/email-exists.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
extend type Query {
"""
Checks whether an email address already exists in the system.

Data source: Rural Payments Portal
"""
emailExists(emailAddress: String!): Boolean
@on
@auth(requires: [CONSOLIDATED_VIEW, SINGLE_FRONT_DOOR])
}
7 changes: 7 additions & 0 deletions app/graphql/types/customer/query.gql
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,11 @@ extend type Query {
customer(crn: ID!): Customer
@on
@auth(requires: [CONSOLIDATED_VIEW, SINGLE_FRONT_DOOR, SFI_REFORM])

"""
Checks whether an email address already exists in the system.

Data source: Rural Payments Portal
"""
customerEmail(emailAddress: String!): CustomerEmail @on @auth(requires: [SINGLE_FRONT_DOOR])
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fcp-dal-api",
"version": "2.2.1",
"version": "2.3.0",
"description": "Customer Registry GraphQL Service",
"homepage": "https://github.com/DEFRA/fcp-data-access-layer-api",
"main": "app/index.js",
Expand Down
1 change: 1 addition & 0 deletions test/graphql/full-schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ type Query {
business(sbi: ID!): Business
customer(crn: ID!): Customer
permissionGroups: [PermissionGroup]
customerEmail(emailAddress: String!): Boolean
}

type Mutation {
Expand Down
1 change: 1 addition & 0 deletions test/graphql/partial-schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ type Query {
business(sbi: ID!): Business
customer(crn: ID!): Customer
permissionGroups: [PermissionGroup]
customerEmail(emailAddress: String!): Boolean
}

type Phone {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,4 +240,22 @@ describe('Rural Payments Customer', () => {
})
expect(httpGet).toHaveBeenCalledTimes(1)
})

test('should return emailDuplicated true when email already exists', async () => {
httpGet.mockImplementationOnce(async () => ({ _data: { emailDuplicated: true } }))

const result = await ruralPaymentsCustomer.customerEmailExistsByEmailAddress('test@example.com')

expect(result).toEqual({ emailDuplicated: true })
expect(httpGet).toHaveBeenCalledWith('person/test@example.com/validateEmail')
})

test('should return emailDuplicated false when email does not exist', async () => {
httpGet.mockImplementationOnce(async () => ({ _data: { emailDuplicated: false } }))

const result = await ruralPaymentsCustomer.customerEmailExistsByEmailAddress('new@example.com')

expect(result).toEqual({ emailDuplicated: false })
expect(httpGet).toHaveBeenCalledWith('person/new@example.com/validateEmail')
})
})
16 changes: 0 additions & 16 deletions test/unit/resolvers/customer/customer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { jest } from '@jest/globals'

import { Permissions } from '../../../../app/data-sources/static/permissions.js'
import { Customer, CustomerBusiness } from '../../../../app/graphql/resolvers/customer/customer.js'
import { Query } from '../../../../app/graphql/resolvers/customer/query.js'
import { organisationPeopleByOrgId } from '../../../fixtures/organisation.js'
import { buildPermissionsFromIdsAndLevels } from '../../../test-helpers/permissions.js'

Expand Down Expand Up @@ -95,21 +94,6 @@ describe('Customer', () => {
jest.clearAllMocks()
})

test('Query.customer.personId', async () => {
dataSources.mongoCustomer.findPersonIdByCRN.mockResolvedValue('internal person id')
const response = await Query.customer(
undefined,
{ crn: personFixture.customerReferenceNumber },
{ dataSources }
)

expect(dataSources.mongoCustomer.findPersonIdByCRN).toHaveBeenCalledWith(
personFixture.customerReferenceNumber
)

expect(response).toEqual({ crn: 'crn-11111111', personId: 'internal person id' })
})

test('Customer.info', async () => {
dataSources.ruralPaymentsCustomer.getPersonByPersonId.mockResolvedValue(personFixture)
const response = await Customer.info({ personId: personFixture.id }, undefined, {
Expand Down
60 changes: 60 additions & 0 deletions test/unit/resolvers/customer/query.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { jest } from '@jest/globals'

import { Query } from '../../../../app/graphql/resolvers/customer/query.js'

const dataSources = {
ruralPaymentsCustomer: {
customerEmailExistsByEmailAddress: jest.fn()
},
mongoCustomer: {
findPersonIdByCRN: jest.fn()
}
}

describe('Query', () => {
beforeEach(() => {
jest.clearAllMocks()
})

describe('CustomerEmail', () => {
test('returns mail address and sets address in use to true when email is in use', async () => {
dataSources.ruralPaymentsCustomer.customerEmailExistsByEmailAddress.mockResolvedValue({
emailDuplicated: true
})

const response = await Query.customerEmail(
undefined,
{ emailAddress: 'test@example.com' },
{
dataSources
}
)

expect(
dataSources.ruralPaymentsCustomer.customerEmailExistsByEmailAddress
).toHaveBeenCalledWith('test@example.com')
expect(response).toMatchObject({
emailAddress: 'test@example.com',
addressInUse: true
})
})

test('returns mail address and sets address in use to false when email is not already in use', async () => {
dataSources.ruralPaymentsCustomer.customerEmailExistsByEmailAddress.mockResolvedValue({
emailDuplicated: false
})

const response = await Query.customerEmail(
undefined,
{ emailAddress: 'test@example.com' },
{
dataSources
}
)
expect(response).toMatchObject({
emailAddress: 'test@example.com',
addressInUse: false
})
})
})
})
Loading