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

404 support for non existing paths #162

Merged
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
875676f
Detect the moment when popup should appear
parostatkiem-zz Oct 24, 2018
477e8f2
Implement not-exact-path alert
parostatkiem-zz Oct 24, 2018
e4bd18e
Handle 404 when route is absolutely not found
parostatkiem-zz Oct 24, 2018
f395863
Add min-width to alert
parostatkiem-zz Oct 24, 2018
64414ee
Rewrite the mechanizm
parostatkiem-zz Oct 24, 2018
b80b7d8
Merge branch 'master' of https://github.com/kyma-project/luigi into 4…
parostatkiem-zz Oct 25, 2018
b75a50c
Change CustomEvents to postMessage
parostatkiem-zz Oct 25, 2018
d694329
Separate tests into directories
parostatkiem-zz Oct 25, 2018
1385ab4
Test the containsAllSegments function
parostatkiem-zz Oct 25, 2018
8389703
Remove obsolete console.warn()
parostatkiem-zz Oct 25, 2018
db71aa4
Rename error, rename variable in alert event, add some 'anti-undefine…
parostatkiem-zz Oct 26, 2018
a6fef26
Correct wrong errorchecking in containsAllSegments, add another test
parostatkiem-zz Oct 26, 2018
78661a8
Merge branch 'master' of https://github.com/kyma-project/luigi into 4…
parostatkiem-zz Oct 26, 2018
e3c1499
Add wrong routes example using linkManager
parostatkiem-zz Oct 31, 2018
af7a078
Add one UI test
parostatkiem-zz Oct 31, 2018
e7c12f6
Merge branch 'master' of https://github.com/kyma-project/luigi into 4…
parostatkiem-zz Oct 31, 2018
1b149dd
Fix bugs
parostatkiem-zz Oct 31, 2018
b311a62
Add UI tests
parostatkiem-zz Oct 31, 2018
56ad343
Merge branch 'master' of https://github.com/kyma-project/luigi into 4…
parostatkiem-zz Nov 5, 2018
a297a41
Merge branch 'master' of https://github.com/kyma-project/luigi into 4…
parostatkiem-zz Nov 7, 2018
bd0f97b
Merge branch 'master' into 404-support-for-non-existing-paths
kwiatekus Nov 7, 2018
c3c9f7a
Remove unnecessary line breaks
parostatkiem-zz Nov 7, 2018
149be2c
Add additional length check before forEach loop
parostatkiem-zz Nov 7, 2018
eedf9bb
Show true url when original url was partly bad & fix tests
parostatkiem-zz Nov 9, 2018
51381a0
Replace pushState with replaceState
parostatkiem-zz Nov 9, 2018
42bc64c
Add support for non-path routing
parostatkiem-zz Nov 9, 2018
c1c3d09
Merge branch 'master' of github.com:kyma-project/luigi into 404-suppo…
kwiatekus Nov 9, 2018
0b73f82
Merge branch 'master' into 404-support-for-non-existing-paths
parostatkiem Nov 9, 2018
4abb343
Merge branch 'master' of https://github.com/kyma-project/luigi into 4…
parostatkiem-zz Nov 13, 2018
e9798e2
Add links to alerts & redirect to '/' after 404 error
parostatkiem-zz Nov 13, 2018
d35f53c
Fix & improve tets
parostatkiem-zz Nov 13, 2018
f7313fd
Merge branch 'master' of https://github.com/kyma-project/luigi into 4…
parostatkiem-zz Nov 14, 2018
ad31069
aa
parostatkiem-zz Nov 14, 2018
67adae6
Change way of handling alert from postMessage to component's state
parostatkiem-zz Nov 14, 2018
6d17ee0
Fix tests
parostatkiem-zz Nov 14, 2018
6f585b5
Remove obsolete line
parostatkiem-zz Nov 14, 2018
e54a288
Merge branch 'master' into 404-support-for-non-existing-paths
jesusreal Nov 14, 2018
306d852
Remove duplicating tests & remove alert link
parostatkiem-zz Nov 16, 2018
a7ccb73
Merge branch 'master' of https://github.com/kyma-project/luigi into 4…
parostatkiem-zz Nov 16, 2018
88d3e2a
Ignore GET parameters when detecting wrong URL and test it
parostatkiem-zz Nov 16, 2018
8008146
Shorten variable name & syntax
parostatkiem-zz Nov 16, 2018
7092f03
Simplify containsAllSegments
parostatkiem-zz Nov 19, 2018
24f7251
Merge branch 'master' of https://github.com/kyma-project/luigi into 4…
parostatkiem-zz Nov 19, 2018
2e47937
Merge branch 'master' of https://github.com/kyma-project/luigi into 4…
parostatkiem-zz Nov 19, 2018
d489a59
Merge branch 'master' into 404-support-for-non-existing-paths
kwiatekus Nov 20, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,37 @@ describe('Luigi client features', () => {
});
});

