Skip to content

Commit

Permalink
Adding sku to the product variant fields for CMS app (#1692)
Browse files Browse the repository at this point in the history
Co-authored-by: Wojciech Mista <[email protected]>
  • Loading branch information
JannikZed and Cloud11PL authored Jan 28, 2025
1 parent a8f63fc commit 34da7f1
Show file tree
Hide file tree
Showing 23 changed files with 183 additions and 90 deletions.
5 changes: 5 additions & 0 deletions .changeset/nervous-suns-hang.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"cms-v2": minor
---

Adding the SKU as synced field to the CMS app
38 changes: 20 additions & 18 deletions apps/cms-v2/generated/graphql.ts

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions apps/cms-v2/graphql/fragments/BulkImportProduct.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ fragment BulkImportProduct on Product {
variants {
id
name
sku
channelListings {
channel {
id
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
fragment WebhookProductVariant on ProductVariant {
id
name
sku
product {
id
name
Expand Down
4 changes: 3 additions & 1 deletion apps/cms-v2/src/modules/configuration/app-config.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { beforeEach,describe, expect, it } from "vitest";
import { beforeEach, describe, expect, it } from "vitest";

import { AppConfig } from "./app-config";
import { ContentfulProviderConfig } from "./schemas/contentful-provider.schema";
Expand All @@ -18,6 +18,7 @@ const getMockContentfulInput = (): ContentfulProviderConfig.InputShape => {
productSlug: "productSlug",
variantId: "variantId",
variantName: "variantName",
sku: "sku",
},
spaceId: "test",
};
Expand All @@ -35,6 +36,7 @@ const getMockDatocmsInput = (): DatocmsProviderConfig.InputShape => {
productSlug: "productSlug",
variantId: "variantId",
variantName: "variantName",
sku: "sku",
},
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,8 @@ export const printSaleorProductFields = (fieldName: SaleorProviderFieldsMappingK
case "variantId": {
return "Variant ID";
}
case "sku": {
return "SKU";
}
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const SaleorProviderFieldsMappingSchema = z.object({
productName: z.string().min(1),
productSlug: z.string().min(1),
channels: z.string().min(1),
sku: z.string().min(1),
});

export type SaleorProviderFieldsMappingType = z.infer<typeof SaleorProviderFieldsMappingSchema>;
Expand All @@ -22,4 +23,5 @@ export const SaleorProviderFieldsMappingKeys: Array<SaleorProviderFieldsMappingK
"productName",
"productSlug",
"channels",
"sku",
];
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,40 @@ export class BuilderIoBulkSyncProcessor implements BulkSyncProcessor {

async uploadProducts(
products: BulkImportProductFragment[],
hooks: BulkSyncProcessorHooks
hooks: BulkSyncProcessorHooks,
): Promise<void> {
const client = new BuilderIoClient(this.config);

products.flatMap((product) =>
product.variants?.map((variant) => {
if (hooks.onUploadStart) {
hooks.onUploadStart({ variantId: variant.id });
}
products.flatMap(
(product) =>
product.variants?.map((variant) => {
if (hooks.onUploadStart) {
hooks.onUploadStart({ variantId: variant.id });
}

return client
.upsertProductVariant({
id: variant.id,
name: variant.name,
channelListings: variant.channelListings,
product: {
id: product.id,
name: product.name,
slug: product.slug,
},
})
.then((r) => {
if (hooks.onUploadSuccess) {
hooks.onUploadSuccess({ variantId: variant.id });
}
})
.catch((e) => {
if (hooks.onUploadError) {
hooks.onUploadError({ variantId: variant.id, error: e });
}
});
})
return client
.upsertProductVariant({
id: variant.id,
name: variant.name,
channelListings: variant.channelListings,
sku: variant.sku,
product: {
id: product.id,
name: product.name,
slug: product.slug,
},
})
.then((r) => {
if (hooks.onUploadSuccess) {
hooks.onUploadSuccess({ variantId: variant.id });
}
})
.catch((e) => {
if (hooks.onUploadError) {
hooks.onUploadError({ variantId: variant.id, error: e });
}
});
}),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ const AddFormVariant = () => {
productName: "",
productSlug: "",
variantId: "",
sku: "",
},
}}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export class ContentfulBulkSyncProcessor implements BulkSyncProcessor {
id: variant.id,
name: variant.name,
channelListings: variant.channelListings,
sku: variant.sku,
product: {
id: product.id,
name: product.name,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { beforeEach,describe, expect, it, vi } from "vitest";
import { beforeEach, describe, expect, it, vi } from "vitest";

import { ContentfulProviderConfig } from "@/modules/configuration";

import { WebhookProductVariantFragment } from "../../../../generated/graphql";
import { ContentfulApiClientChunk,ContentfulClient } from "./contentful-client";
import { ContentfulApiClientChunk, ContentfulClient } from "./contentful-client";

const getMockContenfulConfiguration = (): ContentfulProviderConfig.FullShape => ({
authToken: "test-token",
Expand All @@ -20,13 +20,15 @@ const getMockContenfulConfiguration = (): ContentfulProviderConfig.FullShape =>
productSlug: "product-slug",
variantId: "variant-id",
variantName: "variant-name",
sku: "sku",
},
});

const getMockWebhookProductVariant = (): WebhookProductVariantFragment => {
return {
id: "test-id",
name: "test-name",
sku: "test-sku",
product: {
id: "test-product-id",
name: "test-product-name",
Expand Down Expand Up @@ -107,7 +109,26 @@ describe("ContentfulClient", () => {
describe("updateProductVariant", () => {
it("Mutates the entry fields and calls update method", async () => {
const mockEntry = {
fields: {},
fields: {
[getMockContenfulConfiguration().productVariantFieldsMapping.productId]: {
"en-US": getMockWebhookProductVariant().product.id,
},
[getMockContenfulConfiguration().productVariantFieldsMapping.productName]: {
"en-US": getMockWebhookProductVariant().product.name,
},
[getMockContenfulConfiguration().productVariantFieldsMapping.productSlug]: {
"en-US": getMockWebhookProductVariant().product.slug,
},
[getMockContenfulConfiguration().productVariantFieldsMapping.variantId]: {
"en-US": getMockWebhookProductVariant().id,
},
[getMockContenfulConfiguration().productVariantFieldsMapping.variantName]: {
"en-US": getMockWebhookProductVariant().name,
},
[getMockContenfulConfiguration().productVariantFieldsMapping.channels]: {
"en-US": getMockWebhookProductVariant().channelListings,
},
},
update: vi.fn().mockReturnValue(Promise.resolve({})),
};

Expand Down Expand Up @@ -154,6 +175,9 @@ describe("ContentfulClient", () => {
[mockMapping.variantName]: {
"en-US": mockVariant.name,
},
[mockMapping.sku]: {
"en-US": mockVariant.sku,
},
[mockMapping.channels]: {
"en-US": mockVariant.channelListings,
},
Expand Down Expand Up @@ -221,6 +245,9 @@ describe("ContentfulClient", () => {
[mockMapping.variantName]: {
"en-US": mockVariant.name,
},
[mockMapping.sku]: {
"en-US": mockVariant.sku,
},
[mockMapping.channels]: {
"en-US": mockVariant.channelListings,
},
Expand Down Expand Up @@ -262,6 +289,9 @@ describe("ContentfulClient", () => {
[mockMapping.variantName]: {
"en-US": mockVariant.name,
},
[mockMapping.sku]: {
"en-US": mockVariant.sku,
},
[mockMapping.channels]: {
"en-US": mockVariant.channelListings,
},
Expand All @@ -276,7 +306,26 @@ describe("ContentfulClient", () => {
const mockVariant = getMockWebhookProductVariant();

const mockEntry = {
fields: {},
fields: {
[mockMapping.productId]: {
"en-US": mockVariant.product.id,
},
[mockMapping.productName]: {
"en-US": mockVariant.product.name,
},
[mockMapping.productSlug]: {
"en-US": mockVariant.product.slug,
},
[mockMapping.variantId]: {
"en-US": mockVariant.id,
},
[mockMapping.variantName]: {
"en-US": mockVariant.name,
},
[mockMapping.channels]: {
"en-US": mockVariant.channelListings,
},
},
update: vi.fn().mockReturnValue(Promise.resolve({})),
};

Expand All @@ -288,7 +337,6 @@ describe("ContentfulClient", () => {
variant: mockVariant,
});

// todo fix
expect(mockEntry.fields).toEqual({
[mockMapping.productId]: {
"en-US": mockVariant.product.id,
Expand All @@ -305,6 +353,9 @@ describe("ContentfulClient", () => {
[mockMapping.variantName]: {
"en-US": mockVariant.name,
},
[mockMapping.sku]: {
"en-US": mockVariant.sku,
},
[mockMapping.channels]: {
"en-US": mockVariant.channelListings,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export class ContentfulClient {
productName,
productSlug,
variantId,
sku,
} = productVariantFieldsMapping;

return {
Expand All @@ -75,6 +76,9 @@ export class ContentfulClient {
[variantId]: {
"en-US": variant.id,
},
[sku]: {
"en-US": variant.sku,
},
[channels]: {
"en-US": variant.channelListings,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ const AddVariant = () => {
productName: "",
productSlug: "",
variantId: "",
sku: "",
},
spaceId: "",
}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { beforeEach,describe, expect, it, vi } from "vitest";
import { beforeEach, describe, expect, it, vi } from "vitest";

import { ContentfulProviderConfig } from "@/modules/configuration";

Expand All @@ -23,13 +23,15 @@ const getMockContenfulConfiguration = (): ContentfulProviderConfig.FullShape =>
productSlug: "product-slug",
variantId: "variant-id",
variantName: "variant-name",
sku: "sku",
},
});

const getMockWebhookProductVariant = (): WebhookProductVariantFragment => {
return {
id: "test-id",
name: "test-name",
sku: "test-sku",
product: {
id: "test-product-id",
name: "test-product-name",
Expand Down Expand Up @@ -63,7 +65,7 @@ describe("ContentfulWebhooksProcessor", () => {

processor = new ContentfulWebhooksProcessor(
getMockContenfulConfiguration(),
() => mockContentfulClient
() => mockContentfulClient,
);
});

Expand All @@ -76,7 +78,7 @@ describe("ContentfulWebhooksProcessor", () => {
expect.objectContaining({
configuration: getMockContenfulConfiguration(),
variant: mockProductVariant,
})
}),
);
});

Expand All @@ -89,7 +91,7 @@ describe("ContentfulWebhooksProcessor", () => {
expect.objectContaining({
configuration: getMockContenfulConfiguration(),
variant: mockProductVariant,
})
}),
);
});

Expand All @@ -102,7 +104,7 @@ describe("ContentfulWebhooksProcessor", () => {
expect.objectContaining({
configuration: getMockContenfulConfiguration(),
variant: mockProductVariant,
})
}),
);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export class DatocmsBulkSyncProcessor implements BulkSyncProcessor {
id: variant.id,
name: variant.name,
channelListings: variant.channelListings,
sku: variant.sku,
product: {
id: product.id,
name: product.name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ const AddFormVariant = () => {
productName: "",
productSlug: "",
variantId: "",
sku: "",
},
}}
/>
Expand Down
Loading

0 comments on commit 34da7f1

Please sign in to comment.