diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-07-21 15:10:03 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-07-21 15:10:03 +0300 |
commit | f44215bf40c974c5b20c06c4260eb48c8a6cc7c2 (patch) | |
tree | 3e1145dc1a52fad5cc2f0ef14a1107a15c00b07a /spec | |
parent | 265a7ceccadf01cf1c2983c54abf86de19f6c2ad (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
24 files changed, 296 insertions, 144 deletions
diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb index c46a12680a2..e9f0f0c2879 100644 --- a/spec/controllers/admin/users_controller_spec.rb +++ b/spec/controllers/admin/users_controller_spec.rb @@ -612,8 +612,8 @@ RSpec.describe Admin::UsersController do end context 'when the new password does not match the password confirmation' do - let(:password) { 'some_password' } - let(:password_confirmation) { 'not_same_as_password' } + let(:password) { User.random_password } + let(:password_confirmation) { User.random_password } it 'shows the edit page again' do update_password(user, password, password_confirmation) diff --git a/spec/controllers/import/bulk_imports_controller_spec.rb b/spec/controllers/import/bulk_imports_controller_spec.rb index 7177c8c10a6..3be12717664 100644 --- a/spec/controllers/import/bulk_imports_controller_spec.rb +++ b/spec/controllers/import/bulk_imports_controller_spec.rb @@ -245,11 +245,11 @@ RSpec.describe Import::BulkImportsController do let(:bulk_import_params) do [{ "source_type" => "group_entity", "source_full_path" => "full_path", - "destination_name" => "destination_name", + "destination_slug" => "destination_name", "destination_namespace" => "root" }, { "source_type" => "group_entity2", "source_full_path" => "full_path2", - "destination_name" => "destination_name2", + "destination_slug" => "destination_name2", "destination_namespace" => "root" }] end @@ -258,7 +258,7 @@ RSpec.describe Import::BulkImportsController do session[:bulk_import_gitlab_url] = instance_url end - it 'executes BulkImpors::CreateService' do + it 'executes BulkImports::CreateService' do error_response = ServiceResponse.error(message: 'Record invalid', http_status: :unprocessable_entity) expect_next_instance_of( @@ -276,6 +276,38 @@ RSpec.describe Import::BulkImportsController do expect(json_response).to eq([{ "success" => true, "id" => bulk_import.id, "message" => nil }, { "success" => false, "id" => nil, "message" => "Record invalid" }]) end + + context 'when entity destination_name is specified' do + let(:bulk_import_params) do + [ + { + "source_type" => "group_entity", + "source_full_path" => "full_path", + "destination_name" => "destination_name", + "destination_namespace" => "root" + } + ] + end + + it 'replaces destination_name with destination_slug and executes BulkImports::CreateService' do + entity = { + "source_type" => "group_entity", + "source_full_path" => "full_path", + "destination_slug" => "destination_name", + "destination_namespace" => "root" + } + + expect_next_instance_of( + ::BulkImports::CreateService, user, entity, { url: instance_url, access_token: pat }) do |service| + allow(service).to receive(:execute).and_return(ServiceResponse.success(payload: bulk_import)) + end + + post :create, params: { bulk_import: bulk_import_params } + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response).to match_array([{ "success" => true, "id" => bulk_import.id, "message" => nil }]) + end + end end end diff --git a/spec/controllers/profiles_controller_spec.rb b/spec/controllers/profiles_controller_spec.rb index 6e7cc058fbc..89185a8f856 100644 --- a/spec/controllers/profiles_controller_spec.rb +++ b/spec/controllers/profiles_controller_spec.rb @@ -3,16 +3,16 @@ require('spec_helper') RSpec.describe ProfilesController, :request_store do - let(:password) { 'longsecret987!' } + let(:password) { User.random_password } let(:user) { create(:user, password: password) } describe 'POST update' do it 'does not update password' do sign_in(user) - + new_password = User.random_password expect do post :update, - params: { user: { password: 'hello12345', password_confirmation: 'hello12345' } } + params: { user: { password: new_password, password_confirmation: new_password } } end.not_to change { user.reload.encrypted_password } expect(response).to have_gitlab_http_status(:found) diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb index f4cad5790a3..1a6edab795d 100644 --- a/spec/controllers/projects/environments_controller_spec.rb +++ b/spec/controllers/projects/environments_controller_spec.rb @@ -233,7 +233,7 @@ RSpec.describe Projects::EnvironmentsController do end context "when environment params are invalid" do - let(:params) { environment_params.merge(environment: { name: '/foo/', external_url: '/git.gitlab.com' }) } + let(:params) { environment_params.merge(environment: { external_url: 'javascript:alert("hello")' }) } it 'returns bad request' do subject diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb index c5a97812d1f..70d4559edc1 100644 --- a/spec/controllers/registrations_controller_spec.rb +++ b/spec/controllers/registrations_controller_spec.rb @@ -25,7 +25,7 @@ RSpec.describe RegistrationsController do end let_it_be(:base_user_params) do - { first_name: 'first', last_name: 'last', username: 'new_username', email: 'new@user.com', password: 'Any_password' } + { first_name: 'first', last_name: 'last', username: 'new_username', email: 'new@user.com', password: User.random_password } end let_it_be(:user_params) { { user: base_user_params } } @@ -222,7 +222,7 @@ RSpec.describe RegistrationsController do context 'when the registration fails' do let_it_be(:member) { create(:project_member, :invited) } let_it_be(:missing_user_params) do - { username: '', email: member.invite_email, password: 'Any_password' } + { username: '', email: member.invite_email, password: User.random_password } end let_it_be(:user_params) { { user: missing_user_params } } @@ -535,7 +535,7 @@ RSpec.describe RegistrationsController do end it 'succeeds if password is confirmed' do - post :destroy, params: { password: '12345678' } + post :destroy, params: { password: user.password } expect_success end @@ -576,7 +576,7 @@ RSpec.describe RegistrationsController do end it 'fails' do - delete :destroy, params: { password: '12345678' } + delete :destroy, params: { password: user.password } expect_failure(s_('Profiles|You must transfer ownership or delete groups you are an owner of before you can delete your account')) end diff --git a/spec/features/merge_request/user_posts_diff_notes_spec.rb b/spec/features/merge_request/user_posts_diff_notes_spec.rb index d461170c990..1eebb6c2e28 100644 --- a/spec/features/merge_request/user_posts_diff_notes_spec.rb +++ b/spec/features/merge_request/user_posts_diff_notes_spec.rb @@ -19,7 +19,6 @@ RSpec.describe 'Merge request > User posts diff notes', :js do project.add_developer(user) sign_in(user) - stub_const('Gitlab::QueryLimiting::Transaction::THRESHOLD', 104) end context 'when hovering over a parallel view diff file' do diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb index 3ba3650b608..08d0a8d556a 100644 --- a/spec/features/users/login_spec.rb +++ b/spec/features/users/login_spec.rb @@ -477,14 +477,14 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do end context 'with invalid username and password' do - let(:user) { create(:user, password: 'not-the-default') } + let(:user) { create(:user) } it 'blocks invalid login' do expect(authentication_metrics) .to increment(:user_unauthenticated_counter) .and increment(:user_password_invalid_counter) - gitlab_sign_in(user) + gitlab_sign_in(user, password: 'incorrect-password') expect_single_session_with_short_ttl expect(page).to have_content('Invalid login or password.') diff --git a/spec/frontend/vue_shared/components/source_viewer/plugins/link_dependencies_spec.js b/spec/frontend/vue_shared/components/source_viewer/plugins/link_dependencies_spec.js index 3036ce43888..375b1307616 100644 --- a/spec/frontend/vue_shared/components/source_viewer/plugins/link_dependencies_spec.js +++ b/spec/frontend/vue_shared/components/source_viewer/plugins/link_dependencies_spec.js @@ -1,8 +1,10 @@ import packageJsonLinker from '~/vue_shared/components/source_viewer/plugins/utils/package_json_linker'; +import gemspecLinker from '~/vue_shared/components/source_viewer/plugins/utils/gemspec_linker'; import linkDependencies from '~/vue_shared/components/source_viewer/plugins/link_dependencies'; -import { PACKAGE_JSON_FILE_TYPE, PACKAGE_JSON_CONTENT } from './mock_data'; +import { PACKAGE_JSON_FILE_TYPE, PACKAGE_JSON_CONTENT, GEMSPEC_FILE_TYPE } from './mock_data'; jest.mock('~/vue_shared/components/source_viewer/plugins/utils/package_json_linker'); +jest.mock('~/vue_shared/components/source_viewer/plugins/utils/gemspec_linker'); describe('Highlight.js plugin for linking dependencies', () => { const hljsResultMock = { value: 'test' }; @@ -11,4 +13,9 @@ describe('Highlight.js plugin for linking dependencies', () => { linkDependencies(hljsResultMock, PACKAGE_JSON_FILE_TYPE, PACKAGE_JSON_CONTENT); expect(packageJsonLinker).toHaveBeenCalled(); }); + + it('calls gemspecLinker for gemspec file types', () => { + linkDependencies(hljsResultMock, GEMSPEC_FILE_TYPE); + expect(gemspecLinker).toHaveBeenCalled(); + }); }); diff --git a/spec/frontend/vue_shared/components/source_viewer/plugins/mock_data.js b/spec/frontend/vue_shared/components/source_viewer/plugins/mock_data.js index 75659770e2c..aa874c9c081 100644 --- a/spec/frontend/vue_shared/components/source_viewer/plugins/mock_data.js +++ b/spec/frontend/vue_shared/components/source_viewer/plugins/mock_data.js @@ -1,2 +1,4 @@ export const PACKAGE_JSON_FILE_TYPE = 'package_json'; export const PACKAGE_JSON_CONTENT = '{ "dependencies": { "@babel/core": "^7.18.5" } }'; + +export const GEMSPEC_FILE_TYPE = 'gemspec'; diff --git a/spec/frontend/vue_shared/components/source_viewer/plugins/utils/gemspec_linker_spec.js b/spec/frontend/vue_shared/components/source_viewer/plugins/utils/gemspec_linker_spec.js new file mode 100644 index 00000000000..3f74bfa117f --- /dev/null +++ b/spec/frontend/vue_shared/components/source_viewer/plugins/utils/gemspec_linker_spec.js @@ -0,0 +1,14 @@ +import gemspecLinker from '~/vue_shared/components/source_viewer/plugins/utils/gemspec_linker'; + +describe('Highlight.js plugin for linking gemspec dependencies', () => { + it('mutates the input value by wrapping dependency names in anchors', () => { + const inputValue = + 's.add_dependency(<span class="hljs-string">'rugged'</span>, <span class="hljs-string">'~> 0.24.0'</span>)'; + const outputValue = + 's.add_dependency(<span class="hljs-string linked">'<a href="https://rubygems.org/gems/rugged" rel="nofollow noreferrer noopener">rugged</a>'</span>, <span class="hljs-string">'~> 0.24.0'</span>)'; + const hljsResultMock = { value: inputValue }; + + const output = gemspecLinker(hljsResultMock); + expect(output).toBe(outputValue); + }); +}); diff --git a/spec/frontend/work_items/mock_data.js b/spec/frontend/work_items/mock_data.js index df666b95ad1..a76407931d4 100644 --- a/spec/frontend/work_items/mock_data.js +++ b/spec/frontend/work_items/mock_data.js @@ -59,11 +59,9 @@ export const workItemQueryResponse = { title: 'Parent title', }, children: { - edges: [ + nodes: [ { - node: { - id: 'gid://gitlab/WorkItem/444', - }, + id: 'gid://gitlab/WorkItem/444', }, ], }, @@ -96,9 +94,9 @@ export const updateWorkItemMutationResponse = { widgets: [ { children: { - edges: [ + nodes: [ { - node: 'gid://gitlab/WorkItem/444', + id: 'gid://gitlab/WorkItem/444', }, ], }, @@ -161,11 +159,9 @@ export const workItemResponseFactory = ({ __typename: 'WorkItemWidgetHierarchy', type: 'HIERARCHY', children: { - edges: [ + nodes: [ { - node: { - id: 'gid://gitlab/WorkItem/444', - }, + id: 'gid://gitlab/WorkItem/444', }, ], }, diff --git a/spec/lib/api/entities/bulk_imports/entity_spec.rb b/spec/lib/api/entities/bulk_imports/entity_spec.rb index f91ae1fc5a1..4de85862ab9 100644 --- a/spec/lib/api/entities/bulk_imports/entity_spec.rb +++ b/spec/lib/api/entities/bulk_imports/entity_spec.rb @@ -14,6 +14,7 @@ RSpec.describe API::Entities::BulkImports::Entity do :status, :source_full_path, :destination_name, + :destination_slug, :destination_namespace, :parent_id, :namespace_id, diff --git a/spec/lib/bulk_imports/groups/transformers/group_attributes_transformer_spec.rb b/spec/lib/bulk_imports/groups/transformers/group_attributes_transformer_spec.rb index d775cf6b026..896af865c56 100644 --- a/spec/lib/bulk_imports/groups/transformers/group_attributes_transformer_spec.rb +++ b/spec/lib/bulk_imports/groups/transformers/group_attributes_transformer_spec.rb @@ -13,7 +13,7 @@ RSpec.describe BulkImports::Groups::Transformers::GroupAttributesTransformer do :bulk_import_entity, bulk_import: bulk_import, source_full_path: 'source/full/path', - destination_name: 'destination-name-path', + destination_slug: 'destination-slug-path', destination_namespace: parent.full_path ) end @@ -41,14 +41,14 @@ RSpec.describe BulkImports::Groups::Transformers::GroupAttributesTransformer do 'name' => 'Name', 'description' => 'Description', 'parent_id' => parent.id, - 'path' => 'destination-name-path' + 'path' => 'destination-slug-path' }) end - it 'transforms path from destination_name' do + it 'transforms path from destination_slug' do transformed_data = subject.transform(context, data) - expect(transformed_data['path']).to eq(entity.destination_name) + expect(transformed_data['path']).to eq(entity.destination_slug) end it 'removes full path' do diff --git a/spec/lib/bulk_imports/projects/transformers/project_attributes_transformer_spec.rb b/spec/lib/bulk_imports/projects/transformers/project_attributes_transformer_spec.rb index a1d77b9732d..c1c4d0bf0db 100644 --- a/spec/lib/bulk_imports/projects/transformers/project_attributes_transformer_spec.rb +++ b/spec/lib/bulk_imports/projects/transformers/project_attributes_transformer_spec.rb @@ -15,7 +15,7 @@ RSpec.describe BulkImports::Projects::Transformers::ProjectAttributesTransformer source_type: :project_entity, bulk_import: bulk_import, source_full_path: 'source/full/path', - destination_name: 'Destination Project Name', + destination_slug: 'Destination Project Name', destination_namespace: destination_group.full_path ) end @@ -32,12 +32,12 @@ RSpec.describe BulkImports::Projects::Transformers::ProjectAttributesTransformer subject(:transformed_data) { described_class.new.transform(context, data) } - it 'transforms name to destination name' do - expect(transformed_data[:name]).to eq(entity.destination_name) + it 'transforms name to destination slug' do + expect(transformed_data[:name]).to eq(entity.destination_slug) end it 'adds path as parameterized name' do - expect(transformed_data[:path]).to eq(entity.destination_name.parameterize) + expect(transformed_data[:path]).to eq(entity.destination_slug.parameterize) end it 'transforms visibility level' do @@ -65,7 +65,7 @@ RSpec.describe BulkImports::Projects::Transformers::ProjectAttributesTransformer source_type: :project_entity, bulk_import: bulk_import, source_full_path: 'source/full/path', - destination_name: 'Destination Project Name', + destination_slug: 'Destination Project Name', destination_namespace: '' ) diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb index e3207636bdc..fa03c6920c6 100644 --- a/spec/models/environment_spec.rb +++ b/spec/models/environment_spec.rb @@ -42,6 +42,92 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do end end + describe 'validate and sanitize external url' do + let_it_be_with_refind(:environment) { create(:environment) } + + where(:source_external_url, :expected_error_message) do + nil | nil + 'http://example.com' | nil + 'example.com' | nil + 'www.example.io' | nil + 'http://$URL' | nil + 'http://$(URL)' | nil + 'custom://example.com' | nil + '1.1.1.1' | nil + '$BASE_URL/${CI_COMMIT_REF_NAME}' | nil + '$ENVIRONMENT_URL' | nil + 'https://$SUB.$MAIN' | nil + 'https://$SUB-$REGION.$MAIN' | nil + 'https://example.com?param={()}' | nil + 'http://XSS?x=<script>alert(1)</script>' | nil + 'https://user:${VARIABLE}@example.io' | nil + 'https://example.com/test?param={data}' | nil + 'http://${URL}' | 'URI is invalid' + 'https://${URL}.example/test' | 'URI is invalid' + 'http://test${CI_MERGE_REQUEST_IID}.example.com' | 'URI is invalid' + 'javascript:alert("hello")' | 'javascript scheme is not allowed' + end + with_them do + it 'sets an external URL or an error' do + environment.external_url = source_external_url + + environment.valid? + + if expected_error_message + expect(environment.errors[:external_url].first).to eq(expected_error_message) + else + expect(environment.errors[:external_url]).to be_empty, + "There were unexpected errors: #{environment.errors.full_messages}" + expect(environment.external_url).to eq(source_external_url) + end + end + end + + context 'when soft_validation_on_external_url feature flag is disabled' do + before do + stub_feature_flags(soft_validation_on_external_url: false) + end + + where(:source_external_url, :expected_error_message) do + nil | nil + 'http://example.com' | nil + 'example.com' | 'is blocked: Only allowed schemes are http, https' + 'www.example.io' | 'is blocked: Only allowed schemes are http, https' + 'http://$URL' | 'is blocked: Hostname or IP address invalid' + 'http://$(URL)' | 'is blocked: Hostname or IP address invalid' + 'custom://example.com' | 'is blocked: Only allowed schemes are http, https' + '1.1.1.1' | 'is blocked: Only allowed schemes are http, https' + '$BASE_URL/${CI_COMMIT_REF_NAME}' | 'is blocked: Only allowed schemes are http, https' + '$ENVIRONMENT_URL' | 'is blocked: Only allowed schemes are http, https' + 'https://$SUB.$MAIN' | 'is blocked: Hostname or IP address invalid' + 'https://$SUB-$REGION.$MAIN' | 'is blocked: Hostname or IP address invalid' + 'https://example.com?param={()}' | nil + 'http://XSS?x=<script>alert(1)</script>' | nil + 'https://user:${VARIABLE}@example.io' | nil + 'https://example.com/test?param={data}' | nil + 'http://${URL}' | 'is blocked: URI is invalid' + 'https://${URL}.example/test' | 'is blocked: URI is invalid' + 'http://test${CI_MERGE_REQUEST_IID}.example.com' | 'is blocked: URI is invalid' + 'javascript:alert("hello")' | 'is blocked: Only allowed schemes are http, https' + end + with_them do + it 'sets an external URL or an error' do + environment.external_url = source_external_url + + environment.valid? + + if expected_error_message + expect(environment.errors[:external_url].first).to eq(expected_error_message) + else + expect(environment.errors[:external_url]).to be_empty, + "There were unexpected errors: #{environment.errors.full_messages}" + expect(environment.external_url).to eq(source_external_url) + end + end + end + end + end + describe '.before_save' do it 'ensures environment tier when a new object is created' do environment = build(:environment, name: 'gprd', tier: nil) diff --git a/spec/models/members/group_member_spec.rb b/spec/models/members/group_member_spec.rb index 94032146f51..c076346c619 100644 --- a/spec/models/members/group_member_spec.rb +++ b/spec/models/members/group_member_spec.rb @@ -165,13 +165,6 @@ RSpec.describe GroupMember do let_it_be(:project_b) { create(:project, group: group) } let_it_be(:project_c) { create(:project, group: group) } let_it_be(:user) { create(:user) } - let_it_be(:affected_project_ids) { Project.id_in([project_a, project_b, project_c]).ids } - - before do - stub_const( - "#{described_class.name}::THRESHOLD_FOR_REFRESHING_AUTHORIZATIONS_VIA_PROJECTS", - affected_project_ids.size - 1) - end shared_examples_for 'calls UserProjectAccessChangedService to recalculate authorizations' do it 'calls UserProjectAccessChangedService to recalculate authorizations' do @@ -183,41 +176,6 @@ RSpec.describe GroupMember do end end - shared_examples_for 'tries to update permissions via refreshing authorizations for the affected projects' do - context 'when the number of affected projects exceeds the set threshold' do - it 'updates permissions via refreshing authorizations for the affected projects asynchronously' do - expect_next_instance_of( - AuthorizedProjectUpdate::ProjectAccessChangedService, affected_project_ids - ) do |service| - expect(service).to receive(:execute).with(blocking: false) - end - - action - end - - it 'calls AuthorizedProjectUpdate::UserRefreshFromReplicaWorker with a delay as a safety net' do - expect(AuthorizedProjectUpdate::UserRefreshFromReplicaWorker).to( - receive(:bulk_perform_in) - .with(1.hour, - [[user.id]], - batch_delay: 30.seconds, batch_size: 100) - ) - - action - end - end - - context 'when the number of affected projects does not exceed the set threshold' do - before do - stub_const( - "#{described_class.name}::THRESHOLD_FOR_REFRESHING_AUTHORIZATIONS_VIA_PROJECTS", - affected_project_ids.size + 1) - end - - it_behaves_like 'calls UserProjectAccessChangedService to recalculate authorizations' - end - end - context 'on create' do let(:action) { group.add_member(user, Gitlab::Access::GUEST) } let(:blocking) { true } @@ -228,15 +186,7 @@ RSpec.describe GroupMember do .and change { user.can?(:guest_access, project_c) }.from(false).to(true) end - it_behaves_like 'tries to update permissions via refreshing authorizations for the affected projects' - - context 'when the feature flag `refresh_authorizations_via_affected_projects_on_group_membership` is disabled' do - before do - stub_feature_flags(refresh_authorizations_via_affected_projects_on_group_membership: false) - end - - it_behaves_like 'calls UserProjectAccessChangedService to recalculate authorizations' - end + it_behaves_like 'calls UserProjectAccessChangedService to recalculate authorizations' end context 'on update' do @@ -253,15 +203,7 @@ RSpec.describe GroupMember do .and change { user.can?(:developer_access, project_c) }.from(false).to(true) end - it_behaves_like 'tries to update permissions via refreshing authorizations for the affected projects' - - context 'when the feature flag `refresh_authorizations_via_affected_projects_on_group_membership` is disabled' do - before do - stub_feature_flags(refresh_authorizations_via_affected_projects_on_group_membership: false) - end - - it_behaves_like 'calls UserProjectAccessChangedService to recalculate authorizations' - end + it_behaves_like 'calls UserProjectAccessChangedService to recalculate authorizations' end context 'on destroy' do @@ -278,15 +220,7 @@ RSpec.describe GroupMember do .and change { user.can?(:guest_access, project_c) }.from(true).to(false) end - it_behaves_like 'tries to update permissions via refreshing authorizations for the affected projects' - - context 'when the feature flag `refresh_authorizations_via_affected_projects_on_group_membership` is disabled' do - before do - stub_feature_flags(refresh_authorizations_via_affected_projects_on_group_membership: false) - end - - it_behaves_like 'calls UserProjectAccessChangedService to recalculate authorizations' - end + it_behaves_like 'calls UserProjectAccessChangedService to recalculate authorizations' end end end diff --git a/spec/requests/api/boards_spec.rb b/spec/requests/api/boards_spec.rb index ca6492396cd..feb11f2ffef 100644 --- a/spec/requests/api/boards_spec.rb +++ b/spec/requests/api/boards_spec.rb @@ -57,9 +57,11 @@ RSpec.describe API::Boards do let(:url) { "/projects/#{board_parent.id}/boards/#{board.id}" } it 'delete the issue board' do - delete api(url, user) + expect do + delete api(url, user) - expect(response).to have_gitlab_http_status(:no_content) + expect(response).to have_gitlab_http_status(:no_content) + end.to change {board_parent.boards.count}.by(-1) end end diff --git a/spec/requests/api/bulk_imports_spec.rb b/spec/requests/api/bulk_imports_spec.rb index 9f9907f4f00..6a3d13567bd 100644 --- a/spec/requests/api/bulk_imports_spec.rb +++ b/spec/requests/api/bulk_imports_spec.rb @@ -53,23 +53,80 @@ RSpec.describe API::BulkImports do end end - it 'starts a new migration' do - post api('/bulk_imports', user), params: { - configuration: { - url: 'http://gitlab.example', - access_token: 'access_token' - }, - entities: [ - source_type: 'group_entity', - source_full_path: 'full_path', - destination_name: 'destination_slug', - destination_namespace: 'destination_namespace' - ] - } - - expect(response).to have_gitlab_http_status(:created) - - expect(json_response['status']).to eq('created') + shared_examples 'starting a new migration' do + it 'starts a new migration' do + post api('/bulk_imports', user), params: { + configuration: { + url: 'http://gitlab.example', + access_token: 'access_token' + }, + entities: [ + { + source_type: 'group_entity', + source_full_path: 'full_path', + destination_namespace: 'destination_namespace' + }.merge(destination_param) + ] + } + + expect(response).to have_gitlab_http_status(:created) + + expect(json_response['status']).to eq('created') + end + end + + include_examples 'starting a new migration' do + let(:destination_param) { { destination_slug: 'destination_slug' } } + end + + include_examples 'starting a new migration' do + let(:destination_param) { { destination_name: 'destination_name' } } + end + + context 'when both destination_name & destination_slug are provided' do + it 'returns a mutually exclusive error' do + post api('/bulk_imports', user), params: { + configuration: { + url: 'http://gitlab.example', + access_token: 'access_token' + }, + entities: [ + { + source_type: 'group_entity', + source_full_path: 'full_path', + destination_name: 'destination_name', + destination_slug: 'destination_slug', + destination_namespace: 'destination_namespace' + } + ] + } + + expect(response).to have_gitlab_http_status(:bad_request) + + expect(json_response['error']).to eq('entities[0][destination_slug], entities[0][destination_name] are mutually exclusive') + end + end + + context 'when neither destination_name nor destination_slug is provided' do + it 'returns at_least_one_of error' do + post api('/bulk_imports', user), params: { + configuration: { + url: 'http://gitlab.example', + access_token: 'access_token' + }, + entities: [ + { + source_type: 'group_entity', + source_full_path: 'full_path', + destination_namespace: 'destination_namespace' + } + ] + } + + expect(response).to have_gitlab_http_status(:bad_request) + + expect(json_response['error']).to eq('entities[0][destination_slug], entities[0][destination_name] are missing, at least one parameter must be provided') + end end context 'when provided url is blocked' do @@ -82,7 +139,7 @@ RSpec.describe API::BulkImports do entities: [ source_type: 'group_entity', source_full_path: 'full_path', - destination_name: 'destination_slug', + destination_slug: 'destination_slug', destination_namespace: 'destination_namespace' ] } diff --git a/spec/requests/api/graphql/ci/pipelines_spec.rb b/spec/requests/api/graphql/ci/pipelines_spec.rb index a968e5508cb..f471a152603 100644 --- a/spec/requests/api/graphql/ci/pipelines_spec.rb +++ b/spec/requests/api/graphql/ci/pipelines_spec.rb @@ -166,6 +166,35 @@ RSpec.describe 'Query.project(fullPath).pipelines' do end end + describe '.job' do + let(:first_n) { var('Int') } + let(:query_path) do + [ + [:project, { full_path: project.full_path }], + [:pipelines], + [:nodes], + [:job, { name: 'Job 1' }] + ] + end + + let(:query) do + wrap_fields(query_graphql_path(query_path, :status)) + end + + before_all do + pipeline = create(:ci_pipeline, project: project) + create(:ci_build, pipeline: pipeline, name: 'Job 1', status: :failed, retried: true) + create(:ci_build, pipeline: pipeline, name: 'Job 1', status: :success) + end + + it 'fetches the latest job with the given name' do + post_graphql(query, current_user: user) + expect(graphql_data_at(*query_path.map(&:first))).to contain_exactly a_hash_including( + 'status' => 'SUCCESS' + ) + end + end + describe '.jobs' do let(:first_n) { var('Int') } let(:query_path) do diff --git a/spec/requests/api/graphql/mutations/boards/destroy_spec.rb b/spec/requests/api/graphql/mutations/boards/destroy_spec.rb index 23e099e94b6..7620da3e7e0 100644 --- a/spec/requests/api/graphql/mutations/boards/destroy_spec.rb +++ b/spec/requests/api/graphql/mutations/boards/destroy_spec.rb @@ -65,15 +65,8 @@ RSpec.describe Mutations::Boards::Destroy do other_board.destroy! end - it 'does not destroy the board' do - expect { subject }.not_to change { Board.count }.from(1) - end - - it 'returns an error and not nil board' do - subject - - expect(mutation_response['errors']).not_to be_empty - expect(mutation_response['board']).not_to be_nil + it 'does destroy the board' do + expect { subject }.to change { Board.count }.by(-1) end end end diff --git a/spec/services/bulk_imports/create_service_spec.rb b/spec/services/bulk_imports/create_service_spec.rb index 67ec6fee1ae..4b655dd5d6d 100644 --- a/spec/services/bulk_imports/create_service_spec.rb +++ b/spec/services/bulk_imports/create_service_spec.rb @@ -10,19 +10,19 @@ RSpec.describe BulkImports::CreateService do { source_type: 'group_entity', source_full_path: 'full/path/to/group1', - destination_name: 'destination group 1', + destination_slug: 'destination group 1', destination_namespace: 'full/path/to/destination1' }, { source_type: 'group_entity', source_full_path: 'full/path/to/group2', - destination_name: 'destination group 2', + destination_slug: 'destination group 2', destination_namespace: 'full/path/to/destination2' }, { source_type: 'project_entity', source_full_path: 'full/path/to/project1', - destination_name: 'destination project 1', + destination_slug: 'destination project 1', destination_namespace: 'full/path/to/destination1' } ] diff --git a/spec/services/deployments/update_environment_service_spec.rb b/spec/services/deployments/update_environment_service_spec.rb index 8ab53a37a33..d3e5920baaf 100644 --- a/spec/services/deployments/update_environment_service_spec.rb +++ b/spec/services/deployments/update_environment_service_spec.rb @@ -112,7 +112,7 @@ RSpec.describe Deployments::UpdateEnvironmentService do end context 'when external URL is invalid' do - let(:external_url) { 'google.com' } + let(:external_url) { 'javascript:alert("hello")' } it 'fails to update the tier due to validation error' do expect { subject.execute }.not_to change { environment.tier } @@ -123,7 +123,7 @@ RSpec.describe Deployments::UpdateEnvironmentService do .with(an_instance_of(described_class::EnvironmentUpdateFailure), project_id: project.id, environment_id: environment.id, - reason: %q{External url is blocked: Only allowed schemes are http, https}) + reason: %q{External url javascript scheme is not allowed}) .once subject.execute diff --git a/spec/support/helpers/login_helpers.rb b/spec/support/helpers/login_helpers.rb index c93ef8b0ead..f83f5c7bfde 100644 --- a/spec/support/helpers/login_helpers.rb +++ b/spec/support/helpers/login_helpers.rb @@ -91,12 +91,12 @@ module LoginHelpers # user - User instance to login with # remember - Whether or not to check "Remember me" (default: false) # two_factor_auth - If two-factor authentication is enabled (default: false) - # password - password to attempt to login with + # password - password to attempt to login with (default: user.password) def gitlab_sign_in_with(user, remember: false, two_factor_auth: false, password: nil) visit new_user_session_path fill_in "user_login", with: user.email - fill_in "user_password", with: (password || "12345678") + fill_in "user_password", with: (password || user.password) check 'user_remember_me' if remember find('[data-testid="sign-in-button"]:enabled').click diff --git a/spec/support/shared_examples/boards/destroy_service_shared_examples.rb b/spec/support/shared_examples/boards/destroy_service_shared_examples.rb index 33bae3da44b..b1cb58a736f 100644 --- a/spec/support/shared_examples/boards/destroy_service_shared_examples.rb +++ b/spec/support/shared_examples/boards/destroy_service_shared_examples.rb @@ -20,10 +20,10 @@ RSpec.shared_examples 'board destroy service' do end context 'when there is only one board' do - it 'does not remove board' do + it 'does remove board' do expect do - expect(service.execute(board)).to be_error - end.not_to change(boards, :count) + service.execute(board) + end.to change(boards, :count).by(-1) end end end |