diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-01 12:10:14 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-01 12:10:14 +0000 |
commit | a27b8a5c104f492e4b0abac4c84385a615c4f6ba (patch) | |
tree | 3ec1a2cc06312b1999ce405905ab7881f68927d2 /spec/frontend | |
parent | 635d82b15d83a88a2d073fbf3bb56f6ff626020f (diff) | |
download | gitlab-ce-a27b8a5c104f492e4b0abac4c84385a615c4f6ba.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
14 files changed, 454 insertions, 294 deletions
diff --git a/spec/frontend/commit/pipelines/pipelines_spec.js b/spec/frontend/commit/pipelines/pipelines_spec.js index fdf3c2e85f3..a196b66daa0 100644 --- a/spec/frontend/commit/pipelines/pipelines_spec.js +++ b/spec/frontend/commit/pipelines/pipelines_spec.js @@ -21,6 +21,10 @@ describe('Pipelines table in Commits and Merge requests', () => { preloadFixtures(jsonFixtureName); + const findRunPipelineBtn = () => vm.$el.querySelector('[data-testid="run_pipeline_button"]'); + const findRunPipelineBtnMobile = () => + vm.$el.querySelector('[data-testid="run_pipeline_button_mobile"]'); + beforeEach(() => { mock = new MockAdapter(axios); @@ -131,7 +135,8 @@ describe('Pipelines table in Commits and Merge requests', () => { vm = mountComponent(PipelinesTable, { ...props }); setImmediate(() => { - expect(vm.$el.querySelector('.js-run-mr-pipeline')).not.toBeNull(); + expect(findRunPipelineBtn()).not.toBeNull(); + expect(findRunPipelineBtnMobile()).not.toBeNull(); done(); }); }); @@ -147,7 +152,8 @@ describe('Pipelines table in Commits and Merge requests', () => { vm = mountComponent(PipelinesTable, { ...props }); setImmediate(() => { - expect(vm.$el.querySelector('.js-run-mr-pipeline')).toBeNull(); + expect(findRunPipelineBtn()).toBeNull(); + expect(findRunPipelineBtnMobile()).toBeNull(); done(); }); }); @@ -157,7 +163,7 @@ describe('Pipelines table in Commits and Merge requests', () => { const findModal = () => document.querySelector('#create-pipeline-for-fork-merge-request-modal'); - beforeEach(() => { + beforeEach(done => { pipelineCopy.flags.detached_merge_request_pipeline = true; mock.onGet('endpoint.json').reply(200, [pipelineCopy]); @@ -168,23 +174,46 @@ describe('Pipelines table in Commits and Merge requests', () => { projectId: '5', mergeRequestId: 3, }); - }); - it('updates the loading state', done => { jest.spyOn(Api, 'postMergeRequestPipeline').mockReturnValue(Promise.resolve()); setImmediate(() => { - vm.$el.querySelector('.js-run-mr-pipeline').click(); + done(); + }); + }); - vm.$nextTick(() => { - expect(findModal()).toBeNull(); - expect(vm.state.isRunningMergeRequestPipeline).toBe(true); + it('on desktop, shows a loading button', done => { + findRunPipelineBtn().click(); - setImmediate(() => { - expect(vm.state.isRunningMergeRequestPipeline).toBe(false); + vm.$nextTick(() => { + expect(findModal()).toBeNull(); - done(); - }); + expect(findRunPipelineBtn().disabled).toBe(true); + expect(findRunPipelineBtn().querySelector('.gl-spinner')).not.toBeNull(); + + setImmediate(() => { + expect(findRunPipelineBtn().disabled).toBe(false); + expect(findRunPipelineBtn().querySelector('.gl-spinner')).toBeNull(); + + done(); + }); + }); + }); + + it('on mobile, shows a loading button', done => { + findRunPipelineBtnMobile().click(); + + vm.$nextTick(() => { + expect(findModal()).toBeNull(); + + expect(findModal()).toBeNull(); + expect(findRunPipelineBtn().querySelector('.gl-spinner')).not.toBeNull(); + + setImmediate(() => { + expect(findRunPipelineBtn().disabled).toBe(false); + expect(findRunPipelineBtn().querySelector('.gl-spinner')).toBeNull(); + + done(); }); }); }); @@ -194,7 +223,7 @@ describe('Pipelines table in Commits and Merge requests', () => { const findModal = () => document.querySelector('#create-pipeline-for-fork-merge-request-modal'); - beforeEach(() => { + beforeEach(done => { pipelineCopy.flags.detached_merge_request_pipeline = true; mock.onGet('endpoint.json').reply(200, [pipelineCopy]); @@ -207,18 +236,29 @@ describe('Pipelines table in Commits and Merge requests', () => { sourceProjectFullPath: 'test/parent-project', targetProjectFullPath: 'test/fork-project', }); - }); - it('shows a security warning modal', done => { jest.spyOn(Api, 'postMergeRequestPipeline').mockReturnValue(Promise.resolve()); setImmediate(() => { - vm.$el.querySelector('.js-run-mr-pipeline').click(); + done(); + }); + }); - vm.$nextTick(() => { - expect(findModal()).not.toBeNull(); - done(); - }); + it('on desktop, shows a security warning modal', done => { + findRunPipelineBtn().click(); + + vm.$nextTick(() => { + expect(findModal()).not.toBeNull(); + done(); + }); + }); + + it('on mobile, shows a security warning modal', done => { + findRunPipelineBtnMobile().click(); + + vm.$nextTick(() => { + expect(findModal()).not.toBeNull(); + done(); }); }); }); diff --git a/spec/frontend/fixtures/releases.rb b/spec/frontend/fixtures/releases.rb index eb6326bc3bd..bda62f4850a 100644 --- a/spec/frontend/fixtures/releases.rb +++ b/spec/frontend/fixtures/releases.rb @@ -6,11 +6,13 @@ RSpec.describe 'Releases (JavaScript fixtures)' do include ApiHelpers include JavaScriptFixturesHelpers - let_it_be(:admin) { create(:admin) } - let_it_be(:project) { create(:project, :repository, path: 'releases-project') } + let_it_be(:admin) { create(:admin, username: 'administrator', email: 'admin@example.gitlab.com') } + let_it_be(:namespace) { create(:namespace, path: 'releases-namespace') } + let_it_be(:project) { create(:project, :repository, namespace: namespace, path: 'releases-project') } let_it_be(:milestone_12_3) do create(:milestone, + id: 123, project: project, title: '12.3', description: 'The 12.3 milestone', @@ -20,6 +22,7 @@ RSpec.describe 'Releases (JavaScript fixtures)' do let_it_be(:milestone_12_4) do create(:milestone, + id: 124, project: project, title: '12.4', description: 'The 12.4 milestone', @@ -45,18 +48,25 @@ RSpec.describe 'Releases (JavaScript fixtures)' do let_it_be(:release) do create(:release, - :with_evidence, milestones: [milestone_12_3, milestone_12_4], project: project, tag: 'v1.1', name: 'The first release', + author: admin, description: 'Best. Release. **Ever.** :rocket:', created_at: Time.zone.parse('2018-12-3'), released_at: Time.zone.parse('2018-12-10')) end + let_it_be(:evidence) do + create(:evidence, + release: release, + collected_at: Time.zone.parse('2018-12-03')) + end + let_it_be(:other_link) do create(:release_link, + id: 10, release: release, name: 'linux-amd64 binaries', filepath: '/binaries/linux-amd64', @@ -65,6 +75,7 @@ RSpec.describe 'Releases (JavaScript fixtures)' do let_it_be(:runbook_link) do create(:release_link, + id: 11, release: release, name: 'Runbook', url: "#{release.project.web_url}/runbook", @@ -73,6 +84,7 @@ RSpec.describe 'Releases (JavaScript fixtures)' do let_it_be(:package_link) do create(:release_link, + id: 12, release: release, name: 'Package', url: 'https://example.com/package', @@ -81,6 +93,7 @@ RSpec.describe 'Releases (JavaScript fixtures)' do let_it_be(:image_link) do create(:release_link, + id: 13, release: release, name: 'Image', url: 'https://example.com/image', diff --git a/spec/frontend/merge_request_spec.js b/spec/frontend/merge_request_spec.js index 16f04d032fd..37509f77f71 100644 --- a/spec/frontend/merge_request_spec.js +++ b/spec/frontend/merge_request_spec.js @@ -3,8 +3,6 @@ import MockAdapter from 'axios-mock-adapter'; import { TEST_HOST } from 'spec/test_constants'; import axios from '~/lib/utils/axios_utils'; import MergeRequest from '~/merge_request'; -import CloseReopenReportToggle from '~/close_reopen_report_toggle'; -import IssuablesHelper from '~/helpers/issuables_helper'; describe('MergeRequest', () => { const test = {}; @@ -112,66 +110,7 @@ describe('MergeRequest', () => { }); }); - describe('class constructor', () => { - beforeEach(() => { - jest.spyOn($, 'ajax').mockImplementation(); - }); - - it('calls .initCloseReopenReport', () => { - jest.spyOn(IssuablesHelper, 'initCloseReopenReport').mockImplementation(() => {}); - - new MergeRequest(); // eslint-disable-line no-new - - expect(IssuablesHelper.initCloseReopenReport).toHaveBeenCalled(); - }); - - it('calls .initDroplab', () => { - const container = { - querySelector: jest.fn().mockName('container.querySelector'), - }; - const dropdownTrigger = {}; - const dropdownList = {}; - const button = {}; - - jest.spyOn(CloseReopenReportToggle.prototype, 'initDroplab').mockImplementation(() => {}); - jest.spyOn(document, 'querySelector').mockReturnValue(container); - - container.querySelector - .mockReturnValueOnce(dropdownTrigger) - .mockReturnValueOnce(dropdownList) - .mockReturnValueOnce(button); - - new MergeRequest(); // eslint-disable-line no-new - - expect(document.querySelector).toHaveBeenCalledWith('.js-issuable-close-dropdown'); - expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-toggle'); - expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-menu'); - expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-button'); - expect(CloseReopenReportToggle.prototype.initDroplab).toHaveBeenCalled(); - }); - }); - describe('hideCloseButton', () => { - describe('merge request of another user', () => { - beforeEach(() => { - loadFixtures('merge_requests/merge_request_with_task_list.html'); - test.el = document.querySelector('.js-issuable-actions'); - new MergeRequest(); // eslint-disable-line no-new - MergeRequest.hideCloseButton(); - }); - - it('hides the dropdown close item and selects the next item', () => { - const closeItem = test.el.querySelector('li.close-item'); - const smallCloseItem = test.el.querySelector('.js-close-item'); - const reportItem = test.el.querySelector('li.report-item'); - - expect(closeItem).toHaveClass('hidden'); - expect(smallCloseItem).toHaveClass('hidden'); - expect(reportItem).toHaveClass('droplab-item-selected'); - expect(reportItem).not.toHaveClass('hidden'); - }); - }); - describe('merge request of current_user', () => { beforeEach(() => { loadFixtures('merge_requests/merge_request_of_current_user.html'); @@ -180,10 +119,8 @@ describe('MergeRequest', () => { }); it('hides the close button', () => { - const closeButton = test.el.querySelector('.btn-close'); const smallCloseItem = test.el.querySelector('.js-close-item'); - expect(closeButton).toHaveClass('hidden'); expect(smallCloseItem).toHaveClass('hidden'); }); }); diff --git a/spec/frontend/releases/__snapshots__/util_spec.js.snap b/spec/frontend/releases/__snapshots__/util_spec.js.snap index f3adc45e652..84247e2a5a0 100644 --- a/spec/frontend/releases/__snapshots__/util_spec.js.snap +++ b/spec/frontend/releases/__snapshots__/util_spec.js.snap @@ -5,115 +5,123 @@ Object { "data": Array [ Object { "_links": Object { - "editUrl": "http://0.0.0.0:3000/root/release-test/-/releases/v5.10/edit", - "issuesUrl": null, - "mergeRequestsUrl": null, - "self": "http://0.0.0.0:3000/root/release-test/-/releases/v5.10", - "selfUrl": "http://0.0.0.0:3000/root/release-test/-/releases/v5.10", + "editUrl": "http://localhost/releases-namespace/releases-project/-/releases/v1.1/edit", + "issuesUrl": "http://localhost/releases-namespace/releases-project/-/issues?release_tag=v1.1&scope=all&state=opened", + "mergeRequestsUrl": "http://localhost/releases-namespace/releases-project/-/merge_requests?release_tag=v1.1&scope=all&state=opened", + "self": "http://localhost/releases-namespace/releases-project/-/releases/v1.1", + "selfUrl": "http://localhost/releases-namespace/releases-project/-/releases/v1.1", }, "assets": Object { - "count": 7, + "count": 8, "links": Array [ Object { - "directAssetUrl": "http://0.0.0.0:3000/root/release-test/-/releases/v5.32/permanent/path/to/runbook", + "directAssetUrl": "http://localhost/releases-namespace/releases-project/-/releases/v1.1/binaries/awesome-app-3", "external": true, - "id": "gid://gitlab/Releases::Link/69", - "linkType": "other", - "name": "An example link", - "url": "https://example.com/link", + "id": "gid://gitlab/Releases::Link/13", + "linkType": "image", + "name": "Image", + "url": "https://example.com/image", }, Object { - "directAssetUrl": "https://example.com/package", + "directAssetUrl": "http://localhost/releases-namespace/releases-project/-/releases/v1.1/binaries/awesome-app-2", "external": true, - "id": "gid://gitlab/Releases::Link/68", + "id": "gid://gitlab/Releases::Link/12", "linkType": "package", - "name": "An example package link", + "name": "Package", "url": "https://example.com/package", }, Object { - "directAssetUrl": "https://example.com/image", + "directAssetUrl": "http://localhost/releases-namespace/releases-project/-/releases/v1.1/binaries/awesome-app-1", + "external": false, + "id": "gid://gitlab/Releases::Link/11", + "linkType": "runbook", + "name": "Runbook", + "url": "http://localhost/releases-namespace/releases-project/runbook", + }, + Object { + "directAssetUrl": "http://localhost/releases-namespace/releases-project/-/releases/v1.1/binaries/linux-amd64", "external": true, - "id": "gid://gitlab/Releases::Link/67", - "linkType": "image", - "name": "An example image", - "url": "https://example.com/image", + "id": "gid://gitlab/Releases::Link/10", + "linkType": "other", + "name": "linux-amd64 binaries", + "url": "https://downloads.example.com/bin/gitlab-linux-amd64", }, ], "sources": Array [ Object { "format": "zip", - "url": "http://0.0.0.0:3000/root/release-test/-/archive/v5.10/release-test-v5.10.zip", + "url": "http://localhost/releases-namespace/releases-project/-/archive/v1.1/releases-project-v1.1.zip", }, Object { "format": "tar.gz", - "url": "http://0.0.0.0:3000/root/release-test/-/archive/v5.10/release-test-v5.10.tar.gz", + "url": "http://localhost/releases-namespace/releases-project/-/archive/v1.1/releases-project-v1.1.tar.gz", }, Object { "format": "tar.bz2", - "url": "http://0.0.0.0:3000/root/release-test/-/archive/v5.10/release-test-v5.10.tar.bz2", + "url": "http://localhost/releases-namespace/releases-project/-/archive/v1.1/releases-project-v1.1.tar.bz2", }, Object { "format": "tar", - "url": "http://0.0.0.0:3000/root/release-test/-/archive/v5.10/release-test-v5.10.tar", + "url": "http://localhost/releases-namespace/releases-project/-/archive/v1.1/releases-project-v1.1.tar", }, ], }, "author": Object { - "avatarUrl": "/uploads/-/system/user/avatar/1/avatar.png", - "username": "root", - "webUrl": "http://0.0.0.0:3000/root", + "avatarUrl": "https://www.gravatar.com/avatar/16f8e2050ce10180ca571c2eb19cfce2?s=80&d=identicon", + "username": "administrator", + "webUrl": "http://localhost/administrator", }, "commit": Object { - "shortId": "92e7ea2e", - "title": "Testing a change.", + "shortId": "b83d6e39", + "title": "Merge branch 'branch-merged' into 'master'", }, - "commitPath": "http://0.0.0.0:3000/root/release-test/-/commit/92e7ea2ee4496fe0d00ff69830ba0564d3d1e5a7", - "descriptionHtml": "<p data-sourcepos=\\"1:1-1:24\\" dir=\\"auto\\">This is version <strong>1.0</strong>!</p>", + "commitPath": "http://localhost/releases-namespace/releases-project/-/commit/b83d6e391c22777fca1ed3012fce84f633d7fed0", + "descriptionHtml": "<p data-sourcepos=\\"1:1-1:33\\" dir=\\"auto\\">Best. Release. <strong>Ever.</strong> <gl-emoji title=\\"rocket\\" data-name=\\"rocket\\" data-unicode-version=\\"6.0\\">🚀</gl-emoji></p>", "evidences": Array [ Object { - "collectedAt": "2020-08-21T20:15:19Z", - "filepath": "http://0.0.0.0:3000/root/release-test/-/releases/v5.10/evidences/34.json", - "sha": "22bde8e8b93d870a29ddc339287a1fbb598f45d1396d", + "collectedAt": "2018-12-03T00:00:00Z", + "filepath": "http://localhost/releases-namespace/releases-project/-/releases/v1.1/evidences/1.json", + "sha": "760d6cdfb0879c3ffedec13af470e0f71cf52c6cde4d", }, ], "milestones": Array [ Object { - "description": "", - "id": "gid://gitlab/Milestone/60", + "description": "The 12.4 milestone", + "id": "gid://gitlab/Milestone/124", "issueStats": Object { - "closed": 0, - "total": 0, + "closed": 1, + "total": 4, }, "stats": undefined, "title": "12.4", "webPath": undefined, - "webUrl": "/root/release-test/-/milestones/2", + "webUrl": "/releases-namespace/releases-project/-/milestones/2", }, Object { - "description": "Milestone 12.3", - "id": "gid://gitlab/Milestone/59", + "description": "The 12.3 milestone", + "id": "gid://gitlab/Milestone/123", "issueStats": Object { - "closed": 1, - "total": 2, + "closed": 3, + "total": 5, }, "stats": undefined, "title": "12.3", "webPath": undefined, - "webUrl": "/root/release-test/-/milestones/1", + "webUrl": "/releases-namespace/releases-project/-/milestones/1", }, ], - "name": "Release 1.0", - "releasedAt": "2020-08-21T20:15:18Z", - "tagName": "v5.10", - "tagPath": "/root/release-test/-/tags/v5.10", - "upcomingRelease": false, + "name": "The first release", + "releasedAt": "2018-12-10T00:00:00Z", + "tagName": "v1.1", + "tagPath": "/releases-namespace/releases-project/-/tags/v1.1", + "upcomingRelease": true, }, ], "paginationInfo": Object { - "endCursor": "eyJpZCI6IjMiLCJyZWxlYXNlZF9hdCI6IjIwMjAtMDctMDkgMjA6MTE6MzMuODA0OTYxMDAwIFVUQyJ9", - "hasNextPage": true, + "endCursor": "eyJpZCI6IjEiLCJyZWxlYXNlZF9hdCI6IjIwMTgtMTItMTAgMDA6MDA6MDAuMDAwMDAwMDAwIFVUQyJ9", + "hasNextPage": false, "hasPreviousPage": false, - "startCursor": "eyJpZCI6IjQ0IiwicmVsZWFzZWRfYXQiOiIyMDMwLTAzLTE1IDA4OjAwOjAwLjAwMDAwMDAwMCBVVEMifQ", + "startCursor": "eyJpZCI6IjEiLCJyZWxlYXNlZF9hdCI6IjIwMTgtMTItMTAgMDA6MDA6MDAuMDAwMDAwMDAwIFVUQyJ9", }, } `; diff --git a/spec/frontend/releases/mock_data.js b/spec/frontend/releases/mock_data.js index c5b6f8aae47..c89182faa44 100644 --- a/spec/frontend/releases/mock_data.js +++ b/spec/frontend/releases/mock_data.js @@ -15,139 +15,3 @@ export const pageInfoHeadersWithPagination = { 'X-TOTAL': '21', 'X-TOTAL-PAGES': '2', }; - -export const graphqlReleasesResponse = { - data: { - project: { - releases: { - count: 39, - nodes: [ - { - name: 'Release 1.0', - tagName: 'v5.10', - tagPath: '/root/release-test/-/tags/v5.10', - descriptionHtml: - '<p data-sourcepos="1:1-1:24" dir="auto">This is version <strong>1.0</strong>!</p>', - releasedAt: '2020-08-21T20:15:18Z', - upcomingRelease: false, - assets: { - count: 7, - sources: { - nodes: [ - { - format: 'zip', - url: - 'http://0.0.0.0:3000/root/release-test/-/archive/v5.10/release-test-v5.10.zip', - }, - { - format: 'tar.gz', - url: - 'http://0.0.0.0:3000/root/release-test/-/archive/v5.10/release-test-v5.10.tar.gz', - }, - { - format: 'tar.bz2', - url: - 'http://0.0.0.0:3000/root/release-test/-/archive/v5.10/release-test-v5.10.tar.bz2', - }, - { - format: 'tar', - url: - 'http://0.0.0.0:3000/root/release-test/-/archive/v5.10/release-test-v5.10.tar', - }, - ], - }, - links: { - nodes: [ - { - id: 'gid://gitlab/Releases::Link/69', - name: 'An example link', - url: 'https://example.com/link', - directAssetUrl: - 'http://0.0.0.0:3000/root/release-test/-/releases/v5.32/permanent/path/to/runbook', - linkType: 'OTHER', - external: true, - }, - { - id: 'gid://gitlab/Releases::Link/68', - name: 'An example package link', - url: 'https://example.com/package', - directAssetUrl: 'https://example.com/package', - linkType: 'PACKAGE', - external: true, - }, - { - id: 'gid://gitlab/Releases::Link/67', - name: 'An example image', - url: 'https://example.com/image', - directAssetUrl: 'https://example.com/image', - linkType: 'IMAGE', - external: true, - }, - ], - }, - }, - evidences: { - nodes: [ - { - filepath: - 'http://0.0.0.0:3000/root/release-test/-/releases/v5.10/evidences/34.json', - collectedAt: '2020-08-21T20:15:19Z', - sha: '22bde8e8b93d870a29ddc339287a1fbb598f45d1396d', - }, - ], - }, - links: { - editUrl: 'http://0.0.0.0:3000/root/release-test/-/releases/v5.10/edit', - issuesUrl: null, - mergeRequestsUrl: null, - selfUrl: 'http://0.0.0.0:3000/root/release-test/-/releases/v5.10', - }, - commit: { - sha: '92e7ea2ee4496fe0d00ff69830ba0564d3d1e5a7', - webUrl: - 'http://0.0.0.0:3000/root/release-test/-/commit/92e7ea2ee4496fe0d00ff69830ba0564d3d1e5a7', - title: 'Testing a change.', - }, - author: { - webUrl: 'http://0.0.0.0:3000/root', - avatarUrl: '/uploads/-/system/user/avatar/1/avatar.png', - username: 'root', - }, - milestones: { - nodes: [ - { - id: 'gid://gitlab/Milestone/60', - title: '12.4', - description: '', - webPath: '/root/release-test/-/milestones/2', - stats: { - totalIssuesCount: 0, - closedIssuesCount: 0, - }, - }, - { - id: 'gid://gitlab/Milestone/59', - title: '12.3', - description: 'Milestone 12.3', - webPath: '/root/release-test/-/milestones/1', - stats: { - totalIssuesCount: 2, - closedIssuesCount: 1, - }, - }, - ], - }, - }, - ], - pageInfo: { - startCursor: - 'eyJpZCI6IjQ0IiwicmVsZWFzZWRfYXQiOiIyMDMwLTAzLTE1IDA4OjAwOjAwLjAwMDAwMDAwMCBVVEMifQ', - hasPreviousPage: false, - hasNextPage: true, - endCursor: - 'eyJpZCI6IjMiLCJyZWxlYXNlZF9hdCI6IjIwMjAtMDctMDkgMjA6MTE6MzMuODA0OTYxMDAwIFVUQyJ9', - }, - }, - }, - }, -}; diff --git a/spec/frontend/releases/stores/modules/list/actions_spec.js b/spec/frontend/releases/stores/modules/list/actions_spec.js index 7466f6f9c29..2068d7fee78 100644 --- a/spec/frontend/releases/stores/modules/list/actions_spec.js +++ b/spec/frontend/releases/stores/modules/list/actions_spec.js @@ -16,16 +16,17 @@ import { parseIntPagination, convertObjectPropsToCamelCase, } from '~/lib/utils/common_utils'; -import { - pageInfoHeadersWithoutPagination, - graphqlReleasesResponse as originalGraphqlReleasesResponse, -} from '../../../mock_data'; +import { pageInfoHeadersWithoutPagination } from '../../../mock_data'; import allReleasesQuery from '~/releases/queries/all_releases.query.graphql'; import { PAGE_SIZE } from '~/releases/constants'; const originalRelease = getJSONFixture('api/releases/release.json'); const originalReleases = [originalRelease]; +const originalGraphqlReleasesResponse = getJSONFixture( + 'graphql/releases/queries/all_releases.query.graphql.json', +); + describe('Releases State actions', () => { let mockedState; let releases; diff --git a/spec/frontend/releases/stores/modules/list/mutations_spec.js b/spec/frontend/releases/stores/modules/list/mutations_spec.js index 23d23d23646..914f69ec194 100644 --- a/spec/frontend/releases/stores/modules/list/mutations_spec.js +++ b/spec/frontend/releases/stores/modules/list/mutations_spec.js @@ -3,12 +3,16 @@ import createState from '~/releases/stores/modules/list/state'; import mutations from '~/releases/stores/modules/list/mutations'; import * as types from '~/releases/stores/modules/list/mutation_types'; import { parseIntPagination, convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; -import { pageInfoHeadersWithoutPagination, graphqlReleasesResponse } from '../../../mock_data'; +import { pageInfoHeadersWithoutPagination } from '../../../mock_data'; import { convertGraphQLResponse } from '~/releases/util'; const originalRelease = getJSONFixture('api/releases/release.json'); const originalReleases = [originalRelease]; +const graphqlReleasesResponse = getJSONFixture( + 'graphql/releases/queries/all_releases.query.graphql.json', +); + describe('Releases Store Mutations', () => { let stateCopy; let restPageInfo; diff --git a/spec/frontend/releases/util_spec.js b/spec/frontend/releases/util_spec.js index f40e5729188..a9d0b61695d 100644 --- a/spec/frontend/releases/util_spec.js +++ b/spec/frontend/releases/util_spec.js @@ -1,6 +1,10 @@ import { cloneDeep } from 'lodash'; +import { getJSONFixture } from 'helpers/fixtures'; import { releaseToApiJson, apiJsonToRelease, convertGraphQLResponse } from '~/releases/util'; -import { graphqlReleasesResponse as originalGraphqlReleasesResponse } from './mock_data'; + +const originalGraphqlReleasesResponse = getJSONFixture( + 'graphql/releases/queries/all_releases.query.graphql.json', +); describe('releases/util.js', () => { describe('releaseToApiJson', () => { diff --git a/spec/frontend/sidebar/reviewer_title_spec.js b/spec/frontend/sidebar/reviewer_title_spec.js new file mode 100644 index 00000000000..eae266688d5 --- /dev/null +++ b/spec/frontend/sidebar/reviewer_title_spec.js @@ -0,0 +1,116 @@ +import { shallowMount } from '@vue/test-utils'; +import { GlLoadingIcon } from '@gitlab/ui'; +import { mockTracking, triggerEvent } from 'helpers/tracking_helper'; +import Component from '~/sidebar/components/reviewers/reviewer_title.vue'; + +describe('ReviewerTitle component', () => { + let wrapper; + + const createComponent = props => { + return shallowMount(Component, { + propsData: { + numberOfReviewers: 0, + editable: false, + ...props, + }, + }); + }; + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + describe('reviewer title', () => { + it('renders reviewer', () => { + wrapper = createComponent({ + numberOfReviewers: 1, + editable: false, + }); + + expect(wrapper.vm.$el.innerText.trim()).toEqual('Reviewer'); + }); + + it('renders 2 reviewers', () => { + wrapper = createComponent({ + numberOfReviewers: 2, + editable: false, + }); + + expect(wrapper.vm.$el.innerText.trim()).toEqual('2 Reviewers'); + }); + }); + + describe('gutter toggle', () => { + it('does not show toggle by default', () => { + wrapper = createComponent({ + numberOfReviewers: 2, + editable: false, + }); + + expect(wrapper.vm.$el.querySelector('.gutter-toggle')).toBeNull(); + }); + + it('shows toggle when showToggle is true', () => { + wrapper = createComponent({ + numberOfReviewers: 2, + editable: false, + showToggle: true, + }); + + expect(wrapper.vm.$el.querySelector('.gutter-toggle')).toEqual(expect.any(Object)); + }); + }); + + it('does not render spinner by default', () => { + wrapper = createComponent({ + numberOfReviewers: 0, + editable: false, + }); + + expect(wrapper.find(GlLoadingIcon).exists()).toBeFalsy(); + }); + + it('renders spinner when loading', () => { + wrapper = createComponent({ + loading: true, + numberOfReviewers: 0, + editable: false, + }); + + expect(wrapper.find(GlLoadingIcon).exists()).toBeTruthy(); + }); + + it('does not render edit link when not editable', () => { + wrapper = createComponent({ + numberOfReviewers: 0, + editable: false, + }); + + expect(wrapper.vm.$el.querySelector('.edit-link')).toBeNull(); + }); + + it('renders edit link when editable', () => { + wrapper = createComponent({ + numberOfReviewers: 0, + editable: true, + }); + + expect(wrapper.vm.$el.querySelector('.edit-link')).not.toBeNull(); + }); + + it('tracks the event when edit is clicked', () => { + wrapper = createComponent({ + numberOfReviewers: 0, + editable: true, + }); + + const spy = mockTracking('_category_', wrapper.element, jest.spyOn); + triggerEvent('.js-sidebar-dropdown-toggle'); + + expect(spy).toHaveBeenCalledWith('_category_', 'click_edit_button', { + label: 'right_sidebar', + property: 'reviewer', + }); + }); +}); diff --git a/spec/frontend/sidebar/reviewers_spec.js b/spec/frontend/sidebar/reviewers_spec.js new file mode 100644 index 00000000000..effcac266f0 --- /dev/null +++ b/spec/frontend/sidebar/reviewers_spec.js @@ -0,0 +1,169 @@ +import { mount } from '@vue/test-utils'; +import { trimText } from 'helpers/text_helper'; +import { GlIcon } from '@gitlab/ui'; +import Reviewer from '~/sidebar/components/reviewers/reviewers.vue'; +import UsersMock from './mock_data'; +import UsersMockHelper from '../helpers/user_mock_data_helper'; + +describe('Reviewer component', () => { + const getDefaultProps = () => ({ + rootPath: 'http://localhost:3000', + users: [], + editable: false, + }); + let wrapper; + + const createWrapper = (propsData = getDefaultProps()) => { + wrapper = mount(Reviewer, { + propsData, + }); + }; + + const findCollapsedChildren = () => wrapper.findAll('.sidebar-collapsed-icon > *'); + + afterEach(() => { + wrapper.destroy(); + }); + + describe('No reviewers/users', () => { + it('displays no reviewer icon when collapsed', () => { + createWrapper(); + const collapsedChildren = findCollapsedChildren(); + const userIcon = collapsedChildren.at(0).find(GlIcon); + + expect(collapsedChildren.length).toBe(1); + expect(collapsedChildren.at(0).attributes('aria-label')).toBe('None'); + expect(userIcon.exists()).toBe(true); + expect(userIcon.props('name')).toBe('user'); + }); + }); + + describe('One reviewer/user', () => { + it('displays one reviewer icon when collapsed', () => { + createWrapper({ + ...getDefaultProps(), + users: [UsersMock.user], + }); + + const collapsedChildren = findCollapsedChildren(); + const reviewer = collapsedChildren.at(0); + + expect(collapsedChildren.length).toBe(1); + expect(reviewer.find('.avatar').attributes('src')).toBe(UsersMock.user.avatar); + expect(reviewer.find('.avatar').attributes('alt')).toBe(`${UsersMock.user.name}'s avatar`); + + expect(trimText(reviewer.find('.author').text())).toBe(UsersMock.user.name); + }); + }); + + describe('Two or more reviewers/users', () => { + it('displays two reviewer icons when collapsed', () => { + const users = UsersMockHelper.createNumberRandomUsers(2); + createWrapper({ + ...getDefaultProps(), + users, + }); + + const collapsedChildren = findCollapsedChildren(); + + expect(collapsedChildren.length).toBe(2); + + const first = collapsedChildren.at(0); + + expect(first.find('.avatar').attributes('src')).toBe(users[0].avatar_url); + expect(first.find('.avatar').attributes('alt')).toBe(`${users[0].name}'s avatar`); + + expect(trimText(first.find('.author').text())).toBe(users[0].name); + + const second = collapsedChildren.at(1); + + expect(second.find('.avatar').attributes('src')).toBe(users[1].avatar_url); + expect(second.find('.avatar').attributes('alt')).toBe(`${users[1].name}'s avatar`); + + expect(trimText(second.find('.author').text())).toBe(users[1].name); + }); + + it('displays one reviewer icon and counter when collapsed', () => { + const users = UsersMockHelper.createNumberRandomUsers(3); + createWrapper({ + ...getDefaultProps(), + users, + }); + + const collapsedChildren = findCollapsedChildren(); + + expect(collapsedChildren.length).toBe(2); + + const first = collapsedChildren.at(0); + + expect(first.find('.avatar').attributes('src')).toBe(users[0].avatar_url); + expect(first.find('.avatar').attributes('alt')).toBe(`${users[0].name}'s avatar`); + + expect(trimText(first.find('.author').text())).toBe(users[0].name); + + const second = collapsedChildren.at(1); + + expect(trimText(second.find('.avatar-counter').text())).toBe('+2'); + }); + + it('Shows two reviewers', () => { + const users = UsersMockHelper.createNumberRandomUsers(2); + createWrapper({ + ...getDefaultProps(), + users, + editable: true, + }); + + expect(wrapper.findAll('.user-item').length).toBe(users.length); + expect(wrapper.find('.user-list-more').exists()).toBe(false); + }); + + it('shows sorted reviewer where "can merge" users are sorted first', () => { + const users = UsersMockHelper.createNumberRandomUsers(3); + users[0].can_merge = false; + users[1].can_merge = false; + users[2].can_merge = true; + + createWrapper({ + ...getDefaultProps(), + users, + editable: true, + }); + + expect(wrapper.vm.sortedReviewers[0].can_merge).toBe(true); + }); + + it('passes the sorted reviewers to the uncollapsed-reviewer-list', () => { + const users = UsersMockHelper.createNumberRandomUsers(3); + users[0].can_merge = false; + users[1].can_merge = false; + users[2].can_merge = true; + + createWrapper({ + ...getDefaultProps(), + users, + }); + + const userItems = wrapper.findAll('.user-list .user-item a'); + + expect(userItems.length).toBe(3); + expect(userItems.at(0).attributes('title')).toBe(users[2].name); + }); + + it('passes the sorted reviewers to the collapsed-reviewer-list', () => { + const users = UsersMockHelper.createNumberRandomUsers(3); + users[0].can_merge = false; + users[1].can_merge = false; + users[2].can_merge = true; + + createWrapper({ + ...getDefaultProps(), + users, + }); + + const collapsedButton = wrapper.find('.sidebar-collapsed-user button'); + + expect(trimText(collapsedButton.text())).toBe(users[2].name); + }); + }); +}); diff --git a/spec/frontend/sidebar/sidebar_labels_spec.js b/spec/frontend/sidebar/sidebar_labels_spec.js index 29333a344e1..9d59dc750fb 100644 --- a/spec/frontend/sidebar/sidebar_labels_spec.js +++ b/spec/frontend/sidebar/sidebar_labels_spec.js @@ -114,7 +114,7 @@ describe('sidebar labels', () => { const expected = { [defaultProps.issuableType]: { - label_ids: [27, 28, 40], + label_ids: [27, 28, 29, 40], }, }; diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js index 0df562f97ab..9057ffaea45 100644 --- a/spec/frontend/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js +++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js @@ -492,19 +492,6 @@ describe('ReadyToMerge', () => { }); }); - it('hides close button', done => { - jest.spyOn(vm.service, 'poll').mockReturnValue(returnPromise('merged')); - jest.spyOn(vm, 'initiateRemoveSourceBranchPolling').mockImplementation(() => {}); - - vm.handleMergePolling(() => {}, () => {}); - - setImmediate(() => { - expect(document.querySelector('.btn-close').classList.contains('hidden')).toBeTruthy(); - - done(); - }); - }); - it('updates merge request count badge', done => { jest.spyOn(vm.service, 'poll').mockReturnValue(returnPromise('merged')); jest.spyOn(vm, 'initiateRemoveSourceBranchPolling').mockImplementation(() => {}); diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js index 4be28a6b360..a9350bc059d 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js @@ -69,6 +69,16 @@ describe('DropdownContentsLabelsView', () => { expect(wrapper.vm.visibleLabels[0].title).toBe('Bug'); }); + it('returns matching labels with fuzzy filtering', () => { + wrapper.setData({ + searchKey: 'bg', + }); + + expect(wrapper.vm.visibleLabels.length).toBe(2); + expect(wrapper.vm.visibleLabels[0].title).toBe('Bug'); + expect(wrapper.vm.visibleLabels[1].title).toBe('Boog'); + }); + it('returns all labels when `searchKey` is empty', () => { wrapper.setData({ searchKey: '', diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/mock_data.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/mock_data.js index e1008d13fc2..9697d6c30f2 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/mock_data.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/mock_data.js @@ -24,6 +24,13 @@ export const mockLabels = [ color: '#FF0000', textColor: '#FFFFFF', }, + { + id: 29, + title: 'Boog', + description: 'Label for bugs', + color: '#FF0000', + textColor: '#FFFFFF', + }, ]; export const mockConfig = { |