facet.e2e-spec.ts 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  1. import { pick } from '@vendure/common/lib/pick';
  2. import { createTestEnvironment, E2E_DEFAULT_CHANNEL_TOKEN } from '@vendure/testing';
  3. import gql from 'graphql-tag';
  4. import path from 'path';
  5. import { initialData } from '../../../e2e-common/e2e-initial-data';
  6. import { testConfig, TEST_SETUP_TIMEOUT_MS } from '../../../e2e-common/test-config';
  7. import { FACET_VALUE_FRAGMENT, FACET_WITH_VALUES_FRAGMENT } from './graphql/fragments';
  8. import {
  9. AssignProductsToChannel,
  10. ChannelFragment,
  11. CreateChannel,
  12. CreateFacet,
  13. CreateFacetValues,
  14. CurrencyCode,
  15. DeleteFacet,
  16. DeleteFacetValues,
  17. DeletionResult,
  18. FacetWithValues,
  19. GetFacetList,
  20. GetFacetWithValues,
  21. GetProductListWithVariants,
  22. GetProductWithVariants,
  23. LanguageCode,
  24. UpdateFacet,
  25. UpdateFacetValues,
  26. UpdateProduct,
  27. UpdateProductVariants,
  28. } from './graphql/generated-e2e-admin-types';
  29. import {
  30. ASSIGN_PRODUCT_TO_CHANNEL,
  31. CREATE_CHANNEL,
  32. CREATE_FACET,
  33. GET_FACET_LIST,
  34. GET_FACET_LIST_SIMPLE,
  35. GET_PRODUCT_WITH_VARIANTS,
  36. UPDATE_FACET,
  37. UPDATE_PRODUCT,
  38. UPDATE_PRODUCT_VARIANTS,
  39. } from './graphql/shared-definitions';
  40. import { assertThrowsWithMessage } from './utils/assert-throws-with-message';
  41. // tslint:disable:no-non-null-assertion
  42. describe('Facet resolver', () => {
  43. const { server, adminClient, shopClient } = createTestEnvironment(testConfig());
  44. let brandFacet: FacetWithValues.Fragment;
  45. let speakerTypeFacet: FacetWithValues.Fragment;
  46. beforeAll(async () => {
  47. await server.init({
  48. initialData,
  49. productsCsvPath: path.join(__dirname, 'fixtures/e2e-products-full.csv'),
  50. customerCount: 1,
  51. });
  52. await adminClient.asSuperAdmin();
  53. }, TEST_SETUP_TIMEOUT_MS);
  54. afterAll(async () => {
  55. await server.destroy();
  56. });
  57. it('createFacet', async () => {
  58. const result = await adminClient.query<CreateFacet.Mutation, CreateFacet.Variables>(CREATE_FACET, {
  59. input: {
  60. isPrivate: false,
  61. code: 'speaker-type',
  62. translations: [{ languageCode: LanguageCode.en, name: 'Speaker Type' }],
  63. values: [
  64. {
  65. code: 'portable',
  66. translations: [{ languageCode: LanguageCode.en, name: 'Portable' }],
  67. },
  68. ],
  69. },
  70. });
  71. speakerTypeFacet = result.createFacet;
  72. expect(speakerTypeFacet).toMatchSnapshot();
  73. });
  74. it('updateFacet', async () => {
  75. const result = await adminClient.query<UpdateFacet.Mutation, UpdateFacet.Variables>(UPDATE_FACET, {
  76. input: {
  77. id: speakerTypeFacet.id,
  78. translations: [{ languageCode: LanguageCode.en, name: 'Speaker Category' }],
  79. isPrivate: true,
  80. },
  81. });
  82. expect(result.updateFacet.name).toBe('Speaker Category');
  83. });
  84. it('createFacetValues', async () => {
  85. const { createFacetValues } = await adminClient.query<
  86. CreateFacetValues.Mutation,
  87. CreateFacetValues.Variables
  88. >(CREATE_FACET_VALUES, {
  89. input: [
  90. {
  91. facetId: speakerTypeFacet.id,
  92. code: 'pc',
  93. translations: [{ languageCode: LanguageCode.en, name: 'PC Speakers' }],
  94. },
  95. {
  96. facetId: speakerTypeFacet.id,
  97. code: 'hi-fi',
  98. translations: [{ languageCode: LanguageCode.en, name: 'Hi Fi Speakers' }],
  99. },
  100. ],
  101. });
  102. expect(createFacetValues.length).toBe(2);
  103. expect(pick(createFacetValues.find(fv => fv.code === 'pc')!, ['code', 'facet', 'name'])).toEqual({
  104. code: 'pc',
  105. facet: {
  106. id: 'T_2',
  107. name: 'Speaker Category',
  108. },
  109. name: 'PC Speakers',
  110. });
  111. expect(pick(createFacetValues.find(fv => fv.code === 'hi-fi')!, ['code', 'facet', 'name'])).toEqual({
  112. code: 'hi-fi',
  113. facet: {
  114. id: 'T_2',
  115. name: 'Speaker Category',
  116. },
  117. name: 'Hi Fi Speakers',
  118. });
  119. });
  120. it('updateFacetValues', async () => {
  121. const result = await adminClient.query<UpdateFacetValues.Mutation, UpdateFacetValues.Variables>(
  122. UPDATE_FACET_VALUES,
  123. {
  124. input: [
  125. {
  126. id: speakerTypeFacet.values[0].id,
  127. code: 'compact',
  128. },
  129. ],
  130. },
  131. );
  132. expect(result.updateFacetValues[0].code).toBe('compact');
  133. });
  134. it('facets', async () => {
  135. const result = await adminClient.query<GetFacetList.Query>(GET_FACET_LIST);
  136. const { items } = result.facets;
  137. expect(items.length).toBe(2);
  138. expect(items[0].name).toBe('category');
  139. expect(items[1].name).toBe('Speaker Category');
  140. brandFacet = items[0];
  141. speakerTypeFacet = items[1];
  142. });
  143. it('facets by shop-api', async () => {
  144. const result = await shopClient.query<GetFacetList.Query>(GET_FACET_LIST_SIMPLE);
  145. const { items } = result.facets;
  146. expect(items.length).toBe(1);
  147. expect(items[0].name).toBe('category');
  148. });
  149. it('facet', async () => {
  150. const result = await adminClient.query<GetFacetWithValues.Query, GetFacetWithValues.Variables>(
  151. GET_FACET_WITH_VALUES,
  152. {
  153. id: speakerTypeFacet.id,
  154. },
  155. );
  156. expect(result.facet!.name).toBe('Speaker Category');
  157. });
  158. describe('deletion', () => {
  159. let products: GetProductListWithVariants.Items[];
  160. beforeAll(async () => {
  161. // add the FacetValues to products and variants
  162. const result1 = await adminClient.query<GetProductListWithVariants.Query>(
  163. GET_PRODUCTS_LIST_WITH_VARIANTS,
  164. );
  165. products = result1.products.items;
  166. await adminClient.query<UpdateProduct.Mutation, UpdateProduct.Variables>(UPDATE_PRODUCT, {
  167. input: {
  168. id: products[0].id,
  169. facetValueIds: [speakerTypeFacet.values[0].id],
  170. },
  171. });
  172. await adminClient.query<UpdateProductVariants.Mutation, UpdateProductVariants.Variables>(
  173. UPDATE_PRODUCT_VARIANTS,
  174. {
  175. input: [
  176. {
  177. id: products[0].variants[0].id,
  178. facetValueIds: [speakerTypeFacet.values[0].id],
  179. },
  180. ],
  181. },
  182. );
  183. await adminClient.query<UpdateProduct.Mutation, UpdateProduct.Variables>(UPDATE_PRODUCT, {
  184. input: {
  185. id: products[1].id,
  186. facetValueIds: [speakerTypeFacet.values[1].id],
  187. },
  188. });
  189. });
  190. it('deleteFacetValues deletes unused facetValue', async () => {
  191. const facetValueToDelete = speakerTypeFacet.values[2];
  192. const result1 = await adminClient.query<DeleteFacetValues.Mutation, DeleteFacetValues.Variables>(
  193. DELETE_FACET_VALUES,
  194. {
  195. ids: [facetValueToDelete.id],
  196. force: false,
  197. },
  198. );
  199. const result2 = await adminClient.query<GetFacetWithValues.Query, GetFacetWithValues.Variables>(
  200. GET_FACET_WITH_VALUES,
  201. {
  202. id: speakerTypeFacet.id,
  203. },
  204. );
  205. expect(result1.deleteFacetValues).toEqual([
  206. {
  207. result: DeletionResult.DELETED,
  208. message: ``,
  209. },
  210. ]);
  211. expect(result2.facet!.values[0]).not.toEqual(facetValueToDelete);
  212. });
  213. it('deleteFacetValues for FacetValue in use returns NOT_DELETED', async () => {
  214. const facetValueToDelete = speakerTypeFacet.values[0];
  215. const result1 = await adminClient.query<DeleteFacetValues.Mutation, DeleteFacetValues.Variables>(
  216. DELETE_FACET_VALUES,
  217. {
  218. ids: [facetValueToDelete.id],
  219. force: false,
  220. },
  221. );
  222. const result2 = await adminClient.query<GetFacetWithValues.Query, GetFacetWithValues.Variables>(
  223. GET_FACET_WITH_VALUES,
  224. {
  225. id: speakerTypeFacet.id,
  226. },
  227. );
  228. expect(result1.deleteFacetValues).toEqual([
  229. {
  230. result: DeletionResult.NOT_DELETED,
  231. message: `The selected FacetValue is assigned to 1 Product, 1 ProductVariant`,
  232. },
  233. ]);
  234. expect(result2.facet!.values.find(v => v.id === facetValueToDelete.id)).toBeDefined();
  235. });
  236. it('deleteFacetValues for FacetValue in use can be force deleted', async () => {
  237. const facetValueToDelete = speakerTypeFacet.values[0];
  238. const result1 = await adminClient.query<DeleteFacetValues.Mutation, DeleteFacetValues.Variables>(
  239. DELETE_FACET_VALUES,
  240. {
  241. ids: [facetValueToDelete.id],
  242. force: true,
  243. },
  244. );
  245. expect(result1.deleteFacetValues).toEqual([
  246. {
  247. result: DeletionResult.DELETED,
  248. message: `The selected FacetValue was removed from 1 Product, 1 ProductVariant and deleted`,
  249. },
  250. ]);
  251. // FacetValue no longer in the Facet.values array
  252. const result2 = await adminClient.query<GetFacetWithValues.Query, GetFacetWithValues.Variables>(
  253. GET_FACET_WITH_VALUES,
  254. {
  255. id: speakerTypeFacet.id,
  256. },
  257. );
  258. expect(result2.facet!.values[0]).not.toEqual(facetValueToDelete);
  259. // FacetValue no longer in the Product.facetValues array
  260. const result3 = await adminClient.query<
  261. GetProductWithVariants.Query,
  262. GetProductWithVariants.Variables
  263. >(GET_PRODUCT_WITH_VARIANTS, {
  264. id: products[0].id,
  265. });
  266. expect(result3.product!.facetValues).toEqual([]);
  267. });
  268. it('deleteFacet that is in use returns NOT_DELETED', async () => {
  269. const result1 = await adminClient.query<DeleteFacet.Mutation, DeleteFacet.Variables>(
  270. DELETE_FACET,
  271. {
  272. id: speakerTypeFacet.id,
  273. force: false,
  274. },
  275. );
  276. const result2 = await adminClient.query<GetFacetWithValues.Query, GetFacetWithValues.Variables>(
  277. GET_FACET_WITH_VALUES,
  278. {
  279. id: speakerTypeFacet.id,
  280. },
  281. );
  282. expect(result1.deleteFacet).toEqual({
  283. result: DeletionResult.NOT_DELETED,
  284. message: `The selected Facet includes FacetValues which are assigned to 1 Product`,
  285. });
  286. expect(result2.facet).not.toBe(null);
  287. });
  288. it('deleteFacet that is in use can be force deleted', async () => {
  289. const result1 = await adminClient.query<DeleteFacet.Mutation, DeleteFacet.Variables>(
  290. DELETE_FACET,
  291. {
  292. id: speakerTypeFacet.id,
  293. force: true,
  294. },
  295. );
  296. expect(result1.deleteFacet).toEqual({
  297. result: DeletionResult.DELETED,
  298. message: `The Facet was deleted and its FacetValues were removed from 1 Product`,
  299. });
  300. // FacetValue no longer in the Facet.values array
  301. const result2 = await adminClient.query<GetFacetWithValues.Query, GetFacetWithValues.Variables>(
  302. GET_FACET_WITH_VALUES,
  303. {
  304. id: speakerTypeFacet.id,
  305. },
  306. );
  307. expect(result2.facet).toBe(null);
  308. // FacetValue no longer in the Product.facetValues array
  309. const result3 = await adminClient.query<
  310. GetProductWithVariants.Query,
  311. GetProductWithVariants.Variables
  312. >(GET_PRODUCT_WITH_VARIANTS, {
  313. id: products[1].id,
  314. });
  315. expect(result3.product!.facetValues).toEqual([]);
  316. });
  317. it('deleteFacet with no FacetValues works', async () => {
  318. const { createFacet } = await adminClient.query<CreateFacet.Mutation, CreateFacet.Variables>(
  319. CREATE_FACET,
  320. {
  321. input: {
  322. code: 'test',
  323. isPrivate: false,
  324. translations: [{ languageCode: LanguageCode.en, name: 'Test' }],
  325. },
  326. },
  327. );
  328. const result = await adminClient.query<DeleteFacet.Mutation, DeleteFacet.Variables>(
  329. DELETE_FACET,
  330. {
  331. id: createFacet.id,
  332. force: false,
  333. },
  334. );
  335. expect(result.deleteFacet.result).toBe(DeletionResult.DELETED);
  336. });
  337. });
  338. describe('channels', () => {
  339. const SECOND_CHANNEL_TOKEN = 'second_channel_token';
  340. let createdFacet: CreateFacet.CreateFacet;
  341. beforeAll(async () => {
  342. const { createChannel } = await adminClient.query<
  343. CreateChannel.Mutation,
  344. CreateChannel.Variables
  345. >(CREATE_CHANNEL, {
  346. input: {
  347. code: 'second-channel',
  348. token: SECOND_CHANNEL_TOKEN,
  349. defaultLanguageCode: LanguageCode.en,
  350. currencyCode: CurrencyCode.USD,
  351. pricesIncludeTax: true,
  352. defaultShippingZoneId: 'T_1',
  353. defaultTaxZoneId: 'T_1',
  354. },
  355. });
  356. const { assignProductsToChannel } = await adminClient.query<
  357. AssignProductsToChannel.Mutation,
  358. AssignProductsToChannel.Variables
  359. >(ASSIGN_PRODUCT_TO_CHANNEL, {
  360. input: {
  361. channelId: (createChannel as ChannelFragment).id,
  362. productIds: ['T_1'],
  363. priceFactor: 0.5,
  364. },
  365. });
  366. adminClient.setChannelToken(SECOND_CHANNEL_TOKEN);
  367. });
  368. it('create Facet in channel', async () => {
  369. const { createFacet } = await adminClient.query<CreateFacet.Mutation, CreateFacet.Variables>(
  370. CREATE_FACET,
  371. {
  372. input: {
  373. isPrivate: false,
  374. code: 'channel-facet',
  375. translations: [{ languageCode: LanguageCode.en, name: 'Channel Facet' }],
  376. values: [
  377. {
  378. code: 'channel-value-1',
  379. translations: [{ languageCode: LanguageCode.en, name: 'Channel Value 1' }],
  380. },
  381. {
  382. code: 'channel-value-2',
  383. translations: [{ languageCode: LanguageCode.en, name: 'Channel Value 2' }],
  384. },
  385. ],
  386. },
  387. },
  388. );
  389. expect(createFacet.code).toBe('channel-facet');
  390. createdFacet = createFacet;
  391. });
  392. it('facets list in channel', async () => {
  393. const result = await adminClient.query<GetFacetList.Query>(GET_FACET_LIST);
  394. const { items } = result.facets;
  395. expect(items.length).toBe(1);
  396. expect(items.map(i => i.code)).toEqual(['channel-facet']);
  397. });
  398. it('Product.facetValues in channel', async () => {
  399. adminClient.setChannelToken(E2E_DEFAULT_CHANNEL_TOKEN);
  400. await adminClient.query<UpdateProduct.Mutation, UpdateProduct.Variables>(UPDATE_PRODUCT, {
  401. input: {
  402. id: 'T_1',
  403. facetValueIds: [brandFacet.values[0].id, ...createdFacet.values.map(v => v.id)],
  404. },
  405. });
  406. await adminClient.query<UpdateProductVariants.Mutation, UpdateProductVariants.Variables>(
  407. UPDATE_PRODUCT_VARIANTS,
  408. {
  409. input: [
  410. {
  411. id: 'T_1',
  412. facetValueIds: [brandFacet.values[0].id, ...createdFacet.values.map(v => v.id)],
  413. },
  414. ],
  415. },
  416. );
  417. adminClient.setChannelToken(SECOND_CHANNEL_TOKEN);
  418. const { product } = await adminClient.query<
  419. GetProductWithVariants.Query,
  420. GetProductWithVariants.Variables
  421. >(GET_PRODUCT_WITH_VARIANTS, {
  422. id: 'T_1',
  423. });
  424. expect(product?.facetValues.map(fv => fv.code).sort()).toEqual([
  425. 'channel-value-1',
  426. 'channel-value-2',
  427. ]);
  428. });
  429. it('ProductVariant.facetValues in channel', async () => {
  430. const { product } = await adminClient.query<
  431. GetProductWithVariants.Query,
  432. GetProductWithVariants.Variables
  433. >(GET_PRODUCT_WITH_VARIANTS, {
  434. id: 'T_1',
  435. });
  436. expect(product?.variants[0].facetValues.map(fv => fv.code).sort()).toEqual([
  437. 'channel-value-1',
  438. 'channel-value-2',
  439. ]);
  440. });
  441. it('updating Product facetValuesIds in channel only affects that channel', async () => {
  442. adminClient.setChannelToken(SECOND_CHANNEL_TOKEN);
  443. await adminClient.query<UpdateProduct.Mutation, UpdateProduct.Variables>(UPDATE_PRODUCT, {
  444. input: {
  445. id: 'T_1',
  446. facetValueIds: [createdFacet.values[0].id],
  447. },
  448. });
  449. const { product: productC2 } = await adminClient.query<
  450. GetProductWithVariants.Query,
  451. GetProductWithVariants.Variables
  452. >(GET_PRODUCT_WITH_VARIANTS, {
  453. id: 'T_1',
  454. });
  455. expect(productC2?.facetValues.map(fv => fv.code)).toEqual([createdFacet.values[0].code]);
  456. adminClient.setChannelToken(E2E_DEFAULT_CHANNEL_TOKEN);
  457. const { product: productCD } = await adminClient.query<
  458. GetProductWithVariants.Query,
  459. GetProductWithVariants.Variables
  460. >(GET_PRODUCT_WITH_VARIANTS, {
  461. id: 'T_1',
  462. });
  463. expect(productCD?.facetValues.map(fv => fv.code)).toEqual([
  464. brandFacet.values[0].code,
  465. createdFacet.values[0].code,
  466. ]);
  467. });
  468. it('updating ProductVariant facetValuesIds in channel only affects that channel', async () => {
  469. adminClient.setChannelToken(SECOND_CHANNEL_TOKEN);
  470. await adminClient.query<UpdateProductVariants.Mutation, UpdateProductVariants.Variables>(
  471. UPDATE_PRODUCT_VARIANTS,
  472. {
  473. input: [
  474. {
  475. id: 'T_1',
  476. facetValueIds: [createdFacet.values[0].id],
  477. },
  478. ],
  479. },
  480. );
  481. const { product: productC2 } = await adminClient.query<
  482. GetProductWithVariants.Query,
  483. GetProductWithVariants.Variables
  484. >(GET_PRODUCT_WITH_VARIANTS, {
  485. id: 'T_1',
  486. });
  487. expect(productC2?.variants.find(v => v.id === 'T_1')?.facetValues.map(fv => fv.code)).toEqual([
  488. createdFacet.values[0].code,
  489. ]);
  490. adminClient.setChannelToken(E2E_DEFAULT_CHANNEL_TOKEN);
  491. const { product: productCD } = await adminClient.query<
  492. GetProductWithVariants.Query,
  493. GetProductWithVariants.Variables
  494. >(GET_PRODUCT_WITH_VARIANTS, {
  495. id: 'T_1',
  496. });
  497. expect(productCD?.variants.find(v => v.id === 'T_1')?.facetValues.map(fv => fv.code)).toEqual([
  498. brandFacet.values[0].code,
  499. createdFacet.values[0].code,
  500. ]);
  501. });
  502. it(
  503. 'attempting to create FacetValue in Facet from another Channel throws',
  504. assertThrowsWithMessage(async () => {
  505. adminClient.setChannelToken(SECOND_CHANNEL_TOKEN);
  506. await adminClient.query<CreateFacetValues.Mutation, CreateFacetValues.Variables>(
  507. CREATE_FACET_VALUES,
  508. {
  509. input: [
  510. {
  511. facetId: brandFacet.id,
  512. code: 'channel-brand',
  513. translations: [{ languageCode: LanguageCode.en, name: 'Channel Brand' }],
  514. },
  515. ],
  516. },
  517. );
  518. }, `No Facet with the id '1' could be found`),
  519. );
  520. });
  521. // https://github.com/vendure-ecommerce/vendure/issues/715
  522. describe('code conflicts', () => {
  523. function createFacetWithCode(code: string) {
  524. return adminClient.query<CreateFacet.Mutation, CreateFacet.Variables>(CREATE_FACET, {
  525. input: {
  526. isPrivate: false,
  527. code,
  528. translations: [{ languageCode: LanguageCode.en, name: `Test Facet (${code})` }],
  529. values: [],
  530. },
  531. });
  532. }
  533. // https://github.com/vendure-ecommerce/vendure/issues/831
  534. it('updateFacet with unchanged code', async () => {
  535. const { createFacet } = await createFacetWithCode('some-new-facet');
  536. const result = await adminClient.query<UpdateFacet.Mutation, UpdateFacet.Variables>(
  537. UPDATE_FACET,
  538. {
  539. input: {
  540. id: createFacet.id,
  541. code: createFacet.code,
  542. },
  543. },
  544. );
  545. expect(result.updateFacet.code).toBe(createFacet.code);
  546. });
  547. it('createFacet with conflicting slug gets renamed', async () => {
  548. const { createFacet: result1 } = await createFacetWithCode('test');
  549. expect(result1.code).toBe('test');
  550. const { createFacet: result2 } = await createFacetWithCode('test');
  551. expect(result2.code).toBe('test-2');
  552. });
  553. it('updateFacet with conflicting slug gets renamed', async () => {
  554. const { createFacet } = await createFacetWithCode('foo');
  555. expect(createFacet.code).toBe('foo');
  556. const { updateFacet } = await adminClient.query<UpdateFacet.Mutation, UpdateFacet.Variables>(
  557. UPDATE_FACET,
  558. {
  559. input: {
  560. id: createFacet.id,
  561. code: 'test-2',
  562. },
  563. },
  564. );
  565. expect(updateFacet.code).toBe('test-3');
  566. });
  567. });
  568. });
  569. export const GET_FACET_WITH_VALUES = gql`
  570. query GetFacetWithValues($id: ID!) {
  571. facet(id: $id) {
  572. ...FacetWithValues
  573. }
  574. }
  575. ${FACET_WITH_VALUES_FRAGMENT}
  576. `;
  577. const DELETE_FACET_VALUES = gql`
  578. mutation DeleteFacetValues($ids: [ID!]!, $force: Boolean) {
  579. deleteFacetValues(ids: $ids, force: $force) {
  580. result
  581. message
  582. }
  583. }
  584. `;
  585. const DELETE_FACET = gql`
  586. mutation DeleteFacet($id: ID!, $force: Boolean) {
  587. deleteFacet(id: $id, force: $force) {
  588. result
  589. message
  590. }
  591. }
  592. `;
  593. const GET_PRODUCTS_LIST_WITH_VARIANTS = gql`
  594. query GetProductListWithVariants {
  595. products {
  596. items {
  597. id
  598. name
  599. variants {
  600. id
  601. name
  602. }
  603. }
  604. totalItems
  605. }
  606. }
  607. `;
  608. export const CREATE_FACET_VALUES = gql`
  609. mutation CreateFacetValues($input: [CreateFacetValueInput!]!) {
  610. createFacetValues(input: $input) {
  611. ...FacetValue
  612. }
  613. }
  614. ${FACET_VALUE_FRAGMENT}
  615. `;
  616. export const UPDATE_FACET_VALUES = gql`
  617. mutation UpdateFacetValues($input: [UpdateFacetValueInput!]!) {
  618. updateFacetValues(input: $input) {
  619. ...FacetValue
  620. }
  621. }
  622. ${FACET_VALUE_FRAGMENT}
  623. `;