From 99eedb14fad96a7c82fb74af44d3b5577f28ec6d Mon Sep 17 00:00:00 2001 From: Sebastian Rindom Date: Mon, 14 Jun 2021 15:36:54 +0200 Subject: [PATCH 1/4] chore: testing skeleton --- .../__mocks__/contentful-management.js | 7 + .../src/services/__tests__/contentful.js | 9 + .../src/services/contentful.js | 169 ++++++++++-------- 3 files changed, 108 insertions(+), 77 deletions(-) create mode 100644 packages/medusa-plugin-contentful/__mocks__/contentful-management.js create mode 100644 packages/medusa-plugin-contentful/src/services/__tests__/contentful.js diff --git a/packages/medusa-plugin-contentful/__mocks__/contentful-management.js b/packages/medusa-plugin-contentful/__mocks__/contentful-management.js new file mode 100644 index 0000000000..f988c3f87b --- /dev/null +++ b/packages/medusa-plugin-contentful/__mocks__/contentful-management.js @@ -0,0 +1,7 @@ +module.exports = { + mockClient: { + + }, + createClient: () => { + } +} diff --git a/packages/medusa-plugin-contentful/src/services/__tests__/contentful.js b/packages/medusa-plugin-contentful/src/services/__tests__/contentful.js new file mode 100644 index 0000000000..a684753239 --- /dev/null +++ b/packages/medusa-plugin-contentful/src/services/__tests__/contentful.js @@ -0,0 +1,9 @@ +describe("contentfulService", () => { + const redisClient = { + set: jest.fn(), + get: jest.fn() + } + + describe("", () => { + }) +}) diff --git a/packages/medusa-plugin-contentful/src/services/contentful.js b/packages/medusa-plugin-contentful/src/services/contentful.js index f78d714073..55dfacc40f 100644 --- a/packages/medusa-plugin-contentful/src/services/contentful.js +++ b/packages/medusa-plugin-contentful/src/services/contentful.js @@ -2,6 +2,8 @@ import _ from "lodash" import { BaseService } from "medusa-interfaces" import { createClient } from "contentful-management" +const IGNORE_THRESHOLD = 1 // seconds + class ContentfulService extends BaseService { constructor( { productService, redisClient, productVariantService, eventBusService }, @@ -24,16 +26,14 @@ class ContentfulService extends BaseService { this.redis_ = redisClient } - async getIgnoreIds_(type) { - return new Promise((resolve, reject) => { - this.redis_.get(`${type}_ignore_ids`, (err, reply) => { - if (err) { - return reject(err) - } + async addIgnore_(id, side) { + const key = `${id}_ignore_${side}` + return await this.redis_.set(key, 1, "EX", IGNORE_THRESHOLD) + } - return resolve(JSON.parse(reply)) - }) - }) + async shouldIgnore_(id, side) { + const key = `${id}_ignore_${side}` + return await this.redis_.get(key) } async getContentfulEnvironment_() { @@ -46,12 +46,17 @@ class ContentfulService extends BaseService { } } - async getVariantEntries_(variants) { + async getVariantEntries_(variants, config = { publish: false }) { try { const contentfulVariants = await Promise.all( - variants.map((variant) => - this.updateProductVariantInContentful(variant) - ) + variants.map(async (variant) => { + let updated = await this.updateProductVariantInContentful(variant) + if (config.publish) { + updated = updated.publish() + } + + return updated + }) ) return contentfulVariants @@ -137,13 +142,21 @@ class ContentfulService extends BaseService { }) const environment = await this.getContentfulEnvironment_() - const variantEntries = await this.getVariantEntries_(p.variants) + const variantEntries = await this.getVariantEntries_(p.variants, { + publish: true, + }) const variantLinks = this.getVariantLinks_(variantEntries) const fields = { [this.getCustomField("title", "product")]: { "en-US": p.title, }, + [this.getCustomField("subtitle", "product")]: { + "en-US": p.subtitle, + }, + [this.getCustomField("description", "product")]: { + "en-US": p.description, + }, [this.getCustomField("variants", "product")]: { "en-US": variantLinks, }, @@ -157,7 +170,14 @@ class ContentfulService extends BaseService { if (p.images.length > 0) { const imageLinks = await this.createImageAssets(product) + if (imageLinks) { + fields.images = { + "en-US": imageLinks, + } + } + } + if (p.thumbnail) { const thumbnailAsset = await environment.createAsset({ fields: { title: { @@ -176,7 +196,7 @@ class ContentfulService extends BaseService { }, }) - await thumbnailAsset.processForAllLocales() + await thumbnailAsset.processForAllLocales().then((a) => a.publish()) const thumbnailLink = { sys: { @@ -189,12 +209,6 @@ class ContentfulService extends BaseService { fields.thumbnail = { "en-US": thumbnailLink, } - - if (imageLinks) { - fields.images = { - "en-US": imageLinks, - } - } } if (p.type) { @@ -233,9 +247,6 @@ class ContentfulService extends BaseService { fields, }) - // const ignoreIds = (await this.getIgnoreIds_("product")) || [] - // ignoreIds.push(product.id) - // this.redis_.set("product_ignore_ids", JSON.stringify(ignoreIds)) return result } catch (error) { throw error @@ -288,6 +299,7 @@ class ContentfulService extends BaseService { "options", "tags", "title", + "subtitle", "tags", "type", "type_id", @@ -302,16 +314,10 @@ class ContentfulService extends BaseService { } try { - // const ignoreIds = (await this.getIgnoreIds_("product")) || [] - - // if (ignoreIds.includes(product.id)) { - // const newIgnoreIds = ignoreIds.filter((id) => id !== product.id) - // this.redis_.set("product_ignore_ids", JSON.stringify(newIgnoreIds)) - // return - // } else { - // ignoreIds.push(product.id) - // this.redis_.set("product_ignore_ids", JSON.stringify(ignoreIds)) - // } + const ignore = await this.shouldIgnore_(data.id, "contentful") + if (ignore) { + return + } const p = await this.productService_.retrieve(data.id, { relations: [ @@ -341,6 +347,12 @@ class ContentfulService extends BaseService { [this.getCustomField("title", "product")]: { "en-US": p.title, }, + [this.getCustomField("subtitle", "product")]: { + "en-US": p.subtitle, + }, + [this.getCustomField("description", "product")]: { + "en-US": p.description, + }, [this.getCustomField("options", "product")]: { "en-US": p.options, }, @@ -376,7 +388,7 @@ class ContentfulService extends BaseService { }, }) - await thumbnailAsset.processForAllLocales() + await thumbnailAsset.processForAllLocales().then((a) => a.publish()) const thumbnailLink = { sys: { @@ -430,6 +442,8 @@ class ContentfulService extends BaseService { const updatedEntry = await productEntry.update() const publishedEntry = await updatedEntry.publish() + await this.addIgnore_(data.id, "medusa") + return publishedEntry } catch (error) { throw error @@ -460,19 +474,10 @@ class ContentfulService extends BaseService { } try { - // const ignoreIds = (await this.getIgnoreIds_("product_variant")) || [] - - //if (ignoreIds.includes(variant.id)) { - // const newIgnoreIds = ignoreIds.filter((id) => id !== variant.id) - // this.redis_.set( - // "product_variant_ignore_ids", - // JSON.stringify(newIgnoreIds) - // ) - // return - //} else { - // ignoreIds.push(variant.id) - // this.redis_.set("product_variant_ignore_ids", JSON.stringify(ignoreIds)) - //} + const ignore = await this.shouldIgnore_(variant.id, "contentful") + if (ignore) { + return + } const environment = await this.getContentfulEnvironment_() // check if product exists @@ -512,6 +517,8 @@ class ContentfulService extends BaseService { const updatedEntry = await variantEntry.update() const publishedEntry = await updatedEntry.publish() + await this.addIgnore_(variant.id, "medusa") + return publishedEntry } catch (error) { throw error @@ -519,29 +526,42 @@ class ContentfulService extends BaseService { } async sendContentfulProductToAdmin(productId) { + const ignore = await this.shouldIgnore_(productId, "medusa") + if (ignore) { + return + } + try { const environment = await this.getContentfulEnvironment_() const productEntry = await environment.getEntry(productId) const product = await this.productService_.retrieve(productId) - //const ignoreIds = (await this.getIgnoreIds_("product")) || [] - //if (ignoreIds.includes(productId)) { - // const newIgnoreIds = ignoreIds.filter((id) => id !== productId) - // this.redis_.set("product_ignore_ids", JSON.stringify(newIgnoreIds)) - // return - //} else { - // ignoreIds.push(productId) - // this.redis_.set("product_ignore_ids", JSON.stringify(ignoreIds)) - //} - let update = {} + const title = productEntry.fields[this.getCustomField("title", "product")]["en-US"] + + const subtitle = + productEntry.fields[this.getCustomField("subtitle", "product")]["en-US"] + + const description = + productEntry.fields[this.getCustomField("description", "product")][ + "en-US" + ] + if (product.title !== title) { update.title = title } + if (product.subtitle !== subtitle) { + update.subtitle = subtitle + } + + if (product.description !== description) { + update.description = description + } + // Get the thumbnail, if present if (productEntry.fields.thumbnail) { const thumb = await environment.getAsset( @@ -556,7 +576,9 @@ class ContentfulService extends BaseService { } if (!_.isEmpty(update)) { - await this.productService_.update(productId, update) + await this.productService_.update(productId, update).then(async () => { + return await this.addIgnore_(productId, "contentful") + }) } } catch (error) { throw error @@ -564,32 +586,25 @@ class ContentfulService extends BaseService { } async sendContentfulProductVariantToAdmin(variantId) { + const ignore = this.shouldIgnore_(variantId, "medusa") + if (ignore) { + return + } + try { const environment = await this.getContentfulEnvironment_() const variantEntry = await environment.getEntry(variantId) - // const ignoreIds = (await this.getIgnoreIds_("product_variant")) || [] - // if (ignoreIds.includes(variantId)) { - // const newIgnoreIds = ignoreIds.filter((id) => id !== variantId) - // this.redis_.set( - // "product_variant_ignore_ids", - // JSON.stringify(newIgnoreIds) - // ) - // return - // } else { - // ignoreIds.push(variantId) - // this.redis_.set("product_variant_ignore_ids", JSON.stringify(ignoreIds)) - // } - - const updatedVariant = await this.productVariantService_.update( - variantId, - { + const updatedVariant = await this.productVariantService_ + .update(variantId, { title: variantEntry.fields[this.getCustomField("title", "variant")][ "en-US" ], - } - ) + }) + .then(async () => { + return await this.addIgnore_(variantId, "contentful") + }) return updatedVariant } catch (error) { From 27173d7e6a78c221ae065a0a4d8fc75a658c04b1 Mon Sep 17 00:00:00 2001 From: Sebastian Rindom Date: Tue, 15 Jun 2021 15:03:03 +0200 Subject: [PATCH 2/4] wip --- .../__mocks__/contentful-management.js | 31 ++++- .../src/services/__tests__/contentful.js | 92 +++++++++++++- .../src/services/contentful.js | 117 +++++++++++++++++- packages/medusa/src/services/region.js | 79 +++++++++--- 4 files changed, 295 insertions(+), 24 deletions(-) diff --git a/packages/medusa-plugin-contentful/__mocks__/contentful-management.js b/packages/medusa-plugin-contentful/__mocks__/contentful-management.js index f988c3f87b..c613964699 100644 --- a/packages/medusa-plugin-contentful/__mocks__/contentful-management.js +++ b/packages/medusa-plugin-contentful/__mocks__/contentful-management.js @@ -1,7 +1,26 @@ -module.exports = { - mockClient: { - - }, - createClient: () => { - } +export const MockEntry = { + update: jest.fn(() => Promise.resolve(MockEntry)), + publish: jest.fn(() => Promise.resolve({ sys: { id: "test" } })), } + +export const MockAsset = { + processForAllLocales: jest.fn(() => Promise.resolve(MockAsset)), + publish: jest.fn(() => Promise.resolve({ sys: { id: "test" } })), +} + +export const MockEnvironment = { + createAsset: jest.fn((d) => Promise.resolve(MockAsset)), + createEntryWithId: jest.fn(() => Promise.resolve(MockEntry)), + getEntry: jest.fn(() => Promise.resolve(MockEntry)), + getContentType: jest.fn(() => Promise.resolve({})), +} + +export const MockSpace = { + getEnvironment: jest.fn(() => Promise.resolve(MockEnvironment)), +} + +export const MockClient = { + getSpace: jest.fn(() => Promise.resolve(MockSpace)), +} + +export const createClient = jest.fn(() => MockClient) diff --git a/packages/medusa-plugin-contentful/src/services/__tests__/contentful.js b/packages/medusa-plugin-contentful/src/services/__tests__/contentful.js index a684753239..881fa4c54c 100644 --- a/packages/medusa-plugin-contentful/src/services/__tests__/contentful.js +++ b/packages/medusa-plugin-contentful/src/services/__tests__/contentful.js @@ -1,9 +1,97 @@ +import ContentfulService from "../contentful" +import { MockEnvironment } from "../../../__mocks__/contentful-management" + +jest.mock("contentful-management") + describe("contentfulService", () => { const redisClient = { set: jest.fn(), - get: jest.fn() + get: jest.fn(), } - describe("", () => { + const ProductVariantService = { + retrieve: jest.fn(() => + Promise.resolve({ + id: "variant_medusa", + title: "testvar", + }) + ), + } + + const ProductService = { + retrieve: jest.fn(() => + Promise.resolve({ + id: "product_medusa", + title: "test", + subtitle: "subtest", + description: "something long", + variants: [ + { + id: "variant_medusa", + title: "testvar", + }, + ], + }) + ), + } + + describe("createProductInContentful", () => { + beforeEach(() => { + jest.clearAllMocks() + }) + + it("resolves", async () => { + const contentfulService = new ContentfulService( + { + redisClient, + productVariantService: ProductVariantService, + productService: ProductService, + }, + {} + ) + + await contentfulService.updateProductInContentful({ + id: "testId", + fields: ["title"], + }) + }) + }) + describe("createImageAssets", () => { + beforeEach(() => { + jest.clearAllMocks() + }) + + it("successfully creates assets", async () => { + const contentfulService = new ContentfulService( + { + redisClient, + }, + {} + ) + + await contentfulService.createImageAssets({ + title: "testprod", + images: [{ url: "test123" }], + }) + + expect(MockEnvironment.createAsset).toHaveBeenCalledTimes(1) + expect(MockEnvironment.createAsset).toHaveBeenCalledWith({ + fields: { + title: { + "en-US": `testprod - 0`, + }, + description: { + "en-US": "", + }, + file: { + "en-US": { + contentType: "image/xyz", + fileName: "test123", + upload: "test123", + }, + }, + }, + }) + }) }) }) diff --git a/packages/medusa-plugin-contentful/src/services/contentful.js b/packages/medusa-plugin-contentful/src/services/contentful.js index 55dfacc40f..38f7b4edb3 100644 --- a/packages/medusa-plugin-contentful/src/services/contentful.js +++ b/packages/medusa-plugin-contentful/src/services/contentful.js @@ -2,7 +2,7 @@ import _ from "lodash" import { BaseService } from "medusa-interfaces" import { createClient } from "contentful-management" -const IGNORE_THRESHOLD = 1 // seconds +const IGNORE_THRESHOLD = 2 // seconds class ContentfulService extends BaseService { constructor( @@ -28,7 +28,12 @@ class ContentfulService extends BaseService { async addIgnore_(id, side) { const key = `${id}_ignore_${side}` - return await this.redis_.set(key, 1, "EX", IGNORE_THRESHOLD) + return await this.redis_.set( + key, + 1, + "EX", + this.options_.ignore_threshold || IGNORE_THRESHOLD + ) } async shouldIgnore_(id, side) { @@ -293,6 +298,114 @@ class ContentfulService extends BaseService { } } + async createRegionInContentful(region) { + const hasType = await this.getType("region") + .then(() => true) + .catch(() => false) + if (!hasType) { + return + } + try { + const r = await this.regionService_.retrieve(data.id, { + relations: ["countries", "payment_providers", "fulfillment_providers"], + }) + + const environment = await this.getContentfulEnvironment_() + + const fields = { + [this.getCustomField("name", "region")]: { + "en-US": r.name, + }, + [this.getCustomField("countries", "region")]: { + "en-US": r.countries, + }, + [this.getCustomField("payment_providers", "region")]: { + "en-US": r.payment_providers, + }, + [this.getCustomField("fulfillment_providers", "region")]: { + "en-US": r.fulfillment_providers, + }, + } + + const result = await environment.createEntryWithId("region", p.id, { + fields, + }) + + return result + } catch (error) { + throw error + } + } + + async updateRegionInContentful(data) { + const hasType = await this.getType("region") + .then(() => true) + .catch(() => false) + if (!hasType) { + return + } + + const updateFields = [ + "name", + "currency_code", + "countries", + "payment_providers", + "fulfillment_providers", + ] + + const found = data.fields.find((f) => updateFields.includes(f)) + if (!found) { + return + } + + try { + const ignore = await this.shouldIgnore_(data.id, "contentful") + if (ignore) { + return + } + + const r = await this.regionService_.retrieve(data.id, { + relations: ["countries", "payment_providers", "fulfillment_providers"], + }) + + const environment = await this.getContentfulEnvironment_() + // check if product exists + let regionEntry = undefined + try { + regionEntry = await environment.getEntry(data.id) + } catch (error) { + return this.createRegionInContentful(r) + } + + const regionEntryFields = { + ...regionEntry.fields, + [this.getCustomField("name", "region")]: { + "en-US": r.name, + }, + [this.getCustomField("countries", "region")]: { + "en-US": r.countries, + }, + [this.getCustomField("payment_providers", "region")]: { + "en-US": r.payment_providers, + }, + [this.getCustomField("fulfillment_providers", "region")]: { + "en-US": r.fulfillment_providers, + }, + } + + regionEntry.fields = regionEntryFields + + const updatedEntry = await regionEntry.update() + const publishedEntry = await updatedEntry.publish() + + await this.addIgnore_(data.id, "medusa") + + return publishedEntry + } catch (error) { + throw error + } + } + async updateProductInContentful(data) { const updateFields = [ "variants", diff --git a/packages/medusa/src/services/region.js b/packages/medusa/src/services/region.js index cec4c6690a..33a56ff3c7 100644 --- a/packages/medusa/src/services/region.js +++ b/packages/medusa/src/services/region.js @@ -8,11 +8,17 @@ import { countries } from "../utils/countries" * @implements BaseService */ class RegionService extends BaseService { + static Events = { + UPDATED: "region.updated", + CREATED: "region.created", + } + constructor({ manager, regionRepository, countryRepository, storeService, + eventBusService, currencyRepository, paymentProviderRepository, fulfillmentProviderRepository, @@ -33,6 +39,9 @@ class RegionService extends BaseService { /** @private @const {StoreService} */ this.storeService_ = storeService + /** @private @const {EventBus} */ + this.eventBus_ = eventBusService + /** @private @const {CurrencyRepository} */ this.currencyRepository_ = currencyRepository @@ -60,6 +69,7 @@ class RegionService extends BaseService { currencyRepository: this.currencyRepository_, countryRepository: this.countryRepository_, storeService: this.storeService_, + eventBusService: this.eventBus_, paymentProviderRepository: this.paymentProviderRepository_, paymentProviderService: this.paymentProviderService_, fulfillmentProviderRepository: this.fulfillmentProviderRepository_, @@ -117,6 +127,13 @@ class RegionService extends BaseService { const created = regionRepository.create(regionObject) const result = await regionRepository.save(created) + + await this.eventBus_ + .withTransaction(manager) + .emit(RegionService.Events.CREATED, { + id: result.id, + }) + return result }) } @@ -168,6 +185,14 @@ class RegionService extends BaseService { } const result = await regionRepository.save(region) + + await this.eventBus_ + .withTransaction(manager) + .emit(RegionService.Events.UPDATED, { + id: result.id, + fields: Object.keys(update), + }) + return result }) } @@ -390,6 +415,14 @@ class RegionService extends BaseService { region.countries = [...(region.countries || []), country] const updated = await regionRepo.save(region) + + await this.eventBus_ + .withTransaction(manager) + .emit(RegionService.Events.UPDATED, { + id: updated.id, + fields: ["countries"], + }) + return updated }) } @@ -419,6 +452,12 @@ class RegionService extends BaseService { ) const updated = await regionRepo.save(region) + await this.eventBus_ + .withTransaction(manager) + .emit(RegionService.Events.UPDATED, { + id: updated.id, + fields: ["countries"], + }) return updated }) } @@ -458,6 +497,14 @@ class RegionService extends BaseService { region.payment_providers = [...region.payment_providers, pp] const updated = await regionRepo.save(region) + + await this.eventBus_ + .withTransaction(manager) + .emit(RegionService.Events.UPDATED, { + id: updated.id, + fields: ["payment_providers"], + }) + return updated }) } @@ -497,6 +544,12 @@ class RegionService extends BaseService { region.fulfillment_providers = [...region.fulfillment_providers, fp] const updated = await regionRepo.save(region) + await this.eventBus_ + .withTransaction(manager) + .emit(RegionService.Events.UPDATED, { + id: updated.id, + fields: ["fulfillment_providers"], + }) return updated }) } @@ -525,6 +578,12 @@ class RegionService extends BaseService { ) const updated = await regionRepo.save(region) + await this.eventBus_ + .withTransaction(manager) + .emit(RegionService.Events.UPDATED, { + id: updated.id, + fields: ["payment_providers"], + }) return updated }) } @@ -553,23 +612,15 @@ class RegionService extends BaseService { ) const updated = await regionRepo.save(region) + await this.eventBus_ + .withTransaction(manager) + .emit(RegionService.Events.UPDATED, { + id: updated.id, + fields: ["fulfillment_providers"], + }) return updated }) } - - /** - * Decorates a region - * @param {object} region - the region to decorate - * @param {[string]} fields - the fields to include - * @param {[string]} expandFields - the fields to expand - * @return {Region} the region - */ - async decorate(region, fields, expandFields = []) { - const requiredFields = ["id", "metadata"] - const decorated = _.pick(region, fields.concat(requiredFields)) - const final = await this.runDecorators_(decorated) - return final - } } export default RegionService From 8e29e6e63c305b684a37d817b504b3e471d697bd Mon Sep 17 00:00:00 2001 From: Sebastian Rindom Date: Tue, 15 Jun 2021 15:45:59 +0200 Subject: [PATCH 3/4] fix: region sync --- .babelrc.js | 6 +- .../__mocks__/contentful-management.js | 26 ----- .../src/services/__tests__/contentful.js | 97 ------------------- .../src/services/contentful.js | 25 +++-- .../src/subscribers/contentful.js | 8 ++ .../medusa/src/services/__tests__/region.js | 19 ++++ 6 files changed, 48 insertions(+), 133 deletions(-) delete mode 100644 packages/medusa-plugin-contentful/__mocks__/contentful-management.js delete mode 100644 packages/medusa-plugin-contentful/src/services/__tests__/contentful.js diff --git a/.babelrc.js b/.babelrc.js index bde709c495..39c0fa3e45 100644 --- a/.babelrc.js +++ b/.babelrc.js @@ -1,13 +1,13 @@ -let ignore = [`**/dist`] +let ignore = [`**/dist`]; // Jest needs to compile this code, but generally we don't want this copied // to output folders if (process.env.NODE_ENV !== `test`) { - ignore.push(`**/__tests__`) + ignore.push(`**/__tests__`); } module.exports = { sourceMaps: true, presets: ["babel-preset-medusa-package"], ignore, -} +}; diff --git a/packages/medusa-plugin-contentful/__mocks__/contentful-management.js b/packages/medusa-plugin-contentful/__mocks__/contentful-management.js deleted file mode 100644 index c613964699..0000000000 --- a/packages/medusa-plugin-contentful/__mocks__/contentful-management.js +++ /dev/null @@ -1,26 +0,0 @@ -export const MockEntry = { - update: jest.fn(() => Promise.resolve(MockEntry)), - publish: jest.fn(() => Promise.resolve({ sys: { id: "test" } })), -} - -export const MockAsset = { - processForAllLocales: jest.fn(() => Promise.resolve(MockAsset)), - publish: jest.fn(() => Promise.resolve({ sys: { id: "test" } })), -} - -export const MockEnvironment = { - createAsset: jest.fn((d) => Promise.resolve(MockAsset)), - createEntryWithId: jest.fn(() => Promise.resolve(MockEntry)), - getEntry: jest.fn(() => Promise.resolve(MockEntry)), - getContentType: jest.fn(() => Promise.resolve({})), -} - -export const MockSpace = { - getEnvironment: jest.fn(() => Promise.resolve(MockEnvironment)), -} - -export const MockClient = { - getSpace: jest.fn(() => Promise.resolve(MockSpace)), -} - -export const createClient = jest.fn(() => MockClient) diff --git a/packages/medusa-plugin-contentful/src/services/__tests__/contentful.js b/packages/medusa-plugin-contentful/src/services/__tests__/contentful.js deleted file mode 100644 index 881fa4c54c..0000000000 --- a/packages/medusa-plugin-contentful/src/services/__tests__/contentful.js +++ /dev/null @@ -1,97 +0,0 @@ -import ContentfulService from "../contentful" -import { MockEnvironment } from "../../../__mocks__/contentful-management" - -jest.mock("contentful-management") - -describe("contentfulService", () => { - const redisClient = { - set: jest.fn(), - get: jest.fn(), - } - - const ProductVariantService = { - retrieve: jest.fn(() => - Promise.resolve({ - id: "variant_medusa", - title: "testvar", - }) - ), - } - - const ProductService = { - retrieve: jest.fn(() => - Promise.resolve({ - id: "product_medusa", - title: "test", - subtitle: "subtest", - description: "something long", - variants: [ - { - id: "variant_medusa", - title: "testvar", - }, - ], - }) - ), - } - - describe("createProductInContentful", () => { - beforeEach(() => { - jest.clearAllMocks() - }) - - it("resolves", async () => { - const contentfulService = new ContentfulService( - { - redisClient, - productVariantService: ProductVariantService, - productService: ProductService, - }, - {} - ) - - await contentfulService.updateProductInContentful({ - id: "testId", - fields: ["title"], - }) - }) - }) - describe("createImageAssets", () => { - beforeEach(() => { - jest.clearAllMocks() - }) - - it("successfully creates assets", async () => { - const contentfulService = new ContentfulService( - { - redisClient, - }, - {} - ) - - await contentfulService.createImageAssets({ - title: "testprod", - images: [{ url: "test123" }], - }) - - expect(MockEnvironment.createAsset).toHaveBeenCalledTimes(1) - expect(MockEnvironment.createAsset).toHaveBeenCalledWith({ - fields: { - title: { - "en-US": `testprod - 0`, - }, - description: { - "en-US": "", - }, - file: { - "en-US": { - contentType: "image/xyz", - fileName: "test123", - upload: "test123", - }, - }, - }, - }) - }) - }) -}) diff --git a/packages/medusa-plugin-contentful/src/services/contentful.js b/packages/medusa-plugin-contentful/src/services/contentful.js index 38f7b4edb3..020ca609d9 100644 --- a/packages/medusa-plugin-contentful/src/services/contentful.js +++ b/packages/medusa-plugin-contentful/src/services/contentful.js @@ -6,7 +6,13 @@ const IGNORE_THRESHOLD = 2 // seconds class ContentfulService extends BaseService { constructor( - { productService, redisClient, productVariantService, eventBusService }, + { + regionService, + productService, + redisClient, + productVariantService, + eventBusService, + }, options ) { super() @@ -15,6 +21,8 @@ class ContentfulService extends BaseService { this.productVariantService_ = productVariantService + this.regionService_ = regionService + this.eventBus_ = eventBusService this.options_ = options @@ -306,28 +314,31 @@ class ContentfulService extends BaseService { return } try { - const r = await this.regionService_.retrieve(data.id, { + const r = await this.regionService_.retrieve(region.id, { relations: ["countries", "payment_providers", "fulfillment_providers"], }) const environment = await this.getContentfulEnvironment_() const fields = { + [this.getCustomField("medusaId", "product")]: { + "en-US": r.id, + }, [this.getCustomField("name", "region")]: { "en-US": r.name, }, [this.getCustomField("countries", "region")]: { "en-US": r.countries, }, - [this.getCustomField("payment_providers", "region")]: { + [this.getCustomField("paymentProviders", "region")]: { "en-US": r.payment_providers, }, - [this.getCustomField("fulfillment_providers", "region")]: { + [this.getCustomField("fulfillmentProviders", "region")]: { "en-US": r.fulfillment_providers, }, } - const result = await environment.createEntryWithId("region", p.id, { + const result = await environment.createEntryWithId("region", r.id, { fields, }) @@ -385,10 +396,10 @@ class ContentfulService extends BaseService { [this.getCustomField("countries", "region")]: { "en-US": r.countries, }, - [this.getCustomField("payment_providers", "region")]: { + [this.getCustomField("paymentProviders", "region")]: { "en-US": r.payment_providers, }, - [this.getCustomField("fulfillment_providers", "region")]: { + [this.getCustomField("fulfillmentProviders", "region")]: { "en-US": r.fulfillment_providers, }, } diff --git a/packages/medusa-plugin-contentful/src/subscribers/contentful.js b/packages/medusa-plugin-contentful/src/subscribers/contentful.js index 301ac00160..6431ea60c4 100644 --- a/packages/medusa-plugin-contentful/src/subscribers/contentful.js +++ b/packages/medusa-plugin-contentful/src/subscribers/contentful.js @@ -10,6 +10,14 @@ class ContentfulSubscriber { this.contentfulService_ = contentfulService this.eventBus_ = eventBusService + this.eventBus_.subscribe("region.created", async (data) => { + await this.contentfulService_.createRegionInContentful(data) + }) + + this.eventBus_.subscribe("region.updated", async (data) => { + await this.contentfulService_.updateRegionInContentful(data) + }) + this.eventBus_.subscribe("product-variant.updated", async (data) => { await this.contentfulService_.updateProductVariantInContentful(data) }) diff --git a/packages/medusa/src/services/__tests__/region.js b/packages/medusa/src/services/__tests__/region.js index bd23d97285..4ea0efa171 100644 --- a/packages/medusa/src/services/__tests__/region.js +++ b/packages/medusa/src/services/__tests__/region.js @@ -1,6 +1,14 @@ import { IdMap, MockManager, MockRepository } from "medusa-test-utils" import RegionService from "../region" +const eventBusService = { + emit: jest.fn(), + withTransaction: function() { + return this + }, +} + + describe("RegionService", () => { describe("create", () => { const regionRepository = MockRepository({}) @@ -58,6 +66,7 @@ describe("RegionService", () => { const regionService = new RegionService({ manager: MockManager, + eventBusService, fulfillmentProviderRepository: fpRepository, paymentProviderRepository: ppRepository, currencyRepository, @@ -168,6 +177,7 @@ describe("RegionService", () => { const regionService = new RegionService({ manager: MockManager, + eventBusService, regionRepository, }) @@ -237,6 +247,7 @@ describe("RegionService", () => { const regionService = new RegionService({ manager: MockManager, + eventBusService, fulfillmentProviderRepository: fpRepository, paymentProviderRepository: ppRepository, regionRepository, @@ -335,6 +346,7 @@ describe("RegionService", () => { const regionService = new RegionService({ manager: MockManager, + eventBusService, fulfillmentProviderRepository: fpRepository, paymentProviderRepository: ppRepository, regionRepository, @@ -380,6 +392,7 @@ describe("RegionService", () => { const regionService = new RegionService({ manager: MockManager, + eventBusService, regionRepository, }) @@ -429,6 +442,7 @@ describe("RegionService", () => { const regionService = new RegionService({ manager: MockManager, + eventBusService, regionRepository, countryRepository, }) @@ -473,6 +487,7 @@ describe("RegionService", () => { const regionService = new RegionService({ manager: MockManager, + eventBusService, regionRepository, }) @@ -522,6 +537,7 @@ describe("RegionService", () => { const regionService = new RegionService({ manager: MockManager, + eventBusService, fulfillmentProviderRepository: fpRepository, paymentProviderRepository: ppRepository, regionRepository, @@ -582,6 +598,7 @@ describe("RegionService", () => { const regionService = new RegionService({ manager: MockManager, + eventBusService, fulfillmentProviderRepository: fpRepository, regionRepository, }) @@ -631,6 +648,7 @@ describe("RegionService", () => { const regionService = new RegionService({ manager: MockManager, + eventBusService, regionRepository, }) @@ -665,6 +683,7 @@ describe("RegionService", () => { const regionService = new RegionService({ manager: MockManager, + eventBusService, regionRepository, }) From 4b6445a1b0509dd0c00f240a4ae287caf1a46ebf Mon Sep 17 00:00:00 2001 From: Sebastian Rindom Date: Tue, 15 Jun 2021 18:08:49 +0200 Subject: [PATCH 4/4] fix: typo --- packages/medusa-plugin-contentful/src/services/contentful.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/medusa-plugin-contentful/src/services/contentful.js b/packages/medusa-plugin-contentful/src/services/contentful.js index 020ca609d9..a1498f2695 100644 --- a/packages/medusa-plugin-contentful/src/services/contentful.js +++ b/packages/medusa-plugin-contentful/src/services/contentful.js @@ -380,7 +380,8 @@ class ContentfulService extends BaseService { }) const environment = await this.getContentfulEnvironment_() - // check if product exists + + // check if region exists let regionEntry = undefined try { regionEntry = await environment.getEntry(data.id)