describe('linkManager wrong paths navigation', () => {
let $iframeBody;
beforeEach(() => {
cy.get('iframe').then($iframe => {
$iframeBody = $iframe.contents().find('body');
cy.goToFeaturesPage($iframeBody);
});
});
it('navigate to a partitialy wrong link', () => {
cy.wrap($iframeBody)
.contains('Partitialy wrong link')
.click();
cy.location().should(loc => {
expect(loc.hash).to.eq('#/overview/maskopatol');
});
cy.get('.fd-alert').contains(
'Could not map the exact target node for the requested route'
);
});

it('navigate to a totally wrong link', () => {
cy.wrap($iframeBody)
.contains('Totally wrong link')
.click();
cy.location().should(loc => {
expect(loc.hash).to.eq('#/maskopatol/has/a/child');
});
cy.get('.fd-alert').contains('Could not find the requested route');
});
});

describe('uxManager', () => {
it('backdrop', () => {
cy.wait(500);
Expand Down
23 changes: 23 additions & 0 deletions core/examples/luigi-sample-angular/e2e/tests/navigation.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,27 @@ describe('Navigation', () => {
cy.get('.fd-app__sidebar').should('contain', 'Keep Selected Example');
});
});

describe('Wrong URL handling', () => {
it('Shows "not exact route" error', () => {
cy.visit('http://localhost:4200/#/projects/pr2/maskopatol');

cy.location().should(loc => {
expect(loc.hash).to.eq('#/projects/pr2/maskopatol');
});

cy.get('.fd-alert').contains(
'Could not map the exact target node for the requested route'
);
});
it('Shows "route not found" (404) error', () => {
cy.visit('http://localhost:4200/#/maskopatol');

cy.location().should(loc => {
expect(loc.hash).to.eq('#/maskopatol');
});

cy.get('.fd-alert').contains('Could not find the requested route');
});
});
});
Original file line number Diff line number Diff line change
@@ -1,76 +1,97 @@
<section class="fd-section">
<div class="fd-section__header">
<h1 class="fd-section__title">Project {{ projectId }}</h1>
</div>
<div class="fd-panel">
<p><strong>LuigiClient uxManager methods:</strong></p>
<button class="fd-button" (click)="toggleModal()">Add backdrop</button>
<p>
<app-code-snippet data="luigiClient.uxManager().addBackdrop()"></app-code-snippet>
<app-code-snippet data="luigiClient.uxManager().removeBackdrop()"></app-code-snippet>
</p>
</div>
<div class="fd-section__header">
<h1 class="fd-section__title">Project {{ projectId }}</h1>
</div>
<div class="fd-panel">
<p><strong>LuigiClient uxManager methods:</strong></p>
<button class="fd-button" (click)="toggleModal()">Add backdrop</button>
<p>
<app-code-snippet data="luigiClient.uxManager().addBackdrop()"></app-code-snippet>
<app-code-snippet data="luigiClient.uxManager().removeBackdrop()"></app-code-snippet>
</p>
</div>
</section>

<section class="fd-section" *ngIf="preservedViewCallbackContext">
<div class="fd-panel">
<div class="fd-alert" role="alert">
<span class="fd-status-label fd-status-label--available"></span> Context received from linkManager().goBack():<br />
<pre>{{ preservedViewCallbackContext | json }}</pre>
</div>
</div>
<div class="fd-panel">
<div class="fd-alert" role="alert">
<span class="fd-status-label fd-status-label--available"></span> Context received from linkManager().goBack():<br />
<pre>{{ preservedViewCallbackContext | json }}</pre>
</div>
</div>
</section>

