feat(medusa): Add event emitter to ProductCollectionService (#3495)

* added event emit on ProductCollectionService CRUD, updated unit test

* productCollectionService code style fix

* Create .changeset/gold-fireants-look.md

---------

Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
Davor Bačić
2023-03-16 19:01:26 +01:00
committed by GitHub
co-authored by Oliver Windall Juhl
parent 2e12f13565
commit fe4b8feb7e
3 changed files with 92 additions and 11 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@medusajs/medusa": patch
---
feat(medusa): Add event emitter to ProductCollectionService
@@ -1,5 +1,6 @@
import { IdMap, MockRepository, MockManager } from "medusa-test-utils" import { IdMap, MockRepository, MockManager } from "medusa-test-utils"
import ProductCollectionService from "../product-collection" import ProductCollectionService from "../product-collection"
import { EventBusServiceMock } from "../__mocks__/event-bus"
describe("ProductCollectionService", () => { describe("ProductCollectionService", () => {
describe("retrieve", () => { describe("retrieve", () => {
@@ -15,6 +16,7 @@ describe("ProductCollectionService", () => {
const productCollectionService = new ProductCollectionService({ const productCollectionService = new ProductCollectionService({
manager: MockManager, manager: MockManager,
productCollectionRepository, productCollectionRepository,
eventBusService: EventBusServiceMock,
}) })
beforeEach(async () => { beforeEach(async () => {
@@ -48,11 +50,13 @@ describe("ProductCollectionService", () => {
describe("create", () => { describe("create", () => {
const productCollectionRepository = MockRepository({ const productCollectionRepository = MockRepository({
findOne: query => Promise.resolve({ id: IdMap.getId("bathrobe") }), findOne: query => Promise.resolve({ id: IdMap.getId("bathrobe") }),
create: query => Promise.resolve({ id: IdMap.getId("bathrobe") }),
}) })
const productCollectionService = new ProductCollectionService({ const productCollectionService = new ProductCollectionService({
manager: MockManager, manager: MockManager,
productCollectionRepository, productCollectionRepository,
eventBusService: EventBusServiceMock,
}) })
beforeEach(async () => { beforeEach(async () => {
@@ -60,12 +64,19 @@ describe("ProductCollectionService", () => {
}) })
it("successfully creates a product collection", async () => { it("successfully creates a product collection", async () => {
await productCollectionService.create({ title: "bathrobe" }) const entity = await productCollectionService.create({ title: "bathrobe" })
expect(productCollectionRepository.create).toHaveBeenCalledTimes(1) expect(productCollectionRepository.create).toHaveBeenCalledTimes(1)
expect(productCollectionRepository.create).toHaveBeenCalledWith({ expect(productCollectionRepository.create).toHaveBeenCalledWith({
title: "bathrobe", title: "bathrobe",
}) })
expect(EventBusServiceMock.emit).toHaveBeenCalledTimes(1)
expect(EventBusServiceMock.emit).toHaveBeenCalledWith(
ProductCollectionService.Events.CREATED, {
id: entity.id,
}
)
}) })
}) })
@@ -82,6 +93,7 @@ describe("ProductCollectionService", () => {
const productCollectionService = new ProductCollectionService({ const productCollectionService = new ProductCollectionService({
manager: MockManager, manager: MockManager,
productCollectionRepository, productCollectionRepository,
eventBusService: EventBusServiceMock,
}) })
beforeEach(async () => { beforeEach(async () => {
@@ -98,6 +110,13 @@ describe("ProductCollectionService", () => {
id: IdMap.getId("bathrobe"), id: IdMap.getId("bathrobe"),
title: "bathrobes", title: "bathrobes",
}) })
expect(EventBusServiceMock.emit).toHaveBeenCalledTimes(1)
expect(EventBusServiceMock.emit).toHaveBeenCalledWith(
ProductCollectionService.Events.UPDATED, {
id: IdMap.getId("bathrobe"),
}
)
}) })
it("fails on non-existing product collection", async () => { it("fails on non-existing product collection", async () => {
@@ -126,6 +145,7 @@ describe("ProductCollectionService", () => {
const productCollectionService = new ProductCollectionService({ const productCollectionService = new ProductCollectionService({
manager: MockManager, manager: MockManager,
productCollectionRepository, productCollectionRepository,
eventBusService: EventBusServiceMock,
}) })
beforeEach(async () => { beforeEach(async () => {
@@ -139,6 +159,13 @@ describe("ProductCollectionService", () => {
expect(productCollectionRepository.softRemove).toHaveBeenCalledWith({ expect(productCollectionRepository.softRemove).toHaveBeenCalledWith({
id: IdMap.getId("bathrobe"), id: IdMap.getId("bathrobe"),
}) })
expect(EventBusServiceMock.emit).toHaveBeenCalledTimes(1)
expect(EventBusServiceMock.emit).toHaveBeenCalledWith(
ProductCollectionService.Events.DELETED, {
id: IdMap.getId("bathrobe"),
}
)
}) })
it("succeeds idempotently", async () => { it("succeeds idempotently", async () => {
@@ -38,6 +38,14 @@ class ProductCollectionService extends TransactionBaseService {
protected readonly productCollectionRepository_: typeof ProductCollectionRepository protected readonly productCollectionRepository_: typeof ProductCollectionRepository
protected readonly productRepository_: typeof ProductRepository protected readonly productRepository_: typeof ProductRepository
static readonly Events = {
CREATED: "product-collection.created",
UPDATED: "product-collection.updated",
DELETED: "product-collection.deleted",
PRODUCTS_ADDED: "product-collection.products_added",
PRODUCTS_REMOVED: "product-collection.products_removed",
}
constructor({ constructor({
productCollectionRepository, productCollectionRepository,
productRepository, productRepository,
@@ -124,9 +132,16 @@ class ProductCollectionService extends TransactionBaseService {
const collectionRepo = manager.withRepository( const collectionRepo = manager.withRepository(
this.productCollectionRepository_ this.productCollectionRepository_
) )
let productCollection = collectionRepo.create(collection)
productCollection = await collectionRepo.save(productCollection);
const productCollection = collectionRepo.create(collection) await this.eventBus_
return await collectionRepo.save(productCollection) .withTransaction(manager)
.emit(ProductCollectionService.Events.CREATED, {
id: productCollection.id,
})
return productCollection
}) })
} }
@@ -145,19 +160,27 @@ class ProductCollectionService extends TransactionBaseService {
this.productCollectionRepository_ this.productCollectionRepository_
) )
const collection = await this.retrieve(collectionId) let productCollection = await this.retrieve(collectionId)
const { metadata, ...rest } = update const { metadata, ...rest } = update
if (metadata) { if (metadata) {
collection.metadata = setMetadata(collection, metadata) productCollection.metadata = setMetadata(productCollection, metadata)
} }
for (const [key, value] of Object.entries(rest)) { for (const [key, value] of Object.entries(rest)) {
collection[key] = value productCollection[key] = value
} }
return collectionRepo.save(collection) productCollection = await collectionRepo.save(productCollection)
await this.eventBus_
.withTransaction(manager)
.emit(ProductCollectionService.Events.UPDATED, {
id: productCollection.id,
})
return productCollection
}) })
} }
@@ -172,13 +195,19 @@ class ProductCollectionService extends TransactionBaseService {
this.productCollectionRepository_ this.productCollectionRepository_
) )
const collection = await this.retrieve(collectionId) const productCollection = await this.retrieve(collectionId)
if (!collection) { if (!productCollection) {
return Promise.resolve() return Promise.resolve()
} }
await productCollectionRepo.softRemove(collection) await productCollectionRepo.softRemove(productCollection)
await this.eventBus_
.withTransaction(manager)
.emit(ProductCollectionService.Events.DELETED, {
id: productCollection.id,
})
return Promise.resolve() return Promise.resolve()
}) })
@@ -195,9 +224,18 @@ class ProductCollectionService extends TransactionBaseService {
await productRepo.bulkAddToCollection(productIds, id) await productRepo.bulkAddToCollection(productIds, id)
return await this.retrieve(id, { const productCollection = await this.retrieve(id, {
relations: ["products"], relations: ["products"],
}) })
await this.eventBus_
.withTransaction(manager)
.emit(ProductCollectionService.Events.PRODUCTS_ADDED, {
productCollection: productCollection,
productIds: productIds,
})
return productCollection
}) })
} }
@@ -212,6 +250,17 @@ class ProductCollectionService extends TransactionBaseService {
await productRepo.bulkRemoveFromCollection(productIds, id) await productRepo.bulkRemoveFromCollection(productIds, id)
const productCollection = await this.retrieve(id, {
relations: ["products"],
})
await this.eventBus_
.withTransaction(manager)
.emit(ProductCollectionService.Events.PRODUCTS_REMOVED, {
productCollection: productCollection,
productIds: productIds,
})
return Promise.resolve() return Promise.resolve()
}) })
} }