const glob = require('glob-promise');
const visit = require('unist-util-visit');
-it('should not have any broken link', async () => {
- const root = path.resolve(__dirname + '/..');
- const files = await glob(root + '/pages/**/*.md')
- .then(files => files.map(file => file.substr(root.length + 1)))
- .then(files =>
- files.map(file => ({
- path: file.slice(0, -3),
- content: handleIncludes(fs.readFileSync(root + '/' + file, 'utf8'), root)
- }))
- );
+const rootPath = path.resolve(path.join(__dirname, '/..'));
+let files, parsedFiles;
- const parsedFiles = files.map(file => {
+beforeAll(async () => {
+ files = await loadGlobFiles('/pages/**/*.md');
+ parsedFiles = files.map(file => {
return { ...separateFrontMatter(file.content), path: file.path };
});
+});
+it('should have valid links in trees files', () => {
const trees = [
'SonarCloudNavigationTree.json',
'SonarQubeNavigationTree.json',
'StaticNavigationTree.json'
];
+ let hasErrors = false;
trees.forEach(file => {
- const tree = JSON.parse(fs.readFileSync(root + '/../static/' + file, 'utf8'));
+ const tree = JSON.parse(fs.readFileSync(path.join(rootPath, '..', 'static', file), 'utf8'));
tree.forEach(leaf => {
if (typeof leaf === 'object') {
if (leaf.children) {
leaf.children.forEach(child => {
// Check children markdown file path validity
- const result = urlExists(parsedFiles, child);
- if (!result) {
- // Display custom error message
- console.log('[', child, '] is not a valid link, in ', file);
+ if (!urlExists(parsedFiles, child)) {
+ console.log('[', child, '] is not a valid link, in', file);
+ hasErrors = true;
}
- expect(result).toBeTruthy();
});
}
} else {
// Check markdown file path validity
- const result = urlExists(parsedFiles, leaf);
- if (!result) {
- console.log('[', leaf, '] is not a valid link, in ', file);
+ if (!urlExists(parsedFiles, leaf)) {
+ console.log('[', leaf, '] is not a valid link, in', file);
+ hasErrors = true;
}
- expect(result).toBeTruthy();
}
});
});
+ expect(hasErrors).toBeFalsy();
+});
+
+it('should have valid links in suggestions file', () => {
+ const file = 'EmbedDocsSuggestions.json';
+ const suggestions = JSON.parse(fs.readFileSync(path.join(rootPath, file), 'utf8'));
+ let hasErrors = false;
+ Object.keys(suggestions).forEach(key => {
+ suggestions[key].forEach(suggestion => {
+ if (!suggestion.link.startsWith('/documentation/')) {
+ console.log('[', suggestion.link, '] should starts with "/documentation/", in', file);
+ hasErrors = true;
+ } else if (!urlExists(parsedFiles, suggestion.link.replace('/documentation', ''))) {
+ console.log('[', suggestion.link, '] is not a valid link, in', file);
+ hasErrors = true;
+ }
+ });
+ });
+ expect(hasErrors).toBeFalsy();
+});
- // Check if all url tag in frontmatter are valid and uniques
+it('should have valid and uniq links in url metadata field', () => {
let urlLists = [];
- parsedFiles.map(file => {
- let result = file.frontmatter.url;
- if (!result) {
+ let hasErrors = false;
+ parsedFiles.forEach(file => {
+ if (!file.frontmatter.url) {
console.log('[', file.path, '] has no url metadata');
+ hasErrors = true;
+ } else if (!checkUrlFormat(file.frontmatter.url, file.path)) {
+ hasErrors = true;
+ } else if (urlLists.includes(file.frontmatter.url)) {
+ console.log('[', file.path, '] has an url that is not unique', file.frontmatter.url);
+ hasErrors = true;
}
- expect(result).toBeTruthy();
- result = file.frontmatter.url.startsWith('/');
- if (!result) {
- console.log('[', file.path, '] should starts with a slash ', file.frontmatter.url);
- }
- expect(result).toBeTruthy();
+ urlLists = [...urlLists, file.frontmatter.url];
+ });
+ expect(hasErrors).toBeFalsy();
+});
- result = file.frontmatter.url.endsWith('/');
- if (!result) {
- console.log('[', file.path, '] should ends with a slash ', file.frontmatter.url);
- }
- expect(result).toBeTruthy();
+it('should have valid links pointing to documentation inside pages', () => {
+ checkContentUrl(parsedFiles);
+});
- result = !urlLists.includes(file.frontmatter.url);
- if (!result) {
- console.log('[', file.path, '] has an url that is not unique ', file.frontmatter.url);
- }
- expect(result).toBeTruthy();
+it('should have valid links inside tooltips', async () => {
+ const files = await loadGlobFiles('/tooltips/**/*.md');
+ checkContentUrl(files);
+});
- urlLists = [...urlLists, file.frontmatter.url];
+function handleIncludes(content, rootPath) {
+ return content.replace(/@include (.+)/, (match, p) => {
+ const filePath = path.join(rootPath, '..', `${p}.md`);
+ return fs.readFileSync(filePath, 'utf8');
});
+}
- parsedFiles.map(file => {
- const ast = remark().parse(file.content);
- visit(ast, node => {
+function checkContentUrl(files) {
+ let hasErrors = false;
+ files.forEach(file => {
+ visit(remark().parse(file.content), node => {
if (node.type === 'image' && !node.url.startsWith('http')) {
// Check image path validity
- const result = fs.existsSync(root + '/' + node.url);
- if (!result) {
- console.log('[', node.url, '] is not a valid image path, in ', file.path + '.md');
+ if (!fs.existsSync(path.join(rootPath, node.url))) {
+ console.log('[', node.url, '] is not a valid image path, in', file.path + '.md');
+ hasErrors = true;
}
- expect(result).toBeTruthy();
} else if (
node.type === 'link' &&
!node.url.startsWith('http') &&
!node.url.startsWith('/#')
) {
// Check markdown file path validity
- const result = urlExists(parsedFiles, node.url);
- if (!result) {
- console.log('[', node.url, '] is not a valid link, in ', file.path + '.md');
+ if (!urlExists(parsedFiles, node.url)) {
+ console.log('[', node.url, '] is not a valid link, in', file.path + '.md');
+ hasErrors = true;
}
- expect(result).toBeTruthy();
}
});
});
- expect(true).toBeTruthy();
-});
+ expect(hasErrors).toBeFalsy();
+}
function urlExists(files, url) {
return files.find(f => f.frontmatter.url === url) !== undefined;
}
-function handleIncludes(content, root) {
- return content.replace(/@include (.+)/, (match, p) => {
- const filePath = path.join(root, '..', `${p}.md`);
- return fs.readFileSync(filePath, 'utf8');
- });
+function checkUrlFormat(url, file) {
+ const noError = true;
+
+ if (!url.startsWith('/')) {
+ console.log('[', file, '] should starts with a slash', url);
+ noError = false;
+ }
+ if (!url.endsWith('/')) {
+ console.log('[', file, '] should ends with a slash', url);
+ noError = false;
+ }
+ return noError;
+}
+
+function loadGlobFiles(globPath) {
+ return glob(path.join(rootPath, globPath))
+ .then(files => files.map(file => file.substr(rootPath.length + 1)))
+ .then(files =>
+ files.map(file => ({
+ path: file.slice(0, -3),
+ content: handleIncludes(fs.readFileSync(path.join(rootPath, file), 'utf8'), rootPath)
+ }))
+ );
}
function getFrontMatterPosition(lines) {