| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059 |
- import { pick } from '@vendure/common/lib/pick';
- import { createTestEnvironment, E2E_DEFAULT_CHANNEL_TOKEN } from '@vendure/testing';
- import gql from 'graphql-tag';
- import path from 'path';
- import { afterAll, beforeAll, describe, expect, it } from 'vitest';
- import { initialData } from '../../../e2e-common/e2e-initial-data';
- import { TEST_SETUP_TIMEOUT_MS, testConfig } from '../../../e2e-common/test-config';
- import { FACET_VALUE_FRAGMENT } from './graphql/fragments';
- import * as Codegen from './graphql/generated-e2e-admin-types';
- import {
- ChannelFragment,
- CurrencyCode,
- DeletionResult,
- FacetWithValuesFragment,
- GetFacetWithValueListDocument,
- LanguageCode,
- } from './graphql/generated-e2e-admin-types';
- import {
- ASSIGN_PRODUCT_TO_CHANNEL,
- CREATE_CHANNEL,
- CREATE_FACET,
- CREATE_FACET_VALUE,
- GET_FACET_LIST,
- GET_FACET_LIST_SIMPLE,
- GET_FACET_VALUE,
- GET_FACET_VALUES,
- GET_FACET_WITH_VALUES,
- GET_PRODUCT_WITH_VARIANTS,
- UPDATE_FACET,
- UPDATE_FACET_VALUE,
- UPDATE_PRODUCT,
- UPDATE_PRODUCT_VARIANTS,
- } from './graphql/shared-definitions';
- import { assertThrowsWithMessage } from './utils/assert-throws-with-message';
- /* eslint-disable @typescript-eslint/no-non-null-assertion */
- describe('Facet resolver', () => {
- const { server, adminClient, shopClient } = createTestEnvironment(testConfig());
- let brandFacet: FacetWithValuesFragment;
- let speakerTypeFacet: FacetWithValuesFragment;
- beforeAll(async () => {
- await server.init({
- initialData,
- productsCsvPath: path.join(__dirname, 'fixtures/e2e-products-full.csv'),
- customerCount: 1,
- });
- await adminClient.asSuperAdmin();
- }, TEST_SETUP_TIMEOUT_MS);
- afterAll(async () => {
- await server.destroy();
- });
- it('createFacet', async () => {
- const result = await adminClient.query<
- Codegen.CreateFacetMutation,
- Codegen.CreateFacetMutationVariables
- >(CREATE_FACET, {
- input: {
- isPrivate: false,
- code: 'speaker-type',
- translations: [{ languageCode: LanguageCode.en, name: 'Speaker Type' }],
- values: [
- {
- code: 'portable',
- translations: [{ languageCode: LanguageCode.en, name: 'Portable' }],
- },
- ],
- },
- });
- speakerTypeFacet = result.createFacet;
- expect(speakerTypeFacet).toMatchSnapshot();
- });
- it('updateFacet', async () => {
- const result = await adminClient.query<
- Codegen.UpdateFacetMutation,
- Codegen.UpdateFacetMutationVariables
- >(UPDATE_FACET, {
- input: {
- id: speakerTypeFacet.id,
- translations: [{ languageCode: LanguageCode.en, name: 'Speaker Category' }],
- isPrivate: true,
- },
- });
- expect(result.updateFacet.name).toBe('Speaker Category');
- });
- it('createFacetValues', async () => {
- const { createFacetValues } = await adminClient.query<
- Codegen.CreateFacetValuesMutation,
- Codegen.CreateFacetValuesMutationVariables
- >(CREATE_FACET_VALUES, {
- input: [
- {
- facetId: speakerTypeFacet.id,
- code: 'pc',
- translations: [{ languageCode: LanguageCode.en, name: 'PC Speakers' }],
- },
- {
- facetId: speakerTypeFacet.id,
- code: 'hi-fi',
- translations: [{ languageCode: LanguageCode.en, name: 'Hi Fi Speakers' }],
- },
- ],
- });
- expect(createFacetValues.length).toBe(2);
- expect(pick(createFacetValues.find(fv => fv.code === 'pc')!, ['code', 'facet', 'name'])).toEqual({
- code: 'pc',
- facet: {
- id: 'T_2',
- name: 'Speaker Category',
- },
- name: 'PC Speakers',
- });
- expect(pick(createFacetValues.find(fv => fv.code === 'hi-fi')!, ['code', 'facet', 'name'])).toEqual({
- code: 'hi-fi',
- facet: {
- id: 'T_2',
- name: 'Speaker Category',
- },
- name: 'Hi Fi Speakers',
- });
- });
- it('updateFacetValues', async () => {
- const portableFacetValue = speakerTypeFacet.values.find(v => v.code === 'portable')!;
- const result = await adminClient.query<
- Codegen.UpdateFacetValuesMutation,
- Codegen.UpdateFacetValuesMutationVariables
- >(UPDATE_FACET_VALUES, {
- input: [
- {
- id: portableFacetValue.id,
- code: 'compact',
- },
- ],
- });
- expect(result.updateFacetValues[0].code).toBe('compact');
- });
- it('createFacetValue (single)', async () => {
- const result = await adminClient.query<
- Codegen.CreateFacetValueMutation,
- Codegen.CreateFacetValueMutationVariables
- >(CREATE_FACET_VALUE, {
- input: {
- facetId: speakerTypeFacet.id,
- code: 'wireless',
- translations: [{ languageCode: LanguageCode.en, name: 'Wireless Speakers' }],
- },
- });
- expect(result.createFacetValue).toEqual({
- id: expect.any(String),
- code: 'wireless',
- name: 'Wireless Speakers',
- languageCode: 'en',
- facet: {
- id: speakerTypeFacet.id,
- name: 'Speaker Category',
- },
- translations: [
- {
- id: expect.any(String),
- languageCode: LanguageCode.en,
- name: 'Wireless Speakers',
- },
- ],
- });
- });
- it('updateFacetValue (single)', async () => {
- // First get the newly created facet value
- const facetWithValues = await adminClient.query<
- Codegen.GetFacetWithValuesQuery,
- Codegen.GetFacetWithValuesQueryVariables
- >(GET_FACET_WITH_VALUES, {
- id: speakerTypeFacet.id,
- });
- const wirelessFacetValue = facetWithValues.facet!.values.find(v => v.code === 'wireless')!;
- const result = await adminClient.query<
- Codegen.UpdateFacetValueMutation,
- Codegen.UpdateFacetValueMutationVariables
- >(UPDATE_FACET_VALUE, {
- input: {
- id: wirelessFacetValue.id,
- code: 'bluetooth',
- translations: [
- {
- id: wirelessFacetValue.translations[0].id,
- languageCode: LanguageCode.en,
- name: 'Bluetooth Speakers',
- },
- ],
- },
- });
- expect(result.updateFacetValue).toEqual({
- id: wirelessFacetValue.id,
- code: 'bluetooth',
- name: 'Bluetooth Speakers',
- languageCode: 'en',
- facet: {
- id: speakerTypeFacet.id,
- name: 'Speaker Category',
- },
- translations: [
- {
- id: expect.any(String),
- languageCode: LanguageCode.en,
- name: 'Bluetooth Speakers',
- },
- ],
- });
- });
- it('facets', async () => {
- const result = await adminClient.query<Codegen.GetFacetListQuery>(GET_FACET_LIST);
- const { items } = result.facets;
- expect(items.length).toBe(2);
- expect(items[0].name).toBe('category');
- expect(items[1].name).toBe('Speaker Category');
- brandFacet = items[0];
- speakerTypeFacet = items[1];
- });
- it('facets by shop-api', async () => {
- const result = await shopClient.query<Codegen.GetFacetListQuery>(GET_FACET_LIST_SIMPLE);
- const { items } = result.facets;
- expect(items.length).toBe(1);
- expect(items[0].name).toBe('category');
- });
- it('facet', async () => {
- const result = await adminClient.query<
- Codegen.GetFacetWithValuesQuery,
- Codegen.GetFacetWithValuesQueryVariables
- >(GET_FACET_WITH_VALUES, {
- id: speakerTypeFacet.id,
- });
- expect(result.facet!.name).toBe('Speaker Category');
- });
- it('facet with valueList', async () => {
- const result = await adminClient.query(GetFacetWithValueListDocument, {
- id: speakerTypeFacet.id,
- });
- expect(result.facet?.valueList.totalItems).toBe(4);
- });
- it('facet with valueList with name filter', async () => {
- const result = await adminClient.query(GetFacetWithValueListDocument, {
- id: speakerTypeFacet.id,
- options: {
- filter: {
- name: {
- contains: 'spea',
- },
- },
- },
- });
- expect(result.facet?.valueList.totalItems).toBe(3);
- });
- it('facetValues list query', async () => {
- const result = await adminClient.query<
- Codegen.GetFacetValuesQuery,
- Codegen.GetFacetValuesQueryVariables
- >(GET_FACET_VALUES, {
- options: {
- filter: {
- facetId: { eq: speakerTypeFacet.id },
- },
- },
- });
- expect(result.facetValues.totalItems).toBe(4);
- expect(result.facetValues.items.length).toBe(4);
- expect(result.facetValues.items.map(v => v.code).sort()).toEqual([
- 'bluetooth',
- 'compact',
- 'hi-fi',
- 'pc',
- ]);
- expect(result.facetValues.items.every(v => v.facet.id === speakerTypeFacet.id)).toBe(true);
- });
- it('facetValue single query', async () => {
- const pcFacetValue = speakerTypeFacet.values.find(v => v.code === 'pc')!;
- const result = await adminClient.query<
- Codegen.GetFacetValueQuery,
- Codegen.GetFacetValueQueryVariables
- >(GET_FACET_VALUE, {
- id: pcFacetValue.id,
- });
- expect(result.facetValue).toBeDefined();
- expect(result.facetValue!.id).toBe(pcFacetValue.id);
- expect(result.facetValue!.code).toBe('pc');
- expect(result.facetValue!.name).toBe('PC Speakers');
- expect(result.facetValue!.facet.id).toBe(speakerTypeFacet.id);
- expect(result.facetValue!.facet.name).toBe('Speaker Category');
- });
- it('product.facetValues resolver omits private facets in shop-api', async () => {
- const publicFacetValue = brandFacet.values[0];
- const privateFacetValue = speakerTypeFacet.values[0];
- await adminClient.query<Codegen.UpdateProductMutation, Codegen.UpdateProductMutationVariables>(
- UPDATE_PRODUCT,
- {
- input: {
- id: 'T_1',
- facetValueIds: [publicFacetValue.id, privateFacetValue.id],
- },
- },
- );
- const { product } = await shopClient.query<
- Codegen.GetProductWithFacetValuesQuery,
- Codegen.GetProductWithFacetValuesQueryVariables
- >(GET_PRODUCT_WITH_FACET_VALUES, {
- id: 'T_1',
- });
- expect(product?.facetValues.map(v => v.id).includes(publicFacetValue.id)).toBe(true);
- expect(product?.facetValues.map(v => v.id).includes(privateFacetValue.id)).toBe(false);
- });
- it('productVariant.facetValues resolver omits private facets in shop-api', async () => {
- const publicFacetValue = brandFacet.values[0];
- const privateFacetValue = speakerTypeFacet.values[0];
- await adminClient.query<
- Codegen.UpdateProductVariantsMutation,
- Codegen.UpdateProductVariantsMutationVariables
- >(UPDATE_PRODUCT_VARIANTS, {
- input: [
- {
- id: 'T_1',
- facetValueIds: [publicFacetValue.id, privateFacetValue.id],
- },
- ],
- });
- const { product } = await shopClient.query<
- Codegen.GetProductWithFacetValuesQuery,
- Codegen.GetProductWithFacetValuesQueryVariables
- >(GET_PRODUCT_WITH_FACET_VALUES, {
- id: 'T_1',
- });
- const productVariant1 = product?.variants.find(v => v.id === 'T_1');
- expect(productVariant1?.facetValues.map(v => v.id).includes(publicFacetValue.id)).toBe(true);
- expect(productVariant1?.facetValues.map(v => v.id).includes(privateFacetValue.id)).toBe(false);
- });
- describe('deletion', () => {
- let products: Codegen.GetProductListWithVariantsQuery['products']['items'];
- beforeAll(async () => {
- // add the FacetValues to products and variants
- const result1 = await adminClient.query<Codegen.GetProductListWithVariantsQuery>(
- GET_PRODUCTS_LIST_WITH_VARIANTS,
- );
- products = result1.products.items;
- const pcFacetValue = speakerTypeFacet.values.find(v => v.code === 'pc')!;
- const hifiFacetValue = speakerTypeFacet.values.find(v => v.code === 'hi-fi')!;
- await adminClient.query<Codegen.UpdateProductMutation, Codegen.UpdateProductMutationVariables>(
- UPDATE_PRODUCT,
- {
- input: {
- id: products[0].id,
- facetValueIds: [pcFacetValue.id],
- },
- },
- );
- await adminClient.query<
- Codegen.UpdateProductVariantsMutation,
- Codegen.UpdateProductVariantsMutationVariables
- >(UPDATE_PRODUCT_VARIANTS, {
- input: [
- {
- id: products[0].variants[0].id,
- facetValueIds: [pcFacetValue.id],
- },
- ],
- });
- await adminClient.query<Codegen.UpdateProductMutation, Codegen.UpdateProductMutationVariables>(
- UPDATE_PRODUCT,
- {
- input: {
- id: products[1].id,
- facetValueIds: [hifiFacetValue.id],
- },
- },
- );
- });
- it('deleteFacetValues deletes unused facetValue', async () => {
- const facetValueToDelete = speakerTypeFacet.values.find(v => v.code === 'compact')!;
- const result1 = await adminClient.query<
- Codegen.DeleteFacetValuesMutation,
- Codegen.DeleteFacetValuesMutationVariables
- >(DELETE_FACET_VALUES, {
- ids: [facetValueToDelete.id],
- force: false,
- });
- const result2 = await adminClient.query<
- Codegen.GetFacetWithValuesQuery,
- Codegen.GetFacetWithValuesQueryVariables
- >(GET_FACET_WITH_VALUES, {
- id: speakerTypeFacet.id,
- });
- expect(result1.deleteFacetValues).toEqual([
- {
- result: DeletionResult.DELETED,
- message: '',
- },
- ]);
- expect(result2.facet!.values[0]).not.toEqual(facetValueToDelete);
- });
- it('deleteFacetValues for FacetValue in use returns NOT_DELETED', async () => {
- const facetValueToDelete = speakerTypeFacet.values.find(v => v.code === 'pc')!;
- const result1 = await adminClient.query<
- Codegen.DeleteFacetValuesMutation,
- Codegen.DeleteFacetValuesMutationVariables
- >(DELETE_FACET_VALUES, {
- ids: [facetValueToDelete.id],
- force: false,
- });
- const result2 = await adminClient.query<
- Codegen.GetFacetWithValuesQuery,
- Codegen.GetFacetWithValuesQueryVariables
- >(GET_FACET_WITH_VALUES, {
- id: speakerTypeFacet.id,
- });
- expect(result1.deleteFacetValues).toEqual([
- {
- result: DeletionResult.NOT_DELETED,
- message: 'The FacetValue "pc" is assigned to 1 Product, 1 ProductVariant',
- },
- ]);
- expect(result2.facet!.values.find(v => v.id === facetValueToDelete.id)).toBeDefined();
- });
- it('deleteFacetValues for FacetValue in use can be force deleted', async () => {
- const facetValueToDelete = speakerTypeFacet.values.find(v => v.code === 'pc')!;
- const result1 = await adminClient.query<
- Codegen.DeleteFacetValuesMutation,
- Codegen.DeleteFacetValuesMutationVariables
- >(DELETE_FACET_VALUES, {
- ids: [facetValueToDelete.id],
- force: true,
- });
- expect(result1.deleteFacetValues).toEqual([
- {
- result: DeletionResult.DELETED,
- message:
- 'The selected FacetValue was removed from 1 Product, 1 ProductVariant and deleted',
- },
- ]);
- // FacetValue no longer in the Facet.values array
- const result2 = await adminClient.query<
- Codegen.GetFacetWithValuesQuery,
- Codegen.GetFacetWithValuesQueryVariables
- >(GET_FACET_WITH_VALUES, {
- id: speakerTypeFacet.id,
- });
- expect(result2.facet!.values[0]).not.toEqual(facetValueToDelete);
- // FacetValue no longer in the Product.facetValues array
- const result3 = await adminClient.query<
- Codegen.GetProductWithVariantsQuery,
- Codegen.GetProductWithVariantsQueryVariables
- >(GET_PRODUCT_WITH_VARIANTS, {
- id: products[0].id,
- });
- expect(result3.product!.facetValues).toEqual([]);
- });
- it('deleteFacet that is in use returns NOT_DELETED', async () => {
- const result1 = await adminClient.query<
- Codegen.DeleteFacetMutation,
- Codegen.DeleteFacetMutationVariables
- >(DELETE_FACET, {
- id: speakerTypeFacet.id,
- force: false,
- });
- const result2 = await adminClient.query<
- Codegen.GetFacetWithValuesQuery,
- Codegen.GetFacetWithValuesQueryVariables
- >(GET_FACET_WITH_VALUES, {
- id: speakerTypeFacet.id,
- });
- expect(result1.deleteFacet).toEqual({
- result: DeletionResult.NOT_DELETED,
- message: 'The Facet "speaker-type" includes FacetValues which are assigned to 1 Product',
- });
- expect(result2.facet).not.toBe(null);
- });
- it('deleteFacet that is in use can be force deleted', async () => {
- const result1 = await adminClient.query<
- Codegen.DeleteFacetMutation,
- Codegen.DeleteFacetMutationVariables
- >(DELETE_FACET, {
- id: speakerTypeFacet.id,
- force: true,
- });
- expect(result1.deleteFacet).toEqual({
- result: DeletionResult.DELETED,
- message: 'The Facet was deleted and its FacetValues were removed from 1 Product',
- });
- // FacetValue no longer in the Facet.values array
- const result2 = await adminClient.query<
- Codegen.GetFacetWithValuesQuery,
- Codegen.GetFacetWithValuesQueryVariables
- >(GET_FACET_WITH_VALUES, {
- id: speakerTypeFacet.id,
- });
- expect(result2.facet).toBe(null);
- // FacetValue no longer in the Product.facetValues array
- const result3 = await adminClient.query<
- Codegen.GetProductWithVariantsQuery,
- Codegen.GetProductWithVariantsQueryVariables
- >(GET_PRODUCT_WITH_VARIANTS, {
- id: products[1].id,
- });
- expect(result3.product!.facetValues).toEqual([]);
- });
- it('deleteFacet with no FacetValues works', async () => {
- const { createFacet } = await adminClient.query<
- Codegen.CreateFacetMutation,
- Codegen.CreateFacetMutationVariables
- >(CREATE_FACET, {
- input: {
- code: 'test',
- isPrivate: false,
- translations: [{ languageCode: LanguageCode.en, name: 'Test' }],
- },
- });
- const result = await adminClient.query<
- Codegen.DeleteFacetMutation,
- Codegen.DeleteFacetMutationVariables
- >(DELETE_FACET, {
- id: createFacet.id,
- force: false,
- });
- expect(result.deleteFacet.result).toBe(DeletionResult.DELETED);
- });
- });
- describe('channels', () => {
- const SECOND_CHANNEL_TOKEN = 'second_channel_token';
- let secondChannel: ChannelFragment;
- let createdFacet: Codegen.CreateFacetMutation['createFacet'];
- beforeAll(async () => {
- const { createChannel } = await adminClient.query<
- Codegen.CreateChannelMutation,
- Codegen.CreateChannelMutationVariables
- >(CREATE_CHANNEL, {
- input: {
- code: 'second-channel',
- token: SECOND_CHANNEL_TOKEN,
- defaultLanguageCode: LanguageCode.en,
- currencyCode: CurrencyCode.USD,
- pricesIncludeTax: true,
- defaultShippingZoneId: 'T_1',
- defaultTaxZoneId: 'T_1',
- },
- });
- secondChannel = createChannel as ChannelFragment;
- const { assignProductsToChannel } = await adminClient.query<
- Codegen.AssignProductsToChannelMutation,
- Codegen.AssignProductsToChannelMutationVariables
- >(ASSIGN_PRODUCT_TO_CHANNEL, {
- input: {
- channelId: secondChannel.id,
- productIds: ['T_1'],
- priceFactor: 0.5,
- },
- });
- adminClient.setChannelToken(SECOND_CHANNEL_TOKEN);
- });
- it('create Facet in channel', async () => {
- const { createFacet } = await adminClient.query<
- Codegen.CreateFacetMutation,
- Codegen.CreateFacetMutationVariables
- >(CREATE_FACET, {
- input: {
- isPrivate: false,
- code: 'channel-facet',
- translations: [{ languageCode: LanguageCode.en, name: 'Channel Facet' }],
- values: [
- {
- code: 'channel-value-1',
- translations: [{ languageCode: LanguageCode.en, name: 'Channel Value 1' }],
- },
- {
- code: 'channel-value-2',
- translations: [{ languageCode: LanguageCode.en, name: 'Channel Value 2' }],
- },
- ],
- },
- });
- expect(createFacet.code).toBe('channel-facet');
- createdFacet = createFacet;
- });
- it('facets list in channel', async () => {
- const result = await adminClient.query<Codegen.GetFacetListQuery>(GET_FACET_LIST);
- const { items } = result.facets;
- expect(items.length).toBe(1);
- expect(items.map(i => i.code)).toEqual(['channel-facet']);
- });
- it('Product.facetValues in channel', async () => {
- adminClient.setChannelToken(E2E_DEFAULT_CHANNEL_TOKEN);
- await adminClient.query<Codegen.UpdateProductMutation, Codegen.UpdateProductMutationVariables>(
- UPDATE_PRODUCT,
- {
- input: {
- id: 'T_1',
- facetValueIds: [brandFacet.values[0].id, ...createdFacet.values.map(v => v.id)],
- },
- },
- );
- await adminClient.query<
- Codegen.UpdateProductVariantsMutation,
- Codegen.UpdateProductVariantsMutationVariables
- >(UPDATE_PRODUCT_VARIANTS, {
- input: [
- {
- id: 'T_1',
- facetValueIds: [brandFacet.values[0].id, ...createdFacet.values.map(v => v.id)],
- },
- ],
- });
- adminClient.setChannelToken(SECOND_CHANNEL_TOKEN);
- const { product } = await adminClient.query<
- Codegen.GetProductWithVariantsQuery,
- Codegen.GetProductWithVariantsQueryVariables
- >(GET_PRODUCT_WITH_VARIANTS, {
- id: 'T_1',
- });
- expect(product?.facetValues.map(fv => fv.code).sort()).toEqual([
- 'channel-value-1',
- 'channel-value-2',
- ]);
- });
- it('ProductVariant.facetValues in channel', async () => {
- const { product } = await adminClient.query<
- Codegen.GetProductWithVariantsQuery,
- Codegen.GetProductWithVariantsQueryVariables
- >(GET_PRODUCT_WITH_VARIANTS, {
- id: 'T_1',
- });
- expect(product?.variants[0].facetValues.map(fv => fv.code).sort()).toEqual([
- 'channel-value-1',
- 'channel-value-2',
- ]);
- });
- it('updating Product facetValuesIds in channel only affects that channel', async () => {
- adminClient.setChannelToken(SECOND_CHANNEL_TOKEN);
- await adminClient.query<Codegen.UpdateProductMutation, Codegen.UpdateProductMutationVariables>(
- UPDATE_PRODUCT,
- {
- input: {
- id: 'T_1',
- facetValueIds: [createdFacet.values[0].id],
- },
- },
- );
- const { product: productC2 } = await adminClient.query<
- Codegen.GetProductWithVariantsQuery,
- Codegen.GetProductWithVariantsQueryVariables
- >(GET_PRODUCT_WITH_VARIANTS, {
- id: 'T_1',
- });
- expect(productC2?.facetValues.map(fv => fv.code)).toEqual([createdFacet.values[0].code]);
- adminClient.setChannelToken(E2E_DEFAULT_CHANNEL_TOKEN);
- const { product: productCD } = await adminClient.query<
- Codegen.GetProductWithVariantsQuery,
- Codegen.GetProductWithVariantsQueryVariables
- >(GET_PRODUCT_WITH_VARIANTS, {
- id: 'T_1',
- });
- expect(productCD?.facetValues.map(fv => fv.code)).toEqual([
- brandFacet.values[0].code,
- createdFacet.values[0].code,
- ]);
- });
- it('updating ProductVariant facetValuesIds in channel only affects that channel', async () => {
- adminClient.setChannelToken(SECOND_CHANNEL_TOKEN);
- await adminClient.query<
- Codegen.UpdateProductVariantsMutation,
- Codegen.UpdateProductVariantsMutationVariables
- >(UPDATE_PRODUCT_VARIANTS, {
- input: [
- {
- id: 'T_1',
- facetValueIds: [createdFacet.values[0].id],
- },
- ],
- });
- const { product: productC2 } = await adminClient.query<
- Codegen.GetProductWithVariantsQuery,
- Codegen.GetProductWithVariantsQueryVariables
- >(GET_PRODUCT_WITH_VARIANTS, {
- id: 'T_1',
- });
- expect(productC2?.variants.find(v => v.id === 'T_1')?.facetValues.map(fv => fv.code)).toEqual([
- createdFacet.values[0].code,
- ]);
- adminClient.setChannelToken(E2E_DEFAULT_CHANNEL_TOKEN);
- const { product: productCD } = await adminClient.query<
- Codegen.GetProductWithVariantsQuery,
- Codegen.GetProductWithVariantsQueryVariables
- >(GET_PRODUCT_WITH_VARIANTS, {
- id: 'T_1',
- });
- expect(productCD?.variants.find(v => v.id === 'T_1')?.facetValues.map(fv => fv.code)).toEqual([
- brandFacet.values[0].code,
- createdFacet.values[0].code,
- ]);
- });
- it(
- 'attempting to create FacetValue in Facet from another Channel throws',
- assertThrowsWithMessage(async () => {
- adminClient.setChannelToken(SECOND_CHANNEL_TOKEN);
- await adminClient.query<
- Codegen.CreateFacetValuesMutation,
- Codegen.CreateFacetValuesMutationVariables
- >(CREATE_FACET_VALUES, {
- input: [
- {
- facetId: brandFacet.id,
- code: 'channel-brand',
- translations: [{ languageCode: LanguageCode.en, name: 'Channel Brand' }],
- },
- ],
- });
- }, 'No Facet with the id "1" could be found'),
- );
- it('removing from channel with error', async () => {
- adminClient.setChannelToken(SECOND_CHANNEL_TOKEN);
- const { facets: before } =
- await adminClient.query<Codegen.GetFacetListSimpleQuery>(GET_FACET_LIST_SIMPLE);
- expect(before.items).toEqual([{ id: 'T_4', name: 'Channel Facet' }]);
- adminClient.setChannelToken(E2E_DEFAULT_CHANNEL_TOKEN);
- const { removeFacetsFromChannel } = await adminClient.query<
- Codegen.RemoveFacetsFromChannelMutation,
- Codegen.RemoveFacetsFromChannelMutationVariables
- >(REMOVE_FACETS_FROM_CHANNEL, {
- input: {
- channelId: secondChannel.id,
- facetIds: [createdFacet.id],
- force: false,
- },
- });
- expect(removeFacetsFromChannel).toEqual([
- {
- errorCode: 'FACET_IN_USE_ERROR',
- message:
- 'The Facet "channel-facet" includes FacetValues which are assigned to 1 Product 1 ProductVariant',
- productCount: 1,
- variantCount: 1,
- },
- ]);
- adminClient.setChannelToken(SECOND_CHANNEL_TOKEN);
- const { facets: after } =
- await adminClient.query<Codegen.GetFacetListSimpleQuery>(GET_FACET_LIST_SIMPLE);
- expect(after.items).toEqual([{ id: 'T_4', name: 'Channel Facet' }]);
- });
- it('force removing from channel', async () => {
- adminClient.setChannelToken(SECOND_CHANNEL_TOKEN);
- const { facets: before } =
- await adminClient.query<Codegen.GetFacetListSimpleQuery>(GET_FACET_LIST_SIMPLE);
- expect(before.items).toEqual([{ id: 'T_4', name: 'Channel Facet' }]);
- adminClient.setChannelToken(E2E_DEFAULT_CHANNEL_TOKEN);
- const { removeFacetsFromChannel } = await adminClient.query<
- Codegen.RemoveFacetsFromChannelMutation,
- Codegen.RemoveFacetsFromChannelMutationVariables
- >(REMOVE_FACETS_FROM_CHANNEL, {
- input: {
- channelId: secondChannel.id,
- facetIds: [createdFacet.id],
- force: true,
- },
- });
- expect(removeFacetsFromChannel).toEqual([{ id: 'T_4', name: 'Channel Facet' }]);
- adminClient.setChannelToken(SECOND_CHANNEL_TOKEN);
- const { facets: after } =
- await adminClient.query<Codegen.GetFacetListSimpleQuery>(GET_FACET_LIST_SIMPLE);
- expect(after.items).toEqual([]);
- });
- it('assigning to channel', async () => {
- adminClient.setChannelToken(SECOND_CHANNEL_TOKEN);
- const { facets: before } =
- await adminClient.query<Codegen.GetFacetListSimpleQuery>(GET_FACET_LIST_SIMPLE);
- expect(before.items).toEqual([]);
- adminClient.setChannelToken(E2E_DEFAULT_CHANNEL_TOKEN);
- const { assignFacetsToChannel } = await adminClient.query<
- Codegen.AssignFacetsToChannelMutation,
- Codegen.AssignFacetsToChannelMutationVariables
- >(ASSIGN_FACETS_TO_CHANNEL, {
- input: {
- channelId: secondChannel.id,
- facetIds: [createdFacet.id],
- },
- });
- expect(assignFacetsToChannel).toEqual([{ id: 'T_4', name: 'Channel Facet' }]);
- adminClient.setChannelToken(SECOND_CHANNEL_TOKEN);
- const { facets: after } =
- await adminClient.query<Codegen.GetFacetListSimpleQuery>(GET_FACET_LIST_SIMPLE);
- expect(after.items).toEqual([{ id: 'T_4', name: 'Channel Facet' }]);
- });
- });
- // https://github.com/vendurehq/vendure/issues/715
- describe('code conflicts', () => {
- function createFacetWithCode(code: string) {
- return adminClient.query<Codegen.CreateFacetMutation, Codegen.CreateFacetMutationVariables>(
- CREATE_FACET,
- {
- input: {
- isPrivate: false,
- code,
- translations: [{ languageCode: LanguageCode.en, name: `Test Facet (${code})` }],
- values: [],
- },
- },
- );
- }
- // https://github.com/vendurehq/vendure/issues/831
- it('updateFacet with unchanged code', async () => {
- const { createFacet } = await createFacetWithCode('some-new-facet');
- const result = await adminClient.query<
- Codegen.UpdateFacetMutation,
- Codegen.UpdateFacetMutationVariables
- >(UPDATE_FACET, {
- input: {
- id: createFacet.id,
- code: createFacet.code,
- },
- });
- expect(result.updateFacet.code).toBe(createFacet.code);
- });
- it('createFacet with conflicting slug gets renamed', async () => {
- const { createFacet: result1 } = await createFacetWithCode('test');
- expect(result1.code).toBe('test');
- const { createFacet: result2 } = await createFacetWithCode('test');
- expect(result2.code).toBe('test-2');
- });
- it('updateFacet with conflicting slug gets renamed', async () => {
- const { createFacet } = await createFacetWithCode('foo');
- expect(createFacet.code).toBe('foo');
- const { updateFacet } = await adminClient.query<
- Codegen.UpdateFacetMutation,
- Codegen.UpdateFacetMutationVariables
- >(UPDATE_FACET, {
- input: {
- id: createFacet.id,
- code: 'test-2',
- },
- });
- expect(updateFacet.code).toBe('test-3');
- });
- });
- });
- export const GET_FACET_WITH_VALUE_LIST = gql`
- query GetFacetWithValueList($id: ID!, $options: FacetValueListOptions) {
- facet(id: $id) {
- id
- languageCode
- isPrivate
- code
- name
- valueList(options: $options) {
- items {
- ...FacetValue
- }
- totalItems
- }
- }
- }
- ${FACET_VALUE_FRAGMENT}
- `;
- const DELETE_FACET_VALUES = gql`
- mutation DeleteFacetValues($ids: [ID!]!, $force: Boolean) {
- deleteFacetValues(ids: $ids, force: $force) {
- result
- message
- }
- }
- `;
- const DELETE_FACET = gql`
- mutation DeleteFacet($id: ID!, $force: Boolean) {
- deleteFacet(id: $id, force: $force) {
- result
- message
- }
- }
- `;
- const GET_PRODUCT_WITH_FACET_VALUES = gql`
- query GetProductWithFacetValues($id: ID!) {
- product(id: $id) {
- id
- facetValues {
- id
- name
- code
- }
- variants {
- id
- facetValues {
- id
- name
- code
- }
- }
- }
- }
- `;
- const GET_PRODUCTS_LIST_WITH_VARIANTS = gql`
- query GetProductListWithVariants {
- products {
- items {
- id
- name
- variants {
- id
- name
- }
- }
- totalItems
- }
- }
- `;
- export const CREATE_FACET_VALUES = gql`
- mutation CreateFacetValues($input: [CreateFacetValueInput!]!) {
- createFacetValues(input: $input) {
- ...FacetValue
- }
- }
- ${FACET_VALUE_FRAGMENT}
- `;
- export const UPDATE_FACET_VALUES = gql`
- mutation UpdateFacetValues($input: [UpdateFacetValueInput!]!) {
- updateFacetValues(input: $input) {
- ...FacetValue
- }
- }
- ${FACET_VALUE_FRAGMENT}
- `;
- export const ASSIGN_FACETS_TO_CHANNEL = gql`
- mutation AssignFacetsToChannel($input: AssignFacetsToChannelInput!) {
- assignFacetsToChannel(input: $input) {
- id
- name
- }
- }
- `;
- export const REMOVE_FACETS_FROM_CHANNEL = gql`
- mutation RemoveFacetsFromChannel($input: RemoveFacetsFromChannelInput!) {
- removeFacetsFromChannel(input: $input) {
- ... on Facet {
- id
- name
- }
- ... on FacetInUseError {
- errorCode
- message
- productCount
- variantCount
- }
- }
- }
- `;
|