Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 180 additions & 0 deletions packages/core/utils/src/modules-sdk/__tests__/medusa-service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,40 @@ describe("Abstract Module Service Factory", () => {
mainModelMockService: {
retrieve: jest.fn().mockResolvedValue({ id: "1", name: "Item" }),
list: jest.fn().mockResolvedValue([{ id: "1", name: "Item" }]),
create: jest.fn().mockImplementation((data) => {
// Return single object if single object passed, array if array passed
return Array.isArray(data) ? data.map(item => ({ ...item, id: "1" })) : { ...data, id: "1" }
}),
update: jest.fn().mockImplementation((data) => {
// Return single object if single object passed, array if array passed
return Array.isArray(data) ? data.map(item => ({ ...item, updated: true })) : { ...data, updated: true }
}),
delete: jest.fn().mockResolvedValue([]),
softDelete: jest.fn().mockResolvedValue([[], {}]),
restore: jest.fn().mockResolvedValue([[], {}]),
},
otherModelMock1Service: {
retrieve: jest.fn().mockResolvedValue({ id: "1", name: "Item" }),
list: jest.fn().mockResolvedValue([{ id: "1", name: "Item" }]),
create: jest.fn().mockImplementation((data) => {
return Array.isArray(data) ? data.map(item => ({ ...item, id: "1" })) : { ...data, id: "1" }
}),
update: jest.fn().mockImplementation((data) => {
return Array.isArray(data) ? data.map(item => ({ ...item, updated: true })) : { ...data, updated: true }
}),
delete: jest.fn().mockResolvedValue([]),
softDelete: jest.fn().mockResolvedValue([[], {}]),
restore: jest.fn().mockResolvedValue([[], {}]),
},
otherModelMock2Service: {
retrieve: jest.fn().mockResolvedValue({ id: "1", name: "Item" }),
list: jest.fn().mockResolvedValue([{ id: "1", name: "Item" }]),
create: jest.fn().mockImplementation((data) => {
return Array.isArray(data) ? data.map(item => ({ ...item, id: "1" })) : { ...data, id: "1" }
}),
update: jest.fn().mockImplementation((data) => {
return Array.isArray(data) ? data.map(item => ({ ...item, updated: true })) : { ...data, updated: true }
}),
delete: jest.fn().mockResolvedValue([]),
softDelete: jest.fn().mockResolvedValue([[], {}]),
restore: jest.fn().mockResolvedValue([[], {}]),
Expand Down Expand Up @@ -122,6 +142,77 @@ describe("Abstract Module Service Factory", () => {
defaultTransactionContext
)
})

it("should have create method that handles single object input", async () => {
const inputData = { name: "Test Item" }
const result = await instance.createMainModelMocks(inputData)

// Should return single object when single object is passed
expect(result).toEqual({ name: "Test Item", id: "1" })
expect(Array.isArray(result)).toBe(false)

// Should call underlying service with single object (not wrapped in array)
expect(containerMock.mainModelMockService.create).toHaveBeenCalledWith(
inputData,
defaultTransactionContext
)
})

it("should have create method that handles array input", async () => {
const inputData = [{ name: "Test Item 1" }, { name: "Test Item 2" }]
const result = await instance.createMainModelMocks(inputData)

// Should return array when array is passed
expect(result).toEqual([
{ name: "Test Item 1", id: "1" },
{ name: "Test Item 2", id: "1" }
])
expect(Array.isArray(result)).toBe(true)
expect(result).toHaveLength(2)

// Should call underlying service with array
expect(containerMock.mainModelMockService.create).toHaveBeenCalledWith(
inputData,
defaultTransactionContext
)
})

it("should have update method that handles single object input", async () => {
const inputData = { id: "1", name: "Updated Item" }
const result = await instance.updateMainModelMocks(inputData)

// Should return single object when single object is passed
expect(result).toEqual({ id: "1", name: "Updated Item", updated: true })
expect(Array.isArray(result)).toBe(false)

// Should call underlying service with single object (not wrapped in array)
expect(containerMock.mainModelMockService.update).toHaveBeenCalledWith(
inputData,
defaultTransactionContext
)
})

it("should have update method that handles array input", async () => {
const inputData = [
{ id: "1", name: "Updated Item 1" },
{ id: "2", name: "Updated Item 2" }
]
const result = await instance.updateMainModelMocks(inputData)

// Should return array when array is passed
expect(result).toEqual([
{ id: "1", name: "Updated Item 1", updated: true },
{ id: "2", name: "Updated Item 2", updated: true }
])
expect(Array.isArray(result)).toBe(true)
expect(result).toHaveLength(2)

// Should call underlying service with array
expect(containerMock.mainModelMockService.update).toHaveBeenCalledWith(
inputData,
defaultTransactionContext
)
})
})

