Skip to content

Commit c41d9c1

Browse files
committed
test: add test for scanDiff fail
1 parent dacb516 commit c41d9c1

File tree

2 files changed

+225
-0
lines changed

2 files changed

+225
-0
lines changed
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
const path = require('path');
2+
const simpleGit = require('simple-git');
3+
const fs = require('fs').promises;
4+
const { Action } = require('../../src/proxy/actions');
5+
const { exec: getDiff } = require('../../src/proxy/processors/push-action/getDiff');
6+
const { exec: scanDiff } = require('../../src/proxy/processors/push-action/scanDiff');
7+
8+
const chai = require('chai');
9+
const expect = chai.expect;
10+
11+
describe('Force Push Integration Test', () => {
12+
let tempDir;
13+
let git;
14+
let initialCommitSHA;
15+
let rebasedCommitSHA;
16+
17+
before(async function () {
18+
this.timeout(10000); // eslint-disable-line no-invalid-this
19+
20+
tempDir = path.join(__dirname, '../temp-integration-repo');
21+
await fs.mkdir(tempDir, { recursive: true });
22+
git = simpleGit(tempDir);
23+
24+
await git.init();
25+
await git.addConfig('user.name', 'Test User');
26+
await git.addConfig('user.email', 'test@example.com');
27+
28+
// Create initial commit
29+
await fs.writeFile(path.join(tempDir, 'base.txt'), 'base content');
30+
await git.add('.');
31+
await git.commit('Initial commit');
32+
33+
// Create feature commit
34+
await fs.writeFile(path.join(tempDir, 'feature.txt'), 'feature content');
35+
await git.add('.');
36+
await git.commit('Add feature');
37+
38+
const log = await git.log();
39+
initialCommitSHA = log.latest.hash;
40+
41+
// Simulate rebase by amending commit (changes SHA)
42+
await git.commit(['--amend', '-m', 'Add feature (rebased)']);
43+
44+
const newLog = await git.log();
45+
rebasedCommitSHA = newLog.latest.hash;
46+
47+
console.log(`Initial SHA: ${initialCommitSHA}`);
48+
console.log(`Rebased SHA: ${rebasedCommitSHA}`);
49+
});
50+
51+
after(async () => {
52+
try {
53+
await fs.rmdir(tempDir, { recursive: true });
54+
} catch (e) {
55+
// Ignore cleanup errors
56+
}
57+
});
58+
59+
describe('Complete force push pipeline', () => {
60+
it('should handle legitimate empty diff after rebase scenario', async function () {
61+
this.timeout(5000); // eslint-disable-line no-invalid-this
62+
63+
// Create action simulating force push with old unreachable SHA
64+
const action = new Action(
65+
'force-push-integration',
66+
'push',
67+
'POST',
68+
Date.now(),
69+
'test/repo.git',
70+
);
71+
action.proxyGitPath = path.dirname(tempDir);
72+
action.repoName = path.basename(tempDir);
73+
action.commitFrom = initialCommitSHA; // Old SHA
74+
action.commitTo = rebasedCommitSHA; // New SHA after rebase
75+
action.commitData = [
76+
{
77+
parent: initialCommitSHA,
78+
commit: rebasedCommitSHA,
79+
message: 'Add feature (rebased)',
80+
author: 'Test User',
81+
},
82+
];
83+
84+
const afterGetDiff = await getDiff({}, action);
85+
expect(afterGetDiff.steps).to.have.length.greaterThan(0);
86+
87+
const diffStep = afterGetDiff.steps.find((s) => s.stepName === 'diff');
88+
expect(diffStep).to.exist;
89+
90+
// May produce empty diff or error - both should be handled
91+
if (diffStep.error) {
92+
console.log('getDiff failed as expected with unreachable commitFrom');
93+
expect(diffStep.errorMessage).to.be.a('string');
94+
} else {
95+
console.log('getDiff succeeded, checking content');
96+
expect(diffStep.content).to.satisfy(
97+
(content) => content === null || content === undefined || typeof content === 'string',
98+
);
99+
}
100+
101+
// scanDiff should not block on empty/missing diff
102+
const afterScanDiff = await scanDiff({}, afterGetDiff);
103+
const scanStep = afterScanDiff.steps.find((s) => s.stepName === 'scanDiff');
104+
105+
expect(scanStep).to.exist;
106+
107+
// scanDiff should NOT error on empty diff
108+
if (diffStep.error || !diffStep.content) {
109+
expect(scanStep.error).to.be.false;
110+
console.log('scanDiff correctly allowed empty/missing diff');
111+
} else {
112+
// If diff exists, should process normally
113+
expect(scanStep.error).to.be.false;
114+
console.log('scanDiff processed valid diff content');
115+
}
116+
});
117+
118+
it('should handle missing diff step gracefully', async function () {
119+
const action = new Action(
120+
'missing-diff-integration',
121+
'push',
122+
'POST',
123+
Date.now(),
124+
'test/repo.git',
125+
);
126+
127+
const result = await scanDiff({}, action);
128+
129+
expect(result.steps).to.have.length(1);
130+
expect(result.steps[0].stepName).to.equal('scanDiff');
131+
expect(result.steps[0].error).to.be.false;
132+
});
133+
});
134+
});

