Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-06-11 00:10:02 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-06-11 00:10:02 +0300
commitb20c558db21c0ba8f033217bd6bc2b470716a105 (patch)
tree3c6cc717ae6074e581d76161fdcbf13b00612ecf /spec
parentd715acda3b27b7ca9eacbd058d7cb9629638c52d (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/factories/ci/job_token/project_scope_links.rb9
-rw-r--r--spec/factories_spec.rb1
-rw-r--r--spec/features/admin/clusters/applications_spec.rb22
-rw-r--r--spec/features/calendar_spec.rb13
-rw-r--r--spec/features/clusters/cluster_detail_page_spec.rb24
-rw-r--r--spec/features/clusters/cluster_health_dashboard_spec.rb8
-rw-r--r--spec/features/clusters/installing_applications_shared_examples.rb252
-rw-r--r--spec/features/groups/clusters/applications_spec.rb23
-rw-r--r--spec/features/projects/clusters/applications_spec.rb23
-rw-r--r--spec/finders/ci/auth_job_finder_spec.rb30
-rw-r--r--spec/frontend/clusters/forms/components/integration_form_spec.js13
-rw-r--r--spec/frontend/pages/users/activity_calendar_spec.js16
-rw-r--r--spec/lib/gitlab/auth/auth_finders_spec.rb8
-rw-r--r--spec/models/ci/job_token/project_scope_link_spec.rb68
-rw-r--r--spec/models/ci/job_token/scope_spec.rb55
-rw-r--r--spec/models/hooks/web_hook_log_archived_spec.rb52
-rw-r--r--spec/policies/project_policy_spec.rb49
-rw-r--r--spec/requests/api/generic_packages_spec.rb2
-rw-r--r--spec/requests/api/go_proxy_spec.rb2
-rw-r--r--spec/requests/api/maven_packages_spec.rb2
-rw-r--r--spec/requests/api/npm_project_packages_spec.rb2
-rw-r--r--spec/requests/api/nuget_project_packages_spec.rb4
-rw-r--r--spec/requests/api/pypi_packages_spec.rb2
-rw-r--r--spec/requests/api/releases_spec.rb2
-rw-r--r--spec/requests/api/rubygem_packages_spec.rb2
-rw-r--r--spec/requests/api/terraform/modules/v1/packages_spec.rb2
-rw-r--r--spec/requests/git_http_spec.rb4
-rw-r--r--spec/requests/lfs_http_spec.rb4
-rw-r--r--spec/support/shared_contexts/requests/api/conan_packages_shared_context.rb4
-rw-r--r--spec/support/shared_contexts/requests/api/npm_packages_shared_context.rb2
30 files changed, 257 insertions, 443 deletions
diff --git a/spec/factories/ci/job_token/project_scope_links.rb b/spec/factories/ci/job_token/project_scope_links.rb
new file mode 100644
index 00000000000..a11edd87e4e
--- /dev/null
+++ b/spec/factories/ci/job_token/project_scope_links.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :ci_job_token_project_scope_link, class: 'Ci::JobToken::ProjectScopeLink' do
+ association :source_project, factory: :project
+ association :target_project, factory: :project
+ association :added_by, factory: :user
+ end
+end
diff --git a/spec/factories_spec.rb b/spec/factories_spec.rb
index 994bf066cf0..80e94fa1628 100644
--- a/spec/factories_spec.rb
+++ b/spec/factories_spec.rb
@@ -66,6 +66,7 @@ RSpec.describe 'factories' do
# associations must be unique and cannot be reused, or the factory default
# is being mutated.
skip_factory_defaults = %i[
+ ci_job_token_project_scope_link
evidence
exported_protected_branch
fork_network_member
diff --git a/spec/features/admin/clusters/applications_spec.rb b/spec/features/admin/clusters/applications_spec.rb
deleted file mode 100644
index e083e4fee4c..00000000000
--- a/spec/features/admin/clusters/applications_spec.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_relative '../../../../spec/features/clusters/installing_applications_shared_examples'
-
-RSpec.describe 'Instance-level Cluster Applications', :js do
- include GoogleApi::CloudPlatformHelpers
-
- let(:user) { create(:admin) }
-
- before do
- sign_in(user)
- gitlab_enable_admin_mode_sign_in(user)
- end
-
- describe 'Installing applications' do
- include_examples "installing applications on a cluster" do
- let(:cluster_path) { admin_cluster_path(cluster) }
- let(:cluster_factory_args) { [:instance] }
- end
- end
-end
diff --git a/spec/features/calendar_spec.rb b/spec/features/calendar_spec.rb
index 1281d890ef7..21da92c9f43 100644
--- a/spec/features/calendar_spec.rb
+++ b/spec/features/calendar_spec.rb
@@ -15,10 +15,9 @@ RSpec.describe 'Contributions Calendar', :js do
issue_title = 'Bug in old browser'
issue_params = { title: issue_title }
- def get_cell_color_selector(contributions)
- activity_colors = ["#ededed", "rgb(172, 213, 242)", "rgb(127, 168, 201)", "rgb(82, 123, 160)", "rgb(37, 78, 119)"]
+ def get_cell_level_selector(contributions)
# We currently don't actually test the cases with contributions >= 20
- activity_colors_index =
+ activity_level_index =
if contributions > 0 && contributions < 10
1
elsif contributions >= 10 && contributions < 20
@@ -31,7 +30,7 @@ RSpec.describe 'Contributions Calendar', :js do
0
end
- ".user-contrib-cell[fill='#{activity_colors[activity_colors_index]}']"
+ ".user-contrib-cell:not(.contrib-legend)[data-level='#{activity_level_index}']"
end
def get_cell_date_selector(contributions, date)
@@ -42,7 +41,7 @@ RSpec.describe 'Contributions Calendar', :js do
"#{contributions} #{'contribution'.pluralize(contributions)}"
end
- "#{get_cell_color_selector(contributions)}[title='#{contribution_text}<br /><span class=\"gl-text-gray-300\">#{date}</span>']"
+ "#{get_cell_level_selector(contributions)}[title='#{contribution_text}<br /><span class=\"gl-text-gray-300\">#{date}</span>']"
end
def push_code_contribution
@@ -137,7 +136,7 @@ RSpec.describe 'Contributions Calendar', :js do
include_context 'visit user page'
it 'displays calendar activity square for 1 contribution', :sidekiq_might_not_need_inline do
- expect(find('#js-overview')).to have_selector(get_cell_color_selector(contribution_count), count: 1)
+ expect(find('#js-overview')).to have_selector(get_cell_level_selector(contribution_count), count: 1)
today = Date.today.strftime(date_format)
expect(find('#js-overview')).to have_selector(get_cell_date_selector(contribution_count, today), count: 1)
@@ -187,7 +186,7 @@ RSpec.describe 'Contributions Calendar', :js do
include_context 'visit user page'
it 'displays calendar activity squares for both days', :sidekiq_might_not_need_inline do
- expect(find('#js-overview')).to have_selector(get_cell_color_selector(1), count: 2)
+ expect(find('#js-overview')).to have_selector(get_cell_level_selector(1), count: 2)
end
it 'displays calendar activity square for yesterday', :sidekiq_might_not_need_inline do
diff --git a/spec/features/clusters/cluster_detail_page_spec.rb b/spec/features/clusters/cluster_detail_page_spec.rb
index 84a18a45d35..cba8aaef1ef 100644
--- a/spec/features/clusters/cluster_detail_page_spec.rb
+++ b/spec/features/clusters/cluster_detail_page_spec.rb
@@ -31,30 +31,6 @@ RSpec.describe 'Clusterable > Show page' do
expect(page).to have_content('Kubernetes cluster was successfully updated.')
end
- context 'when there is a cluster with ingress and external ip', :js do
- before do
- cluster.create_application_ingress!(external_ip: '192.168.1.100')
-
- visit cluster_path
- end
-
- it 'shows help text with the domain as an alternative to custom domain', :js do
- within '.js-cluster-details-form' do
- expect(find(cluster_ingress_help_text_selector).text).to include('192.168.1.100')
- end
- end
- end
-
- context 'when there is no ingress' do
- it 'alternative to custom domain is not shown' do
- visit cluster_path
-
- within '.js-cluster-details-form' do
- expect(page).not_to have_selector(cluster_ingress_help_text_selector)
- end
- end
- end
-
it 'does not show the environments tab' do
visit cluster_path
diff --git a/spec/features/clusters/cluster_health_dashboard_spec.rb b/spec/features/clusters/cluster_health_dashboard_spec.rb
index 0e2739a45b1..20c07f4d6ac 100644
--- a/spec/features/clusters/cluster_health_dashboard_spec.rb
+++ b/spec/features/clusters/cluster_health_dashboard_spec.rb
@@ -27,8 +27,8 @@ RSpec.describe 'Cluster Health board', :js, :kubeclient, :use_clean_rails_memory
expect(page).to have_css('.cluster-health-graphs')
end
- context 'no prometheus enabled' do
- it 'shows install prometheus message' do
+ context 'no prometheus available' do
+ it 'shows enable Prometheus message' do
visit cluster_path
click_link 'Health'
@@ -82,12 +82,12 @@ RSpec.describe 'Cluster Health board', :js, :kubeclient, :use_clean_rails_memory
def stub_empty_response
stub_prometheus_request(/prometheus-prometheus-server/, status: 204, body: {})
- stub_prometheus_request(/prometheus\/api\/v1/, status: 204, body: {})
+ stub_prometheus_request(%r{prometheus/api/v1}, status: 204, body: {})
end
def stub_connected
stub_prometheus_request(/prometheus-prometheus-server/, body: prometheus_values_body)
- stub_prometheus_request(/prometheus\/api\/v1/, body: prometheus_values_body)
+ stub_prometheus_request(%r{prometheus/api/v1}, body: prometheus_values_body)
end
end
end
diff --git a/spec/features/clusters/installing_applications_shared_examples.rb b/spec/features/clusters/installing_applications_shared_examples.rb
deleted file mode 100644
index c422aa2be72..00000000000
--- a/spec/features/clusters/installing_applications_shared_examples.rb
+++ /dev/null
@@ -1,252 +0,0 @@
-# frozen_string_literal: true
-
-RSpec.shared_examples "installing applications for a cluster" do
- before do
- # Reduce interval from 10 seconds which is too long for an automated test
- stub_const("#{Clusters::ClustersController}::STATUS_POLLING_INTERVAL", 500)
-
- visit cluster_path
- end
-
- context 'when cluster is being created' do
- let(:cluster) { create(:cluster, :providing_by_gcp, *cluster_factory_args) }
-
- it 'user is unable to install applications' do
- expect(page).not_to have_text('Helm')
- expect(page).not_to have_text('Install')
- end
- end
-
- context 'when cluster is created' do
- let(:cluster) { create(:cluster, :provided_by_gcp, *cluster_factory_args) }
-
- before do
- page.within('.js-edit-cluster-form') do
- click_link 'Applications'
- end
- end
-
- it 'user can install applications' do
- wait_for_requests
-
- application_row = '.js-cluster-application-row-ingress'
-
- page.within(application_row) do
- expect(page).not_to have_css('.js-cluster-application-install-button[disabled]')
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Install')
- end
- end
-
- it 'does not show the Helm application' do
- expect(page).not_to have_selector(:css, '.js-cluster-application-row-helm')
- end
-
- context 'when user installs Knative' do
- context 'on an abac cluster' do
- let(:cluster) { create(:cluster, :provided_by_gcp, :rbac_disabled, *cluster_factory_args) }
-
- it 'shows info block and not be installable' do
- page.within('.js-cluster-application-row-knative') do
- expect(page).to have_css('.rbac-notice')
- expect(page.find(:css, '.js-cluster-application-install-button')['disabled']).to eq('true')
- end
- end
- end
-
- context 'on an rbac cluster' do
- let(:cluster) { create(:cluster, :provided_by_gcp, *cluster_factory_args) }
-
- it 'does not show callout block and be installable' do
- page.within('.js-cluster-application-row-knative') do
- expect(page).not_to have_css('p', text: 'You must have an RBAC-enabled cluster', visible: :all)
- expect(page).to have_css('.js-cluster-application-install-button:not([disabled])')
- end
- end
-
- describe 'when user clicks install button' do
- before do
- allow(ClusterInstallAppWorker).to receive(:perform_async)
- allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_in)
- allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_async)
-
- page.within('.js-cluster-application-row-knative') do
- expect(page).to have_css('.js-cluster-application-install-button:not([disabled])')
-
- page.find('.js-knative-domainname').set("domain.example.org")
-
- click_button 'Install'
-
- wait_for_requests
-
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_knative.make_installing!
- Clusters::Cluster.last.application_knative.make_installed!
- Clusters::Cluster.last.application_knative.update_attribute(:external_ip, '127.0.0.1')
- end
- end
-
- it 'shows status transition' do
- page.within('.js-cluster-application-row-knative') do
- expect(page).to have_field('Knative Domain Name:', with: 'domain.example.org')
- expect(page).to have_css('.js-cluster-application-uninstall-button', exact_text: 'Uninstall')
- end
-
- expect(page).to have_content('Knative was successfully installed on your Kubernetes cluster')
- expect(page).to have_css('.js-knative-save-domain-button'), exact_text: 'Save changes'
- end
-
- it 'can then update the domain' do
- page.within('.js-cluster-application-row-knative') do
- expect(ClusterPatchAppWorker).to receive(:perform_async)
-
- expect(page).to have_field('Knative Domain Name:', with: 'domain.example.org')
-
- page.find('.js-knative-domainname').set("new.domain.example.org")
-
- click_button 'Save changes'
-
- wait_for_requests
-
- expect(page).to have_field('Knative Domain Name:', with: 'new.domain.example.org')
- end
- end
- end
- end
- end
-
- context 'when user installs Cert Manager' do
- before do
- allow(ClusterInstallAppWorker).to receive(:perform_async)
- allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_in)
- allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_async)
- end
-
- it 'shows status transition' do
- page.within('.js-cluster-application-row-cert_manager') do
- click_button 'Install'
- wait_for_requests
-
- expect(page).to have_field('Issuer Email', with: cluster.user.email)
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_cert_manager.make_installing!
-
- expect(page).to have_field('Issuer Email', with: cluster.user.email)
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_cert_manager.make_installed!
-
- expect(page).to have_field('Issuer Email', with: cluster.user.email)
- expect(page).to have_css('.js-cluster-application-uninstall-button', exact_text: 'Uninstall')
- end
-
- expect(page).to have_content('Cert-Manager was successfully installed on your Kubernetes cluster')
- end
-
- it 'installs with custom email' do
- custom_email = 'new_email@example.org'
-
- page.within('.js-cluster-application-row-cert_manager') do
- # Wait for the polling to finish
- wait_for_requests
-
- page.find('.js-email').set(custom_email)
- click_button 'Install'
- wait_for_requests
-
- expect(page).to have_field('Issuer Email', with: custom_email)
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_cert_manager.make_installing!
-
- expect(page).to have_field('Issuer Email', with: custom_email)
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_cert_manager.make_installed!
-
- expect(page).to have_field('Issuer Email', with: custom_email)
- expect(page).to have_css('.js-cluster-application-uninstall-button', exact_text: 'Uninstall')
- end
- end
- end
-
- context 'when user installs Elastic Stack' do
- before do
- allow(ClusterInstallAppWorker).to receive(:perform_async)
-
- page.within('.js-cluster-application-row-elastic_stack') do
- click_button 'Install'
- end
-
- wait_for_requests
- end
-
- it 'shows status transition' do
- page.within('.js-cluster-application-row-elastic_stack') do
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_elastic_stack.make_installing!
-
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_elastic_stack.make_installed!
-
- expect(page).to have_css('.js-cluster-application-uninstall-button', exact_text: 'Uninstall')
- end
-
- expect(page).to have_content('Elastic Stack was successfully installed on your Kubernetes cluster')
- end
- end
-
- context 'when user installs Ingress' do
- before do
- allow(ClusterInstallAppWorker).to receive(:perform_async)
- allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_in)
- allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_async)
-
- page.within('.js-cluster-application-row-ingress') do
- expect(page).to have_css('.js-cluster-application-install-button:not([disabled])')
- page.find(:css, '.js-cluster-application-install-button').click
-
- wait_for_requests
- end
- end
-
- it 'shows the status transition' do
- page.within('.js-cluster-application-row-ingress') do
- # FE sends request and gets the response, then the buttons is "Installing"
- expect(page).to have_css('.js-cluster-application-install-button[disabled]', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_ingress.make_installing!
-
- # FE starts polling and update the buttons to "Installing"
- expect(page).to have_css('.js-cluster-application-install-button[disabled]', exact_text: 'Installing')
-
- # The application becomes installed but we keep waiting for external IP address
- Clusters::Cluster.last.application_ingress.make_installed!
-
- expect(page).to have_css('.js-cluster-application-install-button[disabled]', exact_text: 'Installed')
- expect(page).to have_selector('.js-no-endpoint-message')
- expect(page).to have_selector('.js-ingress-ip-loading-icon')
-
- # We receive the external IP address and display
- Clusters::Cluster.last.application_ingress.update!(external_ip: '192.168.1.100')
-
- expect(page).not_to have_css('button', exact_text: 'Install', visible: :all)
- expect(page).not_to have_css('button', exact_text: 'Installing', visible: :all)
- expect(page).to have_css('.js-cluster-application-uninstall-button:not([disabled])', exact_text: 'Uninstall')
- expect(page).not_to have_css('p', text: 'The endpoint is in the process of being assigned', visible: :all)
- expect(page.find('.js-endpoint').value).to eq('192.168.1.100')
- end
-
- expect(page).to have_content('Ingress was successfully installed on your Kubernetes cluster')
- end
- end
- end
-end
-
-RSpec.shared_examples "installing applications on a cluster" do
- it_behaves_like "installing applications for a cluster", false
- it_behaves_like "installing applications for a cluster", true
-end
diff --git a/spec/features/groups/clusters/applications_spec.rb b/spec/features/groups/clusters/applications_spec.rb
deleted file mode 100644
index 324ef24efc4..00000000000
--- a/spec/features/groups/clusters/applications_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_relative '../../../../spec/features/clusters/installing_applications_shared_examples'
-
-RSpec.describe 'Group-level Cluster Applications', :js do
- include GoogleApi::CloudPlatformHelpers
-
- let(:group) { create(:group) }
- let(:user) { create(:user) }
-
- before do
- group.add_maintainer(user)
- sign_in(user)
- end
-
- describe 'Installing applications' do
- include_examples "installing applications on a cluster" do
- let(:cluster_path) { group_cluster_path(group, cluster) }
- let(:cluster_factory_args) { [:group, groups: [group]] }
- end
- end
-end
diff --git a/spec/features/projects/clusters/applications_spec.rb b/spec/features/projects/clusters/applications_spec.rb
deleted file mode 100644
index 74b477dd85d..00000000000
--- a/spec/features/projects/clusters/applications_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_relative '../../../../spec/features/clusters/installing_applications_shared_examples'
-
-RSpec.describe 'Project-level Cluster Applications', :js do
- include GoogleApi::CloudPlatformHelpers
-
- let(:project) { create(:project) }
- let(:user) { create(:user) }
-
- before do
- project.add_maintainer(user)
- sign_in(user)
- end
-
- describe 'Installing applications' do
- include_examples "installing applications on a cluster" do
- let(:cluster_path) { project_cluster_path(project, cluster) }
- let(:cluster_factory_args) { [projects: [project]] }
- end
- end
-end
diff --git a/spec/finders/ci/auth_job_finder_spec.rb b/spec/finders/ci/auth_job_finder_spec.rb
index 6cd58f5cd01..78827c9ddee 100644
--- a/spec/finders/ci/auth_job_finder_spec.rb
+++ b/spec/finders/ci/auth_job_finder_spec.rb
@@ -2,7 +2,8 @@
require 'spec_helper'
RSpec.describe Ci::AuthJobFinder do
- let_it_be(:job, reload: true) { create(:ci_build, status: :running) }
+ let_it_be(:user, reload: true) { create(:user) }
+ let_it_be(:job, reload: true) { create(:ci_build, status: :running, user: user) }
let(:token) { job.token }
@@ -55,10 +56,31 @@ RSpec.describe Ci::AuthJobFinder do
describe '#execute' do
subject(:execute) { finder.execute }
- before do
- job.success!
+ context 'when job is not running' do
+ before do
+ job.success!
+ end
+
+ it { is_expected.to be_nil }
end
- it { is_expected.to be_nil }
+ context 'when job is running', :request_store do
+ it 'sets ci_job_token_scope on the job user', :aggregate_failures do
+ expect(subject).to eq(job)
+ expect(subject.user).to be_from_ci_job_token
+ expect(subject.user.ci_job_token_scope.source_project).to eq(job.project)
+ end
+
+ context 'when feature flag ci_scoped_job_token is disabled' do
+ before do
+ stub_feature_flags(ci_scoped_job_token: false)
+ end
+
+ it 'does not set ci_job_token_scope on the job user' do
+ expect(subject).to eq(job)
+ expect(subject.user).not_to be_from_ci_job_token
+ end
+ end
+ end
end
end
diff --git a/spec/frontend/clusters/forms/components/integration_form_spec.js b/spec/frontend/clusters/forms/components/integration_form_spec.js
index c5cec4c4fdb..b129baa2d83 100644
--- a/spec/frontend/clusters/forms/components/integration_form_spec.js
+++ b/spec/frontend/clusters/forms/components/integration_form_spec.js
@@ -15,7 +15,6 @@ describe('ClusterIntegrationForm', () => {
editable: true,
environmentScope: '*',
baseDomain: 'testDomain',
- applicationIngressExternalIp: null,
};
const createWrapper = (storeValues = defaultStoreValues) => {
@@ -72,18 +71,6 @@ describe('ClusterIntegrationForm', () => {
expect(findSubmitButton().exists()).toBe(false);
});
});
-
- it('does not render external IP block if applicationIngressExternalIp was not passed', () => {
- createWrapper({ ...defaultStoreValues });
-
- expect(wrapper.find('.js-ingress-domain-help-text').exists()).toBe(false);
- });
-
- it('renders external IP block if applicationIngressExternalIp was passed', () => {
- createWrapper({ ...defaultStoreValues, applicationIngressExternalIp: '127.0.0.1' });
-
- expect(wrapper.find('.js-ingress-domain-help-text').exists()).toBe(true);
- });
});
describe('reactivity', () => {
diff --git a/spec/frontend/pages/users/activity_calendar_spec.js b/spec/frontend/pages/users/activity_calendar_spec.js
new file mode 100644
index 00000000000..b33e92e14b2
--- /dev/null
+++ b/spec/frontend/pages/users/activity_calendar_spec.js
@@ -0,0 +1,16 @@
+import { getLevelFromContributions } from '~/pages/users/activity_calendar';
+
+describe('getLevelFromContributions', () => {
+ it.each([
+ [0, 0],
+ [1, 1],
+ [9, 1],
+ [10, 2],
+ [19, 2],
+ [20, 3],
+ [30, 4],
+ [99, 4],
+ ])('.getLevelFromContributions(%i, %i)', (count, expected) => {
+ expect(getLevelFromContributions(count)).toBe(expected);
+ });
+});
diff --git a/spec/lib/gitlab/auth/auth_finders_spec.rb b/spec/lib/gitlab/auth/auth_finders_spec.rb
index cddcaf09b74..7475ed2796f 100644
--- a/spec/lib/gitlab/auth/auth_finders_spec.rb
+++ b/spec/lib/gitlab/auth/auth_finders_spec.rb
@@ -50,7 +50,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end
shared_examples 'find user from job token' do |without_job_token_allowed|
- context 'when route is allowed to be authenticated' do
+ context 'when route is allowed to be authenticated', :request_store do
let(:route_authentication_setting) { { job_token_allowed: true } }
context 'for an invalid token' do
@@ -68,6 +68,8 @@ RSpec.describe Gitlab::Auth::AuthFinders do
it 'return user' do
expect(subject).to eq(user)
expect(@current_authenticated_job).to eq job
+ expect(subject).to be_from_ci_job_token
+ expect(subject.ci_job_token_scope.source_project).to eq(job.project)
end
end
@@ -81,7 +83,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end
end
- context 'when route is not allowed to be authenticated' do
+ context 'when route is not allowed to be authenticated', :request_store do
let(:route_authentication_setting) { { job_token_allowed: false } }
context 'with a running job' do
@@ -96,6 +98,8 @@ RSpec.describe Gitlab::Auth::AuthFinders do
it 'returns the user' do
expect(subject).to eq(user)
expect(@current_authenticated_job).to eq job
+ expect(subject).to be_from_ci_job_token
+ expect(subject.ci_job_token_scope.source_project).to eq(job.project)
end
else
it 'returns nil' do
diff --git a/spec/models/ci/job_token/project_scope_link_spec.rb b/spec/models/ci/job_token/project_scope_link_spec.rb
new file mode 100644
index 00000000000..d18495b9312
--- /dev/null
+++ b/spec/models/ci/job_token/project_scope_link_spec.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::JobToken::ProjectScopeLink do
+ it { is_expected.to belong_to(:source_project) }
+ it { is_expected.to belong_to(:target_project) }
+ it { is_expected.to belong_to(:added_by) }
+
+ let_it_be(:project) { create(:project) }
+
+ describe 'unique index' do
+ let!(:link) { create(:ci_job_token_project_scope_link) }
+
+ it 'raises an error' do
+ expect do
+ create(:ci_job_token_project_scope_link,
+ source_project: link.source_project,
+ target_project: link.target_project)
+ end.to raise_error(ActiveRecord::RecordNotUnique)
+ end
+ end
+
+ describe 'validations' do
+ it 'must have a source project', :aggregate_failures do
+ link = build(:ci_job_token_project_scope_link, source_project: nil)
+
+ expect(link).not_to be_valid
+ expect(link.errors[:source_project]).to contain_exactly("can't be blank")
+ end
+
+ it 'must have a target project', :aggregate_failures do
+ link = build(:ci_job_token_project_scope_link, target_project: nil)
+
+ expect(link).not_to be_valid
+ expect(link.errors[:target_project]).to contain_exactly("can't be blank")
+ end
+
+ it 'must have a target project different than source project', :aggregate_failures do
+ link = build(:ci_job_token_project_scope_link, target_project: project, source_project: project)
+
+ expect(link).not_to be_valid
+ expect(link.errors[:target_project]).to contain_exactly("can't be the same as the source project")
+ end
+ end
+
+ describe '.from_project' do
+ subject { described_class.from_project(project) }
+
+ let!(:source_link) { create(:ci_job_token_project_scope_link, source_project: project) }
+ let!(:target_link) { create(:ci_job_token_project_scope_link, target_project: project) }
+
+ it 'returns only the links having the given source project' do
+ expect(subject).to contain_exactly(source_link)
+ end
+ end
+
+ describe '.to_project' do
+ subject { described_class.to_project(project) }
+
+ let!(:source_link) { create(:ci_job_token_project_scope_link, source_project: project) }
+ let!(:target_link) { create(:ci_job_token_project_scope_link, target_project: project) }
+
+ it 'returns only the links having the given target project' do
+ expect(subject).to contain_exactly(target_link)
+ end
+ end
+end
diff --git a/spec/models/ci/job_token/scope_spec.rb b/spec/models/ci/job_token/scope_spec.rb
new file mode 100644
index 00000000000..2fbfbac64f8
--- /dev/null
+++ b/spec/models/ci/job_token/scope_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::JobToken::Scope do
+ let_it_be(:project) { create(:project) }
+
+ let(:scope) { described_class.new(project) }
+
+ describe '#all_projects' do
+ subject(:all_projects) { scope.all_projects }
+
+ context 'when no projects are added to the scope' do
+ it 'returns the project defining the scope' do
+ expect(all_projects).to contain_exactly(project)
+ end
+ end
+
+ context 'when other projects are added to the scope' do
+ let_it_be(:scoped_project) { create(:project) }
+ let_it_be(:unscoped_project) { create(:project) }
+
+ let!(:link_in_scope) { create(:ci_job_token_project_scope_link, source_project: project, target_project: scoped_project) }
+ let!(:link_out_of_scope) { create(:ci_job_token_project_scope_link, target_project: unscoped_project) }
+
+ it 'returns all projects that can be accessed from a given scope' do
+ expect(subject).to contain_exactly(project, scoped_project)
+ end
+ end
+ end
+
+ describe 'includes?' do
+ subject { scope.includes?(target_project) }
+
+ context 'when param is the project defining the scope' do
+ let(:target_project) { project }
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when param is a project in scope' do
+ let(:target_link) { create(:ci_job_token_project_scope_link, source_project: project) }
+ let(:target_project) { target_link.target_project }
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when param is a project in another scope' do
+ let(:scope_link) { create(:ci_job_token_project_scope_link) }
+ let(:target_project) { scope_link.target_project }
+
+ it { is_expected.to be_falsey }
+ end
+ end
+end
diff --git a/spec/models/hooks/web_hook_log_archived_spec.rb b/spec/models/hooks/web_hook_log_archived_spec.rb
deleted file mode 100644
index ac726dbaf4f..00000000000
--- a/spec/models/hooks/web_hook_log_archived_spec.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe WebHookLogArchived do
- let(:source_table) { WebHookLog }
- let(:destination_table) { described_class }
-
- it 'has the same columns as the source table' do
- column_names_from_source_table = column_names(source_table)
- column_names_from_destination_table = column_names(destination_table)
-
- expect(column_names_from_destination_table).to match_array(column_names_from_source_table)
- end
-
- it 'has the same null constraints as the source table' do
- constraints_from_source_table = null_constraints(source_table)
- constraints_from_destination_table = null_constraints(destination_table)
-
- expect(constraints_from_destination_table.to_a).to match_array(constraints_from_source_table.to_a)
- end
-
- it 'inserts the same record as the one in the source table', :aggregate_failures do
- expect { create(:web_hook_log) }.to change { destination_table.count }.by(1)
-
- event_from_source_table = source_table.connection.select_one(
- "SELECT * FROM #{source_table.table_name} ORDER BY created_at desc LIMIT 1"
- )
- event_from_destination_table = destination_table.connection.select_one(
- "SELECT * FROM #{destination_table.table_name} ORDER BY created_at desc LIMIT 1"
- )
-
- expect(event_from_destination_table).to eq(event_from_source_table)
- end
-
- def column_names(table)
- table.connection.select_all(<<~SQL)
- SELECT c.column_name
- FROM information_schema.columns c
- WHERE c.table_name = '#{table.table_name}'
- SQL
- end
-
- def null_constraints(table)
- table.connection.select_all(<<~SQL)
- SELECT c.column_name, c.is_nullable
- FROM information_schema.columns c
- WHERE c.table_name = '#{table.table_name}'
- AND c.column_name != 'created_at'
- SQL
- end
-end
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index d0abcfbd091..53d9bdb01a3 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -1385,4 +1385,53 @@ RSpec.describe ProjectPolicy do
end
end
end
+
+ describe 'when user is authenticated via CI_JOB_TOKEN', :request_store do
+ let(:current_user) { developer }
+ let(:job) { build_stubbed(:ci_build, project: scope_project, user: current_user) }
+
+ before do
+ current_user.set_ci_job_token_scope!(job)
+ end
+
+ context 'when accessing a private project' do
+ let(:project) { private_project }
+
+ context 'when the job token comes from the same project' do
+ let(:scope_project) { project }
+
+ it { is_expected.to be_allowed(:developer_access) }
+ end
+
+ context 'when the job token comes from another project' do
+ let(:scope_project) { create(:project, :private) }
+
+ before do
+ scope_project.add_developer(current_user)
+ end
+
+ it { is_expected.to be_disallowed(:guest_access) }
+ end
+ end
+
+ context 'when accessing a public project' do
+ let(:project) { public_project }
+
+ context 'when the job token comes from the same project' do
+ let(:scope_project) { project }
+
+ it { is_expected.to be_allowed(:developer_access) }
+ end
+
+ context 'when the job token comes from another project' do
+ let(:scope_project) { create(:project, :private) }
+
+ before do
+ scope_project.add_developer(current_user)
+ end
+
+ it { is_expected.to be_disallowed(:public_access) }
+ end
+ end
+ end
end
diff --git a/spec/requests/api/generic_packages_spec.rb b/spec/requests/api/generic_packages_spec.rb
index a5e40eec919..6886fff2282 100644
--- a/spec/requests/api/generic_packages_spec.rb
+++ b/spec/requests/api/generic_packages_spec.rb
@@ -18,7 +18,7 @@ RSpec.describe API::GenericPackages do
let_it_be(:project_deploy_token_wo) { create(:project_deploy_token, deploy_token: deploy_token_wo, project: project) }
let(:user) { personal_access_token.user }
- let(:ci_build) { create(:ci_build, :running, user: user) }
+ let(:ci_build) { create(:ci_build, :running, user: user, project: project) }
def auth_header
return {} if user_role == :anonymous
diff --git a/spec/requests/api/go_proxy_spec.rb b/spec/requests/api/go_proxy_spec.rb
index e678b6cf1c8..0143340de11 100644
--- a/spec/requests/api/go_proxy_spec.rb
+++ b/spec/requests/api/go_proxy_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe API::GoProxy do
let_it_be(:base) { "#{Settings.build_gitlab_go_url}/#{project.full_path}" }
let_it_be(:oauth) { create :oauth_access_token, scopes: 'api', resource_owner: user }
- let_it_be(:job) { create :ci_build, user: user, status: :running }
+ let_it_be(:job) { create :ci_build, user: user, status: :running, project: project }
let_it_be(:pa_token) { create :personal_access_token, user: user }
let_it_be(:modules) do
diff --git a/spec/requests/api/maven_packages_spec.rb b/spec/requests/api/maven_packages_spec.rb
index 2bb6d05f54b..d9f11b19e6e 100644
--- a/spec/requests/api/maven_packages_spec.rb
+++ b/spec/requests/api/maven_packages_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe API::MavenPackages do
let_it_be(:package_file) { package.package_files.with_file_name_like('%.xml').first }
let_it_be(:jar_file) { package.package_files.with_file_name_like('%.jar').first }
let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
- let_it_be(:job, reload: true) { create(:ci_build, user: user, status: :running) }
+ let_it_be(:job, reload: true) { create(:ci_build, user: user, status: :running, project: project) }
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
let_it_be(:deploy_token_for_group) { create(:deploy_token, :group, read_package_registry: true, write_package_registry: true) }
diff --git a/spec/requests/api/npm_project_packages_spec.rb b/spec/requests/api/npm_project_packages_spec.rb
index 8230061546f..ab74da4bda4 100644
--- a/spec/requests/api/npm_project_packages_spec.rb
+++ b/spec/requests/api/npm_project_packages_spec.rb
@@ -78,7 +78,7 @@ RSpec.describe API::NpmProjectPackages do
context 'with a job token for a different user' do
let_it_be(:other_user) { create(:user) }
- let_it_be_with_reload(:other_job) { create(:ci_build, :running, user: other_user) }
+ let_it_be_with_reload(:other_job) { create(:ci_build, :running, user: other_user, project: project) }
let(:headers) { build_token_auth_header(other_job.token) }
diff --git a/spec/requests/api/nuget_project_packages_spec.rb b/spec/requests/api/nuget_project_packages_spec.rb
index 98458cb8dfa..572736cfc86 100644
--- a/spec/requests/api/nuget_project_packages_spec.rb
+++ b/spec/requests/api/nuget_project_packages_spec.rb
@@ -192,7 +192,7 @@ RSpec.describe API::NugetProjectPackages do
it_behaves_like 'deploy token for package uploads'
it_behaves_like 'job token for package uploads', authorize_endpoint: true do
- let_it_be(:job) { create(:ci_build, :running, user: user) }
+ let_it_be(:job) { create(:ci_build, :running, user: user, project: project) }
end
it_behaves_like 'rejects nuget access with unknown target id'
@@ -260,7 +260,7 @@ RSpec.describe API::NugetProjectPackages do
it_behaves_like 'deploy token for package uploads'
it_behaves_like 'job token for package uploads' do
- let_it_be(:job) { create(:ci_build, :running, user: user) }
+ let_it_be(:job) { create(:ci_build, :running, user: user, project: project) }
end
it_behaves_like 'rejects nuget access with unknown target id'
diff --git a/spec/requests/api/pypi_packages_spec.rb b/spec/requests/api/pypi_packages_spec.rb
index 552ef2b2120..86925e6a0ba 100644
--- a/spec/requests/api/pypi_packages_spec.rb
+++ b/spec/requests/api/pypi_packages_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe API::PypiPackages do
let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
- let_it_be(:job) { create(:ci_build, :running, user: user) }
+ let_it_be(:job) { create(:ci_build, :running, user: user, project: project) }
let(:headers) { {} }
context 'simple API endpoint' do
diff --git a/spec/requests/api/releases_spec.rb b/spec/requests/api/releases_spec.rb
index dad3e34404b..81a4fcdbcac 100644
--- a/spec/requests/api/releases_spec.rb
+++ b/spec/requests/api/releases_spec.rb
@@ -775,7 +775,7 @@ RSpec.describe API::Releases do
end
context 'when using JOB-TOKEN auth' do
- let(:job) { create(:ci_build, user: maintainer) }
+ let(:job) { create(:ci_build, user: maintainer, project: project) }
let(:params) do
{
name: 'Another release',
diff --git a/spec/requests/api/rubygem_packages_spec.rb b/spec/requests/api/rubygem_packages_spec.rb
index 09b63139e54..7d863b55bbe 100644
--- a/spec/requests/api/rubygem_packages_spec.rb
+++ b/spec/requests/api/rubygem_packages_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe API::RubygemPackages do
let_it_be_with_reload(:project) { create(:project) }
let_it_be(:personal_access_token) { create(:personal_access_token) }
let_it_be(:user) { personal_access_token.user }
- let_it_be(:job) { create(:ci_build, :running, user: user) }
+ let_it_be(:job) { create(:ci_build, :running, user: user, project: project) }
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
let_it_be(:headers) { {} }
diff --git a/spec/requests/api/terraform/modules/v1/packages_spec.rb b/spec/requests/api/terraform/modules/v1/packages_spec.rb
index 6803c09b8c2..b04f5ad9a94 100644
--- a/spec/requests/api/terraform/modules/v1/packages_spec.rb
+++ b/spec/requests/api/terraform/modules/v1/packages_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe API::Terraform::Modules::V1::Packages do
let_it_be(:package) { create(:terraform_module_package, project: project) }
let_it_be(:personal_access_token) { create(:personal_access_token) }
let_it_be(:user) { personal_access_token.user }
- let_it_be(:job) { create(:ci_build, :running, user: user) }
+ let_it_be(:job) { create(:ci_build, :running, user: user, project: project) }
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb
index 279c65fc2f4..7cf46f6adc6 100644
--- a/spec/requests/git_http_spec.rb
+++ b/spec/requests/git_http_spec.rb
@@ -883,10 +883,10 @@ RSpec.describe 'Git HTTP requests' do
context 'when admin mode is enabled', :enable_admin_mode do
it_behaves_like 'can download code only'
- it 'downloads from other project get status 403' do
+ it 'downloads from other project get status 404' do
clone_get "#{other_project.full_path}.git", user: 'gitlab-ci-token', password: build.token
- expect(response).to have_gitlab_http_status(:forbidden)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
diff --git a/spec/requests/lfs_http_spec.rb b/spec/requests/lfs_http_spec.rb
index 0e3a0252638..fda8b2ecec6 100644
--- a/spec/requests/lfs_http_spec.rb
+++ b/spec/requests/lfs_http_spec.rb
@@ -569,7 +569,7 @@ RSpec.describe 'Git LFS API and storage' do
let(:pipeline) { create(:ci_empty_pipeline, project: other_project) }
# I'm not sure what this tests that is different from the previous test
- it_behaves_like 'LFS http 403 response'
+ it_behaves_like 'LFS http 404 response'
end
end
@@ -1043,7 +1043,7 @@ RSpec.describe 'Git LFS API and storage' do
let(:pipeline) { create(:ci_empty_pipeline, project: other_project) }
# I'm not sure what this tests that is different from the previous test
- it_behaves_like 'LFS http 403 response'
+ it_behaves_like 'LFS http 404 response'
end
end
diff --git a/spec/support/shared_contexts/requests/api/conan_packages_shared_context.rb b/spec/support/shared_contexts/requests/api/conan_packages_shared_context.rb
index ac53be1a1cb..c69a987c00d 100644
--- a/spec/support/shared_contexts/requests/api/conan_packages_shared_context.rb
+++ b/spec/support/shared_contexts/requests/api/conan_packages_shared_context.rb
@@ -8,11 +8,11 @@ RSpec.shared_context 'conan api setup' do
let_it_be(:personal_access_token) { create(:personal_access_token) }
let_it_be(:user) { personal_access_token.user }
let_it_be(:base_secret) { SecureRandom.base64(64) }
- let_it_be(:job) { create(:ci_build, :running, user: user) }
- let_it_be(:job_token) { job.token }
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
let(:project) { package.project }
+ let(:job) { create(:ci_build, :running, user: user, project: project) }
+ let(:job_token) { job.token }
let(:auth_token) { personal_access_token.token }
let(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
diff --git a/spec/support/shared_contexts/requests/api/npm_packages_shared_context.rb b/spec/support/shared_contexts/requests/api/npm_packages_shared_context.rb
index 815108be447..c737091df48 100644
--- a/spec/support/shared_contexts/requests/api/npm_packages_shared_context.rb
+++ b/spec/support/shared_contexts/requests/api/npm_packages_shared_context.rb
@@ -11,7 +11,7 @@ RSpec.shared_context 'npm api setup' do
let_it_be(:package, reload: true) { create(:npm_package, project: project, name: "@#{group.path}/scoped_package") }
let_it_be(:token) { create(:oauth_access_token, scopes: 'api', resource_owner: user) }
let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
- let_it_be(:job, reload: true) { create(:ci_build, user: user, status: :running) }
+ let_it_be(:job, reload: true) { create(:ci_build, user: user, status: :running, project: project) }
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }