| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544 |
- import {
- AddOptionGroupToProduct,
- CreateProduct,
- GenerateProductVariants,
- GetAssetList,
- GetProductList,
- GetProductWithVariants,
- LanguageCode,
- ProductWithVariants,
- RemoveOptionGroupFromProduct,
- SortOrder,
- UpdateProduct,
- UpdateProductVariants,
- } from '../../shared/generated-types';
- import { omit } from '../../shared/omit';
- import {
- ADD_OPTION_GROUP_TO_PRODUCT,
- CREATE_PRODUCT,
- GENERATE_PRODUCT_VARIANTS,
- GET_ASSET_LIST,
- GET_PRODUCT_LIST,
- GET_PRODUCT_WITH_VARIANTS,
- REMOVE_OPTION_GROUP_FROM_PRODUCT,
- UPDATE_PRODUCT,
- UPDATE_PRODUCT_VARIANTS,
- } from '../../admin-ui/src/app/data/definitions/product-definitions';
- import { TEST_SETUP_TIMEOUT_MS } from './config/test-config';
- import { TestClient } from './test-client';
- import { TestServer } from './test-server';
- // tslint:disable:no-non-null-assertion
- describe('Product resolver', () => {
- const client = new TestClient();
- const server = new TestServer();
- beforeAll(async () => {
- const token = await server.init({
- productCount: 20,
- customerCount: 1,
- });
- await client.init();
- }, TEST_SETUP_TIMEOUT_MS);
- afterAll(async () => {
- await server.destroy();
- });
- describe('products list query', () => {
- it('returns all products when no options passed', async () => {
- const result = await client.query<GetProductList.Query, GetProductList.Variables>(
- GET_PRODUCT_LIST,
- {
- languageCode: LanguageCode.en,
- },
- );
- expect(result.products.items.length).toBe(20);
- expect(result.products.totalItems).toBe(20);
- });
- it('limits result set with skip & take', async () => {
- const result = await client.query<GetProductList.Query, GetProductList.Variables>(
- GET_PRODUCT_LIST,
- {
- languageCode: LanguageCode.en,
- options: {
- skip: 0,
- take: 3,
- },
- },
- );
- expect(result.products.items.length).toBe(3);
- expect(result.products.totalItems).toBe(20);
- });
- it('filters by name', async () => {
- const result = await client.query<GetProductList.Query, GetProductList.Variables>(
- GET_PRODUCT_LIST,
- {
- languageCode: LanguageCode.en,
- options: {
- filter: {
- name: {
- contains: 'fish',
- },
- },
- },
- },
- );
- expect(result.products.items.length).toBe(1);
- expect(result.products.items[0].name).toBe('en Practical Frozen Fish');
- });
- it('sorts by name', async () => {
- const result = await client.query<GetProductList.Query, GetProductList.Variables>(
- GET_PRODUCT_LIST,
- {
- languageCode: LanguageCode.en,
- options: {
- sort: {
- name: SortOrder.ASC,
- },
- },
- },
- );
- expect(result.products.items.map(p => p.name)).toMatchSnapshot();
- });
- });
- describe('product query', () => {
- it('returns expected properties', async () => {
- const result = await client.query<GetProductWithVariants.Query, GetProductWithVariants.Variables>(
- GET_PRODUCT_WITH_VARIANTS,
- {
- languageCode: LanguageCode.en,
- id: 'T_2',
- },
- );
- if (!result.product) {
- fail('Product not found');
- return;
- }
- expect(omit(result.product, ['variants'])).toMatchSnapshot();
- expect(result.product.variants.length).toBe(2);
- });
- it('ProductVariant price properties are correct', async () => {
- const result = await client.query<GetProductWithVariants.Query, GetProductWithVariants.Variables>(
- GET_PRODUCT_WITH_VARIANTS,
- {
- languageCode: LanguageCode.en,
- id: 'T_2',
- },
- );
- if (!result.product) {
- fail('Product not found');
- return;
- }
- expect(result.product.variants[0].price).toBe(745);
- expect(result.product.variants[0].taxCategory).toEqual({
- id: 'T_1',
- name: 'Standard Tax',
- });
- });
- it('returns null when id not found', async () => {
- const result = await client.query<GetProductWithVariants.Query, GetProductWithVariants.Variables>(
- GET_PRODUCT_WITH_VARIANTS,
- {
- languageCode: LanguageCode.en,
- id: 'bad_id',
- },
- );
- expect(result.product).toBeNull();
- });
- });
- describe('product mutation', () => {
- let newProduct: ProductWithVariants.Fragment;
- it('createProduct creates a new Product', async () => {
- const result = await client.query<CreateProduct.Mutation, CreateProduct.Variables>(
- CREATE_PRODUCT,
- {
- input: {
- translations: [
- {
- languageCode: LanguageCode.en,
- name: 'en Baked Potato',
- slug: 'en-baked-potato',
- description: 'A baked potato',
- },
- {
- languageCode: LanguageCode.de,
- name: 'de Baked Potato',
- slug: 'de-baked-potato',
- description: 'Eine baked Erdapfel',
- },
- ],
- },
- },
- );
- newProduct = result.createProduct;
- expect(newProduct).toMatchSnapshot();
- });
- it('createProduct creates a new Product with assets', async () => {
- const assetsResult = await client.query<GetAssetList.Query, GetAssetList.Variables>(
- GET_ASSET_LIST,
- );
- const assetIds = assetsResult.assets.items.slice(0, 2).map(a => a.id);
- const featuredAssetId = assetsResult.assets.items[0].id;
- const result = await client.query<CreateProduct.Mutation, CreateProduct.Variables>(
- CREATE_PRODUCT,
- {
- input: {
- assetIds,
- featuredAssetId,
- translations: [
- {
- languageCode: LanguageCode.en,
- name: 'en Has Assets',
- slug: 'en-has-assets',
- description: 'A product with assets',
- },
- ],
- },
- },
- );
- expect(result.createProduct.assets.map(a => a.id)).toEqual(assetIds);
- expect(result.createProduct.featuredAsset!.id).toBe(featuredAssetId);
- });
- it('updateProduct updates a Product', async () => {
- const result = await client.query<UpdateProduct.Mutation, UpdateProduct.Variables>(
- UPDATE_PRODUCT,
- {
- input: {
- id: newProduct.id,
- translations: [
- {
- languageCode: LanguageCode.en,
- name: 'en Mashed Potato',
- slug: 'en-mashed-potato',
- description: 'A blob of mashed potato',
- },
- {
- languageCode: LanguageCode.de,
- name: 'de Mashed Potato',
- slug: 'de-mashed-potato',
- description: 'Eine blob von gemashed Erdapfel',
- },
- ],
- },
- },
- );
- expect(result.updateProduct).toMatchSnapshot();
- });
- it('updateProduct accepts partial input', async () => {
- const result = await client.query<UpdateProduct.Mutation, UpdateProduct.Variables>(
- UPDATE_PRODUCT,
- {
- input: {
- id: newProduct.id,
- translations: [
- {
- languageCode: LanguageCode.en,
- name: 'en Very Mashed Potato',
- },
- ],
- },
- },
- );
- expect(result.updateProduct.translations.length).toBe(2);
- expect(result.updateProduct.translations[0].name).toBe('en Very Mashed Potato');
- expect(result.updateProduct.translations[0].description).toBe('A blob of mashed potato');
- expect(result.updateProduct.translations[1].name).toBe('de Mashed Potato');
- });
- it('updateProduct adds Assets to a product and sets featured asset', async () => {
- const assetsResult = await client.query<GetAssetList.Query, GetAssetList.Variables>(
- GET_ASSET_LIST,
- );
- const assetIds = assetsResult.assets.items.map(a => a.id);
- const featuredAssetId = assetsResult.assets.items[2].id;
- const result = await client.query<UpdateProduct.Mutation, UpdateProduct.Variables>(
- UPDATE_PRODUCT,
- {
- input: {
- id: newProduct.id,
- assetIds,
- featuredAssetId,
- },
- },
- );
- expect(result.updateProduct.assets.map(a => a.id)).toEqual(assetIds);
- expect(result.updateProduct.featuredAsset!.id).toBe(featuredAssetId);
- });
- it('updateProduct sets a featured asset', async () => {
- const productResult = await client.query<
- GetProductWithVariants.Query,
- GetProductWithVariants.Variables
- >(GET_PRODUCT_WITH_VARIANTS, {
- id: newProduct.id,
- languageCode: LanguageCode.en,
- });
- const assets = productResult.product!.assets;
- const result = await client.query<UpdateProduct.Mutation, UpdateProduct.Variables>(
- UPDATE_PRODUCT,
- {
- input: {
- id: newProduct.id,
- featuredAssetId: assets[0].id,
- },
- },
- );
- expect(result.updateProduct.featuredAsset!.id).toBe(assets[0].id);
- });
- it('updateProduct errors with an invalid productId', async () => {
- try {
- await client.query<UpdateProduct.Mutation, UpdateProduct.Variables>(UPDATE_PRODUCT, {
- input: {
- id: '999',
- translations: [
- {
- languageCode: LanguageCode.en,
- name: 'en Mashed Potato',
- slug: 'en-mashed-potato',
- description: 'A blob of mashed potato',
- },
- {
- languageCode: LanguageCode.de,
- name: 'de Mashed Potato',
- slug: 'de-mashed-potato',
- description: 'Eine blob von gemashed Erdapfel',
- },
- ],
- },
- });
- fail('Should have thrown');
- } catch (err) {
- expect(err.message).toEqual(
- expect.stringContaining(`No Product with the id '999' could be found`),
- );
- }
- });
- it('addOptionGroupToProduct adds an option group', async () => {
- const result = await client.query<
- AddOptionGroupToProduct.Mutation,
- AddOptionGroupToProduct.Variables
- >(ADD_OPTION_GROUP_TO_PRODUCT, {
- optionGroupId: 'T_1',
- productId: newProduct.id,
- });
- expect(result.addOptionGroupToProduct.optionGroups.length).toBe(1);
- expect(result.addOptionGroupToProduct.optionGroups[0].id).toBe('T_1');
- });
- it('addOptionGroupToProduct errors with an invalid productId', async () => {
- try {
- await client.query<AddOptionGroupToProduct.Mutation, AddOptionGroupToProduct.Variables>(
- ADD_OPTION_GROUP_TO_PRODUCT,
- {
- optionGroupId: 'T_1',
- productId: '999',
- },
- );
- fail('Should have thrown');
- } catch (err) {
- expect(err.message).toEqual(
- expect.stringContaining(`No Product with the id '999' could be found`),
- );
- }
- });
- it('addOptionGroupToProduct errors with an invalid optionGroupId', async () => {
- try {
- await client.query<AddOptionGroupToProduct.Mutation, AddOptionGroupToProduct.Variables>(
- ADD_OPTION_GROUP_TO_PRODUCT,
- {
- optionGroupId: '999',
- productId: newProduct.id,
- },
- );
- fail('Should have thrown');
- } catch (err) {
- expect(err.message).toEqual(
- expect.stringContaining(`No ProductOptionGroup with the id '999' could be found`),
- );
- }
- });
- it('removeOptionGroupFromProduct removes an option group', async () => {
- const result = await client.query<
- RemoveOptionGroupFromProduct.Mutation,
- RemoveOptionGroupFromProduct.Variables
- >(REMOVE_OPTION_GROUP_FROM_PRODUCT, {
- optionGroupId: '1',
- productId: '1',
- });
- expect(result.removeOptionGroupFromProduct.optionGroups.length).toBe(0);
- });
- it('removeOptionGroupFromProduct errors with an invalid productId', async () => {
- try {
- await client.query<
- RemoveOptionGroupFromProduct.Mutation,
- RemoveOptionGroupFromProduct.Variables
- >(REMOVE_OPTION_GROUP_FROM_PRODUCT, {
- optionGroupId: '1',
- productId: '999',
- });
- fail('Should have thrown');
- } catch (err) {
- expect(err.message).toEqual(
- expect.stringContaining(`No Product with the id '999' could be found`),
- );
- }
- });
- describe('variants', () => {
- let variants: ProductWithVariants.Variants[];
- it('generateVariantsForProduct generates variants', async () => {
- const result = await client.query<
- GenerateProductVariants.Mutation,
- GenerateProductVariants.Variables
- >(GENERATE_PRODUCT_VARIANTS, {
- productId: newProduct.id,
- defaultPrice: 123,
- defaultSku: 'ABC',
- });
- variants = result.generateVariantsForProduct.variants;
- expect(variants.length).toBe(2);
- expect(variants[0].options.length).toBe(1);
- expect(variants[1].options.length).toBe(1);
- });
- it('generateVariantsForProduct throws with an invalid productId', async () => {
- try {
- await client.query<GenerateProductVariants.Mutation, GenerateProductVariants.Variables>(
- GENERATE_PRODUCT_VARIANTS,
- {
- productId: '999',
- },
- );
- fail('Should have thrown');
- } catch (err) {
- expect(err.message).toEqual(
- expect.stringContaining(`No Product with the id '999' could be found`),
- );
- }
- });
- it('updateProductVariants updates variants', async () => {
- const firstVariant = variants[0];
- const result = await client.query<
- UpdateProductVariants.Mutation,
- UpdateProductVariants.Variables
- >(UPDATE_PRODUCT_VARIANTS, {
- input: [
- {
- id: firstVariant.id,
- translations: firstVariant.translations,
- sku: 'ABC',
- price: 432,
- },
- ],
- });
- const updatedVariant = result.updateProductVariants[0];
- if (!updatedVariant) {
- fail('no updated variant returned.');
- return;
- }
- expect(updatedVariant.sku).toBe('ABC');
- expect(updatedVariant.price).toBe(432);
- });
- it('updateProductVariants updates taxCategory and priceBeforeTax', async () => {
- const firstVariant = variants[0];
- const result = await client.query<
- UpdateProductVariants.Mutation,
- UpdateProductVariants.Variables
- >(UPDATE_PRODUCT_VARIANTS, {
- input: [
- {
- id: firstVariant.id,
- price: 105,
- taxCategoryId: 'T_2',
- },
- ],
- });
- const updatedVariant = result.updateProductVariants[0];
- if (!updatedVariant) {
- fail('no updated variant returned.');
- return;
- }
- expect(updatedVariant.price).toBe(105);
- expect(updatedVariant.taxCategory.id).toBe('T_2');
- });
- it('updateProductVariants updates facetValues', async () => {
- const firstVariant = variants[0];
- const result = await client.query<
- UpdateProductVariants.Mutation,
- UpdateProductVariants.Variables
- >(UPDATE_PRODUCT_VARIANTS, {
- input: [
- {
- id: firstVariant.id,
- facetValueIds: ['T_1'],
- },
- ],
- });
- const updatedVariant = result.updateProductVariants[0];
- if (!updatedVariant) {
- fail('no updated variant returned.');
- return;
- }
- expect(updatedVariant.facetValues.length).toBe(1);
- expect(updatedVariant.facetValues[0].id).toBe('T_1');
- });
- it('updateProductVariants throws with an invalid variant id', async () => {
- try {
- await client.query<UpdateProductVariants.Mutation, UpdateProductVariants.Variables>(
- UPDATE_PRODUCT_VARIANTS,
- {
- input: [
- {
- id: 'T_999',
- translations: variants[0].translations,
- sku: 'ABC',
- price: 432,
- },
- ],
- },
- );
- fail('Should have thrown');
- } catch (err) {
- expect(err.message).toEqual(
- expect.stringContaining(`No ProductVariant with the id '999' could be found`),
- );
- }
- });
- });
- });
- });
|