Skip to content

Commit

Permalink
feat(medusa): Add event emitter to ProductCollectionService (#3495)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
  • Loading branch information
davorbacic and olivermrbl authored Mar 16, 2023
1 parent 2e12f13 commit fe4b8fe
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 11 deletions.
5 changes: 5 additions & 0 deletions .changeset/gold-fireants-look.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@medusajs/medusa": patch
---

feat(medusa): Add event emitter to ProductCollectionService
29 changes: 28 additions & 1 deletion packages/medusa/src/services/__tests__/product-collection.js
Original file line number Diff line number Diff line change
@@ -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", () => {
Expand All @@ -15,6 +16,7 @@ describe("ProductCollectionService", () => {
const productCollectionService = new ProductCollectionService({
manager: MockManager,
productCollectionRepository,
eventBusService: EventBusServiceMock,
})

beforeEach(async () => {
Expand Down Expand Up @@ -48,24 +50,33 @@ 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 () => {
jest.clearAllMocks()
})

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,
}
)
})
})

Expand All @@ -82,6 +93,7 @@ describe("ProductCollectionService", () => {
const productCollectionService = new ProductCollectionService({
manager: MockManager,
productCollectionRepository,
eventBusService: EventBusServiceMock,
})

beforeEach(async () => {
Expand All @@ -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 () => {
Expand Down Expand Up @@ -126,6 +145,7 @@ describe("ProductCollectionService", () => {
const productCollectionService = new ProductCollectionService({
manager: MockManager,
productCollectionRepository,
eventBusService: EventBusServiceMock,
})

beforeEach(async () => {
Expand All @@ -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 () => {
Expand Down
69 changes: 59 additions & 10 deletions packages/medusa/src/services/product-collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
})
}

Expand All @@ -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
})
}

Expand All @@ -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()
})
Expand All @@ -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
})
}

Expand All @@ -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()
})
}
Expand Down

0 comments on commit fe4b8fe

Please sign in to comment.