diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-09-05 15:13:20 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-09-05 15:13:20 +0300 |
commit | e67e43e958982189b5ba3b816744ab162a34dd4b (patch) | |
tree | f56cc1c78dbd9befcc1db912299b48f335b4daef /spec | |
parent | a7ad6496140ba3272b2d88d8e79e7e4d699f5653 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
34 files changed, 395 insertions, 409 deletions
diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb index 0793e790301..556dd23c135 100644 --- a/spec/controllers/projects/jobs_controller_spec.rb +++ b/spec/controllers/projects/jobs_controller_spec.rb @@ -5,9 +5,25 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do include ApiHelpers include HttpIOHelpers - let(:project) { create(:project, :public, :repository) } + let_it_be(:project) { create(:project, :public, :repository) } + let_it_be(:owner) { create(:owner) } + let_it_be(:admin) { create(:admin) } + let_it_be(:maintainer) { create(:user) } + let_it_be(:developer) { create(:user) } + let_it_be(:reporter) { create(:user) } + let_it_be(:guest) { create(:user) } + + before_all do + project.add_owner(owner) + project.add_maintainer(maintainer) + project.add_developer(developer) + project.add_reporter(reporter) + project.add_guest(guest) + end + + let(:user) { developer } + let(:pipeline) { create(:ci_pipeline, project: project) } - let(:user) { create(:user) } before do stub_feature_flags(ci_enable_live_trace: true) @@ -136,9 +152,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do context 'when requesting JSON' do let(:merge_request) { create(:merge_request, source_project: project) } + let(:user) { developer } before do - project.add_developer(user) sign_in(user) allow_any_instance_of(Ci::Build) @@ -307,9 +323,10 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do let(:environment) { create(:environment, project: project, name: 'staging', state: :available) } let(:job) { create(:ci_build, :running, environment: environment.name, pipeline: pipeline) } + let(:user) { maintainer } + before do create(:deployment, :success, :on_cluster, environment: environment, project: project) - project.add_maintainer(user) # Need to be a maintianer to view cluster.path end it 'exposes the deployment information' do @@ -330,9 +347,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do context 'that belongs to the project' do let(:runner) { create(:ci_runner, :project, projects: [project]) } let(:job) { create(:ci_build, :success, pipeline: pipeline, runner: runner) } + let(:user) { maintainer } before do - project.add_maintainer(user) sign_in(user) end @@ -349,10 +366,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do let(:group) { create(:group) } let(:runner) { create(:ci_runner, :group, groups: [group]) } let(:job) { create(:ci_build, :success, pipeline: pipeline, runner: runner) } - let(:user) { create(:user, :admin) } + let(:user) { maintainer } before do - project.add_maintainer(user) sign_in(user) end @@ -368,10 +384,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do context 'that belongs to instance' do let(:runner) { create(:ci_runner, :instance) } let(:job) { create(:ci_build, :success, pipeline: pipeline, runner: runner) } - let(:user) { create(:user, :admin) } + let(:user) { maintainer } before do - project.add_maintainer(user) sign_in(user) end @@ -421,6 +436,8 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end context 'when user is developer' do + let(:user) { developer } + it 'settings_path is not available' do expect(response).to have_gitlab_http_status(:ok) expect(response).to match_response_schema('job/job_details') @@ -429,10 +446,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end context 'when user is maintainer' do - let(:user) { create(:user, :admin) } + let(:user) { admin } before do - project.add_maintainer(user) sign_in(user) end @@ -499,9 +515,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do let(:trigger) { create(:ci_trigger, project: project) } let(:trigger_request) { create(:ci_trigger_request, pipeline: pipeline, trigger: trigger) } let(:job) { create(:ci_build, pipeline: pipeline, trigger_request: trigger_request) } + let(:user) { developer } before do - project.add_developer(user) sign_in(user) allow_any_instance_of(Ci::Build) @@ -526,9 +542,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end context 'user is a maintainer' do - before do - project.add_maintainer(user) + let(:user) { maintainer } + before do get_show_json end @@ -579,7 +595,7 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do def get_show_json expect { get_show(id: job.id, format: :json) } - .to change { Gitlab::GitalyClient.get_request_count }.by_at_most(2) + .to change { Gitlab::GitalyClient.get_request_count }.by_at_most(3) end def get_show(**extra_params) @@ -617,8 +633,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do let!(:variable) { create(:ci_instance_variable, key: 'CI_DEBUG_TRACE', value: 'true') } context 'with proper permissions on a project' do + let(:user) { developer } + before do - project.add_developer(user) sign_in(user) end @@ -630,8 +647,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end context 'without proper permissions for debug logging' do + let(:user) { guest } + before do - project.add_guest(user) sign_in(user) end @@ -753,8 +771,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end describe 'POST retry' do + let(:user) { developer } + before do - project.add_developer(user) sign_in(user) end @@ -817,12 +836,13 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do describe 'POST play' do let(:variable_attributes) { [] } + let(:user) { developer } before do project.add_developer(user) create(:protected_branch, :developers_can_merge, - name: 'master', project: project) + name: 'protected-branch', project: project) sign_in(user) end @@ -899,8 +919,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do describe 'POST cancel' do context 'when user is authorized to cancel the build' do + let(:user) { developer } + before do - project.add_developer(user) sign_in(user) end @@ -965,8 +986,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do context 'when user is not authorized to cancel the build' do let!(:job) { create(:ci_build, :cancelable, pipeline: pipeline) } + let(:user) { guest } + before do - project.add_reporter(user) sign_in(user) post_cancel @@ -990,12 +1012,13 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do describe 'POST unschedule' do before do - create(:protected_branch, :developers_can_merge, name: 'master', project: project) + create(:protected_branch, :developers_can_merge, name: 'protected-branch', project: project) end context 'when user is authorized to unschedule the build' do + let(:user) { developer } + before do - project.add_developer(user) sign_in(user) post_unschedule @@ -1025,9 +1048,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do context 'when user is not authorized to unschedule the build' do let(:job) { create(:ci_build, :scheduled, pipeline: pipeline) } + let(:user) { guest } before do - project.add_reporter(user) sign_in(user) post_unschedule @@ -1048,10 +1071,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end describe 'POST erase' do - let(:role) { :maintainer } + let(:user) { maintainer } before do - project.add_role(user, role) sign_in(user) end @@ -1097,7 +1119,7 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end context 'when user is developer' do - let(:role) { :developer } + let(:user) { developer } let(:job) { create(:ci_build, :erasable, :trace_artifact, pipeline: pipeline, user: triggered_by) } context 'when triggered by same user' do @@ -1109,7 +1131,7 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end context 'when triggered by different user' do - let(:triggered_by) { create(:user) } + let(:triggered_by) { maintainer } it 'does not have successful status' do expect(response).not_to have_gitlab_http_status(:found) @@ -1168,8 +1190,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end context 'with proper permissions for debug logging on a project' do + let(:user) { developer } + before do - project.add_developer(user) sign_in(user) end @@ -1181,8 +1204,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end context 'without proper permissions for debug logging on a project' do + let(:user) { reporter } + before do - project.add_reporter(user) sign_in(user) end @@ -1218,37 +1242,6 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end end - context "when job has a trace in database" do - let(:job) { create(:ci_build, pipeline: pipeline) } - - before do - job.update_column(:trace, "Sample trace") - end - - it 'sends a trace file' do - response = subject - - expect(response).to have_gitlab_http_status(:ok) - expect(response.headers['Content-Type']).to eq('text/plain; charset=utf-8') - expect(response.headers['Content-Disposition']).to match(/^inline/) - expect(response.body).to eq('Sample trace') - end - - context 'when trace format is not text/plain' do - before do - job.update_column(:trace, '<html></html>') - end - - it 'sets content disposition to attachment' do - response = subject - - expect(response).to have_gitlab_http_status(:ok) - expect(response.headers['Content-Type']).to eq('text/plain; charset=utf-8') - expect(response.headers['Content-Disposition']).to match(/^attachment/) - end - end - end - context 'when job does not have a trace file' do let(:job) { create(:ci_build, pipeline: pipeline) } @@ -1274,8 +1267,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end describe 'GET #terminal' do + let(:user) { developer } + before do - project.add_developer(user) sign_in(user) end @@ -1323,8 +1317,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do describe 'GET #terminal_websocket_authorize' do let!(:job) { create(:ci_build, :running, :with_runner_session, pipeline: pipeline, user: user) } + let(:user) { developer } + before do - project.add_developer(user) sign_in(user) end @@ -1375,14 +1370,6 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end describe 'GET #proxy_websocket_authorize' do - let_it_be(:owner) { create(:owner) } - let_it_be(:admin) { create(:admin) } - let_it_be(:maintainer) { create(:user) } - let_it_be(:developer) { create(:user) } - let_it_be(:reporter) { create(:user) } - let_it_be(:guest) { create(:user) } - let_it_be(:project) { create(:project, :private, :repository, namespace: owner.namespace) } - let(:user) { maintainer } let(:pipeline) { create(:ci_pipeline, project: project, source: :webide, config_source: :webide_source, user: user) } let(:job) { create(:ci_build, :running, :with_runner_session, pipeline: pipeline, user: user) } @@ -1407,11 +1394,6 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do stub_feature_flags(build_service_proxy: true) allow(job).to receive(:has_terminal?).and_return(true) - project.add_maintainer(maintainer) - project.add_developer(developer) - project.add_reporter(reporter) - project.add_guest(guest) - sign_in(user) end diff --git a/spec/features/projects/show/user_interacts_with_stars_spec.rb b/spec/features/projects/show/user_interacts_with_stars_spec.rb index aa61b629d92..e0dd4f65010 100644 --- a/spec/features/projects/show/user_interacts_with_stars_spec.rb +++ b/spec/features/projects/show/user_interacts_with_stars_spec.rb @@ -14,14 +14,36 @@ RSpec.describe 'Projects > Show > User interacts with project stars' do end it 'toggles the star' do - find('.star-btn').click + star_project expect(page).to have_css('.star-count', text: 1) - find('.star-btn').click + unstar_project expect(page).to have_css('.star-count', text: 0) end + + it 'validates starring a project' do + project.add_owner(user) + + star_project + + visit(dashboard_projects_path) + + expect(page).to have_css('.stars', text: 1) + end + + it 'validates un-starring a project' do + project.add_owner(user) + + star_project + + unstar_project + + visit(dashboard_projects_path) + + expect(page).to have_css('.stars', text: 0) + end end context 'when user is not signed in' do @@ -38,3 +60,15 @@ RSpec.describe 'Projects > Show > User interacts with project stars' do end end end + +private + +def star_project + click_button(_('Star')) + wait_for_requests +end + +def unstar_project + click_button(_('Unstar')) + wait_for_requests +end diff --git a/spec/frontend/runner/admin_runners/admin_runners_app_spec.js b/spec/frontend/runner/admin_runners/admin_runners_app_spec.js index ebbb6ed27c7..55a298e1695 100644 --- a/spec/frontend/runner/admin_runners/admin_runners_app_spec.js +++ b/spec/frontend/runner/admin_runners/admin_runners_app_spec.js @@ -17,6 +17,7 @@ import { updateHistory } from '~/lib/utils/url_utility'; import { upgradeStatusTokenConfig } from 'ee_else_ce/runner/components/search_tokens/upgrade_status_token_config'; import { createLocalState } from '~/runner/graphql/list/local_state'; import AdminRunnersApp from '~/runner/admin_runners/admin_runners_app.vue'; +import RunnerStackedLayoutBanner from '~/runner/components/runner_stacked_layout_banner.vue'; import RunnerTypeTabs from '~/runner/components/runner_type_tabs.vue'; import RunnerFilteredSearchBar from '~/runner/components/runner_filtered_search_bar.vue'; import RunnerBulkDelete from '~/runner/components/runner_bulk_delete.vue'; @@ -86,6 +87,7 @@ describe('AdminRunnersApp', () => { let localMutations; let showToast; + const findRunnerStackedLayoutBanner = () => wrapper.findComponent(RunnerStackedLayoutBanner); const findRunnerStats = () => wrapper.findComponent(RunnerStats); const findRunnerActionsCell = () => wrapper.findComponent(RunnerActionsCell); const findRegistrationDropdown = () => wrapper.findComponent(RegistrationDropdown); @@ -145,6 +147,11 @@ describe('AdminRunnersApp', () => { wrapper.destroy(); }); + it('shows the feedback banner', () => { + createComponent(); + expect(findRunnerStackedLayoutBanner().exists()).toBe(true); + }); + it('shows the runner setup instructions', () => { createComponent(); diff --git a/spec/frontend/runner/components/runner_stacked_layout_banner_spec.js b/spec/frontend/runner/components/runner_stacked_layout_banner_spec.js new file mode 100644 index 00000000000..b892cfc7d3d --- /dev/null +++ b/spec/frontend/runner/components/runner_stacked_layout_banner_spec.js @@ -0,0 +1,57 @@ +import Vue from 'vue'; +import { GlBanner } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; +import RunnerStackedLayoutBanner from '~/runner/components/runner_stacked_layout_banner.vue'; +import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue'; + +describe('RunnerStackedLayoutBanner', () => { + let wrapper; + + const findBanner = () => wrapper.findComponent(GlBanner); + const findLocalStorageSync = () => wrapper.findComponent(LocalStorageSync); + + const createComponent = ({ ...options } = {}, mountFn = shallowMount) => { + wrapper = mountFn(RunnerStackedLayoutBanner, { + ...options, + }); + }; + + it('Does not display a banner', () => { + createComponent(); + + expect(findBanner().exists()).toBe(false); + }); + + describe.each` + glFeatures + ${{ runnerListStackedLayoutAdmin: true }} + ${{ runnerListStackedLayout: true }} + `('When glFeatures = $glFeatures', ({ glFeatures }) => { + beforeEach(() => { + createComponent({ + provide: { + glFeatures, + }, + }); + }); + + it('Displays a banner', () => { + expect(findBanner().props()).toMatchObject({ + svgPath: expect.stringContaining('data:image/svg+xml;utf8,'), + title: expect.any(String), + buttonText: expect.any(String), + buttonLink: expect.stringContaining('https://gitlab.com/gitlab-org/gitlab/-/issues/'), + }); + expect(findLocalStorageSync().exists()).toBe(true); + }); + + it('Does not display a banner when dismissed', async () => { + findLocalStorageSync().vm.$emit('input', true); + + await Vue.nextTick(); + + expect(findBanner().exists()).toBe(false); + expect(findLocalStorageSync().exists()).toBe(true); // continues syncing after removal + }); + }); +}); diff --git a/spec/frontend/runner/group_runners/group_runners_app_spec.js b/spec/frontend/runner/group_runners/group_runners_app_spec.js index 2335cd5d7d6..a17502c7eec 100644 --- a/spec/frontend/runner/group_runners/group_runners_app_spec.js +++ b/spec/frontend/runner/group_runners/group_runners_app_spec.js @@ -15,6 +15,7 @@ import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { updateHistory } from '~/lib/utils/url_utility'; import { upgradeStatusTokenConfig } from 'ee_else_ce/runner/components/search_tokens/upgrade_status_token_config'; +import RunnerStackedLayoutBanner from '~/runner/components/runner_stacked_layout_banner.vue'; import RunnerTypeTabs from '~/runner/components/runner_type_tabs.vue'; import RunnerFilteredSearchBar from '~/runner/components/runner_filtered_search_bar.vue'; import RunnerList from '~/runner/components/runner_list.vue'; @@ -77,6 +78,7 @@ jest.mock('~/lib/utils/url_utility', () => ({ describe('GroupRunnersApp', () => { let wrapper; + const findRunnerStackedLayoutBanner = () => wrapper.findComponent(RunnerStackedLayoutBanner); const findRunnerStats = () => wrapper.findComponent(RunnerStats); const findRunnerActionsCell = () => wrapper.findComponent(RunnerActionsCell); const findRegistrationDropdown = () => wrapper.findComponent(RegistrationDropdown); @@ -125,6 +127,11 @@ describe('GroupRunnersApp', () => { wrapper.destroy(); }); + it('shows the feedback banner', () => { + createComponent(); + expect(findRunnerStackedLayoutBanner().exists()).toBe(true); + }); + it('shows the runner tabs with a runner count for each type', async () => { await createComponent({ mountFn: mountExtended }); diff --git a/spec/lib/gitlab/ci/config/external/mapper_spec.rb b/spec/lib/gitlab/ci/config/external/mapper_spec.rb index e74fdc2071b..9eaba12f388 100644 --- a/spec/lib/gitlab/ci/config/external/mapper_spec.rb +++ b/spec/lib/gitlab/ci/config/external/mapper_spec.rb @@ -210,7 +210,7 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper do { 'local' => local_file }, { 'local' => local_file } ], - image: 'image:1.0' } + image: 'image:1.0' } end it 'does not raise an exception' do @@ -427,7 +427,7 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper do { 'local' => 'hello/secret-file1.yml' }, { 'local' => 'hello/secret-file2.yml' } ], - image: 'ruby:2.7' } + image: 'ruby:2.7' } end it 'has expanset with two' do diff --git a/spec/lib/gitlab/ci/lint_spec.rb b/spec/lib/gitlab/ci/lint_spec.rb index 7e0b2b5aa8e..3d46d266c13 100644 --- a/spec/lib/gitlab/ci/lint_spec.rb +++ b/spec/lib/gitlab/ci/lint_spec.rb @@ -341,9 +341,9 @@ RSpec.describe Gitlab::Ci::Lint do let(:counters) do { 'count' => a_kind_of(Numeric), - 'avg' => a_kind_of(Numeric), - 'max' => a_kind_of(Numeric), - 'min' => a_kind_of(Numeric) + 'avg' => a_kind_of(Numeric), + 'max' => a_kind_of(Numeric), + 'min' => a_kind_of(Numeric) } end diff --git a/spec/lib/gitlab/ci/pipeline/seed/deployment_spec.rb b/spec/lib/gitlab/ci/pipeline/seed/deployment_spec.rb index 51185be3e74..6569ce937ac 100644 --- a/spec/lib/gitlab/ci/pipeline/seed/deployment_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/seed/deployment_spec.rb @@ -6,8 +6,7 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Deployment do let_it_be(:project, refind: true) { create(:project, :repository) } let(:pipeline) do - create(:ci_pipeline, project: project, - sha: 'b83d6e391c22777fca1ed3012fce84f633d7fed0') + create(:ci_pipeline, project: project, sha: 'b83d6e391c22777fca1ed3012fce84f633d7fed0') end let(:job) { build(:ci_build, project: project, pipeline: pipeline) } diff --git a/spec/lib/gitlab/ci/trace_spec.rb b/spec/lib/gitlab/ci/trace_spec.rb index 888ceb7ff9a..3043c8c5467 100644 --- a/spec/lib/gitlab/ci/trace_spec.rb +++ b/spec/lib/gitlab/ci/trace_spec.rb @@ -10,7 +10,6 @@ RSpec.describe Gitlab::Ci::Trace, :clean_gitlab_redis_shared_state, factory_defa describe "associations" do it { expect(trace).to respond_to(:job) } - it { expect(trace).to delegate_method(:old_trace).to(:job) } end context 'when trace is migrated to object storage' do diff --git a/spec/lib/gitlab/ci/variables/builder_spec.rb b/spec/lib/gitlab/ci/variables/builder_spec.rb index fc6211a7ba3..4833ccf9093 100644 --- a/spec/lib/gitlab/ci/variables/builder_spec.rb +++ b/spec/lib/gitlab/ci/variables/builder_spec.rb @@ -138,11 +138,11 @@ RSpec.describe Gitlab::Ci::Variables::Builder, :clean_gitlab_redis_cache do { key: 'GITLAB_USER_ID', value: user.id.to_s }, { key: 'GITLAB_USER_EMAIL', - value: user.email }, + value: user.email }, { key: 'GITLAB_USER_LOGIN', - value: user.username }, + value: user.username }, { key: 'GITLAB_USER_NAME', - value: user.name } + value: user.name } ].map { |var| var.merge(public: true, masked: false) } end diff --git a/spec/lib/gitlab/ci/yaml_processor_spec.rb b/spec/lib/gitlab/ci/yaml_processor_spec.rb index bffdd370179..b68b12d8f43 100644 --- a/spec/lib/gitlab/ci/yaml_processor_spec.rb +++ b/spec/lib/gitlab/ci/yaml_processor_spec.rb @@ -298,8 +298,8 @@ module Gitlab context 'when delayed is defined' do let(:config) do YAML.dump(rspec: { - script: 'rollout 10%', - when: 'delayed', + script: 'rollout 10%', + when: 'delayed', start_in: '1 day' }) end @@ -315,7 +315,7 @@ module Gitlab context 'when resource group is defined' do let(:config) do YAML.dump(rspec: { - script: 'test', + script: 'test', resource_group: 'iOS' }) end @@ -1676,10 +1676,10 @@ module Gitlab describe "Artifacts" do it "returns artifacts when defined" do config = YAML.dump({ - image: "image:1.0", - services: ["mysql"], + image: "image:1.0", + services: ["mysql"], before_script: ["pwd"], - rspec: { + rspec: { artifacts: { paths: ["logs/", "binaries/"], expose_as: "Exposed artifacts", @@ -1935,7 +1935,7 @@ module Gitlab let(:config) do { deploy_to_production: { - stage: 'deploy', + stage: 'deploy', script: 'test' } } @@ -2304,15 +2304,15 @@ module Gitlab let(:config) do { - var_default: { stage: 'build', script: 'test', rules: [{ if: '$VAR == null' }] }, - var_when: { stage: 'build', script: 'test', rules: [{ if: '$VAR == null', when: 'always' }] }, + var_default: { stage: 'build', script: 'test', rules: [{ if: '$VAR == null' }] }, + var_when: { stage: 'build', script: 'test', rules: [{ if: '$VAR == null', when: 'always' }] }, var_and_changes: { stage: 'build', script: 'test', rules: [{ if: '$VAR == null', changes: %w[README], when: 'always' }] }, changes_not_var: { stage: 'test', script: 'test', rules: [{ if: '$VAR != null', changes: %w[README] }] }, var_not_changes: { stage: 'test', script: 'test', rules: [{ if: '$VAR == null', changes: %w[other/file.rb], when: 'always' }] }, - nothing: { stage: 'test', script: 'test', rules: [{ when: 'manual' }] }, - var_never: { stage: 'deploy', script: 'test', rules: [{ if: '$VAR == null', when: 'never' }] }, - var_delayed: { stage: 'deploy', script: 'test', rules: [{ if: '$VAR == null', when: 'delayed', start_in: '3 hours' }] }, - two_rules: { stage: 'deploy', script: 'test', rules: [{ if: '$VAR == null', when: 'on_success' }, { changes: %w[README], when: 'manual' }] } + nothing: { stage: 'test', script: 'test', rules: [{ when: 'manual' }] }, + var_never: { stage: 'deploy', script: 'test', rules: [{ if: '$VAR == null', when: 'never' }] }, + var_delayed: { stage: 'deploy', script: 'test', rules: [{ if: '$VAR == null', when: 'delayed', start_in: '3 hours' }] }, + two_rules: { stage: 'deploy', script: 'test', rules: [{ if: '$VAR == null', when: 'on_success' }, { changes: %w[README], when: 'manual' }] } } end diff --git a/spec/lib/gitlab/data_builder/issuable_spec.rb b/spec/lib/gitlab/data_builder/issuable_spec.rb index f0802f335f4..455800a3f7d 100644 --- a/spec/lib/gitlab/data_builder/issuable_spec.rb +++ b/spec/lib/gitlab/data_builder/issuable_spec.rb @@ -73,7 +73,7 @@ RSpec.describe Gitlab::DataBuilder::Issuable do }, assignees: { previous: [], - current: [{ + current: [{ name: "Foo Bar", username: "foobar", avatar_url: "http://www.example.com/my-avatar.jpg" diff --git a/spec/lib/gitlab/data_builder/note_spec.rb b/spec/lib/gitlab/data_builder/note_spec.rb index 3fa535dd800..8e8b8ce6681 100644 --- a/spec/lib/gitlab/data_builder/note_spec.rb +++ b/spec/lib/gitlab/data_builder/note_spec.rb @@ -49,8 +49,7 @@ RSpec.describe Gitlab::DataBuilder::Note do let(:label) { create(:label, project: project) } let(:issue) do - create(:labeled_issue, created_at: fixed_time, updated_at: fixed_time, - project: project, labels: [label]) + create(:labeled_issue, created_at: fixed_time, updated_at: fixed_time, project: project, labels: [label]) end let(:note) do @@ -84,15 +83,15 @@ RSpec.describe Gitlab::DataBuilder::Note do describe 'When asking for a note on merge request' do let(:label) { create(:label, project: project) } let(:merge_request) do - create(:labeled_merge_request, created_at: fixed_time, - updated_at: fixed_time, - source_project: project, - labels: [label]) + create(:labeled_merge_request, + created_at: fixed_time, + updated_at: fixed_time, + source_project: project, + labels: [label]) end let(:note) do - create(:note_on_merge_request, noteable: merge_request, - project: project) + create(:note_on_merge_request, noteable: merge_request, project: project) end it_behaves_like 'includes general data' @@ -112,14 +111,15 @@ RSpec.describe Gitlab::DataBuilder::Note do describe 'When asking for a note on merge request diff' do let(:label) { create(:label, project: project) } let(:merge_request) do - create(:labeled_merge_request, created_at: fixed_time, updated_at: fixed_time, - source_project: project, - labels: [label]) + create(:labeled_merge_request, + created_at: fixed_time, + updated_at: fixed_time, + source_project: + project, labels: [label]) end let(:note) do - create(:diff_note_on_merge_request, noteable: merge_request, - project: project) + create(:diff_note_on_merge_request, noteable: merge_request, project: project) end it_behaves_like 'includes general data' @@ -138,13 +138,11 @@ RSpec.describe Gitlab::DataBuilder::Note do describe 'When asking for a note on project snippet' do let!(:snippet) do - create(:project_snippet, created_at: fixed_time, updated_at: fixed_time, - project: project) + create(:project_snippet, created_at: fixed_time, updated_at: fixed_time, project: project) end let!(:note) do - create(:note_on_project_snippet, noteable: snippet, - project: project) + create(:note_on_project_snippet, noteable: snippet, project: project) end it_behaves_like 'includes general data' diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb index dd5ad40d8ef..d73b478ee7c 100644 --- a/spec/lib/gitlab/database/migration_helpers_spec.rb +++ b/spec/lib/gitlab/database/migration_helpers_spec.rb @@ -667,7 +667,7 @@ RSpec.describe Gitlab::Database::MigrationHelpers do column: :user_id, on_delete: :cascade, name: name, - primary_key: :id).and_return(true) + primary_key: :id).and_return(true) expect(model).not_to receive(:execute).with(/ADD CONSTRAINT/) expect(model).to receive(:execute).with(/VALIDATE CONSTRAINT/) diff --git a/spec/lib/gitlab/database/partitioning/sliding_list_strategy_spec.rb b/spec/lib/gitlab/database/partitioning/sliding_list_strategy_spec.rb index 04b9fba5b2f..1768f97de54 100644 --- a/spec/lib/gitlab/database/partitioning/sliding_list_strategy_spec.rb +++ b/spec/lib/gitlab/database/partitioning/sliding_list_strategy_spec.rb @@ -181,9 +181,10 @@ RSpec.describe Gitlab::Database::Partitioning::SlidingListStrategy do Class.new(ApplicationRecord) do include PartitionedTable - partitioned_by :partition, strategy: :sliding_list, - next_partition_if: proc { false }, - detach_partition_if: proc { false } + partitioned_by :partition, + strategy: :sliding_list, + next_partition_if: proc { false }, + detach_partition_if: proc { false } end end.to raise_error(/ignored_columns/) end @@ -195,7 +196,8 @@ RSpec.describe Gitlab::Database::Partitioning::SlidingListStrategy do self.ignored_columns = [:partition] - partitioned_by :partition, strategy: :sliding_list, + partitioned_by :partition, + strategy: :sliding_list, next_partition_if: proc { false }, detach_partition_if: proc { false } end @@ -221,7 +223,8 @@ RSpec.describe Gitlab::Database::Partitioning::SlidingListStrategy do def self.detach_partition_if_wrapper(...) detach_partition?(...) end - partitioned_by :partition, strategy: :sliding_list, + partitioned_by :partition, + strategy: :sliding_list, next_partition_if: method(:next_partition_if_wrapper), detach_partition_if: method(:detach_partition_if_wrapper) diff --git a/spec/lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table_spec.rb b/spec/lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table_spec.rb index 3072c413246..1885e84ac4c 100644 --- a/spec/lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table_spec.rb +++ b/spec/lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table_spec.rb @@ -97,7 +97,8 @@ RSpec.describe Gitlab::Database::PartitioningMigrationHelpers::BackfillPartition end it 'marks each job record as succeeded after processing' do - create(:background_migration_job, class_name: "::#{described_class.name}", + create(:background_migration_job, + class_name: "::#{described_class.name}", arguments: [source1.id, source3.id, source_table, destination_table, unique_key]) expect(::Gitlab::Database::BackgroundMigrationJob).to receive(:mark_all_as_succeeded).and_call_original @@ -108,7 +109,8 @@ RSpec.describe Gitlab::Database::PartitioningMigrationHelpers::BackfillPartition end it 'returns the number of job records marked as succeeded' do - create(:background_migration_job, class_name: "::#{described_class.name}", + create(:background_migration_job, + class_name: "::#{described_class.name}", arguments: [source1.id, source3.id, source_table, destination_table, unique_key]) jobs_updated = backfill_job.perform(source1.id, source3.id, source_table, destination_table, unique_key) diff --git a/spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb b/spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb index 6601b6658d5..ad91320c6eb 100644 --- a/spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb +++ b/spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb @@ -181,8 +181,8 @@ RSpec.describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService let(:existing_project) { create(:project, namespace: existing_group) } before do - application_setting.update!(instance_administrators_group_id: existing_group.id, - self_monitoring_project_id: existing_project.id) + application_setting.update!( + instance_administrators_group_id: existing_group.id, self_monitoring_project_id: existing_project.id) end it 'returns success' do diff --git a/spec/lib/gitlab/diff/highlight_cache_spec.rb b/spec/lib/gitlab/diff/highlight_cache_spec.rb index 68a2b17840c..53e74748234 100644 --- a/spec/lib/gitlab/diff/highlight_cache_spec.rb +++ b/spec/lib/gitlab/diff/highlight_cache_spec.rb @@ -9,33 +9,33 @@ RSpec.describe Gitlab::Diff::HighlightCache, :clean_gitlab_redis_cache do { ".gitignore-false-false-false" => [{ line_code: nil, rich_text: nil, text: "@@ -17,3 +17,4 @@ rerun.txt", type: "match", index: 0, old_pos: 17, new_pos: 17 }, { line_code: "a5cc2925ca8258af241be7e5b0381edf30266302_17_17", - rich_text: " <span id=\"LC17\" class=\"line\" lang=\"plaintext\">pickle-email-*.html</span>\n", - text: " pickle-email-*.html", - type: nil, - index: 1, - old_pos: 17, - new_pos: 17 }, + rich_text: " <span id=\"LC17\" class=\"line\" lang=\"plaintext\">pickle-email-*.html</span>\n", + text: " pickle-email-*.html", + type: nil, + index: 1, + old_pos: 17, + new_pos: 17 }, { line_code: "a5cc2925ca8258af241be7e5b0381edf30266302_18_18", - rich_text: " <span id=\"LC18\" class=\"line\" lang=\"plaintext\">.project</span>\n", - text: " .project", - type: nil, - index: 2, - old_pos: 18, - new_pos: 18 }, + rich_text: " <span id=\"LC18\" class=\"line\" lang=\"plaintext\">.project</span>\n", + text: " .project", + type: nil, + index: 2, + old_pos: 18, + new_pos: 18 }, { line_code: "a5cc2925ca8258af241be7e5b0381edf30266302_19_19", - rich_text: " <span id=\"LC19\" class=\"line\" lang=\"plaintext\">config/initializers/secret_token.rb</span>\n", - text: " config/initializers/secret_token.rb", - type: nil, - index: 3, - old_pos: 19, - new_pos: 19 }, + rich_text: " <span id=\"LC19\" class=\"line\" lang=\"plaintext\">config/initializers/secret_token.rb</span>\n", + text: " config/initializers/secret_token.rb", + type: nil, + index: 3, + old_pos: 19, + new_pos: 19 }, { line_code: "a5cc2925ca8258af241be7e5b0381edf30266302_20_20", - rich_text: "+<span id=\"LC20\" class=\"line\" lang=\"plaintext\">.DS_Store</span>", - text: "+.DS_Store", - type: "new", - index: 4, - old_pos: 20, - new_pos: 20 }] } + rich_text: "+<span id=\"LC20\" class=\"line\" lang=\"plaintext\">.DS_Store</span>", + text: "+.DS_Store", + type: "new", + index: 4, + old_pos: 20, + new_pos: 20 }] } end let(:cache_key) { cache.key } diff --git a/spec/lib/gitlab/diff/lines_unfolder_spec.rb b/spec/lib/gitlab/diff/lines_unfolder_spec.rb index f0e710be2e4..98f0c4df204 100644 --- a/spec/lib/gitlab/diff/lines_unfolder_spec.rb +++ b/spec/lib/gitlab/diff/lines_unfolder_spec.rb @@ -189,14 +189,14 @@ RSpec.describe Gitlab::Diff::LinesUnfolder do let(:diff) do Gitlab::Git::Diff.new({ diff: raw_diff, - new_path: "build-aux/flatpak/org.gnome.Nautilus.json", - old_path: "build-aux/flatpak/org.gnome.Nautilus.json", - a_mode: "100644", - b_mode: "100644", - new_file: false, - renamed_file: false, - deleted_file: false, - too_large: false }) + new_path: "build-aux/flatpak/org.gnome.Nautilus.json", + old_path: "build-aux/flatpak/org.gnome.Nautilus.json", + a_mode: "100644", + b_mode: "100644", + new_file: false, + renamed_file: false, + deleted_file: false, + too_large: false }) end let(:diff_file) do diff --git a/spec/lib/gitlab/diff/position_spec.rb b/spec/lib/gitlab/diff/position_spec.rb index bb3522eb579..00a468bfef6 100644 --- a/spec/lib/gitlab/diff/position_spec.rb +++ b/spec/lib/gitlab/diff/position_spec.rb @@ -684,7 +684,7 @@ RSpec.describe Gitlab::Diff::Position do "old_line" => 18, "new_line" => 18 }, - "end" => { + "end" => { "line_code" => end_line_code, "type" => nil, "old_line" => end_old_line, diff --git a/spec/lib/gitlab/error_tracking/processor/context_payload_processor_spec.rb b/spec/lib/gitlab/error_tracking/processor/context_payload_processor_spec.rb index 210829056c8..c9b632b50e1 100644 --- a/spec/lib/gitlab/error_tracking/processor/context_payload_processor_spec.rb +++ b/spec/lib/gitlab/error_tracking/processor/context_payload_processor_spec.rb @@ -38,10 +38,10 @@ RSpec.describe Gitlab::ErrorTracking::Processor::ContextPayloadProcessor do expect(result_hash[:tags]) .to include(priority: 'high', - locale: 'en', - program: 'test', - feature_category: 'feature_a', - correlation_id: 'cid') + locale: 'en', + program: 'test', + feature_category: 'feature_a', + correlation_id: 'cid') expect(result_hash[:extra]) .to include(some_info: 'info', diff --git a/spec/lib/gitlab/error_tracking/stack_trace_highlight_decorator_spec.rb b/spec/lib/gitlab/error_tracking/stack_trace_highlight_decorator_spec.rb index 577d59798da..3d23249d00d 100644 --- a/spec/lib/gitlab/error_tracking/stack_trace_highlight_decorator_spec.rb +++ b/spec/lib/gitlab/error_tracking/stack_trace_highlight_decorator_spec.rb @@ -52,7 +52,7 @@ RSpec.describe Gitlab::ErrorTracking::StackTraceHighlightDecorator do 'function' => 'print', 'lineNo' => 3, 'filename' => 'hello_world.php', - 'context' => [ + 'context' => [ [1, '<span id="LC1" class="line" lang="hack"><span class="c1">// PHP/Hack example</span></span>'], [2, '<span id="LC1" class="line" lang="hack"><span class="cp"><?php</span></span>'], [3, '<span id="LC1" class="line" lang="hack"><span class="k">echo</span> <span class="s1">\'Hello, World!\'</span><span class="p">;</span></span>'] diff --git a/spec/lib/gitlab/etag_caching/middleware_spec.rb b/spec/lib/gitlab/etag_caching/middleware_spec.rb index 8228f95dd5e..da5eaf2e4ab 100644 --- a/spec/lib/gitlab/etag_caching/middleware_spec.rb +++ b/spec/lib/gitlab/etag_caching/middleware_spec.rb @@ -119,11 +119,11 @@ RSpec.describe Gitlab::EtagCaching::Middleware, :clean_gitlab_redis_shared_state let(:expected_items) do { etag_route: endpoint, - params: {}, - format: :html, - method: 'GET', - path: enabled_path, - status: status_code + params: {}, + format: :html, + method: 'GET', + path: enabled_path, + status: status_code } end diff --git a/spec/lib/gitlab/etag_caching/router/graphql_spec.rb b/spec/lib/gitlab/etag_caching/router/graphql_spec.rb index 9a6787e3640..792f02f8cda 100644 --- a/spec/lib/gitlab/etag_caching/router/graphql_spec.rb +++ b/spec/lib/gitlab/etag_caching/router/graphql_spec.rb @@ -21,7 +21,7 @@ RSpec.describe Gitlab::EtagCaching::Router::Graphql do def match_route(path, header) described_class.match( double(path_info: path, - headers: { 'X-GITLAB-GRAPHQL-RESOURCE-ETAG' => header })) + headers: { 'X-GITLAB-GRAPHQL-RESOURCE-ETAG' => header })) end describe '.cache_key' do diff --git a/spec/lib/gitlab/grape_logging/formatters/lograge_with_timestamp_spec.rb b/spec/lib/gitlab/grape_logging/formatters/lograge_with_timestamp_spec.rb index 487b19a98e0..5006d27c356 100644 --- a/spec/lib/gitlab/grape_logging/formatters/lograge_with_timestamp_spec.rb +++ b/spec/lib/gitlab/grape_logging/formatters/lograge_with_timestamp_spec.rb @@ -6,7 +6,7 @@ RSpec.describe Gitlab::GrapeLogging::Formatters::LogrageWithTimestamp do let(:log_entry) do { status: 200, - time: { + time: { total: 758.58, db: 77.06, view: 681.52 diff --git a/spec/lib/gitlab/import_export/attributes_finder_spec.rb b/spec/lib/gitlab/import_export/attributes_finder_spec.rb index 428d8d605ee..6536b895b2f 100644 --- a/spec/lib/gitlab/import_export/attributes_finder_spec.rb +++ b/spec/lib/gitlab/import_export/attributes_finder_spec.rb @@ -123,7 +123,7 @@ RSpec.describe Gitlab::ImportExport::AttributesFinder do is_expected.to match( include: [{ merge_requests: { include: [{ notes: { include: [{ author: { include: [] } }], - preload: { author: nil } } }], + preload: { author: nil } } }], preload: { notes: { author: nil } } } }], preload: { merge_requests: { notes: { author: nil } } } @@ -132,7 +132,7 @@ RSpec.describe Gitlab::ImportExport::AttributesFinder do it 'generates the correct hash for a relation with included attributes' do setup_yaml(tree: { project: [:issues] }, - included_attributes: { issues: [:name, :description] }) + included_attributes: { issues: [:name, :description] }) is_expected.to match( include: [{ issues: { include: [], @@ -143,7 +143,7 @@ RSpec.describe Gitlab::ImportExport::AttributesFinder do it 'generates the correct hash for a relation with excluded attributes' do setup_yaml(tree: { project: [:issues] }, - excluded_attributes: { issues: [:name] }) + excluded_attributes: { issues: [:name] }) is_expected.to match( include: [{ issues: { except: [:name], @@ -154,8 +154,8 @@ RSpec.describe Gitlab::ImportExport::AttributesFinder do it 'generates the correct hash for a relation with both excluded and included attributes' do setup_yaml(tree: { project: [:issues] }, - excluded_attributes: { issues: [:name] }, - included_attributes: { issues: [:description] }) + excluded_attributes: { issues: [:name] }, + included_attributes: { issues: [:description] }) is_expected.to match( include: [{ issues: { except: [:name], @@ -167,7 +167,7 @@ RSpec.describe Gitlab::ImportExport::AttributesFinder do it 'generates the correct hash for a relation with custom methods' do setup_yaml(tree: { project: [:issues] }, - methods: { issues: [:name] }) + methods: { issues: [:name] }) is_expected.to match( include: [{ issues: { include: [], diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index eac8115742d..3a656c4a42d 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -1225,70 +1225,6 @@ RSpec.describe Ci::Build do end end - describe '#has_old_trace?' do - subject { build.has_old_trace? } - - context 'when old trace exists' do - before do - build.update_column(:trace, 'old trace') - end - - it { is_expected.to be_truthy } - end - - context 'when old trace does not exist' do - it { is_expected.to be_falsy } - end - end - - describe '#trace=' do - it "expect to fail trace=" do - expect { build.trace = "new" }.to raise_error(NotImplementedError) - end - end - - describe '#old_trace' do - subject { build.old_trace } - - before do - build.update_column(:trace, 'old trace') - end - - it "expect to receive data from database" do - is_expected.to eq('old trace') - end - end - - describe '#erase_old_trace!' do - subject { build.erase_old_trace! } - - context 'when old trace exists' do - before do - build.update_column(:trace, 'old trace') - end - - it "erases old trace" do - subject - - expect(build.old_trace).to be_nil - end - - it "executes UPDATE query" do - recorded = ActiveRecord::QueryRecorder.new { subject } - - expect(recorded.log.count { |l| l.match?(/UPDATE.*ci_builds/) }).to eq(1) - end - end - - context 'when old trace does not exist' do - it 'does not execute UPDATE query' do - recorded = ActiveRecord::QueryRecorder.new { subject } - - expect(recorded.log.count { |l| l.match?(/UPDATE.*ci_builds/) }).to eq(0) - end - end - end - describe '#hide_secrets' do let(:metrics) { spy('metrics') } let(:subject) { build.hide_secrets(data) } diff --git a/spec/models/ci/processable_spec.rb b/spec/models/ci/processable_spec.rb index 594f9b679ec..61e2864a518 100644 --- a/spec/models/ci/processable_spec.rb +++ b/spec/models/ci/processable_spec.rb @@ -55,8 +55,7 @@ RSpec.describe Ci::Processable do let(:clone_accessors) { ::Ci::Build.clone_accessors.without(::Ci::Build.extra_accessors) } let(:reject_accessors) do - %i[id status user token_encrypted coverage trace runner - artifacts_expire_at + %i[id status user token_encrypted coverage runner artifacts_expire_at created_at updated_at started_at finished_at queued_at erased_by erased_at auto_canceled_by job_artifacts job_artifacts_archive job_artifacts_metadata job_artifacts_trace job_artifacts_junit diff --git a/spec/requests/api/graphql/group/work_item_types_spec.rb b/spec/requests/api/graphql/group/work_item_types_spec.rb index a33e3ae5427..d6b0673e4f8 100644 --- a/spec/requests/api/graphql/group/work_item_types_spec.rb +++ b/spec/requests/api/graphql/group/work_item_types_spec.rb @@ -46,7 +46,7 @@ RSpec.describe 'getting a list of work item types for a group' do end end - context "when user doesn't have acces to the group" do + context "when user doesn't have access to the group" do let(:current_user) { create(:user) } before do diff --git a/spec/requests/api/personal_access_tokens/self_revocation_spec.rb b/spec/requests/api/personal_access_tokens/self_revocation_spec.rb new file mode 100644 index 00000000000..f829b39cc1e --- /dev/null +++ b/spec/requests/api/personal_access_tokens/self_revocation_spec.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe API::PersonalAccessTokens::SelfRevocation do + let_it_be(:current_user) { create(:user) } + + describe 'DELETE /personal_access_tokens/self' do + let(:path) { '/personal_access_tokens/self' } + let(:token) { create(:personal_access_token, user: current_user) } + + subject(:delete_token) { delete api(path, personal_access_token: token) } + + shared_examples 'revoking token succeeds' do + it 'revokes token' do + delete_token + + expect(response).to have_gitlab_http_status(:no_content) + expect(token.reload).to be_revoked + end + end + + shared_examples 'revoking token denied' do |status| + it 'cannot revoke token' do + delete_token + + expect(response).to have_gitlab_http_status(status) + end + end + + context 'when current_user is an administrator', :enable_admin_mode do + let(:current_user) { create(:admin) } + + it_behaves_like 'revoking token succeeds' + + context 'with impersonated token' do + let(:token) { create(:personal_access_token, :impersonation, user: current_user) } + + it_behaves_like 'revoking token succeeds' + end + end + + context 'when current_user is not an administrator' do + let(:current_user) { create(:user) } + + it_behaves_like 'revoking token succeeds' + + context 'with impersonated token' do + let(:token) { create(:personal_access_token, :impersonation, user: current_user) } + + it_behaves_like 'revoking token denied', :bad_request + end + + context 'with already revoked token' do + let(:token) { create(:personal_access_token, :revoked, user: current_user) } + + it_behaves_like 'revoking token denied', :unauthorized + end + end + + Gitlab::Auth.all_available_scopes.each do |scope| + context "with a '#{scope}' scoped token" do + let(:token) { create(:personal_access_token, scopes: [scope], user: current_user) } + + it_behaves_like 'revoking token succeeds' + end + end + end +end diff --git a/spec/requests/api/personal_access_tokens_spec.rb b/spec/requests/api/personal_access_tokens_spec.rb index 8d8998cfdd6..37b5a594f2a 100644 --- a/spec/requests/api/personal_access_tokens_spec.rb +++ b/spec/requests/api/personal_access_tokens_spec.rb @@ -75,6 +75,7 @@ RSpec.describe API::PersonalAccessTokens do describe 'GET /personal_access_tokens/:id' do let_it_be(:user_token) { create(:personal_access_token, user: current_user) } + let_it_be(:user_read_only_token) { create(:personal_access_token, scopes: ['read_repository'], user: current_user) } let_it_be(:user_token_path) { "/personal_access_tokens/#{user_token.id}" } let_it_be(:invalid_path) { "/personal_access_tokens/#{non_existing_record_id}" } @@ -125,53 +126,11 @@ RSpec.describe API::PersonalAccessTokens do expect(response).to have_gitlab_http_status(:unauthorized) end - end - end - - describe 'DELETE /personal_access_tokens/self' do - let(:path) { '/personal_access_tokens/self' } - let(:token) { create(:personal_access_token, user: current_user) } - - subject { delete api(path, current_user, personal_access_token: token) } - - shared_examples 'revoking token succeeds' do - it 'revokes token' do - subject - - expect(response).to have_gitlab_http_status(:no_content) - expect(token.reload).to be_revoked - end - end - shared_examples 'revoking token denied' do |status| - it 'cannot revoke token' do - subject + it 'fails to return own PAT by id with read_repository token' do + get api(user_token_path, current_user, personal_access_token: user_read_only_token) - expect(response).to have_gitlab_http_status(status) - end - end - - context 'when current_user is an administrator', :enable_admin_mode do - let(:current_user) { create(:admin) } - - it_behaves_like 'revoking token succeeds' - end - - context 'when current_user is not an administrator' do - let(:current_user) { create(:user) } - - it_behaves_like 'revoking token succeeds' - - context 'with impersonated token' do - let(:token) { create(:personal_access_token, :impersonation, user: current_user) } - - it_behaves_like 'revoking token denied', :bad_request - end - - context 'with already revoked token' do - let(:token) { create(:personal_access_token, :revoked, user: current_user) } - - it_behaves_like 'revoking token denied', :unauthorized + expect(response).to have_gitlab_http_status(:forbidden) end end end @@ -183,6 +142,9 @@ RSpec.describe API::PersonalAccessTokens do let_it_be(:admin_user) { create(:admin) } let_it_be(:admin_token) { create(:personal_access_token, user: admin_user) } let_it_be(:admin_path) { "/personal_access_tokens/#{admin_token.id}" } + let_it_be(:admin_read_only_token) do + create(:personal_access_token, scopes: ['read_repository'], user: admin_user) + end it 'revokes a different users token' do delete api(path, admin_user) @@ -196,6 +158,12 @@ RSpec.describe API::PersonalAccessTokens do expect(response).to have_gitlab_http_status(:no_content) end + + it 'fails to revoke a different user token using a readonly scope' do + delete api(path, personal_access_token: admin_read_only_token) + + expect(token1.reload.revoked?).to be false + end end context 'when current_user is not an administrator' do diff --git a/spec/services/ci/resource_groups/assign_resource_from_resource_group_service_spec.rb b/spec/services/ci/resource_groups/assign_resource_from_resource_group_service_spec.rb index 194203a422c..3d1abe290bc 100644 --- a/spec/services/ci/resource_groups/assign_resource_from_resource_group_service_spec.rb +++ b/spec/services/ci/resource_groups/assign_resource_from_resource_group_service_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe Ci::ResourceGroups::AssignResourceFromResourceGroupService do + include ConcurrentHelpers + let_it_be(:project) { create(:project) } let_it_be(:user) { create(:user) } @@ -134,6 +136,19 @@ RSpec.describe Ci::ResourceGroups::AssignResourceFromResourceGroupService do end end end + + context 'when parallel services are running' do + it 'can run the same command in parallel' do + parallel_num = 4 + + blocks = Array.new(parallel_num).map do + -> { subject } + end + + run_parallel(blocks) + expect(build.reload).to be_pending + end + end end context 'when there are no available resources' do diff --git a/spec/services/projects/destroy_service_spec.rb b/spec/services/projects/destroy_service_spec.rb index 94320320407..8269dbebccb 100644 --- a/spec/services/projects/destroy_service_spec.rb +++ b/spec/services/projects/destroy_service_spec.rb @@ -135,6 +135,33 @@ RSpec.describe Projects::DestroyService, :aggregate_failures, :event_store_publi end end + context 'deleting a project with merge request diffs' do + let!(:merge_request) { create(:merge_request, source_project: project) } + let!(:another_project_mr) { create(:merge_request, source_project: create(:project)) } + + it 'deletes merge request diffs' do + merge_request_diffs = merge_request.merge_request_diffs + expect(merge_request_diffs.size).to eq(1) + + expect { destroy_project(project, user, {}) }.to change(MergeRequestDiff, :count).by(-1) + expect { another_project_mr.reload }.not_to raise_error + end + + context 'when extract_mr_diff_deletions feature flag is disabled' do + before do + stub_feature_flags(extract_mr_diff_deletions: false) + end + + it 'also deletes merge request diffs' do + merge_request_diffs = merge_request.merge_request_diffs + expect(merge_request_diffs.size).to eq(1) + + expect { destroy_project(project, user, {}) }.to change(MergeRequestDiff, :count).by(-1) + expect { another_project_mr.reload }.not_to raise_error + end + end + end + it_behaves_like 'deleting the project' it 'invalidates personal_project_count cache' do diff --git a/spec/support/shared_examples/lib/gitlab/ci/ci_trace_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/ci/ci_trace_shared_examples.rb index c388a3a2c7f..10f58748698 100644 --- a/spec/support/shared_examples/lib/gitlab/ci/ci_trace_shared_examples.rb +++ b/spec/support/shared_examples/lib/gitlab/ci/ci_trace_shared_examples.rb @@ -370,15 +370,6 @@ RSpec.shared_examples 'trace with disabled live trace feature' do end end - shared_examples 'read successfully with StringIO' do - it 'yields with source' do - trace.read do |stream| - expect(stream).to be_a(Gitlab::Ci::Trace::Stream) - expect(stream.stream).to be_a(StringIO) - end - end - end - shared_examples 'failed to read' do it 'yields without source' do trace.read do |stream| @@ -404,14 +395,6 @@ RSpec.shared_examples 'trace with disabled live trace feature' do it_behaves_like 'read successfully with IO' end - context 'when db trace exists' do - before do - build.send(:write_attribute, :trace, "data") - end - - it_behaves_like 'read successfully with StringIO' - end - context 'when no sources exist' do it_behaves_like 'failed to read' end @@ -462,25 +445,6 @@ RSpec.shared_examples 'trace with disabled live trace feature' do expect(trace.exist?).to be(false) end end - - context 'stored in database' do - before do - build.send(:write_attribute, :trace, "data") - end - - it "trace exist" do - expect(trace.exist?).to be(true) - end - - it "can be erased" do - trace.erase! - expect(trace.exist?).to be(false) - end - - it "returns database data" do - expect(trace.raw).to eq("data") - end - end end describe '#archive!' do @@ -520,24 +484,12 @@ RSpec.shared_examples 'trace with disabled live trace feature' do expect(build.trace.exist?).to be_truthy expect(build.job_artifacts_trace.file.exists?).to be_truthy expect(build.job_artifacts_trace.file.filename).to eq('job.log') - expect(build.old_trace).to be_nil expect(src_checksum) .to eq(described_class.sha256_hexdigest(build.job_artifacts_trace.file.path)) expect(build.job_artifacts_trace.file_sha256).to eq(src_checksum) end end - shared_examples 'source trace in database stays intact' do |error:| - it do - expect { subject }.to raise_error(error) - - build.reload - expect(build.trace.exist?).to be_truthy - expect(build.job_artifacts_trace).to be_nil - expect(build.old_trace).to eq(trace_content) - end - end - context 'when job does not have trace artifact' do context 'when trace file stored in default path' do let!(:build) { create(:ci_build, :success, :trace_live) } @@ -564,58 +516,6 @@ RSpec.shared_examples 'trace with disabled live trace feature' do it_behaves_like 'source trace file stays intact', error: ActiveRecord::RecordInvalid end end - - context 'when trace is stored in database' do - let(:build) { create(:ci_build, :success) } - let(:trace_content) { 'Sample trace' } - let(:src_checksum) { Digest::SHA256.hexdigest(trace_content) } - - before do - build.update_column(:trace, trace_content) - end - - it_behaves_like 'archive trace in database' - - context 'when failed to create clone file' do - before do - allow(IO).to receive(:copy_stream).and_return(0) - end - - it_behaves_like 'source trace in database stays intact', error: Gitlab::Ci::Trace::ArchiveError - end - - context 'when failed to create job artifact record' do - before do - allow_any_instance_of(Ci::JobArtifact).to receive(:save).and_return(false) - allow_any_instance_of(Ci::JobArtifact).to receive_message_chain(:errors, :full_messages) - .and_return(%w[Error Error]) - end - - it_behaves_like 'source trace in database stays intact', error: ActiveRecord::RecordInvalid - end - - context 'when there is a validation error on Ci::Build' do - before do - allow_any_instance_of(Ci::Build).to receive(:save).and_return(false) - allow_any_instance_of(Ci::Build).to receive_message_chain(:errors, :full_messages) - .and_return(%w[Error Error]) - end - - context "when erase old trace with 'save'" do - before do - build.send(:write_attribute, :trace, nil) - build.save # rubocop:disable Rails/SaveBang - end - - it 'old trace is not deleted' do - build.reload - expect(build.trace.raw).to eq(trace_content) - end - end - - it_behaves_like 'archive trace in database' - end - end end context 'when job has trace artifact' do @@ -645,22 +545,6 @@ RSpec.shared_examples 'trace with disabled live trace feature' do subject { trace.erase! } context 'when it is a live trace' do - context 'when trace is stored in database' do - let(:build) { create(:ci_build) } - - before do - build.update_column(:trace, 'sample trace') - end - - it { expect(trace.raw).not_to be_nil } - - it "removes trace" do - subject - - expect(trace.raw).to be_nil - end - end - context 'when trace is stored in file storage' do let(:build) { create(:ci_build, :trace_live) } |