Skip to content

Commit

Permalink
feat(transloco): 🎸 update replace-in-flight
Browse files Browse the repository at this point in the history
Update replace-in-flight to ^8.1.0 to resolve CWE-772 in inflight

✅ Closes: jsverse#768
  • Loading branch information
stephaniekatterwe committed Aug 6, 2024
1 parent e327f3b commit 9605da8
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 88 deletions.
8 changes: 5 additions & 3 deletions libs/transloco-schematics/jest.config.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import type {Config} from 'jest';
import type { Config } from 'jest';

export default {
displayName: 'transloco-schematics',
testEnvironment: 'node',
globals: {},
transform: {
'^.+\\.[tj]sx?$': [
'ts-jest',
'^.+.(ts|mjs|js|html)$': [
'jest-preset-angular',
{
tsconfig: '<rootDir>/tsconfig.spec.json',
stringifyContentPathRegex: '\\.(html|svg)$',
},
],
},
transformIgnorePatterns: ['node_modules/?!(.\\*.mjs$|replace-in-file)'],
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
coverageDirectory: '../../coverage/libs/transloco-schematics',
preset: '../../jest.preset.js',
Expand Down
131 changes: 73 additions & 58 deletions libs/transloco-schematics/src/tests/ngx-translate-migration.spec.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,60 @@
// noinspection AngularUndefinedBinding

import * as nodePath from 'node:path';
import {readFile} from 'node:fs/promises';
import { readFile } from 'node:fs/promises';

import {replaceInFile, ReplaceInFileConfig} from 'replace-in-file';
import {glob} from 'glob';
import { replaceInFile, ReplaceInFileConfig } from 'replace-in-file';
import { glob } from 'glob';

import {PIPE_IN_BINDING_REGEX, PIPE_REGEX, run} from '../migrate/ngx-translate-migration';
import {
PIPE_IN_BINDING_REGEX,
PIPE_REGEX,
run,
} from '../migrate/ngx-translate-migration';

jest.mock('replace-in-file');
jest.mock('replace-in-file', () => ({
__esModule: true,
replaceInFile: jest.fn(),
}));

describe('ngx-translate migration', () => {

describe('Positive regex tests', () => {

describe('Pipe in binding', () => {
test.each([
{
testCase: `<component [header]="'hello.world' | translate">`,
match: [`]="'hello.world' | translate"`]
match: [`]="'hello.world' | translate"`],
},
{
testCase: `<component [header]="'hello.world' | translate | anotherPipe">`,
match: [`]="'hello.world' | translate | anotherPipe"`]
match: [`]="'hello.world' | translate | anotherPipe"`],
},
{
testCase: `<component [header]="'hello' | translate:params | anotherPipe">`,
match: [`]="'hello' | translate:params | anotherPipe"`]
match: [`]="'hello' | translate:params | anotherPipe"`],
},
{
testCase: `<component [title]="titleMap[reportType] | translate">`,
match: [`]="titleMap[reportType] | translate"`]
match: [`]="titleMap[reportType] | translate"`],
},
{
testCase: `<component [matTooltip]="('foo.bar' | translate) + ': ' + (value | number: '1.0-2')">`,
match: [`]="('foo.bar' | translate) + ': ' + (value | number: '1.0-2')"`]
match: [
`]="('foo.bar' | translate) + ': ' + (value | number: '1.0-2')"`,
],
},
{
testCase: `<compnent [title]="'Hello, ' + ('mom' | translate) | fooBar">`,
match: [`]="'Hello, ' + ('mom' | translate) | fooBar"`]
match: [`]="'Hello, ' + ('mom' | translate) | fooBar"`],
},
{
testCase: `<edge-wizard-step [label]="'Restore Options' | translate" [validatingMessage]="'Processing archive...'|translate"`,
match: [`]="'Restore Options' | translate"`, `]="'Processing archive...'|translate"`]
}
])('Case: $testCase; Match: $match', ({testCase, match}) => {
match: [
`]="'Restore Options' | translate"`,
`]="'Processing archive...'|translate"`,
],
},
])('Case: $testCase; Match: $match', ({ testCase, match }) => {
const regex = new RegExp(PIPE_IN_BINDING_REGEX, 'gm');
const result = testCase.match(regex);

Expand All @@ -56,33 +66,35 @@ describe('ngx-translate migration', () => {
test.each([
{
testCase: `<component>{{ "hello.world" | translate }}</component>`,
match: [`{{ "hello.world" | translate }}`]
match: [`{{ "hello.world" | translate }}`],
},
{
testCase: `<component>{{ "hello.world" | translate | anotherPipe | oneMore }}</component>`,
match: [`{{ "hello.world" | translate | anotherPipe | oneMore }}`]
match: [`{{ "hello.world" | translate | anotherPipe | oneMore }}`],
},
{
testCase: `<component>{{ "hello" | translate: { name: 'John' } }}</component>`,
match: [`{{ "hello" | translate: { name: 'John' } }}`]
match: [`{{ "hello" | translate: { name: 'John' } }}`],
},
{
testCase: `<component>{{ titleMap[reportType] | translate }}</component>`,
match: [`{{ titleMap[reportType] | translate }}`]
match: [`{{ titleMap[reportType] | translate }}`],
},
{
testCase: `<component>{{ ('foo.bar' | translate) + ': ' + (value | number: '1.0-2') }}</component>`,
match: [`{{ ('foo.bar' | translate) + ': ' + (value | number: '1.0-2') }}`]
match: [
`{{ ('foo.bar' | translate) + ': ' + (value | number: '1.0-2') }}`,
],
},
{
testCase: `<compnent>{{ 'Hello, ' + ('mom' | translate) | fooBar }}</compnent>`,
match: [`{{ 'Hello, ' + ('mom' | translate) | fooBar }}`]
match: [`{{ 'Hello, ' + ('mom' | translate) | fooBar }}`],
},
{
testCase: `{{"1" | translate}} {{errorCounter}} {{"2" | translate}}`,
match: [`{{"1" | translate}}`, `{{"2" | translate}}`]
}
])('Case: $testCase; Match: $match', ({testCase, match}) => {
match: [`{{"1" | translate}}`, `{{"2" | translate}}`],
},
])('Case: $testCase; Match: $match', ({ testCase, match }) => {
const regex = new RegExp(PIPE_REGEX, 'gm');
const result = testCase.match(regex);

Expand All @@ -92,106 +104,109 @@ describe('ngx-translate migration', () => {
});

describe('Negative regex tests', () => {

describe('Pipe in binding', () => {
test.each([
{
testCase: `<component [header]="'hello.world' | transloco">`
testCase: `<component [header]="'hello.world' | transloco">`,
},
{
testCase: `<component [header]="'hello.world' | somePipe | anotherPipe">`
testCase: `<component [header]="'hello.world' | somePipe | anotherPipe">`,
},
{
testCase: `<component [header]="'hello' | transloco:params | anotherPipe">`
testCase: `<component [header]="'hello' | transloco:params | anotherPipe">`,
},
{
testCase: `<component [title]="titleMap[reportType] | fooBar">`
testCase: `<component [title]="titleMap[reportType] | fooBar">`,
},
{
testCase: `<component [matTooltip]="('foo.bar' | transloco) + ': ' + (value | number: '1.0-2')">`
testCase: `<component [matTooltip]="('foo.bar' | transloco) + ': ' + (value | number: '1.0-2')">`,
},
{
testCase: `<compnent [title]="'Hello World ' + ('mom' | transloco) | fooBar">`
testCase: `<compnent [title]="'Hello World ' + ('mom' | transloco) | fooBar">`,
},
{
testCase: `<a [title]="'admin.1' | lowercase
| translate"
</a>`
}
])('Case: $testCase', ({testCase}) => {
</a>`,
},
])('Case: $testCase', ({ testCase }) => {
const regex = new RegExp(PIPE_IN_BINDING_REGEX, 'gm');
const result = testCase.match(regex);

expect(result).toBeNull();
});
});

describe('Pipe', () => {
test.each([
{
testCase: `<component>{{ "hello.world" | transloco }}</component>`
testCase: `<component>{{ "hello.world" | transloco }}</component>`,
},
{
testCase: `<component>{{ "hello.world" | transloco | anotherPipe | oneMore }}</component>`
testCase: `<component>{{ "hello.world" | transloco | anotherPipe | oneMore }}</component>`,
},
{
testCase: `<component>{{ "hello" | transloco: { name: 'John' } }}</component>`
testCase: `<component>{{ "hello" | transloco: { name: 'John' } }}</component>`,
},
{
testCase: `<component>{{ titleMap[reportType] | somePipe }}</component>`
testCase: `<component>{{ titleMap[reportType] | somePipe }}</component>`,
},
{
testCase: `<component>{{ ('foo.bar' | transloco) + ': ' + (value | number: '1.0-2') }}</component>`
testCase: `<component>{{ ('foo.bar' | transloco) + ': ' + (value | number: '1.0-2') }}</component>`,
},
{
testCase: `<compnent>{{ 'Hello, ' + ('mom' | transloco) | fooBar }}</compnent>`
}
])('Case: $testCase', ({testCase}) => {
testCase: `<compnent>{{ 'Hello, ' + ('mom' | transloco) | fooBar }}</compnent>`,
},
])('Case: $testCase', ({ testCase }) => {
const regex = new RegExp(PIPE_REGEX, 'gm');
const result = testCase.match(regex);

expect(result).toBeNull();
});
});

});

describe('HTML template', () => {

it('should replace html template content', async () => {
const replacements: Record<string, string> = {},
isWindows = process.platform === 'win32';

(replaceInFile as unknown as jest.Mock).mockImplementation(
async (config: ReplaceInFileConfig): Promise<void> => {
const path = config.files as string,
regex = config.from as RegExp,
replacer = config.to as (match: string) => string;
const files = await glob(path, {windowsPathsNoEscape: isWindows});

const files = await glob(path, { windowsPathsNoEscape: isWindows });

for (const fullPath of files) {
const filename = nodePath.parse(fullPath).base,
content = replacements[filename] ?? await readFile(fullPath, {encoding: 'utf-8'});

content =
replacements[filename] ??
(await readFile(fullPath, { encoding: 'utf-8' }));

replacements[filename] = content.replace(regex, replacer);
}
}
},
);

const ngxTranslateTemplatePath = './src/tests/templates/pipes/ngx-translate';
const ngxTranslateTemplatePath =
'./src/tests/templates/pipes/ngx-translate';

await run(ngxTranslateTemplatePath);

const filenames = Object.keys(replacements);

for(const filename of filenames) {
const resultPath = nodePath.join(__dirname, './templates/pipes/transloco', filename),
resultContent = await readFile(resultPath, {encoding: 'utf-8'});
for (const filename of filenames) {
const resultPath = nodePath.join(
__dirname,
'./templates/pipes/transloco',
filename,
),
resultContent = await readFile(resultPath, { encoding: 'utf-8' });

expect(replacements[filename]).toBe(resultContent);
}
});

});
});
Loading

0 comments on commit 9605da8

Please sign in to comment.