collection.e2e-spec.ts 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. import gql from 'graphql-tag';
  2. import path from 'path';
  3. import {
  4. CREATE_COLLECTION,
  5. GET_ASSET_LIST,
  6. GET_COLLECTION,
  7. MOVE_COLLECTION,
  8. UPDATE_COLLECTION,
  9. } from '../../admin-ui/src/app/data/definitions/product-definitions';
  10. import {
  11. Collection,
  12. CreateCollection,
  13. GetAssetList,
  14. GetCollection,
  15. LanguageCode,
  16. MoveCollection,
  17. SortOrder,
  18. UpdateCollection,
  19. } from '../../shared/generated-types';
  20. import { ROOT_CATEGORY_NAME } from '../../shared/shared-constants';
  21. import { facetValueCollectionFilter } from '../src/config/collection/default-collection-filters';
  22. import { TEST_SETUP_TIMEOUT_MS } from './config/test-config';
  23. import { TestAdminClient } from './test-client';
  24. import { TestServer } from './test-server';
  25. import { assertThrowsWithMessage } from './test-utils';
  26. // TODO: test collection without filters has no ProductVariants
  27. describe('Collection resolver', () => {
  28. const client = new TestAdminClient();
  29. const server = new TestServer();
  30. let assets: GetAssetList.Items[];
  31. let electronicsCategory: Collection.Fragment;
  32. let computersCategory: Collection.Fragment;
  33. let appleCategory: Collection.Fragment;
  34. beforeAll(async () => {
  35. const token = await server.init({
  36. productsCsvPath: path.join(__dirname, 'fixtures/e2e-products-full.csv'),
  37. customerCount: 1,
  38. });
  39. await client.init();
  40. const assetsResult = await client.query<GetAssetList.Query, GetAssetList.Variables>(GET_ASSET_LIST, {
  41. options: {
  42. sort: {
  43. name: SortOrder.ASC,
  44. },
  45. },
  46. });
  47. assets = assetsResult.assets.items;
  48. }, TEST_SETUP_TIMEOUT_MS);
  49. afterAll(async () => {
  50. await server.destroy();
  51. });
  52. describe('createCollection', () => {
  53. it('creates a root collection', async () => {
  54. const result = await client.query<CreateCollection.Mutation, CreateCollection.Variables>(
  55. CREATE_COLLECTION,
  56. {
  57. input: {
  58. assetIds: [assets[0].id, assets[1].id],
  59. featuredAssetId: assets[1].id,
  60. filters: [
  61. {
  62. code: facetValueCollectionFilter.code,
  63. arguments: [{ name: 'facetValueIds', value: `["T_1"]` }],
  64. },
  65. ],
  66. translations: [
  67. { languageCode: LanguageCode.en, name: 'Electronics', description: '' },
  68. ],
  69. },
  70. },
  71. );
  72. electronicsCategory = result.createCollection;
  73. expect(electronicsCategory).toMatchSnapshot();
  74. expect(electronicsCategory.parent.name).toBe(ROOT_CATEGORY_NAME);
  75. });
  76. it('creates a nested category', async () => {
  77. const result = await client.query<CreateCollection.Mutation, CreateCollection.Variables>(
  78. CREATE_COLLECTION,
  79. {
  80. input: {
  81. parentId: electronicsCategory.id,
  82. translations: [{ languageCode: LanguageCode.en, name: 'Computers', description: '' }],
  83. filters: [
  84. {
  85. code: facetValueCollectionFilter.code,
  86. arguments: [{ name: 'facetValueIds', value: `["T_2"]` }],
  87. },
  88. ],
  89. },
  90. },
  91. );
  92. computersCategory = result.createCollection;
  93. expect(computersCategory.parent.name).toBe(electronicsCategory.name);
  94. });
  95. it('creates a 2nd level nested category', async () => {
  96. const result = await client.query<CreateCollection.Mutation, CreateCollection.Variables>(
  97. CREATE_COLLECTION,
  98. {
  99. input: {
  100. parentId: computersCategory.id,
  101. translations: [{ languageCode: LanguageCode.en, name: 'Apple', description: '' }],
  102. filters: [],
  103. },
  104. },
  105. );
  106. appleCategory = result.createCollection;
  107. expect(appleCategory.parent.name).toBe(computersCategory.name);
  108. });
  109. });
  110. it('collection query', async () => {
  111. const result = await client.query<GetCollection.Query, GetCollection.Variables>(GET_COLLECTION, {
  112. id: computersCategory.id,
  113. });
  114. if (!result.collection) {
  115. fail(`did not return the category`);
  116. return;
  117. }
  118. expect(result.collection.id).toBe(computersCategory.id);
  119. });
  120. it('updateCollection', async () => {
  121. const result = await client.query<UpdateCollection.Mutation, UpdateCollection.Variables>(
  122. UPDATE_COLLECTION,
  123. {
  124. input: {
  125. id: appleCategory.id,
  126. assetIds: [assets[1].id],
  127. featuredAssetId: assets[1].id,
  128. filters: [],
  129. translations: [{ languageCode: LanguageCode.en, description: 'Apple stuff ' }],
  130. },
  131. },
  132. );
  133. expect(result.updateCollection).toMatchSnapshot();
  134. });
  135. describe('moveCollection', () => {
  136. it('moves a category to a new parent', async () => {
  137. const result = await client.query<MoveCollection.Mutation, MoveCollection.Variables>(
  138. MOVE_COLLECTION,
  139. {
  140. input: {
  141. categoryId: appleCategory.id,
  142. parentId: electronicsCategory.id,
  143. index: 0,
  144. },
  145. },
  146. );
  147. expect(result.moveCollection.parent.id).toBe(electronicsCategory.id);
  148. const positions = await getChildrenOf(electronicsCategory.id);
  149. expect(positions.map(i => i.id)).toEqual([appleCategory.id, computersCategory.id]);
  150. });
  151. it('alters the position in the current parent', async () => {
  152. await client.query<MoveCollection.Mutation, MoveCollection.Variables>(MOVE_COLLECTION, {
  153. input: {
  154. categoryId: appleCategory.id,
  155. parentId: electronicsCategory.id,
  156. index: 1,
  157. },
  158. });
  159. const afterResult = await getChildrenOf(electronicsCategory.id);
  160. expect(afterResult.map(i => i.id)).toEqual([computersCategory.id, appleCategory.id]);
  161. });
  162. it('corrects an out-of-bounds negative index value', async () => {
  163. await client.query<MoveCollection.Mutation, MoveCollection.Variables>(MOVE_COLLECTION, {
  164. input: {
  165. categoryId: appleCategory.id,
  166. parentId: electronicsCategory.id,
  167. index: -3,
  168. },
  169. });
  170. const afterResult = await getChildrenOf(electronicsCategory.id);
  171. expect(afterResult.map(i => i.id)).toEqual([appleCategory.id, computersCategory.id]);
  172. });
  173. it('corrects an out-of-bounds positive index value', async () => {
  174. await client.query<MoveCollection.Mutation, MoveCollection.Variables>(MOVE_COLLECTION, {
  175. input: {
  176. categoryId: appleCategory.id,
  177. parentId: electronicsCategory.id,
  178. index: 10,
  179. },
  180. });
  181. const afterResult = await getChildrenOf(electronicsCategory.id);
  182. expect(afterResult.map(i => i.id)).toEqual([computersCategory.id, appleCategory.id]);
  183. });
  184. it(
  185. 'throws if attempting to move into self',
  186. assertThrowsWithMessage(
  187. () =>
  188. client.query<MoveCollection.Mutation, MoveCollection.Variables>(MOVE_COLLECTION, {
  189. input: {
  190. categoryId: appleCategory.id,
  191. parentId: appleCategory.id,
  192. index: 0,
  193. },
  194. }),
  195. `Cannot move a Collection into itself`,
  196. ),
  197. );
  198. it(
  199. 'throws if attempting to move into a decendant of self',
  200. assertThrowsWithMessage(
  201. () =>
  202. client.query<MoveCollection.Mutation, MoveCollection.Variables>(MOVE_COLLECTION, {
  203. input: {
  204. categoryId: appleCategory.id,
  205. parentId: appleCategory.id,
  206. index: 0,
  207. },
  208. }),
  209. `Cannot move a Collection into itself`,
  210. ),
  211. );
  212. async function getChildrenOf(parentId: string): Promise<Array<{ name: string; id: string }>> {
  213. const result = await client.query(GET_COLLECTIONS);
  214. return result.collections.items.filter(i => i.parent.id === parentId);
  215. }
  216. });
  217. /*describe('filters', () => {
  218. it('facetValue filter', async () => {
  219. const result = await client.query(GET_COLLECTION_PRODUCT_VARIANTS, { id: electronicsCategory.id });
  220. expect(result.collection.productVariants.items.map(i => i.name)).toEqual([
  221. '',
  222. ]);
  223. });
  224. });*/
  225. });
  226. const GET_COLLECTIONS = gql`
  227. query GetCollections {
  228. collections(languageCode: en) {
  229. items {
  230. id
  231. name
  232. position
  233. parent {
  234. id
  235. name
  236. }
  237. }
  238. }
  239. }
  240. `;
  241. const GET_COLLECTION_PRODUCT_VARIANTS = gql`
  242. query GetCollectionProducts($id: ID!) {
  243. collection(id: $id) {
  244. productVariants {
  245. items {
  246. id
  247. name
  248. facetValues {
  249. code
  250. }
  251. }
  252. }
  253. }
  254. }
  255. `;