diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-02 09:07:56 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-02 09:07:56 +0300 |
commit | d6209de6f888f6eedb7cdea8d4a356f778fd8e4b (patch) | |
tree | 401967a319ffed321666433e7e2472b862af3da5 | |
parent | 9a2f2c662033adfe4aaf12c4d407f452789c4e01 (diff) |
Add latest changes from gitlab-org/gitlab@master
20 files changed, 363 insertions, 33 deletions
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index fc6727dfc98..61f3a3a5ccc 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -78afcc347d19840f86d35967f35e1f7899080247 +a4415cf7cb934cd333a3c3f6ee7c749306edd925 diff --git a/app/assets/javascripts/ci/pipeline_editor/components/drawer/pipeline_editor_drawer.vue b/app/assets/javascripts/ci/pipeline_editor/components/drawer/pipeline_editor_drawer.vue index 375db7f3054..ea7201efcd9 100644 --- a/app/assets/javascripts/ci/pipeline_editor/components/drawer/pipeline_editor_drawer.vue +++ b/app/assets/javascripts/ci/pipeline_editor/components/drawer/pipeline_editor_drawer.vue @@ -1,6 +1,8 @@ <script> import { GlDrawer } from '@gitlab/ui'; +import { getContentWrapperHeight } from '~/lib/utils/dom_utils'; import { __ } from '~/locale'; +import { DRAWER_CONTAINER_CLASS } from '../job_assistant_drawer/constants'; import FirstPipelineCard from './cards/first_pipeline_card.vue'; import GettingStartedCard from './cards/getting_started_card.vue'; import PipelineConfigReferenceCard from './cards/pipeline_config_reference_card.vue'; @@ -26,14 +28,15 @@ export default { required: false, default: false, }, + zIndex: { + type: Number, + required: false, + default: 200, + }, }, computed: { - drawerCardStyles() { - return ''; - }, drawerHeightOffset() { - const wrapperEl = document.querySelector('.content-wrapper'); - return wrapperEl ? `${wrapperEl.offsetTop}px` : ''; + return getContentWrapperHeight(DRAWER_CONTAINER_CLASS); }, }, methods: { @@ -47,7 +50,7 @@ export default { <gl-drawer :header-height="drawerHeightOffset" :open="isVisible" - :z-index="200" + :z-index="zIndex" @close="closeDrawer" > <template #title> diff --git a/app/assets/javascripts/ci/pipeline_editor/components/editor/ci_editor_header.vue b/app/assets/javascripts/ci/pipeline_editor/components/editor/ci_editor_header.vue index 201fba837e2..b78224e93b0 100644 --- a/app/assets/javascripts/ci/pipeline_editor/components/editor/ci_editor_header.vue +++ b/app/assets/javascripts/ci/pipeline_editor/components/editor/ci_editor_header.vue @@ -1,24 +1,30 @@ <script> import { GlButton } from '@gitlab/ui'; -import { __ } from '~/locale'; +import { __, s__ } from '~/locale'; import Tracking from '~/tracking'; +import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { pipelineEditorTrackingOptions, TEMPLATE_REPOSITORY_URL } from '../../constants'; export default { i18n: { browseTemplates: __('Browse templates'), help: __('Help'), + jobAssistant: s__('JobAssistant|Job assistant'), }, TEMPLATE_REPOSITORY_URL, components: { GlButton, }, - mixins: [Tracking.mixin()], + mixins: [glFeatureFlagMixin(), Tracking.mixin()], props: { showDrawer: { type: Boolean, required: true, }, + showJobAssistantDrawer: { + type: Boolean, + required: true, + }, }, methods: { toggleDrawer() { @@ -29,6 +35,11 @@ export default { this.trackHelpDrawerClick(); } }, + toggleJobAssistantDrawer() { + this.$emit( + this.showJobAssistantDrawer ? 'close-job-assistant-drawer' : 'open-job-assistant-drawer', + ); + }, trackHelpDrawerClick() { const { label, actions } = pipelineEditorTrackingOptions; this.track(actions.openHelpDrawer, { label }); @@ -64,5 +75,15 @@ export default { > {{ $options.i18n.help }} </gl-button> + <gl-button + v-if="glFeatures.ciJobAssistantDrawer" + icon="bulb" + size="small" + data-testid="job-assistant-drawer-toggle" + data-qa-selector="job_assistant_drawer_toggle" + @click="toggleJobAssistantDrawer" + > + {{ $options.i18n.jobAssistant }} + </gl-button> </div> </template> diff --git a/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/constants.js b/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/constants.js new file mode 100644 index 00000000000..1c122fd5e38 --- /dev/null +++ b/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/constants.js @@ -0,0 +1,7 @@ +import { s__ } from '~/locale'; + +export const DRAWER_CONTAINER_CLASS = '.content-wrapper'; + +export const i18n = { + ADD_JOB: s__('JobAssistant|Add job'), +}; diff --git a/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/job_assistant_drawer.vue b/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/job_assistant_drawer.vue new file mode 100644 index 00000000000..65c87df21cb --- /dev/null +++ b/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/job_assistant_drawer.vue @@ -0,0 +1,62 @@ +<script> +import { GlDrawer, GlButton } from '@gitlab/ui'; +import { getContentWrapperHeight } from '~/lib/utils/dom_utils'; +import { DRAWER_CONTAINER_CLASS, i18n } from './constants'; + +export default { + i18n, + components: { + GlDrawer, + GlButton, + }, + props: { + isVisible: { + type: Boolean, + required: false, + default: false, + }, + zIndex: { + type: Number, + required: false, + default: 200, + }, + }, + computed: { + drawerHeightOffset() { + return getContentWrapperHeight(DRAWER_CONTAINER_CLASS); + }, + }, + methods: { + closeDrawer() { + this.$emit('close-job-assistant-drawer'); + }, + }, +}; +</script> +<template> + <gl-drawer + class="job-assistant-drawer" + :header-height="drawerHeightOffset" + :open="isVisible" + :z-index="zIndex" + @close="closeDrawer" + > + <template #title> + <h2 class="gl-m-0 gl-font-lg">{{ $options.i18n.ADD_JOB }}</h2> + </template> + <template #footer> + <div class="gl-display-flex gl-justify-content-end"> + <gl-button + category="primary" + class="gl-mr-3" + data-testid="cancel-button" + @click="closeDrawer" + >{{ __('Cancel') }}</gl-button + > + <gl-button category="primary" variant="confirm" data-testid="confirm-button">{{ + __('Add') + }}</gl-button> + </div> + </template> + </gl-drawer> +</template> diff --git a/app/assets/javascripts/ci/pipeline_editor/components/pipeline_editor_tabs.vue b/app/assets/javascripts/ci/pipeline_editor/components/pipeline_editor_tabs.vue index ed5466ff99c..fd6547468d9 100644 --- a/app/assets/javascripts/ci/pipeline_editor/components/pipeline_editor_tabs.vue +++ b/app/assets/javascripts/ci/pipeline_editor/components/pipeline_editor_tabs.vue @@ -95,6 +95,10 @@ export default { type: Boolean, required: true, }, + showJobAssistantDrawer: { + type: Boolean, + required: true, + }, }, apollo: { appStatus: { @@ -187,7 +191,11 @@ export default { @click="setCurrentTab($options.tabConstants.CREATE_TAB)" > <walkthrough-popover v-if="isNewCiConfigFile" v-on="$listeners" /> - <ci-editor-header :show-drawer="showDrawer" v-on="$listeners" /> + <ci-editor-header + :show-drawer="showDrawer" + :show-job-assistant-drawer="showJobAssistantDrawer" + v-on="$listeners" + /> <text-editor :commit-sha="commitSha" :value="ciFileContent" v-on="$listeners" /> </editor-tab> <editor-tab diff --git a/app/assets/javascripts/ci/pipeline_editor/pipeline_editor_home.vue b/app/assets/javascripts/ci/pipeline_editor/pipeline_editor_home.vue index 1972125ed56..59863edbe0b 100644 --- a/app/assets/javascripts/ci/pipeline_editor/pipeline_editor_home.vue +++ b/app/assets/javascripts/ci/pipeline_editor/pipeline_editor_home.vue @@ -3,6 +3,7 @@ import { GlModal } from '@gitlab/ui'; import { __ } from '~/locale'; import CommitSection from './components/commit/commit_section.vue'; import PipelineEditorDrawer from './components/drawer/pipeline_editor_drawer.vue'; +import JobAssistantDrawer from './components/job_assistant_drawer/job_assistant_drawer.vue'; import PipelineEditorFileNav from './components/file_nav/pipeline_editor_file_nav.vue'; import PipelineEditorFileTree from './components/file_tree/container.vue'; import PipelineEditorHeader from './components/header/pipeline_editor_header.vue'; @@ -28,6 +29,7 @@ export default { CommitSection, GlModal, PipelineEditorDrawer, + JobAssistantDrawer, PipelineEditorFileNav, PipelineEditorFileTree, PipelineEditorHeader, @@ -63,6 +65,9 @@ export default { scrollToCommitForm: false, shouldLoadNewBranch: false, showDrawer: false, + showJobAssistantDrawer: false, + drawerIndex: 200, + jobAssistantIndex: 200, showFileTree: false, showSwitchBranchModal: false, }; @@ -85,11 +90,19 @@ export default { closeDrawer() { this.showDrawer = false; }, + closeJobAssistantDrawer() { + this.showJobAssistantDrawer = false; + }, handleConfirmSwitchBranch() { this.showSwitchBranchModal = true; }, openDrawer() { this.showDrawer = true; + this.drawerIndex = this.jobAssistantIndex + 1; + }, + openJobAssistantDrawer() { + this.showJobAssistantDrawer = true; + this.jobAssistantIndex = this.drawerIndex + 1; }, toggleFileTree() { this.showFileTree = !this.showFileTree; @@ -153,9 +166,12 @@ export default { :current-tab="currentTab" :is-new-ci-config-file="isNewCiConfigFile" :show-drawer="showDrawer" + :show-job-assistant-drawer="showJobAssistantDrawer" v-on="$listeners" @open-drawer="openDrawer" @close-drawer="closeDrawer" + @open-job-assistant-drawer="openJobAssistantDrawer" + @close-job-assistant-drawer="closeJobAssistantDrawer" @set-current-tab="setCurrentTab" @walkthrough-popover-cta-clicked="setScrollToCommitForm" /> @@ -174,8 +190,15 @@ export default { /> <pipeline-editor-drawer :is-visible="showDrawer" + :z-index="drawerIndex" v-on="$listeners" @close-drawer="closeDrawer" /> + <job-assistant-drawer + :is-visible="showJobAssistantDrawer" + :z-index="jobAssistantIndex" + v-on="$listeners" + @close-job-assistant-drawer="closeJobAssistantDrawer" + /> </div> </template> diff --git a/app/assets/javascripts/work_items/components/work_item_comment_form.vue b/app/assets/javascripts/work_items/components/work_item_comment_form.vue index a38fea01d1f..e2025aebd28 100644 --- a/app/assets/javascripts/work_items/components/work_item_comment_form.vue +++ b/app/assets/javascripts/work_items/components/work_item_comment_form.vue @@ -222,7 +222,7 @@ export default { :work-item-type="workItemType" :is-project-archived="isProjectArchived" /> - <div v-else class="gl-display-flex gl-align-items-flex-start gl-flex-wrap-nowrap"> + <div v-else class="gl-relative gl-display-flex gl-align-items-flex-start gl-flex-wrap-nowrap"> <gl-avatar :src="$options.constantOptions.avatarUrl" :size="32" class="gl-mr-3" /> <form v-if="isEditing" class="common-note-form gfm-form js-main-target-form gl-flex-grow-1"> <markdown-editor @@ -250,7 +250,7 @@ export default { @click="updateWorkItem" >{{ __('Comment') }} </gl-button> - <gl-button category="tertiary" class="gl-ml-3" @click="cancelEditing" + <gl-button category="primary" class="gl-ml-3" @click="cancelEditing" >{{ __('Cancel') }} </gl-button> </form> diff --git a/app/assets/stylesheets/page_bundles/pipeline_editor.scss b/app/assets/stylesheets/page_bundles/pipeline_editor.scss index e167052a3e1..13d158b08fe 100644 --- a/app/assets/stylesheets/page_bundles/pipeline_editor.scss +++ b/app/assets/stylesheets/page_bundles/pipeline_editor.scss @@ -20,3 +20,11 @@ @include gl-display-block; top: 2px; } + +.job-assistant-drawer { + width: 100%; + + @include media-breakpoint-up(sm) { + width: 560px; + } +} diff --git a/app/controllers/projects/ci/pipeline_editor_controller.rb b/app/controllers/projects/ci/pipeline_editor_controller.rb index 1942a5fef7b..3a2bc445737 100644 --- a/app/controllers/projects/ci/pipeline_editor_controller.rb +++ b/app/controllers/projects/ci/pipeline_editor_controller.rb @@ -2,6 +2,9 @@ class Projects::Ci::PipelineEditorController < Projects::ApplicationController before_action :check_can_collaborate! + before_action do + push_frontend_feature_flag(:ci_job_assistant_drawer, @project) + end feature_category :pipeline_authoring diff --git a/config/feature_flags/development/ci_job_assistant_drawer.yml b/config/feature_flags/development/ci_job_assistant_drawer.yml new file mode 100644 index 00000000000..94e376e1c8a --- /dev/null +++ b/config/feature_flags/development/ci_job_assistant_drawer.yml @@ -0,0 +1,7 @@ +--- +name: ci_job_assistant_drawer +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/107828 +rollout_issue_url: +milestone: '15.9' +type: development +default_enabled: false diff --git a/config/feature_flags/development/moved_mr_sidebar.yml b/config/feature_flags/development/moved_mr_sidebar.yml index b12d3023e3c..1e542a5a60e 100644 --- a/config/feature_flags/development/moved_mr_sidebar.yml +++ b/config/feature_flags/development/moved_mr_sidebar.yml @@ -1,7 +1,7 @@ --- name: moved_mr_sidebar -introduced_by_url: -rollout_issue_url: +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85584 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/385460 milestone: '14.10' type: development group: group::code review diff --git a/doc/user/application_security/container_scanning/index.md b/doc/user/application_security/container_scanning/index.md index b5792cbfe5b..09ba1ce3b10 100644 --- a/doc/user/application_security/container_scanning/index.md +++ b/doc/user/application_security/container_scanning/index.md @@ -580,7 +580,7 @@ For details on saving and transporting Docker images as a file, see the Docker d - template: Jobs/Container-Scanning.gitlab-ci.yml container_scanning: - image: $CI_REGISTRY/namespace/gitlab-container-scanning + image: $CI_REGISTRY/namespace/container-scanning ``` 1. If your local Docker container registry is running securely over `HTTPS`, but you're using a @@ -597,7 +597,7 @@ following `.gitlab-ci.yml` example as a template. ```yaml variables: SOURCE_IMAGE: registry.gitlab.com/security-products/container-scanning:5 - TARGET_IMAGE: $CI_REGISTRY/namespace/gitlab-container-scanning + TARGET_IMAGE: $CI_REGISTRY/namespace/container-scanning image: docker:stable diff --git a/lib/gitlab/database/shared_model.rb b/lib/gitlab/database/shared_model.rb index 877866b9b23..41c3a27bc5b 100644 --- a/lib/gitlab/database/shared_model.rb +++ b/lib/gitlab/database/shared_model.rb @@ -44,6 +44,11 @@ module Gitlab end end + # in case the connection has been switched with using_connection + def connection_pool + connection.pool + end + private def overriding_connection diff --git a/locale/gitlab.pot b/locale/gitlab.pot index c3eb02ba199..b439fbeb21b 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -24012,6 +24012,12 @@ msgstr "" msgid "Job was retried" msgstr "" +msgid "JobAssistant|Add job" +msgstr "" + +msgid "JobAssistant|Job assistant" +msgstr "" + msgid "Jobs" msgstr "" diff --git a/spec/frontend/ci/pipeline_editor/components/editor/ci_editor_header_spec.js b/spec/frontend/ci/pipeline_editor/components/editor/ci_editor_header_spec.js index d7f0ce838d6..dc72694d26f 100644 --- a/spec/frontend/ci/pipeline_editor/components/editor/ci_editor_header_spec.js +++ b/spec/frontend/ci/pipeline_editor/components/editor/ci_editor_header_spec.js @@ -11,11 +11,12 @@ describe('CI Editor Header', () => { let wrapper; let trackingSpy = null; - const createComponent = ({ showDrawer = false } = {}) => { + const createComponent = ({ showDrawer = false, showJobAssistantDrawer = false } = {}) => { wrapper = extendedWrapper( shallowMount(CiEditorHeader, { propsData: { showDrawer, + showJobAssistantDrawer, }, }), ); diff --git a/spec/frontend/ci/pipeline_editor/components/job_assistant_drawer/job_assistant_drawer_spec.js b/spec/frontend/ci/pipeline_editor/components/job_assistant_drawer/job_assistant_drawer_spec.js new file mode 100644 index 00000000000..79200d92598 --- /dev/null +++ b/spec/frontend/ci/pipeline_editor/components/job_assistant_drawer/job_assistant_drawer_spec.js @@ -0,0 +1,45 @@ +import { GlDrawer } from '@gitlab/ui'; +import VueApollo from 'vue-apollo'; +import Vue from 'vue'; +import JobAssistantDrawer from '~/ci/pipeline_editor/components/job_assistant_drawer/job_assistant_drawer.vue'; +import waitForPromises from 'helpers/wait_for_promises'; +import { mountExtended } from 'helpers/vue_test_utils_helper'; + +Vue.use(VueApollo); + +describe('Job assistant drawer', () => { + let wrapper; + + const findDrawer = () => wrapper.findComponent(GlDrawer); + + const findCancelButton = () => wrapper.findByTestId('cancel-button'); + + const createComponent = () => { + wrapper = mountExtended(JobAssistantDrawer, { + propsData: { + isVisible: true, + }, + }); + }; + + beforeEach(async () => { + createComponent(); + await waitForPromises(); + }); + + it('should emit close job assistant drawer event when closing the drawer', () => { + expect(wrapper.emitted('close-job-assistant-drawer')).toBeUndefined(); + + findDrawer().vm.$emit('close'); + + expect(wrapper.emitted('close-job-assistant-drawer')).toHaveLength(1); + }); + + it('should emit close job assistant drawer event when click cancel button', () => { + expect(wrapper.emitted('close-job-assistant-drawer')).toBeUndefined(); + + findCancelButton().trigger('click'); + + expect(wrapper.emitted('close-job-assistant-drawer')).toHaveLength(1); + }); +}); diff --git a/spec/frontend/ci/pipeline_editor/components/pipeline_editor_tabs_spec.js b/spec/frontend/ci/pipeline_editor/components/pipeline_editor_tabs_spec.js index 70310cbdb10..f40db50aab7 100644 --- a/spec/frontend/ci/pipeline_editor/components/pipeline_editor_tabs_spec.js +++ b/spec/frontend/ci/pipeline_editor/components/pipeline_editor_tabs_spec.js @@ -56,6 +56,7 @@ describe('Pipeline editor tabs component', () => { currentTab: CREATE_TAB, isNewCiConfigFile: true, showDrawer: false, + showJobAssistantDrawer: false, ...props, }, data() { diff --git a/spec/frontend/ci/pipeline_editor/pipeline_editor_home_spec.js b/spec/frontend/ci/pipeline_editor/pipeline_editor_home_spec.js index 621e015e825..4f8f2112abe 100644 --- a/spec/frontend/ci/pipeline_editor/pipeline_editor_home_spec.js +++ b/spec/frontend/ci/pipeline_editor/pipeline_editor_home_spec.js @@ -6,6 +6,7 @@ import setWindowLocation from 'helpers/set_window_location_helper'; import CiEditorHeader from '~/ci/pipeline_editor/components/editor/ci_editor_header.vue'; import CommitSection from '~/ci/pipeline_editor/components/commit/commit_section.vue'; import PipelineEditorDrawer from '~/ci/pipeline_editor/components/drawer/pipeline_editor_drawer.vue'; +import JobAssistantDrawer from '~/ci/pipeline_editor/components/job_assistant_drawer/job_assistant_drawer.vue'; import PipelineEditorFileNav from '~/ci/pipeline_editor/components/file_nav/pipeline_editor_file_nav.vue'; import PipelineEditorFileTree from '~/ci/pipeline_editor/components/file_tree/container.vue'; import BranchSwitcher from '~/ci/pipeline_editor/components/file_nav/branch_switcher.vue'; @@ -56,11 +57,13 @@ describe('Pipeline editor home wrapper', () => { const findFileNav = () => wrapper.findComponent(PipelineEditorFileNav); const findModal = () => wrapper.findComponent(GlModal); const findPipelineEditorDrawer = () => wrapper.findComponent(PipelineEditorDrawer); + const findJobAssistantDrawer = () => wrapper.findComponent(JobAssistantDrawer); const findPipelineEditorFileTree = () => wrapper.findComponent(PipelineEditorFileTree); const findPipelineEditorHeader = () => wrapper.findComponent(PipelineEditorHeader); const findPipelineEditorTabs = () => wrapper.findComponent(PipelineEditorTabs); const findFileTreeBtn = () => wrapper.findByTestId('file-tree-toggle'); const findHelpBtn = () => wrapper.findByTestId('drawer-toggle'); + const findJobAssistantBtn = () => wrapper.findByTestId('job-assistant-drawer-toggle'); afterEach(() => { localStorage.clear(); @@ -261,6 +264,110 @@ describe('Pipeline editor home wrapper', () => { }); }); + describe('job assistant drawer', () => { + const clickHelpBtn = async () => { + findHelpBtn().vm.$emit('click'); + await nextTick(); + }; + const clickJobAssistantBtn = async () => { + findJobAssistantBtn().vm.$emit('click'); + await nextTick(); + }; + + const stubs = { + CiEditorHeader, + GlButton, + GlDrawer, + PipelineEditorTabs, + JobAssistantDrawer, + }; + + it('hides the job assistant drawer by default', () => { + createComponent({ + glFeatures: { + ciJobAssistantDrawer: true, + }, + }); + + expect(findJobAssistantDrawer().props('isVisible')).toBe(false); + }); + + it('toggles the job assistant drawer on button click', async () => { + createComponent({ + stubs, + glFeatures: { + ciJobAssistantDrawer: true, + }, + }); + + await clickJobAssistantBtn(); + + expect(findJobAssistantDrawer().props('isVisible')).toBe(true); + + await clickJobAssistantBtn(); + + expect(findJobAssistantDrawer().props('isVisible')).toBe(false); + }); + + it("closes the job assistant drawer through the drawer's close button", async () => { + createComponent({ + stubs, + glFeatures: { + ciJobAssistantDrawer: true, + }, + }); + + await clickJobAssistantBtn(); + + expect(findJobAssistantDrawer().props('isVisible')).toBe(true); + + findJobAssistantDrawer().findComponent(GlDrawer).vm.$emit('close'); + await nextTick(); + + expect(findJobAssistantDrawer().props('isVisible')).toBe(false); + }); + + it('covers helper drawer when opened last', async () => { + createComponent({ + stubs: { + ...stubs, + PipelineEditorDrawer, + }, + glFeatures: { + ciJobAssistantDrawer: true, + }, + }); + + await clickHelpBtn(); + await clickJobAssistantBtn(); + + const jobAssistantIndex = Number(findJobAssistantDrawer().props().zIndex); + const pipelineEditorDrawerIndex = Number(findPipelineEditorDrawer().props().zIndex); + + expect(jobAssistantIndex).toBeGreaterThan(pipelineEditorDrawerIndex); + }); + + it('covered by helper drawer when opened first', async () => { + createComponent({ + stubs: { + ...stubs, + PipelineEditorDrawer, + }, + glFeatures: { + ciJobAssistantDrawer: true, + }, + }); + + await clickJobAssistantBtn(); + await clickHelpBtn(); + + const jobAssistantIndex = Number(findJobAssistantDrawer().props().zIndex); + const pipelineEditorDrawerIndex = Number(findPipelineEditorDrawer().props().zIndex); + + expect(jobAssistantIndex).toBeLessThan(pipelineEditorDrawerIndex); + }); + }); + describe('file tree', () => { const toggleFileTree = async () => { findFileTreeBtn().vm.$emit('click'); diff --git a/spec/lib/gitlab/database/shared_model_spec.rb b/spec/lib/gitlab/database/shared_model_spec.rb index 7e0ba3397d1..2ae6ccf6c6a 100644 --- a/spec/lib/gitlab/database/shared_model_spec.rb +++ b/spec/lib/gitlab/database/shared_model_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::Database::SharedModel do +RSpec.describe Gitlab::Database::SharedModel, feature_category: :database do describe 'using an external connection' do let!(:original_connection) { described_class.connection } let(:new_connection) { double('connection') } @@ -85,28 +85,51 @@ RSpec.describe Gitlab::Database::SharedModel do end end end - - def expect_original_connection_around - # For safety, ensure our original connection is distinct from our double - # This should be the case, but in case of something leaking we should verify - expect(original_connection).not_to be(new_connection) - expect(described_class.connection).to be(original_connection) - - yield - - expect(described_class.connection).to be(original_connection) - end end describe '#connection_db_config' do - it 'returns the class connection_db_config' do - shared_model_class = Class.new(described_class) do + let!(:original_connection) { shared_model_class.connection } + let!(:original_connection_db_config) { shared_model_class.connection_db_config } + let(:shared_model) { shared_model_class.new } + let(:shared_model_class) do + Class.new(described_class) do self.table_name = 'postgres_async_indexes' end + end - shared_model = shared_model_class.new - + it 'returns the class connection_db_config' do expect(shared_model.connection_db_config).to eq(described_class.connection_db_config) end + + context 'when switching the class connection' do + before do + skip_if_multiple_databases_not_setup + end + + let(:new_base_model) { Ci::ApplicationRecord } + let(:new_connection) { new_base_model.connection } + + it 'returns the db_config of the used connection when using load balancing' do + expect_original_connection_around do + described_class.using_connection(new_connection) do + expect(shared_model.connection_db_config).to eq(new_base_model.connection_db_config) + end + end + + # it restores the connection_db_config afterwards + expect(shared_model.connection_db_config).to eq(original_connection_db_config) + end + end + end + + def expect_original_connection_around + # For safety, ensure our original connection is distinct from our double + # This should be the case, but in case of something leaking we should verify + expect(original_connection).not_to be(new_connection) + expect(described_class.connection).to be(original_connection) + + yield + + expect(described_class.connection).to be(original_connection) end end |