Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(graph): handle special characters in url parameters #13836

Merged
merged 1 commit into from Dec 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions graph/client-e2e/src/e2e/dev-project-graph.cy.ts
Expand Up @@ -269,6 +269,11 @@ describe('dev mode - project graph', () => {
['cart', ...dependencies, ...dependents].length
);
});

it('should url encode projects with special chars', () => {
getFocusButtonForProject('@scoped/project-a').click({ force: true });
cy.url().should('include', '%40scoped%2Fproject-a');
});
});

describe('unfocus button', () => {
Expand Down
27 changes: 27 additions & 0 deletions graph/client-e2e/src/fixtures/nx-examples-project-graph.json
@@ -1,6 +1,26 @@
{
"hash": "081624f3bbc67c126e9dc313133c5a0138ae383da39f8793b26609698aea957b",
"projects": [
{
"name": "@scoped/project-a",
"type": "lib",
"data": {
"tags": [],
"root": "libs/project-a",
"files": [],
"targets": {}
}
},
{
"name": "@scoped/project-b",
"type": "lib",
"data": {
"tags": [],
"root": "libs/project-a",
"files": [],
"targets": {}
}
},
{
"name": "products-product-detail-page",
"type": "lib",
Expand Down Expand Up @@ -1629,6 +1649,13 @@
}
],
"dependencies": {
"@scoped/project-a": [
{
"source": "@scoped/project-a",
"target": "@scoped/project-b"
}
],
"@scoped/project-b": [],
"products-product-detail-page": [
{
"source": "products-product-detail-page",
Expand Down
21 changes: 21 additions & 0 deletions graph/client-e2e/src/support/routing-tests.ts
Expand Up @@ -68,6 +68,27 @@ export function testProjectsRoutes(
);
});

it('should focus projects with special characters', () => {
cy.visit(
resolveProjectsRoute(router, `${route}/%40scoped%2Fproject-a`, '')
);

// wait for first graph to finish loading
waitForProjectGraph(router);

const dependencies = nxExamplesJson.dependencies['@scoped/project-a'];
const dependents = Object.keys(nxExamplesJson.dependencies).filter(
(key) =>
nxExamplesJson.dependencies[key]
.map((dependencies) => dependencies.target)
.includes('@scoped/project-a')
);
getCheckedProjectItems().should(
'have.length',
['@scoped/project-a', ...dependencies, ...dependents].length
);
});

it('should focus projects with search depth', () => {
cy.visit(
resolveProjectsRoute(router, `${route}/cart`, `searchDepth=2`)
Expand Down
2 changes: 1 addition & 1 deletion graph/client/src/app/external-api.ts
Expand Up @@ -25,7 +25,7 @@ export class ExternalApi {
}

focusProject(projectName: string) {
this.router.navigate(`/projects/${projectName}`);
this.router.navigate(`/projects/${encodeURIComponent(projectName)}`);
}

selectAllProjects() {
Expand Down
2 changes: 1 addition & 1 deletion graph/client/src/app/feature-projects/project-list.tsx
Expand Up @@ -103,7 +103,7 @@ function ProjectListItem({
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"
title="Focus on this library"
to={routeConstructor(
`/projects/${project.projectGraphNode.name}`,
`/projects/${encodeURIComponent(project.projectGraphNode.name)}`,
true
)}
>
Expand Down
10 changes: 8 additions & 2 deletions graph/client/src/app/feature-tasks/tasks-sidebar.tsx
Expand Up @@ -58,9 +58,15 @@ export function TasksSidebar() {
hideAllProjects();

if (params['selectedTarget']) {
navigate({ pathname: `../${target}`, search: searchParams.toString() });
navigate({
pathname: `../${encodeURIComponent(target)}`,
search: searchParams.toString(),
});
} else {
navigate({ pathname: `${target}`, search: searchParams.toString() });
navigate({
pathname: `${encodeURIComponent(target)}`,
search: searchParams.toString(),
});
}
}

Expand Down
6 changes: 4 additions & 2 deletions graph/client/src/app/shell.tsx
Expand Up @@ -53,7 +53,7 @@ export function Shell(): JSX.Element {
];

function projectChange(projectGraphId: string) {
navigate(`/${projectGraphId}${topLevelRoute}`);
navigate(`/${encodeURIComponent(projectGraphId)}${topLevelRoute}`);
}

function downloadImage() {
Expand Down Expand Up @@ -107,7 +107,9 @@ export function Shell(): JSX.Element {
projectGraphService.send('deselectAll');
if (environment.environment === 'dev') {
navigate(
`/${currentPath.workspace}${event.currentTarget.value}`
`/${encodeURIComponent(currentPath.workspace)}${
event.currentTarget.value
}`
);
} else {
navigate(`${event.currentTarget.value}`);
Expand Down
13 changes: 11 additions & 2 deletions graph/client/src/app/ui-tooltips/project-node-tooltip.tsx
Expand Up @@ -31,11 +31,20 @@ export function ProjectNodeToolTip({
}

function onStartTrace() {
navigate(routeConstructor(`/projects/trace/${id}`, true));
navigate(
routeConstructor(`/projects/trace/${encodeURIComponent(id)}`, true)
);
}

function onEndTrace() {
navigate(routeConstructor(`/projects/trace/${start}/${id}`, true));
navigate(
routeConstructor(
`/projects/trace/${encodeURIComponent(start)}/${encodeURIComponent(
id
)}`,
true
)
);
}

return (
Expand Down
25 changes: 25 additions & 0 deletions graph/client/src/assets/project-graphs/e2e.json
@@ -1,6 +1,24 @@
{
"hash": "081624f3bbc67c126e9dc313133c5a0138ae383da39f8793b26609698aea957b",
"projects": [
{
"name": "@scoped/project-a",
"type": "lib",
"data": {
"tags": [],
"root": "libs/project-a",
"files": []
}
},
{
"name": "@scoped/project-b",
"type": "lib",
"data": {
"tags": [],
"root": "libs/project-a",
"files": []
}
},
{
"name": "products-product-detail-page",
"type": "lib",
Expand Down Expand Up @@ -1629,6 +1647,13 @@
}
],
"dependencies": {
"@scoped/project-a": [
{
"source": "@scoped/project-a",
"target": "@scoped/project-b"
}
],
"@scoped/project-b": [],
"products-product-detail-page": [
{
"source": "products-product-detail-page",
Expand Down
25 changes: 25 additions & 0 deletions graph/client/src/assets/release-static/environment.js
Expand Up @@ -21,6 +21,24 @@ window.appConfig = {
window.projectGraphResponse = {
hash: '081624f3bbc67c126e9dc313133c5a0138ae383da39f8793b26609698aea957b',
projects: [
{
name: '@scoped/project-a',
type: 'lib',
data: {
tags: [],
root: 'libs/project-a',
files: [],
},
},
{
name: '@scoped/project-b',
type: 'lib',
data: {
tags: [],
root: 'libs/project-a',
files: [],
},
},
{
name: 'products-product-detail-page',
type: 'lib',
Expand Down Expand Up @@ -1651,6 +1669,13 @@ window.projectGraphResponse = {
},
],
dependencies: {
'@scoped/project-a': [
{
source: '@scoped/project-a',
target: '@scoped/project-b',
},
],
'@scoped/project-b': [],
'products-product-detail-page': [
{
source: 'products-product-detail-page',
Expand Down