facet.e2e-spec.ts 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. import gql from 'graphql-tag';
  2. import path from 'path';
  3. import { TEST_SETUP_TIMEOUT_MS } from './config/test-config';
  4. import { FACET_VALUE_FRAGMENT, FACET_WITH_VALUES_FRAGMENT } from './graphql/fragments';
  5. import {
  6. CreateFacet,
  7. CreateFacetValues,
  8. DeleteFacet,
  9. DeleteFacetValues,
  10. DeletionResult,
  11. FacetWithValues,
  12. GetFacetList,
  13. GetFacetWithValues,
  14. GetProductListWithVariants,
  15. GetProductWithVariants,
  16. LanguageCode,
  17. UpdateFacet,
  18. UpdateFacetValues,
  19. UpdateProduct,
  20. UpdateProductVariants,
  21. } from './graphql/generated-e2e-admin-types';
  22. import {
  23. CREATE_FACET,
  24. GET_FACET_LIST,
  25. GET_PRODUCT_WITH_VARIANTS,
  26. UPDATE_FACET,
  27. UPDATE_PRODUCT,
  28. UPDATE_PRODUCT_VARIANTS,
  29. } from './graphql/shared-definitions';
  30. import { TestAdminClient } from './test-client';
  31. import { TestServer } from './test-server';
  32. // tslint:disable:no-non-null-assertion
  33. describe('Facet resolver', () => {
  34. const client = new TestAdminClient();
  35. const server = new TestServer();
  36. let brandFacet: FacetWithValues.Fragment;
  37. let speakerTypeFacet: FacetWithValues.Fragment;
  38. beforeAll(async () => {
  39. await server.init({
  40. productsCsvPath: path.join(__dirname, 'fixtures/e2e-products-full.csv'),
  41. customerCount: 1,
  42. });
  43. await client.init();
  44. }, TEST_SETUP_TIMEOUT_MS);
  45. afterAll(async () => {
  46. await server.destroy();
  47. });
  48. it('createFacet', async () => {
  49. const result = await client.query<CreateFacet.Mutation, CreateFacet.Variables>(CREATE_FACET, {
  50. input: {
  51. isPrivate: false,
  52. code: 'speaker-type',
  53. translations: [{ languageCode: LanguageCode.en, name: 'Speaker Type' }],
  54. values: [
  55. {
  56. code: 'portable',
  57. translations: [{ languageCode: LanguageCode.en, name: 'Portable' }],
  58. },
  59. ],
  60. },
  61. });
  62. speakerTypeFacet = result.createFacet;
  63. expect(speakerTypeFacet).toMatchSnapshot();
  64. });
  65. it('updateFacet', async () => {
  66. const result = await client.query<UpdateFacet.Mutation, UpdateFacet.Variables>(UPDATE_FACET, {
  67. input: {
  68. id: speakerTypeFacet.id,
  69. translations: [{ languageCode: LanguageCode.en, name: 'Speaker Category' }],
  70. },
  71. });
  72. expect(result.updateFacet.name).toBe('Speaker Category');
  73. });
  74. it('createFacetValues', async () => {
  75. const result = await client.query<CreateFacetValues.Mutation, CreateFacetValues.Variables>(
  76. CREATE_FACET_VALUES,
  77. {
  78. input: [
  79. {
  80. facetId: speakerTypeFacet.id,
  81. code: 'pc',
  82. translations: [{ languageCode: LanguageCode.en, name: 'PC Speakers' }],
  83. },
  84. {
  85. facetId: speakerTypeFacet.id,
  86. code: 'hi-fi',
  87. translations: [{ languageCode: LanguageCode.en, name: 'Hi Fi Speakers' }],
  88. },
  89. ],
  90. },
  91. );
  92. expect(result.createFacetValues).toMatchSnapshot();
  93. });
  94. it('updateFacetValues', async () => {
  95. const result = await client.query<UpdateFacetValues.Mutation, UpdateFacetValues.Variables>(
  96. UPDATE_FACET_VALUES,
  97. {
  98. input: [
  99. {
  100. id: speakerTypeFacet.values[0].id,
  101. code: 'compact',
  102. },
  103. ],
  104. },
  105. );
  106. expect(result.updateFacetValues[0].code).toBe('compact');
  107. });
  108. it('facets', async () => {
  109. const result = await client.query<GetFacetList.Query>(GET_FACET_LIST);
  110. const { items } = result.facets;
  111. expect(items.length).toBe(2);
  112. expect(items[0].name).toBe('category');
  113. expect(items[1].name).toBe('Speaker Category');
  114. brandFacet = items[0];
  115. speakerTypeFacet = items[1];
  116. });
  117. it('facet', async () => {
  118. const result = await client.query<GetFacetWithValues.Query, GetFacetWithValues.Variables>(
  119. GET_FACET_WITH_VALUES,
  120. {
  121. id: speakerTypeFacet.id,
  122. },
  123. );
  124. expect(result.facet!.name).toBe('Speaker Category');
  125. });
  126. describe('deletion', () => {
  127. let products: GetProductListWithVariants.Items[];
  128. beforeAll(async () => {
  129. // add the FacetValues to products and variants
  130. const result1 = await client.query<GetProductListWithVariants.Query>(
  131. GET_PRODUCTS_LIST_WITH_VARIANTS,
  132. );
  133. products = result1.products.items;
  134. await client.query<UpdateProduct.Mutation, UpdateProduct.Variables>(UPDATE_PRODUCT, {
  135. input: {
  136. id: products[0].id,
  137. facetValueIds: [speakerTypeFacet.values[0].id],
  138. },
  139. });
  140. await client.query<UpdateProductVariants.Mutation, UpdateProductVariants.Variables>(
  141. UPDATE_PRODUCT_VARIANTS,
  142. {
  143. input: [
  144. {
  145. id: products[0].variants[0].id,
  146. facetValueIds: [speakerTypeFacet.values[0].id],
  147. },
  148. ],
  149. },
  150. );
  151. await client.query<UpdateProduct.Mutation, UpdateProduct.Variables>(UPDATE_PRODUCT, {
  152. input: {
  153. id: products[1].id,
  154. facetValueIds: [speakerTypeFacet.values[1].id],
  155. },
  156. });
  157. });
  158. it('deleteFacetValues deletes unused facetValue', async () => {
  159. const facetValueToDelete = speakerTypeFacet.values[2];
  160. const result1 = await client.query<DeleteFacetValues.Mutation, DeleteFacetValues.Variables>(
  161. DELETE_FACET_VALUES,
  162. {
  163. ids: [facetValueToDelete.id],
  164. force: false,
  165. },
  166. );
  167. const result2 = await client.query<GetFacetWithValues.Query, GetFacetWithValues.Variables>(
  168. GET_FACET_WITH_VALUES,
  169. {
  170. id: speakerTypeFacet.id,
  171. },
  172. );
  173. expect(result1.deleteFacetValues).toEqual([
  174. {
  175. result: DeletionResult.DELETED,
  176. message: ``,
  177. },
  178. ]);
  179. expect(result2.facet!.values[0]).not.toEqual(facetValueToDelete);
  180. });
  181. it('deleteFacetValues for FacetValue in use returns NOT_DELETED', async () => {
  182. const facetValueToDelete = speakerTypeFacet.values[0];
  183. const result1 = await client.query<DeleteFacetValues.Mutation, DeleteFacetValues.Variables>(
  184. DELETE_FACET_VALUES,
  185. {
  186. ids: [facetValueToDelete.id],
  187. force: false,
  188. },
  189. );
  190. const result2 = await client.query<GetFacetWithValues.Query, GetFacetWithValues.Variables>(
  191. GET_FACET_WITH_VALUES,
  192. {
  193. id: speakerTypeFacet.id,
  194. },
  195. );
  196. expect(result1.deleteFacetValues).toEqual([
  197. {
  198. result: DeletionResult.NOT_DELETED,
  199. message: `The selected FacetValue is assigned to 1 Product, 1 ProductVariant`,
  200. },
  201. ]);
  202. expect(result2.facet!.values[0]).toEqual(facetValueToDelete);
  203. });
  204. it('deleteFacetValues for FacetValue in use can be force deleted', async () => {
  205. const facetValueToDelete = speakerTypeFacet.values[0];
  206. const result1 = await client.query<DeleteFacetValues.Mutation, DeleteFacetValues.Variables>(
  207. DELETE_FACET_VALUES,
  208. {
  209. ids: [facetValueToDelete.id],
  210. force: true,
  211. },
  212. );
  213. expect(result1.deleteFacetValues).toEqual([
  214. {
  215. result: DeletionResult.DELETED,
  216. message: `The selected FacetValue was removed from 1 Product, 1 ProductVariant and deleted`,
  217. },
  218. ]);
  219. // FacetValue no longer in the Facet.values array
  220. const result2 = await client.query<GetFacetWithValues.Query, GetFacetWithValues.Variables>(
  221. GET_FACET_WITH_VALUES,
  222. {
  223. id: speakerTypeFacet.id,
  224. },
  225. );
  226. expect(result2.facet!.values[0]).not.toEqual(facetValueToDelete);
  227. // FacetValue no longer in the Product.facetValues array
  228. const result3 = await client.query<
  229. GetProductWithVariants.Query,
  230. GetProductWithVariants.Variables
  231. >(GET_PRODUCT_WITH_VARIANTS, {
  232. id: products[0].id,
  233. });
  234. expect(result3.product!.facetValues).toEqual([]);
  235. });
  236. it('deleteFacet that is in use returns NOT_DELETED', async () => {
  237. const result1 = await client.query<DeleteFacet.Mutation, DeleteFacet.Variables>(DELETE_FACET, { id: speakerTypeFacet.id, force: false });
  238. const result2 = await client.query<GetFacetWithValues.Query, GetFacetWithValues.Variables>(
  239. GET_FACET_WITH_VALUES,
  240. {
  241. id: speakerTypeFacet.id,
  242. },
  243. );
  244. expect(result1.deleteFacet).toEqual({
  245. result: DeletionResult.NOT_DELETED,
  246. message: `The selected Facet includes FacetValues which are assigned to 1 Product`,
  247. });
  248. expect(result2.facet).not.toBe(null);
  249. });
  250. it('deleteFacet that is in use can be force deleted', async () => {
  251. const result1 = await client.query<DeleteFacet.Mutation, DeleteFacet.Variables>(DELETE_FACET, { id: speakerTypeFacet.id, force: true });
  252. expect(result1.deleteFacet).toEqual({
  253. result: DeletionResult.DELETED,
  254. message: `The Facet was deleted and its FacetValues were removed from 1 Product`,
  255. });
  256. // FacetValue no longer in the Facet.values array
  257. const result2 = await client.query<GetFacetWithValues.Query, GetFacetWithValues.Variables>(
  258. GET_FACET_WITH_VALUES,
  259. {
  260. id: speakerTypeFacet.id,
  261. },
  262. );
  263. expect(result2.facet).toBe(null);
  264. // FacetValue no longer in the Product.facetValues array
  265. const result3 = await client.query<
  266. GetProductWithVariants.Query,
  267. GetProductWithVariants.Variables
  268. >(GET_PRODUCT_WITH_VARIANTS, {
  269. id: products[1].id,
  270. });
  271. expect(result3.product!.facetValues).toEqual([]);
  272. });
  273. });
  274. });
  275. export const GET_FACET_WITH_VALUES = gql`
  276. query GetFacetWithValues($id: ID!, $languageCode: LanguageCode) {
  277. facet(id: $id, languageCode: $languageCode) {
  278. ...FacetWithValues
  279. }
  280. }
  281. ${FACET_WITH_VALUES_FRAGMENT}
  282. `;
  283. const DELETE_FACET_VALUES = gql`
  284. mutation DeleteFacetValues($ids: [ID!]!, $force: Boolean) {
  285. deleteFacetValues(ids: $ids, force: $force) {
  286. result
  287. message
  288. }
  289. }
  290. `;
  291. const DELETE_FACET = gql`
  292. mutation DeleteFacet($id: ID!, $force: Boolean) {
  293. deleteFacet(id: $id, force: $force) {
  294. result
  295. message
  296. }
  297. }
  298. `;
  299. const GET_PRODUCTS_LIST_WITH_VARIANTS = gql`
  300. query GetProductListWithVariants {
  301. products {
  302. items {
  303. id
  304. name
  305. variants {
  306. id
  307. name
  308. }
  309. }
  310. totalItems
  311. }
  312. }
  313. `;
  314. export const CREATE_FACET_VALUES = gql`
  315. mutation CreateFacetValues($input: [CreateFacetValueInput!]!) {
  316. createFacetValues(input: $input) {
  317. ...FacetValue
  318. }
  319. }
  320. ${FACET_VALUE_FRAGMENT}
  321. `;
  322. export const UPDATE_FACET_VALUES = gql`
  323. mutation UpdateFacetValues($input: [UpdateFacetValueInput!]!) {
  324. updateFacetValues(input: $input) {
  325. ...FacetValue
  326. }
  327. }
  328. ${FACET_VALUE_FRAGMENT}
  329. `;