Skip to content

Commit 6d4e391

Browse files
generated tests
1 parent 57d1b15 commit 6d4e391

File tree

7 files changed

+571
-0
lines changed

7 files changed

+571
-0
lines changed
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
const { runExport } = require('../../../../../src/commands/export.js')
2+
const api = require('../../../../../src/helpers/api.js')
3+
const starting = require('../../../../../src/helpers/starting.js')
4+
const exportsHelpers = require('../../../../../src/helpers/exports.js')
5+
const common = require('../../../../../src/utils/common.js')
6+
const cmdPrint = require('../../../../../src/utils/cmdPrint.js')
7+
const legacy = require('../../../../../src/utils/legacy.js')
8+
9+
const fs = require('fs')
10+
const getArgsMock = jest.fn();
11+
jest.mock('fs')
12+
13+
const axios = require('axios')
14+
jest.mock('axios')
15+
16+
jest.mock('../../../../../src/utils/getArgs', () => jest.fn({}))
17+
18+
describe('runExport', () => {
19+
afterEach(() => {
20+
jest.resetAllMocks()
21+
})
22+
23+
test('testId exists and test already generated', async () => {
24+
const apiKey = 'testKey'
25+
const testId = 'test1'
26+
getArgsMock.mockReturnValueOnce({
27+
pythagora_api_key: apiKey,
28+
test_id: testId
29+
});
30+
// jest.mock('../../../../../src/utils/getArgs', () => ({
31+
// pythagora_api_key: apiKey,
32+
// test_id: testId
33+
// }))
34+
fs.readdirSync.mockReturnValue([])
35+
fs.readFileSync.mockReturnValue(JSON.stringify({ [testId]: { testName: 'testName.test.js' } }))
36+
exportsHelpers.testExists.mockReturnValue(true)
37+
38+
await runExport()
39+
40+
expect(cmdPrint.logAndExit).toHaveBeenCalledWith(`Test with id ${testId} already generated, you can find it here: ./${'./tests/generated/testName.test.js'}. If you want to generate it again delete old one first.`)
41+
})
42+
43+
test('testId exists but test not found', async () => {
44+
const apiKey = 'testKey'
45+
const testId = 'notfound'
46+
getArgsMock.mockReturnValueOnce({
47+
pythagora_api_key: apiKey,
48+
test_id: testId
49+
});
50+
// jest.mock('../../../../../src/utils/getArgs', () => ({
51+
// pythagora_api_key: apiKey,
52+
// test_id: testId
53+
// }))
54+
fs.readdirSync.mockReturnValue([])
55+
fs.readFileSync.mockReturnValue('{}')
56+
exportsHelpers.testExists.mockReturnValue(false)
57+
common.getAllGeneratedTests.mockReturnValue([])
58+
59+
await expect(runExport()).rejects.toThrow(`Test with id ${testId} not found`)
60+
})
61+
62+
test('testId not provided, OPTIONS method', async () => {
63+
const apiKey = 'testKey'
64+
const testId = undefined
65+
getArgsMock.mockReturnValueOnce({
66+
pythagora_api_key: apiKey,
67+
test_id: testId
68+
});
69+
// jest.mock('../../../../../src/utils/getArgs', () => ({
70+
// pythagora_api_key: apiKey,
71+
// test_id: testId
72+
// }))
73+
fs.readdirSync.mockReturnValue([])
74+
fs.readFileSync.mockReturnValue('{}')
75+
common.getAllGeneratedTests.mockReturnValue([{ method: 'OPTIONS', id: 'test1' }])
76+
77+
await runExport()
78+
79+
expect(exportsHelpers.testExists).not.toHaveBeenCalled()
80+
expect(legacy.convertOldTestForGPT).not.toHaveBeenCalled()
81+
expect(api.isEligibleForExport).not.toHaveBeenCalled()
82+
expect(exportsHelpers.exportTest).not.toHaveBeenCalled()
83+
expect(cmdPrint.testEligibleForExportLog).not.toHaveBeenCalled()
84+
})
85+
86+
test('testId not provided, test already generated', async () => {
87+
const apiKey = 'testKey'
88+
const testId = undefined
89+
getArgsMock.mockReturnValueOnce({
90+
pythagora_api_key: apiKey,
91+
test_id: testId
92+
});
93+
// jest.mock('../../../../../src/utils/getArgs', () => ({
94+
// pythagora_api_key: apiKey,
95+
// test_id: testId
96+
// }))
97+
fs.readdirSync.mockReturnValue([])
98+
fs.readFileSync.mockReturnValue(JSON.stringify({ test1: { testName: 'testName.test.js' } }))
99+
common.getAllGeneratedTests.mockReturnValue([{ method: 'GET', id: 'test1', endpoint: '/example' }])
100+
exportsHelpers.testExists.mockReturnValue(true)
101+
102+
await runExport()
103+
104+
expect(exportsHelpers.testExists).toHaveBeenCalledWith({ testName: 'testName.test.js' }, 'test1')
105+
expect(legacy.convertOldTestForGPT).not.toHaveBeenCalled()
106+
expect(api.isEligibleForExport).not.toHaveBeenCalled()
107+
expect(exportsHelpers.exportTest).not.toHaveBeenCalled()
108+
expect(cmdPrint.testEligibleForExportLog).not.toHaveBeenCalled()
109+
expect(console.log).toHaveBeenCalledWith(`Test with id test1 already generated, you can find it here: ./${'./tests/generated/testName.test.js'}.`)
110+
})
111+
112+
test('testId not provided, test not eligible for export', async () => {
113+
const apiKey = 'testKey'
114+
const testId = undefined
115+
const originalTest = { method: 'GET', id: 'test1', endpoint: '/example' }
116+
const convertedTest = { ...originalTest, testId: 'test1' }
117+
getArgsMock.mockReturnValueOnce({
118+
pythagora_api_key: apiKey,
119+
test_id: testId
120+
});
121+
// jest.mock('../../../../../src/utils/getArgs', () => ({
122+
// pythagora_api_key: apiKey,
123+
// test_id: testId
124+
// }))
125+
fs.readdirSync.mockReturnValue([])
126+
fs.readFileSync.mockReturnValue('{}')
127+
common.getAllGeneratedTests.mockReturnValue([originalTest])
128+
exportsHelpers.testExists.mockReturnValue(false)
129+
legacy.convertOldTestForGPT.mockReturnValue(convertedTest)
130+
api.isEligibleForExport.mockResolvedValue(false)
131+
132+
await runExport()
133+
134+
expect(exportsHelpers.testExists).toHaveBeenCalledWith({}, 'test1')
135+
expect(legacy.convertOldTestForGPT).toHaveBeenCalledWith(originalTest)
136+
expect(api.isEligibleForExport).toHaveBeenCalledWith(convertedTest)
137+
expect(exportsHelpers.exportTest).not.toHaveBeenCalled()
138+
expect(cmdPrint.testEligibleForExportLog).toHaveBeenCalledWith('/example', 'test1', false)
139+
})
140+
141+
test('testId not provided, test eligible for export', async () => {
142+
const apiKey = 'testKey'
143+
const testId = undefined
144+
const originalTest = { method: 'GET', id: 'test1', endpoint: '/example' }
145+
const convertedTest = { ...originalTest, testId: 'test1' }
146+
getArgsMock.mockReturnValueOnce({
147+
pythagora_api_key: apiKey,
148+
test_id: testId
149+
});
150+
// jest.mock('../../../../../src/utils/getArgs', () => ({
151+
// pythagora_api_key: apiKey,
152+
// test_id: testId
153+
// }))
154+
fs.readdirSync.mockReturnValue([])
155+
fs.readFileSync.mockReturnValue('{}')
156+
common.getAllGeneratedTests.mockReturnValue([originalTest])
157+
exportsHelpers.testExists.mockReturnValue(false)
158+
legacy.convertOldTestForGPT.mockReturnValue(convertedTest)
159+
api.isEligibleForExport.mockResolvedValue(true)
160+
exportsHelpers.exportTest.mockResolvedValue()
161+
162+
await runExport()
163+
164+
expect(exportsHelpers.testExists).toHaveBeenCalledWith({}, 'test1')
165+
expect(legacy.convertOldTestForGPT).toHaveBeenCalledWith(originalTest)
166+
expect(api.isEligibleForExport).toHaveBeenCalledWith(convertedTest)
167+
expect(exportsHelpers.exportTest).toHaveBeenCalledWith(originalTest, {})
168+
})
169+
})
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
describe('cleanupDataFolder', () => {
2+
const fs = require('fs');
3+
const path = require('path');
4+
const { cleanupDataFolder } = require('../../../../../src/helpers/exports.js');
5+
const { EXPORTED_TESTS_DIR, EXPORTED_TESTS_DATA_DIR } = require('../../../../../src/const/common');
6+
7+
test('should delete file from data folder if not existing in pythagora_tests folder', () => {
8+
jest.spyOn(fs, 'readdirSync').mockReturnValueOnce(['file1.json']);
9+
jest.spyOn(fs, 'existsSync').mockReturnValueOnce(false);
10+
const unlinkSyncSpy = jest.spyOn(fs, 'unlinkSync').mockImplementationOnce(jest.fn());
11+
12+
cleanupDataFolder();
13+
14+
expect(unlinkSyncSpy).toHaveBeenCalledWith(path.join(`./${EXPORTED_TESTS_DATA_DIR}`, 'file1.json'));
15+
});
16+
17+
test('should not delete file from data folder if existing in pythagora_tests folder', () => {
18+
jest.spyOn(fs, 'readdirSync').mockReturnValueOnce(['file2.json']);
19+
jest.spyOn(fs, 'existsSync').mockReturnValueOnce(true);
20+
const unlinkSyncSpy = jest.spyOn(fs, 'unlinkSync').mockImplementationOnce(jest.fn());
21+
22+
cleanupDataFolder();
23+
24+
expect(unlinkSyncSpy).not.toHaveBeenCalled();
25+
});
26+
27+
test('should not throw error if readdirSync fails', () => {
28+
jest.spyOn(fs, 'readdirSync').mockImplementationOnce(() => { throw new Error() });
29+
jest.spyOn(fs, 'existsSync');
30+
const unlinkSyncSpy = jest.spyOn(fs, 'unlinkSync');
31+
32+
expect(() => cleanupDataFolder()).not.toThrow();
33+
34+
expect(unlinkSyncSpy).not.toHaveBeenCalled();
35+
});
36+
37+
afterEach(() => {
38+
jest.restoreAllMocks();
39+
});
40+
});
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
describe('configureAuthFile tests', () => {
2+
const { configureAuthFile } = require('../../../../../src/helpers/exports.js');
3+
const { updateMetadata } = require('../../../../../src/utils/common.js');
4+
const fs = require('fs');
5+
const originalExit = process.exit;
6+
const originalConsoleLog = console.log;
7+
const originalWriteFileSync = fs.writeFileSync;
8+
9+
afterEach(() => {
10+
process.exit = originalExit;
11+
console.log = originalConsoleLog;
12+
fs.writeFileSync = originalWriteFileSync;
13+
});
14+
15+
test('configureAuthFile with valid loginPath and loginRequestBody, loginMongoQueries', async () => {
16+
const generatedTests = [
17+
{
18+
endpoint: '/test_login_path',
19+
method: 'POST',
20+
body: { key: 'value' },
21+
intermediateData: [{ type: 'mongodb' }]
22+
}
23+
];
24+
25+
const mockExit = jest.fn();
26+
process.exit = mockExit;
27+
28+
const mockConsoleLog = jest.fn();
29+
console.log = mockConsoleLog;
30+
31+
const mockWriteFileSync = jest.fn();
32+
fs.writeFileSync = mockWriteFileSync;
33+
34+
jest.mock('../../../../../src/helpers/api.js', () => ({
35+
getJestAuthFunction: () => Promise.resolve('mocked_gpt_response\n```\n\nmocked_gpt_response\n```')
36+
}));
37+
38+
jest.mock('../../../../../src/utils/common.js', () => ({
39+
...jest.requireActual('../../../../../src/utils/common.js'),
40+
updateMetadata: jest.fn()
41+
}));
42+
43+
await configureAuthFile(generatedTests);
44+
45+
expect(updateMetadata).toHaveBeenCalled();
46+
expect(mockExit).not.toHaveBeenCalled();
47+
expect(mockConsoleLog).not.toHaveBeenCalledWith(expect.stringContaining('To export test to Jest, Pythagora needs a captured test'));
48+
expect(mockWriteFileSync).toHaveBeenCalledWith(expect.stringMatching(/\/auth\.js$/), 'mocked_gpt_response');
49+
});
50+
51+
test('configureAuthFile without loginPath in metadata', async () => {
52+
const generatedTests = [];
53+
54+
const mockExit = jest.fn();
55+
process.exit = mockExit;
56+
57+
const mockConsoleLog = jest.fn();
58+
console.log = mockConsoleLog;
59+
60+
await configureAuthFile(generatedTests);
61+
62+
expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('Login endpoint path not found'));
63+
expect(mockExit).toHaveBeenCalledWith(1);
64+
});
65+
66+
test('configureAuthFile with loginPath but missing loginRequestBody or loginMongoQueries', async () => {
67+
const generatedTests = [
68+
{
69+
endpoint: '/missing_login_test',
70+
method: 'POST',
71+
}
72+
];
73+
74+
const mockExit = jest.fn();
75+
process.exit = mockExit;
76+
77+
const mockConsoleLog = jest.fn();
78+
console.log = mockConsoleLog;
79+
80+
await configureAuthFile(generatedTests);
81+
82+
expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('To export test to Jest, Pythagora needs a captured test'));
83+
expect(mockExit).toHaveBeenCalledWith(1);
84+
});
85+
});
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
describe('Create Default Files', () => {
2+
const fs = require('fs');
3+
const path = require('path');
4+
const { createDefaultFiles } = require('../../../../../src/helpers/exports.js');
5+
const args = ['--globalSetup', '../../jest-global-setup.js'];
6+
let generatedTests;
7+
beforeEach(() => {
8+
jest.resetModules();
9+
10+
const templatePath = path.join(__dirname, '../templates/jest-global-setup.js');
11+
const fsMock = {
12+
[src]: 'jest.config.js',
13+
[dst]: '',
14+
};
15+
16+
fs.readlink.mockImplementation((src, type) => {
17+
return fsMock[src];
18+
});
19+
20+
generatedTests = [
21+
{
22+
endpoint: '/api/login',
23+
method: 'POST',
24+
intermediateData: [],
25+
body: {},
26+
},
27+
];
28+
});
29+
30+
afterEach(() => {
31+
jest.clearAllMocks();
32+
});
33+
34+
test('Create jest-global-setup.js on first run', async () => {
35+
expect.assertions(1);
36+
fs.existsSync.mockReturnValue(false);
37+
await createDefaultFiles(generatedTests);
38+
expect(fs.copyFileSync).toHaveBeenCalledTimes(1);
39+
});
40+
41+
test('Skips copying default files on subsequent runs', async () => {
42+
expect.assertions(1);
43+
fs.existsSync.mockReturnValue(true);
44+
await createDefaultFiles(generatedTests);
45+
expect(fs.copyFileSync).toHaveBeenCalledTimes(0);
46+
});
47+
48+
test('Create jest.config.js if it does not exist', async () => {
49+
expect.assertions(2);
50+
fs.existsSync.mockReturnValue(false);
51+
await createDefaultFiles(generatedTests);
52+
expect(fs.copyFileSync).toHaveBeenCalledTimes(1);
53+
expect(fs.copyFileSync).toHaveBeenCalledWith(expect.any(String), './jest.config.js');
54+
});
55+
56+
test('Skips copying jest.config.js on subsequent runs', async () => {
57+
expect.assertions(2);
58+
fs.existsSync.mockReturnValue(true);
59+
await createDefaultFiles(generatedTests);
60+
expect(fs.copyFileSync).toHaveBeenCalledTimes(0);
61+
});
62+
63+
});

0 commit comments

Comments
 (0)