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

Resolves TODOs in core utilities #3800

Merged
merged 14 commits into from
Jul 22, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/src/services/routing.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { isEqual } from 'lodash';

class RoutingClass {
getNodePath(node, params) {
return node ? RoutingHelpers.buildRoute(node, node.pathSegment ? '/' + node.pathSegment : '', params) : '';
return RoutingHelpers.getNodePath(node, params);
}

normalizePath(path) {
Expand Down
25 changes: 12 additions & 13 deletions core/src/utilities/helpers/iframe-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,18 @@ class IframeHelpersClass {
});
}

isSameDomain(config, component) {
//TODO rename to reflect the fact that it checks for URL till hash (which is more than just domain)
if (config.iframe) {
const componentData = component.get();
const previousUrl = GenericHelpers.getUrlWithoutHash(componentData.previousNodeValues.viewUrl);
const nextUrl = GenericHelpers.getUrlWithoutHash(componentData.viewUrl);
const previousViewGroup = componentData.previousNodeValues.viewGroup;
const nextViewGroup = componentData.viewGroup;
if (previousUrl === nextUrl && !previousViewGroup && !nextViewGroup) {
return true;
}
isSameUrl(config, component) {
if (!config.iframe) {
return false;
}
return false;

const componentData = component.get();
const previousUrl = GenericHelpers.getUrlWithoutHash(componentData.previousNodeValues.viewUrl);
const nextUrl = GenericHelpers.getUrlWithoutHash(componentData.viewUrl);
const previousViewGroup = componentData.previousNodeValues.viewGroup;
const nextViewGroup = componentData.viewGroup;

return !!(previousUrl === nextUrl && !previousViewGroup && !nextViewGroup);
}

isSameViewGroup(config, component) {
Expand All @@ -87,7 +86,7 @@ class IframeHelpersClass {
}

canReuseIframe(config, component) {
return this.isSameDomain(config, component) || this.isSameViewGroup(config, component);
return this.isSameUrl(config, component) || this.isSameViewGroup(config, component);
}

getLocation(url) {
Expand Down
12 changes: 3 additions & 9 deletions core/src/utilities/helpers/navigation-helpers.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// Helper methods for 'navigation.js' file. They don't require any method from 'navigation.js` but are required by them.
import { reject, get } from 'lodash';
import { LuigiAuth, LuigiConfig, LuigiFeatureToggles, LuigiI18N } from '../../core-api';
import { AuthHelpers, GenericHelpers, RoutingHelpers } from './';
import { Navigation } from '../../navigation/services/navigation';
import { Routing } from '../../services/routing';
import { reject, get } from 'lodash';
import { IframeHelpers } from './';
import { AuthHelpers, GenericHelpers, IframeHelpers, RoutingHelpers } from './';

class NavigationHelpersClass {
constructor() {
Expand Down Expand Up @@ -105,13 +104,8 @@ class NavigationHelpersClass {
return context;
}

// TODO: use one extracted generic helper function here and in routing.js
getNodePath(node) {
if (node.parent) {
return this.getNodePath(node.parent) + '/' + node.pathSegment;
} else {
return node.pathSegment;
}
return RoutingHelpers.getNodePath(node, null);
}

groupNodesBy(nodes, property, useVirtualGroups) {
Expand Down
13 changes: 13 additions & 0 deletions core/src/utilities/helpers/routing-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,19 @@ class RoutingHelpersClass {
return undefined;
}

/**
* Returns the path from the passed node and params
* @param {*} node
* @param {*} params
*/
getNodePath(node, params) {
if (!node || params) {
return node ? this.buildRoute(node, node.pathSegment ? '/' + node.pathSegment : '', params) : '';
} else {
return `${node.parent ? this.getNodePath(node.parent) : ''}/${node.pathSegment}`;
}
}

substituteDynamicParamsInObject(object, paramMap, paramPrefix = ':', contains = false) {
return Object.entries(object)
.map(([key, value]) => {
Expand Down
70 changes: 70 additions & 0 deletions core/test/utilities/helpers/iframe-helpers.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,76 @@ describe('Iframe-helpers', () => {
});
});

describe('isSameUrl', () => {
it('should return false when iframe is not set', () => {
const config = { iframe: null };

component.set({
viewUrl: 'http://otherurl.de/app.html!#/someUrl',
viewGroup: 'test',
previousNodeValues: { viewUrl: null, viewGroup: null }
});

const result = IframeHelpers.isSameUrl(config, component);

assert.equal(result, false);
});

it('should return false when iframe is set and previousUrl is different than nextUrl', () => {
const config = {
iframe: {
src: 'http://url.com/index.html!#/prevUrl'
}
};

component.set({
viewUrl: 'http://otherurl.de/app.html!#/someUrl',
viewGroup: 'test',
previousNodeValues: { viewUrl: config.iframe.src, viewGroup: null }
});

const result = IframeHelpers.isSameUrl(config, component);

assert.equal(result, false);
});

it('should return false when iframe is set and previousUrl equals nextUrl, but viewGroup is defined', () => {
const config = {
iframe: {
src: 'http://otherurl.de/app.html!#/someUrl'
}
};

component.set({
viewUrl: 'http://otherurl.de/app.html!#/someUrl',
viewGroup: 'test',
previousNodeValues: { viewUrl: config.iframe.src, viewGroup: null }
});

const result = IframeHelpers.isSameUrl(config, component);

assert.equal(result, false);
});

it('should return true when iframe is set and previousUrl equals nextUrl and viewGroup is not defined', () => {
const config = {
iframe: {
src: 'http://otherurl.de/app.html!#/someUrl'
}
};

component.set({
viewUrl: 'http://otherurl.de/app.html!#/someUrl',
viewGroup: null,
previousNodeValues: { viewUrl: config.iframe.src, viewGroup: null }
});

const result = IframeHelpers.isSameUrl(config, component);

assert.equal(result, true);
});
});

describe('canReuseIframe', () => {
const config = {
iframe: {
Expand Down
164 changes: 150 additions & 14 deletions core/test/utilities/helpers/navigation-helpers.spec.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
/* eslint-disable camelcase */
//TODO: make some tests here
import { LuigiAuth, LuigiConfig, LuigiFeatureToggles, LuigiI18N } from '../../../src/core-api';
import { Navigation } from '../../../src/navigation/services/navigation';
import { Routing } from '../../../src/services';
import { AuthHelpers, NavigationHelpers, RoutingHelpers } from '../../../src/utilities/helpers';

const chai = require('chai');
const assert = chai.assert;
const sinon = require('sinon');
import { AuthHelpers, NavigationHelpers, RoutingHelpers } from '../../../src/utilities/helpers';
import { LuigiAuth, LuigiConfig, LuigiFeatureToggles, LuigiI18N } from '../../../src/core-api';
import { Routing } from '../../../src/services/routing';
import { Navigation } from '../../../src/navigation/services/navigation';

describe('Navigation-helpers', () => {
describe('isNodeAccessPermitted', () => {
Expand Down Expand Up @@ -228,14 +227,25 @@ describe('Navigation-helpers', () => {
});
});

it('getNodePath', () => {
const node = {
parent: {
pathSegment: 'parent'
},
pathSegment: 'pathSegment'
};
assert.equal(NavigationHelpers.getNodePath(node), 'parent/pathSegment', 'path should match');
describe('getNodePath', () => {
it('should return path built without parent segment', () => {
const node = {
pathSegment: 'pathSegment'
};

assert.equal(NavigationHelpers.getNodePath(node), '/pathSegment', 'path should match');
});

it('should return path built from both parent and child segment', () => {
const node = {
parent: {
pathSegment: 'parent'
},
pathSegment: 'pathSegment'
};

assert.equal(NavigationHelpers.getNodePath(node), '/parent/pathSegment', 'path should match');
});
});

describe('handleUnresponsiveClient', () => {
Expand Down Expand Up @@ -1006,4 +1016,130 @@ describe('Navigation-helpers', () => {
assert.equal(sideNavAccordionMode, true);
});
});

describe('getProductSwitcherConfig', () => {
beforeEach(() => {
sinon.stub(LuigiConfig, 'getConfigValue');
});

afterEach(() => {
sinon.restore();
});

it('should return product switcher config', () => {
const mockedConfig = {
icon: 'grid',
label: 'Products',
columns: 'auto',
items: () => {
return [{}, {}, {}];
}
};

LuigiConfig.getConfigValue.returns(mockedConfig);

const result = NavigationHelpers.getProductSwitcherConfig();

assert.deepEqual(result, mockedConfig);
});
});

describe('applyContext', () => {
it('should return provided context when no additional data is present', () => {
const mockedContext = { data: 'store' };
const result = NavigationHelpers.applyContext(mockedContext, null, null);

assert.deepEqual(result, mockedContext);
});

it('should return provided context when additional data is present', () => {
const mockedContext = { data: 'store' };
const mockedAddition = { foo: 'bar' };
const result = NavigationHelpers.applyContext(mockedContext, mockedAddition, null);

assert.deepEqual(result, { ...mockedContext, ...mockedAddition });
});
});

describe('stripNode', () => {
it('should return stripped node', () => {
const mockedNode = { children: [], data: 'store', navHeader: {}, parent: {} };
const result = NavigationHelpers.stripNode(mockedNode);

assert.deepEqual(result, { data: 'store' });
});
});

describe('getParentNode', () => {
it('should return node parent when it is present', () => {
const mockedNode = { children: [], data: 'store', navHeader: {}, parent: {} };
const mockedPathData = [
{
navigationPath: [
{
pathSegment: 'groups',
children: [
{
pathSegment: 'stakeholders',
viewUrl: '/sampleapp.html#/projects/1/users/groups/stakeholders'
},
{
pathSegment: 'customers',
viewUrl: '/sampleapp.html#/projects/1/users/groups/customers'
}
]
}
],
context: {}
}
];
const result = NavigationHelpers.getParentNode(mockedNode, mockedPathData);

assert.deepEqual(result, {});
});

it('should return path data item when node parent is not present', () => {
const mockedNode = { children: [], data: 'store', navHeader: {}, parent: null };
const mockedPathData = [
{
navigationPath: [
{
pathSegment: 'groups',
children: [
{
pathSegment: 'stakeholders',
viewUrl: '/sampleapp.html#/projects/1/users/groups/stakeholders'
},
{
pathSegment: 'customers',
viewUrl: '/sampleapp.html#/projects/1/users/groups/customers'
}
]
}
],
context: {}
},
mockedNode
];
const result = NavigationHelpers.getParentNode(mockedNode, mockedPathData);

assert.deepEqual(result, mockedPathData[0]);
});
});

describe('getTestId', () => {
it('should return node testId when it is present', () => {
const mockedNode = { children: [], label: null, pathSegment: null, testId: 'ab_cd' };
const result = NavigationHelpers.getTestId(mockedNode);

assert.equal(result, 'ab_cd');
});

it('should return generated testId when it is not present in node', () => {
const mockedNode = { children: [], label: 'cd', pathSegment: 'ab', testId: null };
const result = NavigationHelpers.getTestId(mockedNode);

assert.equal(result, 'ab_cd');
});
});
});
28 changes: 28 additions & 0 deletions core/test/utilities/helpers/routing-helpers.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,34 @@ describe('Routing-helpers', () => {
sinon.assert.calledOnce(RoutingHelpers.getRouteLink);
});
});

describe('getNodePath', () => {
const node = {
label: 'AAA',
pathSegment: 'projects',
viewUrl: '/aaa.html'
};
const params = '~test=true&foo=bar';

it('should not fail if node is not defined', () => {
const result = Routing.getNodePath(undefined, params);

assert.equal(result, '');
});

it('should not fail if params are not defined', () => {
const result = Routing.getNodePath(node, undefined);

assert.equal(result, '/projects');
});

it('should return node path with params', () => {
const result = Routing.getNodePath(node, params);

assert.equal(result, '/projects?~test=true&foo=bar');
});
});

describe('getLastNodeObject', () => {
let mockPathData;

Expand Down