facet.e2e-spec.ts 25 KB

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