Skip to content

Commit 6c516a3

Browse files
authored
Merge pull request #1109 from andypols/add-get-repo-by-url
test: improve repo DB tests and CheckRepoInAuthList tests
2 parents 4a0fe55 + 767ca64 commit 6c516a3

File tree

6 files changed

+181
-64
lines changed

6 files changed

+181
-64
lines changed

src/db/file/repo.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ if (!fs.existsSync('./.data')) fs.mkdirSync('./.data');
1212
/* istanbul ignore if */
1313
if (!fs.existsSync('./.data/db')) fs.mkdirSync('./.data/db');
1414

15-
const db = new Datastore({ filename: './.data/db/repos.db', autoload: true });
15+
// export for testing purposes
16+
export const db = new Datastore({ filename: './.data/db/repos.db', autoload: true });
1617

1718
try {
1819
db.ensureIndex({ fieldName: 'url', unique: true });

src/proxy/processors/push-action/checkRepoInAuthorisedList.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,15 @@ import { getRepoByUrl } from '../../../db';
55
const exec = async (req: any, action: Action): Promise<Action> => {
66
const step = new Step('checkRepoInAuthorisedList');
77

8-
// console.log(found);
98
const found = (await getRepoByUrl(action.url)) !== null;
10-
11-
if (!found) {
12-
console.log(`Repository url '${action.url}' not found`);
9+
if (found) {
10+
step.log(`repo ${action.url} is in the authorisedList`);
11+
} else {
1312
step.error = true;
14-
step.log(`repo ${action.url} is not in the authorisedList, ending`);
15-
console.log('setting error');
16-
step.setError(`Rejecting repo ${action.url} not in the authorisedList`);
17-
action.addStep(step);
18-
return action;
13+
step.log(`repo ${action.url} is not in the authorised whitelist, ending`);
14+
step.setError(`Rejecting repo ${action.url} not in the authorised whitelist`);
1915
}
2016

21-
console.log('found');
22-
step.log(`repo ${action.url} is in the authorisedList`);
2317
action.addStep(step);
2418
return action;
2519
};

test/db/file/repo.test.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
const { expect } = require('chai');
2+
const sinon = require('sinon');
3+
const repoModule = require('../../../src/db/file/repo');
4+
5+
describe('File DB', () => {
6+
let sandbox;
7+
8+
beforeEach(() => {
9+
sandbox = sinon.createSandbox();
10+
});
11+
12+
afterEach(() => {
13+
sandbox.restore();
14+
});
15+
16+
describe('getRepo', () => {
17+
it('should get the repo using the name', async () => {
18+
const repoData = {
19+
name: 'sample',
20+
users: { canPush: [] },
21+
url: 'http://example.com/sample-repo.git',
22+
};
23+
24+
sandbox.stub(repoModule.db, 'findOne').callsFake((query, cb) => cb(null, repoData));
25+
26+
const result = await repoModule.getRepo('Sample');
27+
expect(result).to.deep.equal(repoData);
28+
});
29+
});
30+
31+
describe('getRepoByUrl', () => {
32+
it('should get the repo using the url', async () => {
33+
const repoData = {
34+
name: 'sample',
35+
users: { canPush: [] },
36+
url: 'https://github.com/finos/git-proxy.git',
37+
};
38+
39+
sandbox.stub(repoModule.db, 'findOne').callsFake((query, cb) => cb(null, repoData));
40+
41+
const result = await repoModule.getRepoByUrl('https://github.com/finos/git-proxy.git');
42+
expect(result).to.deep.equal(repoData);
43+
});
44+
it('should return null if the repo is not found', async () => {
45+
sandbox.stub(repoModule.db, 'findOne').callsFake((query, cb) => cb(null, null));
46+
47+
const result = await repoModule.getRepoByUrl('https://github.com/finos/missing-repo.git');
48+
expect(result).to.be.null;
49+
expect(
50+
repoModule.db.findOne.calledWith(
51+
sinon.match({ url: 'https://github.com/finos/missing-repo.git' }),
52+
),
53+
).to.be.true;
54+
});
55+
56+
it('should reject if the database returns an error', async () => {
57+
sandbox.stub(repoModule.db, 'findOne').callsFake((query, cb) => cb(new Error('DB error')));
58+
59+
try {
60+
await repoModule.getRepoByUrl('https://github.com/finos/git-proxy.git');
61+
expect.fail('Expected promise to be rejected');
62+
} catch (err) {
63+
expect(err.message).to.equal('DB error');
64+
}
65+
});
66+
});
67+
});

test/db/mongo/repo.test.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
const { expect } = require('chai');
2+
const sinon = require('sinon');
3+
const proxyqquire = require('proxyquire');
4+
5+
const repoCollection = {
6+
findOne: sinon.stub(),
7+
};
8+
9+
const connectionStub = sinon.stub().returns(repoCollection);
10+
11+
const { getRepo, getRepoByUrl } = proxyqquire('../../../src/db/mongo/repo', {
12+
'./helper': { connect: connectionStub },
13+
});
14+
15+
describe('MongoDB', () => {
16+
afterEach(function () {
17+
sinon.restore();
18+
});
19+
20+
describe('getRepo', () => {
21+
it('should get the repo using the name', async () => {
22+
const repoData = {
23+
name: 'sample',
24+
users: { canPush: [] },
25+
url: 'http://example.com/sample-repo.git',
26+
};
27+
repoCollection.findOne.resolves(repoData);
28+
29+
const result = await getRepo('Sample');
30+
expect(result).to.deep.equal(repoData);
31+
expect(connectionStub.calledWith('repos')).to.be.true;
32+
expect(repoCollection.findOne.calledWith({ name: { $eq: 'sample' } })).to.be.true;
33+
});
34+
});
35+
36+
describe('getRepoByUrl', () => {
37+
it('should get the repo using the url', async () => {
38+
const repoData = {
39+
name: 'sample',
40+
users: { canPush: [] },
41+
url: 'https://github.com/finos/git-proxy.git',
42+
};
43+
repoCollection.findOne.resolves(repoData);
44+
45+
const result = await getRepoByUrl('https://github.com/finos/git-proxy.git');
46+
expect(result).to.deep.equal(repoData);
47+
expect(connectionStub.calledWith('repos')).to.be.true;
48+
expect(
49+
repoCollection.findOne.calledWith({
50+
url: { $eq: 'https://github.com/finos/git-proxy.git' },
51+
}),
52+
).to.be.true;
53+
});
54+
});
55+
});
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
const chai = require('chai');
2+
const sinon = require('sinon');
3+
const fc = require('fast-check');
4+
const actions = require('../../src/proxy/actions/Action');
5+
const processor = require('../../src/proxy/processors/push-action/checkRepoInAuthorisedList');
6+
const expect = chai.expect;
7+
const db = require('../../src/db');
8+
9+
describe('Check a Repo is in the authorised list', async () => {
10+
afterEach(() => {
11+
sinon.restore();
12+
});
13+
14+
it('accepts the action if the repository is whitelisted in the db', async () => {
15+
sinon.stub(db, 'getRepoByUrl').resolves({
16+
name: 'repo-is-ok',
17+
project: 'thisproject',
18+
url: 'https://github.com/thisproject/repo-is-ok',
19+
});
20+
21+
const action = new actions.Action('123', 'type', 'get', 1234, 'thisproject/repo-is-ok');
22+
const result = await processor.exec(null, action);
23+
expect(result.error).to.be.false;
24+
expect(result.steps[0].logs[0]).to.eq(
25+
'checkRepoInAuthorisedList - repo thisproject/repo-is-ok is in the authorisedList',
26+
);
27+
});
28+
29+
it('rejects the action if repository not in the db', async () => {
30+
sinon.stub(db, 'getRepoByUrl').resolves(null);
31+
32+
const action = new actions.Action('123', 'type', 'get', 1234, 'thisproject/repo-is-not-ok');
33+
const result = await processor.exec(null, action);
34+
expect(result.error).to.be.true;
35+
expect(result.steps[0].logs[0]).to.eq(
36+
'checkRepoInAuthorisedList - repo thisproject/repo-is-not-ok is not in the authorised whitelist, ending',
37+
);
38+
});
39+
40+
describe('fuzzing', () => {
41+
it('should not crash on random repo names', async () => {
42+
await fc.assert(
43+
fc.asyncProperty(fc.string(), async (repoName) => {
44+
const action = new actions.Action('123', 'type', 'get', 1234, repoName);
45+
const result = await processor.exec(null, action);
46+
expect(result.error).to.be.true;
47+
}),
48+
{ numRuns: 1000 },
49+
);
50+
});
51+
});
52+
});

test/testCheckRepoInAuthList.test.js

Lines changed: 0 additions & 52 deletions
This file was deleted.

0 commit comments

Comments
 (0)