From fb52ce1a953d330ad5977668cf36071aa0972b70 Mon Sep 17 00:00:00 2001 From: Alex Bradley Date: Sun, 5 Oct 2025 13:10:25 -0400 Subject: [PATCH 1/2] add wasm integration tests --- .github/workflows/validate-js-functions.yml | 2 +- .github/workflows/validate-ts-functions.yml | 2 +- .../package.json.liquid | 7 +- .../tests/default.test.js | 45 +++++++++++ .../tests/fixtures/log.json | 30 ++++++++ .../vitest.config.js | 1 + .../package.json.liquid | 13 ++++ .../tests/default.test.js | 45 +++++++++++ .../tests/fixtures/log.json | 30 ++++++++ .../package.json.liquid | 7 +- .../tests/default.test.js | 45 +++++++++++ .../tests/fixtures/log.json | 19 +++++ functions-cart-transform-js/vitest.config.js | 1 + .../package.json.liquid | 13 ++++ .../tests/default.test.js | 45 +++++++++++ .../tests/fixtures/log.json | 19 +++++ .../package.json.liquid | 7 +- .../tests/default.test.js | 45 +++++++++++ .../tests/fixtures/log.json | 16 ++++ .../vitest.config.js | 1 + .../package.json.liquid | 13 ++++ .../tests/default.test.js | 45 +++++++++++ .../tests/fixtures/log.json | 16 ++++ functions-discount-js/package.json.liquid | 7 +- functions-discount-js/tests/default.test.js | 45 +++++++++++ .../cart-lines-discount-generate-log.json | 72 ++++++++++++++++++ ...elivery-options-discount-generate-log.json | 44 +++++++++++ functions-discount-js/vitest.config.js | 1 + functions-discount-rs/package.json.liquid | 13 ++++ functions-discount-rs/tests/default.test.js | 45 +++++++++++ .../cart-lines-discount-generate-log.json | 76 +++++++++++++++++++ ...elivery-options-discount-generate-log.json | 45 +++++++++++ .../package.json.liquid | 11 ++- .../tests/default.test.js | 45 +++++++++++ .../tests/fixtures/log.json | 17 +++++ .../vitest.config.js | 1 + .../package.json.liquid | 13 ++++ .../tests/default.test.js | 45 +++++++++++ .../tests/fixtures/log.json | 17 +++++ .../package.json.liquid | 7 +- .../tests/default.test.js | 45 +++++++++++ .../tests/fixtures/log.json | 23 ++++++ .../vitest.config.js | 1 + .../package.json.liquid | 13 ++++ .../tests/default.test.js | 44 +++++++++++ .../tests/fixtures/log.json | 23 ++++++ .../package.json.liquid | 7 +- .../src/run.graphql.liquid | 2 +- .../tests/default.test.js | 44 +++++++++++ .../tests/fixtures/log.json | 57 ++++++++++++++ .../vitest.config.js | 1 + .../package.json.liquid | 13 ++++ .../src/run.graphql.liquid | 2 +- .../tests/default.test.js | 44 +++++++++++ .../tests/fixtures/log.json | 58 ++++++++++++++ functions-location-rules-js/notes.md | 7 ++ .../package.json.liquid | 7 +- .../tests/default.test.js | 44 +++++++++++ .../tests/fixtures/log.json | 17 +++++ functions-location-rules-js/vitest.config.js | 1 + functions-location-rules-rs/notes.md | 7 ++ .../package.json.liquid | 13 ++++ .../tests/default.test.js | 44 +++++++++++ .../tests/fixtures/log.json | 17 +++++ .../package.json.liquid | 7 +- .../tests/default.test.js | 44 +++++++++++ .../tests/fixtures/log.json | 17 +++++ functions-order-discounts-js/vitest.config.js | 1 + .../package.json.liquid | 13 ++++ .../tests/default.test.js | 44 +++++++++++ .../tests/fixtures/log.json | 17 +++++ .../package.json.liquid | 7 +- .../tests/default.test.js | 44 +++++++++++ .../tests/fixtures/log.json | 16 ++++ .../vitest.config.js | 1 + .../package.json.liquid | 13 ++++ .../tests/default.test.js | 44 +++++++++++ .../tests/fixtures/log.json | 16 ++++ .../package.json.liquid | 7 +- .../tests/default.test.js | 44 +++++++++++ .../tests/fixtures/log.json | 15 ++++ .../vitest.config.js | 1 + .../package.json.liquid | 13 ++++ .../tests/default.test.js | 44 +++++++++++ .../tests/fixtures/log.json | 15 ++++ .../package.json.liquid | 7 +- .../tests/default.test.js | 44 +++++++++++ .../tests/fixtures/log.json | 17 +++++ .../vitest.config.js | 1 + .../package.json.liquid | 13 ++++ .../tests/default.test.js | 44 +++++++++++ .../tests/fixtures/log.json | 17 +++++ .../package.json.liquid | 7 +- .../tests/default.test.js | 44 +++++++++++ .../tests/fixtures/log.json | 16 ++++ .../vitest.config.js | 1 + .../package.json.liquid | 13 ++++ .../tests/default.test.js | 44 +++++++++++ .../tests/fixtures/log.json | 16 ++++ package.json | 3 +- 100 files changed, 2182 insertions(+), 33 deletions(-) create mode 100644 functions-cart-checkout-validation-js/tests/default.test.js create mode 100644 functions-cart-checkout-validation-js/tests/fixtures/log.json create mode 100644 functions-cart-checkout-validation-js/vitest.config.js create mode 100644 functions-cart-checkout-validation-rs/package.json.liquid create mode 100644 functions-cart-checkout-validation-rs/tests/default.test.js create mode 100644 functions-cart-checkout-validation-rs/tests/fixtures/log.json create mode 100644 functions-cart-transform-js/tests/default.test.js create mode 100644 functions-cart-transform-js/tests/fixtures/log.json create mode 100644 functions-cart-transform-js/vitest.config.js create mode 100644 functions-cart-transform-rs/package.json.liquid create mode 100644 functions-cart-transform-rs/tests/default.test.js create mode 100644 functions-cart-transform-rs/tests/fixtures/log.json create mode 100644 functions-delivery-customization-js/tests/default.test.js create mode 100644 functions-delivery-customization-js/tests/fixtures/log.json create mode 100644 functions-delivery-customization-js/vitest.config.js create mode 100644 functions-delivery-customization-rs/package.json.liquid create mode 100644 functions-delivery-customization-rs/tests/default.test.js create mode 100644 functions-delivery-customization-rs/tests/fixtures/log.json create mode 100644 functions-discount-js/tests/default.test.js create mode 100644 functions-discount-js/tests/fixtures/cart-lines-discount-generate-log.json create mode 100644 functions-discount-js/tests/fixtures/delivery-options-discount-generate-log.json create mode 100644 functions-discount-js/vitest.config.js create mode 100644 functions-discount-rs/package.json.liquid create mode 100644 functions-discount-rs/tests/default.test.js create mode 100644 functions-discount-rs/tests/fixtures/cart-lines-discount-generate-log.json create mode 100644 functions-discount-rs/tests/fixtures/delivery-options-discount-generate-log.json create mode 100644 functions-discounts-allocator-js/tests/default.test.js create mode 100644 functions-discounts-allocator-js/tests/fixtures/log.json create mode 100644 functions-discounts-allocator-js/vitest.config.js create mode 100644 functions-discounts-allocator-rs/package.json.liquid create mode 100644 functions-discounts-allocator-rs/tests/default.test.js create mode 100644 functions-discounts-allocator-rs/tests/fixtures/log.json create mode 100644 functions-fulfillment-constraints-js/tests/default.test.js create mode 100644 functions-fulfillment-constraints-js/tests/fixtures/log.json create mode 100644 functions-fulfillment-constraints-js/vitest.config.js create mode 100644 functions-fulfillment-constraints-rs/package.json.liquid create mode 100644 functions-fulfillment-constraints-rs/tests/default.test.js create mode 100644 functions-fulfillment-constraints-rs/tests/fixtures/log.json create mode 100644 functions-local-pickup-delivery-option-generators-js/tests/default.test.js create mode 100644 functions-local-pickup-delivery-option-generators-js/tests/fixtures/log.json create mode 100644 functions-local-pickup-delivery-option-generators-js/vitest.config.js create mode 100644 functions-local-pickup-delivery-option-generators-rs/package.json.liquid create mode 100644 functions-local-pickup-delivery-option-generators-rs/tests/default.test.js create mode 100644 functions-local-pickup-delivery-option-generators-rs/tests/fixtures/log.json create mode 100644 functions-location-rules-js/notes.md create mode 100644 functions-location-rules-js/tests/default.test.js create mode 100644 functions-location-rules-js/tests/fixtures/log.json create mode 100644 functions-location-rules-js/vitest.config.js create mode 100644 functions-location-rules-rs/notes.md create mode 100644 functions-location-rules-rs/package.json.liquid create mode 100644 functions-location-rules-rs/tests/default.test.js create mode 100644 functions-location-rules-rs/tests/fixtures/log.json create mode 100644 functions-order-discounts-js/tests/default.test.js create mode 100644 functions-order-discounts-js/tests/fixtures/log.json create mode 100644 functions-order-discounts-js/vitest.config.js create mode 100644 functions-order-discounts-rs/package.json.liquid create mode 100644 functions-order-discounts-rs/tests/default.test.js create mode 100644 functions-order-discounts-rs/tests/fixtures/log.json create mode 100644 functions-payment-customization-js/tests/default.test.js create mode 100644 functions-payment-customization-js/tests/fixtures/log.json create mode 100644 functions-payment-customization-js/vitest.config.js create mode 100644 functions-payment-customization-rs/package.json.liquid create mode 100644 functions-payment-customization-rs/tests/default.test.js create mode 100644 functions-payment-customization-rs/tests/fixtures/log.json create mode 100644 functions-pickup-point-delivery-option-generators-js/tests/default.test.js create mode 100644 functions-pickup-point-delivery-option-generators-js/tests/fixtures/log.json create mode 100644 functions-pickup-point-delivery-option-generators-js/vitest.config.js create mode 100644 functions-pickup-point-delivery-option-generators-rs/package.json.liquid create mode 100644 functions-pickup-point-delivery-option-generators-rs/tests/default.test.js create mode 100644 functions-pickup-point-delivery-option-generators-rs/tests/fixtures/log.json create mode 100644 functions-product-discounts-js/tests/default.test.js create mode 100644 functions-product-discounts-js/tests/fixtures/log.json create mode 100644 functions-product-discounts-js/vitest.config.js create mode 100644 functions-product-discounts-rs/package.json.liquid create mode 100644 functions-product-discounts-rs/tests/default.test.js create mode 100644 functions-product-discounts-rs/tests/fixtures/log.json create mode 100644 functions-shipping-discounts-js/tests/default.test.js create mode 100644 functions-shipping-discounts-js/tests/fixtures/log.json create mode 100644 functions-shipping-discounts-js/vitest.config.js create mode 100644 functions-shipping-discounts-rs/package.json.liquid create mode 100644 functions-shipping-discounts-rs/tests/default.test.js create mode 100644 functions-shipping-discounts-rs/tests/fixtures/log.json diff --git a/.github/workflows/validate-js-functions.yml b/.github/workflows/validate-js-functions.yml index 059bc801..082d62cc 100644 --- a/.github/workflows/validate-js-functions.yml +++ b/.github/workflows/validate-js-functions.yml @@ -25,4 +25,4 @@ jobs: - name: Generate types run: yarn js-typegen - name: Test - run: yarn js-test + run: yarn js-test:unit diff --git a/.github/workflows/validate-ts-functions.yml b/.github/workflows/validate-ts-functions.yml index 8d362b10..61dfa36a 100644 --- a/.github/workflows/validate-ts-functions.yml +++ b/.github/workflows/validate-ts-functions.yml @@ -25,4 +25,4 @@ jobs: - name: Generate types run: yarn js-typegen - name: Test - run: yarn js-test + run: yarn js-test:unit diff --git a/functions-cart-checkout-validation-js/package.json.liquid b/functions-cart-checkout-validation-js/package.json.liquid index aa829248..b6d85ff2 100644 --- a/functions-cart-checkout-validation-js/package.json.liquid +++ b/functions-cart-checkout-validation-js/package.json.liquid @@ -2,12 +2,14 @@ "name": "{{handle}}", "version": "0.0.1", "license": "UNLICENSED", + "type": "module", "scripts": { "shopify": "npm exec -- shopify", "typegen": "npm exec -- shopify app function typegen", "build": "npm exec -- shopify app function build", "preview": "npm exec -- shopify app function run", - "test": "vitest" + "test": "vitest", + "test:unit": "vitest run src/" }, "codegen": { "schema": "schema.graphql", @@ -28,6 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "vitest": "2.1.9" + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" } } diff --git a/functions-cart-checkout-validation-js/tests/default.test.js b/functions-cart-checkout-validation-js/tests/default.test.js new file mode 100644 index 00000000..23221643 --- /dev/null +++ b/functions-cart-checkout-validation-js/tests/default.test.js @@ -0,0 +1,45 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs + .readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-cart-checkout-validation-js/tests/fixtures/log.json b/functions-cart-checkout-validation-js/tests/fixtures/log.json new file mode 100644 index 00000000..8519d8cd --- /dev/null +++ b/functions-cart-checkout-validation-js/tests/fixtures/log.json @@ -0,0 +1,30 @@ +{ + "payload": { + "export": "cart-validations-generate-run", + "target": "cart.validations.generate.run", + "input": { + "cart": { + "lines": [ + { + "quantity": 1 + }, + { + "quantity": 1 + }, + { + "quantity": 1 + } + ] + } + }, + "output": { + "operations": [ + { + "validationAdd": { + "errors": [] + } + } + ] + } + } +} diff --git a/functions-cart-checkout-validation-js/vitest.config.js b/functions-cart-checkout-validation-js/vitest.config.js new file mode 100644 index 00000000..ff8b4c56 --- /dev/null +++ b/functions-cart-checkout-validation-js/vitest.config.js @@ -0,0 +1 @@ +export default {}; diff --git a/functions-cart-checkout-validation-rs/package.json.liquid b/functions-cart-checkout-validation-rs/package.json.liquid new file mode 100644 index 00000000..98d6960c --- /dev/null +++ b/functions-cart-checkout-validation-rs/package.json.liquid @@ -0,0 +1,13 @@ +{ + "name": "{{handle}}", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": { + "test": "vitest run" + }, + "devDependencies": { + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" + } +} diff --git a/functions-cart-checkout-validation-rs/tests/default.test.js b/functions-cart-checkout-validation-rs/tests/default.test.js new file mode 100644 index 00000000..23221643 --- /dev/null +++ b/functions-cart-checkout-validation-rs/tests/default.test.js @@ -0,0 +1,45 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs + .readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-cart-checkout-validation-rs/tests/fixtures/log.json b/functions-cart-checkout-validation-rs/tests/fixtures/log.json new file mode 100644 index 00000000..45fff29e --- /dev/null +++ b/functions-cart-checkout-validation-rs/tests/fixtures/log.json @@ -0,0 +1,30 @@ +{ + "payload": { + "export": "cart_validations_generate_run", + "target": "cart.validations.generate.run", + "input": { + "cart": { + "lines": [ + { + "quantity": 1 + }, + { + "quantity": 1 + }, + { + "quantity": 1 + } + ] + } + }, + "output": { + "operations": [ + { + "validationAdd": { + "errors": [] + } + } + ] + } + } +} diff --git a/functions-cart-transform-js/package.json.liquid b/functions-cart-transform-js/package.json.liquid index aa829248..b6d85ff2 100644 --- a/functions-cart-transform-js/package.json.liquid +++ b/functions-cart-transform-js/package.json.liquid @@ -2,12 +2,14 @@ "name": "{{handle}}", "version": "0.0.1", "license": "UNLICENSED", + "type": "module", "scripts": { "shopify": "npm exec -- shopify", "typegen": "npm exec -- shopify app function typegen", "build": "npm exec -- shopify app function build", "preview": "npm exec -- shopify app function run", - "test": "vitest" + "test": "vitest", + "test:unit": "vitest run src/" }, "codegen": { "schema": "schema.graphql", @@ -28,6 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "vitest": "2.1.9" + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" } } diff --git a/functions-cart-transform-js/tests/default.test.js b/functions-cart-transform-js/tests/default.test.js new file mode 100644 index 00000000..23221643 --- /dev/null +++ b/functions-cart-transform-js/tests/default.test.js @@ -0,0 +1,45 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs + .readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-cart-transform-js/tests/fixtures/log.json b/functions-cart-transform-js/tests/fixtures/log.json new file mode 100644 index 00000000..e2b9aadc --- /dev/null +++ b/functions-cart-transform-js/tests/fixtures/log.json @@ -0,0 +1,19 @@ +{ + "payload": { + "export": "cart-transform-run", + "target": "cart.transform.run", + "input": { + "cart": { + "lines": [ + { + "id": "gid://shopify/CartLine/1", + "quantity": 1 + } + ] + } + }, + "output": { + "operations": [] + } + } +} diff --git a/functions-cart-transform-js/vitest.config.js b/functions-cart-transform-js/vitest.config.js new file mode 100644 index 00000000..ff8b4c56 --- /dev/null +++ b/functions-cart-transform-js/vitest.config.js @@ -0,0 +1 @@ +export default {}; diff --git a/functions-cart-transform-rs/package.json.liquid b/functions-cart-transform-rs/package.json.liquid new file mode 100644 index 00000000..98d6960c --- /dev/null +++ b/functions-cart-transform-rs/package.json.liquid @@ -0,0 +1,13 @@ +{ + "name": "{{handle}}", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": { + "test": "vitest run" + }, + "devDependencies": { + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" + } +} diff --git a/functions-cart-transform-rs/tests/default.test.js b/functions-cart-transform-rs/tests/default.test.js new file mode 100644 index 00000000..23221643 --- /dev/null +++ b/functions-cart-transform-rs/tests/default.test.js @@ -0,0 +1,45 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs + .readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-cart-transform-rs/tests/fixtures/log.json b/functions-cart-transform-rs/tests/fixtures/log.json new file mode 100644 index 00000000..fb42130f --- /dev/null +++ b/functions-cart-transform-rs/tests/fixtures/log.json @@ -0,0 +1,19 @@ +{ + "payload": { + "export": "cart_transform_run", + "target": "cart.transform.run", + "input": { + "cart": { + "lines": [ + { + "id": "gid://shopify/CartLine/1", + "quantity": 1 + } + ] + } + }, + "output": { + "operations": [] + } + } +} diff --git a/functions-delivery-customization-js/package.json.liquid b/functions-delivery-customization-js/package.json.liquid index aa829248..b6d85ff2 100644 --- a/functions-delivery-customization-js/package.json.liquid +++ b/functions-delivery-customization-js/package.json.liquid @@ -2,12 +2,14 @@ "name": "{{handle}}", "version": "0.0.1", "license": "UNLICENSED", + "type": "module", "scripts": { "shopify": "npm exec -- shopify", "typegen": "npm exec -- shopify app function typegen", "build": "npm exec -- shopify app function build", "preview": "npm exec -- shopify app function run", - "test": "vitest" + "test": "vitest", + "test:unit": "vitest run src/" }, "codegen": { "schema": "schema.graphql", @@ -28,6 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "vitest": "2.1.9" + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" } } diff --git a/functions-delivery-customization-js/tests/default.test.js b/functions-delivery-customization-js/tests/default.test.js new file mode 100644 index 00000000..23221643 --- /dev/null +++ b/functions-delivery-customization-js/tests/default.test.js @@ -0,0 +1,45 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs + .readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-delivery-customization-js/tests/fixtures/log.json b/functions-delivery-customization-js/tests/fixtures/log.json new file mode 100644 index 00000000..b060b1fc --- /dev/null +++ b/functions-delivery-customization-js/tests/fixtures/log.json @@ -0,0 +1,16 @@ +{ + "payload": { + "export": "cart-delivery-options-transform-run", + "target": "cart.delivery-options.transform.run", + "input": { + "deliveryCustomization": { + "metafield": { + "jsonValue": {} + } + } + }, + "output": { + "operations": [] + } + } +} diff --git a/functions-delivery-customization-js/vitest.config.js b/functions-delivery-customization-js/vitest.config.js new file mode 100644 index 00000000..ff8b4c56 --- /dev/null +++ b/functions-delivery-customization-js/vitest.config.js @@ -0,0 +1 @@ +export default {}; diff --git a/functions-delivery-customization-rs/package.json.liquid b/functions-delivery-customization-rs/package.json.liquid new file mode 100644 index 00000000..98d6960c --- /dev/null +++ b/functions-delivery-customization-rs/package.json.liquid @@ -0,0 +1,13 @@ +{ + "name": "{{handle}}", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": { + "test": "vitest run" + }, + "devDependencies": { + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" + } +} diff --git a/functions-delivery-customization-rs/tests/default.test.js b/functions-delivery-customization-rs/tests/default.test.js new file mode 100644 index 00000000..23221643 --- /dev/null +++ b/functions-delivery-customization-rs/tests/default.test.js @@ -0,0 +1,45 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs + .readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-delivery-customization-rs/tests/fixtures/log.json b/functions-delivery-customization-rs/tests/fixtures/log.json new file mode 100644 index 00000000..e4c37278 --- /dev/null +++ b/functions-delivery-customization-rs/tests/fixtures/log.json @@ -0,0 +1,16 @@ +{ + "payload": { + "export": "cart_delivery_options_transform_run", + "target": "cart.delivery-options.transform.run", + "input": { + "deliveryCustomization": { + "metafield": { + "jsonValue": {} + } + } + }, + "output": { + "operations": [] + } + } +} diff --git a/functions-discount-js/package.json.liquid b/functions-discount-js/package.json.liquid index aa829248..b6d85ff2 100644 --- a/functions-discount-js/package.json.liquid +++ b/functions-discount-js/package.json.liquid @@ -2,12 +2,14 @@ "name": "{{handle}}", "version": "0.0.1", "license": "UNLICENSED", + "type": "module", "scripts": { "shopify": "npm exec -- shopify", "typegen": "npm exec -- shopify app function typegen", "build": "npm exec -- shopify app function build", "preview": "npm exec -- shopify app function run", - "test": "vitest" + "test": "vitest", + "test:unit": "vitest run src/" }, "codegen": { "schema": "schema.graphql", @@ -28,6 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "vitest": "2.1.9" + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" } } diff --git a/functions-discount-js/tests/default.test.js b/functions-discount-js/tests/default.test.js new file mode 100644 index 00000000..23221643 --- /dev/null +++ b/functions-discount-js/tests/default.test.js @@ -0,0 +1,45 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs + .readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-discount-js/tests/fixtures/cart-lines-discount-generate-log.json b/functions-discount-js/tests/fixtures/cart-lines-discount-generate-log.json new file mode 100644 index 00000000..a4ea78aa --- /dev/null +++ b/functions-discount-js/tests/fixtures/cart-lines-discount-generate-log.json @@ -0,0 +1,72 @@ +{ + "payload": { + "export": "cart-lines-discounts-generate-run", + "target": "cart.lines.discounts.generate.run", + "input": { + "cart": { + "lines": [ + { + "id": "gid://shopify/CartLine/0", + "cost": { + "subtotalAmount": { + "amount": "6.0" + } + } + } + ] + }, + "discount": { + "discountClasses": ["PRODUCT", "ORDER", "SHIPPING"] + } + }, + "inputBytes": 126, + "output": { + "operations": [ + { + "orderDiscountsAdd": { + "candidates": [ + { + "message": "10% OFF ORDER", + "targets": [ + { + "orderSubtotal": { + "excludedCartLineIds": [] + } + } + ], + "value": { + "percentage": { + "value": 10.0 + } + } + } + ], + "selectionStrategy": "FIRST" + } + }, + { + "productDiscountsAdd": { + "candidates": [ + { + "message": "20% OFF PRODUCT", + "targets": [ + { + "cartLine": { + "id": "gid://shopify/CartLine/0" + } + } + ], + "value": { + "percentage": { + "value": 20.0 + } + } + } + ], + "selectionStrategy": "FIRST" + } + } + ] + } + } +} diff --git a/functions-discount-js/tests/fixtures/delivery-options-discount-generate-log.json b/functions-discount-js/tests/fixtures/delivery-options-discount-generate-log.json new file mode 100644 index 00000000..d31e7c43 --- /dev/null +++ b/functions-discount-js/tests/fixtures/delivery-options-discount-generate-log.json @@ -0,0 +1,44 @@ +{ + "payload": { + "export": "cart-delivery-options-discounts-generate-run", + "target": "cart.delivery-options.discounts.generate.run", + "input": { + "discount": { + "discountClasses": ["SHIPPING"] + }, + "cart": { + "deliveryGroups": [ + { + "id": "gid://shopify/CartDeliveryGroup/1" + } + ] + } + }, + "output": { + "operations": [ + { + "deliveryDiscountsAdd": { + "candidates": [ + { + "message": "FREE DELIVERY", + "targets": [ + { + "deliveryGroup": { + "id": "gid://shopify/CartDeliveryGroup/1" + } + } + ], + "value": { + "percentage": { + "value": 100.0 + } + } + } + ], + "selectionStrategy": "ALL" + } + } + ] + } + } +} diff --git a/functions-discount-js/vitest.config.js b/functions-discount-js/vitest.config.js new file mode 100644 index 00000000..ff8b4c56 --- /dev/null +++ b/functions-discount-js/vitest.config.js @@ -0,0 +1 @@ +export default {}; diff --git a/functions-discount-rs/package.json.liquid b/functions-discount-rs/package.json.liquid new file mode 100644 index 00000000..98d6960c --- /dev/null +++ b/functions-discount-rs/package.json.liquid @@ -0,0 +1,13 @@ +{ + "name": "{{handle}}", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": { + "test": "vitest run" + }, + "devDependencies": { + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" + } +} diff --git a/functions-discount-rs/tests/default.test.js b/functions-discount-rs/tests/default.test.js new file mode 100644 index 00000000..23221643 --- /dev/null +++ b/functions-discount-rs/tests/default.test.js @@ -0,0 +1,45 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs + .readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-discount-rs/tests/fixtures/cart-lines-discount-generate-log.json b/functions-discount-rs/tests/fixtures/cart-lines-discount-generate-log.json new file mode 100644 index 00000000..45fcd4d5 --- /dev/null +++ b/functions-discount-rs/tests/fixtures/cart-lines-discount-generate-log.json @@ -0,0 +1,76 @@ +{ + "payload": { + "export": "cart_lines_discounts_generate_run", + "target": "cart.lines.discounts.generate.run", + "input": { + "cart": { + "lines": [ + { + "id": "gid://shopify/CartLine/0", + "cost": { + "subtotalAmount": { + "amount": "6.0" + } + } + } + ] + }, + "discount": { + "discountClasses": ["PRODUCT", "ORDER", "SHIPPING"] + } + }, + "inputBytes": 126, + "output": { + "operations": [ + { + "orderDiscountsAdd": { + "candidates": [ + { + "associatedDiscountCode": null, + "conditions": null, + "message": "10% OFF ORDER", + "targets": [ + { + "orderSubtotal": { + "excludedCartLineIds": [] + } + } + ], + "value": { + "percentage": { + "value": "10.0" + } + } + } + ], + "selectionStrategy": "FIRST" + } + }, + { + "productDiscountsAdd": { + "candidates": [ + { + "associatedDiscountCode": null, + "message": "20% OFF PRODUCT", + "targets": [ + { + "cartLine": { + "id": "gid://shopify/CartLine/0", + "quantity": null + } + } + ], + "value": { + "percentage": { + "value": "20.0" + } + } + } + ], + "selectionStrategy": "FIRST" + } + } + ] + } + } +} diff --git a/functions-discount-rs/tests/fixtures/delivery-options-discount-generate-log.json b/functions-discount-rs/tests/fixtures/delivery-options-discount-generate-log.json new file mode 100644 index 00000000..5ee44a7e --- /dev/null +++ b/functions-discount-rs/tests/fixtures/delivery-options-discount-generate-log.json @@ -0,0 +1,45 @@ +{ + "payload": { + "export": "cart_delivery_options_discounts_generate_run", + "target": "cart.delivery-options.discounts.generate.run", + "input": { + "discount": { + "discountClasses": ["SHIPPING"] + }, + "cart": { + "deliveryGroups": [ + { + "id": "gid://shopify/CartDeliveryGroup/1" + } + ] + } + }, + "output": { + "operations": [ + { + "deliveryDiscountsAdd": { + "candidates": [ + { + "associatedDiscountCode": null, + "message": "FREE DELIVERY", + "targets": [ + { + "deliveryGroup": { + "id": "gid://shopify/CartDeliveryGroup/1" + } + } + ], + "value": { + "percentage": { + "value": "100.0" + } + } + } + ], + "selectionStrategy": "ALL" + } + } + ] + } + } +} \ No newline at end of file diff --git a/functions-discounts-allocator-js/package.json.liquid b/functions-discounts-allocator-js/package.json.liquid index 59fbed29..636560eb 100644 --- a/functions-discounts-allocator-js/package.json.liquid +++ b/functions-discounts-allocator-js/package.json.liquid @@ -2,12 +2,14 @@ "name": "{{handle}}", "version": "0.0.1", "license": "UNLICENSED", + "type": "module", "scripts": { "shopify": "npm exec -- shopify", "typegen": "npm exec -- shopify app function typegen", "build": "npm exec -- shopify app function build", "preview": "npm exec -- shopify app function run", - "test": "vitest" + "test": "vitest", + "test:unit": "vitest run src/" }, "codegen": { "schema": "schema.graphql", @@ -24,11 +26,12 @@ "omitOperationSuffix": true } }, - "devDependencies": { - "vitest": "2.1.9" - }, "dependencies": { "decimal.js": "^10.5.0", "@shopify/shopify_function": "2.0.0" + }, + "devDependencies": { + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" } } diff --git a/functions-discounts-allocator-js/tests/default.test.js b/functions-discounts-allocator-js/tests/default.test.js new file mode 100644 index 00000000..23221643 --- /dev/null +++ b/functions-discounts-allocator-js/tests/default.test.js @@ -0,0 +1,45 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs + .readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-discounts-allocator-js/tests/fixtures/log.json b/functions-discounts-allocator-js/tests/fixtures/log.json new file mode 100644 index 00000000..d8e79bdf --- /dev/null +++ b/functions-discounts-allocator-js/tests/fixtures/log.json @@ -0,0 +1,17 @@ +{ + "payload": { + "export": "run", + "target": "purchase.discounts-allocator.run", + "input": { + "shop": { + "metafield": { + "value": "{}" + } + } + }, + "output": { + "displayableErrors": [], + "lineDiscounts": [] + } + } +} diff --git a/functions-discounts-allocator-js/vitest.config.js b/functions-discounts-allocator-js/vitest.config.js new file mode 100644 index 00000000..ff8b4c56 --- /dev/null +++ b/functions-discounts-allocator-js/vitest.config.js @@ -0,0 +1 @@ +export default {}; diff --git a/functions-discounts-allocator-rs/package.json.liquid b/functions-discounts-allocator-rs/package.json.liquid new file mode 100644 index 00000000..98d6960c --- /dev/null +++ b/functions-discounts-allocator-rs/package.json.liquid @@ -0,0 +1,13 @@ +{ + "name": "{{handle}}", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": { + "test": "vitest run" + }, + "devDependencies": { + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" + } +} diff --git a/functions-discounts-allocator-rs/tests/default.test.js b/functions-discounts-allocator-rs/tests/default.test.js new file mode 100644 index 00000000..23221643 --- /dev/null +++ b/functions-discounts-allocator-rs/tests/default.test.js @@ -0,0 +1,45 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs + .readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-discounts-allocator-rs/tests/fixtures/log.json b/functions-discounts-allocator-rs/tests/fixtures/log.json new file mode 100644 index 00000000..d8e79bdf --- /dev/null +++ b/functions-discounts-allocator-rs/tests/fixtures/log.json @@ -0,0 +1,17 @@ +{ + "payload": { + "export": "run", + "target": "purchase.discounts-allocator.run", + "input": { + "shop": { + "metafield": { + "value": "{}" + } + } + }, + "output": { + "displayableErrors": [], + "lineDiscounts": [] + } + } +} diff --git a/functions-fulfillment-constraints-js/package.json.liquid b/functions-fulfillment-constraints-js/package.json.liquid index aa829248..b6d85ff2 100644 --- a/functions-fulfillment-constraints-js/package.json.liquid +++ b/functions-fulfillment-constraints-js/package.json.liquid @@ -2,12 +2,14 @@ "name": "{{handle}}", "version": "0.0.1", "license": "UNLICENSED", + "type": "module", "scripts": { "shopify": "npm exec -- shopify", "typegen": "npm exec -- shopify app function typegen", "build": "npm exec -- shopify app function build", "preview": "npm exec -- shopify app function run", - "test": "vitest" + "test": "vitest", + "test:unit": "vitest run src/" }, "codegen": { "schema": "schema.graphql", @@ -28,6 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "vitest": "2.1.9" + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" } } diff --git a/functions-fulfillment-constraints-js/tests/default.test.js b/functions-fulfillment-constraints-js/tests/default.test.js new file mode 100644 index 00000000..23221643 --- /dev/null +++ b/functions-fulfillment-constraints-js/tests/default.test.js @@ -0,0 +1,45 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs + .readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-fulfillment-constraints-js/tests/fixtures/log.json b/functions-fulfillment-constraints-js/tests/fixtures/log.json new file mode 100644 index 00000000..e76df2c0 --- /dev/null +++ b/functions-fulfillment-constraints-js/tests/fixtures/log.json @@ -0,0 +1,23 @@ +{ + "payload": { + "export": "cart-fulfillment-constraints-generate-run", + "target": "cart.fulfillment-constraints.generate.run", + "input": { + "cart": { + "deliverableLines": [ + { + "id": "gid://shopify/CartLine/1" + } + ] + }, + "fulfillmentConstraintRule": { + "metafield": { + "jsonValue": {} + } + } + }, + "output": { + "operations": [] + } + } +} diff --git a/functions-fulfillment-constraints-js/vitest.config.js b/functions-fulfillment-constraints-js/vitest.config.js new file mode 100644 index 00000000..ff8b4c56 --- /dev/null +++ b/functions-fulfillment-constraints-js/vitest.config.js @@ -0,0 +1 @@ +export default {}; diff --git a/functions-fulfillment-constraints-rs/package.json.liquid b/functions-fulfillment-constraints-rs/package.json.liquid new file mode 100644 index 00000000..98d6960c --- /dev/null +++ b/functions-fulfillment-constraints-rs/package.json.liquid @@ -0,0 +1,13 @@ +{ + "name": "{{handle}}", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": { + "test": "vitest run" + }, + "devDependencies": { + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" + } +} diff --git a/functions-fulfillment-constraints-rs/tests/default.test.js b/functions-fulfillment-constraints-rs/tests/default.test.js new file mode 100644 index 00000000..0d5ad405 --- /dev/null +++ b/functions-fulfillment-constraints-rs/tests/default.test.js @@ -0,0 +1,44 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs.readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-fulfillment-constraints-rs/tests/fixtures/log.json b/functions-fulfillment-constraints-rs/tests/fixtures/log.json new file mode 100644 index 00000000..29b26f04 --- /dev/null +++ b/functions-fulfillment-constraints-rs/tests/fixtures/log.json @@ -0,0 +1,23 @@ +{ + "payload": { + "export": "cart_fulfillment_constraints_generate_run", + "target": "cart.fulfillment-constraints.generate.run", + "input": { + "cart": { + "deliverableLines": [ + { + "id": "gid://shopify/CartLine/1" + } + ] + }, + "fulfillmentConstraintRule": { + "metafield": { + "jsonValue": {} + } + } + }, + "output": { + "operations": [] + } + } +} diff --git a/functions-local-pickup-delivery-option-generators-js/package.json.liquid b/functions-local-pickup-delivery-option-generators-js/package.json.liquid index aa829248..b6d85ff2 100644 --- a/functions-local-pickup-delivery-option-generators-js/package.json.liquid +++ b/functions-local-pickup-delivery-option-generators-js/package.json.liquid @@ -2,12 +2,14 @@ "name": "{{handle}}", "version": "0.0.1", "license": "UNLICENSED", + "type": "module", "scripts": { "shopify": "npm exec -- shopify", "typegen": "npm exec -- shopify app function typegen", "build": "npm exec -- shopify app function build", "preview": "npm exec -- shopify app function run", - "test": "vitest" + "test": "vitest", + "test:unit": "vitest run src/" }, "codegen": { "schema": "schema.graphql", @@ -28,6 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "vitest": "2.1.9" + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" } } diff --git a/functions-local-pickup-delivery-option-generators-js/src/run.graphql.liquid b/functions-local-pickup-delivery-option-generators-js/src/run.graphql.liquid index b007169e..e0299406 100644 --- a/functions-local-pickup-delivery-option-generators-js/src/run.graphql.liquid +++ b/functions-local-pickup-delivery-option-generators-js/src/run.graphql.liquid @@ -22,7 +22,7 @@ query RunInput { } } deliveryOptionGenerator { - metafield: metafield(namespace: "$app:local-pickup-options-generator", key: "pickup-ids") { + metafield(namespace: "$app:local-pickup-options-generator", key: "pickup-ids") { value } } diff --git a/functions-local-pickup-delivery-option-generators-js/tests/default.test.js b/functions-local-pickup-delivery-option-generators-js/tests/default.test.js new file mode 100644 index 00000000..0d5ad405 --- /dev/null +++ b/functions-local-pickup-delivery-option-generators-js/tests/default.test.js @@ -0,0 +1,44 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs.readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-local-pickup-delivery-option-generators-js/tests/fixtures/log.json b/functions-local-pickup-delivery-option-generators-js/tests/fixtures/log.json new file mode 100644 index 00000000..005ec9a3 --- /dev/null +++ b/functions-local-pickup-delivery-option-generators-js/tests/fixtures/log.json @@ -0,0 +1,57 @@ +{ + "payload": { + "export": "run", + "target": "purchase.local-pickup-delivery-option-generator.run", + "input": { + "cart": { + "lines": [ + { + "id": "gid://shopify/CartLine/1" + } + ] + }, + "fulfillmentGroups": [ + { + "handle": "group1", + "inventoryLocationHandles": ["location1"], + "lines": [ + { + "id": "gid://shopify/CartLine/1" + } + ], + "deliveryGroup": { + "id": "gid://shopify/DeliveryGroup/1" + } + } + ], + "locations": [ + { + "handle": "location1", + "name": "Store", + "address": { + "address1": "123 Main St" + } + } + ], + "deliveryOptionGenerator": { + "metafield": { + "value": "[]" + } + } + }, + "output": { + "operations": [ + { + "add": { + "title": "Main St.", + "cost": 1.99, + "pickupLocation": { + "locationHandle": "2578303", + "pickupInstruction": "Usually ready in 24 hours." + } + } + } + ] + } + } +} diff --git a/functions-local-pickup-delivery-option-generators-js/vitest.config.js b/functions-local-pickup-delivery-option-generators-js/vitest.config.js new file mode 100644 index 00000000..ff8b4c56 --- /dev/null +++ b/functions-local-pickup-delivery-option-generators-js/vitest.config.js @@ -0,0 +1 @@ +export default {}; diff --git a/functions-local-pickup-delivery-option-generators-rs/package.json.liquid b/functions-local-pickup-delivery-option-generators-rs/package.json.liquid new file mode 100644 index 00000000..98d6960c --- /dev/null +++ b/functions-local-pickup-delivery-option-generators-rs/package.json.liquid @@ -0,0 +1,13 @@ +{ + "name": "{{handle}}", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": { + "test": "vitest run" + }, + "devDependencies": { + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" + } +} diff --git a/functions-local-pickup-delivery-option-generators-rs/src/run.graphql.liquid b/functions-local-pickup-delivery-option-generators-rs/src/run.graphql.liquid index 8caeb6b7..d442f4f2 100644 --- a/functions-local-pickup-delivery-option-generators-rs/src/run.graphql.liquid +++ b/functions-local-pickup-delivery-option-generators-rs/src/run.graphql.liquid @@ -22,7 +22,7 @@ query Input { } } deliveryOptionGenerator { - metafield: metafield(namespace: "$app:local-pickup-options-generator", key: "pickup-ids") { + metafield(namespace: "$app:local-pickup-options-generator", key: "pickup-ids") { value } } diff --git a/functions-local-pickup-delivery-option-generators-rs/tests/default.test.js b/functions-local-pickup-delivery-option-generators-rs/tests/default.test.js new file mode 100644 index 00000000..0d5ad405 --- /dev/null +++ b/functions-local-pickup-delivery-option-generators-rs/tests/default.test.js @@ -0,0 +1,44 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs.readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-local-pickup-delivery-option-generators-rs/tests/fixtures/log.json b/functions-local-pickup-delivery-option-generators-rs/tests/fixtures/log.json new file mode 100644 index 00000000..ed58472f --- /dev/null +++ b/functions-local-pickup-delivery-option-generators-rs/tests/fixtures/log.json @@ -0,0 +1,58 @@ +{ + "payload": { + "export": "run", + "target": "purchase.local-pickup-delivery-option-generator.run", + "input": { + "cart": { + "lines": [ + { + "id": "gid://shopify/CartLine/1" + } + ] + }, + "fulfillmentGroups": [ + { + "handle": "group1", + "inventoryLocationHandles": ["location1"], + "lines": [ + { + "id": "gid://shopify/CartLine/1" + } + ], + "deliveryGroup": { + "id": "gid://shopify/DeliveryGroup/1" + } + } + ], + "locations": [ + { + "handle": "location1", + "name": "Store", + "address": { + "address1": "123 Main St" + } + } + ], + "deliveryOptionGenerator": { + "metafield": { + "value": "[]" + } + } + }, + "output": { + "operations": [ + { + "add": { + "title": "Main St.", + "cost": "1.99", + "pickupLocation": { + "locationHandle": "2578303", + "pickupInstruction": "Usually ready in 24 hours." + }, + "metafields": null + } + } + ] + } + } +} diff --git a/functions-location-rules-js/notes.md b/functions-location-rules-js/notes.md new file mode 100644 index 00000000..649e50f5 --- /dev/null +++ b/functions-location-rules-js/notes.md @@ -0,0 +1,7 @@ +# Notes + +## Template Not Available in CLI + +As of October 5, 2025, the `fulfillment_groups_location_rankings` function template is not yet available in the Shopify CLI for generation. The template files exist but cannot be generated using `shopify app generate extension`. + +This means the integration tests in the `tests/` directory cannot be verified locally until the template is added to the supported extension types in the CLI. diff --git a/functions-location-rules-js/package.json.liquid b/functions-location-rules-js/package.json.liquid index aa829248..b6d85ff2 100644 --- a/functions-location-rules-js/package.json.liquid +++ b/functions-location-rules-js/package.json.liquid @@ -2,12 +2,14 @@ "name": "{{handle}}", "version": "0.0.1", "license": "UNLICENSED", + "type": "module", "scripts": { "shopify": "npm exec -- shopify", "typegen": "npm exec -- shopify app function typegen", "build": "npm exec -- shopify app function build", "preview": "npm exec -- shopify app function run", - "test": "vitest" + "test": "vitest", + "test:unit": "vitest run src/" }, "codegen": { "schema": "schema.graphql", @@ -28,6 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "vitest": "2.1.9" + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" } } diff --git a/functions-location-rules-js/tests/default.test.js b/functions-location-rules-js/tests/default.test.js new file mode 100644 index 00000000..0d5ad405 --- /dev/null +++ b/functions-location-rules-js/tests/default.test.js @@ -0,0 +1,44 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs.readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-location-rules-js/tests/fixtures/log.json b/functions-location-rules-js/tests/fixtures/log.json new file mode 100644 index 00000000..fff63a6c --- /dev/null +++ b/functions-location-rules-js/tests/fixtures/log.json @@ -0,0 +1,17 @@ +{ + "payload": { + "export": "cart-fulfillment-groups-location-rankings-generate-run", + "target": "cart.fulfillment-groups.location-rankings.generate.run", + "input": { + "fulfillmentGroups": [ + { + "handle": "group1", + "inventoryLocationHandles": ["location1"] + } + ] + }, + "output": { + "rankingOperations": [] + } + } +} diff --git a/functions-location-rules-js/vitest.config.js b/functions-location-rules-js/vitest.config.js new file mode 100644 index 00000000..ff8b4c56 --- /dev/null +++ b/functions-location-rules-js/vitest.config.js @@ -0,0 +1 @@ +export default {}; diff --git a/functions-location-rules-rs/notes.md b/functions-location-rules-rs/notes.md new file mode 100644 index 00000000..649e50f5 --- /dev/null +++ b/functions-location-rules-rs/notes.md @@ -0,0 +1,7 @@ +# Notes + +## Template Not Available in CLI + +As of October 5, 2025, the `fulfillment_groups_location_rankings` function template is not yet available in the Shopify CLI for generation. The template files exist but cannot be generated using `shopify app generate extension`. + +This means the integration tests in the `tests/` directory cannot be verified locally until the template is added to the supported extension types in the CLI. diff --git a/functions-location-rules-rs/package.json.liquid b/functions-location-rules-rs/package.json.liquid new file mode 100644 index 00000000..98d6960c --- /dev/null +++ b/functions-location-rules-rs/package.json.liquid @@ -0,0 +1,13 @@ +{ + "name": "{{handle}}", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": { + "test": "vitest run" + }, + "devDependencies": { + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" + } +} diff --git a/functions-location-rules-rs/tests/default.test.js b/functions-location-rules-rs/tests/default.test.js new file mode 100644 index 00000000..0d5ad405 --- /dev/null +++ b/functions-location-rules-rs/tests/default.test.js @@ -0,0 +1,44 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs.readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-location-rules-rs/tests/fixtures/log.json b/functions-location-rules-rs/tests/fixtures/log.json new file mode 100644 index 00000000..e7425f8e --- /dev/null +++ b/functions-location-rules-rs/tests/fixtures/log.json @@ -0,0 +1,17 @@ +{ + "payload": { + "export": "cart_fulfillment_groups_location_rankings_generate_run", + "target": "cart.fulfillment-groups.location-rankings.generate.run", + "input": { + "fulfillmentGroups": [ + { + "handle": "group1", + "inventoryLocationHandles": ["location1"] + } + ] + }, + "output": { + "rankingOperations": [] + } + } +} diff --git a/functions-order-discounts-js/package.json.liquid b/functions-order-discounts-js/package.json.liquid index aa829248..b6d85ff2 100644 --- a/functions-order-discounts-js/package.json.liquid +++ b/functions-order-discounts-js/package.json.liquid @@ -2,12 +2,14 @@ "name": "{{handle}}", "version": "0.0.1", "license": "UNLICENSED", + "type": "module", "scripts": { "shopify": "npm exec -- shopify", "typegen": "npm exec -- shopify app function typegen", "build": "npm exec -- shopify app function build", "preview": "npm exec -- shopify app function run", - "test": "vitest" + "test": "vitest", + "test:unit": "vitest run src/" }, "codegen": { "schema": "schema.graphql", @@ -28,6 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "vitest": "2.1.9" + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" } } diff --git a/functions-order-discounts-js/tests/default.test.js b/functions-order-discounts-js/tests/default.test.js new file mode 100644 index 00000000..0d5ad405 --- /dev/null +++ b/functions-order-discounts-js/tests/default.test.js @@ -0,0 +1,44 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs.readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-order-discounts-js/tests/fixtures/log.json b/functions-order-discounts-js/tests/fixtures/log.json new file mode 100644 index 00000000..214a5ec9 --- /dev/null +++ b/functions-order-discounts-js/tests/fixtures/log.json @@ -0,0 +1,17 @@ +{ + "payload": { + "export": "run", + "target": "purchase.order-discount.run", + "input": { + "discountNode": { + "metafield": { + "value": "{}" + } + } + }, + "output": { + "discountApplicationStrategy": "FIRST", + "discounts": [] + } + } +} diff --git a/functions-order-discounts-js/vitest.config.js b/functions-order-discounts-js/vitest.config.js new file mode 100644 index 00000000..ff8b4c56 --- /dev/null +++ b/functions-order-discounts-js/vitest.config.js @@ -0,0 +1 @@ +export default {}; diff --git a/functions-order-discounts-rs/package.json.liquid b/functions-order-discounts-rs/package.json.liquid new file mode 100644 index 00000000..98d6960c --- /dev/null +++ b/functions-order-discounts-rs/package.json.liquid @@ -0,0 +1,13 @@ +{ + "name": "{{handle}}", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": { + "test": "vitest run" + }, + "devDependencies": { + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" + } +} diff --git a/functions-order-discounts-rs/tests/default.test.js b/functions-order-discounts-rs/tests/default.test.js new file mode 100644 index 00000000..0d5ad405 --- /dev/null +++ b/functions-order-discounts-rs/tests/default.test.js @@ -0,0 +1,44 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs.readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-order-discounts-rs/tests/fixtures/log.json b/functions-order-discounts-rs/tests/fixtures/log.json new file mode 100644 index 00000000..e7bb9b35 --- /dev/null +++ b/functions-order-discounts-rs/tests/fixtures/log.json @@ -0,0 +1,17 @@ +{ + "payload": { + "export": "run", + "target": "purchase.order-discount.run", + "input": { + "discountNode": { + "metafield": { + "jsonValue": {} + } + } + }, + "output": { + "discountApplicationStrategy": "FIRST", + "discounts": [] + } + } +} diff --git a/functions-payment-customization-js/package.json.liquid b/functions-payment-customization-js/package.json.liquid index aa829248..b6d85ff2 100644 --- a/functions-payment-customization-js/package.json.liquid +++ b/functions-payment-customization-js/package.json.liquid @@ -2,12 +2,14 @@ "name": "{{handle}}", "version": "0.0.1", "license": "UNLICENSED", + "type": "module", "scripts": { "shopify": "npm exec -- shopify", "typegen": "npm exec -- shopify app function typegen", "build": "npm exec -- shopify app function build", "preview": "npm exec -- shopify app function run", - "test": "vitest" + "test": "vitest", + "test:unit": "vitest run src/" }, "codegen": { "schema": "schema.graphql", @@ -28,6 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "vitest": "2.1.9" + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" } } diff --git a/functions-payment-customization-js/tests/default.test.js b/functions-payment-customization-js/tests/default.test.js new file mode 100644 index 00000000..0d5ad405 --- /dev/null +++ b/functions-payment-customization-js/tests/default.test.js @@ -0,0 +1,44 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs.readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-payment-customization-js/tests/fixtures/log.json b/functions-payment-customization-js/tests/fixtures/log.json new file mode 100644 index 00000000..69da6b26 --- /dev/null +++ b/functions-payment-customization-js/tests/fixtures/log.json @@ -0,0 +1,16 @@ +{ + "payload": { + "export": "cart-payment-methods-transform-run", + "target": "cart.payment-methods.transform.run", + "input": { + "paymentCustomization": { + "metafield": { + "value": "{}" + } + } + }, + "output": { + "operations": [] + } + } +} diff --git a/functions-payment-customization-js/vitest.config.js b/functions-payment-customization-js/vitest.config.js new file mode 100644 index 00000000..ff8b4c56 --- /dev/null +++ b/functions-payment-customization-js/vitest.config.js @@ -0,0 +1 @@ +export default {}; diff --git a/functions-payment-customization-rs/package.json.liquid b/functions-payment-customization-rs/package.json.liquid new file mode 100644 index 00000000..98d6960c --- /dev/null +++ b/functions-payment-customization-rs/package.json.liquid @@ -0,0 +1,13 @@ +{ + "name": "{{handle}}", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": { + "test": "vitest run" + }, + "devDependencies": { + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" + } +} diff --git a/functions-payment-customization-rs/tests/default.test.js b/functions-payment-customization-rs/tests/default.test.js new file mode 100644 index 00000000..0d5ad405 --- /dev/null +++ b/functions-payment-customization-rs/tests/default.test.js @@ -0,0 +1,44 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs.readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-payment-customization-rs/tests/fixtures/log.json b/functions-payment-customization-rs/tests/fixtures/log.json new file mode 100644 index 00000000..0d809c29 --- /dev/null +++ b/functions-payment-customization-rs/tests/fixtures/log.json @@ -0,0 +1,16 @@ +{ + "payload": { + "export": "cart_payment_methods_transform_run", + "target": "cart.payment-methods.transform.run", + "input": { + "paymentCustomization": { + "metafield": { + "jsonValue": {} + } + } + }, + "output": { + "operations": [] + } + } +} diff --git a/functions-pickup-point-delivery-option-generators-js/package.json.liquid b/functions-pickup-point-delivery-option-generators-js/package.json.liquid index aa829248..b6d85ff2 100644 --- a/functions-pickup-point-delivery-option-generators-js/package.json.liquid +++ b/functions-pickup-point-delivery-option-generators-js/package.json.liquid @@ -2,12 +2,14 @@ "name": "{{handle}}", "version": "0.0.1", "license": "UNLICENSED", + "type": "module", "scripts": { "shopify": "npm exec -- shopify", "typegen": "npm exec -- shopify app function typegen", "build": "npm exec -- shopify app function build", "preview": "npm exec -- shopify app function run", - "test": "vitest" + "test": "vitest", + "test:unit": "vitest run src/" }, "codegen": { "schema": "schema.graphql", @@ -28,6 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "vitest": "2.1.9" + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" } } diff --git a/functions-pickup-point-delivery-option-generators-js/tests/default.test.js b/functions-pickup-point-delivery-option-generators-js/tests/default.test.js new file mode 100644 index 00000000..0d5ad405 --- /dev/null +++ b/functions-pickup-point-delivery-option-generators-js/tests/default.test.js @@ -0,0 +1,44 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs.readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-pickup-point-delivery-option-generators-js/tests/fixtures/log.json b/functions-pickup-point-delivery-option-generators-js/tests/fixtures/log.json new file mode 100644 index 00000000..d9e3903c --- /dev/null +++ b/functions-pickup-point-delivery-option-generators-js/tests/fixtures/log.json @@ -0,0 +1,15 @@ +{ + "payload": { + "export": "run", + "target": "purchase.pickup-point-delivery-option-generator.run", + "input": { + "fetchResult": { + "status": 200, + "body": "{\"deliveryPoints\":[]}" + } + }, + "output": { + "operations": [] + } + } +} diff --git a/functions-pickup-point-delivery-option-generators-js/vitest.config.js b/functions-pickup-point-delivery-option-generators-js/vitest.config.js new file mode 100644 index 00000000..ff8b4c56 --- /dev/null +++ b/functions-pickup-point-delivery-option-generators-js/vitest.config.js @@ -0,0 +1 @@ +export default {}; diff --git a/functions-pickup-point-delivery-option-generators-rs/package.json.liquid b/functions-pickup-point-delivery-option-generators-rs/package.json.liquid new file mode 100644 index 00000000..98d6960c --- /dev/null +++ b/functions-pickup-point-delivery-option-generators-rs/package.json.liquid @@ -0,0 +1,13 @@ +{ + "name": "{{handle}}", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": { + "test": "vitest run" + }, + "devDependencies": { + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" + } +} diff --git a/functions-pickup-point-delivery-option-generators-rs/tests/default.test.js b/functions-pickup-point-delivery-option-generators-rs/tests/default.test.js new file mode 100644 index 00000000..0d5ad405 --- /dev/null +++ b/functions-pickup-point-delivery-option-generators-rs/tests/default.test.js @@ -0,0 +1,44 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs.readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-pickup-point-delivery-option-generators-rs/tests/fixtures/log.json b/functions-pickup-point-delivery-option-generators-rs/tests/fixtures/log.json new file mode 100644 index 00000000..d9e3903c --- /dev/null +++ b/functions-pickup-point-delivery-option-generators-rs/tests/fixtures/log.json @@ -0,0 +1,15 @@ +{ + "payload": { + "export": "run", + "target": "purchase.pickup-point-delivery-option-generator.run", + "input": { + "fetchResult": { + "status": 200, + "body": "{\"deliveryPoints\":[]}" + } + }, + "output": { + "operations": [] + } + } +} diff --git a/functions-product-discounts-js/package.json.liquid b/functions-product-discounts-js/package.json.liquid index aa829248..b6d85ff2 100644 --- a/functions-product-discounts-js/package.json.liquid +++ b/functions-product-discounts-js/package.json.liquid @@ -2,12 +2,14 @@ "name": "{{handle}}", "version": "0.0.1", "license": "UNLICENSED", + "type": "module", "scripts": { "shopify": "npm exec -- shopify", "typegen": "npm exec -- shopify app function typegen", "build": "npm exec -- shopify app function build", "preview": "npm exec -- shopify app function run", - "test": "vitest" + "test": "vitest", + "test:unit": "vitest run src/" }, "codegen": { "schema": "schema.graphql", @@ -28,6 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "vitest": "2.1.9" + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" } } diff --git a/functions-product-discounts-js/tests/default.test.js b/functions-product-discounts-js/tests/default.test.js new file mode 100644 index 00000000..0d5ad405 --- /dev/null +++ b/functions-product-discounts-js/tests/default.test.js @@ -0,0 +1,44 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs.readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-product-discounts-js/tests/fixtures/log.json b/functions-product-discounts-js/tests/fixtures/log.json new file mode 100644 index 00000000..aa8c79b3 --- /dev/null +++ b/functions-product-discounts-js/tests/fixtures/log.json @@ -0,0 +1,17 @@ +{ + "payload": { + "export": "run", + "target": "purchase.product-discount.run", + "input": { + "discountNode": { + "metafield": { + "value": "{}" + } + } + }, + "output": { + "discountApplicationStrategy": "FIRST", + "discounts": [] + } + } +} diff --git a/functions-product-discounts-js/vitest.config.js b/functions-product-discounts-js/vitest.config.js new file mode 100644 index 00000000..ff8b4c56 --- /dev/null +++ b/functions-product-discounts-js/vitest.config.js @@ -0,0 +1 @@ +export default {}; diff --git a/functions-product-discounts-rs/package.json.liquid b/functions-product-discounts-rs/package.json.liquid new file mode 100644 index 00000000..98d6960c --- /dev/null +++ b/functions-product-discounts-rs/package.json.liquid @@ -0,0 +1,13 @@ +{ + "name": "{{handle}}", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": { + "test": "vitest run" + }, + "devDependencies": { + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" + } +} diff --git a/functions-product-discounts-rs/tests/default.test.js b/functions-product-discounts-rs/tests/default.test.js new file mode 100644 index 00000000..0d5ad405 --- /dev/null +++ b/functions-product-discounts-rs/tests/default.test.js @@ -0,0 +1,44 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs.readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-product-discounts-rs/tests/fixtures/log.json b/functions-product-discounts-rs/tests/fixtures/log.json new file mode 100644 index 00000000..2603da68 --- /dev/null +++ b/functions-product-discounts-rs/tests/fixtures/log.json @@ -0,0 +1,17 @@ +{ + "payload": { + "export": "run", + "target": "purchase.product-discount.run", + "input": { + "discountNode": { + "metafield": { + "jsonValue": {} + } + } + }, + "output": { + "discountApplicationStrategy": "FIRST", + "discounts": [] + } + } +} diff --git a/functions-shipping-discounts-js/package.json.liquid b/functions-shipping-discounts-js/package.json.liquid index aa829248..b6d85ff2 100644 --- a/functions-shipping-discounts-js/package.json.liquid +++ b/functions-shipping-discounts-js/package.json.liquid @@ -2,12 +2,14 @@ "name": "{{handle}}", "version": "0.0.1", "license": "UNLICENSED", + "type": "module", "scripts": { "shopify": "npm exec -- shopify", "typegen": "npm exec -- shopify app function typegen", "build": "npm exec -- shopify app function build", "preview": "npm exec -- shopify app function run", - "test": "vitest" + "test": "vitest", + "test:unit": "vitest run src/" }, "codegen": { "schema": "schema.graphql", @@ -28,6 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "vitest": "2.1.9" + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" } } diff --git a/functions-shipping-discounts-js/tests/default.test.js b/functions-shipping-discounts-js/tests/default.test.js new file mode 100644 index 00000000..0d5ad405 --- /dev/null +++ b/functions-shipping-discounts-js/tests/default.test.js @@ -0,0 +1,44 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs.readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-shipping-discounts-js/tests/fixtures/log.json b/functions-shipping-discounts-js/tests/fixtures/log.json new file mode 100644 index 00000000..6373d5fe --- /dev/null +++ b/functions-shipping-discounts-js/tests/fixtures/log.json @@ -0,0 +1,16 @@ +{ + "payload": { + "export": "run", + "target": "purchase.shipping-discount.run", + "input": { + "discountNode": { + "metafield": { + "value": "{}" + } + } + }, + "output": { + "discounts": [] + } + } +} diff --git a/functions-shipping-discounts-js/vitest.config.js b/functions-shipping-discounts-js/vitest.config.js new file mode 100644 index 00000000..ff8b4c56 --- /dev/null +++ b/functions-shipping-discounts-js/vitest.config.js @@ -0,0 +1 @@ +export default {}; diff --git a/functions-shipping-discounts-rs/package.json.liquid b/functions-shipping-discounts-rs/package.json.liquid new file mode 100644 index 00000000..98d6960c --- /dev/null +++ b/functions-shipping-discounts-rs/package.json.liquid @@ -0,0 +1,13 @@ +{ + "name": "{{handle}}", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": { + "test": "vitest run" + }, + "devDependencies": { + "@shopify/shopify-function-test-helpers": "~0.0.0", + "vitest": "^3.2.4" + } +} diff --git a/functions-shipping-discounts-rs/tests/default.test.js b/functions-shipping-discounts-rs/tests/default.test.js new file mode 100644 index 00000000..0d5ad405 --- /dev/null +++ b/functions-shipping-discounts-rs/tests/default.test.js @@ -0,0 +1,44 @@ +import path from "path"; +import fs from "fs"; +import { describe, beforeAll, test, expect } from "vitest"; +import { buildFunction, getFunctionInfo, loadSchema, loadInputQuery, loadFixture, validateTestAssets, runFunction } from "@shopify/shopify-function-test-helpers"; + +describe("Default Integration Test", () => { + let schema; + let functionDir; + let functionInfo; + let schemaPath; + let targeting; + let functionRunnerPath; + let wasmPath; + + beforeAll(async () => { + functionDir = path.dirname(__dirname); + await buildFunction(functionDir); + functionInfo = await getFunctionInfo(functionDir); + ({ schemaPath, functionRunnerPath, wasmPath, targeting } = functionInfo); + schema = await loadSchema(schemaPath); + }, 45000); + + const fixturesDir = path.join(__dirname, "fixtures"); + const fixtureFiles = fs.readdirSync(fixturesDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(fixturesDir, file)); + + fixtureFiles.forEach((fixtureFile) => { + test(`runs ${path.relative(fixturesDir, fixtureFile)}`, async () => { + const fixture = await loadFixture(fixtureFile); + const targetInputQueryPath = targeting[fixture.target].inputQueryPath; + const inputQueryAST = await loadInputQuery(targetInputQueryPath); + + const validationResult = await validateTestAssets({ schema, fixture, inputQueryAST }); + expect(validationResult.inputQuery.errors).toEqual([]); + expect(validationResult.inputFixture.errors).toEqual([]); + expect(validationResult.outputFixture.errors).toEqual([]); + + const runResult = await runFunction(fixture, functionRunnerPath, wasmPath, targetInputQueryPath, schemaPath); + expect(runResult.error).toBeNull(); + expect(runResult.result.output).toEqual(fixture.expectedOutput); + }, 10000); + }); +}); diff --git a/functions-shipping-discounts-rs/tests/fixtures/log.json b/functions-shipping-discounts-rs/tests/fixtures/log.json new file mode 100644 index 00000000..81aa11ed --- /dev/null +++ b/functions-shipping-discounts-rs/tests/fixtures/log.json @@ -0,0 +1,16 @@ +{ + "payload": { + "export": "run", + "target": "purchase.shipping-discount.run", + "input": { + "discountNode": { + "metafield": { + "jsonValue": {} + } + } + }, + "output": { + "discounts": [] + } + } +} diff --git a/package.json b/package.json index 863635f9..fe0b8cc3 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "scripts": { "expand-liquid": "node .github/scripts/expand-liquid.js", "js-typegen": "yarn workspaces run graphql-code-generator --config package.json", - "js-test": "yarn workspaces run test run" + "js-test": "yarn workspaces run test run", + "js-test:unit": "yarn workspaces run test:unit" }, "private": true, "workspaces": ["functions-*-js"] From a99d8dfb1a2b67c8291f90f4e340200465f56aa6 Mon Sep 17 00:00:00 2001 From: Alex Bradley Date: Tue, 2 Dec 2025 09:28:03 -0500 Subject: [PATCH 2/2] update to helpers v1 --- functions-cart-checkout-validation-js/package.json.liquid | 2 +- functions-cart-checkout-validation-rs/package.json.liquid | 2 +- functions-cart-transform-js/package.json.liquid | 2 +- functions-cart-transform-rs/package.json.liquid | 2 +- functions-delivery-customization-js/package.json.liquid | 2 +- functions-delivery-customization-rs/package.json.liquid | 2 +- functions-discount-js/package.json.liquid | 2 +- functions-discount-rs/package.json.liquid | 2 +- functions-discounts-allocator-js/package.json.liquid | 2 +- functions-discounts-allocator-rs/package.json.liquid | 2 +- functions-fulfillment-constraints-js/package.json.liquid | 2 +- functions-fulfillment-constraints-rs/package.json.liquid | 2 +- .../package.json.liquid | 2 +- .../package.json.liquid | 2 +- functions-location-rules-js/package.json.liquid | 2 +- functions-location-rules-rs/package.json.liquid | 2 +- functions-order-discounts-js/package.json.liquid | 2 +- functions-order-discounts-rs/package.json.liquid | 2 +- functions-payment-customization-js/package.json.liquid | 2 +- functions-payment-customization-rs/package.json.liquid | 2 +- .../package.json.liquid | 2 +- .../package.json.liquid | 2 +- functions-product-discounts-js/package.json.liquid | 2 +- functions-product-discounts-rs/package.json.liquid | 2 +- functions-shipping-discounts-js/package.json.liquid | 2 +- functions-shipping-discounts-rs/package.json.liquid | 2 +- 26 files changed, 26 insertions(+), 26 deletions(-) diff --git a/functions-cart-checkout-validation-js/package.json.liquid b/functions-cart-checkout-validation-js/package.json.liquid index b6d85ff2..82ffbdf6 100644 --- a/functions-cart-checkout-validation-js/package.json.liquid +++ b/functions-cart-checkout-validation-js/package.json.liquid @@ -30,7 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-cart-checkout-validation-rs/package.json.liquid b/functions-cart-checkout-validation-rs/package.json.liquid index 98d6960c..f10238c8 100644 --- a/functions-cart-checkout-validation-rs/package.json.liquid +++ b/functions-cart-checkout-validation-rs/package.json.liquid @@ -7,7 +7,7 @@ "test": "vitest run" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-cart-transform-js/package.json.liquid b/functions-cart-transform-js/package.json.liquid index b6d85ff2..82ffbdf6 100644 --- a/functions-cart-transform-js/package.json.liquid +++ b/functions-cart-transform-js/package.json.liquid @@ -30,7 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-cart-transform-rs/package.json.liquid b/functions-cart-transform-rs/package.json.liquid index 98d6960c..f10238c8 100644 --- a/functions-cart-transform-rs/package.json.liquid +++ b/functions-cart-transform-rs/package.json.liquid @@ -7,7 +7,7 @@ "test": "vitest run" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-delivery-customization-js/package.json.liquid b/functions-delivery-customization-js/package.json.liquid index b6d85ff2..82ffbdf6 100644 --- a/functions-delivery-customization-js/package.json.liquid +++ b/functions-delivery-customization-js/package.json.liquid @@ -30,7 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-delivery-customization-rs/package.json.liquid b/functions-delivery-customization-rs/package.json.liquid index 98d6960c..f10238c8 100644 --- a/functions-delivery-customization-rs/package.json.liquid +++ b/functions-delivery-customization-rs/package.json.liquid @@ -7,7 +7,7 @@ "test": "vitest run" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-discount-js/package.json.liquid b/functions-discount-js/package.json.liquid index b6d85ff2..82ffbdf6 100644 --- a/functions-discount-js/package.json.liquid +++ b/functions-discount-js/package.json.liquid @@ -30,7 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-discount-rs/package.json.liquid b/functions-discount-rs/package.json.liquid index 98d6960c..f10238c8 100644 --- a/functions-discount-rs/package.json.liquid +++ b/functions-discount-rs/package.json.liquid @@ -7,7 +7,7 @@ "test": "vitest run" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-discounts-allocator-js/package.json.liquid b/functions-discounts-allocator-js/package.json.liquid index 636560eb..674bb395 100644 --- a/functions-discounts-allocator-js/package.json.liquid +++ b/functions-discounts-allocator-js/package.json.liquid @@ -31,7 +31,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-discounts-allocator-rs/package.json.liquid b/functions-discounts-allocator-rs/package.json.liquid index 98d6960c..f10238c8 100644 --- a/functions-discounts-allocator-rs/package.json.liquid +++ b/functions-discounts-allocator-rs/package.json.liquid @@ -7,7 +7,7 @@ "test": "vitest run" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-fulfillment-constraints-js/package.json.liquid b/functions-fulfillment-constraints-js/package.json.liquid index b6d85ff2..82ffbdf6 100644 --- a/functions-fulfillment-constraints-js/package.json.liquid +++ b/functions-fulfillment-constraints-js/package.json.liquid @@ -30,7 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-fulfillment-constraints-rs/package.json.liquid b/functions-fulfillment-constraints-rs/package.json.liquid index 98d6960c..f10238c8 100644 --- a/functions-fulfillment-constraints-rs/package.json.liquid +++ b/functions-fulfillment-constraints-rs/package.json.liquid @@ -7,7 +7,7 @@ "test": "vitest run" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-local-pickup-delivery-option-generators-js/package.json.liquid b/functions-local-pickup-delivery-option-generators-js/package.json.liquid index b6d85ff2..82ffbdf6 100644 --- a/functions-local-pickup-delivery-option-generators-js/package.json.liquid +++ b/functions-local-pickup-delivery-option-generators-js/package.json.liquid @@ -30,7 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-local-pickup-delivery-option-generators-rs/package.json.liquid b/functions-local-pickup-delivery-option-generators-rs/package.json.liquid index 98d6960c..f10238c8 100644 --- a/functions-local-pickup-delivery-option-generators-rs/package.json.liquid +++ b/functions-local-pickup-delivery-option-generators-rs/package.json.liquid @@ -7,7 +7,7 @@ "test": "vitest run" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-location-rules-js/package.json.liquid b/functions-location-rules-js/package.json.liquid index b6d85ff2..82ffbdf6 100644 --- a/functions-location-rules-js/package.json.liquid +++ b/functions-location-rules-js/package.json.liquid @@ -30,7 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-location-rules-rs/package.json.liquid b/functions-location-rules-rs/package.json.liquid index 98d6960c..f10238c8 100644 --- a/functions-location-rules-rs/package.json.liquid +++ b/functions-location-rules-rs/package.json.liquid @@ -7,7 +7,7 @@ "test": "vitest run" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-order-discounts-js/package.json.liquid b/functions-order-discounts-js/package.json.liquid index b6d85ff2..82ffbdf6 100644 --- a/functions-order-discounts-js/package.json.liquid +++ b/functions-order-discounts-js/package.json.liquid @@ -30,7 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-order-discounts-rs/package.json.liquid b/functions-order-discounts-rs/package.json.liquid index 98d6960c..f10238c8 100644 --- a/functions-order-discounts-rs/package.json.liquid +++ b/functions-order-discounts-rs/package.json.liquid @@ -7,7 +7,7 @@ "test": "vitest run" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-payment-customization-js/package.json.liquid b/functions-payment-customization-js/package.json.liquid index b6d85ff2..82ffbdf6 100644 --- a/functions-payment-customization-js/package.json.liquid +++ b/functions-payment-customization-js/package.json.liquid @@ -30,7 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-payment-customization-rs/package.json.liquid b/functions-payment-customization-rs/package.json.liquid index 98d6960c..f10238c8 100644 --- a/functions-payment-customization-rs/package.json.liquid +++ b/functions-payment-customization-rs/package.json.liquid @@ -7,7 +7,7 @@ "test": "vitest run" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-pickup-point-delivery-option-generators-js/package.json.liquid b/functions-pickup-point-delivery-option-generators-js/package.json.liquid index b6d85ff2..82ffbdf6 100644 --- a/functions-pickup-point-delivery-option-generators-js/package.json.liquid +++ b/functions-pickup-point-delivery-option-generators-js/package.json.liquid @@ -30,7 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-pickup-point-delivery-option-generators-rs/package.json.liquid b/functions-pickup-point-delivery-option-generators-rs/package.json.liquid index 98d6960c..f10238c8 100644 --- a/functions-pickup-point-delivery-option-generators-rs/package.json.liquid +++ b/functions-pickup-point-delivery-option-generators-rs/package.json.liquid @@ -7,7 +7,7 @@ "test": "vitest run" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-product-discounts-js/package.json.liquid b/functions-product-discounts-js/package.json.liquid index b6d85ff2..82ffbdf6 100644 --- a/functions-product-discounts-js/package.json.liquid +++ b/functions-product-discounts-js/package.json.liquid @@ -30,7 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-product-discounts-rs/package.json.liquid b/functions-product-discounts-rs/package.json.liquid index 98d6960c..f10238c8 100644 --- a/functions-product-discounts-rs/package.json.liquid +++ b/functions-product-discounts-rs/package.json.liquid @@ -7,7 +7,7 @@ "test": "vitest run" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-shipping-discounts-js/package.json.liquid b/functions-shipping-discounts-js/package.json.liquid index b6d85ff2..82ffbdf6 100644 --- a/functions-shipping-discounts-js/package.json.liquid +++ b/functions-shipping-discounts-js/package.json.liquid @@ -30,7 +30,7 @@ "@shopify/shopify_function": "2.0.0" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } } diff --git a/functions-shipping-discounts-rs/package.json.liquid b/functions-shipping-discounts-rs/package.json.liquid index 98d6960c..f10238c8 100644 --- a/functions-shipping-discounts-rs/package.json.liquid +++ b/functions-shipping-discounts-rs/package.json.liquid @@ -7,7 +7,7 @@ "test": "vitest run" }, "devDependencies": { - "@shopify/shopify-function-test-helpers": "~0.0.0", + "@shopify/shopify-function-test-helpers": "^1.0.0", "vitest": "^3.2.4" } }