feat(medusa): Emit events on product category mutations (#3003)
* chore: added events on product category mutation * chore: remove duplicates + refactor test
This commit is contained in:
5
.changeset/selfish-bulldogs-knock.md
Normal file
5
.changeset/selfish-bulldogs-knock.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@medusajs/medusa": patch
|
||||
---
|
||||
|
||||
feat(medusa): emit events on product category mutation
|
||||
@@ -1,5 +1,13 @@
|
||||
import { IdMap, MockRepository, MockManager } from "medusa-test-utils"
|
||||
import ProductCategoryService from "../product-category"
|
||||
import { EventBusService } from "../"
|
||||
|
||||
const eventBusService = {
|
||||
emit: jest.fn(),
|
||||
withTransaction: function () {
|
||||
return this
|
||||
},
|
||||
} as unknown as EventBusService
|
||||
|
||||
describe("ProductCategoryService", () => {
|
||||
const validProdCategoryId = "skinny-jeans"
|
||||
@@ -22,6 +30,7 @@ describe("ProductCategoryService", () => {
|
||||
const productCategoryService = new ProductCategoryService({
|
||||
manager: MockManager,
|
||||
productCategoryRepository,
|
||||
eventBusService,
|
||||
})
|
||||
|
||||
beforeEach(async () => { jest.clearAllMocks() })
|
||||
@@ -65,6 +74,7 @@ describe("ProductCategoryService", () => {
|
||||
const productCategoryService = new ProductCategoryService({
|
||||
manager: MockManager,
|
||||
productCategoryRepository,
|
||||
eventBusService,
|
||||
})
|
||||
|
||||
beforeEach(async () => { jest.clearAllMocks() })
|
||||
@@ -99,12 +109,15 @@ describe("ProductCategoryService", () => {
|
||||
|
||||
describe("create", () => {
|
||||
const productCategoryRepository = MockRepository({
|
||||
findOne: query => Promise.resolve({ id: IdMap.getId("jeans") }),
|
||||
findOne: (query) => Promise.resolve({ id: IdMap.getId(validProdCategoryId) }),
|
||||
create: () => Promise.resolve({ id: IdMap.getId(validProdCategoryId) }),
|
||||
save: (record) => Promise.resolve(record),
|
||||
})
|
||||
|
||||
const productCategoryService = new ProductCategoryService({
|
||||
manager: MockManager,
|
||||
productCategoryRepository,
|
||||
eventBusService,
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
@@ -112,13 +125,24 @@ describe("ProductCategoryService", () => {
|
||||
})
|
||||
|
||||
it("successfully creates a product category", async () => {
|
||||
await productCategoryService.create({ name: "jeans" })
|
||||
await productCategoryService.create({ name: validProdCategoryId })
|
||||
|
||||
expect(productCategoryRepository.create).toHaveBeenCalledTimes(1)
|
||||
expect(productCategoryRepository.create).toHaveBeenCalledWith({
|
||||
name: "jeans",
|
||||
name: validProdCategoryId,
|
||||
})
|
||||
})
|
||||
|
||||
it("emits a message on successful create", async () => {
|
||||
await productCategoryService.create({ name: validProdCategoryId })
|
||||
|
||||
expect(eventBusService.emit).toHaveBeenCalledTimes(1)
|
||||
expect(eventBusService.emit).toHaveBeenCalledWith(
|
||||
"product-category.created", {
|
||||
"id": IdMap.getId(validProdCategoryId)
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("delete", () => {
|
||||
@@ -138,7 +162,7 @@ describe("ProductCategoryService", () => {
|
||||
}
|
||||
|
||||
return Promise.resolve({
|
||||
id: IdMap.getId("jeans"),
|
||||
id: IdMap.getId(validProdCategoryId),
|
||||
category_children: []
|
||||
})
|
||||
},
|
||||
@@ -150,17 +174,18 @@ describe("ProductCategoryService", () => {
|
||||
const productCategoryService = new ProductCategoryService({
|
||||
manager: MockManager,
|
||||
productCategoryRepository,
|
||||
eventBusService,
|
||||
})
|
||||
|
||||
beforeEach(async () => { jest.clearAllMocks() })
|
||||
|
||||
it("successfully deletes a product category", async () => {
|
||||
const result = await productCategoryService.delete(
|
||||
IdMap.getId("jeans")
|
||||
IdMap.getId(validProdCategoryId)
|
||||
)
|
||||
|
||||
expect(productCategoryRepository.delete).toBeCalledTimes(1)
|
||||
expect(productCategoryRepository.delete).toBeCalledWith(IdMap.getId("jeans"))
|
||||
expect(productCategoryRepository.delete).toBeCalledWith(IdMap.getId(validProdCategoryId))
|
||||
})
|
||||
|
||||
it("returns without failure on not-found product category id", async () => {
|
||||
@@ -179,6 +204,19 @@ describe("ProductCategoryService", () => {
|
||||
`Deleting ProductCategory (with-children) with category children is not allowed`
|
||||
)
|
||||
})
|
||||
|
||||
it("emits a message on successful delete", async () => {
|
||||
const result = await productCategoryService.delete(
|
||||
IdMap.getId(validProdCategoryId)
|
||||
)
|
||||
|
||||
expect(eventBusService.emit).toHaveBeenCalledTimes(1)
|
||||
expect(eventBusService.emit).toHaveBeenCalledWith(
|
||||
"product-category.deleted", {
|
||||
"id": IdMap.getId(validProdCategoryId)
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("update", () => {
|
||||
@@ -198,6 +236,7 @@ describe("ProductCategoryService", () => {
|
||||
const productCategoryService = new ProductCategoryService({
|
||||
manager: MockManager,
|
||||
productCategoryRepository,
|
||||
eventBusService,
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
@@ -205,9 +244,11 @@ describe("ProductCategoryService", () => {
|
||||
})
|
||||
|
||||
it("successfully updates a product category", async () => {
|
||||
await productCategoryService.update(IdMap.getId(validProdCategoryId), {
|
||||
name: "bathrobes",
|
||||
})
|
||||
await productCategoryService.update(
|
||||
IdMap.getId(validProdCategoryId), {
|
||||
name: "bathrobes",
|
||||
}
|
||||
)
|
||||
|
||||
expect(productCategoryRepository.save).toHaveBeenCalledTimes(1)
|
||||
expect(productCategoryRepository.save).toHaveBeenCalledWith({
|
||||
@@ -217,13 +258,30 @@ describe("ProductCategoryService", () => {
|
||||
})
|
||||
|
||||
it("fails on not-found Id product category", async () => {
|
||||
const error = await productCategoryService.update(IdMap.getId(invalidProdCategoryId), {
|
||||
name: "bathrobes",
|
||||
}).catch(e => e)
|
||||
const error = await productCategoryService.update(
|
||||
IdMap.getId(invalidProdCategoryId), {
|
||||
name: "bathrobes",
|
||||
}
|
||||
).catch(e => e)
|
||||
|
||||
expect(error.message).toBe(
|
||||
`ProductCategory with id: ${IdMap.getId(invalidProdCategoryId)} was not found`
|
||||
)
|
||||
})
|
||||
|
||||
it("emits a message on successful update", async () => {
|
||||
const result = await productCategoryService.update(
|
||||
IdMap.getId(validProdCategoryId), {
|
||||
name: "bathrobes",
|
||||
}
|
||||
)
|
||||
|
||||
expect(eventBusService.emit).toHaveBeenCalledTimes(1)
|
||||
expect(eventBusService.emit).toHaveBeenCalledWith(
|
||||
"product-category.updated", {
|
||||
"id": IdMap.getId(validProdCategoryId)
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -5,6 +5,7 @@ import { ProductCategory } from "../models"
|
||||
import { ProductCategoryRepository } from "../repositories/product-category"
|
||||
import { FindConfig, Selector, QuerySelector } from "../types/common"
|
||||
import { buildQuery } from "../utils"
|
||||
import { EventBusService } from "."
|
||||
import {
|
||||
CreateProductCategoryInput,
|
||||
UpdateProductCategoryInput,
|
||||
@@ -12,6 +13,7 @@ import {
|
||||
|
||||
type InjectedDependencies = {
|
||||
manager: EntityManager
|
||||
eventBusService: EventBusService
|
||||
productCategoryRepository: typeof ProductCategoryRepository
|
||||
}
|
||||
|
||||
@@ -19,15 +21,27 @@ type InjectedDependencies = {
|
||||
* Provides layer to manipulate product categories.
|
||||
*/
|
||||
class ProductCategoryService extends TransactionBaseService {
|
||||
protected manager_: EntityManager
|
||||
protected readonly productCategoryRepo_: typeof ProductCategoryRepository
|
||||
protected readonly eventBusService_: EventBusService
|
||||
protected transactionManager_: EntityManager | undefined
|
||||
protected manager_: EntityManager
|
||||
|
||||
constructor({ manager, productCategoryRepository }: InjectedDependencies) {
|
||||
static Events = {
|
||||
CREATED: "product-category.created",
|
||||
UPDATED: "product-category.updated",
|
||||
DELETED: "product-category.deleted",
|
||||
}
|
||||
|
||||
constructor({
|
||||
manager,
|
||||
productCategoryRepository,
|
||||
eventBusService,
|
||||
}: InjectedDependencies) {
|
||||
// eslint-disable-next-line prefer-rest-params
|
||||
super(arguments[0])
|
||||
this.manager_ = manager
|
||||
|
||||
this.manager_ = manager
|
||||
this.eventBusService_ = eventBusService
|
||||
this.productCategoryRepo_ = productCategoryRepository
|
||||
}
|
||||
|
||||
@@ -109,13 +123,20 @@ class ProductCategoryService extends TransactionBaseService {
|
||||
* @return created product category
|
||||
*/
|
||||
async create(
|
||||
productCategory: CreateProductCategoryInput
|
||||
productCategoryInput: CreateProductCategoryInput
|
||||
): Promise<ProductCategory> {
|
||||
return await this.atomicPhase_(async (manager) => {
|
||||
const pcRepo = manager.getCustomRepository(this.productCategoryRepo_)
|
||||
const productCategoryRecord = pcRepo.create(productCategory)
|
||||
let productCategory = pcRepo.create(productCategoryInput)
|
||||
productCategory = await pcRepo.save(productCategory)
|
||||
|
||||
return await pcRepo.save(productCategoryRecord)
|
||||
await this.eventBusService_
|
||||
.withTransaction(manager)
|
||||
.emit(ProductCategoryService.Events.CREATED, {
|
||||
id: productCategory.id
|
||||
})
|
||||
|
||||
return productCategory
|
||||
})
|
||||
}
|
||||
|
||||
@@ -134,7 +155,7 @@ class ProductCategoryService extends TransactionBaseService {
|
||||
this.productCategoryRepo_
|
||||
)
|
||||
|
||||
const productCategory = await this.retrieve(productCategoryId)
|
||||
let productCategory = await this.retrieve(productCategoryId)
|
||||
|
||||
for (const key in productCategoryInput) {
|
||||
if (isDefined(productCategoryInput[key])) {
|
||||
@@ -142,7 +163,15 @@ class ProductCategoryService extends TransactionBaseService {
|
||||
}
|
||||
}
|
||||
|
||||
return await productCategoryRepo.save(productCategory)
|
||||
productCategory = await productCategoryRepo.save(productCategory)
|
||||
|
||||
await this.eventBusService_
|
||||
.withTransaction(manager)
|
||||
.emit(ProductCategoryService.Events.UPDATED, {
|
||||
id: productCategory.id,
|
||||
})
|
||||
|
||||
return productCategory
|
||||
})
|
||||
}
|
||||
|
||||
@@ -173,6 +202,12 @@ class ProductCategoryService extends TransactionBaseService {
|
||||
}
|
||||
|
||||
await productCategoryRepository.delete(productCategory.id)
|
||||
|
||||
await this.eventBusService_
|
||||
.withTransaction(manager)
|
||||
.emit(ProductCategoryService.Events.DELETED, {
|
||||
id: productCategory.id
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user