Skip to content

Commit

Permalink
feat(application-config): Enforce uniqueness for uriPath of the subme…
Browse files Browse the repository at this point in the history
…nu links. (#2567)

* refactor(shield-469): validate application config for submenulink, throw error when there is a duplicate uripath

* refactor(shield-469): add changeset

* refactor(application-config): implement helper for validating submenulinks

* refactor(application-config): rename validations-config file, use named exports

* refactor(application-config): remove unnecessary hyphen

* refactor(application-config): pass custom app object to vaalidator
  • Loading branch information
Rhotimee authored May 3, 2022
1 parent e74d462 commit 3094da2
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/bright-hornets-enjoy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@commercetools-frontend/application-config': patch
---

Enforce uniqueness for `uriPath` of the submenu links.
4 changes: 2 additions & 2 deletions packages/application-config/src/process-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type {
import fs from 'fs';
import omitEmpty from 'omit-empty-es';
import loadConfig from './load-config';
import validate from './validate-config';
import { validateConfig } from './validations';
import substituteVariablePlaceholders from './substitute-variable-placeholders';
import {
mapCloudIdentifierToApiUrl,
Expand Down Expand Up @@ -54,7 +54,7 @@ const processConfig = ({
if (cachedConfig && !disableCache) return cachedConfig;

const rawConfig = loadConfig(applicationPath);
validate(rawConfig);
validateConfig(rawConfig);
const appConfig =
substituteVariablePlaceholders<JSONSchemaForCustomApplicationConfigurationFiles>(
rawConfig,
Expand Down
3 changes: 3 additions & 0 deletions packages/application-config/src/transformers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { JSONSchemaForCustomApplicationConfigurationFiles } from './schema';
import type { CustomApplicationData } from './types';
import { entryPointUriPathToResourceAccesses } from './formatters';
import { validateSubmenuLinks } from './validations';

// The `uriPath` of each submenu link is supposed to be defined relative
// to the `entryPointUriPath`. Computing the full path is done internally to keep
Expand All @@ -24,6 +25,8 @@ function transformCustomApplicationConfigToData(
appConfig.entryPointUriPath
);

validateSubmenuLinks(appConfig);

return {
id: appConfig.env.production.applicationId,
name: appConfig.name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type ErrorAdditionalProperty = ErrorObject<
type ErrorEnum = ErrorObject<'enum', { allowedValues: string[] }>;

const ajv = new Ajv({ strict: true, useDefaults: true });

const validate =
ajv.compile<JSONSchemaForCustomApplicationConfigurationFiles>(schemaJson);

Expand Down Expand Up @@ -36,7 +37,7 @@ const printErrors = (errors?: ErrorObject[] | null) => {
.join('\n');
};

const validateConfig = (
export const validateConfig = (
config: JSONSchemaForCustomApplicationConfigurationFiles
): void => {
const valid = validate(config);
Expand All @@ -45,4 +46,16 @@ const validateConfig = (
}
};

export default validateConfig;
export const validateSubmenuLinks = (
config: JSONSchemaForCustomApplicationConfigurationFiles
) => {
const uriPathSet = new Set();
config.submenuLinks.forEach(({ uriPath }) => {
if (uriPathSet.has(uriPath)) {
throw new Error(
'Duplicate URI path. Every submenu link must have a unique URI path value'
);
}
uriPathSet.add(uriPath);
});
};
25 changes: 24 additions & 1 deletion packages/application-config/test/json-schema.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import validateConfig from '../src/validate-config';
import { validateConfig, validateSubmenuLinks } from '../src/validations';
import fixtureConfigSimple from './fixtures/config-simple.json';
import fixtureConfigFull from './fixtures/config-full.json';
import fixtureConfigOidc from './fixtures/config-oidc.json';
Expand Down Expand Up @@ -173,4 +173,27 @@ describe('invalid configurations', () => {
`" must have required property 'mainMenuLink'"`
);
});
it('should validate that "uriPath" for "submenuLinks" is unique', () => {
expect(() =>
validateSubmenuLinks({
...fixtureConfigSimple,
submenuLinks: [
{
uriPath: 'custom-app/avengers',
defaultLabel: 'avengers',
permissions: [],
labelAllLocales: [],
},
{
uriPath: 'custom-app/avengers',
defaultLabel: 'justice-league',
permissions: [],
labelAllLocales: [],
},
],
})
).toThrowErrorMatchingInlineSnapshot(
`"Duplicate URI path. Every submenu link must have a unique URI path value"`
);
});
});
2 changes: 1 addition & 1 deletion packages/application-config/test/load-config.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import path from 'path';
import loadConfig from '../src/load-config';
import validateConfig from '../src/validate-config';
import { validateConfig } from '../src/validations';

describe.each`
extension | fixtureApp
Expand Down

1 comment on commit 3094da2

@vercel
Copy link

@vercel vercel bot commented on 3094da2 May 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.