<section class="fd-section link-manager" *ngIf="projectId && projectId !== 'overview'">
<div class="fd-panel">
<p><strong>LuigiClient linkManager methods:</strong></p>
<ul class="fd-list-group">
<li class="fd-list-group__item">
<a href="javascript:void(0)" (click)="luigiClient.linkManager().navigate('/overview')">absolute: to overview</a>
<app-code-snippet data="luigiClient.linkManager().navigate('/overview')"></app-code-snippet>
</li>
<li class="fd-list-group__item">
<a href="javascript:void(0)" (click)="luigiClient.linkManager().navigate('users/groups/stakeholders')">relative: to stakeholders</a>
<app-code-snippet data="luigiClient.linkManager().navigate('users/groups/stakeholders')"></app-code-snippet>
</li>
<li class="fd-list-group__item">
<a href="javascript:void(0)" (click)="luigiClient.linkManager().fromClosestContext().navigate('/users/groups/stakeholders')">closest parent: to stakeholders</a>
<app-code-snippet data="luigiClient.linkManager().fromClosestContext().navigate('/users/groups/stakeholders')"></app-code-snippet>
</li>
<li class="fd-list-group__item">
<a href="javascript:void(0)" (click)="luigiClient.linkManager().fromContext('project').navigate('/settings')">parent by name: project to settings</a>
<app-code-snippet data="luigiClient.linkManager().fromContext('project').navigate('/settings')"></app-code-snippet>
</li>
<li class="fd-list-group__item">
<a href="javascript:void(0)" (click)="luigiClient.linkManager().fromClosestContext().withParams({foo: 'bar'}).navigate('settings')">project to settings with params (foo=bar)</a>
<app-code-snippet data="luigiClient.linkManager().fromClosestContext().withParams({foo: 'bar'}).navigate('settings')"></app-code-snippet>
</li>
<li class="fd-list-group__item">
<a href="javascript:void(0)" (click)="luigiClient.linkManager().fromContext('FOOMARK').navigate('/settings')">parent by name: with nonexisting context</a> (look at the console)
<app-code-snippet data="luigiClient.linkManager().fromContext('FOOMARK').navigate('/settings')"></app-code-snippet>
</li>
<li class="fd-list-group__item">
<a href="javascript:void(0)" (click)="luigiClient.linkManager().navigate('/settings', null, true)">with preserved view: project to global settings and back</a>
<app-code-snippet data="luigiClient.linkManager().navigate('/settings', null, true)"></app-code-snippet>
</li>
<li class="fd-list-group__item check-path">
<span>Check if path exists</span>
<app-code-snippet data="luigiClient.linkManager().pathExists('{{pathExists.formValue}}')"></app-code-snippet>
<span>
<input type="text" [(ngModel)]="pathExists.formValue" (input)="resetPathExistsResult()"/>
<button class="fd-button" (click)="checkIfPathExists()">Check</button>
</span>
<p class="check-path-result">
<ng-container *ngIf="pathExists.result === true">
Path {{pathExists.formValue}} exists!
</ng-container>
<ng-container *ngIf="pathExists.result === false">
Path {{pathExists.formValue}} does not exist!
</ng-container>
</p>
</li>
</ul>
</div>
<div class="fd-panel">
<p><strong>LuigiClient linkManager methods:</strong></p>
<ul class="fd-list-group">
<li class="fd-list-group__item">
<a href="javascript:void(0)" (click)="luigiClient.linkManager().navigate('/overview')">absolute: to overview</a>
<app-code-snippet data="luigiClient.linkManager().navigate('/overview')"></app-code-snippet>
</li>
<li class="fd-list-group__item">
<a href="javascript:void(0)" (click)="luigiClient.linkManager().navigate('users/groups/stakeholders')">relative: to stakeholders</a>
<app-code-snippet data="luigiClient.linkManager().navigate('users/groups/stakeholders')"></app-code-snippet>
</li>
<li class="fd-list-group__item">
<a href="javascript:void(0)" (click)="luigiClient.linkManager().fromClosestContext().navigate('/users/groups/stakeholders')">
closest parent: to stakeholders</a>
<app-code-snippet data="luigiClient.linkManager().fromClosestContext().navigate('/users/groups/stakeholders')"></app-code-snippet>
</li>
<li class="fd-list-group__item">
<a href="javascript:void(0)" (click)="luigiClient.linkManager().fromContext('project').navigate('/settings')">
parent by name: project to settings</a>
<app-code-snippet data="luigiClient.linkManager().fromContext('project').navigate('/settings')"></app-code-snippet>
</li>
<li class="fd-list-group__item">
<a href="javascript:void(0)" (click)="luigiClient.linkManager().fromClosestContext().withParams({foo: 'bar'}).navigate('settings')">
project to settings with params (foo=bar)</a>
<app-code-snippet data="luigiClient.linkManager().fromClosestContext().withParams({foo: 'bar'}).navigate('settings')"></app-code-snippet>
</li>
<li class="fd-list-group__item">
<a href="javascript:void(0)" (click)="luigiClient.linkManager().fromContext('FOOMARK').navigate('/settings')">
parent by name: with nonexisting context</a> (look at the console)
<app-code-snippet data="luigiClient.linkManager().fromContext('FOOMARK').navigate('/settings')"></app-code-snippet>
</li>
<li class="fd-list-group__item">
<a href="javascript:void(0)" (click)="luigiClient.linkManager().navigate('/settings', null, true)">
with preserved view: project to global settings and back</a>
<app-code-snippet data="luigiClient.linkManager().navigate('/settings', null, true)"></app-code-snippet>
</li>
<li class="fd-list-group__item check-path">
<span>Check if path exists</span>
<app-code-snippet data="luigiClient.linkManager().pathExists('{{pathExists.formValue}}')"></app-code-snippet>
<span>
<input type="text" [(ngModel)]="pathExists.formValue" (input)="resetPathExistsResult()" />
<button class="fd-button" (click)="checkIfPathExists()">Check</button>
</span>
<p class="check-path-result">
<ng-container *ngIf="pathExists.result === true">
Path {{pathExists.formValue}} exists!
</ng-container>
<ng-container *ngIf="pathExists.result === false">
Path {{pathExists.formValue}} does not exist!
</ng-container>
</p>
</li>
</ul>
</div>
</section>

