customer.e2e-spec.ts 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  1. import { OnModuleInit } from '@nestjs/common';
  2. import { HistoryEntryType } from '@vendure/common/lib/generated-types';
  3. import { omit } from '@vendure/common/lib/omit';
  4. import { pick } from '@vendure/common/lib/pick';
  5. import {
  6. AccountRegistrationEvent,
  7. EventBus,
  8. EventBusModule,
  9. mergeConfig,
  10. VendurePlugin,
  11. } from '@vendure/core';
  12. import { createTestEnvironment } from '@vendure/testing';
  13. import gql from 'graphql-tag';
  14. import path from 'path';
  15. import { initialData } from '../../../e2e-common/e2e-initial-data';
  16. import { TEST_SETUP_TIMEOUT_MS, testConfig } from '../../../e2e-common/test-config';
  17. import { CUSTOMER_FRAGMENT } from './graphql/fragments';
  18. import {
  19. AddNoteToCustomer,
  20. CreateAddress,
  21. CreateCustomer,
  22. DeleteCustomer,
  23. DeleteCustomerAddress,
  24. DeleteCustomerNote,
  25. DeletionResult,
  26. GetCustomer,
  27. GetCustomerHistory,
  28. GetCustomerList,
  29. GetCustomerOrders,
  30. GetCustomerWithUser,
  31. UpdateAddress,
  32. UpdateCustomer,
  33. UpdateCustomerNote,
  34. } from './graphql/generated-e2e-admin-types';
  35. import { AddItemToOrder } from './graphql/generated-e2e-shop-types';
  36. import { GET_CUSTOMER, GET_CUSTOMER_HISTORY, GET_CUSTOMER_LIST } from './graphql/shared-definitions';
  37. import { ADD_ITEM_TO_ORDER } from './graphql/shop-definitions';
  38. import { assertThrowsWithMessage } from './utils/assert-throws-with-message';
  39. // tslint:disable:no-non-null-assertion
  40. let sendEmailFn: jest.Mock;
  41. /**
  42. * This mock plugin simulates an EmailPlugin which would send emails
  43. * on the registration & password reset events.
  44. */
  45. @VendurePlugin({
  46. imports: [EventBusModule],
  47. })
  48. class TestEmailPlugin implements OnModuleInit {
  49. constructor(private eventBus: EventBus) {}
  50. onModuleInit() {
  51. this.eventBus.ofType(AccountRegistrationEvent).subscribe((event) => {
  52. sendEmailFn(event);
  53. });
  54. }
  55. }
  56. describe('Customer resolver', () => {
  57. const { server, adminClient, shopClient } = createTestEnvironment(
  58. mergeConfig(testConfig, { plugins: [TestEmailPlugin] }),
  59. );
  60. let firstCustomer: GetCustomerList.Items;
  61. let secondCustomer: GetCustomerList.Items;
  62. let thirdCustomer: GetCustomerList.Items;
  63. beforeAll(async () => {
  64. await server.init({
  65. initialData,
  66. productsCsvPath: path.join(__dirname, 'fixtures/e2e-products-minimal.csv'),
  67. customerCount: 5,
  68. });
  69. await adminClient.asSuperAdmin();
  70. }, TEST_SETUP_TIMEOUT_MS);
  71. afterAll(async () => {
  72. await server.destroy();
  73. });
  74. it('customers list', async () => {
  75. const result = await adminClient.query<GetCustomerList.Query, GetCustomerList.Variables>(
  76. GET_CUSTOMER_LIST,
  77. );
  78. expect(result.customers.items.length).toBe(5);
  79. expect(result.customers.totalItems).toBe(5);
  80. firstCustomer = result.customers.items[0];
  81. secondCustomer = result.customers.items[1];
  82. thirdCustomer = result.customers.items[2];
  83. });
  84. it('customer resolver resolves User', async () => {
  85. const { customer } = await adminClient.query<
  86. GetCustomerWithUser.Query,
  87. GetCustomerWithUser.Variables
  88. >(GET_CUSTOMER_WITH_USER, {
  89. id: firstCustomer.id,
  90. });
  91. expect(customer!.user).toEqual({
  92. id: 'T_2',
  93. identifier: firstCustomer.emailAddress,
  94. verified: true,
  95. });
  96. });
  97. describe('addresses', () => {
  98. let firstCustomerAddressIds: string[] = [];
  99. let firstCustomerThirdAddressId: string;
  100. it(
  101. 'createCustomerAddress throws on invalid countryCode',
  102. assertThrowsWithMessage(
  103. () =>
  104. adminClient.query<CreateAddress.Mutation, CreateAddress.Variables>(CREATE_ADDRESS, {
  105. id: firstCustomer.id,
  106. input: {
  107. streetLine1: 'streetLine1',
  108. countryCode: 'INVALID',
  109. },
  110. }),
  111. `The countryCode "INVALID" was not recognized`,
  112. ),
  113. );
  114. it('createCustomerAddress creates a new address', async () => {
  115. const result = await adminClient.query<CreateAddress.Mutation, CreateAddress.Variables>(
  116. CREATE_ADDRESS,
  117. {
  118. id: firstCustomer.id,
  119. input: {
  120. fullName: 'fullName',
  121. company: 'company',
  122. streetLine1: 'streetLine1',
  123. streetLine2: 'streetLine2',
  124. city: 'city',
  125. province: 'province',
  126. postalCode: 'postalCode',
  127. countryCode: 'GB',
  128. phoneNumber: 'phoneNumber',
  129. defaultShippingAddress: false,
  130. defaultBillingAddress: false,
  131. },
  132. },
  133. );
  134. expect(omit(result.createCustomerAddress, ['id'])).toEqual({
  135. fullName: 'fullName',
  136. company: 'company',
  137. streetLine1: 'streetLine1',
  138. streetLine2: 'streetLine2',
  139. city: 'city',
  140. province: 'province',
  141. postalCode: 'postalCode',
  142. country: {
  143. code: 'GB',
  144. name: 'United Kingdom',
  145. },
  146. phoneNumber: 'phoneNumber',
  147. defaultShippingAddress: false,
  148. defaultBillingAddress: false,
  149. });
  150. });
  151. it('customer query returns addresses', async () => {
  152. const result = await adminClient.query<GetCustomer.Query, GetCustomer.Variables>(GET_CUSTOMER, {
  153. id: firstCustomer.id,
  154. });
  155. expect(result.customer!.addresses!.length).toBe(2);
  156. firstCustomerAddressIds = result.customer!.addresses!.map((a) => a.id).sort();
  157. });
  158. it('updateCustomerAddress updates the country', async () => {
  159. const result = await adminClient.query<UpdateAddress.Mutation, UpdateAddress.Variables>(
  160. UPDATE_ADDRESS,
  161. {
  162. input: {
  163. id: firstCustomerAddressIds[0],
  164. countryCode: 'AT',
  165. },
  166. },
  167. );
  168. expect(result.updateCustomerAddress.country).toEqual({
  169. code: 'AT',
  170. name: 'Austria',
  171. });
  172. });
  173. it('updateCustomerAddress allows only a single default address', async () => {
  174. // set the first customer's second address to be default
  175. const result1 = await adminClient.query<UpdateAddress.Mutation, UpdateAddress.Variables>(
  176. UPDATE_ADDRESS,
  177. {
  178. input: {
  179. id: firstCustomerAddressIds[1],
  180. defaultShippingAddress: true,
  181. defaultBillingAddress: true,
  182. },
  183. },
  184. );
  185. expect(result1.updateCustomerAddress.defaultShippingAddress).toBe(true);
  186. expect(result1.updateCustomerAddress.defaultBillingAddress).toBe(true);
  187. // assert the first customer's other addresse is not default
  188. const result2 = await adminClient.query<GetCustomer.Query, GetCustomer.Variables>(GET_CUSTOMER, {
  189. id: firstCustomer.id,
  190. });
  191. const otherAddress = result2.customer!.addresses!.filter(
  192. (a) => a.id !== firstCustomerAddressIds[1],
  193. )[0]!;
  194. expect(otherAddress.defaultShippingAddress).toBe(false);
  195. expect(otherAddress.defaultBillingAddress).toBe(false);
  196. // set the first customer's first address to be default
  197. const result3 = await adminClient.query<UpdateAddress.Mutation, UpdateAddress.Variables>(
  198. UPDATE_ADDRESS,
  199. {
  200. input: {
  201. id: firstCustomerAddressIds[0],
  202. defaultShippingAddress: true,
  203. defaultBillingAddress: true,
  204. },
  205. },
  206. );
  207. expect(result3.updateCustomerAddress.defaultShippingAddress).toBe(true);
  208. expect(result3.updateCustomerAddress.defaultBillingAddress).toBe(true);
  209. // assert the first customer's second address is not default
  210. const result4 = await adminClient.query<GetCustomer.Query, GetCustomer.Variables>(GET_CUSTOMER, {
  211. id: firstCustomer.id,
  212. });
  213. const otherAddress2 = result4.customer!.addresses!.filter(
  214. (a) => a.id !== firstCustomerAddressIds[0],
  215. )[0]!;
  216. expect(otherAddress2.defaultShippingAddress).toBe(false);
  217. expect(otherAddress2.defaultBillingAddress).toBe(false);
  218. // get the second customer's address id
  219. const result5 = await adminClient.query<GetCustomer.Query, GetCustomer.Variables>(GET_CUSTOMER, {
  220. id: secondCustomer.id,
  221. });
  222. const secondCustomerAddressId = result5.customer!.addresses![0].id;
  223. // set the second customer's address to be default
  224. const result6 = await adminClient.query<UpdateAddress.Mutation, UpdateAddress.Variables>(
  225. UPDATE_ADDRESS,
  226. {
  227. input: {
  228. id: secondCustomerAddressId,
  229. defaultShippingAddress: true,
  230. defaultBillingAddress: true,
  231. },
  232. },
  233. );
  234. expect(result6.updateCustomerAddress.defaultShippingAddress).toBe(true);
  235. expect(result6.updateCustomerAddress.defaultBillingAddress).toBe(true);
  236. // assets the first customer's address defaults are unchanged
  237. const result7 = await adminClient.query<GetCustomer.Query, GetCustomer.Variables>(GET_CUSTOMER, {
  238. id: firstCustomer.id,
  239. });
  240. expect(result7.customer!.addresses![0].defaultShippingAddress).toBe(true);
  241. expect(result7.customer!.addresses![0].defaultBillingAddress).toBe(true);
  242. expect(result7.customer!.addresses![1].defaultShippingAddress).toBe(false);
  243. expect(result7.customer!.addresses![1].defaultBillingAddress).toBe(false);
  244. });
  245. it('createCustomerAddress with true defaults unsets existing defaults', async () => {
  246. const { createCustomerAddress } = await adminClient.query<
  247. CreateAddress.Mutation,
  248. CreateAddress.Variables
  249. >(CREATE_ADDRESS, {
  250. id: firstCustomer.id,
  251. input: {
  252. streetLine1: 'new default streetline',
  253. countryCode: 'GB',
  254. defaultShippingAddress: true,
  255. defaultBillingAddress: true,
  256. },
  257. });
  258. expect(omit(createCustomerAddress, ['id'])).toEqual({
  259. fullName: '',
  260. company: '',
  261. streetLine1: 'new default streetline',
  262. streetLine2: '',
  263. city: '',
  264. province: '',
  265. postalCode: '',
  266. country: {
  267. code: 'GB',
  268. name: 'United Kingdom',
  269. },
  270. phoneNumber: '',
  271. defaultShippingAddress: true,
  272. defaultBillingAddress: true,
  273. });
  274. const { customer } = await adminClient.query<GetCustomer.Query, GetCustomer.Variables>(
  275. GET_CUSTOMER,
  276. {
  277. id: firstCustomer.id,
  278. },
  279. );
  280. for (const address of customer!.addresses!) {
  281. const shouldBeDefault = address.id === createCustomerAddress.id;
  282. expect(address.defaultShippingAddress).toEqual(shouldBeDefault);
  283. expect(address.defaultBillingAddress).toEqual(shouldBeDefault);
  284. }
  285. firstCustomerThirdAddressId = createCustomerAddress.id;
  286. });
  287. it('deleteCustomerAddress on default address resets defaults', async () => {
  288. const { deleteCustomerAddress } = await adminClient.query<
  289. DeleteCustomerAddress.Mutation,
  290. DeleteCustomerAddress.Variables
  291. >(
  292. gql`
  293. mutation DeleteCustomerAddress($id: ID!) {
  294. deleteCustomerAddress(id: $id)
  295. }
  296. `,
  297. { id: firstCustomerThirdAddressId },
  298. );
  299. expect(deleteCustomerAddress).toBe(true);
  300. const { customer } = await adminClient.query<GetCustomer.Query, GetCustomer.Variables>(
  301. GET_CUSTOMER,
  302. {
  303. id: firstCustomer.id,
  304. },
  305. );
  306. expect(customer!.addresses!.length).toBe(2);
  307. const defaultAddress = customer!.addresses!.filter(
  308. (a) => a.defaultBillingAddress && a.defaultShippingAddress,
  309. );
  310. const otherAddress = customer!.addresses!.filter(
  311. (a) => !a.defaultBillingAddress && !a.defaultShippingAddress,
  312. );
  313. expect(defaultAddress.length).toBe(1);
  314. expect(otherAddress.length).toBe(1);
  315. });
  316. });
  317. describe('orders', () => {
  318. it(`lists that user\'s orders`, async () => {
  319. // log in as first customer
  320. await shopClient.asUserWithCredentials(firstCustomer.emailAddress, 'test');
  321. // add an item to the order to create an order
  322. const { addItemToOrder } = await shopClient.query<
  323. AddItemToOrder.Mutation,
  324. AddItemToOrder.Variables
  325. >(ADD_ITEM_TO_ORDER, {
  326. productVariantId: 'T_1',
  327. quantity: 1,
  328. });
  329. const { customer } = await adminClient.query<
  330. GetCustomerOrders.Query,
  331. GetCustomerOrders.Variables
  332. >(GET_CUSTOMER_ORDERS, { id: firstCustomer.id });
  333. expect(customer!.orders.totalItems).toBe(1);
  334. expect(customer!.orders.items[0].id).toBe(addItemToOrder!.id);
  335. });
  336. });
  337. describe('creation', () => {
  338. it('triggers verification event if no password supplied', async () => {
  339. sendEmailFn = jest.fn();
  340. const { createCustomer } = await adminClient.query<
  341. CreateCustomer.Mutation,
  342. CreateCustomer.Variables
  343. >(CREATE_CUSTOMER, {
  344. input: {
  345. emailAddress: 'test1@test.com',
  346. firstName: 'New',
  347. lastName: 'Customer',
  348. },
  349. });
  350. expect(createCustomer.user!.verified).toBe(false);
  351. expect(sendEmailFn).toHaveBeenCalledTimes(1);
  352. expect(sendEmailFn.mock.calls[0][0] instanceof AccountRegistrationEvent).toBe(true);
  353. expect(sendEmailFn.mock.calls[0][0].user.identifier).toBe('test1@test.com');
  354. });
  355. it('creates a verified Customer', async () => {
  356. sendEmailFn = jest.fn();
  357. const { createCustomer } = await adminClient.query<
  358. CreateCustomer.Mutation,
  359. CreateCustomer.Variables
  360. >(CREATE_CUSTOMER, {
  361. input: {
  362. emailAddress: 'test2@test.com',
  363. firstName: 'New',
  364. lastName: 'Customer',
  365. },
  366. password: 'test',
  367. });
  368. expect(createCustomer.user!.verified).toBe(true);
  369. expect(sendEmailFn).toHaveBeenCalledTimes(0);
  370. });
  371. it(
  372. 'throws when using an existing, non-deleted emailAddress',
  373. assertThrowsWithMessage(async () => {
  374. const { createCustomer } = await adminClient.query<
  375. CreateCustomer.Mutation,
  376. CreateCustomer.Variables
  377. >(CREATE_CUSTOMER, {
  378. input: {
  379. emailAddress: 'test2@test.com',
  380. firstName: 'New',
  381. lastName: 'Customer',
  382. },
  383. password: 'test',
  384. });
  385. }, 'The email address must be unique'),
  386. );
  387. });
  388. describe('deletion', () => {
  389. it('deletes a customer', async () => {
  390. const result = await adminClient.query<DeleteCustomer.Mutation, DeleteCustomer.Variables>(
  391. DELETE_CUSTOMER,
  392. { id: thirdCustomer.id },
  393. );
  394. expect(result.deleteCustomer).toEqual({ result: DeletionResult.DELETED });
  395. });
  396. it('cannot get a deleted customer', async () => {
  397. const result = await adminClient.query<GetCustomer.Query, GetCustomer.Variables>(GET_CUSTOMER, {
  398. id: thirdCustomer.id,
  399. });
  400. expect(result.customer).toBe(null);
  401. });
  402. it('deleted customer omitted from list', async () => {
  403. const result = await adminClient.query<GetCustomerList.Query, GetCustomerList.Variables>(
  404. GET_CUSTOMER_LIST,
  405. );
  406. expect(result.customers.items.map((c) => c.id).includes(thirdCustomer.id)).toBe(false);
  407. });
  408. it(
  409. 'updateCustomer throws for deleted customer',
  410. assertThrowsWithMessage(
  411. () =>
  412. adminClient.query<UpdateCustomer.Mutation, UpdateCustomer.Variables>(UPDATE_CUSTOMER, {
  413. input: {
  414. id: thirdCustomer.id,
  415. firstName: 'updated',
  416. },
  417. }),
  418. `No Customer with the id '3' could be found`,
  419. ),
  420. );
  421. it(
  422. 'createCustomerAddress throws for deleted customer',
  423. assertThrowsWithMessage(
  424. () =>
  425. adminClient.query<CreateAddress.Mutation, CreateAddress.Variables>(CREATE_ADDRESS, {
  426. id: thirdCustomer.id,
  427. input: {
  428. streetLine1: 'test',
  429. countryCode: 'GB',
  430. },
  431. }),
  432. `No Customer with the id '3' could be found`,
  433. ),
  434. );
  435. it('new Customer can be created with same emailAddress as a deleted Customer', async () => {
  436. const { createCustomer } = await adminClient.query<
  437. CreateCustomer.Mutation,
  438. CreateCustomer.Variables
  439. >(CREATE_CUSTOMER, {
  440. input: {
  441. emailAddress: thirdCustomer.emailAddress,
  442. firstName: 'Reusing Email',
  443. lastName: 'Customer',
  444. },
  445. });
  446. expect(createCustomer.emailAddress).toBe(thirdCustomer.emailAddress);
  447. expect(createCustomer.firstName).toBe('Reusing Email');
  448. expect(createCustomer.user?.identifier).toBe(thirdCustomer.emailAddress);
  449. });
  450. });
  451. describe('customer notes', () => {
  452. let noteId: string;
  453. it('addNoteToCustomer', async () => {
  454. const { addNoteToCustomer } = await adminClient.query<
  455. AddNoteToCustomer.Mutation,
  456. AddNoteToCustomer.Variables
  457. >(ADD_NOTE_TO_CUSTOMER, {
  458. input: {
  459. id: firstCustomer.id,
  460. isPublic: false,
  461. note: 'Test note',
  462. },
  463. });
  464. const { customer } = await adminClient.query<
  465. GetCustomerHistory.Query,
  466. GetCustomerHistory.Variables
  467. >(GET_CUSTOMER_HISTORY, {
  468. id: firstCustomer.id,
  469. options: {
  470. filter: {
  471. type: {
  472. eq: HistoryEntryType.CUSTOMER_NOTE,
  473. },
  474. },
  475. },
  476. });
  477. expect(customer?.history.items.map(pick(['type', 'data']))).toEqual([
  478. {
  479. type: HistoryEntryType.CUSTOMER_NOTE,
  480. data: {
  481. note: 'Test note',
  482. },
  483. },
  484. ]);
  485. noteId = customer?.history.items[0].id!;
  486. });
  487. it('update note', async () => {
  488. const { updateCustomerNote } = await adminClient.query<
  489. UpdateCustomerNote.Mutation,
  490. UpdateCustomerNote.Variables
  491. >(UPDATE_CUSTOMER_NOTE, {
  492. input: {
  493. noteId,
  494. note: 'An updated note',
  495. },
  496. });
  497. expect(updateCustomerNote.data).toEqual({
  498. note: 'An updated note',
  499. });
  500. });
  501. it('delete note', async () => {
  502. const { customer: before } = await adminClient.query<
  503. GetCustomerHistory.Query,
  504. GetCustomerHistory.Variables
  505. >(GET_CUSTOMER_HISTORY, { id: firstCustomer.id });
  506. const historyCount = before?.history.totalItems!;
  507. const { deleteCustomerNote } = await adminClient.query<
  508. DeleteCustomerNote.Mutation,
  509. DeleteCustomerNote.Variables
  510. >(DELETE_CUSTOMER_NOTE, {
  511. id: noteId,
  512. });
  513. expect(deleteCustomerNote.result).toBe(DeletionResult.DELETED);
  514. const { customer: after } = await adminClient.query<
  515. GetCustomerHistory.Query,
  516. GetCustomerHistory.Variables
  517. >(GET_CUSTOMER_HISTORY, { id: firstCustomer.id });
  518. expect(after?.history.totalItems).toBe(historyCount - 1);
  519. });
  520. });
  521. });
  522. const GET_CUSTOMER_WITH_USER = gql`
  523. query GetCustomerWithUser($id: ID!) {
  524. customer(id: $id) {
  525. id
  526. user {
  527. id
  528. identifier
  529. verified
  530. }
  531. }
  532. }
  533. `;
  534. const CREATE_ADDRESS = gql`
  535. mutation CreateAddress($id: ID!, $input: CreateAddressInput!) {
  536. createCustomerAddress(customerId: $id, input: $input) {
  537. id
  538. fullName
  539. company
  540. streetLine1
  541. streetLine2
  542. city
  543. province
  544. postalCode
  545. country {
  546. code
  547. name
  548. }
  549. phoneNumber
  550. defaultShippingAddress
  551. defaultBillingAddress
  552. }
  553. }
  554. `;
  555. const UPDATE_ADDRESS = gql`
  556. mutation UpdateAddress($input: UpdateAddressInput!) {
  557. updateCustomerAddress(input: $input) {
  558. id
  559. defaultShippingAddress
  560. defaultBillingAddress
  561. country {
  562. code
  563. name
  564. }
  565. }
  566. }
  567. `;
  568. const GET_CUSTOMER_ORDERS = gql`
  569. query GetCustomerOrders($id: ID!) {
  570. customer(id: $id) {
  571. orders {
  572. items {
  573. id
  574. }
  575. totalItems
  576. }
  577. }
  578. }
  579. `;
  580. export const CREATE_CUSTOMER = gql`
  581. mutation CreateCustomer($input: CreateCustomerInput!, $password: String) {
  582. createCustomer(input: $input, password: $password) {
  583. ...Customer
  584. }
  585. }
  586. ${CUSTOMER_FRAGMENT}
  587. `;
  588. export const UPDATE_CUSTOMER = gql`
  589. mutation UpdateCustomer($input: UpdateCustomerInput!) {
  590. updateCustomer(input: $input) {
  591. ...Customer
  592. }
  593. }
  594. ${CUSTOMER_FRAGMENT}
  595. `;
  596. const DELETE_CUSTOMER = gql`
  597. mutation DeleteCustomer($id: ID!) {
  598. deleteCustomer(id: $id) {
  599. result
  600. }
  601. }
  602. `;
  603. const ADD_NOTE_TO_CUSTOMER = gql`
  604. mutation AddNoteToCustomer($input: AddNoteToCustomerInput!) {
  605. addNoteToCustomer(input: $input) {
  606. ...Customer
  607. }
  608. }
  609. ${CUSTOMER_FRAGMENT}
  610. `;
  611. export const UPDATE_CUSTOMER_NOTE = gql`
  612. mutation UpdateCustomerNote($input: UpdateCustomerNoteInput!) {
  613. updateCustomerNote(input: $input) {
  614. id
  615. data
  616. isPublic
  617. }
  618. }
  619. `;
  620. export const DELETE_CUSTOMER_NOTE = gql`
  621. mutation DeleteCustomerNote($id: ID!) {
  622. deleteCustomerNote(id: $id) {
  623. result
  624. message
  625. }
  626. }
  627. `;