From b89a946d8d7a68185b896bb600e6a14cd2399e21 Mon Sep 17 00:00:00 2001 From: "Ronald A. Richardson" Date: Fri, 9 Oct 2026 20:56:21 +0800 Subject: [PATCH] test: make the engine's own test suite bootable The dummy app never ran: ember-classic-decorator (unused) crashes on Ember 5, lazy loading kept the engine's modules out of the test bundle, and the host services, config and intl data the panels need were missing. Mirrors what fleetops already does: eager loading when `ember test` runs from this package, an inert stand-in for the console's extensions module, the API config the core adapter reads at module scope, and the legacy built-in components the engine's templates still use. The dummy intl service ignores missing locale data, since headless Chrome has no number formats for every bundled locale, and the order details and network controller tests stub the host router, fetch and app cache the way the widget tests already do. --- index.js | 8 +- package.json | 4 +- pnpm-lock.yaml | 84 +++++++++++-------- tests/dummy/app/services/intl.js | 18 ++++ tests/dummy/config/environment.js | 14 ++++ .../components/shared-identity-test.js | 4 +- .../storefront/order/details-test.js | 53 ++++++++++-- .../components/widget/customers-test.js | 8 ++ tests/test-helper.js | 11 +++ .../unit/controllers/customers/index-test.js | 2 + .../networks/index/network/customers-test.js | 8 ++ .../networks/index/network/orders-test.js | 8 ++ tests/unit/controllers/orders/index-test.js | 2 + 13 files changed, 174 insertions(+), 50 deletions(-) create mode 100644 tests/dummy/app/services/intl.js diff --git a/index.js b/index.js index 005d7714..10a66128 100644 --- a/index.js +++ b/index.js @@ -8,8 +8,14 @@ const path = require('path'); module.exports = buildEngine({ name, + // Lazy loading keeps the engine out of the host bundle, but it also keeps the + // engine's modules out of the dummy app that `ember test` builds, so every test + // importing `@fleetbase/storefront-engine/*` fails to load. Eager loading is + // scoped to `ember test` run from this package, so host apps consuming the + // engine, including their own test builds, keep lazy loading. Addon index + // files are evaluated before ember-cli assigns EMBER_ENV, hence the argv check. lazyLoading: { - enabled: true, + enabled: !(process.argv.includes('test') && process.cwd() === __dirname), }, isDevelopingAddon() { diff --git a/package.json b/package.json index 344a57db..33417fed 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "@babel/core": "^7.23.2", "@fleetbase/ember-core": "^0.3.25", "@fleetbase/ember-ui": "^0.4.5", - "@fleetbase/fleetops-data": "^0.2.3", + "@fleetbase/fleetops-data": "^0.2.2", "@fortawesome/ember-fontawesome": "^2.0.0", "@fortawesome/fontawesome-svg-core": "6.4.0", "@fortawesome/free-brands-svg-icons": "6.4.0", @@ -61,6 +61,7 @@ "devDependencies": { "@babel/eslint-parser": "^7.22.15", "@babel/plugin-proposal-decorators": "^7.23.2", + "@ember/legacy-built-in-components": "^0.4.2", "@ember/optional-features": "^2.0.0", "@ember/test-helpers": "^3.2.0", "@embroider/test-setup": "^3.0.2", @@ -71,7 +72,6 @@ "broccoli-funnel": "^3.0.8", "broccoli-merge-trees": "^4.2.0", "concurrently": "^8.2.2", - "ember-classic-decorator": "^3.0.0", "ember-cli": "~5.4.1", "ember-cli-clean-css": "^3.0.0", "ember-cli-dependency-checker": "^3.3.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 676fd872..091b4870 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,8 +18,8 @@ importers: specifier: ^0.4.5 version: 0.4.5(fd4e3593913b6af1971bbb09f229d016) '@fleetbase/fleetops-data': - specifier: ^0.1.37 - version: 0.1.37(d08c013ce78c1181b04d076f9e3ef4de) + specifier: ^0.2.2 + version: 0.2.2(d08c013ce78c1181b04d076f9e3ef4de) '@fortawesome/ember-fontawesome': specifier: ^2.0.0 version: 2.0.0(@babel/core@7.29.7(supports-color@8.1.1))(ember-source@5.4.1(@babel/core@7.29.7(supports-color@8.1.1))(@glimmer/component@1.1.2(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(rsvp@4.8.5)(supports-color@8.1.1)(webpack@5.107.2(clean-css@5.3.3)(postcss@8.5.15)(uglify-js@3.19.3)))(rollup@2.80.0)(supports-color@8.1.1)(webpack@5.107.2(clean-css@5.3.3)(postcss@8.5.15)(uglify-js@3.19.3)) @@ -57,6 +57,9 @@ importers: '@babel/plugin-proposal-decorators': specifier: ^7.23.2 version: 7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1) + '@ember/legacy-built-in-components': + specifier: ^0.4.2 + version: 0.4.2(@babel/core@7.29.7(supports-color@8.1.1))(ember-source@5.4.1(@babel/core@7.29.7(supports-color@8.1.1))(@glimmer/component@1.1.2(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(rsvp@4.8.5)(supports-color@8.1.1)(webpack@5.107.2(clean-css@5.3.3)(postcss@8.5.15)(uglify-js@3.19.3)))(supports-color@8.1.1) '@ember/optional-features': specifier: ^2.0.0 version: 2.3.0(supports-color@8.1.1) @@ -87,9 +90,6 @@ importers: concurrently: specifier: ^8.2.2 version: 8.2.2 - ember-classic-decorator: - specifier: ^3.0.0 - version: 3.0.1(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1) ember-cli: specifier: ~5.4.1 version: 5.4.2(@babel/core@7.29.7(supports-color@8.1.1))(@types/node@25.9.1)(debug@4.4.3(supports-color@8.1.1))(handlebars@4.7.9)(supports-color@8.1.1)(underscore@1.13.8) @@ -116,7 +116,7 @@ importers: version: 4.12.8(@babel/core@7.29.7(supports-color@8.1.1))(@ember/string@3.1.1(supports-color@8.1.1))(@glimmer/tracking@1.1.2)(ember-source@5.4.1(@babel/core@7.29.7(supports-color@8.1.1))(@glimmer/component@1.1.2(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(rsvp@4.8.5)(supports-color@8.1.1)(webpack@5.107.2(clean-css@5.3.3)(postcss@8.5.15)(uglify-js@3.19.3)))(supports-color@8.1.1)(webpack@5.107.2(clean-css@5.3.3)(postcss@8.5.15)(uglify-js@3.19.3)) ember-engines: specifier: ^0.9.0 - version: 0.9.0(@babel/core@7.29.7(supports-color@8.1.1))(ember-source@5.4.1(@babel/core@7.29.7(supports-color@8.1.1))(@glimmer/component@1.1.2(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(rsvp@4.8.5)(supports-color@8.1.1)(webpack@5.107.2(clean-css@5.3.3)(postcss@8.5.15)(uglify-js@3.19.3)))(supports-color@8.1.1) + version: 0.9.0(@babel/core@7.29.7(supports-color@8.1.1))(@ember/legacy-built-in-components@0.4.2(@babel/core@7.29.7(supports-color@8.1.1))(ember-source@5.4.1(@babel/core@7.29.7(supports-color@8.1.1))(@glimmer/component@1.1.2(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(rsvp@4.8.5)(supports-color@8.1.1)(webpack@5.107.2(clean-css@5.3.3)(postcss@8.5.15)(uglify-js@3.19.3)))(supports-color@8.1.1))(ember-source@5.4.1(@babel/core@7.29.7(supports-color@8.1.1))(@glimmer/component@1.1.2(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(rsvp@4.8.5)(supports-color@8.1.1)(webpack@5.107.2(clean-css@5.3.3)(postcss@8.5.15)(uglify-js@3.19.3)))(supports-color@8.1.1) ember-load-initializers: specifier: ^2.1.2 version: 2.1.2(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1) @@ -1147,6 +1147,12 @@ packages: '@ember/edition-utils@1.2.0': resolution: {integrity: sha512-VmVq/8saCaPdesQmftPqbFtxJWrzxNGSQ+e8x8LLe3Hjm36pJ04Q8LeORGZkAeOhldoUX9seLGmSaHeXkIqoog==} + '@ember/legacy-built-in-components@0.4.2': + resolution: {integrity: sha512-rJulbyVQIVe1zEDQDqAQHechHy44DsS2qxO24+NmU/AYxwPFSzWC/OZNCDFSfLU+Y5BVd/00qjxF0pu7Nk+TNA==} + engines: {node: 12.* || 14.* || >= 16} + peerDependencies: + ember-source: '*' + '@ember/optional-features@2.3.0': resolution: {integrity: sha512-+M8CkPledQEaDbfIlwlq6Phgpm5jdT3a6WVDJk7b/zadw5xAJkuQKVK7DgR0SFgHGiWlyn6a8AU5p2mCA706RA==} engines: {node: 10.* || 12.* || >= 14} @@ -1283,14 +1289,14 @@ packages: resolution: {integrity: sha512-C/+OvMpH5fCKYY5v+CteR6Tx6IAI33nfvOrmo7mFGDnyKDsjplsVVgWpsecLG94fJvpuVVI+CFvaiH50GUM3Mg==} engines: {node: '>= 18'} - '@fleetbase/fleetops-data@0.1.37': - resolution: {integrity: sha512-VGVWaGlwQAqHWA9/A80jKAjoDkAM7U9Ve1UVmKkCTlolqUd5/k/Z66rVC0iFUijj8qzkMCdahdh3mBPQ6x71WA==} - engines: {node: '>= 18'} - '@fleetbase/fleetops-data@0.1.40': resolution: {integrity: sha512-bp4tWaS2cpnitjtmH9hm3T7milwSqgt4j3T/KA8cvsFpbg7p303ADb5CNml5RsribgdBcRYtMsLEFYeYnU9dpg==} engines: {node: '>= 18'} + '@fleetbase/fleetops-data@0.2.2': + resolution: {integrity: sha512-HDgcGpJAk8q+sSmV070nCh02o4S0kuFCvwrf+Ltb+IrUkQ2RhDL/w8gdrqM65HrgbgWxQnslIeqzKfF6pV4/DA==} + engines: {node: '>= 18'} + '@fleetbase/intl-lint@0.0.1': resolution: {integrity: sha512-LkjxJr15hSiGmqh3JwixcpjmkhXNieNAEgQUVv1Duo50jTr/D5WXEyOaeI8wuVnVFhT+FS/DMqm403DgSKlsEg==} hasBin: true @@ -3140,6 +3146,7 @@ packages: concat-stream@1.6.2: resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} concurrently@8.2.2: resolution: {integrity: sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==} @@ -3750,10 +3757,6 @@ packages: ember-resolver: '>= 8.0.0' ember-source: ^3.28.0 || ^4.0.0 || >=5.0.0 - ember-classic-decorator@3.0.1: - resolution: {integrity: sha512-IoocHPX1cY93Sma7VeDGbF0M1+TkBWDJLus+RD01902eD+KHEL2+diwM+iayCyO+1/xaUzdzNGh35J+i+TCxoA==} - engines: {node: 12.* || 14.* || >= 16} - ember-cli-babel-plugin-helpers@1.1.1: resolution: {integrity: sha512-sKvOiPNHr5F/60NLd7SFzMpYPte/nnGkq/tMIfXejfKHIhaiIkYFqX8Z9UFTKWLLn+V7NOaby6niNPZUdvKCRw==} engines: {node: 6.* || 8.* || >= 10.*} @@ -9866,6 +9869,18 @@ snapshots: '@ember/edition-utils@1.2.0': {} + '@ember/legacy-built-in-components@0.4.2(@babel/core@7.29.7(supports-color@8.1.1))(ember-source@5.4.1(@babel/core@7.29.7(supports-color@8.1.1))(@glimmer/component@1.1.2(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(rsvp@4.8.5)(supports-color@8.1.1)(webpack@5.107.2(clean-css@5.3.3)(postcss@8.5.15)(uglify-js@3.19.3)))(supports-color@8.1.1)': + dependencies: + '@embroider/macros': 1.20.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1) + ember-cli-babel: 7.26.11(supports-color@8.1.1) + ember-cli-htmlbars: 5.7.2(supports-color@8.1.1) + ember-cli-typescript: 4.2.1(supports-color@8.1.1) + ember-source: 5.4.1(@babel/core@7.29.7(supports-color@8.1.1))(@glimmer/component@1.1.2(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(rsvp@4.8.5)(supports-color@8.1.1)(webpack@5.107.2(clean-css@5.3.3)(postcss@8.5.15)(uglify-js@3.19.3)) + transitivePeerDependencies: + - '@babel/core' + - '@glint/template' + - supports-color + '@ember/optional-features@2.3.0(supports-color@8.1.1)': dependencies: chalk: 4.1.2 @@ -9953,7 +9968,7 @@ snapshots: find-up: 5.0.0 lodash: 4.18.1 resolve: 1.22.12 - semver: 7.8.1 + semver: 7.8.5 transitivePeerDependencies: - '@babel/core' - supports-color @@ -10001,10 +10016,10 @@ snapshots: js-string-escape: 1.0.1 lodash: 4.18.1 minimatch: 3.1.5 - pkg-entry-points: 1.1.1 + pkg-entry-points: 1.1.2 resolve-package-path: 4.0.3 resolve.exports: 2.0.3 - semver: 7.8.1 + semver: 7.8.5 typescript-memoize: 1.1.1 transitivePeerDependencies: - supports-color @@ -10249,6 +10264,7 @@ snapshots: - ember-cli-mirage - ember-resolver - ember-source + - encoding - eslint - miragejs - postcss @@ -10263,7 +10279,7 @@ snapshots: - webpack-command - yaml - '@fleetbase/fleetops-data@0.1.37(d08c013ce78c1181b04d076f9e3ef4de)': + '@fleetbase/fleetops-data@0.1.40(d08c013ce78c1181b04d076f9e3ef4de)': dependencies: '@babel/core': 7.29.7(supports-color@8.1.1) '@fleetbase/ember-core': 0.3.25(d08c013ce78c1181b04d076f9e3ef4de) @@ -10284,10 +10300,10 @@ snapshots: - utf-8-validate - webpack - '@fleetbase/fleetops-data@0.1.40(d08c013ce78c1181b04d076f9e3ef4de)': + '@fleetbase/fleetops-data@0.2.2(d08c013ce78c1181b04d076f9e3ef4de)': dependencies: '@babel/core': 7.29.7(supports-color@8.1.1) - '@fleetbase/ember-core': 0.3.24(d08c013ce78c1181b04d076f9e3ef4de) + '@fleetbase/ember-core': 0.3.25(d08c013ce78c1181b04d076f9e3ef4de) date-fns: 2.30.0 ember-cli-babel: 8.3.1(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1) ember-cli-htmlbars: 6.3.0(supports-color@8.1.1) @@ -10298,6 +10314,7 @@ snapshots: - bufferutil - ember-resolver - ember-source + - encoding - eslint - supports-color - typescript @@ -11055,7 +11072,7 @@ snapshots: '@types/glob@9.0.0': dependencies: - glob: 8.1.0 + glob: 13.0.6 '@types/http-errors@2.0.5': {} @@ -11080,7 +11097,7 @@ snapshots: '@types/minimatch@6.0.0': dependencies: - minimatch: 7.4.9 + minimatch: 10.2.5 '@types/minimist@1.2.5': {} @@ -11586,7 +11603,7 @@ snapshots: babel-generator: 6.26.1 babel-helpers: 6.24.1(supports-color@8.1.1) babel-messages: 6.23.0 - babel-register: 6.26.0 + babel-register: 6.26.0(supports-color@8.1.1) babel-runtime: 6.26.0 babel-template: 6.26.0(supports-color@8.1.1) babel-traverse: 6.26.0(supports-color@8.1.1) @@ -11742,7 +11759,7 @@ snapshots: babel-plugin-syntax-dynamic-import@6.18.0: {} - babel-register@6.26.0: + babel-register@6.26.0(supports-color@8.1.1): dependencies: babel-core: 6.26.3(supports-color@8.1.1) babel-runtime: 6.26.0 @@ -11751,6 +11768,8 @@ snapshots: lodash: 4.18.1 mkdirp: 0.5.6 source-map-support: 0.4.18 + transitivePeerDependencies: + - supports-color babel-runtime@6.26.0: dependencies: @@ -13512,17 +13531,6 @@ snapshots: - '@babel/core' - supports-color - ember-classic-decorator@3.0.1(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1): - dependencies: - '@embroider/macros': 1.20.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1) - babel-plugin-filter-imports: 4.0.0 - ember-cli-babel: 7.26.11(supports-color@8.1.1) - ember-cli-htmlbars: 6.3.0(supports-color@8.1.1) - transitivePeerDependencies: - - '@babel/core' - - '@glint/template' - - supports-color - ember-cli-babel-plugin-helpers@1.1.1: {} ember-cli-babel@7.26.11(supports-color@8.1.1): @@ -13655,7 +13663,7 @@ snapshots: hash-for-dep: 1.5.2(supports-color@8.1.1) heimdalljs-logger: 0.1.10(supports-color@8.1.1) json-stable-stringify: 1.3.0 - semver: 7.8.1 + semver: 7.8.5 silent-error: 1.1.1(supports-color@8.1.1) strip-bom: 4.0.0 walk-sync: 2.2.0 @@ -14173,7 +14181,7 @@ snapshots: transitivePeerDependencies: - supports-color - ember-engines@0.9.0(@babel/core@7.29.7(supports-color@8.1.1))(ember-source@5.4.1(@babel/core@7.29.7(supports-color@8.1.1))(@glimmer/component@1.1.2(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(rsvp@4.8.5)(supports-color@8.1.1)(webpack@5.107.2(clean-css@5.3.3)(postcss@8.5.15)(uglify-js@3.19.3)))(supports-color@8.1.1): + ember-engines@0.9.0(@babel/core@7.29.7(supports-color@8.1.1))(@ember/legacy-built-in-components@0.4.2(@babel/core@7.29.7(supports-color@8.1.1))(ember-source@5.4.1(@babel/core@7.29.7(supports-color@8.1.1))(@glimmer/component@1.1.2(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(rsvp@4.8.5)(supports-color@8.1.1)(webpack@5.107.2(clean-css@5.3.3)(postcss@8.5.15)(uglify-js@3.19.3)))(supports-color@8.1.1))(ember-source@5.4.1(@babel/core@7.29.7(supports-color@8.1.1))(@glimmer/component@1.1.2(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(rsvp@4.8.5)(supports-color@8.1.1)(webpack@5.107.2(clean-css@5.3.3)(postcss@8.5.15)(uglify-js@3.19.3)))(supports-color@8.1.1): dependencies: '@embroider/macros': 1.20.3(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1) amd-name-resolver: 1.3.1 @@ -14193,6 +14201,8 @@ snapshots: ember-cli-version-checker: 5.1.2(supports-color@8.1.1) ember-source: 5.4.1(@babel/core@7.29.7(supports-color@8.1.1))(@glimmer/component@1.1.2(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(rsvp@4.8.5)(supports-color@8.1.1)(webpack@5.107.2(clean-css@5.3.3)(postcss@8.5.15)(uglify-js@3.19.3)) lodash: 4.18.1 + optionalDependencies: + '@ember/legacy-built-in-components': 0.4.2(@babel/core@7.29.7(supports-color@8.1.1))(ember-source@5.4.1(@babel/core@7.29.7(supports-color@8.1.1))(@glimmer/component@1.1.2(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(rsvp@4.8.5)(supports-color@8.1.1)(webpack@5.107.2(clean-css@5.3.3)(postcss@8.5.15)(uglify-js@3.19.3)))(supports-color@8.1.1) transitivePeerDependencies: - '@babel/core' - '@glint/template' diff --git a/tests/dummy/app/services/intl.js b/tests/dummy/app/services/intl.js new file mode 100644 index 00000000..90cd3308 --- /dev/null +++ b/tests/dummy/app/services/intl.js @@ -0,0 +1,18 @@ +import IntlService from 'ember-intl/services/intl'; + +/** + * ember-intl builds a formatter for every bundled locale when the service is + * created. Headless Chrome ships no number-format data for some of them + * (Mongolian among them), which ember-intl's default handler turns into a thrown + * error inside whichever test first touches intl. Missing locale data and + * missing translations are not what any test here checks, so both are ignored. + */ +export default class DummyIntlService extends IntlService { + onIntlError(error) { + if (error?.code === 'MISSING_DATA' || error?.code === 'MISSING_TRANSLATION') { + return; + } + + super.onIntlError(error); + } +} diff --git a/tests/dummy/config/environment.js b/tests/dummy/config/environment.js index 61f3a09d..12eb0fdb 100644 --- a/tests/dummy/config/environment.js +++ b/tests/dummy/config/environment.js @@ -14,6 +14,20 @@ module.exports = function (environment) { }, }, + // `@fleetbase/ember-core`'s application adapter reads `config.API.host` at + + // module scope, so the dummy application must declare it before any + + // adapter module can even be evaluated. The values are deliberately + + // obviously-fake: nothing in the suite performs a real request. + + API: { + host: 'https://api.fleetbase.test', + + namespace: 'int/v1', + }, + APP: { // Here you can pass flags/options to your application instance // when it is created diff --git a/tests/integration/components/shared-identity-test.js b/tests/integration/components/shared-identity-test.js index 00bf135c..aed5eba7 100644 --- a/tests/integration/components/shared-identity-test.js +++ b/tests/integration/components/shared-identity-test.js @@ -17,7 +17,7 @@ module('Integration | Component | shared identity components', function (hooks) }); test('a driver identity cell renders the name, status dot and vehicle badge from the shared descriptor', async function (assert) { - this.set('row', { driver_assigned: { resourceType: 'driver', name: 'Ada Driver', status: 'available', vehicle_name: 'Truck 10' } }); + this.set('row', { driver_assigned: { resourceType: 'driver', name: 'Ada Driver', status: 'available', online: true, vehicle_name: 'Truck 10' } }); this.set('column', { resourceType: 'driver', resourcePath: 'driver_assigned', popover: false }); await render(hbs``); @@ -52,7 +52,7 @@ module('Integration | Component | shared identity components', function (hooks) `); assert.dom('[data-test-customer] [data-test-resource-pill-title]').hasText('Ava Chen'); - assert.dom('[data-test-customer] [data-test-resource-pill-subtitle]').hasText('Customer'); + assert.dom('[data-test-customer] [data-test-resource-pill-subtitle]').hasText('Contact', 'the polymorphic type reads as a person would say it'); assert.dom('[data-test-driver] [data-test-resource-pill-title]').hasText('Ada Driver'); assert.dom('[data-test-driver] [data-test-resource-pill-subtitle]').hasText('+15550100'); assert.dom('[data-test-place] [data-test-resource-pill-title]').hasText('Depot'); diff --git a/tests/integration/components/storefront/order/details-test.js b/tests/integration/components/storefront/order/details-test.js index 981b8944..185ebc4a 100644 --- a/tests/integration/components/storefront/order/details-test.js +++ b/tests/integration/components/storefront/order/details-test.js @@ -1,13 +1,49 @@ import { module, test } from 'qunit'; import { setupRenderingTest } from 'dummy/tests/helpers'; -import { render } from '@ember/test-helpers'; +import { setupIntl } from 'ember-intl/test-support'; +import { render, findAll } from '@ember/test-helpers'; +import Service from '@ember/service'; import { hbs } from 'ember-cli-htmlbars'; import { initialize } from '@fleetbase/fleetops-data/instance-initializers/register-shared-resource-descriptors'; module('Integration | Component | storefront/order/details', function (hooks) { setupRenderingTest(hooks); + setupIntl(hooks, 'en-us'); hooks.beforeEach(function () { + // The activity, route and tracking panels fetch on insert and the dummy app has + // no API. A request that never answers leaves each task pending, and ember-concurrency + // cancels it with its component, so nothing writes to a torn-down panel. + this.owner.register( + 'service:fetch', + class extends Service { + get() { + return new Promise(() => {}); + } + + post() { + return new Promise(() => {}); + } + } + ); + // The app cache keeps a proxy that outlives a test's owner; the activity panel reads + // it while initialising, so give it an inert cache like the widget tests do. + this.owner.register( + 'service:app-cache', + class extends Service { + get() { + return undefined; + } + + set() {} + + setEmberData() {} + + getEmberData() { + return []; + } + } + ); initialize(this.owner); }); @@ -55,13 +91,14 @@ module('Integration | Component | storefront/order/details', function (hooks) { await render(hbs``); - assert.dom('.next-content-panel-title-container').hasTextContaining('Activity'); - assert.dom('.next-content-panel-title-container').hasTextContaining('Store'); - assert.dom('.next-content-panel-title-container').hasTextContaining('Order'); - assert.dom('.next-content-panel-title-container').hasTextContaining('Details'); - assert.dom('.next-content-panel-title-container').hasTextContaining('Customer Insights'); - assert.dom('.next-content-panel-title-container').hasTextContaining('Route'); - assert.dom('.next-content-panel-title-container').hasTextContaining('Metadata'); + const titles = findAll('.next-content-panel-title-container').map((element) => element.textContent.trim()); + + for (const title of ['Activity', 'Store', 'Order', 'Details', 'Customer Insights', 'Route', 'Metadata']) { + assert.ok( + titles.some((text) => text.includes(title)), + `a panel titled ${title} renders` + ); + } assert.dom('.storefront-order-person__name').hasTextContaining('Tasty Store'); assert.dom('[data-test-order-driver-pill] [data-test-resource-pill-title]').hasText('No driver assigned', 'an unassigned driver is a static pill with the fallback title'); assert.dom('[data-test-order-customer-pill] [data-test-resource-pill-title]').hasText('No customer'); diff --git a/tests/integration/components/widget/customers-test.js b/tests/integration/components/widget/customers-test.js index 4aa03639..9a9f20b2 100644 --- a/tests/integration/components/widget/customers-test.js +++ b/tests/integration/components/widget/customers-test.js @@ -26,6 +26,14 @@ class FetchStubService extends Service { } class IntlStubService extends Service { + exists() { + return false; + } + + onLocaleChanged() { + return () => {}; + } + t(key) { if (key === 'storefront.component.widget.customers.widget-title') { return 'Recent Customers'; diff --git a/tests/test-helper.js b/tests/test-helper.js index 4efd6e58..d355f8d0 100644 --- a/tests/test-helper.js +++ b/tests/test-helper.js @@ -5,6 +5,17 @@ import { setApplication } from '@ember/test-helpers'; import { setup } from 'qunit-dom'; import { start } from 'ember-qunit'; +// The universe extension manager imports a module the console host generates at build +// time. The engine's dummy app has no host, so provide an inert stand-in before boot. +if (typeof window.define === 'function' && !window.requirejs?.entries?.['@fleetbase/console/extensions']) { + window.define('@fleetbase/console/extensions', ['exports'], function (exports) { + exports.getExtensionLoader = function () { + return null; + }; + exports.default = {}; + }); +} + setApplication(Application.create(config.APP)); setup(QUnit.assert); diff --git a/tests/unit/controllers/customers/index-test.js b/tests/unit/controllers/customers/index-test.js index d8189724..d29291a8 100644 --- a/tests/unit/controllers/customers/index-test.js +++ b/tests/unit/controllers/customers/index-test.js @@ -1,8 +1,10 @@ import { module, test } from 'qunit'; import { setupTest } from 'dummy/tests/helpers'; +import { setupIntl } from 'ember-intl/test-support'; module('Unit | Controller | customers/index', function (hooks) { setupTest(hooks); + setupIntl(hooks, 'en-us'); test('it exists', function (assert) { let controller = this.owner.lookup('controller:customers/index'); diff --git a/tests/unit/controllers/networks/index/network/customers-test.js b/tests/unit/controllers/networks/index/network/customers-test.js index bd90c9fb..b86fd691 100644 --- a/tests/unit/controllers/networks/index/network/customers-test.js +++ b/tests/unit/controllers/networks/index/network/customers-test.js @@ -1,8 +1,16 @@ import { module, test } from 'qunit'; import { setupTest } from 'dummy/tests/helpers'; +import { setupIntl } from 'ember-intl/test-support'; +import Service from '@ember/service'; module('Unit | Controller | networks/index/network/customers', function (hooks) { setupTest(hooks); + setupIntl(hooks, 'en-us'); + + hooks.beforeEach(function () { + // The engine's dummy app has no console host to provide the host router. + this.owner.register('service:hostRouter', class extends Service {}); + }); test('it exists', function (assert) { let controller = this.owner.lookup('controller:networks/index/network/customers'); diff --git a/tests/unit/controllers/networks/index/network/orders-test.js b/tests/unit/controllers/networks/index/network/orders-test.js index 141a91cc..a6b26e5d 100644 --- a/tests/unit/controllers/networks/index/network/orders-test.js +++ b/tests/unit/controllers/networks/index/network/orders-test.js @@ -1,8 +1,16 @@ import { module, test } from 'qunit'; import { setupTest } from 'dummy/tests/helpers'; +import { setupIntl } from 'ember-intl/test-support'; +import Service from '@ember/service'; module('Unit | Controller | networks/index/network/orders', function (hooks) { setupTest(hooks); + setupIntl(hooks, 'en-us'); + + hooks.beforeEach(function () { + // The engine's dummy app has no console host to provide the host router. + this.owner.register('service:hostRouter', class extends Service {}); + }); test('it exists', function (assert) { let controller = this.owner.lookup('controller:networks/index/network/orders'); diff --git a/tests/unit/controllers/orders/index-test.js b/tests/unit/controllers/orders/index-test.js index 6c9ca5d4..5a2748a1 100644 --- a/tests/unit/controllers/orders/index-test.js +++ b/tests/unit/controllers/orders/index-test.js @@ -1,9 +1,11 @@ import { module, test } from 'qunit'; import { setupTest } from 'dummy/tests/helpers'; +import { setupIntl } from 'ember-intl/test-support'; import Service from '@ember/service'; module('Unit | Controller | orders/index', function (hooks) { setupTest(hooks); + setupIntl(hooks, 'en-us'); test('it exists', function (assert) { let controller = this.owner.lookup('controller:orders/index');