diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-28 03:15:57 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-28 03:15:57 +0000 |
commit | c5f4c801a6b40e7ee4b96aba20bbec687ccf0502 (patch) | |
tree | ad58e3d5ca9b38d0e86a78143f12362bb35ea1be /spec | |
parent | 3235221bc498ca3c80eeca505fb32bf9f237778a (diff) | |
download | gitlab-ce-c5f4c801a6b40e7ee4b96aba20bbec687ccf0502.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
20 files changed, 352 insertions, 48 deletions
diff --git a/spec/controllers/dashboard/projects_controller_spec.rb b/spec/controllers/dashboard/projects_controller_spec.rb index 743759d5023..b4a4ac56fce 100644 --- a/spec/controllers/dashboard/projects_controller_spec.rb +++ b/spec/controllers/dashboard/projects_controller_spec.rb @@ -97,14 +97,18 @@ RSpec.describe Dashboard::ProjectsController, :aggregate_failures do subject { get :starred, format: :json } let(:projects) { create_list(:project, 2, creator: user) } + let(:aimed_for_deletion_project) { create_list(:project, 2, :archived, creator: user, marked_for_deletion_at: 3.days.ago) } before do - allow(Kaminari.config).to receive(:default_per_page).and_return(1) - projects.each do |project| project.add_developer(user) create(:users_star_project, project_id: project.id, user_id: user.id) end + + aimed_for_deletion_project.each do |project| + project.add_developer(user) + create(:users_star_project, project_id: project.id, user_id: user.id) + end end it 'returns success' do @@ -113,10 +117,22 @@ RSpec.describe Dashboard::ProjectsController, :aggregate_failures do expect(response).to have_gitlab_http_status(:ok) end - it 'paginates the records' do + context "pagination" do + before do + allow(Kaminari.config).to receive(:default_per_page).and_return(1) + end + + it 'paginates the records' do + subject + + expect(assigns(:projects).count).to eq(1) + end + end + + it 'does not include projects aimed for deletion' do subject - expect(assigns(:projects).count).to eq(1) + expect(assigns(:projects).count).to eq(2) end end end diff --git a/spec/controllers/explore/projects_controller_spec.rb b/spec/controllers/explore/projects_controller_spec.rb index f2328303102..c3f6c653376 100644 --- a/spec/controllers/explore/projects_controller_spec.rb +++ b/spec/controllers/explore/projects_controller_spec.rb @@ -73,6 +73,24 @@ RSpec.describe Explore::ProjectsController do expect(assigns(:projects)).to eq [project1, project2] end end + + context 'projects aimed for deletion' do + let(:project1) { create(:project, :public, updated_at: 3.days.ago) } + let(:project2) { create(:project, :public, updated_at: 1.day.ago) } + let(:aimed_for_deletion_project) { create(:project, :public, :archived, updated_at: 2.days.ago, marked_for_deletion_at: 2.days.ago) } + + before do + create(:trending_project, project: project1) + create(:trending_project, project: project2) + create(:trending_project, project: aimed_for_deletion_project) + end + + it 'does not list projects aimed for deletion' do + get :trending + + expect(assigns(:projects)).to eq [project2, project1] + end + end end describe 'GET #topic' do diff --git a/spec/features/admin/users/users_spec.rb b/spec/features/admin/users/users_spec.rb index 473f51370b3..5b0b6e085c9 100644 --- a/spec/features/admin/users/users_spec.rb +++ b/spec/features/admin/users/users_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe 'Admin::Users' do include Spec::Support::Helpers::Features::AdminUsersHelpers + include Spec::Support::Helpers::ModalHelpers let_it_be(:user, reload: true) { create(:omniauth_user, provider: 'twitter', extern_uid: '123456') } let_it_be(:current_user) { create(:admin) } @@ -294,6 +295,22 @@ RSpec.describe 'Admin::Users' do end end + context 'when a user is locked', time_travel_to: '2020-02-25 10:30:45 -0700' do + let_it_be(:locked_user) { create(:user, locked_at: DateTime.parse('2020-02-25 10:30:00 -0700')) } + + it "displays `Locked` badge next to user" do + expect(page).to have_content("#{locked_user.name} Locked") + end + + it 'allows a user to be unlocked from the `User administration dropdown', :js do + accept_gl_confirm("Unlock user #{locked_user.name}?", button_text: 'Unlock') do + click_action_in_user_dropdown(locked_user.id, 'Unlock') + end + + expect(page).not_to have_content("#{locked_user.name} (Locked)") + end + end + describe 'internal users' do context 'when showing a `Ghost User`' do let_it_be(:ghost_user) { create(:user, :ghost) } diff --git a/spec/features/merge_request/user_sees_merge_widget_spec.rb b/spec/features/merge_request/user_sees_merge_widget_spec.rb index 8761ee89463..872507c3b7a 100644 --- a/spec/features/merge_request/user_sees_merge_widget_spec.rb +++ b/spec/features/merge_request/user_sees_merge_widget_spec.rb @@ -104,10 +104,11 @@ RSpec.describe 'Merge request > User sees merge widget', :js do visit project_merge_request_path(project, merge_request) end - it 'has danger button while waiting for external CI status' do + it 'has merge button with confirm variant while waiting for external CI status' do # Wait for the `ci_status` and `merge_check` requests wait_for_requests - expect(page).to have_selector('.accept-merge-request.btn-danger') + + expect(page).to have_selector('.accept-merge-request.btn-confirm') end end @@ -125,10 +126,27 @@ RSpec.describe 'Merge request > User sees merge widget', :js do visit project_merge_request_path(project, merge_request) end - it 'has danger button when not succeeded' do + it 'has merge button that shows modal when pipeline does not succeeded' do # Wait for the `ci_status` and `merge_check` requests wait_for_requests - expect(page).to have_selector('.accept-merge-request.btn-danger') + + click_button 'Merge...' + + expect(page).to have_selector('[data-testid="merge-failed-pipeline-confirmation-dialog"]', visible: true) + end + + it 'allows me to merge with a failed pipeline' do + modal_selector = '[data-testid="merge-failed-pipeline-confirmation-dialog"]' + + wait_for_requests + + click_button 'Merge...' + + page.within(modal_selector) do + click_button 'Merge unverified changes' + end + + expect(find('.media-body h4')).to have_content('Merging!') end end diff --git a/spec/features/projects/view_on_env_spec.rb b/spec/features/projects/view_on_env_spec.rb index 94085b075aa..5dd30f59e3d 100644 --- a/spec/features/projects/view_on_env_spec.rb +++ b/spec/features/projects/view_on_env_spec.rb @@ -9,7 +9,6 @@ RSpec.describe 'View on environment', :js do let(:user) { project.creator } before do - stub_feature_flags(refactor_blob_viewer: false) # This stub will be removed in https://gitlab.com/gitlab-org/gitlab/-/issues/350457 project.add_maintainer(user) end diff --git a/spec/finders/environments/environments_by_deployments_finder_spec.rb b/spec/finders/environments/environments_by_deployments_finder_spec.rb index 8349092c79e..c8e6b038634 100644 --- a/spec/finders/environments/environments_by_deployments_finder_spec.rb +++ b/spec/finders/environments/environments_by_deployments_finder_spec.rb @@ -64,6 +64,22 @@ RSpec.describe Environments::EnvironmentsByDeploymentsFinder do end end + context 'sha deployment' do + before do + create(:deployment, :success, environment: environment, sha: project.commit.id) + end + + it 'returns environment' do + expect(described_class.new(project, user, sha: project.commit.id).execute) + .to contain_exactly(environment) + end + + it 'does not return environment when sha is different' do + expect(described_class.new(project, user, sha: '1234').execute) + .to be_empty + end + end + context 'commit deployment' do before do create(:deployment, :success, environment: environment, ref: 'master', sha: project.commit.id) diff --git a/spec/finders/group_descendants_finder_spec.rb b/spec/finders/group_descendants_finder_spec.rb index 26fa5544f3b..5c5db874e85 100644 --- a/spec/finders/group_descendants_finder_spec.rb +++ b/spec/finders/group_descendants_finder_spec.rb @@ -68,6 +68,12 @@ RSpec.describe GroupDescendantsFinder do expect(finder.execute).to be_empty end + it 'does not include projects aimed for deletion' do + _project_aimed_for_deletion = create(:project, :archived, marked_for_deletion_at: 2.days.ago, pending_delete: false) + + expect(finder.execute).to be_empty + end + context 'with a filter' do let(:params) { { filter: 'test' } } diff --git a/spec/frontend/blob/components/blob_header_default_actions_spec.js b/spec/frontend/blob/components/blob_header_default_actions_spec.js index e321bb41774..af605b257de 100644 --- a/spec/frontend/blob/components/blob_header_default_actions_spec.js +++ b/spec/frontend/blob/components/blob_header_default_actions_spec.js @@ -1,13 +1,13 @@ import { GlButtonGroup, GlButton } from '@gitlab/ui'; -import { mount } from '@vue/test-utils'; import BlobHeaderActions from '~/blob/components/blob_header_default_actions.vue'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { BTN_COPY_CONTENTS_TITLE, BTN_DOWNLOAD_TITLE, BTN_RAW_TITLE, RICH_BLOB_VIEWER, } from '~/blob/components/constants'; -import { Blob } from './mock_data'; +import { Blob, mockEnvironmentName, mockEnvironmentPath } from './mock_data'; describe('Blob Header Default Actions', () => { let wrapper; @@ -17,7 +17,7 @@ describe('Blob Header Default Actions', () => { const blobHash = 'foo-bar'; function createComponent(propsData = {}) { - wrapper = mount(BlobHeaderActions, { + wrapper = shallowMountExtended(BlobHeaderActions, { provide: { blobHash, }, @@ -39,8 +39,8 @@ describe('Blob Header Default Actions', () => { }); describe('renders', () => { - const findCopyButton = () => wrapper.find('[data-testid="copyContentsButton"]'); - const findViewRawButton = () => wrapper.find('[data-testid="viewRawButton"]'); + const findCopyButton = () => wrapper.findByTestId('copyContentsButton'); + const findViewRawButton = () => wrapper.findByTestId('viewRawButton'); it('gl-button-group component', () => { expect(btnGroup.exists()).toBe(true); @@ -89,4 +89,37 @@ describe('Blob Header Default Actions', () => { expect(findViewRawButton().exists()).toBe(false); }); }); + + describe('view on environment button', () => { + const findEnvironmentButton = () => wrapper.findByTestId('environment'); + + it.each` + environmentName | environmentPath | isVisible + ${null} | ${null} | ${false} + ${null} | ${mockEnvironmentPath} | ${false} + ${mockEnvironmentName} | ${null} | ${false} + ${mockEnvironmentName} | ${mockEnvironmentPath} | ${true} + `( + 'when environmentName is $environmentName and environmentPath is $environmentPath', + ({ environmentName, environmentPath, isVisible }) => { + createComponent({ environmentName, environmentPath }); + + expect(findEnvironmentButton().exists()).toBe(isVisible); + }, + ); + + it('renders the correct attributes', () => { + createComponent({ + environmentName: mockEnvironmentName, + environmentPath: mockEnvironmentPath, + }); + + expect(findEnvironmentButton().attributes()).toMatchObject({ + title: `View on ${mockEnvironmentName}`, + href: mockEnvironmentPath, + }); + + expect(findEnvironmentButton().props('icon')).toBe('external-link'); + }); + }); }); diff --git a/spec/frontend/blob/components/mock_data.js b/spec/frontend/blob/components/mock_data.js index 95789ca13cb..9a345921f16 100644 --- a/spec/frontend/blob/components/mock_data.js +++ b/spec/frontend/blob/components/mock_data.js @@ -55,3 +55,6 @@ export const SimpleBlobContentMock = { path: 'foo.js', plainData: 'Plain', }; + +export const mockEnvironmentName = 'my.testing.environment'; +export const mockEnvironmentPath = 'https://my.testing.environment'; diff --git a/spec/frontend/repository/mock_data.js b/spec/frontend/repository/mock_data.js index a5ee17ba672..b8ab5cfcef1 100644 --- a/spec/frontend/repository/mock_data.js +++ b/spec/frontend/repository/mock_data.js @@ -11,6 +11,8 @@ export const simpleViewerMock = { ideEditPath: 'some_file.js/ide/edit', forkAndEditPath: 'some_file.js/fork/edit', ideForkAndEditPath: 'some_file.js/fork/ide', + environmentFormattedExternalUrl: '', + environmentExternalUrlForRouteMap: '', canModifyBlob: true, canCurrentUserPushToBranch: true, archived: false, diff --git a/spec/frontend/vue_mr_widget/components/states/merge_failed_pipeline_confirmation_dialog_spec.js b/spec/frontend/vue_mr_widget/components/states/merge_failed_pipeline_confirmation_dialog_spec.js new file mode 100644 index 00000000000..0e1c38437f0 --- /dev/null +++ b/spec/frontend/vue_mr_widget/components/states/merge_failed_pipeline_confirmation_dialog_spec.js @@ -0,0 +1,78 @@ +import { shallowMount } from '@vue/test-utils'; +import MergeFailedPipelineConfirmationDialog from '~/vue_merge_request_widget/components/states/merge_failed_pipeline_confirmation_dialog.vue'; +import { trimText } from 'helpers/text_helper'; + +describe('MergeFailedPipelineConfirmationDialog', () => { + let wrapper; + + const GlModal = { + template: ` + <div> + <slot></slot> + <slot name="modal-footer"></slot> + </div> + `, + methods: { + hide: jest.fn(), + }, + }; + + const createComponent = () => { + wrapper = shallowMount(MergeFailedPipelineConfirmationDialog, { + propsData: { + visible: true, + }, + stubs: { + GlModal, + }, + attachTo: document.body, + }); + }; + + const findModal = () => wrapper.findComponent(GlModal); + const findMergeBtn = () => wrapper.find('[data-testid="merge-unverified-changes"]'); + const findCancelBtn = () => wrapper.find('[data-testid="merge-cancel-btn"]'); + + beforeEach(() => { + createComponent(); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('should render informational text explaining why merging immediately can be dangerous', () => { + expect(trimText(wrapper.text())).toContain( + 'The latest pipeline for this merge request did not succeed. The latest changes are unverified. Are you sure you want to attempt to merge?', + ); + }); + + it('should emit the mergeWithFailedPipeline event', () => { + findMergeBtn().vm.$emit('click'); + + expect(wrapper.emitted('mergeWithFailedPipeline')).toBeTruthy(); + }); + + it('when the cancel button is clicked should emit cancel and call hide', () => { + jest.spyOn(findModal().vm, 'hide'); + + findCancelBtn().vm.$emit('click'); + + expect(wrapper.emitted('cancel')).toBeTruthy(); + expect(findModal().vm.hide).toHaveBeenCalled(); + }); + + it('should emit cancel when the hide event is emitted', () => { + findModal().vm.$emit('hide'); + + expect(wrapper.emitted('cancel')).toBeTruthy(); + }); + + it('when modal is shown it will focus the cancel button', () => { + jest.spyOn(findCancelBtn().element, 'focus'); + + findModal().vm.$emit('shown'); + + expect(findCancelBtn().element.focus).toHaveBeenCalled(); + }); +}); 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 8b4a0b4c28e..d1ac1608fd5 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 @@ -7,6 +7,7 @@ import CommitMessageDropdown from '~/vue_merge_request_widget/components/states/ import CommitsHeader from '~/vue_merge_request_widget/components/states/commits_header.vue'; import ReadyToMerge from '~/vue_merge_request_widget/components/states/ready_to_merge.vue'; import SquashBeforeMerge from '~/vue_merge_request_widget/components/states/squash_before_merge.vue'; +import MergeFailedPipelineConfirmationDialog from '~/vue_merge_request_widget/components/states/merge_failed_pipeline_confirmation_dialog.vue'; import { MWPS_MERGE_STRATEGY } from '~/vue_merge_request_widget/constants'; import eventHub from '~/vue_merge_request_widget/event_hub'; @@ -61,6 +62,11 @@ const createTestService = () => ({ }); let wrapper; + +const findMergeButton = () => wrapper.find('[data-testid="merge-button"]'); +const findPipelineFailedConfirmModal = () => + wrapper.findComponent(MergeFailedPipelineConfirmationDialog); + const createComponent = (customConfig = {}, mergeRequestWidgetGraphql = false) => { wrapper = shallowMount(ReadyToMerge, { propsData: { @@ -132,33 +138,13 @@ describe('ReadyToMerge', () => { }); }); - describe('mergeButtonVariant', () => { + describe('Merge Button Variant', () => { it('defaults to confirm class', () => { createComponent({ mr: { availableAutoMergeStrategies: [] }, }); - expect(wrapper.vm.mergeButtonVariant).toEqual('confirm'); - }); - - it('returns confirm class for success status', () => { - createComponent({ - mr: { availableAutoMergeStrategies: [], pipeline: true }, - }); - - expect(wrapper.vm.mergeButtonVariant).toEqual('confirm'); - }); - - it('returns confirm class for pending status', () => { - createComponent(); - - expect(wrapper.vm.mergeButtonVariant).toEqual('confirm'); - }); - - it('returns danger class for failed status', () => { - createComponent({ mr: { hasCI: true } }); - - expect(wrapper.vm.mergeButtonVariant).toEqual('danger'); + expect(findMergeButton().attributes('variant')).toBe('confirm'); }); }); @@ -794,4 +780,24 @@ describe('ReadyToMerge', () => { }); }); }); + + describe('Merge button when pipeline has failed', () => { + beforeEach(() => { + createComponent({ + mr: { pipeline: {}, isPipelineFailed: true, availableAutoMergeStrategies: [] }, + }); + }); + + it('should display the correct merge text', () => { + expect(findMergeButton().text()).toBe('Merge...'); + }); + + it('should display confirmation modal when merge button is clicked', async () => { + expect(findPipelineFailedConfirmModal().props()).toEqual({ visible: false }); + + await findMergeButton().vm.$emit('click'); + + expect(findPipelineFailedConfirmModal().props()).toEqual({ visible: true }); + }); + }); }); diff --git a/spec/graphql/types/repository/blob_type_spec.rb b/spec/graphql/types/repository/blob_type_spec.rb index 8d845e5d814..489b617f763 100644 --- a/spec/graphql/types/repository/blob_type_spec.rb +++ b/spec/graphql/types/repository/blob_type_spec.rb @@ -29,6 +29,8 @@ RSpec.describe Types::Repository::BlobType do :blame_path, :history_path, :permalink_path, + :environment_formatted_external_url, + :environment_external_url_for_route_map, :code_owners, :simple_viewer, :rich_viewer, diff --git a/spec/helpers/issuables_description_templates_helper_spec.rb b/spec/helpers/issuables_description_templates_helper_spec.rb index 6b05bab7432..768ce5975c1 100644 --- a/spec/helpers/issuables_description_templates_helper_spec.rb +++ b/spec/helpers/issuables_description_templates_helper_spec.rb @@ -72,6 +72,37 @@ RSpec.describe IssuablesDescriptionTemplatesHelper, :clean_gitlab_redis_cache do ].to_json expect(helper.available_service_desk_templates_for(@project)).to eq(value) end + + context 'when no issuable_template parameter or default template is present' do + it 'does not select a template' do + expect(helper.selected_template(project)).to be(nil) + end + end + + context 'when an issuable_template parameter has been provided' do + before do + allow(helper).to receive(:params).and_return({ issuable_template: 'another_issue_template' }) + end + + it 'selects the issuable template' do + expect(helper.selected_template(project)).to eq('another_issue_template') + end + end + + context 'when there is a default template' do + let(:templates) do + { + "" => [ + { name: "another_issue_template", id: "another_issue_template", project_id: project.id }, + { name: "default", id: "default", project_id: project.id } + ] + } + end + + it 'selects the default template' do + expect(helper.selected_template(project)).to eq('default') + end + end end context 'when there are not templates in the project' do diff --git a/spec/helpers/users_helper_spec.rb b/spec/helpers/users_helper_spec.rb index 2b55319c70c..a2d91414e78 100644 --- a/spec/helpers/users_helper_spec.rb +++ b/spec/helpers/users_helper_spec.rb @@ -122,7 +122,7 @@ RSpec.describe UsersHelper do badges = helper.user_badges_in_admin_section(blocked_user) - expect(filter_ee_badges(badges)).to eq([text: "Blocked", variant: "danger"]) + expect(filter_ee_badges(badges)).to match_array([text: "Blocked", variant: "danger"]) end end @@ -132,7 +132,7 @@ RSpec.describe UsersHelper do badges = helper.user_badges_in_admin_section(blocked_pending_approval_user) - expect(filter_ee_badges(badges)).to eq([text: 'Pending approval', variant: 'info']) + expect(filter_ee_badges(badges)).to match_array([text: 'Pending approval', variant: 'info']) end end @@ -142,7 +142,7 @@ RSpec.describe UsersHelper do badges = helper.user_badges_in_admin_section(banned_user) - expect(filter_ee_badges(badges)).to eq([text: 'Banned', variant: 'danger']) + expect(filter_ee_badges(badges)).to match_array([text: 'Banned', variant: 'danger']) end end @@ -152,7 +152,7 @@ RSpec.describe UsersHelper do badges = helper.user_badges_in_admin_section(admin_user) - expect(filter_ee_badges(badges)).to eq([text: "Admin", variant: "success"]) + expect(filter_ee_badges(badges)).to match_array([text: "Admin", variant: "success"]) end end @@ -162,7 +162,7 @@ RSpec.describe UsersHelper do badges = helper.user_badges_in_admin_section(external_user) - expect(filter_ee_badges(badges)).to eq([text: "External", variant: "secondary"]) + expect(filter_ee_badges(badges)).to match_array([text: "External", variant: "secondary"]) end end @@ -170,7 +170,7 @@ RSpec.describe UsersHelper do it 'returns the "It\'s You" badge' do badges = helper.user_badges_in_admin_section(user) - expect(filter_ee_badges(badges)).to eq([text: "It's you!", variant: "muted"]) + expect(filter_ee_badges(badges)).to match_array([text: "It's you!", variant: "muted"]) end end @@ -180,7 +180,7 @@ RSpec.describe UsersHelper do badges = helper.user_badges_in_admin_section(user) - expect(badges).to eq([ + expect(badges).to match_array([ { text: "Blocked", variant: "danger" }, { text: "Admin", variant: "success" }, { text: "External", variant: "secondary" } @@ -188,6 +188,16 @@ RSpec.describe UsersHelper do end end + context 'with a locked user', time_travel_to: '2020-02-25 10:30:45 -0700' do + it 'returns the "Locked" badge' do + locked_user = create(:user, locked_at: DateTime.parse('2020-02-25 10:30:00 -0700')) + + badges = helper.user_badges_in_admin_section(locked_user) + + expect(filter_ee_badges(badges)).to match_array([text: "Locked", variant: "warning"]) + end + end + context 'get badges for normal user' do it 'returns no badges' do user = create(:user) diff --git a/spec/models/deployment_spec.rb b/spec/models/deployment_spec.rb index 29b37ef7371..299800c56a3 100644 --- a/spec/models/deployment_spec.rb +++ b/spec/models/deployment_spec.rb @@ -615,7 +615,7 @@ RSpec.describe Deployment do it 'returns false' do commit = project.commit('feature') - expect(deployment.includes_commit?(commit)).to be false + expect(deployment.includes_commit?(commit.id)).to be false end end @@ -623,7 +623,7 @@ RSpec.describe Deployment do it 'returns true' do commit = project.commit - expect(deployment.includes_commit?(commit)).to be true + expect(deployment.includes_commit?(commit.id)).to be true end end @@ -632,7 +632,7 @@ RSpec.describe Deployment do deployment.update!(sha: Gitlab::Git::BLANK_SHA) commit = project.commit - expect(deployment.includes_commit?(commit)).to be false + expect(deployment.includes_commit?(commit.id)).to be false end end end diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb index 3dd0e01d7b3..112dc93658f 100644 --- a/spec/models/environment_spec.rb +++ b/spec/models/environment_spec.rb @@ -412,7 +412,7 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do context 'in the same branch' do it 'returns true' do - expect(environment.includes_commit?(RepoHelpers.sample_commit)).to be true + expect(environment.includes_commit?(RepoHelpers.sample_commit.id)).to be true end end @@ -422,7 +422,7 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do end it 'returns false' do - expect(environment.includes_commit?(RepoHelpers.sample_commit)).to be false + expect(environment.includes_commit?(RepoHelpers.sample_commit.id)).to be false end end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index ac2474ac393..27dde57c03c 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -3602,13 +3602,16 @@ RSpec.describe User do let!(:project1) { create(:project) } let!(:project2) { fork_project(project3) } let!(:project3) { create(:project) } + let!(:project_aimed_for_deletion) { create(:project, marked_for_deletion_at: 2.days.ago, pending_delete: false) } let!(:merge_request) { create(:merge_request, source_project: project2, target_project: project3, author: subject) } let!(:push_event) { create(:push_event, project: project1, author: subject) } let!(:merge_event) { create(:event, :created, project: project3, target: merge_request, author: subject) } + let!(:merge_event_2) { create(:event, :created, project: project_aimed_for_deletion, target: merge_request, author: subject) } before do project1.add_maintainer(subject) project2.add_maintainer(subject) + project_aimed_for_deletion.add_maintainer(subject) end it 'includes IDs for projects the user has pushed to' do @@ -3622,6 +3625,10 @@ RSpec.describe User do it "doesn't include IDs for unrelated projects" do expect(subject.contributed_projects).not_to include(project2) end + + it "doesn't include projects aimed for deletion" do + expect(subject.contributed_projects).not_to include(project_aimed_for_deletion) + end end describe '#fork_of' do diff --git a/spec/presenters/blob_presenter_spec.rb b/spec/presenters/blob_presenter_spec.rb index 30c5d17b2aa..abeeef69d39 100644 --- a/spec/presenters/blob_presenter_spec.rb +++ b/spec/presenters/blob_presenter_spec.rb @@ -87,6 +87,33 @@ RSpec.describe BlobPresenter do it { expect(presenter.permalink_path).to eq("/#{project.full_path}/-/blob/#{project.repository.commit.sha}/files/ruby/regex.rb") } end + context 'environment has been deployed' do + let(:external_url) { "https://some.environment" } + let(:environment) { create(:environment, project: project, external_url: external_url) } + let!(:deployment) { create(:deployment, :success, environment: environment, project: project, sha: blob.commit_id) } + + before do + allow(project).to receive(:public_path_for_source_path).with(blob.path, blob.commit_id).and_return(blob.path) + end + + describe '#environment_formatted_external_url' do + it { expect(presenter.environment_formatted_external_url).to eq("some.environment") } + end + + describe '#environment_external_url_for_route_map' do + it { expect(presenter.environment_external_url_for_route_map).to eq("#{external_url}/#{blob.path}") } + end + + describe 'chooses the latest deployed environment for #environment_formatted_external_url and #environment_external_url_for_route_map' do + let(:another_external_url) { "https://another.environment" } + let(:another_environment) { create(:environment, project: project, external_url: another_external_url) } + let!(:another_deployment) { create(:deployment, :success, environment: another_environment, project: project, sha: blob.commit_id) } + + it { expect(presenter.environment_formatted_external_url).to eq("another.environment") } + it { expect(presenter.environment_external_url_for_route_map).to eq("#{another_external_url}/#{blob.path}") } + end + end + describe '#code_owners' do it { expect(presenter.code_owners).to match_array([]) } end diff --git a/spec/requests/users_controller_spec.rb b/spec/requests/users_controller_spec.rb index cbbb3a054f4..d033ce15b00 100644 --- a/spec/requests/users_controller_spec.rb +++ b/spec/requests/users_controller_spec.rb @@ -506,6 +506,7 @@ RSpec.describe UsersController do describe 'GET #contributed' do let(:project) { create(:project, :public) } + let(:aimed_for_deletion_project) { create(:project, :public, :archived, marked_for_deletion_at: 3.days.ago) } subject do get user_contributed_projects_url author.username, format: format @@ -516,7 +517,10 @@ RSpec.describe UsersController do project.add_developer(public_user) project.add_developer(private_user) + aimed_for_deletion_project.add_developer(public_user) + aimed_for_deletion_project.add_developer(private_user) create(:push_event, project: project, author: author) + create(:push_event, project: aimed_for_deletion_project, author: author) subject end @@ -526,6 +530,11 @@ RSpec.describe UsersController do expect(response).to have_gitlab_http_status(:ok) expect(response.body).not_to be_empty end + + it 'does not list projects aimed for deletion' do + expect(response).to have_gitlab_http_status(:ok) + expect(assigns(:contributed_projects)).to eq([project]) + end end %i(html json).each do |format| @@ -557,6 +566,7 @@ RSpec.describe UsersController do describe 'GET #starred' do let(:project) { create(:project, :public) } + let(:aimed_for_deletion_project) { create(:project, :public, :archived, marked_for_deletion_at: 3.days.ago) } subject do get user_starred_projects_url author.username, format: format @@ -574,6 +584,11 @@ RSpec.describe UsersController do expect(response).to have_gitlab_http_status(:ok) expect(response.body).not_to be_empty end + + it 'does not list projects aimed for deletion' do + expect(response).to have_gitlab_http_status(:ok) + expect(assigns(:starred_projects)).to eq([project]) + end end %i(html json).each do |format| |