|  | <!DOCTYPE html> | 
|  | <!-- | 
|  | @license | 
|  | Copyright (C) 2017 The Android Open Source Project | 
|  |  | 
|  | Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | you may not use this file except in compliance with the License. | 
|  | You may obtain a copy of the License at | 
|  |  | 
|  | http://www.apache.org/licenses/LICENSE-2.0 | 
|  |  | 
|  | Unless required by applicable law or agreed to in writing, software | 
|  | distributed under the License is distributed on an "AS IS" BASIS, | 
|  | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | See the License for the specific language governing permissions and | 
|  | limitations under the License. | 
|  | --> | 
|  |  | 
|  | <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"> | 
|  | <title>gr-repo</title> | 
|  |  | 
|  | <script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script> | 
|  | <script src="../../../bower_components/web-component-tester/browser.js"></script> | 
|  | <link rel="import" href="../../../test/common-test-setup.html"/> | 
|  | <link rel="import" href="gr-repo.html"> | 
|  |  | 
|  | <script>void(0);</script> | 
|  |  | 
|  | <test-fixture id="basic"> | 
|  | <template> | 
|  | <gr-repo></gr-repo> | 
|  | </template> | 
|  | </test-fixture> | 
|  |  | 
|  | <script> | 
|  | suite('gr-repo tests', () => { | 
|  | let element; | 
|  | let sandbox; | 
|  | let repoStub; | 
|  | const repoConf = { | 
|  | description: 'Access inherited by all other projects.', | 
|  | use_contributor_agreements: { | 
|  | value: false, | 
|  | configured_value: 'FALSE', | 
|  | }, | 
|  | use_content_merge: { | 
|  | value: false, | 
|  | configured_value: 'FALSE', | 
|  | }, | 
|  | use_signed_off_by: { | 
|  | value: false, | 
|  | configured_value: 'FALSE', | 
|  | }, | 
|  | create_new_change_for_all_not_in_target: { | 
|  | value: false, | 
|  | configured_value: 'FALSE', | 
|  | }, | 
|  | require_change_id: { | 
|  | value: false, | 
|  | configured_value: 'FALSE', | 
|  | }, | 
|  | enable_signed_push: { | 
|  | value: false, | 
|  | configured_value: 'FALSE', | 
|  | }, | 
|  | require_signed_push: { | 
|  | value: false, | 
|  | configured_value: 'FALSE', | 
|  | }, | 
|  | reject_implicit_merges: { | 
|  | value: false, | 
|  | configured_value: 'FALSE', | 
|  | }, | 
|  | private_by_default: { | 
|  | value: false, | 
|  | configured_value: 'FALSE', | 
|  | }, | 
|  | match_author_to_committer_date: { | 
|  | value: false, | 
|  | configured_value: 'FALSE', | 
|  | }, | 
|  | reject_empty_commit: { | 
|  | value: false, | 
|  | configured_value: 'FALSE', | 
|  | }, | 
|  | enable_reviewer_by_email: { | 
|  | value: false, | 
|  | configured_value: 'FALSE', | 
|  | }, | 
|  | max_object_size_limit: {}, | 
|  | submit_type: 'MERGE_IF_NECESSARY', | 
|  | default_submit_type: { | 
|  | value: 'MERGE_IF_NECESSARY', | 
|  | configured_value: 'INHERIT', | 
|  | inherited_value: 'MERGE_IF_NECESSARY', | 
|  | }, | 
|  | }; | 
|  |  | 
|  | const REPO = 'test-repo'; | 
|  | const SCHEMES = {http: {}, repo: {}, ssh: {}}; | 
|  |  | 
|  | function getFormFields() { | 
|  | const selects = Polymer.dom(element.root).querySelectorAll('select'); | 
|  | const textareas = | 
|  | Polymer.dom(element.root).querySelectorAll('iron-autogrow-textarea'); | 
|  | const inputs = Polymer.dom(element.root).querySelectorAll('input'); | 
|  | return inputs.concat(textareas).concat(selects); | 
|  | } | 
|  |  | 
|  | setup(() => { | 
|  | sandbox = sinon.sandbox.create(); | 
|  | stub('gr-rest-api-interface', { | 
|  | getLoggedIn() { return Promise.resolve(false); }, | 
|  | getConfig() { | 
|  | return Promise.resolve({download: {}}); | 
|  | }, | 
|  | }); | 
|  | element = fixture('basic'); | 
|  | repoStub = sandbox.stub(element.$.restAPI, 'getProjectConfig', () => { | 
|  | return Promise.resolve(repoConf); | 
|  | }); | 
|  | }); | 
|  |  | 
|  | teardown(() => { | 
|  | sandbox.restore(); | 
|  | }); | 
|  |  | 
|  | test('_computePluginData', () => { | 
|  | assert.deepEqual(element._computePluginData(), []); | 
|  | assert.deepEqual(element._computePluginData({}), []); | 
|  | assert.deepEqual(element._computePluginData({base: {}}), []); | 
|  | assert.deepEqual(element._computePluginData({base: {plugin: 'data'}}), | 
|  | [{name: 'plugin', config: 'data'}]); | 
|  | }); | 
|  |  | 
|  | test('_handlePluginConfigChanged', () => { | 
|  | const notifyStub = sandbox.stub(element, 'notifyPath'); | 
|  | element._repoConfig = {plugin_config: {}}; | 
|  | element._handlePluginConfigChanged({detail: { | 
|  | name: 'test', | 
|  | config: 'data', | 
|  | notifyPath: 'path', | 
|  | }}); | 
|  | flushAsynchronousOperations(); | 
|  |  | 
|  | assert.equal(element._repoConfig.plugin_config.test, 'data'); | 
|  | assert.equal(notifyStub.lastCall.args[0], | 
|  | '_repoConfig.plugin_config.path'); | 
|  | }); | 
|  |  | 
|  | test('loading displays before repo config is loaded', () => { | 
|  | assert.isTrue(element.$.loading.classList.contains('loading')); | 
|  | assert.isFalse(getComputedStyle(element.$.loading).display === 'none'); | 
|  | assert.isTrue(element.$.loadedContent.classList.contains('loading')); | 
|  | assert.isTrue(getComputedStyle(element.$.loadedContent) | 
|  | .display === 'none'); | 
|  | }); | 
|  |  | 
|  | test('download commands visibility', () => { | 
|  | element._loading = false; | 
|  | flushAsynchronousOperations(); | 
|  | assert.isTrue(element.$.downloadContent.classList.contains('hide')); | 
|  | assert.isTrue(getComputedStyle(element.$.downloadContent) | 
|  | .display == 'none'); | 
|  | element._schemesObj = SCHEMES; | 
|  | flushAsynchronousOperations(); | 
|  | assert.isFalse(element.$.downloadContent.classList.contains('hide')); | 
|  | assert.isFalse(getComputedStyle(element.$.downloadContent) | 
|  | .display == 'none'); | 
|  | }); | 
|  |  | 
|  | test('form defaults to read only', () => { | 
|  | assert.isTrue(element._readOnly); | 
|  | }); | 
|  |  | 
|  | test('form defaults to read only when not logged in', done => { | 
|  | element.repo = REPO; | 
|  | element._loadRepo().then(() => { | 
|  | assert.isTrue(element._readOnly); | 
|  | done(); | 
|  | }); | 
|  | }); | 
|  |  | 
|  | test('form defaults to read only when logged in and not admin', done => { | 
|  | element.repo = REPO; | 
|  | sandbox.stub(element, '_getLoggedIn', () => { | 
|  | return Promise.resolve(true); | 
|  | }); | 
|  | sandbox.stub(element.$.restAPI, 'getRepoAccess', () => { | 
|  | return Promise.resolve({'test-repo': {}}); | 
|  | }); | 
|  | element._loadRepo().then(() => { | 
|  | assert.isTrue(element._readOnly); | 
|  | done(); | 
|  | }); | 
|  | }); | 
|  |  | 
|  | test('all form elements are disabled when not admin', done => { | 
|  | element.repo = REPO; | 
|  | element._loadRepo().then(() => { | 
|  | flushAsynchronousOperations(); | 
|  | const formFields = getFormFields(); | 
|  | for (const field of formFields) { | 
|  | assert.isTrue(field.hasAttribute('disabled')); | 
|  | } | 
|  | done(); | 
|  | }); | 
|  | }); | 
|  |  | 
|  | test('_formatBooleanSelect', () => { | 
|  | let item = {inherited_value: true}; | 
|  | assert.deepEqual(element._formatBooleanSelect(item), [ | 
|  | { | 
|  | label: 'Inherit (true)', | 
|  | value: 'INHERIT', | 
|  | }, | 
|  | { | 
|  | label: 'True', | 
|  | value: 'TRUE', | 
|  | }, { | 
|  | label: 'False', | 
|  | value: 'FALSE', | 
|  | }, | 
|  | ]); | 
|  |  | 
|  | item = {inherited_value: false}; | 
|  | assert.deepEqual(element._formatBooleanSelect(item), [ | 
|  | { | 
|  | label: 'Inherit (false)', | 
|  | value: 'INHERIT', | 
|  | }, | 
|  | { | 
|  | label: 'True', | 
|  | value: 'TRUE', | 
|  | }, { | 
|  | label: 'False', | 
|  | value: 'FALSE', | 
|  | }, | 
|  | ]); | 
|  |  | 
|  | // For items without inherited values | 
|  | item = {}; | 
|  | assert.deepEqual(element._formatBooleanSelect(item), [ | 
|  | { | 
|  | label: 'Inherit', | 
|  | value: 'INHERIT', | 
|  | }, | 
|  | { | 
|  | label: 'True', | 
|  | value: 'TRUE', | 
|  | }, { | 
|  | label: 'False', | 
|  | value: 'FALSE', | 
|  | }, | 
|  | ]); | 
|  | }); | 
|  |  | 
|  | test('fires page-error', done => { | 
|  | repoStub.restore(); | 
|  |  | 
|  | element.repo = 'test'; | 
|  |  | 
|  | const response = {status: 404}; | 
|  | sandbox.stub( | 
|  | element.$.restAPI, 'getProjectConfig', (repo, errFn) => { | 
|  | errFn(response); | 
|  | }); | 
|  | element.addEventListener('page-error', e => { | 
|  | assert.deepEqual(e.detail.response, response); | 
|  | done(); | 
|  | }); | 
|  |  | 
|  | element._loadRepo(); | 
|  | }); | 
|  |  | 
|  | suite('admin', () => { | 
|  | setup(() => { | 
|  | element.repo = REPO; | 
|  | sandbox.stub(element, '_getLoggedIn', () => { | 
|  | return Promise.resolve(true); | 
|  | }); | 
|  | sandbox.stub(element.$.restAPI, 'getRepoAccess', () => { | 
|  | return Promise.resolve({'test-repo': {is_owner: true}}); | 
|  | }); | 
|  | }); | 
|  |  | 
|  | test('all form elements are enabled', done => { | 
|  | element._loadRepo().then(() => { | 
|  | flushAsynchronousOperations(); | 
|  | const formFields = getFormFields(); | 
|  | for (const field of formFields) { | 
|  | assert.isFalse(field.hasAttribute('disabled')); | 
|  | } | 
|  | assert.isFalse(element._loading); | 
|  | done(); | 
|  | }); | 
|  | }); | 
|  |  | 
|  | test('state gets set correctly', done => { | 
|  | element._loadRepo().then(() => { | 
|  | assert.equal(element._repoConfig.state, 'ACTIVE'); | 
|  | assert.equal(element.$.stateSelect.bindValue, 'ACTIVE'); | 
|  | done(); | 
|  | }); | 
|  | }); | 
|  |  | 
|  | test('inherited submit type value is calculated correctly', () => { | 
|  | return element._loadRepo().then(() => { | 
|  | const sel = element.$.submitTypeSelect; | 
|  | assert.equal(sel.bindValue, 'INHERIT'); | 
|  | assert.equal( | 
|  | sel.nativeSelect.options[0].text, 'Inherit (Merge if necessary)'); | 
|  | }); | 
|  | }); | 
|  |  | 
|  | test('fields update and save correctly', () => { | 
|  | const configInputObj = { | 
|  | description: 'new description', | 
|  | use_contributor_agreements: 'TRUE', | 
|  | use_content_merge: 'TRUE', | 
|  | use_signed_off_by: 'TRUE', | 
|  | create_new_change_for_all_not_in_target: 'TRUE', | 
|  | require_change_id: 'TRUE', | 
|  | enable_signed_push: 'TRUE', | 
|  | require_signed_push: 'TRUE', | 
|  | reject_implicit_merges: 'TRUE', | 
|  | private_by_default: 'TRUE', | 
|  | match_author_to_committer_date: 'TRUE', | 
|  | reject_empty_commit: 'TRUE', | 
|  | max_object_size_limit: 10, | 
|  | submit_type: 'FAST_FORWARD_ONLY', | 
|  | state: 'READ_ONLY', | 
|  | enable_reviewer_by_email: 'TRUE', | 
|  | }; | 
|  |  | 
|  | const saveStub = sandbox.stub(element.$.restAPI, 'saveRepoConfig' | 
|  | , () => { | 
|  | return Promise.resolve({}); | 
|  | }); | 
|  |  | 
|  | const button = Polymer.dom(element.root).querySelector('gr-button'); | 
|  |  | 
|  | return element._loadRepo().then(() => { | 
|  | assert.isTrue(button.hasAttribute('disabled')); | 
|  | assert.isFalse(element.$.Title.classList.contains('edited')); | 
|  | element.$.descriptionInput.bindValue = configInputObj.description; | 
|  | element.$.stateSelect.bindValue = configInputObj.state; | 
|  | element.$.submitTypeSelect.bindValue = configInputObj.submit_type; | 
|  | element.$.contentMergeSelect.bindValue = | 
|  | configInputObj.use_content_merge; | 
|  | element.$.newChangeSelect.bindValue = | 
|  | configInputObj.create_new_change_for_all_not_in_target; | 
|  | element.$.requireChangeIdSelect.bindValue = | 
|  | configInputObj.require_change_id; | 
|  | element.$.enableSignedPush.bindValue = | 
|  | configInputObj.enable_signed_push; | 
|  | element.$.requireSignedPush.bindValue = | 
|  | configInputObj.require_signed_push; | 
|  | element.$.rejectImplicitMergesSelect.bindValue = | 
|  | configInputObj.reject_implicit_merges; | 
|  | element.$.setAllnewChangesPrivateByDefaultSelect.bindValue = | 
|  | configInputObj.private_by_default; | 
|  | element.$.matchAuthoredDateWithCommitterDateSelect.bindValue = | 
|  | configInputObj.match_author_to_committer_date; | 
|  | element.$.maxGitObjSizeInput.bindValue = | 
|  | configInputObj.max_object_size_limit; | 
|  | element.$.contributorAgreementSelect.bindValue = | 
|  | configInputObj.use_contributor_agreements; | 
|  | element.$.useSignedOffBySelect.bindValue = | 
|  | configInputObj.use_signed_off_by; | 
|  | element.$.rejectEmptyCommitSelect.bindValue = | 
|  | configInputObj.reject_empty_commit; | 
|  | element.$.unRegisteredCcSelect.bindValue = | 
|  | configInputObj.enable_reviewer_by_email; | 
|  |  | 
|  | assert.isFalse(button.hasAttribute('disabled')); | 
|  | assert.isTrue(element.$.configurations.classList.contains('edited')); | 
|  |  | 
|  | const formattedObj = | 
|  | element._formatRepoConfigForSave(element._repoConfig); | 
|  | assert.deepEqual(formattedObj, configInputObj); | 
|  |  | 
|  | return element._handleSaveRepoConfig().then(() => { | 
|  | assert.isTrue(button.hasAttribute('disabled')); | 
|  | assert.isFalse(element.$.Title.classList.contains('edited')); | 
|  | assert.isTrue(saveStub.lastCall.calledWithExactly(REPO, | 
|  | configInputObj)); | 
|  | }); | 
|  | }); | 
|  | }); | 
|  | }); | 
|  | }); | 
|  | </script> |