describe("Other Models Methods", () => {
Expand Down Expand Up @@ -185,6 +276,77 @@ describe("Abstract Module Service Factory", () => {
defaultTransactionContext
)
})

it("should have create method for other models that handles single object input", async () => {
const inputData = { name: "Test Other Item" }
const result = await instance.createOtherModelMock1s(inputData)

// Should return single object when single object is passed
expect(result).toEqual({ name: "Test Other Item", id: "1" })
expect(Array.isArray(result)).toBe(false)

// Should call underlying service with single object (not wrapped in array)
expect(containerMock.otherModelMock1Service.create).toHaveBeenCalledWith(
inputData,
defaultTransactionContext
)
})

it("should have create method for other models that handles array input", async () => {
const inputData = [{ name: "Test Other Item 1" }, { name: "Test Other Item 2" }]
const result = await instance.createOtherModelMock1s(inputData)

// Should return array when array is passed
expect(result).toEqual([
{ name: "Test Other Item 1", id: "1" },
{ name: "Test Other Item 2", id: "1" }
])
expect(Array.isArray(result)).toBe(true)
expect(result).toHaveLength(2)

// Should call underlying service with array
expect(containerMock.otherModelMock1Service.create).toHaveBeenCalledWith(
inputData,
defaultTransactionContext
)
})

it("should have update method for other models that handles single object input", async () => {
const inputData = { id: "1", name: "Updated Other Item" }
const result = await instance.updateOtherModelMock1s(inputData)

// Should return single object when single object is passed
expect(result).toEqual({ id: "1", name: "Updated Other Item", updated: true })
expect(Array.isArray(result)).toBe(false)

// Should call underlying service with single object (not wrapped in array)
expect(containerMock.otherModelMock1Service.update).toHaveBeenCalledWith(
inputData,
defaultTransactionContext
)
})

it("should have update method for other models that handles array input", async () => {
const inputData = [
{ id: "1", name: "Updated Other Item 1" },
{ id: "2", name: "Updated Other Item 2" }
]
const result = await instance.updateOtherModelMock1s(inputData)

// Should return array when array is passed
expect(result).toEqual([
{ id: "1", name: "Updated Other Item 1", updated: true },
{ id: "2", name: "Updated Other Item 2", updated: true }
])
expect(Array.isArray(result)).toBe(true)
expect(result).toHaveLength(2)

// Should call underlying service with array
expect(containerMock.otherModelMock1Service.update).toHaveBeenCalledWith(
inputData,
defaultTransactionContext
)
})
})

describe("Custom configuration using DML", () => {
Expand All @@ -196,20 +358,38 @@ describe("Abstract Module Service Factory", () => {
houseService: {
retrieve: jest.fn().mockResolvedValue({ id: "1", name: "Item" }),
list: jest.fn().mockResolvedValue([{ id: "1", name: "Item" }]),
create: jest.fn().mockImplementation((data) => {
return Array.isArray(data) ? data.map(item => ({ ...item, id: "1" })) : { ...data, id: "1" }
}),
update: jest.fn().mockImplementation((data) => {
return Array.isArray(data) ? data.map(item => ({ ...item, updated: true })) : { ...data, updated: true }
}),
delete: jest.fn().mockResolvedValue(undefined),
softDelete: jest.fn().mockResolvedValue([[], {}]),
restore: jest.fn().mockResolvedValue([[], {}]),
},
carService: {
retrieve: jest.fn().mockResolvedValue({ id: "1", name: "Item" }),
list: jest.fn().mockResolvedValue([{ id: "1", name: "Item" }]),
create: jest.fn().mockImplementation((data) => {
return Array.isArray(data) ? data.map(item => ({ ...item, id: "1" })) : { ...data, id: "1" }
}),
update: jest.fn().mockImplementation((data) => {
return Array.isArray(data) ? data.map(item => ({ ...item, updated: true })) : { ...data, updated: true }
}),
delete: jest.fn().mockResolvedValue(undefined),
softDelete: jest.fn().mockResolvedValue([[], {}]),
restore: jest.fn().mockResolvedValue([[], {}]),
},
userService: {
retrieve: jest.fn().mockResolvedValue({ id: "1", name: "Item" }),
list: jest.fn().mockResolvedValue([{ id: "1", name: "Item" }]),
create: jest.fn().mockImplementation((data) => {
return Array.isArray(data) ? data.map(item => ({ ...item, id: "1" })) : { ...data, id: "1" }
}),
update: jest.fn().mockImplementation((data) => {
return Array.isArray(data) ? data.map(item => ({ ...item, updated: true })) : { ...data, updated: true }
}),
delete: jest.fn().mockResolvedValue(undefined),
softDelete: jest.fn().mockResolvedValue([[], {}]),
restore: jest.fn().mockResolvedValue([[], {}]),
Expand Down
2 changes: 1 addition & 1 deletion packages/core/utils/src/modules-sdk/medusa-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ export function MedusaService<
data = [],
sharedContext: Context = {}
): Promise<T | T[]> {
const serviceData = Array.isArray(data) ? data : [data]
const serviceData = data
const service = this.__container__[serviceRegistrationName]
const response = await service.update(serviceData, sharedContext)

Expand Down