fix(admin-vite-plugin): Normalize file paths and add tests (#9595)

**What**
- #9338 had a regression which caused the import path in some virtual modules to be invalid on Windows.
- This PR fixes the issue so we now again create the correct import paths, and adds tests to prevent this from slipping in again.
This commit is contained in:
Kasper Fabricius Kristensen
2024-10-15 16:48:56 +00:00
committed by GitHub
parent 84fa6ccde5
commit 813efeae51
15 changed files with 1069 additions and 14 deletions
@@ -0,0 +1,113 @@
import { describe, expect, it, vi } from "vitest"
import fs from "fs/promises"
import * as utils from "../../utils"
import { generateMenuItems } from "../generate-menu-items"
vi.mock("../../utils", async () => {
const actual = await vi.importActual("../../utils")
return {
...actual,
crawl: vi.fn(),
}
})
vi.mock("fs/promises", () => ({
default: {
readFile: vi.fn(),
},
}))
const mockFileContents = [
`
import { defineRouteConfig } from "@medusajs/admin-sdk"
const Page = () => {
return <div>Page 1</div>
}
export const config = defineRouteConfig({
label: "Page 1",
icon: "icon1",
})
export default Page
`,
`
import { defineRouteConfig } from "@medusajs/admin-sdk"
const Page = () => {
return <div>Page 2</div>
}
export const config = defineRouteConfig({
label: "Page 2",
})
export default Page
`,
]
const expectedMenuItems = `
menuItems: [
{
label: RouteConfig0.label,
icon: RouteConfig0.icon,
path: "/one",
},
{
label: RouteConfig1.label,
icon: undefined,
path: "/two",
}
]
`
describe("generateMenuItems", () => {
it("should generate menu items", async () => {
const mockFiles = [
"Users/user/medusa/src/admin/routes/one/page.tsx",
"Users/user/medusa/src/admin/routes/two/page.tsx",
]
vi.mocked(utils.crawl).mockResolvedValue(mockFiles)
vi.mocked(fs.readFile).mockImplementation(async (file) =>
Promise.resolve(mockFileContents[mockFiles.indexOf(file as string)])
)
const result = await generateMenuItems(
new Set(["Users/user/medusa/src/admin"])
)
expect(result.imports).toEqual([
`import { config as RouteConfig0 } from "Users/user/medusa/src/admin/routes/one/page.tsx"`,
`import { config as RouteConfig1 } from "Users/user/medusa/src/admin/routes/two/page.tsx"`,
])
expect(utils.normalizeString(result.code)).toEqual(
utils.normalizeString(expectedMenuItems)
)
})
it("should handle windows paths", async () => {
// Setup mocks
const mockFiles = [
"C:\\medusa\\src\\admin\\routes\\one\\page.tsx",
"C:\\medusa\\src\\admin\\routes\\two\\page.tsx",
]
vi.mocked(utils.crawl).mockResolvedValue(mockFiles)
vi.mocked(fs.readFile).mockImplementation(async (file) =>
Promise.resolve(mockFileContents[mockFiles.indexOf(file as string)])
)
const result = await generateMenuItems(new Set(["C:\\medusa\\src\\admin"]))
expect(result.imports).toEqual([
`import { config as RouteConfig0 } from "C:/medusa/src/admin/routes/one/page.tsx"`,
`import { config as RouteConfig1 } from "C:/medusa/src/admin/routes/two/page.tsx"`,
])
expect(utils.normalizeString(result.code)).toEqual(
utils.normalizeString(expectedMenuItems)
)
})
})
@@ -0,0 +1,144 @@
import { describe, expect, it, vi } from "vitest"
import { Stats } from "fs"
import fs from "fs/promises"
import * as utils from "../../utils"
import { generateRoutes } from "../generate-routes"
// Mock the dependencies
vi.mock("../../utils", async () => {
const actual = await vi.importActual("../../utils")
return {
...actual,
crawl: vi.fn(),
}
})
vi.mock("fs/promises", () => ({
default: {
readFile: vi.fn(),
stat: vi.fn(),
},
}))
const mockFileContents = [
`
import { defineRouteConfig } from "@medusajs/admin-sdk"
const Page = () => {
return <div>Page 1</div>
}
export const config = defineRouteConfig({
label: "Page 1",
icon: "icon1",
})
export default Page
`,
`
import { defineRouteConfig } from "@medusajs/admin-sdk"
const Page = () => {
return <div>Page 2</div>
}
export const config = defineRouteConfig({
label: "Page 2",
})
export default Page
`,
]
const expectedRoutesWithoutLoaders = `
routes: [
{
Component: RouteComponent0,
loader: undefined,
path: "/one",
},
{
Component: RouteComponent1,
loader: undefined,
path: "/two",
}
]
`
const expectedRoutesWithLoaders = `
routes: [
{
Component: RouteComponent0,
loader: RouteLoader0,
path: "/one",
},
{
Component: RouteComponent1,
loader: RouteLoader1,
path: "/two",
}
]
`
describe("generateRoutes", () => {
it("should generate routes", async () => {
const mockFiles = [
"Users/user/medusa/src/admin/routes/one/page.tsx",
"Users/user/medusa/src/admin/routes/two/page.tsx",
]
vi.mocked(utils.crawl).mockResolvedValue(mockFiles)
vi.mocked(fs.readFile).mockImplementation(async (file) =>
Promise.resolve(mockFileContents[mockFiles.indexOf(file as string)])
)
vi.mocked(fs.stat).mockRejectedValue(new Error("File not found"))
const result = await generateRoutes(
new Set(["Users/user/medusa/src/admin"])
)
expect(utils.normalizeString(result.code)).toEqual(
utils.normalizeString(expectedRoutesWithoutLoaders)
)
})
it("should generate routes with loaders", async () => {
const mockFiles = [
"Users/user/medusa/src/admin/routes/one/page.tsx",
"Users/user/medusa/src/admin/routes/two/page.tsx",
]
vi.mocked(utils.crawl).mockResolvedValue(mockFiles)
vi.mocked(fs.readFile).mockImplementation(async (file) =>
Promise.resolve(mockFileContents[mockFiles.indexOf(file as string)])
)
vi.mocked(fs.stat).mockResolvedValue({} as Stats) // We just want to mock that the check passes
const result = await generateRoutes(
new Set(["Users/user/medusa/src/admin"])
)
expect(utils.normalizeString(result.code)).toEqual(
utils.normalizeString(expectedRoutesWithLoaders)
)
})
it("should handle windows paths", async () => {
const mockFiles = [
"C:\\medusa\\src\\admin\\routes\\one\\page.tsx",
"C:\\medusa\\src\\admin\\routes\\two\\page.tsx",
]
vi.mocked(utils.crawl).mockResolvedValue(mockFiles)
vi.mocked(fs.readFile).mockImplementation(async (file) =>
Promise.resolve(mockFileContents[mockFiles.indexOf(file as string)])
)
vi.mocked(fs.stat).mockRejectedValue(new Error("File not found"))
const result = await generateRoutes(new Set(["C:\\medusa\\src\\admin"]))
expect(utils.normalizeString(result.code)).toEqual(
utils.normalizeString(expectedRoutesWithoutLoaders)
)
})
})