|
|
@@ -8,14 +8,37 @@ import { omit } from '../../common/lib/omit';
|
|
|
|
|
|
import { PRODUCT_OPTION_GROUP_FRAGMENT } from './graphql/fragments';
|
|
|
import {
|
|
|
+ AddOptionGroupToProduct,
|
|
|
+ AddOptionGroupToProductMutation,
|
|
|
+ AddOptionGroupToProductMutationVariables,
|
|
|
+ CreateProduct,
|
|
|
+ CreateProductMutation,
|
|
|
+ CreateProductMutationVariables,
|
|
|
CreateProductOption,
|
|
|
CreateProductOptionGroup,
|
|
|
+ CreateProductVariants,
|
|
|
+ CreateProductVariantsMutation,
|
|
|
+ CreateProductVariantsMutationVariables,
|
|
|
+ DeleteProductOptionMutation,
|
|
|
+ DeleteProductOptionMutationVariables,
|
|
|
+ DeleteProductVariantMutation,
|
|
|
+ DeleteProductVariantMutationVariables,
|
|
|
+ DeletionResult,
|
|
|
+ GetProductOptionGroupQuery,
|
|
|
+ GetProductOptionGroupQueryVariables,
|
|
|
LanguageCode,
|
|
|
ProductOptionGroupFragment,
|
|
|
+ ProductVariantFragment,
|
|
|
UpdateProductOption,
|
|
|
UpdateProductOptionGroup,
|
|
|
} from './graphql/generated-e2e-admin-types';
|
|
|
-import { CREATE_PRODUCT_OPTION_GROUP } from './graphql/shared-definitions';
|
|
|
+import {
|
|
|
+ ADD_OPTION_GROUP_TO_PRODUCT,
|
|
|
+ CREATE_PRODUCT,
|
|
|
+ CREATE_PRODUCT_OPTION_GROUP,
|
|
|
+ CREATE_PRODUCT_VARIANTS,
|
|
|
+ DELETE_PRODUCT_VARIANT,
|
|
|
+} from './graphql/shared-definitions';
|
|
|
import { assertThrowsWithMessage } from './utils/assert-throws-with-message';
|
|
|
|
|
|
// tslint:disable:no-non-null-assertion
|
|
|
@@ -150,8 +173,139 @@ describe('ProductOption resolver', () => {
|
|
|
|
|
|
expect(updateProductOption.name).toBe('Middling');
|
|
|
});
|
|
|
+
|
|
|
+ describe('deletion', () => {
|
|
|
+ let sizeOptionGroupWithOptions: NonNullable<GetProductOptionGroupQuery['productOptionGroup']>;
|
|
|
+ let variants: CreateProductVariantsMutation['createProductVariants'];
|
|
|
+
|
|
|
+ beforeAll(async () => {
|
|
|
+ // Create a new product with a variant in each size option
|
|
|
+ const { createProduct } = await adminClient.query<
|
|
|
+ CreateProductMutation,
|
|
|
+ CreateProductMutationVariables
|
|
|
+ >(CREATE_PRODUCT, {
|
|
|
+ input: {
|
|
|
+ translations: [
|
|
|
+ {
|
|
|
+ languageCode: LanguageCode.en,
|
|
|
+ name: 'T-shirt',
|
|
|
+ slug: 't-shirt',
|
|
|
+ description: 'A television set',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ const result = await adminClient.query<
|
|
|
+ AddOptionGroupToProductMutation,
|
|
|
+ AddOptionGroupToProductMutationVariables
|
|
|
+ >(ADD_OPTION_GROUP_TO_PRODUCT, {
|
|
|
+ optionGroupId: sizeGroup.id,
|
|
|
+ productId: createProduct.id,
|
|
|
+ });
|
|
|
+
|
|
|
+ const { productOptionGroup } = await adminClient.query<
|
|
|
+ GetProductOptionGroupQuery,
|
|
|
+ GetProductOptionGroupQueryVariables
|
|
|
+ >(GET_PRODUCT_OPTION_GROUP, {
|
|
|
+ id: sizeGroup.id,
|
|
|
+ });
|
|
|
+
|
|
|
+ const variantInput: CreateProductVariantsMutationVariables['input'] =
|
|
|
+ productOptionGroup!.options.map((option, i) => ({
|
|
|
+ productId: createProduct.id,
|
|
|
+ sku: `TS-${option.code}`,
|
|
|
+ optionIds: [option.id],
|
|
|
+ translations: [{ languageCode: LanguageCode.en, name: `T-shirt ${option.code}` }],
|
|
|
+ }));
|
|
|
+
|
|
|
+ const { createProductVariants } = await adminClient.query<
|
|
|
+ CreateProductVariantsMutation,
|
|
|
+ CreateProductVariantsMutationVariables
|
|
|
+ >(CREATE_PRODUCT_VARIANTS, {
|
|
|
+ input: variantInput,
|
|
|
+ });
|
|
|
+ variants = createProductVariants;
|
|
|
+ sizeOptionGroupWithOptions = productOptionGroup!;
|
|
|
+ });
|
|
|
+
|
|
|
+ it(
|
|
|
+ 'attempting to delete a non-existent id throws',
|
|
|
+ assertThrowsWithMessage(
|
|
|
+ () =>
|
|
|
+ adminClient.query<DeleteProductOptionMutation, DeleteProductOptionMutationVariables>(
|
|
|
+ DELETE_PRODUCT_OPTION,
|
|
|
+ {
|
|
|
+ id: '999999',
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ "No ProductOption with the id '999999' could be found",
|
|
|
+ ),
|
|
|
+ );
|
|
|
+
|
|
|
+ it('cannot delete ProductOption that is used by a ProductVariant', async () => {
|
|
|
+ const { deleteProductOption } = await adminClient.query<
|
|
|
+ DeleteProductOptionMutation,
|
|
|
+ DeleteProductOptionMutationVariables
|
|
|
+ >(DELETE_PRODUCT_OPTION, {
|
|
|
+ id: sizeOptionGroupWithOptions.options.find(o => o.code === 'medium')!.id,
|
|
|
+ });
|
|
|
+
|
|
|
+ expect(deleteProductOption.result).toBe(DeletionResult.NOT_DELETED);
|
|
|
+ expect(deleteProductOption.message).toBe(
|
|
|
+ 'Cannot delete the option "medium" as it is being used by 1 ProductVariant',
|
|
|
+ );
|
|
|
+ });
|
|
|
+
|
|
|
+ it('can delete ProductOption after deleting associated ProductVariant', async () => {
|
|
|
+ const { deleteProductVariant } = await adminClient.query<
|
|
|
+ DeleteProductVariantMutation,
|
|
|
+ DeleteProductVariantMutationVariables
|
|
|
+ >(DELETE_PRODUCT_VARIANT, {
|
|
|
+ id: variants.find(v => v!.name.includes('medium'))!.id,
|
|
|
+ });
|
|
|
+
|
|
|
+ expect(deleteProductVariant.result).toBe(DeletionResult.DELETED);
|
|
|
+
|
|
|
+ const { deleteProductOption } = await adminClient.query<
|
|
|
+ DeleteProductOptionMutation,
|
|
|
+ DeleteProductOptionMutationVariables
|
|
|
+ >(DELETE_PRODUCT_OPTION, {
|
|
|
+ id: sizeOptionGroupWithOptions.options.find(o => o.code === 'medium')!.id,
|
|
|
+ });
|
|
|
+
|
|
|
+ expect(deleteProductOption.result).toBe(DeletionResult.DELETED);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('deleted ProductOptions not included in query result', async () => {
|
|
|
+ const { productOptionGroup } = await adminClient.query<
|
|
|
+ GetProductOptionGroupQuery,
|
|
|
+ GetProductOptionGroupQueryVariables
|
|
|
+ >(GET_PRODUCT_OPTION_GROUP, {
|
|
|
+ id: sizeGroup.id,
|
|
|
+ });
|
|
|
+
|
|
|
+ expect(productOptionGroup?.options.length).toBe(2);
|
|
|
+ expect(productOptionGroup?.options.findIndex(o => o.code === 'medium')).toBe(-1);
|
|
|
+ });
|
|
|
+ });
|
|
|
});
|
|
|
|
|
|
+const GET_PRODUCT_OPTION_GROUP = gql`
|
|
|
+ query GetProductOptionGroup($id: ID!) {
|
|
|
+ productOptionGroup(id: $id) {
|
|
|
+ id
|
|
|
+ code
|
|
|
+ name
|
|
|
+ options {
|
|
|
+ id
|
|
|
+ code
|
|
|
+ name
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+`;
|
|
|
+
|
|
|
const UPDATE_PRODUCT_OPTION_GROUP = gql`
|
|
|
mutation UpdateProductOptionGroup($input: UpdateProductOptionGroupInput!) {
|
|
|
updateProductOptionGroup(input: $input) {
|
|
|
@@ -187,3 +341,12 @@ const UPDATE_PRODUCT_OPTION = gql`
|
|
|
}
|
|
|
}
|
|
|
`;
|
|
|
+
|
|
|
+const DELETE_PRODUCT_OPTION = gql`
|
|
|
+ mutation DeleteProductOption($id: ID!) {
|
|
|
+ deleteProductOption(id: $id) {
|
|
|
+ result
|
|
|
+ message
|
|
|
+ }
|
|
|
+ }
|
|
|
+`;
|