blob: 884b97fa322cfb9045897d2b17efabe2f6f1c603 [file] [log] [blame]
<!DOCTYPE html>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="../node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>
<script src="../bower_components/web-component-tester/browser.js"></script>
<title>code owners service test</title>
<script type="module">
import '../test/common-test-setup.js';
import {CodeOwnerService} from './code-owners-service.js';
suite('code owners service tests', () => {
let sandbox;
let codeOwnersService;
const fakeRestApi = {
get() {
return Promise.resolve({});
},
getLoggedIn() {
return Promise.resolve(undefined);
},
};
const getApiStub = sinon.stub(fakeRestApi, 'get');
getApiStub.returns(Promise.resolve({}));
const fakeStatus = {
// fake data with fake files
patch_set_number: 1,
file_code_owner_statuses: [
{
new_path_status: {
path: 'a.js',
status: 'INSUFFICIENT_REVIEWERS',
},
},
{
new_path_status: {
path: 'b.js',
status: 'INSUFFICIENT_REVIEWERS',
},
},
{
new_path_status: {
path: 'c.ts',
status: 'INSUFFICIENT_REVIEWERS',
},
},
{
change_type: 'RENAMED',
old_path_status: {
path: 'd.ts',
status: 'INSUFFICIENT_REVIEWERS',
},
new_path_status: {
path: 'd_edit.ts',
status: 'INSUFFICIENT_REVIEWERS',
},
},
{
new_path_status: {
path: 'e.ts',
status: 'PENDING',
},
},
{
new_path_status: {
path: 'f.ts',
status: 'PENDING',
},
},
{
new_path_status: {
path: 'g.ts',
status: 'PENDING',
},
},
],
};
const fakeChange = {
project: 'test',
branch: 'main',
_number: '123',
revisions: {
a: {
_number: 1,
},
},
current_revision: 'a',
};
setup(() => {
sandbox = sinon.sandbox.create();
getApiStub.reset();
});
teardown(() => { sandbox.restore(); });
suite('basic api request tests', () => {
setup(done => {
getApiStub.withArgs(`/changes/${fakeChange._number}/code_owners.status`)
.returns(Promise.resolve(fakeStatus));
codeOwnersService = CodeOwnerService.getOwnerService(fakeRestApi,
{...fakeChange});
flush(done);
});
test('getOwnerService - same change returns the same instance', () => {
assert.equal(
CodeOwnerService.getOwnerService(fakeRestApi, fakeChange),
CodeOwnerService.getOwnerService(fakeRestApi, fakeChange)
);
});
test('return a new instance when change changed', () => {
assert.notEqual(
CodeOwnerService.getOwnerService(fakeRestApi, {...fakeChange}),
CodeOwnerService.getOwnerService(fakeRestApi, {...fakeChange})
);
});
test('should fetch status after init', () => {
assert.isTrue(getApiStub.calledOnce);
assert.equal(getApiStub.lastCall.args[0],
`/changes/${fakeChange._number}/code_owners.status`);
});
test('getSuggestion should kickoff the fetch', done => {
codeOwnersService.getSuggestedOwners().then(r => {
// 6 requests for getting file owners + 1 status call
assert.equal(getApiStub.callCount, 7);
assert.equal(r.finished, false);
flush(() => {
assert.equal(getApiStub.callCount, 9);
done();
});
});
});
test('approved status calculation', done => {
codeOwnersService.areAllFilesApproved().then(approved => {
assert.equal(approved, false);
done();
});
});
});
suite('all approved case', () => {
setup(done => {
getApiStub.withArgs(`/changes/${fakeChange._number}/code_owners.status`)
.returns(Promise.resolve({
// fake data with fake files
patch_set_number: 1,
file_code_owner_statuses: [
{
new_path_status: {
path: 'a.js',
status: 'APPROVED',
},
},
{
new_path_status: {
path: 'b.js',
status: 'APPROVED',
},
},
{
old_path_status: {
path: 'd.js',
status: 'APPROVED',
},
change_type: 'DELETED',
},
],
}));
codeOwnersService = CodeOwnerService.getOwnerService(fakeRestApi,
{...fakeChange});
flush(done);
});
test('getSuggestion and finished in first batch', done => {
codeOwnersService.getSuggestedOwners().then(r => {
// 1 status call
assert.equal(getApiStub.callCount, 1);
// initially false as getSuggestedOwners is synchrously
assert.equal(r.finished, false);
codeOwnersService.getSuggestedOwners().then(nR => {
assert.equal(nR.finished, true);
done();
});
});
});
test('approved status calculation', done => {
codeOwnersService.areAllFilesApproved().then(approved => {
assert.equal(approved, true);
done();
});
});
});
suite('abort', () => {
setup(done => {
getApiStub.withArgs(`/changes/${fakeChange._number}/code_owners.status`)
.returns(Promise.resolve(fakeStatus));
codeOwnersService = CodeOwnerService.getOwnerService(fakeRestApi,
{...fakeChange});
flush(done);
});
test('abort should abort pending requests', done => {
codeOwnersService.getSuggestedOwners().then(r => {
// 6 requests for getting file owners + 1 status call
assert.equal(getApiStub.callCount, 7);
assert.equal(r.finished, false);
codeOwnersService.abort();
flush(() => {
// should still at 7 since aborted
assert.equal(getApiStub.callCount, 7);
done();
});
});
});
test('getSuggestedOwners should restart if aborted', done => {
codeOwnersService.abort();
codeOwnersService.getSuggestedOwners().then(r => {
// 6 requests for getting file owners + 1 status call
assert.equal(getApiStub.callCount, 7);
assert.equal(r.finished, false);
codeOwnersService.abort();
flush(() => {
codeOwnersService.getSuggestedOwners().then(r => {
// should at 13 since restarted
assert.equal(getApiStub.callCount, 13);
done();
});
});
});
});
});
});
</script>