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
parent 2e12f13565
commit fe4b8feb7e
3 changed files with 92 additions and 11 deletions

View File

@@ -1,5 +1,6 @@
import { IdMap, MockRepository, MockManager } from "medusa-test-utils"
import ProductCollectionService from "../product-collection"
import { EventBusServiceMock } from "../__mocks__/event-bus"
describe("ProductCollectionService", () => {
describe("retrieve", () => {
@@ -15,6 +16,7 @@ describe("ProductCollectionService", () => {
const productCollectionService = new ProductCollectionService({
manager: MockManager,
productCollectionRepository,
eventBusService: EventBusServiceMock,
})
beforeEach(async () => {
@@ -48,11 +50,13 @@ describe("ProductCollectionService", () => {
describe("create", () => {
const productCollectionRepository = MockRepository({
findOne: query => Promise.resolve({ id: IdMap.getId("bathrobe") }),
create: query => Promise.resolve({ id: IdMap.getId("bathrobe") }),
})
const productCollectionService = new ProductCollectionService({
manager: MockManager,
productCollectionRepository,
eventBusService: EventBusServiceMock,
})
beforeEach(async () => {
@@ -60,12 +64,19 @@ describe("ProductCollectionService", () => {
})
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).toHaveBeenCalledWith({
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({
manager: MockManager,
productCollectionRepository,
eventBusService: EventBusServiceMock,
})
beforeEach(async () => {
@@ -98,6 +110,13 @@ describe("ProductCollectionService", () => {
id: IdMap.getId("bathrobe"),
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 () => {
@@ -126,6 +145,7 @@ describe("ProductCollectionService", () => {
const productCollectionService = new ProductCollectionService({
manager: MockManager,
productCollectionRepository,
eventBusService: EventBusServiceMock,
})
beforeEach(async () => {
@@ -139,6 +159,13 @@ describe("ProductCollectionService", () => {
expect(productCollectionRepository.softRemove).toHaveBeenCalledWith({
id: IdMap.getId("bathrobe"),
})
expect(EventBusServiceMock.emit).toHaveBeenCalledTimes(1)
expect(EventBusServiceMock.emit).toHaveBeenCalledWith(
ProductCollectionService.Events.DELETED, {
id: IdMap.getId("bathrobe"),
}
)
})
it("succeeds idempotently", async () => {

View File

@@ -38,6 +38,14 @@ class ProductCollectionService extends TransactionBaseService {
protected readonly productCollectionRepository_: typeof ProductCollectionRepository
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({
productCollectionRepository,
productRepository,
@@ -124,9 +132,16 @@ class ProductCollectionService extends TransactionBaseService {
const collectionRepo = manager.withRepository(
this.productCollectionRepository_
)
let productCollection = collectionRepo.create(collection)
productCollection = await collectionRepo.save(productCollection);
const productCollection = collectionRepo.create(collection)
return await collectionRepo.save(productCollection)
await this.eventBus_
.withTransaction(manager)
.emit(ProductCollectionService.Events.CREATED, {
id: productCollection.id,
})
return productCollection
})
}
@@ -145,19 +160,27 @@ class ProductCollectionService extends TransactionBaseService {
this.productCollectionRepository_
)
const collection = await this.retrieve(collectionId)
let productCollection = await this.retrieve(collectionId)
const { metadata, ...rest } = update
if (metadata) {
collection.metadata = setMetadata(collection, metadata)
productCollection.metadata = setMetadata(productCollection, metadata)
}
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_
)
const collection = await this.retrieve(collectionId)
const productCollection = await this.retrieve(collectionId)
if (!collection) {
if (!productCollection) {
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()
})
@@ -195,9 +224,18 @@ class ProductCollectionService extends TransactionBaseService {
await productRepo.bulkAddToCollection(productIds, id)
return await this.retrieve(id, {
const productCollection = await this.retrieve(id, {
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)
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()
})
}