docusaurus/packages/docusaurus-plugin-content-blog/src/__tests__/authorsMap.test.ts
ozaki f356e29938
feat(blog): authors page (#10216)
Co-authored-by: OzakIOne <OzakIOne@users.noreply.github.com>
Co-authored-by: sebastien <lorber.sebastien@gmail.com>
Co-authored-by: slorber <slorber@users.noreply.github.com>
2024-08-01 17:30:49 +02:00

307 lines
7.7 KiB
TypeScript

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import path from 'path';
import {
type AuthorsMapInput,
checkAuthorsMapPermalinkCollisions,
getAuthorsMap,
validateAuthorsMap,
validateAuthorsMapInput,
} from '../authorsMap';
import type {AuthorsMap} from '@docusaurus/plugin-content-blog';
describe('checkAuthorsMapPermalinkCollisions', () => {
it('do not throw when permalinks are unique', () => {
const authors: AuthorsMap = {
author1: {
name: 'author1',
key: 'author1',
page: {
permalink: '/author1',
},
},
author2: {
name: 'author2',
key: 'author2',
page: {
permalink: '/author2',
},
},
};
expect(() => {
checkAuthorsMapPermalinkCollisions(authors);
}).not.toThrow();
});
it('throw when permalinks collide', () => {
const authors: AuthorsMap = {
author1: {
name: 'author1',
key: 'author1',
page: {
permalink: '/author1',
},
},
author2: {
name: 'author1',
key: 'author1',
page: {
permalink: '/author1',
},
},
};
expect(() => {
checkAuthorsMapPermalinkCollisions(authors);
}).toThrowErrorMatchingInlineSnapshot(`
"The following permalinks are duplicated:
Permalink: /author1
Authors: author1, author1"
`);
});
});
describe('getAuthorsMap', () => {
const fixturesDir = path.join(__dirname, '__fixtures__/authorsMapFiles');
const contentPaths = {
contentPathLocalized: fixturesDir,
contentPath: fixturesDir,
};
it('getAuthorsMap can read yml file', async () => {
await expect(
getAuthorsMap({
contentPaths,
authorsMapPath: 'authors.yml',
authorsBaseRoutePath: '/authors',
}),
).resolves.toBeDefined();
});
it('getAuthorsMap can read json file', async () => {
await expect(
getAuthorsMap({
contentPaths,
authorsMapPath: 'authors.json',
authorsBaseRoutePath: '/authors',
}),
).resolves.toBeDefined();
});
it('getAuthorsMap can return undefined if yaml file not found', async () => {
await expect(
getAuthorsMap({
contentPaths,
authorsMapPath: 'authors_does_not_exist.yml',
authorsBaseRoutePath: '/authors',
}),
).resolves.toBeUndefined();
});
});
describe('validateAuthorsMapInput', () => {
it('accept valid authors map', () => {
const authorsMap: AuthorsMapInput = {
slorber: {
name: 'Sébastien Lorber',
title: 'maintainer',
url: 'https://sebastienlorber.com',
imageURL: 'https://github.com/slorber.png',
key: 'slorber',
page: false,
},
yangshun: {
name: 'Yangshun Tay',
imageURL: 'https://github.com/yangshun.png',
randomField: 42,
key: 'yangshun',
page: false,
},
jmarcey: {
name: 'Joel',
title: 'creator of Docusaurus',
hello: new Date(),
key: 'jmarcey',
page: false,
},
};
expect(validateAuthorsMapInput(authorsMap)).toEqual(authorsMap);
});
it('rename snake case image_url to camelCase imageURL', () => {
const authorsMap: AuthorsMapInput = {
slorber: {
name: 'Sébastien Lorber',
image_url: 'https://github.com/slorber.png',
key: 'slorber',
page: false,
},
};
expect(validateAuthorsMapInput(authorsMap)).toEqual({
slorber: {
name: 'Sébastien Lorber',
imageURL: 'https://github.com/slorber.png',
page: false,
key: 'slorber',
},
});
});
it('accept author with only image', () => {
const authorsMap: AuthorsMapInput = {
slorber: {
imageURL: 'https://github.com/slorber.png',
url: 'https://github.com/slorber',
key: 'slorber',
page: false,
},
};
expect(validateAuthorsMapInput(authorsMap)).toEqual(authorsMap);
});
it('reject author without name or image', () => {
const authorsMap: AuthorsMapInput = {
slorber: {
title: 'foo',
key: 'slorber',
page: false,
},
};
expect(() =>
validateAuthorsMapInput(authorsMap),
).toThrowErrorMatchingInlineSnapshot(
`""slorber" must contain at least one of [name, imageURL]"`,
);
});
it('reject undefined author', () => {
expect(() =>
validateAuthorsMapInput({
slorber: undefined,
}),
).toThrowErrorMatchingInlineSnapshot(
`""slorber" cannot be undefined. It should be an author object containing properties like name, title, and imageURL."`,
);
});
it('reject null author', () => {
expect(() =>
validateAuthorsMapInput({
slorber: null,
}),
).toThrowErrorMatchingInlineSnapshot(
`""slorber" should be an author object containing properties like name, title, and imageURL."`,
);
});
it('reject array author', () => {
expect(() =>
validateAuthorsMapInput({slorber: []}),
).toThrowErrorMatchingInlineSnapshot(
`""slorber" should be an author object containing properties like name, title, and imageURL."`,
);
});
it('reject array content', () => {
expect(() =>
validateAuthorsMapInput([]),
).toThrowErrorMatchingInlineSnapshot(
`"The authors map file should contain an object where each entry contains an author key and the corresponding author's data."`,
);
});
it('reject flat author', () => {
expect(() =>
validateAuthorsMapInput({name: 'Sébastien'}),
).toThrowErrorMatchingInlineSnapshot(
`""name" should be an author object containing properties like name, title, and imageURL."`,
);
});
it('reject non-map author', () => {
const authorsMap: AuthorsMapInput = {
// @ts-expect-error: intentionally invalid
slorber: [],
};
expect(() =>
validateAuthorsMapInput(authorsMap),
).toThrowErrorMatchingInlineSnapshot(
`""slorber" should be an author object containing properties like name, title, and imageURL."`,
);
});
});
describe('authors socials', () => {
it('valid known author map socials', () => {
const authorsMap: AuthorsMapInput = {
ozaki: {
name: 'ozaki',
socials: {
twitter: 'ozakione',
github: 'ozakione',
},
key: 'ozaki',
page: false,
},
};
expect(validateAuthorsMap(authorsMap)).toEqual(authorsMap);
});
it('throw socials that are not strings', () => {
const authorsMap: AuthorsMapInput = {
ozaki: {
name: 'ozaki',
socials: {
// @ts-expect-error: for tests
twitter: 42,
},
},
};
expect(() =>
validateAuthorsMap(authorsMap),
).toThrowErrorMatchingInlineSnapshot(
`""ozaki.socials.twitter" must be a string"`,
);
});
it('throw socials that are objects', () => {
const authorsMap: AuthorsMapInput = {
ozaki: {
name: 'ozaki',
socials: {
// @ts-expect-error: for tests
twitter: {link: 'ozakione'},
},
},
};
expect(() =>
validateAuthorsMap(authorsMap),
).toThrowErrorMatchingInlineSnapshot(
`""ozaki.socials.twitter" must be a string"`,
);
});
it('valid unknown author map socials', () => {
const authorsMap: AuthorsMapInput = {
ozaki: {
name: 'ozaki',
socials: {
random: 'ozakione',
},
key: 'ozaki',
page: false,
},
};
expect(validateAuthorsMap(authorsMap)).toEqual(authorsMap);
});
});