e2e-helpers.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. import { Client } from '@elastic/elasticsearch';
  2. import { SortOrder } from '@vendure/common/lib/generated-types';
  3. import { SimpleGraphQLClient } from '@vendure/testing';
  4. import { expect } from 'vitest';
  5. import { SearchGetPricesQuery, SearchInput } from '../../core/e2e/graphql/generated-e2e-admin-types';
  6. import {
  7. LogicalOperator,
  8. SearchProductsShopQuery,
  9. SearchProductsShopQueryVariables,
  10. } from '../../core/e2e/graphql/generated-e2e-shop-types';
  11. import { SEARCH_PRODUCTS_SHOP } from '../../core/e2e/graphql/shop-definitions';
  12. import { deleteIndices } from '../src/indexing/indexing-utils';
  13. import { SEARCH_GET_PRICES, SEARCH_PRODUCTS } from './elasticsearch-plugin.e2e-spec';
  14. import {
  15. SearchGetPricesQueryVariables,
  16. SearchProductsAdminQuery,
  17. SearchProductsAdminQueryVariables,
  18. } from './graphql/generated-e2e-elasticsearch-plugin-types';
  19. // eslint-disable-next-line @typescript-eslint/no-var-requires
  20. const { elasticsearchHost, elasticsearchPort } = require('./constants');
  21. export function doAdminSearchQuery(client: SimpleGraphQLClient, input: SearchInput) {
  22. return client.query<SearchProductsAdminQuery, SearchProductsAdminQueryVariables>(SEARCH_PRODUCTS, {
  23. input,
  24. });
  25. }
  26. export async function testGroupByProduct(client: SimpleGraphQLClient) {
  27. const result = await client.query<SearchProductsShopQuery, SearchProductsShopQueryVariables>(
  28. SEARCH_PRODUCTS_SHOP,
  29. {
  30. input: {
  31. groupByProduct: true,
  32. },
  33. },
  34. );
  35. expect(result.search.totalItems).toBe(21);
  36. }
  37. export async function testGroupBySKU(client: SimpleGraphQLClient) {
  38. const result = await client.query<SearchProductsShopQuery, SearchProductsShopQueryVariables>(
  39. SEARCH_PRODUCTS_SHOP,
  40. {
  41. input: {
  42. term: 'bonsai',
  43. groupBySKU: true,
  44. },
  45. },
  46. );
  47. expect(result.search.totalItems).toBe(1);
  48. }
  49. export async function testNoGrouping(client: SimpleGraphQLClient) {
  50. const result = await client.query<SearchProductsShopQuery, SearchProductsShopQueryVariables>(
  51. SEARCH_PRODUCTS_SHOP,
  52. {
  53. input: {
  54. groupByProduct: false,
  55. groupBySKU: false,
  56. },
  57. },
  58. );
  59. expect(result.search.totalItems).toBe(35);
  60. }
  61. export async function testMatchSearchTerm(client: SimpleGraphQLClient) {
  62. const result = await client.query<SearchProductsShopQuery, SearchProductsShopQueryVariables>(
  63. SEARCH_PRODUCTS_SHOP,
  64. {
  65. input: {
  66. term: 'camera',
  67. groupByProduct: true,
  68. },
  69. },
  70. );
  71. expect(result.search.items.map(i => i.productName)).toEqual([
  72. 'Camera Lens',
  73. 'Instant Camera',
  74. 'SLR Camera',
  75. ]);
  76. }
  77. export async function testMatchFacetIdsAnd(client: SimpleGraphQLClient) {
  78. const result = await client.query<SearchProductsShopQuery, SearchProductsShopQueryVariables>(
  79. SEARCH_PRODUCTS_SHOP,
  80. {
  81. input: {
  82. facetValueIds: ['T_1', 'T_2'],
  83. facetValueOperator: LogicalOperator.AND,
  84. groupByProduct: true,
  85. sort: {
  86. name: SortOrder.ASC,
  87. },
  88. },
  89. },
  90. );
  91. expect(result.search.items.map(i => i.productName)).toEqual([
  92. 'Clacky Keyboard',
  93. 'Curvy Monitor',
  94. 'Gaming PC',
  95. 'Hard Drive',
  96. 'Laptop',
  97. 'USB Cable',
  98. ]);
  99. }
  100. export async function testMatchFacetIdsOr(client: SimpleGraphQLClient) {
  101. const result = await client.query<SearchProductsShopQuery, SearchProductsShopQueryVariables>(
  102. SEARCH_PRODUCTS_SHOP,
  103. {
  104. input: {
  105. facetValueIds: ['T_1', 'T_5'],
  106. facetValueOperator: LogicalOperator.OR,
  107. groupByProduct: true,
  108. sort: {
  109. name: SortOrder.ASC,
  110. },
  111. take: 20,
  112. },
  113. },
  114. );
  115. expect(result.search.items.map(i => i.productName)).toEqual([
  116. 'Bonsai Tree',
  117. 'Bonsai Tree (Ch2)',
  118. 'Camera Lens',
  119. 'Clacky Keyboard',
  120. 'Curvy Monitor',
  121. 'Gaming PC',
  122. 'Hard Drive',
  123. 'Instant Camera',
  124. 'Laptop',
  125. 'Orchid',
  126. 'SLR Camera',
  127. 'Spiky Cactus',
  128. 'Tripod',
  129. 'USB Cable',
  130. ]);
  131. }
  132. export async function testMatchFacetValueFiltersAnd(client: SimpleGraphQLClient) {
  133. const result = await client.query<SearchProductsShopQuery, SearchProductsShopQueryVariables>(
  134. SEARCH_PRODUCTS_SHOP,
  135. {
  136. input: {
  137. groupByProduct: true,
  138. facetValueFilters: [{ and: 'T_1' }, { and: 'T_2' }],
  139. },
  140. },
  141. );
  142. expect(result.search.items.map(i => i.productName).sort()).toEqual(
  143. ['Laptop', 'Curvy Monitor', 'Gaming PC', 'Hard Drive', 'Clacky Keyboard', 'USB Cable'].sort(),
  144. );
  145. }
  146. export async function testMatchFacetValueFiltersOr(client: SimpleGraphQLClient) {
  147. const result = await client.query<SearchProductsShopQuery, SearchProductsShopQueryVariables>(
  148. SEARCH_PRODUCTS_SHOP,
  149. {
  150. input: {
  151. groupByProduct: true,
  152. facetValueFilters: [{ or: ['T_1', 'T_5'] }],
  153. sort: {
  154. name: SortOrder.ASC,
  155. },
  156. take: 20,
  157. },
  158. },
  159. );
  160. expect(result.search.items.map(i => i.productName).sort()).toEqual(
  161. [
  162. 'Bonsai Tree',
  163. 'Bonsai Tree (Ch2)',
  164. 'Camera Lens',
  165. 'Clacky Keyboard',
  166. 'Curvy Monitor',
  167. 'Gaming PC',
  168. 'Hard Drive',
  169. 'Instant Camera',
  170. 'Laptop',
  171. 'Orchid',
  172. 'SLR Camera',
  173. 'Spiky Cactus',
  174. 'Tripod',
  175. 'USB Cable',
  176. ].sort(),
  177. );
  178. }
  179. export async function testMatchFacetValueFiltersOrWithAnd(client: SimpleGraphQLClient) {
  180. const result = await client.query<SearchProductsShopQuery, SearchProductsShopQueryVariables>(
  181. SEARCH_PRODUCTS_SHOP,
  182. {
  183. input: {
  184. groupByProduct: true,
  185. facetValueFilters: [{ and: 'T_1' }, { or: ['T_2', 'T_3'] }],
  186. },
  187. },
  188. );
  189. expect(result.search.items.map(i => i.productName).sort()).toEqual(
  190. [
  191. 'Laptop',
  192. 'Curvy Monitor',
  193. 'Gaming PC',
  194. 'Hard Drive',
  195. 'Clacky Keyboard',
  196. 'USB Cable',
  197. 'Instant Camera',
  198. 'Camera Lens',
  199. 'Tripod',
  200. 'SLR Camera',
  201. ].sort(),
  202. );
  203. }
  204. export async function testMatchFacetValueFiltersWithFacetIdsOr(client: SimpleGraphQLClient) {
  205. const result = await client.query<SearchProductsShopQuery, SearchProductsShopQueryVariables>(
  206. SEARCH_PRODUCTS_SHOP,
  207. {
  208. input: {
  209. facetValueIds: ['T_2', 'T_3'],
  210. facetValueOperator: LogicalOperator.OR,
  211. facetValueFilters: [{ and: 'T_1' }],
  212. groupByProduct: true,
  213. },
  214. },
  215. );
  216. expect(result.search.items.map(i => i.productName).sort()).toEqual(
  217. [
  218. 'Laptop',
  219. 'Curvy Monitor',
  220. 'Gaming PC',
  221. 'Hard Drive',
  222. 'Clacky Keyboard',
  223. 'USB Cable',
  224. 'Instant Camera',
  225. 'Camera Lens',
  226. 'Tripod',
  227. 'SLR Camera',
  228. ].sort(),
  229. );
  230. }
  231. export async function testMatchFacetValueFiltersWithFacetIdsAnd(client: SimpleGraphQLClient) {
  232. const result = await client.query<SearchProductsShopQuery, SearchProductsShopQueryVariables>(
  233. SEARCH_PRODUCTS_SHOP,
  234. {
  235. input: {
  236. facetValueIds: ['T_1'],
  237. facetValueFilters: [{ and: 'T_3' }],
  238. facetValueOperator: LogicalOperator.AND,
  239. groupByProduct: true,
  240. },
  241. },
  242. );
  243. expect(result.search.items.map(i => i.productName).sort()).toEqual(
  244. ['Instant Camera', 'Camera Lens', 'Tripod', 'SLR Camera'].sort(),
  245. );
  246. }
  247. export async function testMatchCollectionId(client: SimpleGraphQLClient) {
  248. const result = await client.query<SearchProductsShopQuery, SearchProductsShopQueryVariables>(
  249. SEARCH_PRODUCTS_SHOP,
  250. {
  251. input: {
  252. collectionId: 'T_2',
  253. groupByProduct: true,
  254. },
  255. },
  256. );
  257. expect(result.search.items.map(i => i.productName).sort()).toEqual([
  258. 'Bonsai Tree',
  259. 'Bonsai Tree (Ch2)',
  260. 'Orchid',
  261. 'Spiky Cactus',
  262. ]);
  263. }
  264. export async function testMatchCollectionSlug(client: SimpleGraphQLClient) {
  265. const result = await client.query<SearchProductsShopQuery, SearchProductsShopQueryVariables>(
  266. SEARCH_PRODUCTS_SHOP,
  267. {
  268. input: {
  269. collectionSlug: 'plants',
  270. groupByProduct: true,
  271. },
  272. },
  273. );
  274. expect(result.search.items.map(i => i.productName).sort()).toEqual([
  275. 'Bonsai Tree',
  276. 'Bonsai Tree (Ch2)',
  277. 'Orchid',
  278. 'Spiky Cactus',
  279. ]);
  280. }
  281. export async function testSinglePrices(client: SimpleGraphQLClient) {
  282. const result = await client.query<SearchGetPricesQuery, SearchGetPricesQueryVariables>(
  283. SEARCH_GET_PRICES,
  284. {
  285. input: {
  286. groupByProduct: false,
  287. take: 3,
  288. sort: {
  289. price: SortOrder.ASC,
  290. },
  291. },
  292. },
  293. );
  294. expect(result.search.items).toEqual([
  295. {
  296. price: { value: 799 },
  297. priceWithTax: { value: 959 },
  298. },
  299. {
  300. price: { value: 1498 },
  301. priceWithTax: { value: 1798 },
  302. },
  303. {
  304. price: { value: 1550 },
  305. priceWithTax: { value: 1860 },
  306. },
  307. ]);
  308. }
  309. export async function testPriceRanges(client: SimpleGraphQLClient) {
  310. const result = await client.query<SearchGetPricesQuery, SearchGetPricesQueryVariables>(
  311. SEARCH_GET_PRICES,
  312. {
  313. input: {
  314. groupByProduct: true,
  315. take: 3,
  316. term: 'laptop',
  317. },
  318. },
  319. );
  320. expect(result.search.items).toEqual([
  321. {
  322. price: { min: 129900, max: 229900 },
  323. priceWithTax: { min: 155880, max: 275880 },
  324. },
  325. ]);
  326. }
  327. export async function dropElasticIndices(indexPrefix: string) {
  328. const esClient = new Client({
  329. node: `${elasticsearchHost as string}:${elasticsearchPort as string}`,
  330. });
  331. return deleteIndices(esClient, indexPrefix);
  332. }