<app-modal [modalActive]="modalActive" (modalClosed)="toggleModal()"></app-modal>
<section class="fd-section" *ngIf="projectId && projectId !== 'overview'">
<div class="fd-panel">
<p><strong>LuigiClient - wrong paths in linkManager.navigate():</strong></p>
<ul class="fd-list-group">
<li class="fd-list-group__item">
<a href="javascript:void(0)" (click)="luigiClient.linkManager().navigate('/overview/maskopatol')">Partitialy wrong link</a>
<app-code-snippet data="luigiClient.linkManager().navigate('/overview/maskopatol')"></app-code-snippet>
</li>
<li class="fd-list-group__item">
<a href="javascript:void(0)" (click)="luigiClient.linkManager().navigate('/maskopatol/has/a/child')">Totally wrong link</a>
dariadomagala-sap marked this conversation as resolved.
Show resolved Hide resolved
<app-code-snippet data="luigiClient.linkManager().navigate('/maskopatol/has/a/child')"></app-code-snippet>
</li>
</ul>
</div>
</section>

<app-modal [modalActive]="modalActive" (modalClosed)="toggleModal()"></app-modal>
2 changes: 1 addition & 1 deletion core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"scripts": {
"bundle": "webpack --display-error-details",
"bundle-develop": "webpack -d --watch",
"test": "./node_modules/mocha/bin/mocha --require babel-register --require babel-polyfill --require jsdom-global/register",
"test": "./node_modules/mocha/bin/mocha --require babel-register --require babel-polyfill --require jsdom-global/register --recursive test",
"bundlesize": "bundlesize",
"prepush": "npm run bundle && npm run bundlesize"
},
Expand Down
83 changes: 63 additions & 20 deletions core/src/App.html
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@

