Skip to content

Commit

Permalink
feat: add tests for build tools script (asyncapi#3245)
Browse files Browse the repository at this point in the history
Co-authored-by: Ansh Goyal <[email protected]>
  • Loading branch information
vishvamsinh28 and anshgoyalevil authored Oct 3, 2024
1 parent 1ae0ca3 commit e56289b
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 18 deletions.
25 changes: 17 additions & 8 deletions scripts/build-tools.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
const { getData } = require('./tools/extract-tools-github');
const { convertTools } = require('./tools/tools-object');
const { combineTools } = require('./tools/combine-tools');
const manualTools = require('../config/tools-manual.json')

const fs = require('fs');
const { resolve } = require('path');

const buildTools = async () => {
const buildTools = async (automatedToolsPath, manualToolsPath, toolsPath, tagsPath) => {
try {
let githubExtractData = await getData();
let automatedTools = await convertTools(githubExtractData);

fs.writeFileSync(
resolve(__dirname, '../config', 'tools-automated.json'),
automatedToolsPath,
JSON.stringify(automatedTools, null, ' ')
);
await combineTools(automatedTools, manualTools);

await combineTools(automatedTools, require(manualToolsPath), toolsPath, tagsPath);
} catch (err) {
console.log(err);
throw err
throw new Error(`An error occurred while building tools: ${err.message}`);
}
};

buildTools();
/* istanbul ignore next */
if (require.main === module) {
const automatedToolsPath = resolve(__dirname, '../config', 'tools-automated.json');
const manualToolsPath = resolve(__dirname, '../config', 'tools-manual.json');
const toolsPath = resolve(__dirname, '../config', 'tools.json');
const tagsPath = resolve(__dirname, '../config', 'all-tags.json');

buildTools(automatedToolsPath, manualToolsPath, toolsPath, tagsPath);
}

module.exports = { buildTools };
13 changes: 3 additions & 10 deletions scripts/tools/combine-tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ const fs = require('fs')
const schema = require("./tools-schema.json");
const Ajv = require("ajv")
const addFormats = require("ajv-formats")
const { resolve } = require('path');
const Fuse = require("fuse.js");
const ajv = new Ajv()
addFormats(ajv, ["uri"])
Expand Down Expand Up @@ -106,7 +105,7 @@ const getFinalTool = async (toolObject) => {

// Combine the automated tools and manual tools list into single JSON object file, and
// lists down all the language and technology tags in one JSON file.
const combineTools = async (automatedTools, manualTools) => {
const combineTools = async (automatedTools, manualTools, toolsPath, tagsPath) => {
for (const key in automatedTools) {
let finalToolsList = [];
if (automatedTools[key].toolsList.length) {
Expand Down Expand Up @@ -136,14 +135,8 @@ const combineTools = async (automatedTools, manualTools) => {
finalToolsList.sort((tool, anotherTool) => tool.title.localeCompare(anotherTool.title));
finalTools[key].toolsList = finalToolsList
}
fs.writeFileSync(
resolve(__dirname, '../../config', 'tools.json'),
JSON.stringify(finalTools)
);
fs.writeFileSync(
resolve(__dirname, '../../config', 'all-tags.json'),
JSON.stringify({ languages: languageList, technologies: technologyList }),
)
fs.writeFileSync(toolsPath,JSON.stringify(finalTools));
fs.writeFileSync(tagsPath,JSON.stringify({ languages: languageList, technologies: technologyList }),)
}

module.exports = { combineTools }
89 changes: 89 additions & 0 deletions tests/build-tools.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
const axios = require('axios');
const { resolve } = require('path');
const { buildTools } = require('../scripts/build-tools');
const { tagsData, manualTools, mockConvertedData, mockExtractData } = require('../tests/fixtures/buildToolsData');
const fs = require('fs');

jest.mock('axios');
jest.mock('../scripts/tools/categorylist', () => ({
categoryList: [
{ name: 'Category1', description: 'Description for Category1' },
{ name: 'Category2', description: 'Description for Category2' }
]
}));

jest.mock('../scripts/tools/tags-color', () => ({
languagesColor: [
{ name: 'JavaScript', color: 'bg-[#f1e05a]', borderColor: 'border-[#f1e05a]' },
{ name: 'Python', color: 'bg-[#3572A5]', borderColor: 'border-[#3572A5]' }
],
technologiesColor: [
{ name: 'React', color: 'bg-[#61dafb]', borderColor: 'border-[#61dafb]' },
{ name: 'Node.js', color: 'bg-[#68a063]', borderColor: 'border-[#68a063]' }
]
}));

describe('buildTools', () => {
const testDir = resolve(__dirname, 'test_config');
const toolsPath = resolve(testDir, 'tools.json');
const tagsPath = resolve(testDir, 'all-tags.json');
const automatedToolsPath = resolve(testDir, 'tools-automated.json');
const manualToolsPath = resolve(testDir, 'tools-manual.json');

beforeAll(() => {
fs.mkdirSync(testDir, { recursive: true });
fs.writeFileSync(manualToolsPath, JSON.stringify(manualTools));
});

afterAll(() => {
fs.rmSync(testDir, { recursive: true, force: true });
});

beforeEach(() => {
jest.clearAllMocks();
});

it('should extract, convert, combine tools, and write to file', async () => {
axios.get.mockResolvedValue({ data: mockExtractData });

await buildTools(automatedToolsPath, manualToolsPath, toolsPath, tagsPath);

const automatedToolsContent = JSON.parse(fs.readFileSync(automatedToolsPath, 'utf8'));
const combinedToolsContent = JSON.parse(fs.readFileSync(toolsPath, 'utf8'));
const tagsContent = JSON.parse(fs.readFileSync(tagsPath, 'utf8'));

expect(Object.keys(automatedToolsContent)).toEqual(Object.keys(mockConvertedData));
expect(automatedToolsContent["Category1"].description).toEqual(mockConvertedData["Category1"].description);
expect(automatedToolsContent["Category2"].description).toEqual(mockConvertedData["Category2"].description);

expect(combinedToolsContent).toHaveProperty('Category1');
expect(combinedToolsContent).toHaveProperty('Category2');
expect(combinedToolsContent["Category1"].description).toEqual(mockConvertedData["Category1"].description);
expect(combinedToolsContent["Category2"].description).toEqual(mockConvertedData["Category2"].description);

expect(tagsContent).toEqual(tagsData);

});

it('should handle getData error', async () => {
axios.get.mockRejectedValue(new Error('Extract error'));

try {
await buildTools(automatedToolsPath, manualToolsPath, toolsPath, tagsPath);
} catch (err) {
expect(err.message).toContain('Extract error');
}
});

it('should handle file write errors', async () => {
axios.get.mockResolvedValue({ data: mockExtractData });

const invalidPath = '/invalid_dir/tools.json';

try {
await buildTools(invalidPath, manualToolsPath, toolsPath, tagsPath);
} catch (err) {
expect(err.message).toMatch(/ENOENT|EACCES/);
}
});
});
84 changes: 84 additions & 0 deletions tests/fixtures/buildToolsData.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
const tagsData = {
languages: [
{ name: 'JavaScript', color: 'bg-[#f1e05a]', borderColor: 'border-[#f1e05a]' },
{ name: 'Python', color: 'bg-[#3572A5]', borderColor: 'border-[#3572A5]' },
],
technologies: [
{ name: 'React', color: 'bg-[#61dafb]', borderColor: 'border-[#61dafb]' },
{ name: 'Node.js', color: 'bg-[#68a063]', borderColor: 'border-[#68a063]' },
],
};

const manualTools = [
{
title: "Manual Tool 1",
description: "Description for manual tool 1",
links: { repoUrl: "https://github.com/manual/tool1" },
filters: { categories: ["Category1"], language: "JavaScript", technology: ["React"] }
},
{
title: "Manual Tool 2",
description: "Description for manual tool 2",
links: { repoUrl: "https://github.com/manual/tool2" },
filters: { categories: ["Category2"], language: "Python", technology: ["Node.js"] }
},
];

const mockConvertedData = {
"Category1": {
description: "Description for Category1",
toolsList: [
{
title: "Tool 1",
description: "Description for tool 1",
links: { repoUrl: "https://github.com/tool1" },
filters: { categories: ["Category1"], language: "JavaScript", technology: ["React"] }
}
]
},
"Category2": {
description: "Description for Category2",
toolsList: [
{
title: "Tool 2",
description: "Description for tool 2",
links: { repoUrl: "https://github.com/tool2" },
filters: { categories: ["Category2"], language: "Python", technology: ["Node.js"] }
}
]
}
};

const mockExtractData = {
items: [
{
name: '.asyncapi-tool',
url: 'https://api.github.com/repositories/123456/contents/.asyncapi-tool?ref=abcdef',
repository: {
full_name: 'user/repo1',
html_url: 'https://github.com/user/repo1',
description: 'Description for repo1',
owner: { login: 'asyncapi' }
},
path: '.asyncapi-tool'
},
{
name: '.asyncapi-tool',
url: 'https://api.github.com/repositories/789012/contents/.asyncapi-tool?ref=ghijkl',
repository: {
full_name: 'user/repo2',
html_url: 'https://github.com/user/repo2',
description: 'Description for repo2',
owner: { login: 'asyncapi' }
},
path: '.asyncapi-tool'
}
]
};

module.exports = {
tagsData,
manualTools,
mockConvertedData,
mockExtractData,
};

0 comments on commit e56289b

Please sign in to comment.