317 lines
9.1 KiB
TypeScript
317 lines
9.1 KiB
TypeScript
import {
|
|
createContainer,
|
|
asValue,
|
|
Resolver,
|
|
ClassOrFunctionReturning,
|
|
asFunction,
|
|
AwilixContainer,
|
|
} from "awilix"
|
|
import { mkdirSync, rmSync, writeFileSync } from "fs"
|
|
import { resolve } from "path"
|
|
import Logger from "../logger"
|
|
import { registerServices, registerStrategies } from "../plugins"
|
|
import { MedusaContainer } from "../../types/global"
|
|
|
|
// ***** TEMPLATES *****
|
|
const buildServiceTemplate = (name: string): string => {
|
|
return `
|
|
import { BaseService } from "medusa-interfaces"
|
|
export default class ${name}Service extends BaseService {}
|
|
`
|
|
}
|
|
const buildTransactionBaseServiceServiceTemplate = (name: string) => {
|
|
return `
|
|
import { TransactionBaseService } from "${resolve(
|
|
__dirname,
|
|
"../../interfaces"
|
|
)}"
|
|
export default class ${name}Service extends TransactionBaseService {}
|
|
`
|
|
}
|
|
|
|
const buildBatchJobStrategyTemplate = (name: string, type: string): string => {
|
|
return `
|
|
import { AbstractBatchJobStrategy } from "../../../../interfaces/batch-job-strategy"
|
|
|
|
class ${name}BatchStrategy extends AbstractBatchJobStrategy{
|
|
static identifier = '${name}-identifier';
|
|
static batchType = '${type}';
|
|
|
|
manager_
|
|
transactionManager_
|
|
|
|
validateContext(context) {
|
|
throw new Error("Method not implemented.")
|
|
}
|
|
processJob(batchJobId) {
|
|
throw new Error("Method not implemented.")
|
|
}
|
|
completeJob(batchJobId) {
|
|
throw new Error("Method not implemented.")
|
|
}
|
|
validateFile(fileLocation) {
|
|
throw new Error("Method not implemented.")
|
|
}
|
|
async buildTemplate() {
|
|
throw new Error("Method not implemented.")
|
|
}
|
|
}
|
|
|
|
export default ${name}BatchStrategy
|
|
`
|
|
}
|
|
|
|
const buildPriceSelectionStrategyTemplate = (name: string): string => {
|
|
return `
|
|
import { AbstractPriceSelectionStrategy } from "../../../../interfaces/price-selection-strategy"
|
|
|
|
class ${name}PriceSelectionStrategy extends AbstractPriceSelectionStrategy {
|
|
withTransaction() {
|
|
throw new Error("Method not implemented.");
|
|
}
|
|
calculateVariantPrice(variant_id, context) {
|
|
throw new Error("Method not implemented.");
|
|
}
|
|
}
|
|
|
|
export default ${name}PriceSelectionStrategy
|
|
`
|
|
}
|
|
|
|
const buildTaxCalcStrategyTemplate = (name: string): string => {
|
|
return `
|
|
class ${name}TaxCalculationStrategy {
|
|
calculate(items, taxLines, calculationContext) {
|
|
throw new Error("Method not implemented.")
|
|
}
|
|
}
|
|
|
|
export default ${name}TaxCalculationStrategy
|
|
`
|
|
}
|
|
|
|
// ***** UTILS *****
|
|
|
|
const distTestTargetDirectorPath = resolve(__dirname, "__pluginsLoaderTest__")
|
|
|
|
const getFolderTestTargetDirectoryPath = (folderName: string): string => {
|
|
return resolve(distTestTargetDirectorPath, folderName)
|
|
}
|
|
|
|
function asArray(
|
|
resolvers: (ClassOrFunctionReturning<unknown> | Resolver<unknown>)[]
|
|
): { resolve: (container: AwilixContainer) => unknown[] } {
|
|
return {
|
|
resolve: (container: AwilixContainer): unknown[] =>
|
|
resolvers.map((resolver) => container.build(resolver)),
|
|
}
|
|
}
|
|
|
|
// ***** TESTS *****
|
|
|
|
describe("plugins loader", () => {
|
|
const container = createContainer() as MedusaContainer
|
|
container.registerAdd = function (
|
|
this: MedusaContainer,
|
|
name: string,
|
|
registration: typeof asFunction | typeof asValue
|
|
): MedusaContainer {
|
|
const storeKey = name + "_STORE"
|
|
|
|
if (this.registrations[storeKey] === undefined) {
|
|
this.register(storeKey, asValue([] as Resolver<unknown>[]))
|
|
}
|
|
const store = this.resolve(storeKey) as (
|
|
| ClassOrFunctionReturning<unknown>
|
|
| Resolver<unknown>
|
|
)[]
|
|
|
|
if (this.registrations[name] === undefined) {
|
|
this.register(name, asArray(store))
|
|
}
|
|
store.unshift(registration)
|
|
|
|
return this
|
|
}.bind(container)
|
|
|
|
container.register("logger", asValue(Logger))
|
|
const pluginsDetails = {
|
|
resolve: resolve(__dirname, "__pluginsLoaderTest__"),
|
|
name: `project-plugin`,
|
|
id: "fakeId",
|
|
options: {},
|
|
version: '"fakeVersion',
|
|
}
|
|
let err
|
|
|
|
afterAll(() => {
|
|
rmSync(distTestTargetDirectorPath, { recursive: true, force: true })
|
|
jest.clearAllMocks()
|
|
})
|
|
|
|
describe("registerStrategies", function () {
|
|
beforeAll(async () => {
|
|
mkdirSync(getFolderTestTargetDirectoryPath("strategies"), {
|
|
mode: "777",
|
|
recursive: true,
|
|
})
|
|
writeFileSync(
|
|
resolve(
|
|
getFolderTestTargetDirectoryPath("strategies"),
|
|
"test-batch-1.js"
|
|
),
|
|
buildBatchJobStrategyTemplate("testBatch1", "type-1")
|
|
)
|
|
writeFileSync(
|
|
resolve(
|
|
getFolderTestTargetDirectoryPath("strategies"),
|
|
"test-price-selection.js"
|
|
),
|
|
buildPriceSelectionStrategyTemplate("test")
|
|
)
|
|
writeFileSync(
|
|
resolve(
|
|
getFolderTestTargetDirectoryPath("strategies"),
|
|
"test-batch-2.js"
|
|
),
|
|
buildBatchJobStrategyTemplate("testBatch2", "type-1")
|
|
)
|
|
writeFileSync(
|
|
resolve(
|
|
getFolderTestTargetDirectoryPath("strategies"),
|
|
"test-batch-3.js"
|
|
),
|
|
buildBatchJobStrategyTemplate("testBatch3", "type-2")
|
|
)
|
|
writeFileSync(
|
|
resolve(getFolderTestTargetDirectoryPath("strategies"), "test-tax.js"),
|
|
buildTaxCalcStrategyTemplate("test")
|
|
)
|
|
|
|
try {
|
|
await registerStrategies(pluginsDetails, container)
|
|
} catch (e) {
|
|
err = e
|
|
}
|
|
})
|
|
|
|
afterAll(() => {
|
|
jest.clearAllMocks()
|
|
})
|
|
|
|
it("err should be falsy", () => {
|
|
expect(err).toBeFalsy()
|
|
})
|
|
|
|
it("registers price selection strategy", () => {
|
|
const priceSelectionStrategy =
|
|
container.resolve("priceSelectionStrategy") as (...args: unknown[]) => any
|
|
|
|
expect(priceSelectionStrategy).toBeTruthy()
|
|
expect(priceSelectionStrategy.constructor.name).toBe(
|
|
"testPriceSelectionStrategy"
|
|
)
|
|
})
|
|
|
|
it("registers tax calculation strategy", () => {
|
|
const taxCalculationStrategy =
|
|
container.resolve("taxCalculationStrategy") as (...args: unknown[]) => any
|
|
|
|
expect(taxCalculationStrategy).toBeTruthy()
|
|
expect(taxCalculationStrategy.constructor.name).toBe(
|
|
"testTaxCalculationStrategy"
|
|
)
|
|
})
|
|
|
|
it("registers batch job strategies as single array", () => {
|
|
const batchJobStrategies =
|
|
container.resolve("batchJobStrategies") as (...args: unknown[]) => any
|
|
|
|
expect(batchJobStrategies).toBeTruthy()
|
|
expect(Array.isArray(batchJobStrategies)).toBeTruthy()
|
|
expect(batchJobStrategies.length).toBe(3)
|
|
})
|
|
|
|
it("registers batch job strategies by type and only keep the last", () => {
|
|
const batchJobStrategy =
|
|
container.resolve("batchType_type-1") as (...args: unknown[]) => any
|
|
|
|
expect(batchJobStrategy).toBeTruthy()
|
|
expect(batchJobStrategy.constructor.name).toBe("testBatch2BatchStrategy")
|
|
expect((batchJobStrategy.constructor as any).batchType).toBe("type-1")
|
|
expect((batchJobStrategy.constructor as any).identifier).toBe(
|
|
"testBatch2-identifier"
|
|
)
|
|
})
|
|
|
|
it("registers batch job strategies by identifier", () => {
|
|
const batchJobStrategy = container.resolve(
|
|
"batch_testBatch3-identifier"
|
|
) as (...args: unknown[]) => any
|
|
|
|
expect(batchJobStrategy).toBeTruthy()
|
|
expect(Array.isArray(batchJobStrategy)).toBeFalsy()
|
|
expect(batchJobStrategy.constructor.name).toBe("testBatch3BatchStrategy")
|
|
})
|
|
})
|
|
|
|
describe("registerServices", function () {
|
|
beforeAll(() => {
|
|
container.register("logger", asValue(Logger))
|
|
mkdirSync(getFolderTestTargetDirectoryPath("services"), {
|
|
mode: "777",
|
|
recursive: true,
|
|
})
|
|
writeFileSync(
|
|
resolve(getFolderTestTargetDirectoryPath("services"), "test.js"),
|
|
buildServiceTemplate("test")
|
|
)
|
|
writeFileSync(
|
|
resolve(getFolderTestTargetDirectoryPath("services"), "test2.js"),
|
|
buildServiceTemplate("test2")
|
|
)
|
|
writeFileSync(
|
|
resolve(getFolderTestTargetDirectoryPath("services"), "test3.js"),
|
|
buildTransactionBaseServiceServiceTemplate("test3")
|
|
)
|
|
writeFileSync(
|
|
resolve(getFolderTestTargetDirectoryPath("services"), "test2.js.map"),
|
|
"map:file"
|
|
)
|
|
writeFileSync(
|
|
resolve(getFolderTestTargetDirectoryPath("services"), "test2.d.ts"),
|
|
"export interface Test {}"
|
|
)
|
|
})
|
|
|
|
afterAll(() => {
|
|
jest.clearAllMocks()
|
|
})
|
|
|
|
it("should load the services from the services directory but only js files", async () => {
|
|
let err
|
|
try {
|
|
await registerServices(pluginsDetails, container)
|
|
} catch (e) {
|
|
err = e
|
|
}
|
|
|
|
expect(err).toBeFalsy()
|
|
|
|
const testService: (...args: unknown[]) => any =
|
|
container.resolve("testService")
|
|
const test2Service: (...args: unknown[]) => any =
|
|
container.resolve("test2Service")
|
|
const test3Service: (...args: unknown[]) => any =
|
|
container.resolve("test3Service")
|
|
|
|
expect(testService).toBeTruthy()
|
|
expect(testService.constructor.name).toBe("testService")
|
|
expect(test2Service).toBeTruthy()
|
|
expect(test2Service.constructor.name).toBe("test2Service")
|
|
expect(test3Service).toBeTruthy()
|
|
expect(test3Service.constructor.name).toBe("test3Service")
|
|
})
|
|
})
|
|
})
|