<div id="app {hideNav? 'no-nav' : ''}">
<Backdrop>
<div class="fd-page iframeContainer" use:init="context"></div>
</Backdrop>
{#if showLoadingIndicator}
<div in:fade='{delay: 250, duration: 250}' out:fade='{duration: 250}' class="fd-page spinnerContainer" aria-hidden="false" aria-label="Loading">
<div class="fd-spinner"><div></div></div>
</div>
{/if}

<TopNav pathData={navigationPath} />
<LeftNav pathData={navigationPath} />
{#if alertMessage}
<div class="fd-alert fd-alert--error fd-alert--dismissible" role="alert" id="j2ALl423">
<button on:click="set({alertMessage:null})" class="fd-alert__close" aria-controls="j2ALl423" aria-label="Close"></button>
{alertMessage}
</div>
{/if}
<Backdrop>
<div class="fd-page iframeContainer" use:init="context" />
</Backdrop>
{#if showLoadingIndicator}
<div in:fade='{delay: 250, duration: 250}' out:fade='{duration: 250}' class="fd-page spinnerContainer" aria-hidden="false"
aria-label="Loading">
<div class="fd-spinner">
<div></div>
</div>
</div>
{/if}

<TopNav pathData={navigationPath} />
<LeftNav pathData={navigationPath} />
</div>

<script type="text/javascript">
Expand All @@ -22,6 +30,9 @@
import { getConfigValue, getConfigValueFromObject } from './services/config.js';
import { isFunction } from './utilities/helpers.js';

const handleAlertReceived = message => {
this.set({ alertMessage: message });
};
const trimLeadingSlash = str => str.replace(/^\//, '');
const isValidBackRoute = (preservedViews, routeHash) => {
if (preservedViews.length === 0) {
Expand Down Expand Up @@ -119,12 +130,14 @@
};

const handleNavigation = async (component, data, config) => {
const path = buildPath(component, data.params);
const matchedPath = await Routing.matchPath(path);
if (matchedPath !== null) {
addPreserveView(component, data, config);
Routing.navigateTo(matchedPath);
let path = buildPath(component, data.params);

if (path[0] !== '/') {
path = '/' + path; //add leading slash if necessary
}

addPreserveView(component, data, config);
Routing.navigateTo(path); //navigate to the raw path. Any errors/alerts are handled later
};

const sendContextToClient = (component, config, goBackContext = {}) => {
Expand All @@ -147,6 +160,7 @@
return {
isNavigateBack: false,
showLoadingIndicator: false,
alertMessage: null,
preservedViews: [
// {
// path: '/project/p2/settings',
Expand All @@ -167,7 +181,7 @@
builderCompatibilityMode: Boolean(window.builderCompatibilityMode)
};

window.addEventListener('message', async (e) => {
window.addEventListener('message', async e => {
if ('luigi.get-context' === e.data.msg && config.iframe) {
sendContextToClient(this, config, {});

Expand Down Expand Up @@ -226,13 +240,27 @@
}
}

if ('luigi.displayAlert' === e.data.msg) {
if (e.data.errorMessage) {
this.set({ alertMessage: e.data.errorMessage });
} else {
console.error(
'Ooops, seems like the developers have misconfigured something'
);
}
}

if ('luigi.hideAlert' === e.data.msg) {
this.set({ alertMessage: null });
}
if ('luigi.navigation.pathExists' === e.data.msg) {
const data = e.data.data;
const path = buildPath(this, data);
const matchedPath = await Routing.matchPath(path);

let normalizedPath = ((!path.startsWith('/')) ? '/' : '') +
((path.endsWith('/')) ? path.slice(0,-1) : path);
let normalizedPath =
(!path.startsWith('/') ? '/' : '') +
(path.endsWith('/') ? path.slice(0, -1) : path);
const pathExists = matchedPath === normalizedPath;
config.iframe.contentWindow.postMessage(
{
Expand Down Expand Up @@ -278,6 +306,7 @@
<style type="text/scss">
@import 'node_modules/fundamental-ui/scss/layout/page';
@import 'node_modules/fundamental-ui/scss/components/spinner';
@import 'node_modules/fundamental-ui/scss/components/alert';
@import 'static.css';

:global(html) {
Expand Down Expand Up @@ -351,4 +380,18 @@
right: 0;
}
}

$topNavHeight: 50px;
$leftNavWidth: 320px;
.fd-alert {
position: absolute;
min-width: 20rem;
width: calc(100% - 2 * (#{$leftNavWidth} + 1rem));
top: calc(#{$topNavHeight} + 1rem);
left: calc(#{$leftNavWidth} + 1rem);
z-index: 2;
.fd-alert__close {
cursor: pointer;
}
}
</style>
Loading