diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-13 18:10:17 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-13 18:10:17 +0300 |
commit | effc12bf9dac4bf1e48f1397c25e0381ac1bd76f (patch) | |
tree | e2ff447fff4e156a94b684df6edddc108a767365 /spec | |
parent | c3eeb6a8d6a4b11f0bc5e5eb1ed43b0726f1ea26 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
14 files changed, 124 insertions, 350 deletions
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb index d3b43029f2a..5f0d697b1e0 100644 --- a/spec/features/admin/admin_settings_spec.rb +++ b/spec/features/admin/admin_settings_spec.rb @@ -116,7 +116,7 @@ RSpec.describe 'Admin updates settings', feature_category: :shared do it 'change Maximum export size' do page.within(find('[data-testid="account-limit"]')) do - fill_in 'Maximum export size (MB)', with: 25 + fill_in 'Maximum export size (MiB)', with: 25 click_button 'Save changes' end @@ -126,7 +126,7 @@ RSpec.describe 'Admin updates settings', feature_category: :shared do it 'change Maximum import size' do page.within(find('[data-testid="account-limit"]')) do - fill_in 'Maximum import size (MB)', with: 15 + fill_in 'Maximum import size (MiB)', with: 15 click_button 'Save changes' end @@ -905,7 +905,7 @@ RSpec.describe 'Admin updates settings', feature_category: :shared do it 'change Pages settings' do page.within('.as-pages') do - fill_in 'Maximum size of pages (MB)', with: 15 + fill_in 'Maximum size of pages (MiB)', with: 15 check 'Require users to prove ownership of custom domains' click_button 'Save changes' end diff --git a/spec/features/projects/blobs/edit_spec.rb b/spec/features/projects/blobs/edit_spec.rb index 3c68f310744..e8a9edcc0cc 100644 --- a/spec/features/projects/blobs/edit_spec.rb +++ b/spec/features/projects/blobs/edit_spec.rb @@ -23,15 +23,11 @@ RSpec.describe 'Editing file blob', :js, feature_category: :groups_and_projects end def edit_and_commit(commit_changes: true, is_diff: false) - set_default_button('edit') - refresh - wait_for_requests - if is_diff first('.js-diff-more-actions').click click_link('Edit in single-file editor') else - click_link('Edit') + edit_in_single_file_editor end fill_editor(content: 'class NextFeature\\nend\\n') diff --git a/spec/features/projects/blobs/user_views_pipeline_editor_button_spec.rb b/spec/features/projects/blobs/user_views_pipeline_editor_button_spec.rb index 3e4ee13269f..bef4e5f89b1 100644 --- a/spec/features/projects/blobs/user_views_pipeline_editor_button_spec.rb +++ b/spec/features/projects/blobs/user_views_pipeline_editor_button_spec.rb @@ -19,6 +19,8 @@ RSpec.describe 'User views pipeline editor button on root ci config file', :js, project.repository.create_file(user, project.ci_config_path_or_default, 'test', message: 'testing', branch_name: 'master') visit project_blob_path(project, File.join('master', '.my-config.yml')) + click_button 'Edit' + expect(page).to have_content('Edit in pipeline editor') end @@ -26,6 +28,8 @@ RSpec.describe 'User views pipeline editor button on root ci config file', :js, project.repository.create_file(user, '.my-sub-config.yml', 'test', message: 'testing', branch_name: 'master') visit project_blob_path(project, File.join('master', '.my-sub-config.yml')) + click_button 'Edit' + expect(page).not_to have_content('Edit in pipeline editor') end end @@ -36,6 +40,9 @@ RSpec.describe 'User views pipeline editor button on root ci config file', :js, end it 'does not shows the Pipeline Editor button' do visit project_blob_path(project, File.join('master', '.my-config.yml')) + + click_button 'Edit' + expect(page).not_to have_content('Edit in pipeline editor') end end diff --git a/spec/features/projects/files/user_browses_lfs_files_spec.rb b/spec/features/projects/files/user_browses_lfs_files_spec.rb index 04094ae2d6f..d8c1c8e4f2a 100644 --- a/spec/features/projects/files/user_browses_lfs_files_spec.rb +++ b/spec/features/projects/files/user_browses_lfs_files_spec.rb @@ -71,7 +71,9 @@ RSpec.describe 'Projects > Files > User browses LFS files', feature_category: :g expect(page).not_to have_content('Annotate') expect(page).not_to have_content('Blame') - expect(page).not_to have_selector(:link_or_button, text: /^Edit$/) + click_button 'Edit' + + expect(page).not_to have_selector(:link_or_button, text: /^Edit single file$/) expect(page).to have_selector(:link_or_button, 'Open in Web IDE') end end diff --git a/spec/features/projects/files/user_creates_files_spec.rb b/spec/features/projects/files/user_creates_files_spec.rb index 7d888aabf53..de82f3062a2 100644 --- a/spec/features/projects/files/user_creates_files_spec.rb +++ b/spec/features/projects/files/user_creates_files_spec.rb @@ -105,8 +105,6 @@ RSpec.describe 'Projects > Files > User creates files', :js, feature_category: : end it 'creates and commit a new file with new lines at the end of file' do - set_default_button('edit') - editor_set_value('Sample\n\n\n') fill_in(:file_name, with: 'not_a_file.md') fill_in(:commit_message, with: 'New commit message', visible: true) @@ -116,7 +114,7 @@ RSpec.describe 'Projects > Files > User creates files', :js, feature_category: : expect(page).to have_current_path(new_file_path, ignore_query: true) - click_link('Edit') + edit_in_single_file_editor expect(find('.monaco-editor')).to have_content('Sample\n\n\n') end diff --git a/spec/features/projects/files/user_edits_files_spec.rb b/spec/features/projects/files/user_edits_files_spec.rb index acaeffe5ef4..10fa4a21359 100644 --- a/spec/features/projects/files/user_edits_files_spec.rb +++ b/spec/features/projects/files/user_edits_files_spec.rb @@ -19,10 +19,6 @@ RSpec.describe 'Projects > Files > User edits files', :js, feature_category: :gr sign_in(user) end - after do - unset_default_button - end - shared_examples 'unavailable for an archived project' do it 'does not show the edit link for an archived project', :js do project.update!(archived: true) @@ -48,9 +44,8 @@ RSpec.describe 'Projects > Files > User edits files', :js, feature_category: :gr end it 'inserts a content of a file' do - set_default_button('edit') click_link('.gitignore') - click_link_or_button('Edit') + edit_in_single_file_editor find('.file-editor', match: :first) editor_set_value('*.rbca') @@ -69,9 +64,8 @@ RSpec.describe 'Projects > Files > User edits files', :js, feature_category: :gr end it 'commits an edited file' do - set_default_button('edit') click_link('.gitignore') - click_link_or_button('Edit') + edit_in_single_file_editor find('.file-editor', match: :first) editor_set_value('*.rbca') @@ -86,9 +80,8 @@ RSpec.describe 'Projects > Files > User edits files', :js, feature_category: :gr end it 'commits an edited file to a new branch' do - set_default_button('edit') click_link('.gitignore') - click_link_or_button('Edit') + edit_in_single_file_editor find('.file-editor', match: :first) @@ -105,10 +98,8 @@ RSpec.describe 'Projects > Files > User edits files', :js, feature_category: :gr end it 'shows loader on commit changes' do - set_default_button('edit') click_link('.gitignore') - click_link_or_button('Edit') - + edit_in_single_file_editor # why: We don't want the form to actually submit, so that we can assert the button's changed state page.execute_script("document.querySelector('.js-edit-blob-form').addEventListener('submit', e => e.preventDefault())") @@ -120,9 +111,8 @@ RSpec.describe 'Projects > Files > User edits files', :js, feature_category: :gr end it 'shows the diff of an edited file' do - set_default_button('edit') click_link('.gitignore') - click_link_or_button('Edit') + edit_in_single_file_editor find('.file-editor', match: :first) editor_set_value('*.rbca') @@ -158,9 +148,8 @@ RSpec.describe 'Projects > Files > User edits files', :js, feature_category: :gr end it 'inserts a content of a file in a forked project', :sidekiq_might_not_need_inline do - set_default_button('edit') click_link('.gitignore') - click_link_or_button('Edit') + edit_in_single_file_editor expect_fork_prompt @@ -176,9 +165,8 @@ RSpec.describe 'Projects > Files > User edits files', :js, feature_category: :gr end it 'opens the Web IDE in a forked project', :sidekiq_might_not_need_inline do - set_default_button('webide') click_link('.gitignore') - click_link_or_button('Web IDE') + edit_in_web_ide expect_fork_prompt @@ -191,9 +179,8 @@ RSpec.describe 'Projects > Files > User edits files', :js, feature_category: :gr end it 'commits an edited file in a forked project', :sidekiq_might_not_need_inline do - set_default_button('edit') click_link('.gitignore') - click_link_or_button('Edit') + edit_in_single_file_editor expect_fork_prompt click_link_or_button('Fork') @@ -222,9 +209,8 @@ RSpec.describe 'Projects > Files > User edits files', :js, feature_category: :gr end it 'links to the forked project for editing', :sidekiq_might_not_need_inline do - set_default_button('edit') click_link('.gitignore') - click_link_or_button('Edit') + edit_in_single_file_editor expect(page).not_to have_link('Fork') diff --git a/spec/features/projects/show/user_sees_collaboration_links_spec.rb b/spec/features/projects/show/user_sees_collaboration_links_spec.rb index a86bc0ae97a..29fb20841fd 100644 --- a/spec/features/projects/show/user_sees_collaboration_links_spec.rb +++ b/spec/features/projects/show/user_sees_collaboration_links_spec.rb @@ -51,7 +51,8 @@ RSpec.describe 'Projects > Show > Collaboration links', :js, feature_category: : end # The Web IDE - expect(page).to have_link('Web IDE') + click_button 'Edit' + expect(page).to have_button('Web IDE') end it 'hides the links when the project is archived' do @@ -73,7 +74,7 @@ RSpec.describe 'Projects > Show > Collaboration links', :js, feature_category: : expect(page).not_to have_selector('[data-testid="add-to-tree"]') - expect(page).not_to have_link('Web IDE') + expect(page).not_to have_button('Edit') end end @@ -95,7 +96,7 @@ RSpec.describe 'Projects > Show > Collaboration links', :js, feature_category: : end it "updates Web IDE link" do - expect(page.has_link?('Web IDE')).to be(expect_ide_link) + expect(page.has_button?('Edit')).to be(expect_ide_link) end end end diff --git a/spec/frontend/batch_comments/stores/modules/batch_comments/actions_spec.js b/spec/frontend/batch_comments/stores/modules/batch_comments/actions_spec.js index 57bafb51cd6..521bbf06b02 100644 --- a/spec/frontend/batch_comments/stores/modules/batch_comments/actions_spec.js +++ b/spec/frontend/batch_comments/stores/modules/batch_comments/actions_spec.js @@ -70,6 +70,19 @@ describe('Batch comments store actions', () => { ); }); + it('dispatchs addDraftToFile if draft is on file', () => { + res = { id: 1, position: { position_type: 'file' }, file_path: 'index.js' }; + mock.onAny().reply(HTTP_STATUS_OK, res); + + return testAction( + actions.createNewDraft, + { endpoint: TEST_HOST, data: 'test' }, + null, + [{ type: 'ADD_NEW_DRAFT', payload: res }], + [{ type: 'diffs/addDraftToFile', payload: { draft: res, filePath: 'index.js' } }], + ); + }); + it('does not commit ADD_NEW_DRAFT if errors returned', () => { mock.onAny().reply(HTTP_STATUS_INTERNAL_SERVER_ERROR); diff --git a/spec/frontend/feature_flags/components/strategies/gitlab_user_list_spec.js b/spec/frontend/feature_flags/components/strategies/gitlab_user_list_spec.js index 96b9434f3ec..133796df3e4 100644 --- a/spec/frontend/feature_flags/components/strategies/gitlab_user_list_spec.js +++ b/spec/frontend/feature_flags/components/strategies/gitlab_user_list_spec.js @@ -1,4 +1,4 @@ -import { GlDropdown, GlDropdownItem, GlSearchBoxByType, GlLoadingIcon } from '@gitlab/ui'; +import { GlCollapsibleListbox, GlListboxItem } from '@gitlab/ui'; import { mount } from '@vue/test-utils'; import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; @@ -24,11 +24,10 @@ describe('~/feature_flags/components/strategies/gitlab_user_list.vue', () => { propsData: { ...DEFAULT_PROPS, ...props }, }); - const findDropdown = () => wrapper.findComponent(GlDropdown); + const findDropdown = () => wrapper.findComponent(GlCollapsibleListbox); + const findGlListboxItem = () => wrapper.findAllComponents(GlListboxItem).at(0); describe('with user lists', () => { - const findDropdownItem = () => wrapper.findComponent(GlDropdownItem); - beforeEach(() => { Api.searchFeatureFlagUserLists.mockResolvedValue({ data: [userList] }); wrapper = factory(); @@ -37,22 +36,19 @@ describe('~/feature_flags/components/strategies/gitlab_user_list.vue', () => { it('should show the input for userListId with the correct value', () => { const dropdownWrapper = findDropdown(); expect(dropdownWrapper.exists()).toBe(true); - expect(dropdownWrapper.props('text')).toBe(userList.name); + expect(dropdownWrapper.props('toggleText')).toBe(userList.name); }); it('should show a check for the selected list', () => { - const itemWrapper = findDropdownItem(); - expect(itemWrapper.props('isChecked')).toBe(true); + expect(findGlListboxItem().props('isSelected')).toBe(true); }); it('should display the name of the list in the drop;down', () => { - const itemWrapper = findDropdownItem(); - expect(itemWrapper.text()).toBe(userList.name); + expect(findGlListboxItem().text()).toBe(userList.name); }); it('should emit a change event when altering the userListId', () => { - const inputWrapper = findDropdownItem(); - inputWrapper.vm.$emit('click'); + findDropdown().vm.$emit('select', userList.id); expect(wrapper.emitted('change')).toEqual([ [ { @@ -63,25 +59,19 @@ describe('~/feature_flags/components/strategies/gitlab_user_list.vue', () => { }); it('should search when the filter changes', async () => { + findDropdown().vm.$emit('search', 'new'); let r; Api.searchFeatureFlagUserLists.mockReturnValue( new Promise((resolve) => { r = resolve; }), ); - const searchWrapper = wrapper.findComponent(GlSearchBoxByType); - searchWrapper.vm.$emit('input', 'new'); - await nextTick(); - const loadingIcon = wrapper.findComponent(GlLoadingIcon); - expect(loadingIcon.exists()).toBe(true); expect(Api.searchFeatureFlagUserLists).toHaveBeenCalledWith('1', 'new'); r({ data: [userList] }); await nextTick(); - - expect(loadingIcon.exists()).toBe(false); }); }); diff --git a/spec/frontend/vue_shared/components/actions_button_spec.js b/spec/frontend/vue_shared/components/actions_button_spec.js index 8c2f2b52f8e..e7663e2adb2 100644 --- a/spec/frontend/vue_shared/components/actions_button_spec.js +++ b/spec/frontend/vue_shared/components/actions_button_spec.js @@ -1,12 +1,15 @@ -import { GlDropdown, GlDropdownDivider, GlButton, GlTooltip } from '@gitlab/ui'; -import { shallowMount } from '@vue/test-utils'; +import { + GlDisclosureDropdown, + GlDisclosureDropdownGroup, + GlDisclosureDropdownItem, +} from '@gitlab/ui'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import ActionsButton from '~/vue_shared/components/actions_button.vue'; const TEST_ACTION = { key: 'action1', text: 'Sample', secondaryText: 'Lorem ipsum.', - tooltip: '', href: '/sample', attrs: { 'data-test': '123', @@ -14,191 +17,75 @@ const TEST_ACTION = { href: '/sample', variant: 'default', }, + handle: jest.fn(), }; const TEST_ACTION_2 = { key: 'action2', text: 'Sample 2', secondaryText: 'Dolar sit amit.', - tooltip: 'Dolar sit amit.', href: '#', attrs: { 'data-test': '456' }, + handle: jest.fn(), }; -const TEST_TOOLTIP = 'Lorem ipsum dolar sit'; -describe('Actions button component', () => { +describe('vue_shared/components/actions_button', () => { let wrapper; function createComponent(props) { - wrapper = shallowMount(ActionsButton, { - propsData: { ...props }, + wrapper = shallowMountExtended(ActionsButton, { + propsData: { actions: [TEST_ACTION, TEST_ACTION_2], toggleText: 'Edit', ...props }, + stubs: { + GlDisclosureDropdownItem, + }, }); } + const findDropdown = () => wrapper.findComponent(GlDisclosureDropdown); - const findButton = () => wrapper.findComponent(GlButton); - const findTooltip = () => wrapper.findComponent(GlTooltip); - const findDropdown = () => wrapper.findComponent(GlDropdown); - const parseDropdownItems = () => - findDropdown() - .findAll('gl-dropdown-item-stub,gl-dropdown-divider-stub') - .wrappers.map((x) => { - if (x.is(GlDropdownDivider)) { - return { type: 'divider' }; - } - - const { isCheckItem, isChecked, secondaryText } = x.props(); - - return { - type: 'item', - isCheckItem, - isChecked, - secondaryText, - text: x.text(), - }; - }); - const clickOn = (child, evt = new Event('click')) => child.vm.$emit('click', evt); - const clickLink = (...args) => clickOn(findButton(), ...args); - const clickDropdown = (...args) => clickOn(findDropdown(), ...args); - - describe('with 1 action', () => { - beforeEach(() => { - createComponent({ actions: [TEST_ACTION] }); - }); - - it('should not render dropdown', () => { - expect(findDropdown().exists()).toBe(false); - }); - - it('should render single button', () => { - expect(findButton().attributes()).toMatchObject({ - href: TEST_ACTION.href, - ...TEST_ACTION.attrs, - }); - expect(findButton().text()).toBe(TEST_ACTION.text); - }); - - it('should not have tooltip', () => { - expect(findTooltip().exists()).toBe(false); - }); + it('dropdown toggle displays provided toggleLabel', () => { + createComponent(); - it('should have attrs', () => { - expect(findButton().attributes()).toMatchObject(TEST_ACTION.attrs); - }); - - it('can click', () => { - expect(clickLink).not.toThrow(); - }); + expect(findDropdown().props().toggleText).toBe('Edit'); }); - describe('with 1 action with tooltip', () => { - it('should have tooltip', () => { - createComponent({ actions: [{ ...TEST_ACTION, tooltip: TEST_TOOLTIP }] }); + it('allows customizing variant and category', () => { + const variant = 'confirm'; + const category = 'secondary'; - expect(findTooltip().text()).toBe(TEST_TOOLTIP); - }); + createComponent({ variant, category }); + + expect(findDropdown().props()).toMatchObject({ category, variant }); }); - describe('when showActionTooltip is false', () => { - it('should not have tooltip', () => { - createComponent({ - actions: [{ ...TEST_ACTION, tooltip: TEST_TOOLTIP }], - showActionTooltip: false, - }); + it('displays a single dropdown group', () => { + createComponent(); - expect(findTooltip().exists()).toBe(false); - }); + expect(wrapper.findAllComponents(GlDisclosureDropdownGroup)).toHaveLength(1); }); - describe('with 1 action with handle', () => { - it('can click and trigger handle', () => { - const handleClick = jest.fn(); - createComponent({ actions: [{ ...TEST_ACTION, handle: handleClick }] }); + it('create dropdown items for every action', () => { + createComponent(); - const event = new Event('click'); - clickLink(event); + [TEST_ACTION, TEST_ACTION_2].forEach((action, index) => { + const dropdownItem = wrapper.findAllComponents(GlDisclosureDropdownItem).at(index); - expect(handleClick).toHaveBeenCalledWith(event); + expect(dropdownItem.props().item).toBe(action); + expect(dropdownItem.attributes()).toMatchObject(action.attrs); + expect(dropdownItem.text()).toContain(action.text); + expect(dropdownItem.text()).toContain(action.secondaryText); }); }); - describe('with multiple actions', () => { - let handleAction; + describe('when clicking a dropdown item', () => { + it("invokes the action's handle method", () => { + createComponent(); - beforeEach(() => { - handleAction = jest.fn(); + [TEST_ACTION, TEST_ACTION_2].forEach((action, index) => { + const dropdownItem = wrapper.findAllComponents(GlDisclosureDropdownItem).at(index); - createComponent({ actions: [{ ...TEST_ACTION, handle: handleAction }, TEST_ACTION_2] }); - }); + dropdownItem.vm.$emit('action'); - it('should default to selecting first action', () => { - expect(findDropdown().attributes()).toMatchObject({ - text: TEST_ACTION.text, - 'split-href': TEST_ACTION.href, + expect(action.handle).toHaveBeenCalled(); }); }); - - it('should handle first action click', () => { - const event = new Event('click'); - - clickDropdown(event); - - expect(handleAction).toHaveBeenCalledWith(event); - }); - - it('should render dropdown items', () => { - expect(parseDropdownItems()).toEqual([ - { - type: 'item', - isCheckItem: true, - isChecked: true, - secondaryText: TEST_ACTION.secondaryText, - text: TEST_ACTION.text, - }, - { type: 'divider' }, - { - type: 'item', - isCheckItem: true, - isChecked: false, - secondaryText: TEST_ACTION_2.secondaryText, - text: TEST_ACTION_2.text, - }, - ]); - }); - - it('should select action 2 when clicked', () => { - expect(wrapper.emitted('select')).toBeUndefined(); - - const action2 = wrapper.find(`[data-testid="action_${TEST_ACTION_2.key}"]`); - action2.vm.$emit('click'); - - expect(wrapper.emitted('select')).toEqual([[TEST_ACTION_2.key]]); - }); - - it('should not have tooltip value', () => { - expect(findTooltip().exists()).toBe(false); - }); - }); - - describe('with multiple actions and selectedKey', () => { - beforeEach(() => { - createComponent({ actions: [TEST_ACTION, TEST_ACTION_2], selectedKey: TEST_ACTION_2.key }); - }); - - it('should show action 2 as selected', () => { - expect(parseDropdownItems()).toEqual([ - expect.objectContaining({ - type: 'item', - isChecked: false, - }), - { type: 'divider' }, - expect.objectContaining({ - type: 'item', - isChecked: true, - }), - ]); - }); - - it('should have tooltip value', () => { - expect(findTooltip().text()).toBe(TEST_ACTION_2.tooltip); - }); }); }); diff --git a/spec/frontend/vue_shared/components/web_ide_link_spec.js b/spec/frontend/vue_shared/components/web_ide_link_spec.js index d888abc19ef..26557c63a77 100644 --- a/spec/frontend/vue_shared/components/web_ide_link_spec.js +++ b/spec/frontend/vue_shared/components/web_ide_link_spec.js @@ -1,19 +1,12 @@ -import { GlButton, GlModal } from '@gitlab/ui'; +import { GlModal } from '@gitlab/ui'; import { nextTick } from 'vue'; import ActionsButton from '~/vue_shared/components/actions_button.vue'; -import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue'; -import WebIdeLink, { - i18n, - PREFERRED_EDITOR_RESET_KEY, - PREFERRED_EDITOR_KEY, -} from '~/vue_shared/components/web_ide_link.vue'; +import WebIdeLink, { i18n } from '~/vue_shared/components/web_ide_link.vue'; import ConfirmForkModal from '~/vue_shared/components/confirm_fork_modal.vue'; -import { KEY_WEB_IDE } from '~/vue_shared/components/constants'; import { stubComponent } from 'helpers/stub_component'; import { shallowMountExtended, mountExtended } from 'helpers/vue_test_utils_helper'; -import { useLocalStorageSpy } from 'helpers/local_storage_helper'; import { visitUrl } from '~/lib/utils/url_utility'; @@ -30,9 +23,8 @@ const forkPath = '/some/fork/path'; const ACTION_EDIT = { href: TEST_EDIT_URL, key: 'edit', - text: 'Edit', + text: 'Edit single file', secondaryText: 'Edit this file only.', - tooltip: '', attrs: { 'data-qa-selector': 'edit_button', 'data-track-action': 'click_consolidated_edit', @@ -45,10 +37,8 @@ const ACTION_EDIT_CONFIRM_FORK = { handle: expect.any(Function), }; const ACTION_WEB_IDE = { - href: TEST_WEB_IDE_URL, key: 'webide', secondaryText: i18n.webIdeText, - tooltip: i18n.webIdeTooltip, text: 'Web IDE', attrs: { 'data-qa-selector': 'web_ide_button', @@ -59,7 +49,6 @@ const ACTION_WEB_IDE = { }; const ACTION_WEB_IDE_CONFIRM_FORK = { ...ACTION_WEB_IDE, - href: '#modal-confirm-fork-webide', handle: expect.any(Function), }; const ACTION_WEB_IDE_EDIT_FORK = { ...ACTION_WEB_IDE, text: 'Edit fork in Web IDE' }; @@ -67,7 +56,6 @@ const ACTION_GITPOD = { href: TEST_GITPOD_URL, key: 'gitpod', secondaryText: 'Launch a ready-to-code development environment for your project.', - tooltip: 'Launch a ready-to-code development environment for your project.', text: 'Gitpod', attrs: { 'data-qa-selector': 'gitpod_button', @@ -82,16 +70,13 @@ const ACTION_PIPELINE_EDITOR = { href: TEST_PIPELINE_EDITOR_URL, key: 'pipeline_editor', secondaryText: 'Edit, lint, and visualize your pipeline.', - tooltip: 'Edit, lint, and visualize your pipeline.', text: 'Edit in pipeline editor', attrs: { 'data-qa-selector': 'pipeline_editor_button', }, }; -describe('Web IDE link component', () => { - useLocalStorageSpy(); - +describe('vue_shared/components/web_ide_link', () => { let wrapper; function createComponent(props, { mountFn = shallowMountExtended, glFeatures = {} } = {}) { @@ -120,12 +105,7 @@ describe('Web IDE link component', () => { }); } - beforeEach(() => { - localStorage.setItem(PREFERRED_EDITOR_RESET_KEY, 'true'); - }); - const findActionsButton = () => wrapper.findComponent(ActionsButton); - const findLocalStorageSync = () => wrapper.findComponent(LocalStorageSync); const findModal = () => wrapper.findComponent(GlModal); const findForkConfirmModal = () => wrapper.findComponent(ConfirmForkModal); @@ -238,64 +218,16 @@ describe('Web IDE link component', () => { }); }); - it('selected Pipeline Editor by default', () => { + it('displays Pipeline Editor as the first action', () => { expect(findActionsButton().props()).toMatchObject({ actions: [ACTION_PIPELINE_EDITOR, ACTION_WEB_IDE, ACTION_GITPOD], - selectedKey: ACTION_PIPELINE_EDITOR.key, }); }); it('when web ide button is clicked it opens in a new tab', async () => { - findActionsButton().props('actions')[1].handle({ - preventDefault: jest.fn(), - }); - await nextTick(); - expect(visitUrl).toHaveBeenCalledWith(ACTION_WEB_IDE.href, true); - }); - }); - - describe('with multiple actions', () => { - beforeEach(() => { - createComponent({ - showEditButton: false, - showWebIdeButton: true, - showGitpodButton: true, - showPipelineEditorButton: false, - userPreferencesGitpodPath: TEST_USER_PREFERENCES_GITPOD_PATH, - userProfileEnableGitpodPath: TEST_USER_PROFILE_ENABLE_GITPOD_PATH, - gitpodEnabled: true, - }); - }); - - it('selected Web IDE by default', () => { - expect(findActionsButton().props()).toMatchObject({ - actions: [ACTION_WEB_IDE, ACTION_GITPOD], - selectedKey: ACTION_WEB_IDE.key, - }); - }); - - it('should set selection with local storage value', async () => { - expect(findActionsButton().props('selectedKey')).toBe(ACTION_WEB_IDE.key); - - findLocalStorageSync().vm.$emit('input', ACTION_GITPOD.key); - + findActionsButton().props('actions')[1].handle(); await nextTick(); - - expect(findActionsButton().props('selectedKey')).toBe(ACTION_GITPOD.key); - }); - - it('should update local storage when selection changes', async () => { - expect(findLocalStorageSync().props()).toMatchObject({ - asString: true, - value: ACTION_WEB_IDE.key, - }); - - findActionsButton().vm.$emit('select', ACTION_GITPOD.key); - - await nextTick(); - - expect(findActionsButton().props('selectedKey')).toBe(ACTION_GITPOD.key); - expect(findLocalStorageSync().props('value')).toBe(ACTION_GITPOD.key); + expect(visitUrl).toHaveBeenCalledWith(TEST_WEB_IDE_URL, true); }); }); @@ -348,7 +280,10 @@ describe('Web IDE link component', () => { it.each(testActions)('opens the modal when the button is clicked', async ({ props }) => { createComponent({ ...props, needsToFork: true }, { mountFn: mountExtended }); - await findActionsButton().findComponent(GlButton).trigger('click'); + wrapper.findComponent(ActionsButton).props().actions[0].handle(); + + await nextTick(); + await wrapper.findByRole('button', { name: /Web IDE|Edit/im }).trigger('click'); expect(findForkConfirmModal().props()).toEqual({ visible: true, @@ -404,10 +339,8 @@ describe('Web IDE link component', () => { { mountFn: mountExtended }, ); - findLocalStorageSync().vm.$emit('input', ACTION_GITPOD.key); - await nextTick(); - await wrapper.findByRole('button', { name: gitpodText }).trigger('click'); + await wrapper.findByRole('button', { name: new RegExp(gitpodText, 'm') }).trigger('click'); expect(findModal().props('visible')).toBe(true); }); @@ -425,58 +358,4 @@ describe('Web IDE link component', () => { expect(findModal().exists()).toBe(false); }); }); - - describe('when vscode_web_ide feature flag is enabled', () => { - describe('when is not showing edit button', () => { - describe(`when ${PREFERRED_EDITOR_RESET_KEY} is unset`, () => { - beforeEach(() => { - localStorage.setItem.mockReset(); - localStorage.getItem.mockReturnValueOnce(null); - createComponent({ showEditButton: false }, { glFeatures: { vscodeWebIde: true } }); - }); - - it(`sets ${PREFERRED_EDITOR_KEY} local storage key to ${KEY_WEB_IDE}`, () => { - expect(localStorage.getItem).toHaveBeenCalledWith(PREFERRED_EDITOR_RESET_KEY); - expect(localStorage.setItem).toHaveBeenCalledWith(PREFERRED_EDITOR_KEY, KEY_WEB_IDE); - }); - - it(`sets ${PREFERRED_EDITOR_RESET_KEY} local storage key to true`, () => { - expect(localStorage.setItem).toHaveBeenCalledWith(PREFERRED_EDITOR_RESET_KEY, true); - }); - - it(`selects ${KEY_WEB_IDE} as the preferred editor`, () => { - expect(findActionsButton().props().selectedKey).toBe(KEY_WEB_IDE); - }); - }); - - describe(`when ${PREFERRED_EDITOR_RESET_KEY} is set to true`, () => { - beforeEach(() => { - localStorage.setItem.mockReset(); - localStorage.getItem.mockReturnValueOnce('true'); - createComponent({ showEditButton: false }, { glFeatures: { vscodeWebIde: true } }); - }); - - it(`does not update the persisted preferred editor`, () => { - expect(localStorage.getItem).toHaveBeenCalledWith(PREFERRED_EDITOR_RESET_KEY); - expect(localStorage.setItem).not.toHaveBeenCalledWith(PREFERRED_EDITOR_RESET_KEY); - }); - }); - }); - - describe('when is showing the edit button', () => { - it(`does not try to reset the ${PREFERRED_EDITOR_KEY}`, () => { - createComponent({ showEditButton: true }, { glFeatures: { vscodeWebIde: true } }); - - expect(localStorage.getItem).not.toHaveBeenCalledWith(PREFERRED_EDITOR_RESET_KEY); - }); - }); - }); - - describe('when vscode_web_ide feature flag is disabled', () => { - it(`does not try to reset the ${PREFERRED_EDITOR_KEY}`, () => { - createComponent({}, { glFeatures: { vscodeWebIde: false } }); - - expect(localStorage.getItem).not.toHaveBeenCalledWith(PREFERRED_EDITOR_RESET_KEY); - }); - }); }); diff --git a/spec/lib/gitlab/database/postgres_autovacuum_activity_spec.rb b/spec/lib/gitlab/database/postgres_autovacuum_activity_spec.rb index f24c4559349..5367cf1fb9b 100644 --- a/spec/lib/gitlab/database/postgres_autovacuum_activity_spec.rb +++ b/spec/lib/gitlab/database/postgres_autovacuum_activity_spec.rb @@ -28,5 +28,15 @@ RSpec.describe Gitlab::Database::PostgresAutovacuumActivity, type: :model, featu it 'returns autovacuum activity for queries tables' do expect(subject.map(&:table).sort).to eq(tables) end + + it 'executes the query' do + is_expected.to be_a Array + end + end + + describe '.wraparound_prevention' do + subject { described_class.wraparound_prevention } + + it { expect(subject.where_values_hash).to match(a_hash_including('wraparound_prevention' => true)) } end end diff --git a/spec/support/helpers/features/blob_spec_helpers.rb b/spec/support/helpers/features/blob_spec_helpers.rb index 8254e1d76bd..91969107a17 100644 --- a/spec/support/helpers/features/blob_spec_helpers.rb +++ b/spec/support/helpers/features/blob_spec_helpers.rb @@ -5,12 +5,14 @@ module Features module BlobSpecHelpers include ActionView::Helpers::JavaScriptHelper - def set_default_button(type) - evaluate_script("localStorage.setItem('gl-web-ide-button-selected', '#{type}')") + def edit_in_single_file_editor + click_button 'Edit' + click_link_or_button 'Edit single file' end - def unset_default_button - set_default_button('') + def edit_in_web_ide + click_button 'Edit' + click_link_or_button 'Web IDE' end end end diff --git a/spec/support/helpers/features/web_ide_spec_helpers.rb b/spec/support/helpers/features/web_ide_spec_helpers.rb index c51116b55b2..32b27864e0b 100644 --- a/spec/support/helpers/features/web_ide_spec_helpers.rb +++ b/spec/support/helpers/features/web_ide_spec_helpers.rb @@ -12,6 +12,7 @@ module Features module WebIdeSpecHelpers include Features::SourceEditorSpecHelpers + include Features::BlobSpecHelpers # Open the IDE from anywhere by first visiting the given project's page def ide_visit(project) @@ -21,8 +22,10 @@ module Features end # Open the IDE from the current page by clicking the Web IDE link - def ide_visit_from_link(link_sel = 'Web IDE') - new_tab = window_opened_by { click_link(link_sel) } + def ide_visit_from_link + new_tab = window_opened_by do + edit_in_web_ide + end switch_to_window new_tab end |