Skip to content

Commit

Permalink
fix(utils): Fix inferrence of public method name and service registra…
Browse files Browse the repository at this point in the history
…tion name based on configuration (#8237)
  • Loading branch information
adrien2p authored Jul 23, 2024
1 parent 1b61c9b commit a9abf44
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 8 deletions.
108 changes: 107 additions & 1 deletion packages/core/utils/src/modules-sdk/__tests__/medusa-service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { MedusaService } from "../medusa-service"
import { model } from "../../dml"

const baseRepoMock = {
serialize: jest.fn().mockImplementation((item) => item),
Expand Down Expand Up @@ -52,7 +53,7 @@ describe("Abstract Module Service Factory", () => {
})

describe("Main Model Methods", () => {
let instance: medusaService
let instance: InstanceType<typeof medusaService>

beforeEach(() => {
jest.clearAllMocks()
Expand Down Expand Up @@ -172,4 +173,109 @@ describe("Abstract Module Service Factory", () => {
)
})
})

describe("Custom configuration using DML", () => {
const containerMock = {
baseRepository: baseRepoMock,
mainModelMockRepository: baseRepoMock,
otherModelMock1Repository: baseRepoMock,
otherModelMock2Repository: baseRepoMock,
houseService: {
retrieve: jest.fn().mockResolvedValue({ id: "1", name: "Item" }),
list: jest.fn().mockResolvedValue([{ id: "1", name: "Item" }]),
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" }]),
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" }]),
delete: jest.fn().mockResolvedValue(undefined),
softDelete: jest.fn().mockResolvedValue([[], {}]),
restore: jest.fn().mockResolvedValue([[], {}]),
},
}

const MockModel = model.define("user", {
id: model.id().primaryKey(),
})
const MockModel2 = model.define("car", {
id: model.id().primaryKey(),
})
const MockModel3 = model.define("house", {
id: model.id().primaryKey(),
})

const medusaService = MedusaService({
MockModel,
MockModel2,
MockModel3,
})

let instance: InstanceType<typeof medusaService>

beforeEach(() => {
jest.clearAllMocks()
instance = new medusaService(containerMock)
})

it("should have the correct methods name while resolving the correct underlying service representation of target models", async () => {
const prototype = Object.getPrototypeOf(instance)

expect(prototype).toHaveProperty("retrieveMockModel")
expect(prototype).toHaveProperty("listMockModels")
expect(prototype).toHaveProperty("listAndCountMockModels")
expect(prototype).toHaveProperty("createMockModels")
expect(prototype).toHaveProperty("updateMockModels")
expect(prototype).toHaveProperty("deleteMockModels")
expect(prototype).toHaveProperty("softDeleteMockModels")

expect(prototype).toHaveProperty("retrieveMockModel2")
expect(prototype).toHaveProperty("listMockModel2s")
expect(prototype).toHaveProperty("listAndCountMockModel2s")
expect(prototype).toHaveProperty("createMockModel2s")
expect(prototype).toHaveProperty("updateMockModel2s")
expect(prototype).toHaveProperty("deleteMockModel2s")
expect(prototype).toHaveProperty("softDeleteMockModel2s")

expect(prototype).toHaveProperty("retrieveMockModel3")
expect(prototype).toHaveProperty("listMockModel3s")
expect(prototype).toHaveProperty("listAndCountMockModel3s")
expect(prototype).toHaveProperty("createMockModel3s")
expect(prototype).toHaveProperty("updateMockModel3s")
expect(prototype).toHaveProperty("deleteMockModel3s")
expect(prototype).toHaveProperty("softDeleteMockModel3s")

let result = await instance.retrieveMockModel("1")
expect(result).toEqual({ id: "1", name: "Item" })
expect(containerMock.userService.retrieve).toHaveBeenCalledWith(
"1",
undefined,
defaultContext
)

result = await instance.retrieveMockModel2("1")
expect(result).toEqual({ id: "1", name: "Item" })
expect(containerMock.carService.retrieve).toHaveBeenCalledWith(
"1",
undefined,
defaultContext
)

result = await instance.retrieveMockModel3("1")
expect(result).toEqual({ id: "1", name: "Item" })
expect(containerMock.houseService.retrieve).toHaveBeenCalledWith(
"1",
undefined,
defaultContext
)
})
})
})
19 changes: 12 additions & 7 deletions packages/core/utils/src/modules-sdk/medusa-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
ModelsConfigTemplate,
} from "./types/medusa-service"
import { buildModelsNameToLinkableKeysMap } from "./joiner-config-builder"
import { DmlEntity } from "../dml"

const readMethods = ["retrieve", "list", "listAndCount"] as BaseMethods[]
const writeMethods = [
Expand All @@ -46,18 +47,22 @@ const methods: BaseMethods[] = [...readMethods, ...writeMethods]
* @internal
*/
function buildMethodNamesFromModel(
modelName: string,
defaultMethodName: string,
model: ModelEntries[keyof ModelEntries]
): Record<string, string> {
return methods.reduce((acc, method) => {
let normalizedModelName: string = ""

if (method === "retrieve") {
normalizedModelName =
"singular" in model && model.singular ? model.singular : modelName
"singular" in model && model.singular
? model.singular
: defaultMethodName
} else {
normalizedModelName =
"plural" in model && model.plural ? model.plural : pluralize(modelName)
"plural" in model && model.plural
? model.plural
: pluralize(defaultMethodName)
}

const methodName = `${method}${upperCaseFirst(normalizedModelName)}`
Expand Down Expand Up @@ -406,11 +411,11 @@ export function MedusaService<
*/

const modelsMethods: [
string,
TModels[keyof TModels],
Record<string, string>
string, // model name
TModels[keyof TModels], // configuration (dml, conf, entity)
Record<string, string> // method names
][] = Object.entries(models as {}).map(([name, config]) => [
name,
DmlEntity.isDmlEntity(config) ? config.name : name,
config as TModels[keyof TModels],
buildMethodNamesFromModel(name, config as TModels[keyof TModels]),
])
Expand Down

0 comments on commit a9abf44

Please sign in to comment.