diff options
author | Lukas Eipert <leipert@gitlab.com> | 2018-05-07 18:21:34 +0000 |
---|---|---|
committer | Clement Ho <clemmakesapps@gmail.com> | 2018-05-07 18:21:34 +0000 |
commit | 5e436de6e4137494710d0f3f4ac5610f4f35e6a6 (patch) | |
tree | 7970cd8838fbac7acd3a74be40b365a7de16b75f /spec/javascripts/deploy_keys | |
parent | 924ea97aab21ba265634aca11d36f37210de8442 (diff) | |
download | gitlab-ce-5e436de6e4137494710d0f3f4ac5610f4f35e6a6.tar.gz |
Make deploy keys table more clearly structured
Diffstat (limited to 'spec/javascripts/deploy_keys')
4 files changed, 184 insertions, 150 deletions
diff --git a/spec/javascripts/deploy_keys/components/action_btn_spec.js b/spec/javascripts/deploy_keys/components/action_btn_spec.js index 7025c3d836c..5bf72cc0018 100644 --- a/spec/javascripts/deploy_keys/components/action_btn_spec.js +++ b/spec/javascripts/deploy_keys/components/action_btn_spec.js @@ -7,62 +7,64 @@ describe('Deploy keys action btn', () => { const deployKey = data.enabled_keys[0]; let vm; - beforeEach((done) => { - const ActionBtnComponent = Vue.extend(actionBtn); - - vm = new ActionBtnComponent({ - propsData: { - deployKey, - type: 'enable', + beforeEach(done => { + const ActionBtnComponent = Vue.extend({ + components: { + actionBtn, + }, + data() { + return { + deployKey, + }; }, - }).$mount(); + template: ` + <action-btn + :deploy-key="deployKey" + type="enable"> + Enable + </action-btn>`, + }); + + vm = new ActionBtnComponent().$mount(); - setTimeout(done); + Vue.nextTick() + .then(done) + .catch(done.fail); }); - it('renders the type as uppercase', () => { - expect( - vm.$el.textContent.trim(), - ).toBe('Enable'); + it('renders the default slot', () => { + expect(vm.$el.textContent.trim()).toBe('Enable'); }); - it('sends eventHub event with btn type', (done) => { + it('sends eventHub event with btn type', done => { spyOn(eventHub, '$emit'); vm.$el.click(); - setTimeout(() => { - expect( - eventHub.$emit, - ).toHaveBeenCalledWith('enable.key', deployKey, jasmine.anything()); + Vue.nextTick(() => { + expect(eventHub.$emit).toHaveBeenCalledWith('enable.key', deployKey, jasmine.anything()); done(); }); }); - it('shows loading spinner after click', (done) => { + it('shows loading spinner after click', done => { vm.$el.click(); - setTimeout(() => { - expect( - vm.$el.querySelector('.fa'), - ).toBeDefined(); + Vue.nextTick(() => { + expect(vm.$el.querySelector('.fa')).toBeDefined(); done(); }); }); - it('disables button after click', (done) => { + it('disables button after click', done => { vm.$el.click(); - setTimeout(() => { - expect( - vm.$el.classList.contains('disabled'), - ).toBeTruthy(); + Vue.nextTick(() => { + expect(vm.$el.classList.contains('disabled')).toBeTruthy(); - expect( - vm.$el.getAttribute('disabled'), - ).toBe('disabled'); + expect(vm.$el.getAttribute('disabled')).toBe('disabled'); done(); }); diff --git a/spec/javascripts/deploy_keys/components/app_spec.js b/spec/javascripts/deploy_keys/components/app_spec.js index b870f87eab9..3f9e25a8862 100644 --- a/spec/javascripts/deploy_keys/components/app_spec.js +++ b/spec/javascripts/deploy_keys/components/app_spec.js @@ -8,12 +8,14 @@ describe('Deploy keys app component', () => { let vm; const deployKeysResponse = (request, next) => { - next(request.respondWith(JSON.stringify(data), { - status: 200, - })); + next( + request.respondWith(JSON.stringify(data), { + status: 200, + }), + ); }; - beforeEach((done) => { + beforeEach(done => { const Component = Vue.extend(deployKeysApp); Vue.http.interceptors.push(deployKeysResponse); @@ -21,6 +23,7 @@ describe('Deploy keys app component', () => { vm = new Component({ propsData: { endpoint: '/test', + projectId: '8', }, }).$mount(); @@ -31,117 +34,112 @@ describe('Deploy keys app component', () => { Vue.http.interceptors = _.without(Vue.http.interceptors, deployKeysResponse); }); - it('renders loading icon', (done) => { + it('renders loading icon', done => { vm.store.keys = {}; vm.isLoading = false; Vue.nextTick(() => { - expect( - vm.$el.querySelectorAll('.deploy-keys-panel').length, - ).toBe(0); + expect(vm.$el.querySelectorAll('.deploy-keys .nav-links li').length).toBe(0); - expect( - vm.$el.querySelector('.fa-spinner'), - ).toBeDefined(); + expect(vm.$el.querySelector('.fa-spinner')).toBeDefined(); done(); }); }); it('renders keys panels', () => { - expect( - vm.$el.querySelectorAll('.deploy-keys-panel').length, - ).toBe(3); + expect(vm.$el.querySelectorAll('.deploy-keys .nav-links li').length).toBe(3); }); - it('does not render key panels when keys object is empty', (done) => { - vm.store.keys = {}; - - Vue.nextTick(() => { - expect( - vm.$el.querySelectorAll('.deploy-keys-panel').length, - ).toBe(0); - - done(); - }); + it('renders the titles with keys count', () => { + const textContent = selector => { + const element = vm.$el.querySelector(`${selector}`); + + expect(element).not.toBeNull(); + return element.textContent.trim(); + }; + + expect(textContent('.js-deployKeys-tab-enabled_keys')).toContain('Enabled deploy keys'); + expect(textContent('.js-deployKeys-tab-available_project_keys')).toContain( + 'Privately accessible deploy keys', + ); + expect(textContent('.js-deployKeys-tab-public_keys')).toContain( + 'Publicly accessible deploy keys', + ); + + expect(textContent('.js-deployKeys-tab-enabled_keys .badge')).toBe( + `${vm.store.keys.enabled_keys.length}`, + ); + expect(textContent('.js-deployKeys-tab-available_project_keys .badge')).toBe( + `${vm.store.keys.available_project_keys.length}`, + ); + expect(textContent('.js-deployKeys-tab-public_keys .badge')).toBe( + `${vm.store.keys.public_keys.length}`, + ); }); - it('does not render public panel when empty', (done) => { - vm.store.keys.public_keys = []; + it('does not render key panels when keys object is empty', done => { + vm.store.keys = {}; Vue.nextTick(() => { - expect( - vm.$el.querySelectorAll('.deploy-keys-panel').length, - ).toBe(2); + expect(vm.$el.querySelectorAll('.deploy-keys .nav-links li').length).toBe(0); done(); }); }); - it('re-fetches deploy keys when enabling a key', (done) => { + it('re-fetches deploy keys when enabling a key', done => { const key = data.public_keys[0]; spyOn(vm.service, 'getKeys'); - spyOn(vm.service, 'enableKey').and.callFake(() => new Promise((resolve) => { - resolve(); - - setTimeout(() => { - expect(vm.service.getKeys).toHaveBeenCalled(); - - done(); - }); - })); + spyOn(vm.service, 'enableKey').and.callFake(() => Promise.resolve()); eventHub.$emit('enable.key', key); - expect(vm.service.enableKey).toHaveBeenCalledWith(key.id); + Vue.nextTick(() => { + expect(vm.service.enableKey).toHaveBeenCalledWith(key.id); + expect(vm.service.getKeys).toHaveBeenCalled(); + done(); + }); }); - it('re-fetches deploy keys when disabling a key', (done) => { + it('re-fetches deploy keys when disabling a key', done => { const key = data.public_keys[0]; spyOn(window, 'confirm').and.returnValue(true); spyOn(vm.service, 'getKeys'); - spyOn(vm.service, 'disableKey').and.callFake(() => new Promise((resolve) => { - resolve(); - - setTimeout(() => { - expect(vm.service.getKeys).toHaveBeenCalled(); - - done(); - }); - })); + spyOn(vm.service, 'disableKey').and.callFake(() => Promise.resolve()); eventHub.$emit('disable.key', key); - expect(vm.service.disableKey).toHaveBeenCalledWith(key.id); + Vue.nextTick(() => { + expect(vm.service.disableKey).toHaveBeenCalledWith(key.id); + expect(vm.service.getKeys).toHaveBeenCalled(); + done(); + }); }); - it('calls disableKey when removing a key', (done) => { + it('calls disableKey when removing a key', done => { const key = data.public_keys[0]; spyOn(window, 'confirm').and.returnValue(true); spyOn(vm.service, 'getKeys'); - spyOn(vm.service, 'disableKey').and.callFake(() => new Promise((resolve) => { - resolve(); - - setTimeout(() => { - expect(vm.service.getKeys).toHaveBeenCalled(); - - done(); - }); - })); + spyOn(vm.service, 'disableKey').and.callFake(() => Promise.resolve()); eventHub.$emit('remove.key', key); - expect(vm.service.disableKey).toHaveBeenCalledWith(key.id); + Vue.nextTick(() => { + expect(vm.service.disableKey).toHaveBeenCalledWith(key.id); + expect(vm.service.getKeys).toHaveBeenCalled(); + done(); + }); }); it('hasKeys returns true when there are keys', () => { expect(vm.hasKeys).toEqual(3); }); - it('resets remove button loading state', (done) => { + it('resets disable button loading state', done => { spyOn(window, 'confirm').and.returnValue(false); const btn = vm.$el.querySelector('.btn-warning'); @@ -149,7 +147,7 @@ describe('Deploy keys app component', () => { btn.click(); Vue.nextTick(() => { - expect(btn.querySelector('.fa')).toBeNull(); + expect(btn.querySelector('.btn-warning')).not.toExist(); done(); }); diff --git a/spec/javascripts/deploy_keys/components/key_spec.js b/spec/javascripts/deploy_keys/components/key_spec.js index b7aadf604a4..4279add21d1 100644 --- a/spec/javascripts/deploy_keys/components/key_spec.js +++ b/spec/javascripts/deploy_keys/components/key_spec.js @@ -7,7 +7,7 @@ describe('Deploy keys key', () => { let vm; const KeyComponent = Vue.extend(key); const data = getJSONFixture('deploy_keys/keys.json'); - const createComponent = (deployKey) => { + const createComponent = deployKey => { const store = new DeployKeysStore(); store.keys = data; @@ -23,37 +23,42 @@ describe('Deploy keys key', () => { describe('enabled key', () => { const deployKey = data.enabled_keys[0]; - beforeEach((done) => { + beforeEach(done => { createComponent(deployKey); setTimeout(done); }); it('renders the keys title', () => { - expect( - vm.$el.querySelector('.title').textContent.trim(), - ).toContain('My title'); + expect(vm.$el.querySelector('.title').textContent.trim()).toContain('My title'); }); it('renders human friendly formatted created date', () => { - expect( - vm.$el.querySelector('.key-created-at').textContent.trim(), - ).toBe(`created ${getTimeago().format(deployKey.created_at)}`); + expect(vm.$el.querySelector('.key-created-at').textContent.trim()).toBe( + `${getTimeago().format(deployKey.created_at)}`, + ); }); - it('shows edit button', () => { - expect( - vm.$el.querySelectorAll('.btn')[0].textContent.trim(), - ).toBe('Edit'); + it('shows pencil button for editing', () => { + expect(vm.$el.querySelector('.btn .ic-pencil')).toExist(); }); - it('shows remove button', () => { - expect( - vm.$el.querySelectorAll('.btn')[1].textContent.trim(), - ).toBe('Remove'); + it('shows disable button when the project is not deletable', () => { + expect(vm.$el.querySelector('.btn .ic-cancel')).toExist(); }); - it('shows write access title when key has write access', (done) => { + it('shows remove button when the project is deletable', done => { + vm.deployKey.destroyed_when_orphaned = true; + vm.deployKey.almost_orphaned = true; + Vue.nextTick(() => { + expect(vm.$el.querySelector('.btn .ic-remove')).toExist(); + done(); + }); + }); + }); + + describe('deploy key labels', () => { + it('shows write access title when key has write access', done => { vm.deployKey.deploy_keys_projects[0].can_push = true; Vue.nextTick(() => { @@ -64,7 +69,7 @@ describe('Deploy keys key', () => { }); }); - it('does not show write access title when key has write access', (done) => { + it('does not show write access title when key has write access', done => { vm.deployKey.deploy_keys_projects[0].can_push = false; Vue.nextTick(() => { @@ -74,36 +79,73 @@ describe('Deploy keys key', () => { done(); }); }); + + it('shows expandable button if more than two projects', () => { + const labels = vm.$el.querySelectorAll('.deploy-project-label'); + expect(labels.length).toBe(2); + expect(labels[1].textContent).toContain('others'); + expect(labels[1].getAttribute('data-original-title')).toContain('Expand'); + }); + + it('expands all project labels after click', done => { + const length = vm.deployKey.deploy_keys_projects.length; + vm.$el.querySelectorAll('.deploy-project-label')[1].click(); + + Vue.nextTick(() => { + const labels = vm.$el.querySelectorAll('.deploy-project-label'); + expect(labels.length).toBe(length); + expect(labels[1].textContent).not.toContain(`+${length} others`); + expect(labels[1].getAttribute('data-original-title')).not.toContain('Expand'); + done(); + }); + }); + + it('shows two projects', done => { + vm.deployKey.deploy_keys_projects = [...vm.deployKey.deploy_keys_projects].slice(0, 2); + + Vue.nextTick(() => { + const labels = vm.$el.querySelectorAll('.deploy-project-label'); + expect(labels.length).toBe(2); + expect(labels[1].textContent).toContain( + vm.deployKey.deploy_keys_projects[1].project.full_name, + ); + done(); + }); + }); }); describe('public keys', () => { const deployKey = data.public_keys[0]; - beforeEach((done) => { + beforeEach(done => { createComponent(deployKey); setTimeout(done); }); - it('shows edit button', () => { - expect( - vm.$el.querySelectorAll('.btn')[0].textContent.trim(), - ).toBe('Edit'); + it('renders deploy keys without any enabled projects', done => { + vm.deployKey.deploy_keys_projects = []; + + Vue.nextTick(() => { + expect(vm.$el.querySelector('.deploy-project-list').textContent.trim()).toBe('None'); + + done(); + }); }); it('shows enable button', () => { - expect( - vm.$el.querySelectorAll('.btn')[1].textContent.trim(), - ).toBe('Enable'); + expect(vm.$el.querySelectorAll('.btn')[0].textContent.trim()).toBe('Enable'); }); - it('shows disable button when key is enabled', (done) => { + it('shows pencil button for editing', () => { + expect(vm.$el.querySelector('.btn .ic-pencil')).toExist(); + }); + + it('shows disable button when key is enabled', done => { vm.store.keys.enabled_keys.push(deployKey); Vue.nextTick(() => { - expect( - vm.$el.querySelectorAll('.btn')[1].textContent.trim(), - ).toBe('Disable'); + expect(vm.$el.querySelector('.btn .ic-cancel')).toExist(); done(); }); diff --git a/spec/javascripts/deploy_keys/components/keys_panel_spec.js b/spec/javascripts/deploy_keys/components/keys_panel_spec.js index 08357d2b547..f71f5ccf082 100644 --- a/spec/javascripts/deploy_keys/components/keys_panel_spec.js +++ b/spec/javascripts/deploy_keys/components/keys_panel_spec.js @@ -6,7 +6,7 @@ describe('Deploy keys panel', () => { const data = getJSONFixture('deploy_keys/keys.json'); let vm; - beforeEach((done) => { + beforeEach(done => { const DeployKeysPanelComponent = Vue.extend(deployKeysPanel); const store = new DeployKeysStore(); store.keys = data; @@ -24,46 +24,38 @@ describe('Deploy keys panel', () => { setTimeout(done); }); - it('renders the title with keys count', () => { - expect( - vm.$el.querySelector('h5').textContent.trim(), - ).toContain('test'); - - expect( - vm.$el.querySelector('h5').textContent.trim(), - ).toContain(`(${vm.keys.length})`); + it('renders list of keys', () => { + expect(vm.$el.querySelectorAll('.deploy-key').length).toBe(vm.keys.length); }); - it('renders list of keys', () => { - expect( - vm.$el.querySelectorAll('li').length, - ).toBe(vm.keys.length); + it('renders table header', () => { + const tableHeader = vm.$el.querySelector('.table-row-header'); + + expect(tableHeader).toExist(); + expect(tableHeader.textContent).toContain('Deploy key'); + expect(tableHeader.textContent).toContain('Project usage'); + expect(tableHeader.textContent).toContain('Created'); }); - it('renders help box if keys are empty', (done) => { + it('renders help box if keys are empty', done => { vm.keys = []; Vue.nextTick(() => { - expect( - vm.$el.querySelector('.settings-message'), - ).toBeDefined(); + expect(vm.$el.querySelector('.settings-message')).toBeDefined(); - expect( - vm.$el.querySelector('.settings-message').textContent.trim(), - ).toBe('No deploy keys found. Create one with the form above.'); + expect(vm.$el.querySelector('.settings-message').textContent.trim()).toBe( + 'No deploy keys found. Create one with the form above.', + ); done(); }); }); - it('does not render help box if keys are empty & showHelpBox is false', (done) => { + it('renders no table header if keys are empty', done => { vm.keys = []; - vm.showHelpBox = false; Vue.nextTick(() => { - expect( - vm.$el.querySelector('.settings-message'), - ).toBeNull(); + expect(vm.$el.querySelector('.table-row-header')).not.toExist(); done(); }); |