|  | <!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> |