Skip to content

Commit

Permalink
Merge branch 'CU-9rvcxw/ProductVariants' into channel-aware-variants
Browse files Browse the repository at this point in the history
# Conflicts:
#	schema-admin.json
  • Loading branch information
michaelbromley committed Nov 24, 2020
2 parents 4564d79 + 8384299 commit 50975a4
Show file tree
Hide file tree
Showing 33 changed files with 1,420 additions and 442 deletions.
30 changes: 28 additions & 2 deletions packages/admin-ui/src/lib/core/src/common/generated-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,9 @@ export type Mutation = {
addNoteToOrder: Order;
/** Add an OptionGroup to a Product */
addOptionGroupToProduct: Product;
/** Assigns Products to the specified Channel */
/** Assigns ProductVariants to the specified Channel */
assignProductVariantsToChannel: Array<ProductVariant>;
/** Assigns all ProductVariants of Product to the specified Channel */
assignProductsToChannel: Array<Product>;
/** Assign a Role to an Administrator */
assignRoleToAdministrator: Administrator;
Expand Down Expand Up @@ -394,7 +396,9 @@ export type Mutation = {
removeMembersFromZone: Zone;
/** Remove an OptionGroup from a Product */
removeOptionGroupFromProduct: RemoveOptionGroupFromProductResult;
/** Removes Products from the specified Channel */
/** Removes ProductVariants from the specified Channel */
removeProductVariantsFromChannel: Array<ProductVariant>;
/** Removes all ProductVariants of Product from the specified Channel */
removeProductsFromChannel: Array<Product>;
/** Remove all settled jobs in the given queues olfer than the given date. Returns the number of jobs deleted. */
removeSettledJobs: Scalars['Int'];
Expand Down Expand Up @@ -492,6 +496,11 @@ export type MutationAddOptionGroupToProductArgs = {
};


export type MutationAssignProductVariantsToChannelArgs = {
input: AssignProductVariantsToChannelInput;
};


export type MutationAssignProductsToChannelArgs = {
input: AssignProductsToChannelInput;
};
Expand Down Expand Up @@ -765,6 +774,11 @@ export type MutationRemoveOptionGroupFromProductArgs = {
};


export type MutationRemoveProductVariantsFromChannelArgs = {
input: RemoveProductVariantsFromChannelInput;
};


export type MutationRemoveProductsFromChannelArgs = {
input: RemoveProductsFromChannelInput;
};
Expand Down Expand Up @@ -1677,6 +1691,7 @@ export type ProductVariant = Node & {
outOfStockThreshold: Scalars['Int'];
useGlobalOutOfStockThreshold: Scalars['Boolean'];
stockMovements: StockMovementList;
channels: Array<Channel>;
id: Scalars['ID'];
product: Product;
productId: Scalars['ID'];
Expand Down Expand Up @@ -1795,6 +1810,17 @@ export type RemoveProductsFromChannelInput = {
channelId: Scalars['ID'];
};

export type AssignProductVariantsToChannelInput = {
productVariantIds: Array<Scalars['ID']>;
channelId: Scalars['ID'];
priceFactor?: Maybe<Scalars['Float']>;
};

export type RemoveProductVariantsFromChannelInput = {
productVariantIds: Array<Scalars['ID']>;
channelId: Scalars['ID'];
};

export type ProductOptionInUseError = ErrorResult & {
__typename?: 'ProductOptionInUseError';
errorCode: ErrorCode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -362,10 +362,14 @@ export type Mutation = {
updateProductVariants: Array<Maybe<ProductVariant>>;
/** Delete a ProductVariant */
deleteProductVariant: DeletionResponse;
/** Assigns Products to the specified Channel */
/** Assigns all ProductVariants of Product to the specified Channel */
assignProductsToChannel: Array<Product>;
/** Removes Products from the specified Channel */
/** Removes all ProductVariants of Product from the specified Channel */
removeProductsFromChannel: Array<Product>;
/** Assigns ProductVariants to the specified Channel */
assignProductVariantsToChannel: Array<ProductVariant>;
/** Removes ProductVariants from the specified Channel */
removeProductVariantsFromChannel: Array<ProductVariant>;
createPromotion: CreatePromotionResult;
updatePromotion: UpdatePromotionResult;
deletePromotion: DeletionResponse;
Expand Down Expand Up @@ -702,6 +706,14 @@ export type MutationRemoveProductsFromChannelArgs = {
input: RemoveProductsFromChannelInput;
};

export type MutationAssignProductVariantsToChannelArgs = {
input: AssignProductVariantsToChannelInput;
};

export type MutationRemoveProductVariantsFromChannelArgs = {
input: RemoveProductVariantsFromChannelInput;
};

export type MutationCreatePromotionArgs = {
input: CreatePromotionInput;
};
Expand Down Expand Up @@ -1503,6 +1515,7 @@ export type ProductVariant = Node & {
outOfStockThreshold: Scalars['Int'];
useGlobalOutOfStockThreshold: Scalars['Boolean'];
stockMovements: StockMovementList;
channels: Array<Channel>;
id: Scalars['ID'];
product: Product;
productId: Scalars['ID'];
Expand Down Expand Up @@ -1620,6 +1633,17 @@ export type RemoveProductsFromChannelInput = {
channelId: Scalars['ID'];
};

export type AssignProductVariantsToChannelInput = {
productVariantIds: Array<Scalars['ID']>;
channelId: Scalars['ID'];
priceFactor?: Maybe<Scalars['Float']>;
};

export type RemoveProductVariantsFromChannelInput = {
productVariantIds: Array<Scalars['ID']>;
channelId: Scalars['ID'];
};

export type ProductOptionInUseError = ErrorResult & {
errorCode: ErrorCode;
message: Scalars['String'];
Expand Down
30 changes: 28 additions & 2 deletions packages/common/src/generated-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -404,10 +404,14 @@ export type Mutation = {
updateProductVariants: Array<Maybe<ProductVariant>>;
/** Delete a ProductVariant */
deleteProductVariant: DeletionResponse;
/** Assigns Products to the specified Channel */
/** Assigns all ProductVariants of Product to the specified Channel */
assignProductsToChannel: Array<Product>;
/** Removes Products from the specified Channel */
/** Removes all ProductVariants of Product from the specified Channel */
removeProductsFromChannel: Array<Product>;
/** Assigns ProductVariants to the specified Channel */
assignProductVariantsToChannel: Array<ProductVariant>;
/** Removes ProductVariants from the specified Channel */
removeProductVariantsFromChannel: Array<ProductVariant>;
createPromotion: CreatePromotionResult;
updatePromotion: UpdatePromotionResult;
deletePromotion: DeletionResponse;
Expand Down Expand Up @@ -815,6 +819,16 @@ export type MutationRemoveProductsFromChannelArgs = {
};


export type MutationAssignProductVariantsToChannelArgs = {
input: AssignProductVariantsToChannelInput;
};


export type MutationRemoveProductVariantsFromChannelArgs = {
input: RemoveProductVariantsFromChannelInput;
};


export type MutationCreatePromotionArgs = {
input: CreatePromotionInput;
};
Expand Down Expand Up @@ -1646,6 +1660,7 @@ export type ProductVariant = Node & {
outOfStockThreshold: Scalars['Int'];
useGlobalOutOfStockThreshold: Scalars['Boolean'];
stockMovements: StockMovementList;
channels: Array<Channel>;
id: Scalars['ID'];
product: Product;
productId: Scalars['ID'];
Expand Down Expand Up @@ -1764,6 +1779,17 @@ export type RemoveProductsFromChannelInput = {
channelId: Scalars['ID'];
};

export type AssignProductVariantsToChannelInput = {
productVariantIds: Array<Scalars['ID']>;
channelId: Scalars['ID'];
priceFactor?: Maybe<Scalars['Float']>;
};

export type RemoveProductVariantsFromChannelInput = {
productVariantIds: Array<Scalars['ID']>;
channelId: Scalars['ID'];
};

export type ProductOptionInUseError = ErrorResult & {
__typename?: 'ProductOptionInUseError';
errorCode: ErrorCode;
Expand Down
132 changes: 7 additions & 125 deletions packages/core/e2e/channel.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import {
LanguageCode,
Me,
Permission,
RemoveProductsFromChannel,
UpdateChannel,
UpdateGlobalLanguages,
} from './graphql/generated-e2e-admin-types';
Expand All @@ -40,15 +39,13 @@ import {
GET_CUSTOMER_LIST,
GET_PRODUCT_WITH_VARIANTS,
ME,
REMOVE_PRODUCT_FROM_CHANNEL,
UPDATE_CHANNEL,
} from './graphql/shared-definitions';
import { assertThrowsWithMessage } from './utils/assert-throws-with-message';

describe('Channels', () => {
const { server, adminClient, shopClient } = createTestEnvironment(testConfig);
const SECOND_CHANNEL_TOKEN = 'second_channel_token';
const THIRD_CHANNEL_TOKEN = 'third_channel_token';
let secondChannelAdminRole: CreateRole.CreateRole;
let customerUser: GetCustomerList.Items;

Expand Down Expand Up @@ -272,129 +269,10 @@ describe('Channels', () => {
]);
});

describe('assigning Product to Channels', () => {
let product1: GetProductWithVariants.Product;

beforeAll(async () => {
await adminClient.asSuperAdmin();
await adminClient.setChannelToken(E2E_DEFAULT_CHANNEL_TOKEN);
await adminClient.query<CreateChannel.Mutation, CreateChannel.Variables>(CREATE_CHANNEL, {
input: {
code: 'third-channel',
token: THIRD_CHANNEL_TOKEN,
defaultLanguageCode: LanguageCode.en,
currencyCode: CurrencyCode.GBP,
pricesIncludeTax: true,
defaultShippingZoneId: 'T_1',
defaultTaxZoneId: 'T_1',
},
});

const { product } = await adminClient.query<
GetProductWithVariants.Query,
GetProductWithVariants.Variables
>(GET_PRODUCT_WITH_VARIANTS, {
id: 'T_1',
});
product1 = product!;
});

it(
'throws if attempting to assign Product to channel to which the admin has no access',
assertThrowsWithMessage(async () => {
await adminClient.asUserWithCredentials('[email protected]', 'test');
await adminClient.query<AssignProductsToChannel.Mutation, AssignProductsToChannel.Variables>(
ASSIGN_PRODUCT_TO_CHANNEL,
{
input: {
channelId: 'T_3',
productIds: [product1.id],
},
},
);
}, 'You are not currently authorized to perform this action'),
);

it('assigns Product to Channel and applies price factor', async () => {
const PRICE_FACTOR = 0.5;
await adminClient.asSuperAdmin();
const { assignProductsToChannel } = await adminClient.query<
AssignProductsToChannel.Mutation,
AssignProductsToChannel.Variables
>(ASSIGN_PRODUCT_TO_CHANNEL, {
input: {
channelId: 'T_2',
productIds: [product1.id],
priceFactor: PRICE_FACTOR,
},
});

expect(assignProductsToChannel[0].channels.map(c => c.id).sort()).toEqual(['T_1', 'T_2']);
await adminClient.setChannelToken(SECOND_CHANNEL_TOKEN);
const { product } = await adminClient.query<
GetProductWithVariants.Query,
GetProductWithVariants.Variables
>(GET_PRODUCT_WITH_VARIANTS, {
id: product1.id,
});

expect(product!.variants.map(v => v.price)).toEqual(
product1.variants.map(v => v.price * PRICE_FACTOR),
);
// Second Channel is configured to include taxes in price, so they should be the same.
expect(product!.variants.map(v => v.priceWithTax)).toEqual(
product1.variants.map(v => v.price * PRICE_FACTOR),
);
});

it('does not assign Product to same channel twice', async () => {
const { assignProductsToChannel } = await adminClient.query<
AssignProductsToChannel.Mutation,
AssignProductsToChannel.Variables
>(ASSIGN_PRODUCT_TO_CHANNEL, {
input: {
channelId: 'T_2',
productIds: [product1.id],
},
});

expect(assignProductsToChannel[0].channels.map(c => c.id).sort()).toEqual(['T_1', 'T_2']);
});

it(
'throws if attempting to remove Product from default Channel',
assertThrowsWithMessage(async () => {
await adminClient.query<
RemoveProductsFromChannel.Mutation,
RemoveProductsFromChannel.Variables
>(REMOVE_PRODUCT_FROM_CHANNEL, {
input: {
productIds: [product1.id],
channelId: 'T_1',
},
});
}, 'Products cannot be removed from the default Channel'),
);

it('removes Product from Channel', async () => {
await adminClient.asSuperAdmin();
await adminClient.setChannelToken(E2E_DEFAULT_CHANNEL_TOKEN);
const { removeProductsFromChannel } = await adminClient.query<
RemoveProductsFromChannel.Mutation,
RemoveProductsFromChannel.Variables
>(REMOVE_PRODUCT_FROM_CHANNEL, {
input: {
productIds: [product1.id],
channelId: 'T_2',
},
});

expect(removeProductsFromChannel[0].channels.map(c => c.id)).toEqual(['T_1']);
});
});

describe('setting defaultLanguage', () => {
it('returns error result if languageCode not in availableLanguages', async () => {
await adminClient.asSuperAdmin();
await adminClient.setChannelToken(E2E_DEFAULT_CHANNEL_TOKEN);
const { updateChannel } = await adminClient.query<
UpdateChannel.Mutation,
UpdateChannel.Variables
Expand All @@ -414,6 +292,8 @@ describe('Channels', () => {
});

it('allows setting to an available language', async () => {
await adminClient.asSuperAdmin();
await adminClient.setChannelToken(E2E_DEFAULT_CHANNEL_TOKEN);
await adminClient.query<UpdateGlobalLanguages.Mutation, UpdateGlobalLanguages.Variables>(
UPDATE_GLOBAL_LANGUAGES,
{
Expand All @@ -439,6 +319,8 @@ describe('Channels', () => {

it('deleteChannel', async () => {
const PROD_ID = 'T_1';
await adminClient.asSuperAdmin();
await adminClient.setChannelToken(E2E_DEFAULT_CHANNEL_TOKEN);

const { assignProductsToChannel } = await adminClient.query<
AssignProductsToChannel.Mutation,
Expand All @@ -461,7 +343,7 @@ describe('Channels', () => {
expect(deleteChannel.result).toBe(DeletionResult.DELETED);

const { channels } = await adminClient.query<GetChannels.Query>(GET_CHANNELS);
expect(channels.map(c => c.id).sort()).toEqual(['T_1', 'T_3']);
expect(channels.map(c => c.id).sort()).toEqual(['T_1']);

const { product } = await adminClient.query<
GetProductWithVariants.Query,
Expand Down
Loading

0 comments on commit 50975a4

Please sign in to comment.