diff --git a/app/assets/javascripts/ide/components/activity_bar.vue b/app/assets/javascripts/ide/components/activity_bar.vue index 7b4e03be8eb..186d4b6d7d2 100644 --- a/app/assets/javascripts/ide/components/activity_bar.vue +++ b/app/assets/javascripts/ide/components/activity_bar.vue @@ -3,7 +3,7 @@ import $ from 'jquery'; import { mapActions, mapGetters, mapState } from 'vuex'; import Icon from '~/vue_shared/components/icon.vue'; import tooltip from '~/vue_shared/directives/tooltip'; -import { activityBarViews } from '../constants'; +import { leftSidebarViews } from '../constants'; export default { components: { @@ -26,7 +26,7 @@ export default { $(e.currentTarget).tooltip('hide'); }, }, - activityBarViews, + leftSidebarViews, }; @@ -37,7 +37,7 @@ export default { @@ -54,7 +54,7 @@ export default { @@ -71,7 +71,7 @@ export default { diff --git a/app/assets/javascripts/ide/components/commit_sidebar/form.vue b/app/assets/javascripts/ide/components/commit_sidebar/form.vue index 9777f365557..5ec3fc4041b 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/form.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/form.vue @@ -5,7 +5,7 @@ import LoadingButton from '~/vue_shared/components/loading_button.vue'; import CommitMessageField from './message_field.vue'; import Actions from './actions.vue'; import SuccessMessage from './success_message.vue'; -import { activityBarViews, MAX_WINDOW_HEIGHT_COMPACT } from '../../constants'; +import { leftSidebarViews, MAX_WINDOW_HEIGHT_COMPACT } from '../../constants'; export default { components: { @@ -41,7 +41,7 @@ export default { }, currentViewIsCommitView() { - return this.currentActivityView === activityBarViews.commit; + return this.currentActivityView === leftSidebarViews.commit.name; }, }, watch: { @@ -57,7 +57,7 @@ export default { lastCommitMsg() { this.isCompact = - this.currentActivityView !== activityBarViews.commit && this.lastCommitMsg === ''; + this.currentActivityView !== leftSidebarViews.commit.name && this.lastCommitMsg === ''; }, }, methods: { @@ -67,7 +67,7 @@ export default { if (this.currentViewIsCommitView) { this.isCompact = !this.isCompact; } else { - this.updateActivityBarView(activityBarViews.commit) + this.updateActivityBarView(leftSidebarViews.commit.name) .then(() => { this.isCompact = false; }) diff --git a/app/assets/javascripts/ide/components/ide_side_bar.vue b/app/assets/javascripts/ide/components/ide_side_bar.vue index 6178d2b1fc7..40cd2178e09 100644 --- a/app/assets/javascripts/ide/components/ide_side_bar.vue +++ b/app/assets/javascripts/ide/components/ide_side_bar.vue @@ -4,19 +4,19 @@ import { GlSkeletonLoading } from '@gitlab/ui'; import IdeTree from './ide_tree.vue'; import ResizablePanel from './resizable_panel.vue'; import ActivityBar from './activity_bar.vue'; -import CommitSection from './repo_commit_section.vue'; +import RepoCommitSection from './repo_commit_section.vue'; import CommitForm from './commit_sidebar/form.vue'; import IdeReview from './ide_review.vue'; import SuccessMessage from './commit_sidebar/success_message.vue'; import IdeProjectHeader from './ide_project_header.vue'; -import { activityBarViews } from '../constants'; +import { leftSidebarViews } from '../constants'; export default { components: { GlSkeletonLoading, ResizablePanel, ActivityBar, - CommitSection, + RepoCommitSection, IdeTree, CommitForm, IdeReview, @@ -28,7 +28,7 @@ export default { ...mapGetters(['currentProject', 'someUncommittedChanges']), showSuccessMessage() { return ( - this.currentActivityView === activityBarViews.edit && + this.currentActivityView === leftSidebarViews.edit.name && (this.lastCommitMsg && !this.someUncommittedChanges) ); }, diff --git a/app/assets/javascripts/ide/components/repo_commit_section.vue b/app/assets/javascripts/ide/components/repo_commit_section.vue index b3a7597e7bb..62fb0b03975 100644 --- a/app/assets/javascripts/ide/components/repo_commit_section.vue +++ b/app/assets/javascripts/ide/components/repo_commit_section.vue @@ -5,7 +5,7 @@ import DeprecatedModal from '~/vue_shared/components/deprecated_modal.vue'; import CommitFilesList from './commit_sidebar/list.vue'; import EmptyState from './commit_sidebar/empty_state.vue'; import consts from '../stores/modules/commit/constants'; -import { activityBarViews, stageKeys } from '../constants'; +import { leftSidebarViews, stageKeys } from '../constants'; export default { components: { @@ -37,7 +37,7 @@ export default { watch: { hasChanges() { if (!this.hasChanges) { - this.updateActivityBarView(activityBarViews.edit); + this.updateActivityBarView(leftSidebarViews.edit.name); } }, }, diff --git a/app/assets/javascripts/ide/components/repo_editor.vue b/app/assets/javascripts/ide/components/repo_editor.vue index 8af34dcb5cc..bfb760f3579 100644 --- a/app/assets/javascripts/ide/components/repo_editor.vue +++ b/app/assets/javascripts/ide/components/repo_editor.vue @@ -5,7 +5,7 @@ import flash from '~/flash'; import ContentViewer from '~/vue_shared/components/content_viewer/content_viewer.vue'; import DiffViewer from '~/vue_shared/components/diff_viewer/diff_viewer.vue'; import { - activityBarViews, + leftSidebarViews, viewerTypes, FILE_VIEW_MODE_EDITOR, FILE_VIEW_MODE_PREVIEW, @@ -100,7 +100,7 @@ export default { if (oldVal.key !== this.file.key) { this.initEditor(); - if (this.currentActivityView !== activityBarViews.edit) { + if (this.currentActivityView !== leftSidebarViews.edit.name) { this.setFileViewMode({ file: this.file, viewMode: FILE_VIEW_MODE_EDITOR, @@ -109,7 +109,7 @@ export default { } }, currentActivityView() { - if (this.currentActivityView !== activityBarViews.edit) { + if (this.currentActivityView !== leftSidebarViews.edit.name) { this.setFileViewMode({ file: this.file, viewMode: FILE_VIEW_MODE_EDITOR, diff --git a/app/assets/javascripts/ide/constants.js b/app/assets/javascripts/ide/constants.js index 54d3e79411f..e7762f9e0f2 100644 --- a/app/assets/javascripts/ide/constants.js +++ b/app/assets/javascripts/ide/constants.js @@ -11,12 +11,6 @@ export const FILE_VIEW_MODE_PREVIEW = 'preview'; export const PERMISSION_CREATE_MR = 'createMergeRequestIn'; export const PERMISSION_READ_MR = 'readMergeRequest'; -export const activityBarViews = { - edit: 'ide-tree', - commit: 'commit-section', - review: 'ide-review', -}; - export const viewerTypes = { mr: 'mrdiff', edit: 'editor', @@ -47,6 +41,12 @@ export const diffViewerErrors = Object.freeze({ stored_externally: 'server_side_but_stored_externally', }); +export const leftSidebarViews = { + edit: { name: 'ide-tree', keepAlive: false }, + review: { name: 'ide-review', keepAlive: false }, + commit: { name: 'repo-commit-section', keepAlive: false }, +}; + export const rightSidebarViews = { pipelines: { name: 'pipelines-list', keepAlive: true }, jobsDetail: { name: 'jobs-detail', keepAlive: false }, diff --git a/app/assets/javascripts/ide/stores/actions/merge_request.js b/app/assets/javascripts/ide/stores/actions/merge_request.js index 9e9c6fc42b3..fcaf060ef09 100644 --- a/app/assets/javascripts/ide/stores/actions/merge_request.js +++ b/app/assets/javascripts/ide/stores/actions/merge_request.js @@ -2,7 +2,7 @@ import flash from '~/flash'; import { __ } from '~/locale'; import service from '../../services'; import * as types from '../mutation_types'; -import { activityBarViews, PERMISSION_READ_MR } from '../../constants'; +import { leftSidebarViews, PERMISSION_READ_MR } from '../../constants'; export const getMergeRequestsForBranch = ( { commit, state, getters }, @@ -187,7 +187,7 @@ export const openMergeRequest = ( ) .then(mrChanges => { if (mrChanges.changes.length) { - dispatch('updateActivityBarView', activityBarViews.review); + dispatch('updateActivityBarView', leftSidebarViews.review.name); } mrChanges.changes.forEach((change, ind) => { diff --git a/app/assets/javascripts/ide/stores/getters.js b/app/assets/javascripts/ide/stores/getters.js index 257062d118c..d7ad39019a5 100644 --- a/app/assets/javascripts/ide/stores/getters.js +++ b/app/assets/javascripts/ide/stores/getters.js @@ -1,6 +1,6 @@ import { getChangesCountForFiles, filePathMatches } from './utils'; import { - activityBarViews, + leftSidebarViews, packageJsonPath, PERMISSION_READ_MR, PERMISSION_CREATE_MR, @@ -74,9 +74,11 @@ export const getOpenFile = state => path => state.openFiles.find(f => f.path === export const lastOpenedFile = state => [...state.changedFiles, ...state.stagedFiles].sort((a, b) => b.lastOpenedAt - a.lastOpenedAt)[0]; -export const isEditModeActive = state => state.currentActivityView === activityBarViews.edit; -export const isCommitModeActive = state => state.currentActivityView === activityBarViews.commit; -export const isReviewModeActive = state => state.currentActivityView === activityBarViews.review; +export const isEditModeActive = state => state.currentActivityView === leftSidebarViews.edit.name; +export const isCommitModeActive = state => + state.currentActivityView === leftSidebarViews.commit.name; +export const isReviewModeActive = state => + state.currentActivityView === leftSidebarViews.review.name; export const someUncommittedChanges = state => Boolean(state.changedFiles.length || state.stagedFiles.length); diff --git a/app/assets/javascripts/ide/stores/modules/commit/actions.js b/app/assets/javascripts/ide/stores/modules/commit/actions.js index 3be350db3da..9bf0542cd0b 100644 --- a/app/assets/javascripts/ide/stores/modules/commit/actions.js +++ b/app/assets/javascripts/ide/stores/modules/commit/actions.js @@ -7,7 +7,7 @@ import router from '../../../ide_router'; import service from '../../../services'; import * as types from './mutation_types'; import consts from './constants'; -import { activityBarViews } from '../../../constants'; +import { leftSidebarViews } from '../../../constants'; import eventHub from '../../../eventhub'; export const updateCommitMessage = ({ commit }, message) => { @@ -189,7 +189,7 @@ export const commitChanges = ({ commit, state, getters, dispatch, rootState, roo throw e; }); } else { - dispatch('updateActivityBarView', activityBarViews.edit, { root: true }); + dispatch('updateActivityBarView', leftSidebarViews.edit.name, { root: true }); dispatch('updateViewer', 'editor', { root: true }); if (rootGetters.activeFile) { diff --git a/app/assets/javascripts/ide/stores/modules/file_templates/getters.js b/app/assets/javascripts/ide/stores/modules/file_templates/getters.js index f10891a8e5b..453df8d7e0c 100644 --- a/app/assets/javascripts/ide/stores/modules/file_templates/getters.js +++ b/app/assets/javascripts/ide/stores/modules/file_templates/getters.js @@ -1,4 +1,4 @@ -import { activityBarViews } from '../../../constants'; +import { leftSidebarViews } from '../../../constants'; import { __ } from '~/locale'; export const templateTypes = () => [ @@ -22,6 +22,6 @@ export const templateTypes = () => [ export const showFileTemplatesBar = (_, getters, rootState) => name => getters.templateTypes.find(t => t.name === name) && - rootState.currentActivityView === activityBarViews.edit; + rootState.currentActivityView === leftSidebarViews.edit.name; export default () => {}; diff --git a/app/assets/javascripts/ide/stores/state.js b/app/assets/javascripts/ide/stores/state.js index 828cec3e141..a714562c5b2 100644 --- a/app/assets/javascripts/ide/stores/state.js +++ b/app/assets/javascripts/ide/stores/state.js @@ -1,4 +1,4 @@ -import { activityBarViews, viewerTypes } from '../constants'; +import { leftSidebarViews, viewerTypes } from '../constants'; import { DEFAULT_THEME } from '../lib/themes'; export default () => ({ @@ -21,7 +21,7 @@ export default () => ({ entries: {}, viewer: viewerTypes.edit, delayViewerUpdated: false, - currentActivityView: activityBarViews.edit, + currentActivityView: leftSidebarViews.edit.name, unusedSeal: true, fileFindVisible: false, links: {}, diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index 8b2c67378d9..f8832047d49 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -1006,14 +1006,6 @@ pre.light-well { } } - &:not(.with-pipeline-status) { - .icon-wrapper:first-of-type { - @include media-breakpoint-up(lg) { - margin-left: $gl-padding-32; - } - } - } - .ci-status-link { display: inline-flex; } diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 27a394e4ab8..e95e2c538c5 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -114,6 +114,7 @@ module Ci end scope :eager_load_job_artifacts, -> { includes(:job_artifacts) } + scope :eager_load_job_artifacts_archive, -> { includes(:job_artifacts_archive) } scope :eager_load_everything, -> do includes( diff --git a/app/serializers/pipeline_details_entity.rb b/app/serializers/pipeline_details_entity.rb index a4ab1d399bc..a58278cf4ef 100644 --- a/app/serializers/pipeline_details_entity.rb +++ b/app/serializers/pipeline_details_entity.rb @@ -8,7 +8,12 @@ class PipelineDetailsEntity < PipelineEntity end expose :details do - expose :artifacts, using: BuildArtifactEntity + expose :artifacts do |pipeline, options| + rel = pipeline.artifacts + rel = rel.eager_load_job_artifacts_archive if options.fetch(:preload_job_artifacts_archive, true) + + BuildArtifactEntity.represent(rel, options) + end expose :manual_actions, using: BuildActionEntity expose :scheduled_actions, using: BuildActionEntity end diff --git a/app/serializers/pipeline_serializer.rb b/app/serializers/pipeline_serializer.rb index 58df62dfea5..3ad9f2bc0bf 100644 --- a/app/serializers/pipeline_serializer.rb +++ b/app/serializers/pipeline_serializer.rb @@ -7,6 +7,10 @@ class PipelineSerializer < BaseSerializer # rubocop: disable CodeReuse/ActiveRecord def represent(resource, opts = {}) if resource.is_a?(ActiveRecord::Relation) + # We don't want PipelineDetailsEntity to preload the job_artifacts_archive + # because we do it with preloaded_relations in a more optimal way + # if the given resource is a collection of multiple pipelines. + opts[:preload_job_artifacts_archive] = false resource = resource.preload(preloaded_relations) end diff --git a/app/views/dashboard/projects/_projects.html.haml b/app/views/dashboard/projects/_projects.html.haml index 5122164dbcb..ca201e626b8 100644 --- a/app/views/dashboard/projects/_projects.html.haml +++ b/app/views/dashboard/projects/_projects.html.haml @@ -1 +1 @@ -= render 'shared/projects/list', projects: @projects, pipeline_status: Feature.enabled?(:dashboard_pipeline_status, default_enabled: true), user: current_user += render 'shared/projects/list', projects: @projects, user: current_user diff --git a/app/views/explore/projects/_projects.html.haml b/app/views/explore/projects/_projects.html.haml index d819c4ea554..35b32662b8a 100644 --- a/app/views/explore/projects/_projects.html.haml +++ b/app/views/explore/projects/_projects.html.haml @@ -1,2 +1,2 @@ - is_explore_page = defined?(explore_page) && explore_page -= render 'shared/projects/list', projects: projects, user: current_user, explore_page: is_explore_page, pipeline_status: Feature.enabled?(:dashboard_pipeline_status, default_enabled: true) += render 'shared/projects/list', projects: projects, user: current_user, explore_page: is_explore_page diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml index 45e95685677..07a61b71b8e 100644 --- a/app/views/shared/projects/_project.html.haml +++ b/app/views/shared/projects/_project.html.haml @@ -12,9 +12,7 @@ - css_class += " no-description" if project.description.blank? && !show_last_commit_as_description - cache_key = project_list_cache_key(project, pipeline_status: pipeline_status) - updated_tooltip = time_ago_with_tooltip(project.last_activity_date) -- show_pipeline_status_icon = pipeline_status && can?(current_user, :read_cross_project) && project.pipeline_status.has_status? && can?(current_user, :read_build, project) - css_controls_class = compact_mode ? [] : ["flex-lg-row", "justify-content-lg-between"] -- css_controls_class << "with-pipeline-status" if show_pipeline_status_icon - avatar_container_class = project.creator && use_creator_avatar ? '' : 'rect-avatar' %li.project-row.d-flex{ class: css_class } @@ -62,11 +60,6 @@ .controls.d-flex.flex-sm-column.align-items-center.align-items-sm-end.flex-wrap.flex-shrink-0.text-secondary{ class: css_controls_class.join(" ") } .icon-container.d-flex.align-items-center - - if show_pipeline_status_icon - - pipeline_path = pipelines_project_commit_path(project.pipeline_status.project, project.pipeline_status.sha, ref: project.pipeline_status.ref) - %span.icon-wrapper.pipeline-status - = render 'ci/status/icon', status: project.last_pipeline.detailed_status(current_user), tooltip_placement: 'top', path: pipeline_path - = render_if_exists 'shared/projects/archived', project: project - if stars = link_to project_starrers_path(project), diff --git a/changelogs/unreleased/205248-remove-ci-status-from-project-dashboard.yml b/changelogs/unreleased/205248-remove-ci-status-from-project-dashboard.yml new file mode 100644 index 00000000000..462d4e04d2e --- /dev/null +++ b/changelogs/unreleased/205248-remove-ci-status-from-project-dashboard.yml @@ -0,0 +1,5 @@ +--- +title: Remove CI status from Projects Dashboard +merge_request: 25225 +author: George Thomas @thegeorgeous +type: removed diff --git a/changelogs/unreleased/eb-preload-artifacts-merge-request-widget.yml b/changelogs/unreleased/eb-preload-artifacts-merge-request-widget.yml new file mode 100644 index 00000000000..da867c60938 --- /dev/null +++ b/changelogs/unreleased/eb-preload-artifacts-merge-request-widget.yml @@ -0,0 +1,6 @@ +--- +title: Fix N+1 queries caused by loading job artifacts archive in pipeline details + entity +merge_request: 25250 +author: +type: fixed diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb index fbb77304ce9..fd33f32e877 100644 --- a/spec/controllers/projects/pipelines_controller_spec.rb +++ b/spec/controllers/projects/pipelines_controller_spec.rb @@ -171,7 +171,17 @@ describe Projects::PipelinesController do def create_build(pipeline, stage, stage_idx, name, user = nil) status = %w[created running pending success failed canceled].sample - create(:ci_build, pipeline: pipeline, stage: stage, stage_idx: stage_idx, name: name, status: status, user: user) + create( + :ci_build, + :artifacts, + artifacts_expire_at: 2.days.from_now, + pipeline: pipeline, + stage: stage, + stage_idx: stage_idx, + name: name, + status: status, + user: user + ) end end diff --git a/spec/features/clusters/installing_applications_shared_examples.rb b/spec/features/clusters/installing_applications_shared_examples.rb index 20648ed3d46..ff44ce46213 100644 --- a/spec/features/clusters/installing_applications_shared_examples.rb +++ b/spec/features/clusters/installing_applications_shared_examples.rb @@ -187,6 +187,8 @@ shared_examples "installing applications on a cluster" do page.within('.js-cluster-application-row-elastic_stack') do click_button 'Install' end + + wait_for_requests end it 'shows status transition' do diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb index 73f759f8a54..9bd2e85e3b8 100644 --- a/spec/features/dashboard/projects_spec.rb +++ b/spec/features/dashboard/projects_spec.rb @@ -152,61 +152,6 @@ describe 'Dashboard Projects' do end end - describe 'with a pipeline', :clean_gitlab_redis_shared_state do - let(:pipeline) { create(:ci_pipeline, project: project, sha: project.commit.sha, ref: project.default_branch) } - - before do - # Since the cache isn't updated when a new pipeline is created - # we need the pipeline to advance in the pipeline since the cache was created - # by visiting the login page. - pipeline.succeed - end - - it 'shows that the last pipeline passed' do - visit dashboard_projects_path - - page.within('.controls') do - expect(page).to have_xpath("//a[@href='#{pipelines_project_commit_path(project, project.commit, ref: pipeline.ref)}']") - expect(page).to have_css('.ci-status-link') - expect(page).to have_css('.ci-status-icon-success') - expect(page).to have_link('Pipeline: passed') - end - end - - shared_examples 'hidden pipeline status' do - it 'does not show the pipeline status' do - visit dashboard_projects_path - - page.within('.controls') do - expect(page).not_to have_xpath("//a[@href='#{pipelines_project_commit_path(project, project.commit, ref: pipeline.ref)}']") - expect(page).not_to have_css('.ci-status-link') - expect(page).not_to have_css('.ci-status-icon-success') - expect(page).not_to have_link('Pipeline: passed') - end - end - end - - context 'guest user of project and project has private pipelines' do - let(:guest_user) { create(:user) } - - before do - project.update(public_builds: false) - project.add_guest(guest_user) - sign_in(guest_user) - end - - it_behaves_like 'hidden pipeline status' - end - - context 'when dashboard_pipeline_status is disabled' do - before do - stub_feature_flags(dashboard_pipeline_status: false) - end - - it_behaves_like 'hidden pipeline status' - end - end - context 'last push widget', :use_clean_rails_memory_store_caching do before do event = create(:push_event, project: project, author: user) diff --git a/spec/frontend/ide/stores/modules/file_templates/getters_spec.js b/spec/frontend/ide/stores/modules/file_templates/getters_spec.js index 17cb457881f..5855496a330 100644 --- a/spec/frontend/ide/stores/modules/file_templates/getters_spec.js +++ b/spec/frontend/ide/stores/modules/file_templates/getters_spec.js @@ -1,5 +1,5 @@ import createState from '~/ide/stores/state'; -import { activityBarViews } from '~/ide/constants'; +import { leftSidebarViews } from '~/ide/constants'; import * as getters from '~/ide/stores/modules/file_templates/getters'; describe('IDE file templates getters', () => { @@ -17,7 +17,7 @@ describe('IDE file templates getters', () => { }); it('returns true if template is found and currentActivityView is edit', () => { - rootState.currentActivityView = activityBarViews.edit; + rootState.currentActivityView = leftSidebarViews.edit.name; expect( getters.showFileTemplatesBar( @@ -31,7 +31,7 @@ describe('IDE file templates getters', () => { }); it('returns false if template is found and currentActivityView is not edit', () => { - rootState.currentActivityView = activityBarViews.commit; + rootState.currentActivityView = leftSidebarViews.commit.name; expect( getters.showFileTemplatesBar( diff --git a/spec/javascripts/ide/components/activity_bar_spec.js b/spec/javascripts/ide/components/activity_bar_spec.js index 4d878e633fe..823ca29dab9 100644 --- a/spec/javascripts/ide/components/activity_bar_spec.js +++ b/spec/javascripts/ide/components/activity_bar_spec.js @@ -1,6 +1,6 @@ import Vue from 'vue'; import store from '~/ide/stores'; -import { activityBarViews } from '~/ide/constants'; +import { leftSidebarViews } from '~/ide/constants'; import ActivityBar from '~/ide/components/activity_bar.vue'; import { createComponentWithStore } from '../../helpers/vue_mount_component_helper'; import { resetStore } from '../helpers'; @@ -34,19 +34,19 @@ describe('IDE activity bar', () => { it('calls updateActivityBarView with edit value on click', () => { vm.$el.querySelector('.js-ide-edit-mode').click(); - expect(vm.updateActivityBarView).toHaveBeenCalledWith(activityBarViews.edit); + expect(vm.updateActivityBarView).toHaveBeenCalledWith(leftSidebarViews.edit.name); }); it('calls updateActivityBarView with commit value on click', () => { vm.$el.querySelector('.js-ide-commit-mode').click(); - expect(vm.updateActivityBarView).toHaveBeenCalledWith(activityBarViews.commit); + expect(vm.updateActivityBarView).toHaveBeenCalledWith(leftSidebarViews.commit.name); }); it('calls updateActivityBarView with review value on click', () => { vm.$el.querySelector('.js-ide-review-mode').click(); - expect(vm.updateActivityBarView).toHaveBeenCalledWith(activityBarViews.review); + expect(vm.updateActivityBarView).toHaveBeenCalledWith(leftSidebarViews.review.name); }); }); @@ -60,7 +60,7 @@ describe('IDE activity bar', () => { }); it('sets commit item active', done => { - vm.$store.state.currentActivityView = activityBarViews.commit; + vm.$store.state.currentActivityView = leftSidebarViews.commit.name; vm.$nextTick(() => { expect(vm.$el.querySelector('.js-ide-commit-mode').classList).toContain('active'); diff --git a/spec/javascripts/ide/components/commit_sidebar/form_spec.js b/spec/javascripts/ide/components/commit_sidebar/form_spec.js index 9ee0cbdd3d4..5cb804938ed 100644 --- a/spec/javascripts/ide/components/commit_sidebar/form_spec.js +++ b/spec/javascripts/ide/components/commit_sidebar/form_spec.js @@ -4,7 +4,7 @@ import getSetTimeoutPromise from 'spec/helpers/set_timeout_promise_helper'; import { projectData } from 'spec/ide/mock_data'; import store from '~/ide/stores'; import CommitForm from '~/ide/components/commit_sidebar/form.vue'; -import { activityBarViews } from '~/ide/constants'; +import { leftSidebarViews } from '~/ide/constants'; import { resetStore } from '../../helpers'; describe('IDE commit form', () => { @@ -71,7 +71,7 @@ describe('IDE commit form', () => { vm.$el.querySelector('.btn-primary').click(); vm.$nextTick(() => { - expect(store.state.currentActivityView).toBe(activityBarViews.commit); + expect(store.state.currentActivityView).toBe(leftSidebarViews.commit.name); done(); }); @@ -79,7 +79,7 @@ describe('IDE commit form', () => { it('collapses if lastCommitMsg is set to empty and current view is not commit view', done => { store.state.lastCommitMsg = 'abc'; - store.state.currentActivityView = activityBarViews.edit; + store.state.currentActivityView = leftSidebarViews.edit.name; vm.$nextTick(() => { // if commit message is set, form is uncollapsed @@ -133,7 +133,7 @@ describe('IDE commit form', () => { vm.$el.querySelector('.btn-primary').click(); vm.$nextTick(() => { - expect(store.state.currentActivityView).toBe(activityBarViews.commit); + expect(store.state.currentActivityView).toBe(leftSidebarViews.commit.name); expect(vm.isCompact).toBe(false); done(); diff --git a/spec/javascripts/ide/components/ide_side_bar_spec.js b/spec/javascripts/ide/components/ide_side_bar_spec.js index a2d15462ac5..28f127a61c0 100644 --- a/spec/javascripts/ide/components/ide_side_bar_spec.js +++ b/spec/javascripts/ide/components/ide_side_bar_spec.js @@ -2,7 +2,7 @@ import Vue from 'vue'; import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; import store from '~/ide/stores'; import ideSidebar from '~/ide/components/ide_side_bar.vue'; -import { activityBarViews } from '~/ide/constants'; +import { leftSidebarViews } from '~/ide/constants'; import { resetStore } from '../helpers'; import { projectData } from '../mock_data'; @@ -45,7 +45,7 @@ describe('IdeSidebar', () => { }); it('renders commit component', done => { - vm.$store.state.currentActivityView = activityBarViews.commit; + vm.$store.state.currentActivityView = leftSidebarViews.commit.name; vm.$nextTick(() => { expect(vm.$el.querySelector('.multi-file-commit-panel-section')).not.toBeNull(); diff --git a/spec/javascripts/ide/components/repo_editor_spec.js b/spec/javascripts/ide/components/repo_editor_spec.js index 8935d8f56fc..ef0299f0d56 100644 --- a/spec/javascripts/ide/components/repo_editor_spec.js +++ b/spec/javascripts/ide/components/repo_editor_spec.js @@ -5,7 +5,7 @@ import axios from '~/lib/utils/axios_utils'; import store from '~/ide/stores'; import repoEditor from '~/ide/components/repo_editor.vue'; import Editor from '~/ide/lib/editor'; -import { activityBarViews, FILE_VIEW_MODE_EDITOR, FILE_VIEW_MODE_PREVIEW } from '~/ide/constants'; +import { leftSidebarViews, FILE_VIEW_MODE_EDITOR, FILE_VIEW_MODE_PREVIEW } from '~/ide/constants'; import { createComponentWithStore } from '../../helpers/vue_mount_component_helper'; import setTimeoutPromise from '../../helpers/set_timeout_promise_helper'; import { file, resetStore } from '../helpers'; @@ -359,7 +359,7 @@ describe('RepoEditor', () => { }); it('hides tabs in review mode', done => { - vm.$store.state.currentActivityView = activityBarViews.review; + vm.$store.state.currentActivityView = leftSidebarViews.review.name; vm.$nextTick(() => { expect(vm.$el.querySelector('.nav-links')).toBe(null); @@ -369,7 +369,7 @@ describe('RepoEditor', () => { }); it('hides tabs in commit mode', done => { - vm.$store.state.currentActivityView = activityBarViews.commit; + vm.$store.state.currentActivityView = leftSidebarViews.commit.name; vm.$nextTick(() => { expect(vm.$el.querySelector('.nav-links')).toBe(null); diff --git a/spec/javascripts/ide/stores/actions/merge_request_spec.js b/spec/javascripts/ide/stores/actions/merge_request_spec.js index 4917984cd42..ce09cf51ac5 100644 --- a/spec/javascripts/ide/stores/actions/merge_request_spec.js +++ b/spec/javascripts/ide/stores/actions/merge_request_spec.js @@ -8,7 +8,7 @@ import actions, { openMergeRequest, } from '~/ide/stores/actions/merge_request'; import service from '~/ide/services'; -import { activityBarViews, PERMISSION_READ_MR } from '~/ide/constants'; +import { leftSidebarViews, PERMISSION_READ_MR } from '~/ide/constants'; import { resetStore } from '../../helpers'; const TEST_PROJECT = 'abcproject'; @@ -470,7 +470,7 @@ describe('IDE store merge request actions', () => { .then(() => { expect(store.dispatch).toHaveBeenCalledWith( 'updateActivityBarView', - activityBarViews.review, + leftSidebarViews.review.name, ); testMergeRequestChanges.changes.forEach((change, i) => { diff --git a/spec/serializers/pipeline_details_entity_spec.rb b/spec/serializers/pipeline_details_entity_spec.rb index 9ce7c265e43..f270f9fd4cb 100644 --- a/spec/serializers/pipeline_details_entity_spec.rb +++ b/spec/serializers/pipeline_details_entity_spec.rb @@ -173,5 +173,44 @@ describe PipelineDetailsEntity do expect(subject[:triggered].first[:project]).not_to be_nil end end + + context 'when pipeline has expiring archive artifacts' do + let(:pipeline) { create(:ci_empty_pipeline) } + let!(:build_1) { create(:ci_build, :artifacts, pipeline: pipeline, artifacts_expire_at: 2.days.from_now, name: 'build_1') } + let!(:build_2) { create(:ci_build, :artifacts, pipeline: pipeline, artifacts_expire_at: 2.days.from_now, name: 'build_2') } + let!(:build_3) { create(:ci_build, :artifacts, pipeline: pipeline, artifacts_expire_at: 2.days.from_now, name: 'build_3') } + + let(:names) { subject[:details][:artifacts].map { |a| a[:name] } } + + context 'and preload_job_artifacts_archive is not defined in the options' do + it 'defaults to true and eager loads the job_artifacts_archive' do + recorder = ActiveRecord::QueryRecorder.new do + expect(names).to match_array(%w[build_1 build_2 build_3]) + end + + expected_queries = Gitlab.ee? ? 42 : 29 + + # This makes only one query to fetch all job artifacts + expect(recorder.count).to eq(expected_queries) + end + end + + context 'and preload_job_artifacts_archive is set to false' do + let(:entity) do + described_class.represent(pipeline, request: request, preload_job_artifacts_archive: false) + end + + it 'does not eager load the job_artifacts_archive' do + recorder = ActiveRecord::QueryRecorder.new do + expect(names).to match_array(%w[build_1 build_2 build_3]) + end + + expected_queries = Gitlab.ee? ? 44 : 31 + + # This makes one query for each job artifact + expect(recorder.count).to eq(expected_queries) + end + end + end end end