mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] router: better support for hash mode
This commit is contained in:
@@ -164,7 +164,8 @@ export class Router {
|
|||||||
parts[i] = <string>params[key];
|
parts[i] = <string>params[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return parts.join("/");
|
const prefix = this.mode === "hash" ? "#" : "";
|
||||||
|
return prefix + parts.join("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
private currentPath(): string {
|
private currentPath(): string {
|
||||||
@@ -223,6 +224,9 @@ export class Router {
|
|||||||
if (route.path === "*") {
|
if (route.path === "*") {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
if (path.startsWith("#")) {
|
||||||
|
path = path.slice(1);
|
||||||
|
}
|
||||||
const descrParts = route.path.split("/");
|
const descrParts = route.path.split("/");
|
||||||
const targetParts = path.split("/");
|
const targetParts = path.split("/");
|
||||||
const l = descrParts.length;
|
const l = descrParts.length;
|
||||||
|
|||||||
+70
-19
@@ -1,4 +1,4 @@
|
|||||||
import { Destination, Router, RouterEnv, Route } from "../../src/router/Router";
|
import { Destination, RouterEnv, Route } from "../../src/router/Router";
|
||||||
import { makeTestEnv } from "../helpers";
|
import { makeTestEnv } from "../helpers";
|
||||||
import { TestRouter } from "./TestRouter";
|
import { TestRouter } from "./TestRouter";
|
||||||
|
|
||||||
@@ -28,15 +28,28 @@ describe("router miscellaneous", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("routeToPath", () => {
|
describe("routeToPath", () => {
|
||||||
const routeToPath = Router.prototype["routeToPath"];
|
|
||||||
test("simple non parameterized path", () => {
|
test("simple non parameterized path", () => {
|
||||||
expect(routeToPath({path: "/abc"} as Route, {})).toBe("/abc");
|
router = new TestRouter(env, []);
|
||||||
expect(routeToPath({path: "/abc/def"} as Route, {})).toBe("/abc/def");
|
expect(router["routeToPath"]({ path: "/abc" } as Route, {})).toBe("/abc");
|
||||||
expect(routeToPath({path: "/abc"} as Route, { val: 12 })).toBe("/abc");
|
expect(router["routeToPath"]({ path: "/abc/def" } as Route, {})).toBe("/abc/def");
|
||||||
|
expect(router["routeToPath"]({ path: "/abc" } as Route, { val: 12 })).toBe("/abc");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("simple parameterized path", () => {
|
test("simple parameterized path", () => {
|
||||||
expect(routeToPath({path: "/abc/{{def}}"} as Route, { def: 34 })).toBe("/abc/34");
|
router = new TestRouter(env, []);
|
||||||
|
expect(router["routeToPath"]({ path: "/abc/{{def}}" } as Route, { def: 34 })).toBe("/abc/34");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("simple non parameterized path, mode = hash", () => {
|
||||||
|
router = new TestRouter(env, [], { mode: "hash" });
|
||||||
|
expect(router["routeToPath"]({ path: "/abc" } as Route, {})).toBe("#/abc");
|
||||||
|
expect(router["routeToPath"]({ path: "/abc/def" } as Route, {})).toBe("#/abc/def");
|
||||||
|
expect(router["routeToPath"]({ path: "/abc" } as Route, { val: 12 })).toBe("#/abc");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("simple parameterized path, mode=hash", () => {
|
||||||
|
router = new TestRouter(env, [], { mode: "hash" });
|
||||||
|
expect(router["routeToPath"]({ path: "/abc/{{def}}" } as Route, { def: 34 })).toBe("#/abc/34");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -58,26 +71,60 @@ describe("destToPath", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("getRouteParams", () => {
|
describe("getRouteParams", () => {
|
||||||
const getRouteParams = Router.prototype["getRouteParams"];
|
|
||||||
test("properly match simple routes", () => {
|
test("properly match simple routes", () => {
|
||||||
|
router = new TestRouter(env, []);
|
||||||
// simple route
|
// simple route
|
||||||
expect(getRouteParams({path: "/home"} as Route, "/home")).toEqual({});
|
expect(router["getRouteParams"]({ path: "/home" } as Route, "/home")).toEqual({});
|
||||||
|
|
||||||
// no match
|
// no match
|
||||||
expect(getRouteParams({path: "/home"} as Route, "/otherpath")).toEqual(false);
|
expect(router["getRouteParams"]({ path: "/home" } as Route, "/otherpath")).toEqual(false);
|
||||||
|
|
||||||
// fallback route
|
// fallback route
|
||||||
expect(getRouteParams({path: "*"} as Route, "somepath")).toEqual({});
|
expect(router["getRouteParams"]({ path: "*" } as Route, "somepath")).toEqual({});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("properly match simple routes, mode hash", () => {
|
||||||
|
router = new TestRouter(env, [], { mode: "hash" });
|
||||||
|
// simple route
|
||||||
|
expect(router["getRouteParams"]({ path: "/home" } as Route, "#/home")).toEqual({});
|
||||||
|
|
||||||
|
// no match
|
||||||
|
expect(router["getRouteParams"]({ path: "/home" } as Route, "#/otherpath")).toEqual(false);
|
||||||
|
|
||||||
|
// fallback route
|
||||||
|
expect(router["getRouteParams"]({ path: "*" } as Route, "#/somepath")).toEqual({});
|
||||||
});
|
});
|
||||||
|
|
||||||
test("match some parameterized routes", () => {
|
test("match some parameterized routes", () => {
|
||||||
expect(getRouteParams({path: "/invoices/{{id}}"} as Route, "/invoices/3")).toEqual({
|
router = new TestRouter(env, []);
|
||||||
|
expect(router["getRouteParams"]({ path: "/invoices/{{id}}" } as Route, "/invoices/3")).toEqual({
|
||||||
id: "3"
|
id: "3"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("match some parameterized routes, mode hash", () => {
|
||||||
|
router = new TestRouter(env, [], { mode: "hash" });
|
||||||
|
expect(router["getRouteParams"]({ path: "/invoices/{{id}}" } as Route, "#/invoices/3")).toEqual(
|
||||||
|
{
|
||||||
|
id: "3"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
test("can convert to number if needed", () => {
|
test("can convert to number if needed", () => {
|
||||||
expect(getRouteParams({path: "/invoices/{{id.number}}"} as Route, "/invoices/3")).toEqual({
|
router = new TestRouter(env, []);
|
||||||
|
expect(
|
||||||
|
router["getRouteParams"]({ path: "/invoices/{{id.number}}" } as Route, "/invoices/3")
|
||||||
|
).toEqual({
|
||||||
|
id: 3
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("can convert to number if needed, mode: hash", () => {
|
||||||
|
router = new TestRouter(env, [], { mode: "hash" });
|
||||||
|
expect(
|
||||||
|
router["getRouteParams"]({ path: "/invoices/{{id.number}}" } as Route, "#/invoices/3")
|
||||||
|
).toEqual({
|
||||||
id: 3
|
id: 3
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -131,7 +178,7 @@ describe("beforeRouteEnter", () => {
|
|||||||
expect(window.location.pathname).toBe("/");
|
expect(window.location.pathname).toBe("/");
|
||||||
const guard = jest.fn(() => false);
|
const guard = jest.fn(() => false);
|
||||||
router = new TestRouter(env, [
|
router = new TestRouter(env, [
|
||||||
{ name: "routea", path: "/some/patha"},
|
{ name: "routea", path: "/some/patha" },
|
||||||
{ name: "routeb", path: "/some/pathb", beforeRouteEnter: guard }
|
{ name: "routeb", path: "/some/pathb", beforeRouteEnter: guard }
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -147,11 +194,13 @@ describe("beforeRouteEnter", () => {
|
|||||||
|
|
||||||
test("navigation is redirected if guard decides so", async () => {
|
test("navigation is redirected if guard decides so", async () => {
|
||||||
expect(window.location.pathname).toBe("/");
|
expect(window.location.pathname).toBe("/");
|
||||||
const guard = jest.fn(() => {return {to: "routec"}});
|
const guard = jest.fn(() => {
|
||||||
|
return { to: "routec" };
|
||||||
|
});
|
||||||
router = new TestRouter(env, [
|
router = new TestRouter(env, [
|
||||||
{ name: "routea", path: "/some/patha"},
|
{ name: "routea", path: "/some/patha" },
|
||||||
{ name: "routeb", path: "/some/pathb", beforeRouteEnter: guard },
|
{ name: "routeb", path: "/some/pathb", beforeRouteEnter: guard },
|
||||||
{ name: "routec", path: "/some/pathc"},
|
{ name: "routec", path: "/some/pathc" }
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await router.start();
|
await router.start();
|
||||||
@@ -166,10 +215,12 @@ describe("beforeRouteEnter", () => {
|
|||||||
|
|
||||||
test("navigation is initially redirected if guard decides so", async () => {
|
test("navigation is initially redirected if guard decides so", async () => {
|
||||||
expect(window.location.pathname).toBe("/");
|
expect(window.location.pathname).toBe("/");
|
||||||
const guard = jest.fn(() => {return {to: "otherroute"}});
|
const guard = jest.fn(() => {
|
||||||
|
return { to: "otherroute" };
|
||||||
|
});
|
||||||
router = new TestRouter(env, [
|
router = new TestRouter(env, [
|
||||||
{ name: "landing", path: "/", beforeRouteEnter: guard},
|
{ name: "landing", path: "/", beforeRouteEnter: guard },
|
||||||
{ name: "otherroute", path: "/some/other/route"}
|
{ name: "otherroute", path: "/some/other/route" }
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(window.location.pathname).toBe("/");
|
expect(window.location.pathname).toBe("/");
|
||||||
|
|||||||
Reference in New Issue
Block a user