summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-01-28 03:15:57 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-01-28 03:15:57 +0000
commitc5f4c801a6b40e7ee4b96aba20bbec687ccf0502 (patch)
treead58e3d5ca9b38d0e86a78143f12362bb35ea1be /spec
parent3235221bc498ca3c80eeca505fb32bf9f237778a (diff)
downloadgitlab-ce-c5f4c801a6b40e7ee4b96aba20bbec687ccf0502.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/dashboard/projects_controller_spec.rb24
-rw-r--r--spec/controllers/explore/projects_controller_spec.rb18
-rw-r--r--spec/features/admin/users/users_spec.rb17
-rw-r--r--spec/features/merge_request/user_sees_merge_widget_spec.rb26
-rw-r--r--spec/features/projects/view_on_env_spec.rb1
-rw-r--r--spec/finders/environments/environments_by_deployments_finder_spec.rb16
-rw-r--r--spec/finders/group_descendants_finder_spec.rb6
-rw-r--r--spec/frontend/blob/components/blob_header_default_actions_spec.js43
-rw-r--r--spec/frontend/blob/components/mock_data.js3
-rw-r--r--spec/frontend/repository/mock_data.js2
-rw-r--r--spec/frontend/vue_mr_widget/components/states/merge_failed_pipeline_confirmation_dialog_spec.js78
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js50
-rw-r--r--spec/graphql/types/repository/blob_type_spec.rb2
-rw-r--r--spec/helpers/issuables_description_templates_helper_spec.rb31
-rw-r--r--spec/helpers/users_helper_spec.rb24
-rw-r--r--spec/models/deployment_spec.rb6
-rw-r--r--spec/models/environment_spec.rb4
-rw-r--r--spec/models/user_spec.rb7
-rw-r--r--spec/presenters/blob_presenter_spec.rb27
-rw-r--r--spec/requests/users_controller_spec.rb15
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|