import { mount } from '@vue/test-utils'; import { nextTick } from 'vue'; import data from 'test_fixtures/deploy_keys/keys.json'; import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; import key from '~/deploy_keys/components/key.vue'; import DeployKeysStore from '~/deploy_keys/store'; import { getTimeago, formatDate } from '~/lib/utils/datetime_utility'; describe('Deploy keys key', () => { let wrapper; let store; const findTextAndTrim = (selector) => wrapper.find(selector).text().trim(); const createComponent = (propsData) => { wrapper = mount(key, { propsData: { store, endpoint: 'https://test.host/dummy/endpoint', ...propsData, }, directives: { GlTooltip: createMockDirective('gl-tooltip'), }, }); }; beforeEach(() => { store = new DeployKeysStore(); store.keys = data; }); describe('enabled key', () => { const deployKey = data.enabled_keys[0]; it('renders the keys title', () => { createComponent({ deployKey }); expect(findTextAndTrim('.title')).toContain('My title'); }); it('renders human friendly formatted created date', () => { createComponent({ deployKey }); expect(findTextAndTrim('.key-created-at')).toBe( `${getTimeago().format(deployKey.created_at)}`, ); }); it('renders human friendly expiration date', () => { const expiresAt = new Date(); createComponent({ deployKey: { ...deployKey, expires_at: expiresAt }, }); expect(findTextAndTrim('.key-expires-at')).toBe(`${getTimeago().format(expiresAt)}`); }); it('shows tooltip for expiration date', () => { const expiresAt = new Date(); createComponent({ deployKey: { ...deployKey, expires_at: expiresAt }, }); const expiryComponent = wrapper.find('[data-testid="expires-at-tooltip"]'); const tooltip = getBinding(expiryComponent.element, 'gl-tooltip'); expect(tooltip).toBeDefined(); expect(expiryComponent.attributes('title')).toBe(`${formatDate(expiresAt)}`); }); it('renders never when no expiration date', () => { createComponent({ deployKey: { ...deployKey, expires_at: null }, }); expect(wrapper.find('[data-testid="expires-never"]').exists()).toBe(true); }); it('shows pencil button for editing', () => { createComponent({ deployKey }); expect(wrapper.find('.btn [data-testid="pencil-icon"]').exists()).toBe(true); }); it('shows disable button when the project is not deletable', () => { createComponent({ deployKey }); expect(wrapper.find('.btn [data-testid="cancel-icon"]').exists()).toBe(true); }); it('shows remove button when the project is deletable', () => { createComponent({ deployKey: { ...deployKey, destroyed_when_orphaned: true, almost_orphaned: true }, }); expect(wrapper.find('.btn [data-testid="remove-icon"]').exists()).toBe(true); }); }); describe('deploy key labels', () => { const deployKey = data.enabled_keys[0]; const deployKeysProjects = [...deployKey.deploy_keys_projects]; it('shows write access title when key has write access', () => { deployKeysProjects[0] = { ...deployKeysProjects[0], can_push: true }; createComponent({ deployKey: { ...deployKey, deploy_keys_projects: deployKeysProjects } }); expect(wrapper.find('.deploy-project-label').attributes('title')).toBe( 'Grant write permissions to this key', ); }); it('does not show write access title when key has write access', () => { deployKeysProjects[0] = { ...deployKeysProjects[0], can_push: false }; createComponent({ deployKey: { ...deployKey, deploy_keys_projects: deployKeysProjects } }); expect(wrapper.find('.deploy-project-label').attributes('title')).toBe('Read access only'); }); it('shows expandable button if more than two projects', () => { createComponent({ deployKey }); const labels = wrapper.findAll('.deploy-project-label'); expect(labels.length).toBe(2); expect(labels.at(1).text()).toContain('others'); expect(labels.at(1).attributes('title')).toContain('Expand'); }); it('expands all project labels after click', async () => { createComponent({ deployKey }); const { length } = deployKey.deploy_keys_projects; wrapper.findAll('.deploy-project-label').at(1).trigger('click'); await nextTick(); const labels = wrapper.findAll('.deploy-project-label'); expect(labels.length).toBe(length); expect(labels.at(1).text()).not.toContain(`+${length} others`); expect(labels.at(1).attributes('title')).not.toContain('Expand'); }); it('shows two projects', () => { createComponent({ deployKey: { ...deployKey, deploy_keys_projects: [...deployKeysProjects].slice(0, 2) }, }); const labels = wrapper.findAll('.deploy-project-label'); expect(labels.length).toBe(2); expect(labels.at(1).text()).toContain(deployKey.deploy_keys_projects[1].project.full_name); }); }); describe('public keys', () => { const deployKey = data.public_keys[0]; it('renders deploy keys without any enabled projects', () => { createComponent({ deployKey: { ...deployKey, deploy_keys_projects: [] } }); expect(findTextAndTrim('.deploy-project-list')).toBe('None'); }); it('shows enable button', () => { createComponent({ deployKey }); expect(findTextAndTrim('.btn')).toBe('Enable'); }); it('shows pencil button for editing', () => { createComponent({ deployKey }); expect(wrapper.find('.btn [data-testid="pencil-icon"]').exists()).toBe(true); }); it('shows disable button when key is enabled', () => { store.keys.enabled_keys.push(deployKey); createComponent({ deployKey }); expect(wrapper.find('.btn [data-testid="cancel-icon"]').exists()).toBe(true); }); }); });