From 3caf5a8a007d8d9e9a86b7c847b5d9cfa6d41843 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Mon, 15 Jun 2020 18:08:43 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- .../experience_levels_controller_spec.rb | 32 +++++++++++ spec/features/admin/admin_groups_spec.rb | 2 +- spec/features/dashboard/projects_spec.rb | 2 +- .../components/alert_management_list_spec.js | 4 +- .../components/error_details_spec.js | 3 + .../resolvers/project_pipeline_resolver_spec.rb | 36 ++++++++++++ spec/lib/gitlab/cache/import/caching_spec.rb | 15 ++++- .../gitlab/ci/pipeline/seed/build/cache_spec.rb | 2 +- spec/lib/gitlab/jira_import_spec.rb | 25 +++++++- spec/lib/gitlab/utils_spec.rb | 13 +++++ spec/models/ci/pipeline_spec.rb | 11 ++++ spec/requests/api/deploy_keys_spec.rb | 54 ++++++++++++++++- spec/requests/api/graphql/project/pipeline_spec.rb | 32 +++++++++++ spec/requests/api/internal/base_spec.rb | 28 +++++++-- spec/requests/api/users_spec.rb | 67 ++++++++++++++++++++++ spec/services/prometheus/proxy_service_spec.rb | 39 +++++++++++++ 16 files changed, 352 insertions(+), 13 deletions(-) create mode 100644 spec/graphql/resolvers/project_pipeline_resolver_spec.rb create mode 100644 spec/requests/api/graphql/project/pipeline_spec.rb (limited to 'spec') diff --git a/spec/controllers/registrations/experience_levels_controller_spec.rb b/spec/controllers/registrations/experience_levels_controller_spec.rb index e67195cb932..1fc728f5de8 100644 --- a/spec/controllers/registrations/experience_levels_controller_spec.rb +++ b/spec/controllers/registrations/experience_levels_controller_spec.rb @@ -97,6 +97,38 @@ describe Registrations::ExperienceLevelsController do it { is_expected.to have_gitlab_http_status(:redirect) } it { is_expected.to redirect_to(root_path) } end + + describe 'applying the chosen level' do + context "when an 'onboarding_issues_settings' cookie does not exist" do + let(:params) { super().merge(experience_level: :novice) } + + it 'does not change the cookie' do + expect { subject }.not_to change { cookies[:onboarding_issues_settings] } + end + end + + context "when an 'onboarding_issues_settings' cookie does exist" do + before do + request.cookies[:onboarding_issues_settings] = '{}' + end + + context 'when novice' do + let(:params) { super().merge(experience_level: :novice) } + + it "adds a 'hideAdvanced' setting to the cookie" do + expect { subject }.to change { Gitlab::Json.parse(cookies[:onboarding_issues_settings])['hideAdvanced'] }.from(nil).to(true) + end + end + + context 'when experienced' do + let(:params) { super().merge(experience_level: :experienced) } + + it 'does not change the cookie' do + expect { subject }.not_to change { cookies[:onboarding_issues_settings] } + end + end + end + end end context 'when user update fails' do diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb index 5b6c1e15917..9cd335ffb8c 100644 --- a/spec/features/admin/admin_groups_spec.rb +++ b/spec/features/admin/admin_groups_spec.rb @@ -181,7 +181,7 @@ RSpec.describe 'Admin Groups' do end end - describe 'admin remove himself from a group', :js do + describe 'admin remove themself from a group', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/222342' do it 'removes admin from the group' do group.add_user(current_user, Gitlab::Access::DEVELOPER) diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb index 218cbf871a9..5201d56cc44 100644 --- a/spec/features/dashboard/projects_spec.rb +++ b/spec/features/dashboard/projects_spec.rb @@ -125,7 +125,7 @@ describe 'Dashboard Projects' do end context 'when on Starred projects tab', :js do - it 'shows the empty state when there are no starred projects' do + it 'shows the empty state when there are no starred projects', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/222357' do visit(starred_dashboard_projects_path) element = page.find('.row.empty-state') diff --git a/spec/frontend/alert_management/components/alert_management_list_spec.js b/spec/frontend/alert_management/components/alert_management_list_spec.js index 39099f25150..0154e5fa112 100644 --- a/spec/frontend/alert_management/components/alert_management_list_spec.js +++ b/spec/frontend/alert_management/components/alert_management_list_spec.js @@ -344,11 +344,11 @@ describe('AlertManagementList', () => { it('updates sort with new direction and column key', () => { findSeverityColumnHeader().trigger('click'); - expect(wrapper.vm.$data.sort).toBe('SEVERITY_ASC'); + expect(wrapper.vm.$data.sort).toBe('SEVERITY_DESC'); findSeverityColumnHeader().trigger('click'); - expect(wrapper.vm.$data.sort).toBe('SEVERITY_DESC'); + expect(wrapper.vm.$data.sort).toBe('SEVERITY_ASC'); }); }); diff --git a/spec/frontend/error_tracking/components/error_details_spec.js b/spec/frontend/error_tracking/components/error_details_spec.js index 9d926ca3998..fd2164d05fc 100644 --- a/spec/frontend/error_tracking/components/error_details_spec.js +++ b/spec/frontend/error_tracking/components/error_details_spec.js @@ -183,6 +183,9 @@ describe('ErrorDetails', () => { count: 12, userCount: 2, }, + stacktraceData: { + date_received: '2020-05-20', + }, }); }); diff --git a/spec/graphql/resolvers/project_pipeline_resolver_spec.rb b/spec/graphql/resolvers/project_pipeline_resolver_spec.rb new file mode 100644 index 00000000000..72049f16d7d --- /dev/null +++ b/spec/graphql/resolvers/project_pipeline_resolver_spec.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Resolvers::ProjectPipelineResolver do + include GraphqlHelpers + + let_it_be(:project) { create(:project) } + let_it_be(:pipeline) { create(:ci_pipeline, project: project, iid: '1234') } + let_it_be(:other_pipeline) { create(:ci_pipeline) } + let(:current_user) { create(:user) } + + def resolve_pipeline(project, args) + resolve(described_class, obj: project, args: args, ctx: { current_user: current_user }) + end + + it 'resolves pipeline for the passed iid' do + result = batch_sync do + resolve_pipeline(project, { iid: '1234' }) + end + + expect(result).to eq(pipeline) + end + + it 'does not resolve a pipeline outside the project' do + result = batch_sync do + resolve_pipeline(other_pipeline.project, { iid: '1234' }) + end + + expect(result).to be_nil + end + + it 'errors when no iid is passed' do + expect { resolve_pipeline(project, {}) }.to raise_error(ArgumentError) + end +end diff --git a/spec/lib/gitlab/cache/import/caching_spec.rb b/spec/lib/gitlab/cache/import/caching_spec.rb index e4aec0f4dec..7b4308d32ae 100644 --- a/spec/lib/gitlab/cache/import/caching_spec.rb +++ b/spec/lib/gitlab/cache/import/caching_spec.rb @@ -89,7 +89,7 @@ describe Gitlab::Cache::Import::Caching, :clean_gitlab_redis_cache do end describe '.write_multiple' do - it 'sets multiple keys' do + it 'sets multiple keys when key_prefix not set' do mapping = { 'foo' => 10, 'bar' => 20 } described_class.write_multiple(mapping) @@ -101,6 +101,19 @@ describe Gitlab::Cache::Import::Caching, :clean_gitlab_redis_cache do expect(found).to eq(value.to_s) end end + + it 'sets multiple keys with correct prefix' do + mapping = { 'foo' => 10, 'bar' => 20 } + + described_class.write_multiple(mapping, key_prefix: 'pref/') + + mapping.each do |key, value| + full_key = described_class.cache_key_for("pref/#{key}") + found = Gitlab::Redis::Cache.with { |r| r.get(full_key) } + + expect(found).to eq(value.to_s) + end + end end describe '.expire' do diff --git a/spec/lib/gitlab/ci/pipeline/seed/build/cache_spec.rb b/spec/lib/gitlab/ci/pipeline/seed/build/cache_spec.rb index fe19244659f..f5b43b5aeab 100644 --- a/spec/lib/gitlab/ci/pipeline/seed/build/cache_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/seed/build/cache_spec.rb @@ -134,7 +134,7 @@ describe Gitlab::Ci::Pipeline::Seed::Build::Cache do it_behaves_like 'foo/bar directory key' end - context 'with directories ending in slash star' do + context 'with directories ending in slash star', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/222356' do let(:files) { ['foo/bar/*'] } it_behaves_like 'foo/bar directory key' diff --git a/spec/lib/gitlab/jira_import_spec.rb b/spec/lib/gitlab/jira_import_spec.rb index 6f3c8bd6ecf..5b95891c97e 100644 --- a/spec/lib/gitlab/jira_import_spec.rb +++ b/spec/lib/gitlab/jira_import_spec.rb @@ -107,7 +107,7 @@ describe Gitlab::JiraImport do describe '.jira_issue_cache_key' do it 'returns cache key for Jira issue imported to given project' do - expect(described_class.jira_issue_cache_key(project_id, 'DEMO-123')).to eq("jira-import/items-mapper/#{project_id}/issues/DEMO-123") + expect(described_class.jira_item_cache_key(project_id, 'DEMO-123', :issues)).to eq("jira-import/items-mapper/#{project_id}/issues/DEMO-123") end end @@ -144,6 +144,29 @@ describe Gitlab::JiraImport do end end + describe '.cache_users_mapping', :clean_gitlab_redis_cache do + let(:data) { { 'user1' => '456', 'user234' => '23' } } + + it 'stores the data correctly' do + described_class.cache_users_mapping(project_id, data) + + expect(Gitlab::Cache::Import::Caching.read("jira-import/items-mapper/#{project_id}/users/user1")).to eq('456') + expect(Gitlab::Cache::Import::Caching.read("jira-import/items-mapper/#{project_id}/users/user234")).to eq('23') + end + end + + describe '.get_user_mapping', :clean_gitlab_redis_cache do + it 'reads the data correctly' do + Gitlab::Cache::Import::Caching.write("jira-import/items-mapper/#{project_id}/users/user-123", '456') + + expect(described_class.get_user_mapping(project_id, 'user-123')).to eq(456) + end + + it 'returns nil if value not found' do + expect(described_class.get_user_mapping(project_id, 'user-123')).to be_nil + end + end + describe '.store_issues_next_started_at', :clean_gitlab_redis_cache do it 'stores nil value' do described_class.store_issues_next_started_at(project_id, nil) diff --git a/spec/lib/gitlab/utils_spec.rb b/spec/lib/gitlab/utils_spec.rb index 0f0d6a93c97..3a2430d1f2d 100644 --- a/spec/lib/gitlab/utils_spec.rb +++ b/spec/lib/gitlab/utils_spec.rb @@ -345,4 +345,17 @@ describe Gitlab::Utils do expect(described_class.parse_url(1)).to be nil end end + + describe 'multiple_key_invert' do + it 'invert keys with array values' do + hash = { + dast: [:vulnerabilities_count, :scanned_resources_count], + sast: [:vulnerabilities_count] + } + expect(described_class.multiple_key_invert(hash)).to eq({ + vulnerabilities_count: [:dast, :sast], + scanned_resources_count: [:dast] + }) + end + end end diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 650f33b4e33..409affec5a7 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -121,6 +121,17 @@ describe Ci::Pipeline, :mailer do end end + describe '.for_iid' do + subject { described_class.for_iid(iid) } + + let(:iid) { '1234' } + let!(:pipeline) { create(:ci_pipeline, iid: '1234') } + + it 'returns the pipeline' do + is_expected.to contain_exactly(pipeline) + end + end + describe '.for_sha' do subject { described_class.for_sha(sha) } diff --git a/spec/requests/api/deploy_keys_spec.rb b/spec/requests/api/deploy_keys_spec.rb index e8cc6bc71ae..1baa18b53ce 100644 --- a/spec/requests/api/deploy_keys_spec.rb +++ b/spec/requests/api/deploy_keys_spec.rb @@ -8,7 +8,7 @@ describe API::DeployKeys do let(:admin) { create(:admin) } let(:project) { create(:project, creator_id: user.id) } let(:project2) { create(:project, creator_id: user.id) } - let(:deploy_key) { create(:deploy_key, public: true) } + let(:deploy_key) { create(:deploy_key, public: true, user: user) } let!(:deploy_keys_project) do create(:deploy_keys_project, project: project, deploy_key: deploy_key) @@ -40,6 +40,32 @@ describe API::DeployKeys do expect(json_response).to be_an Array expect(json_response.first['id']).to eq(deploy_keys_project.deploy_key.id) end + + it 'returns all deploy keys with comments replaced with'\ + 'a simple identifier of username + hostname' do + get api('/deploy_keys', admin) + + expect(response).to have_gitlab_http_status(:ok) + expect(response).to include_pagination_headers + expect(json_response).to be_an Array + + keys = json_response.map { |key_detail| key_detail['key'] } + expect(keys).to all(include("#{user.name} (#{Gitlab.config.gitlab.host}")) + end + + context 'N+1 queries' do + before do + get api('/deploy_keys', admin) + end + + it 'avoids N+1 queries', :request_store do + control_count = ActiveRecord::QueryRecorder.new { get api('/deploy_keys', admin) }.count + + create_list(:deploy_key, 2, public: true, user: create(:user)) + + expect { get api('/deploy_keys', admin) }.not_to exceed_query_limit(control_count) + end + end end end @@ -56,6 +82,25 @@ describe API::DeployKeys do expect(json_response).to be_an Array expect(json_response.first['title']).to eq(deploy_key.title) end + + context 'N+1 queries' do + before do + get api("/projects/#{project.id}/deploy_keys", admin) + end + + it 'avoids N+1 queries', :request_store do + control_count = ActiveRecord::QueryRecorder.new do + get api("/projects/#{project.id}/deploy_keys", admin) + end.count + + deploy_key = create(:deploy_key, user: create(:user)) + create(:deploy_keys_project, project: project, deploy_key: deploy_key) + + expect do + get api("/projects/#{project.id}/deploy_keys", admin) + end.not_to exceed_query_limit(control_count) + end + end end describe 'GET /projects/:id/deploy_keys/:key_id' do @@ -66,6 +111,13 @@ describe API::DeployKeys do expect(json_response['title']).to eq(deploy_key.title) end + it 'exposes key comment as a simple identifier of username + hostname' do + get api("/projects/#{project.id}/deploy_keys/#{deploy_key.id}", admin) + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response['key']).to include("#{deploy_key.user_name} (#{Gitlab.config.gitlab.host})") + end + it 'returns 404 Not Found with invalid ID' do get api("/projects/#{project.id}/deploy_keys/404", admin) diff --git a/spec/requests/api/graphql/project/pipeline_spec.rb b/spec/requests/api/graphql/project/pipeline_spec.rb new file mode 100644 index 00000000000..bed9a18577f --- /dev/null +++ b/spec/requests/api/graphql/project/pipeline_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'getting pipeline information nested in a project' do + include GraphqlHelpers + + let(:project) { create(:project, :repository, :public) } + let(:pipeline) { create(:ci_pipeline, project: project) } + let(:current_user) { create(:user) } + let(:pipeline_graphql_data) { graphql_data['project']['pipeline'] } + + let(:query) do + graphql_query_for( + 'project', + { 'fullPath' => project.full_path }, + query_graphql_field('pipeline', iid: pipeline.iid.to_s) + ) + end + + it_behaves_like 'a working graphql query' do + before do + post_graphql(query, current_user: current_user) + end + end + + it 'contains pipeline information' do + post_graphql(query, current_user: current_user) + + expect(pipeline_graphql_data).not_to be_nil + end +end diff --git a/spec/requests/api/internal/base_spec.rb b/spec/requests/api/internal/base_spec.rb index 403984d02f2..aa5e2367a2b 100644 --- a/spec/requests/api/internal/base_spec.rb +++ b/spec/requests/api/internal/base_spec.rb @@ -218,7 +218,15 @@ describe API::Internal::Base do get(api('/internal/authorized_keys'), params: { fingerprint: key.fingerprint, secret_token: secret_token }) expect(response).to have_gitlab_http_status(:ok) - expect(json_response["key"]).to eq(key.key) + expect(json_response['id']).to eq(key.id) + expect(json_response['key'].split[1]).to eq(key.key.split[1]) + end + + it 'exposes the comment of the key as a simple identifier of username + hostname' do + get(api('/internal/authorized_keys'), params: { fingerprint: key.fingerprint, secret_token: secret_token }) + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response['key']).to include("#{key.user_name} (#{Gitlab.config.gitlab.host})") end end @@ -239,11 +247,21 @@ describe API::Internal::Base do end context "sending the key" do - it "finds the key" do - get(api('/internal/authorized_keys'), params: { key: key.key.split[1], secret_token: secret_token }) + context "using an existing key" do + it "finds the key" do + get(api('/internal/authorized_keys'), params: { key: key.key.split[1], secret_token: secret_token }) - expect(response).to have_gitlab_http_status(:ok) - expect(json_response["key"]).to eq(key.key) + expect(response).to have_gitlab_http_status(:ok) + expect(json_response['id']).to eq(key.id) + expect(json_response['key'].split[1]).to eq(key.key.split[1]) + end + + it 'exposes the comment of the key as a simple identifier of username + hostname' do + get(api('/internal/authorized_keys'), params: { fingerprint: key.fingerprint, secret_token: secret_token }) + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response['key']).to include("#{key.user_name} (#{Gitlab.config.gitlab.host})") + end end it "returns 404 with a partial key" do diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index 7c0b6ac2e45..e780f67bcab 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -1276,6 +1276,36 @@ describe API::Users, :do_not_mock_admin_mode do expect(json_response).to be_an Array expect(json_response.first['title']).to eq(key.title) end + + it 'returns array of ssh keys with comments replaced with'\ + 'a simple identifier of username + hostname' do + get api("/users/#{user.id}/keys") + + expect(response).to have_gitlab_http_status(:ok) + expect(response).to include_pagination_headers + expect(json_response).to be_an Array + + keys = json_response.map { |key_detail| key_detail['key'] } + expect(keys).to all(include("#{user.name} (#{Gitlab.config.gitlab.host}")) + end + + context 'N+1 queries' do + before do + get api("/users/#{user.id}/keys") + end + + it 'avoids N+1 queries', :request_store do + control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do + get api("/users/#{user.id}/keys") + end.count + + create_list(:key, 2, user: user) + + expect do + get api("/users/#{user.id}/keys") + end.not_to exceed_all_query_limit(control_count) + end + end end describe 'GET /user/:user_id/keys' do @@ -1751,6 +1781,36 @@ describe API::Users, :do_not_mock_admin_mode do expect(json_response.first["title"]).to eq(key.title) end + it 'returns array of ssh keys with comments replaced with'\ + 'a simple identifier of username + hostname' do + get api("/user/keys", user) + + expect(response).to have_gitlab_http_status(:ok) + expect(response).to include_pagination_headers + expect(json_response).to be_an Array + + keys = json_response.map { |key_detail| key_detail['key'] } + expect(keys).to all(include("#{user.name} (#{Gitlab.config.gitlab.host}")) + end + + context 'N+1 queries' do + before do + get api("/user/keys", user) + end + + it 'avoids N+1 queries', :request_store do + control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do + get api("/user/keys", user) + end.count + + create_list(:key, 2, user: user) + + expect do + get api("/user/keys", user) + end.not_to exceed_all_query_limit(control_count) + end + end + context "scopes" do let(:path) { "/user/keys" } let(:api_call) { method(:api) } @@ -1769,6 +1829,13 @@ describe API::Users, :do_not_mock_admin_mode do expect(json_response["title"]).to eq(key.title) end + it 'exposes SSH key comment as a simple identifier of username + hostname' do + get api("/user/keys/#{key.id}", user) + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response['key']).to include("#{key.user_name} (#{Gitlab.config.gitlab.host})") + end + it "returns 404 Not Found within invalid ID" do get api("/user/keys/#{non_existing_record_id}", user) diff --git a/spec/services/prometheus/proxy_service_spec.rb b/spec/services/prometheus/proxy_service_spec.rb index 656ccea10de..bd451ff00a1 100644 --- a/spec/services/prometheus/proxy_service_spec.rb +++ b/spec/services/prometheus/proxy_service_spec.rb @@ -41,6 +41,27 @@ describe Prometheus::ProxyService do expect(result.params).to eq('query' => '1') end end + + context 'with series method' do + let(:params) do + ActionController::Parameters.new( + match: ['1'], + start: "2020-06-11T10:15:51Z", + end: "2020-06-11T11:16:06Z", + unknown_param: 'val' + ).permit! + end + + it 'allows match, start and end parameters' do + result = described_class.new(environment, 'GET', 'series', params) + + expect(result.params).to eq( + 'match' => ['1'], + 'start' => "2020-06-11T10:15:51Z", + 'end' => "2020-06-11T11:16:06Z" + ) + end + end end describe '#execute' do @@ -182,6 +203,24 @@ describe Prometheus::ProxyService do end end end + + context 'with series API' do + let(:rest_client_response) { instance_double(RestClient::Response, code: 200, body: '') } + + let(:params) do + ActionController::Parameters.new(match: ['1'], start: 1.hour.ago.rfc3339, end: Time.current.rfc3339).permit! + end + + subject { described_class.new(environment, 'GET', 'series', params) } + + it 'calls PrometheusClient with given parameters' do + expect(prometheus_client).to receive(:proxy) + .with('series', params.to_h) + .and_return(rest_client_response) + + subject.execute + end + end end end -- cgit v1.2.1