diff --git a/assets/js/live_vue/utils.test.ts b/assets/js/live_vue/utils.test.ts
new file mode 100644
index 0000000..4989c73
--- /dev/null
+++ b/assets/js/live_vue/utils.test.ts
@@ -0,0 +1,88 @@
+import { describe, it, expect } from "vitest"
+import { findComponent } from "./utils"
+import type { ComponentMap } from "./types"
+
+describe("findComponent", () => {
+ const MockComponent = {
+ template: "
Mock Component
",
+ }
+
+ const MockCreateWorkspaceComponent = {
+ template: "Create Workspace Component
",
+ }
+
+ it("should find exact component match for 'workspace'", () => {
+ const components: ComponentMap = {
+ "../../lib/live_vue/web/pages/workspace.vue": MockComponent,
+ "../../lib/live_vue/web/pages/create-workspace.vue": MockCreateWorkspaceComponent,
+ }
+
+ const result = findComponent(components, "workspace")
+
+ expect(result).toBe(MockComponent)
+ })
+
+ it("should NOT match 'workspace' to 'create-workspace'", () => {
+ const components: ComponentMap = {
+ "../../lib/live_vue/web/pages/create-workspace.vue": MockCreateWorkspaceComponent,
+ "../../lib/live_vue/web/pages/workspace.vue": MockComponent,
+ }
+
+ const result = findComponent(components, "workspace")
+
+ expect(result).toBe(MockComponent)
+ })
+
+ it("should find 'create-workspace' component when requested", () => {
+ const components: ComponentMap = {
+ "../../lib/live_vue/web/pages/workspace.vue": MockComponent,
+ "../../lib/live_vue/web/pages/create-workspace.vue": MockCreateWorkspaceComponent,
+ }
+
+ const result = findComponent(components, "create-workspace")
+
+ expect(result).toBe(MockCreateWorkspaceComponent)
+ })
+
+ it("should throw error when component is not found", () => {
+ const components: ComponentMap = {
+ "../../lib/leuchtturm/web/pages/workspace.vue": MockComponent,
+ }
+
+ expect(() => findComponent(components, "nonexistent")).toThrow("Component 'nonexistent' not found!")
+ })
+
+ it("should handle index.vue files", () => {
+ const components: ComponentMap = {
+ "../../lib/live_vue/web/pages/workspace/index.vue": MockComponent,
+ }
+
+ const result = findComponent(components, "workspace")
+
+ expect(result).toBe(MockComponent)
+ })
+
+ it("should handle index.vue files with multiple nested paths", () => {
+ const components: ComponentMap = {
+ "../../lib/live_vue/web/pages/admin/workspace/index.vue": MockComponent,
+ "../../lib/live_vue/web/pages/public/dashboard/index.vue": MockCreateWorkspaceComponent,
+ }
+
+ const result1 = findComponent(components, "workspace")
+ const result2 = findComponent(components, "dashboard")
+
+ expect(result1).toBe(MockComponent)
+ expect(result2).toBe(MockCreateWorkspaceComponent)
+ })
+
+ it("should avoid false matches due to substring matching", () => {
+ const components: ComponentMap = {
+ "../../lib/live_vue/web/pages/create-workspace.vue": MockCreateWorkspaceComponent,
+ "../../lib/live_vue/web/pages/workspace.vue": MockComponent,
+ }
+
+ const result = findComponent(components, "workspace")
+
+ expect(result).toBe(MockComponent)
+ })
+})
diff --git a/assets/js/live_vue/utils.ts b/assets/js/live_vue/utils.ts
index 84e830a..a1c3bdf 100644
--- a/assets/js/live_vue/utils.ts
+++ b/assets/js/live_vue/utils.ts
@@ -33,9 +33,10 @@ export const flatMapKeys = (
* @returns The component if found, otherwise throws an error with a list of available components.
*/
export const findComponent = (components: ComponentMap, name: string): ComponentOrComponentPromise => {
- // we're looking for a component by name or path suffix.
+ // we're looking for a component by exact filename match
for (const [key, value] of Object.entries(components)) {
- if (key.endsWith(`${name}.vue`) || key.endsWith(`${name}/index.vue`)) {
+ const fileName = key.split('/').pop() // Get the actual filename
+ if (fileName === `${name}.vue` || (fileName === 'index.vue' && key.endsWith(`/${name}/index.vue`))) {
return value
}
}