diff --git a/jest.base.config.js b/jest.base.config.js deleted file mode 100644 index eb526b980..000000000 --- a/jest.base.config.js +++ /dev/null @@ -1,58 +0,0 @@ -// For a detailed explanation regarding each configuration property, visit: -// https://jestjs.io/docs/en/configuration.html - -module.exports = { - globals: { - __DEV__: true, - }, - // noStackTrace: true, - // bail: true, - // cache: false, - // verbose: true, - // watch: true, - coverageReporters: ['lcov'], - - coverageThreshold: { - global: { - // branches: 50, - // functions: 50, - // lines: 50, - // statements: 50 - }, - }, - - coveragePathIgnorePatterns: ['/node_modules/', '.d.ts$', '/__mocks__/'], - - testEnvironment: 'jest-environment-jsdom-sixteen', - - transform: { - '^.+\\.(ts)$': 'ts-jest', - }, - - coverageDirectory: './coverage/', - - collectCoverageFrom: [ - 'src/**/*.ts', - ], - - setupFiles: [ - 'jest-date-mock', - 'jest-localstorage-mock', - ], - - transformIgnorePatterns: [ - 'node_modules', - '/node_modules', - ], - - testMatch: ['/**/__tests__/**/*spec.[jt]s?(x)'], - - watchPlugins: [ - 'jest-watch-typeahead/filename', - 'jest-watch-typeahead/testname', - ['jest-watch-toggle-config', { setting: 'verbose' }], - ['jest-watch-toggle-config', { setting: 'collectCoverage' }], - ['jest-watch-toggle-config', { setting: 'notify' }], - ['jest-watch-toggle-config', { setting: 'bail' }], - ], -}; diff --git a/package.json b/package.json index b8b087f3b..8eded3ac2 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,6 @@ "husky": "^7.0.4", "jest": "^27.4.7", "jest-date-mock": "^1.0.8", - "jest-environment-jsdom-sixteen": "^2.0.0", "jest-localstorage-mock": "^2.4.18", "jest-silent-reporter": "^0.5.0", "jest-transform-stub": "^2.0.0", diff --git a/packages/api-client/__tests__/api/storeConfig/storeConfig.spec.ts b/packages/api-client/__tests__/api/storeConfig/storeConfig.spec.ts new file mode 100644 index 000000000..1207868f7 --- /dev/null +++ b/packages/api-client/__tests__/api/storeConfig/storeConfig.spec.ts @@ -0,0 +1,70 @@ +import request from '../../setup/request'; +import {STORE_CONFIG_MOCK_RESP} from './../../mockData/api/storeConfig' + +describe('[Magento-API-Client] storeConfig', () => { + it('Fetching the storeConfig', async () => { + const res = await request({ + body: JSON.stringify({ + query: ` + query { + storeConfig { + allow_guests_to_write_product_reviews + allow_items + allow_order + base_currency_code + catalog_default_sort_by + category_fixed_product_tax_display_setting + cms_home_page + cms_no_cookies + cms_no_route + configurable_thumbnail_source + copyright + default_description + default_display_currency_code + default_keywords + default_title + grid_per_page + grid_per_page_values + head_shortcut_icon + header_logo_src + is_default_store + is_default_store_group + list_mode + list_per_page + list_per_page_values + locale + logo_alt + logo_height + logo_width + magento_wishlist_general_is_enabled + minimum_password_length + no_route + product_fixed_product_tax_display_setting + product_reviews_enabled + required_character_classes_number + root_category_uid + sales_fixed_product_tax_display_setting + store_code + store_group_code + store_group_name + store_name + store_sort_order + timezone + title_prefix + title_separator + title_suffix + use_store_in_url + website_code + website_name + weight_unit + welcome + } + } + ` + }) + }); + const { data } = await res.json(); + + expect(data).toEqual(STORE_CONFIG_MOCK_RESP); + }); +}); diff --git a/packages/api-client/__tests__/mockData/api/storeConfig.ts b/packages/api-client/__tests__/mockData/api/storeConfig.ts new file mode 100644 index 000000000..4692b7027 --- /dev/null +++ b/packages/api-client/__tests__/mockData/api/storeConfig.ts @@ -0,0 +1,58 @@ +const STORE_CONFIG_MOCK_RESP = { + storeConfig: { + allow_guests_to_write_product_reviews: '1', + allow_items: null, + allow_order: null, + base_currency_code: 'USD', + catalog_default_sort_by: 'position', + category_fixed_product_tax_display_setting: 'FPT_DISABLED', + cms_home_page: 'home', + cms_no_cookies: 'enable-cookies', + cms_no_route: 'no-route', + configurable_thumbnail_source: 'parent', + copyright: 'Copyright © 2013-present Magento, Inc. All rights reserved.', + default_description: null, + default_display_currency_code: 'USD', + default_keywords: null, + default_title: 'Magento Commerce', + grid_per_page: 12, + grid_per_page_values: '12,24,36', + head_shortcut_icon: null, + header_logo_src: null, + is_default_store: true, + is_default_store_group: true, + list_mode: 'grid-list', + list_per_page: 10, + list_per_page_values: '5,10,15,20,25', + locale: 'en_US', + logo_alt: null, + logo_height: null, + logo_width: null, + magento_wishlist_general_is_enabled: '1', + minimum_password_length: '8', + no_route: 'cms/noroute/index', + product_fixed_product_tax_display_setting: 'FPT_DISABLED', + product_reviews_enabled: '1', + required_character_classes_number: '3', + root_category_uid: 'Mg==', + sales_fixed_product_tax_display_setting: 'FPT_DISABLED', + store_code: 'default', + store_group_code: 'main_website_store', + store_group_name: 'Main Website Store', + store_name: 'Default Store View', + store_sort_order: 0, + timezone: 'America/Chicago', + title_prefix: null, + title_separator: '-', + title_suffix: null, + use_store_in_url: false, + website_code: 'base', + website_name: 'Main Website', + weight_unit: 'lbs', + welcome: 'Default welcome msg!', + }, +}; + +export { + STORE_CONFIG_MOCK_RESP, +}; diff --git a/packages/api-client/__tests__/setup/handlers.ts b/packages/api-client/__tests__/setup/handlers.ts new file mode 100644 index 000000000..544bcb7bb --- /dev/null +++ b/packages/api-client/__tests__/setup/handlers.ts @@ -0,0 +1,12 @@ +import { graphql } from 'msw'; +import {STORE_CONFIG_MOCK_RESP} from './../mockData/api/storeConfig' + +const magento = graphql.link('https://magento2-instance.vuestorefront.io/graphql'); + +export const handlers = [ + magento.query('storeConfig', (req, res, ctx) => res( + ctx.data({ + data: STORE_CONFIG_MOCK_RESP, + }), + )), +]; diff --git a/packages/api-client/__tests__/setup/index.ts b/packages/api-client/__tests__/setup/index.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/api-client/__tests__/setup/request.ts b/packages/api-client/__tests__/setup/request.ts new file mode 100644 index 000000000..cc48316d3 --- /dev/null +++ b/packages/api-client/__tests__/setup/request.ts @@ -0,0 +1,11 @@ +import fetch from 'cross-fetch'; + +const request = ({ body }) => fetch('https://magento2-instance.vuestorefront.io/graphql', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body, +}); + +export default request; diff --git a/packages/api-client/__tests__/setup/server.ts b/packages/api-client/__tests__/setup/server.ts new file mode 100644 index 000000000..55673ce2b --- /dev/null +++ b/packages/api-client/__tests__/setup/server.ts @@ -0,0 +1,4 @@ +import { setupServer } from 'msw/node'; +import { handlers } from './handlers'; + +export const server = setupServer(...handlers) diff --git a/packages/api-client/jest.config.js b/packages/api-client/jest.config.js index dd14a17fd..8d990f8a0 100644 --- a/packages/api-client/jest.config.js +++ b/packages/api-client/jest.config.js @@ -1,13 +1,71 @@ -const baseConfig = require('../../jest.base.config'); - +/* eslint-disable unicorn/prefer-module */ module.exports = { - ...baseConfig, - transform: { - ...baseConfig.transform, - '\\.(gql|graphql)$': 'jest-transform-graphql', + globals: { + __DEV__: true, + }, + coverageReporters: [ + 'lcov', + ], + coverageThreshold: { + global: {}, }, - setupFilesAfterEnv: ['./__tests__/setup.ts'], + coveragePathIgnorePatterns: [ + '/node_modules/', + '.d.ts$', + '/__mocks__/', + ], + coverageDirectory: './coverage/', moduleNameMapper: { + '^@/(.*)$': '/$1', + '^~/(.*)$': '/$1', 'api-client(.*)$': '$1', }, + testEnvironment: 'jsdom', + transform: { + '^.+\\.(ts)$': 'ts-jest', + '^.+\\.js$': 'babel-jest', + }, + transformIgnorePatterns: [ + 'node_modules', + '/node_modules', + ], + testMatch: [ + '/**/__tests__/**/*spec.[jt]s?(x)', + ], + watchPlugins: [ + 'jest-watch-typeahead/filename', + 'jest-watch-typeahead/testname', + [ + 'jest-watch-toggle-config', + { + setting: 'verbose', + }, + ], + [ + 'jest-watch-toggle-config', + { + setting: 'collectCoverage', + }, + ], + [ + 'jest-watch-toggle-config', + { + setting: 'notify', + }, + ], + [ + 'jest-watch-toggle-config', + { + setting: 'bail', + }, + ], + ], + collectCoverageFrom: [ + '/src/**/*.ts', + ], + moduleFileExtensions: [ + 'js', + 'json', + 'ts', + ], }; diff --git a/packages/api-client/jest.setup.ts b/packages/api-client/jest.setup.ts new file mode 100644 index 000000000..f0430c7c4 --- /dev/null +++ b/packages/api-client/jest.setup.ts @@ -0,0 +1,11 @@ +import { server } from './__tests__/setup/server'; + +// Establish API mocking before all tests. +beforeAll(() => server.listen()); + +// Reset any request handlers that we may add during the tests, +// so they don't affect other tests. +afterEach(() => server.resetHandlers()); + +// Clean up after the tests are finished. +afterAll(() => server.close()); diff --git a/packages/api-client/package.json b/packages/api-client/package.json index 9f9cc4668..b7391fb56 100644 --- a/packages/api-client/package.json +++ b/packages/api-client/package.json @@ -38,6 +38,7 @@ "dotenv": "^12.0.1", "graphql-tools": "^8.2.0", "jest-transform-graphql": "^2.1.0", + "msw": "^0.36.4", "typescript": "^4.5.4", "webpack": "4.46.0" }, diff --git a/packages/composables/__tests__/getters/productHelpers.spec.ts b/packages/composables/__tests__/getters/productHelpers.spec.ts index c92051591..b4233c7cd 100644 --- a/packages/composables/__tests__/getters/productHelpers.spec.ts +++ b/packages/composables/__tests__/getters/productHelpers.spec.ts @@ -140,7 +140,7 @@ const product = { }] } as any; -describe('[commercetools-getters] product getters', () => { +describe('[magento-getters] product getters', () => { it('returns default values', () => { expect(getName(null)).toBe(''); expect(getSlug(null)).toBe(''); @@ -149,221 +149,41 @@ describe('[commercetools-getters] product getters', () => { }); it('returns name', () => { - expect(getName(product)).toBe('variant 1'); + expect(getName(product)).toBe('Joust Duffle Bag'); }); it('returns slug', () => { - expect(getSlug(product)).toBe('variant-1'); + expect(getSlug(product)).toBe('/joust-duffle-bag.html'); }); it('returns price', () => { - expect(getPrice(product)).toEqual({ regular: 12, special: 12 }); + expect(getPrice(product)).toEqual({ regular: 34, special: null }); }); it('returns gallery', () => { expect(getGallery(product)).toEqual([ { - small: 'imageV11/url.jpg', - big: 'imageV11/url.jpg', - normal: 'imageV11/url.jpg' - }, - { - small: 'imageV12/url.jpg', - big: 'imageV12/url.jpg', - normal: 'imageV12/url.jpg' + small: 'https://m2.caravelx.com/media/catalog/product/cache/746ba992681b73af7e339699b3e0caf7/m/b/mb01-blue-0.jpg', + normal: 'https://m2.caravelx.com/media/catalog/product/cache/746ba992681b73af7e339699b3e0caf7/m/b/mb01-blue-0.jpg', + big: 'https://m2.caravelx.com/media/catalog/product/cache/746ba992681b73af7e339699b3e0caf7/m/b/mb01-blue-0.jpg' } ]); }); it('returns cover image', () => { - expect(getCoverImage({ images: [] } as any)).toEqual(''); - expect(getCoverImage(product)).toEqual('imageV11/url.jpg'); - }); - - it('returns master variant', () => { - const variants = [ - { - _name: 'variant 1', - _master: false - }, - { - _name: 'variant 2', - _master: true - } - ]; - expect(getFiltered(variants as any, { master: true })).toEqual([{ - _name: 'variant 2', - _master: true - }]); - }); - - it('returns master variants', () => { - const variants = [ - { - _name: 'variant 1_1', - _master: false - }, - { - _name: 'variant 1_2', - _master: true - }, - { - _name: 'variant 2_1', - _master: true - }, - { - _name: 'variant 2_2', - _master: false - } - ]; - expect(getFiltered(variants as any, { master: true })).toEqual([ - { - _name: 'variant 1_2', - _master: true - }, - { - _name: 'variant 2_1', - _master: true - } - ]); - }); - - it('returns all variants', () => { - const variants = [ - { - _name: 'variant 1', - _master: false - }, - { - _name: 'variant 2', - _master: true - } - ]; - expect(getFiltered(variants as any)).toEqual(variants); - }); - - it('returns product by given attributes', () => { - const variant1 = { - ...product, - attributesRaw: [ - { - name: 'size', - value: '36', - _translated: '26', - attributeDefinition: { type: { name: 'text' } } - }, - { - name: 'color', - value: 'white', - _translated: 'white', - attributeDefinition: { type: { name: 'text' } } - } - ] - }; - const variant2 = { - ...product, - attributesRaw: [ - { - name: 'size', - value: '38', - _translated: '38', - attributeDefinition: { type: { name: 'text' } } - }, - { - name: 'color', - value: 'black', - _translated: 'black', - attributeDefinition: { type: { name: 'text' } } - } - ] - }; - - const variants = [variant1, variant2]; - - const attributes = { - color: 'black', - size: '38' - }; - expect(getFiltered(variants, { attributes })).toEqual([variant2]); - }); - - // Attributes - - it('returns product attributes', () => { - expect(getAttributes([product])).toEqual({ - articleNumberManufacturer: [{ - label: 'H805 C195 85072', - value: 'H805 C195 85072' - }] - }); - }); - - it('returns attributes of single product', () => { - expect(getAttributes(product)).toEqual({ articleNumberManufacturer: 'H805 C195 85072' }); - }); - - it('returns product unique attributes', () => { - const prod = { - ...product, - attributesRaw: [ - { - name: 'articleNumberManufacturer', - value: 'H805 C195 85072', - _translated: 'H805 C195 85072', - attributeDefinition: { type: { name: 'text' } } - }, - { - name: 'articleNumberManufacturer', - value: 'H805 C195 85072', - _translated: 'H805 C195 85072', - attributeDefinition: { type: { name: 'text' } } - } - ] - } as any; - - expect(getAttributes([prod])).toEqual({ - articleNumberManufacturer: [{ - label: 'H805 C195 85072', - value: 'H805 C195 85072' - }] - }); - }); - - it('returns filtered product attributes', () => { - const product = { - attributesRaw: [ - { - name: 'articleNumberManufacturer', - value: 'H805 C195 85072', - _translated: 'H805 C195 85072', - attributeDefinition: { type: { name: 'text' } } - }, - { - name: 'color', - value: 'H805 C195 85072', - _translated: 'H805 C195 85072', - attributeDefinition: { type: { name: 'text' } } - } - ] - } as any; - - expect(getAttributes([product], ['color'])).toEqual({ - color: [{ - value: 'H805 C195 85072', - label: 'H805 C195 85072' - }] - }); + expect(getCoverImage({ images: [] } as any)).toEqual(null); + expect(getCoverImage(product)).toEqual('https://m2.caravelx.com/media/catalog/product/cache/746ba992681b73af7e339699b3e0caf7/m/b/mb01-blue-0.jpg'); }); it('returns product categories', () => { expect(getCategoryIds(product)).toEqual([ - 'catA', - 'catB' + 'Mw==', + 'NA==' ]); }); it('returns product ID', () => { - expect(getId(product)).toEqual(1234); + expect(getId(product)).toEqual('MQ=='); }); it('returns empty array if there is no product', () => { diff --git a/packages/composables/jest.config.js b/packages/composables/jest.config.js index d9b5f2a65..6d23ed571 100644 --- a/packages/composables/jest.config.js +++ b/packages/composables/jest.config.js @@ -1,9 +1,70 @@ -const baseConfig = require('./../../jest.base.config'); - +/* eslint-disable unicorn/prefer-module */ module.exports = { - ...baseConfig, - coverageReporters: ['html', 'lcov', 'text'], - rootDir: __dirname, - setupFilesAfterEnv: ['./__tests__/setup.ts'], - watchPathIgnorePatterns: ['/node_modules/'] + globals: { + __DEV__: true, + }, + coverageReporters: [ + 'lcov', + ], + coverageThreshold: { + global: {}, + }, + coveragePathIgnorePatterns: [ + '/node_modules/', + '.d.ts$', + '/__mocks__/', + ], + coverageDirectory: './coverage/', + moduleNameMapper: { + '^@/(.*)$': '/$1', + '^~/(.*)$': '/$1', + }, + testEnvironment: 'jsdom', + transform: { + '^.+\\.(ts)$': 'ts-jest', + '^.+\\.js$': 'babel-jest', + }, + transformIgnorePatterns: [ + 'node_modules', + '/node_modules', + ], + testMatch: [ + '/**/__tests__/**/*spec.[jt]s?(x)', + ], + watchPlugins: [ + 'jest-watch-typeahead/filename', + 'jest-watch-typeahead/testname', + [ + 'jest-watch-toggle-config', + { + setting: 'verbose', + }, + ], + [ + 'jest-watch-toggle-config', + { + setting: 'collectCoverage', + }, + ], + [ + 'jest-watch-toggle-config', + { + setting: 'notify', + }, + ], + [ + 'jest-watch-toggle-config', + { + setting: 'bail', + }, + ], + ], + collectCoverageFrom: [ + '/composables/**/*.ts', + ], + moduleFileExtensions: [ + 'js', + 'json', + 'ts', + ], }; diff --git a/packages/composables/src/getters/productGetters.ts b/packages/composables/src/getters/productGetters.ts index 23920cb84..abd2d7af7 100644 --- a/packages/composables/src/getters/productGetters.ts +++ b/packages/composables/src/getters/productGetters.ts @@ -26,8 +26,8 @@ export const getName = (product: Product): string => { }; export const getSlug = (product: Product, category?: Category): string => { - const rewrites = product.url_rewrites; - let url = `/p/${product.sku}`; + const rewrites = product?.url_rewrites; + let url = product?.sku ? `/p/${product.sku}` : ''; if (!rewrites || rewrites.length === 0) { return url; } diff --git a/packages/theme/jest.config.js b/packages/theme/jest.config.js index c916bdd18..ee617d53e 100644 --- a/packages/theme/jest.config.js +++ b/packages/theme/jest.config.js @@ -1,33 +1,23 @@ /* eslint-disable unicorn/prefer-module */ module.exports = { - globals: { - __DEV__: true, - }, - // noStackTrace: true, - // bail: true, - // cache: false, - // verbose: true, - // watch: true, + globals: { __DEV__: true }, + coverageReporters: ['lcov'], - coverageThreshold: { - global: { - // branches: 50, - // functions: 50, - // lines: 50, - // statements: 50 - }, - }, + coverageThreshold: { global: {} }, coveragePathIgnorePatterns: ['/node_modules/', '.d.ts$', '/__mocks__/'], - collectCoverage: false, - testEnvironment: 'jsdom', + + coverageDirectory: './coverage/', + moduleNameMapper: { '^@/(.*)$': '/$1', '^~/(.*)$': '/$1', '^vue$': 'vue/dist/vue.common.js', }, - moduleFileExtensions: ['js', 'vue', 'json', 'ts'], + + testEnvironment: 'jsdom', + transform: { '^.+\\.(ts)$': 'ts-jest', '^.+\\.js$': 'babel-jest', @@ -35,8 +25,6 @@ module.exports = { '^.+\\.(css|svg)': 'jest-transform-stub', }, - coverageDirectory: './coverage/', - collectCoverageFrom: [ '/components/**/*.vue', '/pages/**/*.vue', @@ -53,13 +41,10 @@ module.exports = { transformIgnorePatterns: [ 'node_modules/(?!(@storefront-ui)|vee-validate/dist/rules|nouislider)', - ], testMatch: ['/**/__tests__/**/*spec.[jt]s?(x)'], - modulePathIgnorePatterns: ['_theme', 'tests/e2e'], - watchPlugins: [ 'jest-watch-typeahead/filename', 'jest-watch-typeahead/testname', @@ -68,4 +53,10 @@ module.exports = { ['jest-watch-toggle-config', { setting: 'notify' }], ['jest-watch-toggle-config', { setting: 'bail' }], ], + + collectCoverage: false, + + moduleFileExtensions: ['js', 'vue', 'json', 'ts'], + + modulePathIgnorePatterns: ['_theme', 'tests/e2e'], };