collection.e2e-spec.ts 11 KB

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