test/scanDiff.emptyDiff.test.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
const { Action } = require('../src/proxy/actions');
2+
const { exec } = require('../src/proxy/processors/push-action/scanDiff');
3+
4+
const chai = require('chai');
5+
const expect = chai.expect;
6+
7+
describe('scanDiff - Empty Diff Handling', () => {
8+
describe('Empty diff scenarios', () => {
9+
it('should allow empty diff (legitimate empty push)', async () => {
10+
const action = new Action('empty-diff-test', 'push', 'POST', Date.now(), 'test/repo.git');
11+
12+
// Simulate getDiff step with empty content
13+
const diffStep = { stepName: 'diff', content: '', error: false };
14+
action.steps = [diffStep];
15+
16+
const result = await exec({}, action);
17+
18+
expect(result.steps.length).to.equal(2); // diff step + scanDiff step
19+
expect(result.steps[1].error).to.be.false;
20+
expect(result.steps[1].errorMessage).to.be.null;
21+
});
22+
23+
it('should allow null diff', async () => {
24+
const action = new Action('null-diff-test', 'push', 'POST', Date.now(), 'test/repo.git');
25+
26+
// Simulate getDiff step with null content
27+
const diffStep = { stepName: 'diff', content: null, error: false };
28+
action.steps = [diffStep];
29+
30+
const result = await exec({}, action);
31+
32+
expect(result.steps.length).to.equal(2);
33+
expect(result.steps[1].error).to.be.false;
34+
expect(result.steps[1].errorMessage).to.be.null;
35+
});
36+
37+
it('should allow undefined diff', async () => {
38+
const action = new Action('undefined-diff-test', 'push', 'POST', Date.now(), 'test/repo.git');
39+
40+
// Simulate getDiff step with undefined content
41+
const diffStep = { stepName: 'diff', content: undefined, error: false };
42+
action.steps = [diffStep];
43+
44+
const result = await exec({}, action);
45+
46+
expect(result.steps.length).to.equal(2);
47+
expect(result.steps[1].error).to.be.false;
48+
expect(result.steps[1].errorMessage).to.be.null;
49+
});
50+
});
51+
52+
describe('Normal diff processing', () => {
53+
it('should process valid diff content without blocking', async () => {
54+
const action = new Action('valid-diff-test', 'push', 'POST', Date.now(), 'test/repo.git');
55+
action.project = 'test-org';
56+
57+
// Simulate normal diff content
58+
const normalDiff = `diff --git a/config.js b/config.js
59+
index 1234567..abcdefg 100644
60+
--- a/config.js
61+
+++ b/config.js
62+
@@ -1,3 +1,4 @@
63+
module.exports = {
64+
+ newFeature: true,
65+
database: "production"
66+
};`;
67+
68+
const diffStep = { stepName: 'diff', content: normalDiff, error: false };
69+
action.steps = [diffStep];
70+
71+
const result = await exec({}, action);
72+
73+
expect(result.steps[1].error).to.be.false;
74+
expect(result.steps[1].errorMessage).to.be.null;
75+
});
76+
});
77+
78+
describe('Error conditions', () => {
79+
it('should handle non-string diff content', async () => {
80+
const action = new Action('non-string-test', 'push', 'POST', Date.now(), 'test/repo.git');
81+
82+
const diffStep = { stepName: 'diff', content: 12345, error: false };
83+
action.steps = [diffStep];
84+
85+
const result = await exec({}, action);
86+
87+
expect(result.steps[1].error).to.be.true;
88+
expect(result.steps[1].errorMessage).to.include('non-string value');
89+
});
90+
});
91+
});

0 commit comments

Comments
 (0)