test(docs-infra): ensure all redirect rules are tested (#42452)

This commit adds a test assertion to verify that all redirect rules
defined in `firebase.json` are tested, i.e. that each rule is applied to
at least one testcase from `URLS_TO_REDIRECT.txt`.

This will ensure that any redirect rules added in the future will be
tested.

PR Close #42452
This commit is contained in:
George Kalpakas 2021-06-17 23:58:15 +03:00 committed by Dylan Hunn
parent c66423ab2a
commit c397b59855
5 changed files with 44 additions and 4 deletions

View File

@ -12,6 +12,7 @@ import { FirebaseRedirector, FirebaseRedirectConfig } from '../../../tools/fireb
const AIO_DIR = resolvePath(__dirname, '../../..');
export const PATH_TO_LEGACY_URLS = resolvePath(__dirname, 'URLS_TO_REDIRECT.txt');
export function getRedirector() {
return new FirebaseRedirector(loadRedirects());
@ -40,8 +41,7 @@ export function loadRedirects(): FirebaseRedirectConfig[] {
}
export function loadLegacyUrls() {
const pathToLegacyUrls = `${__dirname}/URLS_TO_REDIRECT.txt`;
const urls = readFileSync(pathToLegacyUrls, 'utf8')
const urls = readFileSync(PATH_TO_LEGACY_URLS, 'utf8')
.split('\n')
.filter(line => line.trim() !== '')
.map(line => line.split(/\s*-->\s*/));

View File

@ -1,4 +1,6 @@
import { getRedirector, loadLegacyUrls, loadLocalSitemapUrls, loadRedirects } from '../shared/helpers';
import {
getRedirector, loadLegacyUrls, loadLocalSitemapUrls, loadRedirects, PATH_TO_LEGACY_URLS,
} from '../shared/helpers';
describe('firebase.json redirect config', () => {
describe('with sitemap urls', () => {
@ -14,6 +16,14 @@ describe('firebase.json redirect config', () => {
describe('with legacy urls', () => {
const redirector = getRedirector();
afterAll(() => {
expect(redirector.unusedRedirectConfigs)
.withContext(
'Some redirect rules from \'firebase.json\' were not tested. ' +
`Ensure there is at least one testcase for each redirect rule in '${PATH_TO_LEGACY_URLS}'.`)
.toEqual([]);
});
loadLegacyUrls().forEach(urlPair => {
it(`should redirect legacy URL '${urlPair[0]}'`, () => {
const redirected = redirector.redirect(urlPair[0]);

View File

@ -6,7 +6,8 @@ export class FirebaseRedirect {
source: FirebaseRedirectSource;
destination: string;
constructor({source, regex, destination}: FirebaseRedirectConfig) {
constructor(readonly rawConfig: FirebaseRedirectConfig) {
const {source, regex, destination} = rawConfig;
this.source = (typeof source === 'string') ?
FirebaseRedirectSource.fromGlobPattern(source) :
FirebaseRedirectSource.fromRegexPattern(regex!);

View File

@ -39,4 +39,25 @@ describe('FirebaseRedirector', () => {
]);
expect(() => redirector.redirect('a')).toThrowError('infinite redirect loop');
});
it('should keep track of unused redirects', () => {
const redirects = [
{ source: '/a', destination: '/A' },
{ regex: '^/b$', destination: '/B' },
{ source: '/c', destination: '/C' },
];
const redirector = new FirebaseRedirector(redirects);
expect(redirector.unusedRedirectConfigs).toEqual([redirects[0], redirects[1], redirects[2]]);
redirector.redirect('/a');
expect(redirector.unusedRedirectConfigs).toEqual([redirects[1], redirects[2]]);
redirector.redirect('/not-redirected');
expect(redirector.unusedRedirectConfigs).toEqual([redirects[1], redirects[2]]);
redirector.redirect('/b');
redirector.redirect('/c');
expect(redirector.unusedRedirectConfigs).toEqual([]);
});
});

View File

@ -6,8 +6,15 @@ export type FirebaseRedirectConfig =
export class FirebaseRedirector {
private redirects: FirebaseRedirect[];
private unusedRedirects: Set<FirebaseRedirect>;
get unusedRedirectConfigs(): FirebaseRedirectConfig[] {
return [...this.unusedRedirects].map(({rawConfig}) => rawConfig);
}
constructor(redirects: FirebaseRedirectConfig[]) {
this.redirects = redirects.map(redirect => new FirebaseRedirect(redirect));
this.unusedRedirects = new Set(this.redirects);
}
redirect(url: string): string {
@ -28,6 +35,7 @@ export class FirebaseRedirector {
for (const redirect of this.redirects) {
const newUrl = redirect.replace(url);
if (newUrl !== undefined) {
this.unusedRedirects.delete(redirect);
return newUrl;
}
}