From 0f4ecaeff6e9ea4d2e4ade975e77e289dee4f94e Mon Sep 17 00:00:00 2001 From: gabrielHosino Date: Tue, 8 Feb 2022 10:07:26 -0300 Subject: [PATCH 1/5] Update masterdata schema --- masterdata/affiliates/schema.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/masterdata/affiliates/schema.json b/masterdata/affiliates/schema.json index de826bb..3143961 100644 --- a/masterdata/affiliates/schema.json +++ b/masterdata/affiliates/schema.json @@ -15,6 +15,9 @@ "phone": { "type": "string" }, + "refId": { + "type": "string" + }, "address": { "type": "object", "properties": { @@ -56,7 +59,7 @@ "isApproved": { "type": "boolean" }, - "social": { + "marketing": { "type": "object", "properties": { "instagram": { @@ -67,6 +70,9 @@ }, "facebook": { "type": "string" + }, + "gtmId": { + "type": "string" } } } From 1915b372d3b106965d62f189c5043b716111e033 Mon Sep 17 00:00:00 2001 From: gabrielHosino Date: Tue, 8 Feb 2022 10:10:27 -0300 Subject: [PATCH 2/5] Add addAffiliate mutation to schema --- graphql/schema.graphql | 1 + graphql/types/affiliates.graphql | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/graphql/schema.graphql b/graphql/schema.graphql index d0698a6..b54eed7 100644 --- a/graphql/schema.graphql +++ b/graphql/schema.graphql @@ -10,5 +10,6 @@ type Query { } type Mutation { + addAffiliate(newAffiliate: NewAffiliateInput!): Affiliate! setAffiliateOnOrderForm(affiliateId: String, orderFormId: String): OrderForm } diff --git a/graphql/types/affiliates.graphql b/graphql/types/affiliates.graphql index 2e6a743..e9b9f02 100644 --- a/graphql/types/affiliates.graphql +++ b/graphql/types/affiliates.graphql @@ -8,6 +8,37 @@ input AffliatesSortingInput { order: SortingOrder! } +input AddresInput { + city: String + country: String + neighborhood: String + number: String + postalCode: String + reference: String + street: String + state: String +} + +input MarketingInput { + instagram: String + facebook: String + whatsapp: String + gtmId: String +} + +input NewAffiliateInput { + slug: String! + name: String! + email: String! + isApproved: Boolean! + storeName: String + address: AddresInput + document: String + documentType: String + phone: String + marketing: MarketingInput +} + type Affiliate { id: ID name: String From 0a1aa0ca819eeb69f9c97e7b6adec5295d73fb93 Mon Sep 17 00:00:00 2001 From: gabrielHosino Date: Tue, 8 Feb 2022 10:11:19 -0300 Subject: [PATCH 3/5] Add addAffiliate mutation to service --- .../unit/resolvers/addAffiliate.spec.ts | 99 +++++++++++++++++++ node/resolvers/addAffiliate.ts | 42 ++++++++ 2 files changed, 141 insertions(+) create mode 100644 node/__tests__/unit/resolvers/addAffiliate.spec.ts create mode 100644 node/resolvers/addAffiliate.ts diff --git a/node/__tests__/unit/resolvers/addAffiliate.spec.ts b/node/__tests__/unit/resolvers/addAffiliate.spec.ts new file mode 100644 index 0000000..74281a2 --- /dev/null +++ b/node/__tests__/unit/resolvers/addAffiliate.spec.ts @@ -0,0 +1,99 @@ +import { addAffiliate } from '../../../resolvers/addAffiliate' + +describe('addAffiliate mutation', () => { + it('Should return error if slug is invalid', () => { + const newAffiliateParams = { + newAffiliate: { + slug: 'Invalid Slug', + }, + } + + const mockCtx = { + clients: { + affiliates: { + get: jest.fn(), + search: jest.fn(), + }, + }, + } as unknown as Context + + return expect( + addAffiliate(null, newAffiliateParams, mockCtx) + ).rejects.toThrow('Slug is not valid, must be alphanumeric') + }) + + it('Should return error if slug is already in use', () => { + const newAffiliateParams = { + newAffiliate: { + slug: 'validSlug', + }, + } + + const mockCtx = { + clients: { + affiliates: { + get: jest.fn().mockResolvedValueOnce({ id: 'validSlug' }), + search: jest.fn(), + }, + }, + } as unknown as Context + + return expect( + addAffiliate(null, newAffiliateParams, mockCtx) + ).rejects.toThrow('Affiliate already exists(slug is already in use)') + }) + + it('Should return error if email is already in use', () => { + const newAffiliateParams = { + newAffiliate: { + slug: 'validSlug', + email: 'alreadyUsedEmail@email.com', + }, + } + + const mockCtx = { + clients: { + affiliates: { + get: jest.fn().mockResolvedValueOnce(null), + search: jest.fn().mockResolvedValueOnce([{ id: 'validSlug' }]), + }, + }, + } as unknown as Context + + return expect( + addAffiliate(null, newAffiliateParams, mockCtx) + ).rejects.toThrow('Affiliate already exists(email is already in use)') + }) + + it('Should add a new affiliate if no errors were found', () => { + const newAffiliateParams = { + newAffiliate: { + slug: 'validSlug', + email: 'alreadyUsedEmail@email.com', + name: 'affiliate name', + isApproved: true, + }, + } + + const mdFields = { + id: 'validSlug', + email: 'alreadyUsedEmail@email.com', + name: 'affiliate name', + isApproved: true, + } + + const mockCtx = { + clients: { + affiliates: { + get: jest.fn().mockResolvedValueOnce(null), + search: jest.fn().mockResolvedValueOnce([]), + save: jest.fn(), + }, + }, + } as unknown as Context + + return addAffiliate(null, newAffiliateParams, mockCtx).then(() => { + expect(mockCtx.clients.affiliates.save).toHaveBeenCalledWith(mdFields) + }) + }) +}) diff --git a/node/resolvers/addAffiliate.ts b/node/resolvers/addAffiliate.ts new file mode 100644 index 0000000..e5f8cc2 --- /dev/null +++ b/node/resolvers/addAffiliate.ts @@ -0,0 +1,42 @@ +import type { Affiliates, MutationAddAffiliateArgs } from 'vtex.affiliates' + +import { isSlugValid } from '../utils/shared' + +export const addAffiliate = async ( + _: unknown, + { newAffiliate }: MutationAddAffiliateArgs, + { clients: { affiliates } }: Context +) => { + const { slug, email } = newAffiliate + + if (!isSlugValid(slug)) { + throw new Error('Slug is not valid, must be alphanumeric') + } + + const affiliateInDbById = await affiliates.get(slug, ['_all']) + + if (affiliateInDbById) { + throw new Error('Affiliate already exists(slug is already in use)') + } + + const affiliateInDbByEmail = await affiliates.search( + { page: 1, pageSize: 10 }, + ['_all'], + undefined, + `email=${email}` + ) + + if (affiliateInDbByEmail.length > 0) { + throw new Error('Affiliate already exists(email is already in use)') + } + + const mdDocument = { + id: slug, + ...newAffiliate, + } as Affiliates + + delete mdDocument.slug + await affiliates.save(mdDocument) + + return affiliates.get(slug, ['_all']) +} From 8f9e0ac4a74c4d03d0be1b58c408ae9204ad12e0 Mon Sep 17 00:00:00 2001 From: gabrielHosino Date: Tue, 8 Feb 2022 10:11:52 -0300 Subject: [PATCH 4/5] Add addAffiliate mutation --- node/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/node/index.ts b/node/index.ts index 0cf6474..9d5eeda 100644 --- a/node/index.ts +++ b/node/index.ts @@ -28,6 +28,7 @@ import { getAffiliateLead } from './middlewares/getAffiliateLead' import { verifyUserAffiliation } from './middlewares/verifyUserAffiliation' import { authenticateRequest } from './middlewares/authenticateRequest' import { getAffiliates } from './resolvers/getAffiliates' +import { addAffiliate } from './resolvers/addAffiliate' const TIMEOUT_MS = 1000 @@ -105,6 +106,7 @@ export default new Service({ getAffiliates, }, Mutation: { + addAffiliate, setAffiliateOnOrderForm, }, }, From 0d642cca1141c1b389133a7545e6ddccdadce45d Mon Sep 17 00:00:00 2001 From: gabrielHosino Date: Thu, 10 Feb 2022 14:55:26 -0300 Subject: [PATCH 5/5] Update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f4ed58..e20f746 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +### Added + +- addAffiliate mutation + ## [0.28.0] - 2022-02-08 ### Added