From d5f781c77f9965cb146f081f70893465c4cf1372 Mon Sep 17 00:00:00 2001 From: RollingRidges Date: Sun, 19 Nov 2023 23:12:44 +0100 Subject: [PATCH] fix(core): Default search plugin query for non-default language fails --- .../search-strategy/search-strategy-common.ts | 8 ----- .../search-strategy/search-strategy-utils.ts | 34 ++++++++----------- .../graphql/shop/complete-order.graphql | 2 +- .../dev-server/load-testing/init-load-test.ts | 16 ++++++++- .../load-testing/load-test-config.ts | 2 +- .../dev-server/load-testing/run-load-test.ts | 4 +-- .../scripts/search-and-checkout.js | 10 +++--- .../load-testing/utils/api-request.js | 11 +++--- 8 files changed, 47 insertions(+), 40 deletions(-) diff --git a/packages/core/src/plugin/default-search-plugin/search-strategy/search-strategy-common.ts b/packages/core/src/plugin/default-search-plugin/search-strategy/search-strategy-common.ts index 053190aa6d..0f8eac82b8 100644 --- a/packages/core/src/plugin/default-search-plugin/search-strategy/search-strategy-common.ts +++ b/packages/core/src/plugin/default-search-plugin/search-strategy/search-strategy-common.ts @@ -22,14 +22,6 @@ export const fieldsToSelect = [ 'productVariantPreviewFocalPoint', ]; -export const identifierFields = [ - 'channelId', - 'productVariantId', - 'productId', - 'productAssetId', - 'productVariantAssetId', -]; - export function getFieldsToSelect(includeStockStatus: boolean = false) { return includeStockStatus ? [...fieldsToSelect, 'inStock', 'productInStock'] : fieldsToSelect; } diff --git a/packages/core/src/plugin/default-search-plugin/search-strategy/search-strategy-utils.ts b/packages/core/src/plugin/default-search-plugin/search-strategy/search-strategy-utils.ts index 0014cce6c4..1a2fb6530a 100644 --- a/packages/core/src/plugin/default-search-plugin/search-strategy/search-strategy-utils.ts +++ b/packages/core/src/plugin/default-search-plugin/search-strategy/search-strategy-utils.ts @@ -139,28 +139,24 @@ export function applyLanguageConstraints( languageCode, }); } else { - const count = qb - .subQuery() - .select('COUNT(*) as countLanguageCode') - .from(SearchIndexItem, 'sil') - .where(`sil.${ciEscaped} = si.${ciEscaped}`) - .andWhere(`sil.${pviEscaped} = si.${pviEscaped}`) - .andWhere(`sil.${lcEscaped} = :countLanguageCode`) - .getQuery(); + qb.andWhere(`si.${lcEscaped} IN (:...languageCodes)`, { + languageCodes: [languageCode, defaultLanguageCode], + }); + + qb.leftJoin( + SearchIndexItem, + 'sil', + `sil.${lcEscaped} = :languageCode AND sil.${ciEscaped} = si.${ciEscaped} AND sil.${pviEscaped} = si.${pviEscaped}`, + { + languageCode, + }, + ); qb.andWhere( new Brackets(qb1 => { - qb1.where(`si.${lcEscaped} = :languageCode`, { - languageCode, - }).orWhere( - new Brackets(qb2 => { - qb2.where(`si.${lcEscaped} = :defaultLanguageCode`, { - defaultLanguageCode, - }).andWhere(`NOT(1 IN (${count}))`, { - countLanguageCode: languageCode, - }); - }), - ); + qb1.where(`si.${lcEscaped} = :languageCode1`, { + languageCode1: languageCode, + }).orWhere(`sil.${lcEscaped} IS NULL`); }), ); } diff --git a/packages/dev-server/load-testing/graphql/shop/complete-order.graphql b/packages/dev-server/load-testing/graphql/shop/complete-order.graphql index d0a24ba4ce..959185f0aa 100644 --- a/packages/dev-server/load-testing/graphql/shop/complete-order.graphql +++ b/packages/dev-server/load-testing/graphql/shop/complete-order.graphql @@ -1,4 +1,4 @@ -mutation SetShippingMethod($id: ID!) { +mutation SetShippingMethod($id: [ID!]!) { setOrderShippingMethod(shippingMethodId: $id) { ...on Order { code diff --git a/packages/dev-server/load-testing/init-load-test.ts b/packages/dev-server/load-testing/init-load-test.ts index 4526ab996c..48f96b3fce 100644 --- a/packages/dev-server/load-testing/init-load-test.ts +++ b/packages/dev-server/load-testing/init-load-test.ts @@ -2,7 +2,7 @@ /// import { bootstrap, JobQueueService, Logger } from '@vendure/core'; import { populate } from '@vendure/core/cli/populate'; -import { clearAllTables, populateCustomers } from '@vendure/testing'; +import { clearAllTables, populateCustomers, SimpleGraphQLClient } from '@vendure/testing'; import stringify from 'csv-stringify'; import fs from 'fs'; import path from 'path'; @@ -17,6 +17,8 @@ import { getProductCsvFilePath, } from './load-test-config'; +import { awaitRunningJobs } from '../../core/e2e/utils/await-running-jobs'; + /* eslint-disable no-console */ /** @@ -49,6 +51,18 @@ if (require.main === module) { csvFile, ), ) + .then(async app => { + console.log('synchronize on search index updated...'); + const { port, adminApiPath, shopApiPath } = config.apiOptions; + const adminClient = new SimpleGraphQLClient( + config, + `http://localhost:${port}/${adminApiPath!}`, + ); + await adminClient.asSuperAdmin(); + await new Promise(resolve => setTimeout(resolve, 5000)); + await awaitRunningJobs(adminClient, 5000000); + return app; + }) .then(async app => { console.log('populating customers...'); await populateCustomers(app, 10, message => Logger.error(message)); diff --git a/packages/dev-server/load-testing/load-test-config.ts b/packages/dev-server/load-testing/load-test-config.ts index bc4391017f..d574446e21 100644 --- a/packages/dev-server/load-testing/load-test-config.ts +++ b/packages/dev-server/load-testing/load-test-config.ts @@ -72,7 +72,7 @@ export function getLoadTestConfig( assetUploadDir: path.join(__dirname, 'static/assets'), route: 'assets', }), - DefaultSearchPlugin, + DefaultSearchPlugin.init({ bufferUpdates: false, indexStockStatus: false }), DefaultJobQueuePlugin.init({ pollInterval: 1000, }), diff --git a/packages/dev-server/load-testing/run-load-test.ts b/packages/dev-server/load-testing/run-load-test.ts index d008a88e27..4b062970a6 100644 --- a/packages/dev-server/load-testing/run-load-test.ts +++ b/packages/dev-server/load-testing/run-load-test.ts @@ -26,7 +26,7 @@ if (require.main === module) { stdio: 'inherit', }); - init.on('exit', code => { + init.on('exit', async code => { if (code === 0) { const databaseName = `vendure-load-testing-${count}`; return bootstrap(getLoadTestConfig('cookie', databaseName)) @@ -49,7 +49,7 @@ if (require.main === module) { }); } -function runLoadTestScript(script: string): Promise { +async function runLoadTestScript(script: string): Promise { const rawResultsFile = `${script}.${count}.json`; return new Promise((resolve, reject) => { diff --git a/packages/dev-server/load-testing/scripts/search-and-checkout.js b/packages/dev-server/load-testing/scripts/search-and-checkout.js index 467c6874f0..7a93814a8c 100644 --- a/packages/dev-server/load-testing/scripts/search-and-checkout.js +++ b/packages/dev-server/load-testing/scripts/search-and-checkout.js @@ -26,10 +26,12 @@ export default function () { addToCart(randomItem(product.variants).id); } setShippingAddressAndCustomer(); - const data = getShippingMethodsQuery.post().data; - const result = completeOrderMutation.post({ id: data.eligibleShippingMethods[0].id }).data; - check(result, { - 'Order completed': r => r.addPaymentToOrder.state === 'PaymentAuthorized', + const { data: shippingMethods } = getShippingMethodsQuery.post(); + const { data: order } = completeOrderMutation.post({ + id: [shippingMethods.eligibleShippingMethods.at(0).id], + }); + check(order, { + 'Order completed': o => o.addPaymentToOrder.state === 'PaymentAuthorized', }); } diff --git a/packages/dev-server/load-testing/utils/api-request.js b/packages/dev-server/load-testing/utils/api-request.js index 433e8e7e5f..3bd17cefbd 100644 --- a/packages/dev-server/load-testing/utils/api-request.js +++ b/packages/dev-server/load-testing/utils/api-request.js @@ -17,13 +17,16 @@ export class ApiRequest { post(variables = {}, authToken) { const res = http.post( this.apiUrl, - { + JSON.stringify({ query: this.document, - variables: JSON.stringify(variables), - }, + variables, + }), { timeout: 120 * 1000, - headers: { Authorization: authToken ? `Bearer ${authToken}` : undefined }, + headers: { + Authorization: authToken ? `Bearer ${authToken}` : '', + 'Content-Type': 'application/json', + }, }, ); check(res, {