Skip to content

Commit 9163756

Browse files
philipjfulcherPhilip Fulcher
andauthored
fix(graph): handle special characters in url parameters (nrwl#13836)
Co-authored-by: Philip Fulcher <philipfulcher@Philips-MacBook-Air.local>
1 parent 4f9b9d4 commit 9163756

10 files changed

Lines changed: 128 additions & 8 deletions

File tree

graph/client-e2e/src/e2e/dev-project-graph.cy.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,11 @@ describe('dev mode - project graph', () => {
269269
['cart', ...dependencies, ...dependents].length
270270
);
271271
});
272+
273+
it('should url encode projects with special chars', () => {
274+
getFocusButtonForProject('@scoped/project-a').click({ force: true });
275+
cy.url().should('include', '%40scoped%2Fproject-a');
276+
});
272277
});
273278

274279
describe('unfocus button', () => {

graph/client-e2e/src/fixtures/nx-examples-project-graph.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,26 @@
11
{
22
"hash": "081624f3bbc67c126e9dc313133c5a0138ae383da39f8793b26609698aea957b",
33
"projects": [
4+
{
5+
"name": "@scoped/project-a",
6+
"type": "lib",
7+
"data": {
8+
"tags": [],
9+
"root": "libs/project-a",
10+
"files": [],
11+
"targets": {}
12+
}
13+
},
14+
{
15+
"name": "@scoped/project-b",
16+
"type": "lib",
17+
"data": {
18+
"tags": [],
19+
"root": "libs/project-a",
20+
"files": [],
21+
"targets": {}
22+
}
23+
},
424
{
525
"name": "products-product-detail-page",
626
"type": "lib",
@@ -1629,6 +1649,13 @@
16291649
}
16301650
],
16311651
"dependencies": {
1652+
"@scoped/project-a": [
1653+
{
1654+
"source": "@scoped/project-a",
1655+
"target": "@scoped/project-b"
1656+
}
1657+
],
1658+
"@scoped/project-b": [],
16321659
"products-product-detail-page": [
16331660
{
16341661
"source": "products-product-detail-page",

graph/client-e2e/src/support/routing-tests.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,27 @@ export function testProjectsRoutes(
6868
);
6969
});
7070

71+
it('should focus projects with special characters', () => {
72+
cy.visit(
73+
resolveProjectsRoute(router, `${route}/%40scoped%2Fproject-a`, '')
74+
);
75+
76+
// wait for first graph to finish loading
77+
waitForProjectGraph(router);
78+
79+
const dependencies = nxExamplesJson.dependencies['@scoped/project-a'];
80+
const dependents = Object.keys(nxExamplesJson.dependencies).filter(
81+
(key) =>
82+
nxExamplesJson.dependencies[key]
83+
.map((dependencies) => dependencies.target)
84+
.includes('@scoped/project-a')
85+
);
86+
getCheckedProjectItems().should(
87+
'have.length',
88+
['@scoped/project-a', ...dependencies, ...dependents].length
89+
);
90+
});
91+
7192
it('should focus projects with search depth', () => {
7293
cy.visit(
7394
resolveProjectsRoute(router, `${route}/cart`, `searchDepth=2`)

graph/client/src/app/external-api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export class ExternalApi {
2525
}
2626

2727
focusProject(projectName: string) {
28-
this.router.navigate(`/projects/${projectName}`);
28+
this.router.navigate(`/projects/${encodeURIComponent(projectName)}`);
2929
}
3030

3131
selectAllProjects() {

graph/client/src/app/feature-projects/project-list.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ function ProjectListItem({
103103
className="mr-1 flex items-center rounded-md border-slate-300 bg-white p-1 font-medium text-slate-500 shadow-sm ring-1 ring-slate-200 transition hover:bg-slate-50 dark:border-slate-600 dark:bg-slate-800 dark:text-slate-400 dark:ring-slate-600 hover:dark:bg-slate-700"
104104
title="Focus on this library"
105105
to={routeConstructor(
106-
`/projects/${project.projectGraphNode.name}`,
106+
`/projects/${encodeURIComponent(project.projectGraphNode.name)}`,
107107
true
108108
)}
109109
>

graph/client/src/app/feature-tasks/tasks-sidebar.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,15 @@ export function TasksSidebar() {
5858
hideAllProjects();
5959

6060
if (params['selectedTarget']) {
61-
navigate({ pathname: `../${target}`, search: searchParams.toString() });
61+
navigate({
62+
pathname: `../${encodeURIComponent(target)}`,
63+
search: searchParams.toString(),
64+
});
6265
} else {
63-
navigate({ pathname: `${target}`, search: searchParams.toString() });
66+
navigate({
67+
pathname: `${encodeURIComponent(target)}`,
68+
search: searchParams.toString(),
69+
});
6470
}
6571
}
6672

graph/client/src/app/shell.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export function Shell(): JSX.Element {
5353
];
5454

5555
function projectChange(projectGraphId: string) {
56-
navigate(`/${projectGraphId}${topLevelRoute}`);
56+
navigate(`/${encodeURIComponent(projectGraphId)}${topLevelRoute}`);
5757
}
5858

5959
function downloadImage() {
@@ -107,7 +107,9 @@ export function Shell(): JSX.Element {
107107
projectGraphService.send('deselectAll');
108108
if (environment.environment === 'dev') {
109109
navigate(
110-
`/${currentPath.workspace}${event.currentTarget.value}`
110+
`/${encodeURIComponent(currentPath.workspace)}${
111+
event.currentTarget.value
112+
}`
111113
);
112114
} else {
113115
navigate(`${event.currentTarget.value}`);

graph/client/src/app/ui-tooltips/project-node-tooltip.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,20 @@ export function ProjectNodeToolTip({
3131
}
3232

3333
function onStartTrace() {
34-
navigate(routeConstructor(`/projects/trace/${id}`, true));
34+
navigate(
35+
routeConstructor(`/projects/trace/${encodeURIComponent(id)}`, true)
36+
);
3537
}
3638

3739
function onEndTrace() {
38-
navigate(routeConstructor(`/projects/trace/${start}/${id}`, true));
40+
navigate(
41+
routeConstructor(
42+
`/projects/trace/${encodeURIComponent(start)}/${encodeURIComponent(
43+
id
44+
)}`,
45+
true
46+
)
47+
);
3948
}
4049

4150
return (

graph/client/src/assets/project-graphs/e2e.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,24 @@
11
{
22
"hash": "081624f3bbc67c126e9dc313133c5a0138ae383da39f8793b26609698aea957b",
33
"projects": [
4+
{
5+
"name": "@scoped/project-a",
6+
"type": "lib",
7+
"data": {
8+
"tags": [],
9+
"root": "libs/project-a",
10+
"files": []
11+
}
12+
},
13+
{
14+
"name": "@scoped/project-b",
15+
"type": "lib",
16+
"data": {
17+
"tags": [],
18+
"root": "libs/project-a",
19+
"files": []
20+
}
21+
},
422
{
523
"name": "products-product-detail-page",
624
"type": "lib",
@@ -1629,6 +1647,13 @@
16291647
}
16301648
],
16311649
"dependencies": {
1650+
"@scoped/project-a": [
1651+
{
1652+
"source": "@scoped/project-a",
1653+
"target": "@scoped/project-b"
1654+
}
1655+
],
1656+
"@scoped/project-b": [],
16321657
"products-product-detail-page": [
16331658
{
16341659
"source": "products-product-detail-page",

graph/client/src/assets/release-static/environment.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,24 @@ window.appConfig = {
2121
window.projectGraphResponse = {
2222
hash: '081624f3bbc67c126e9dc313133c5a0138ae383da39f8793b26609698aea957b',
2323
projects: [
24+
{
25+
name: '@scoped/project-a',
26+
type: 'lib',
27+
data: {
28+
tags: [],
29+
root: 'libs/project-a',
30+
files: [],
31+
},
32+
},
33+
{
34+
name: '@scoped/project-b',
35+
type: 'lib',
36+
data: {
37+
tags: [],
38+
root: 'libs/project-a',
39+
files: [],
40+
},
41+
},
2442
{
2543
name: 'products-product-detail-page',
2644
type: 'lib',
@@ -1651,6 +1669,13 @@ window.projectGraphResponse = {
16511669
},
16521670
],
16531671
dependencies: {
1672+
'@scoped/project-a': [
1673+
{
1674+
source: '@scoped/project-a',
1675+
target: '@scoped/project-b',
1676+
},
1677+
],
1678+
'@scoped/project-b': [],
16541679
'products-product-detail-page': [
16551680
{
16561681
source: 'products-product-detail-page',

0 commit comments

Comments
 (0)