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-11-03 21:13:40 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-11-03 21:13:40 +0300
commitbbc36645d34c557df40d031a1a41fbd05e491644 (patch)
tree55529c6e93d72f7e35e78488a397f50098f137a5 /spec
parent70a50740a20ab0027e0490487f6244f5ec961eee (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/jira_connect/app_descriptor_controller_spec.rb12
-rw-r--r--spec/controllers/jira_connect/events_controller_spec.rb75
-rw-r--r--spec/frontend/boards/components/board_filtered_search_spec.js33
-rw-r--r--spec/frontend/commit/pipelines/pipelines_table_spec.js14
-rw-r--r--spec/lib/gitlab/application_rate_limiter_spec.rb173
-rw-r--r--spec/requests/api/lint_spec.rb123
6 files changed, 275 insertions, 155 deletions
diff --git a/spec/controllers/jira_connect/app_descriptor_controller_spec.rb b/spec/controllers/jira_connect/app_descriptor_controller_spec.rb
index 9d890efdd33..4f8b2b90637 100644
--- a/spec/controllers/jira_connect/app_descriptor_controller_spec.rb
+++ b/spec/controllers/jira_connect/app_descriptor_controller_spec.rb
@@ -90,17 +90,5 @@ RSpec.describe JiraConnect::AppDescriptorController do
)
)
end
-
- context 'when jira_connect_asymmetric_jwt is disabled' do
- before do
- stub_feature_flags(jira_connect_asymmetric_jwt: false)
- end
-
- specify do
- get :show
-
- expect(json_response).to include('apiMigrations' => include('signed-install' => false))
- end
- end
end
end
diff --git a/spec/controllers/jira_connect/events_controller_spec.rb b/spec/controllers/jira_connect/events_controller_spec.rb
index 78bd0dc8318..2a70a2ea683 100644
--- a/spec/controllers/jira_connect/events_controller_spec.rb
+++ b/spec/controllers/jira_connect/events_controller_spec.rb
@@ -77,18 +77,6 @@ RSpec.describe JiraConnect::EventsController do
expect(installation.base_url).to eq('https://test.atlassian.net')
end
- context 'when jira_connect_asymmetric_jwt is disabled' do
- before do
- stub_feature_flags(jira_connect_asymmetric_jwt: false)
- end
-
- it 'saves the jira installation data without JWT validation' do
- expect(Atlassian::JiraConnect::AsymmetricJwt).not_to receive(:new)
-
- expect { subject }.to change { JiraConnectInstallation.count }.by(1)
- end
- end
-
context 'when it is a version update and shared_secret is not sent' do
let(:params) do
{
@@ -110,22 +98,6 @@ RSpec.describe JiraConnect::EventsController do
expect { subject }.not_to change { JiraConnectInstallation.count }
expect(response).to have_gitlab_http_status(:ok)
end
-
- context 'when jira_connect_asymmetric_jwt is disabled' do
- before do
- stub_feature_flags(jira_connect_asymmetric_jwt: false)
- end
-
- it 'decodes the JWT token in authorization header and returns 200 without creating a new installation' do
- request.headers["Authorization"] = "Bearer #{Atlassian::Jwt.encode({ iss: client_key }, shared_secret)}"
-
- expect(Atlassian::JiraConnect::AsymmetricJwt).not_to receive(:new)
-
- expect { subject }.not_to change { JiraConnectInstallation.count }
-
- expect(response).to have_gitlab_http_status(:ok)
- end
- end
end
end
end
@@ -153,23 +125,6 @@ RSpec.describe JiraConnect::EventsController do
it 'does not delete the installation' do
expect { post_uninstalled }.not_to change { JiraConnectInstallation.count }
end
-
- context 'when jira_connect_asymmetric_jwt is disabled' do
- before do
- stub_feature_flags(jira_connect_asymmetric_jwt: false)
- request.headers['Authorization'] = 'JWT invalid token'
- end
-
- it 'returns 403' do
- post_uninstalled
-
- expect(response).to have_gitlab_http_status(:forbidden)
- end
-
- it 'does not delete the installation' do
- expect { post_uninstalled }.not_to change { JiraConnectInstallation.count }
- end
- end
end
context 'when JWT is valid' do
@@ -197,36 +152,6 @@ RSpec.describe JiraConnect::EventsController do
expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
-
- context 'when jira_connect_asymmetric_jwt is disabled' do
- before do
- stub_feature_flags(jira_connect_asymmetric_jwt: false)
-
- request.headers['Authorization'] = "JWT #{Atlassian::Jwt.encode({ iss: installation.client_key, qsh: qsh }, installation.shared_secret)}"
- end
-
- let(:qsh) { Atlassian::Jwt.create_query_string_hash('https://gitlab.test/events/uninstalled', 'POST', 'https://gitlab.test') }
-
- it 'calls the DestroyService and returns ok in case of success' do
- expect_next_instance_of(JiraConnectInstallations::DestroyService, installation, jira_base_path, jira_event_path) do |destroy_service|
- expect(destroy_service).to receive(:execute).and_return(true)
- end
-
- post_uninstalled
-
- expect(response).to have_gitlab_http_status(:ok)
- end
-
- it 'calls the DestroyService and returns unprocessable_entity in case of failure' do
- expect_next_instance_of(JiraConnectInstallations::DestroyService, installation, jira_base_path, jira_event_path) do |destroy_service|
- expect(destroy_service).to receive(:execute).and_return(false)
- end
-
- post_uninstalled
-
- expect(response).to have_gitlab_http_status(:unprocessable_entity)
- end
- end
end
end
end
diff --git a/spec/frontend/boards/components/board_filtered_search_spec.js b/spec/frontend/boards/components/board_filtered_search_spec.js
index dc93890f27a..b858d6e95a0 100644
--- a/spec/frontend/boards/components/board_filtered_search_spec.js
+++ b/spec/frontend/boards/components/board_filtered_search_spec.js
@@ -7,6 +7,7 @@ import { __ } from '~/locale';
import FilteredSearchBarRoot from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
import AuthorToken from '~/vue_shared/components/filtered_search_bar/tokens/author_token.vue';
import LabelToken from '~/vue_shared/components/filtered_search_bar/tokens/label_token.vue';
+import { createStore } from '~/boards/stores';
Vue.use(Vuex);
@@ -42,17 +43,13 @@ describe('BoardFilteredSearch', () => {
},
];
- const createComponent = ({ initialFilterParams = {} } = {}) => {
- store = new Vuex.Store({
- actions: {
- performSearch: jest.fn(),
- },
- });
-
+ const createComponent = ({ initialFilterParams = {}, props = {} } = {}) => {
+ store = createStore();
wrapper = shallowMount(BoardFilteredSearch, {
provide: { initialFilterParams, fullPath: '' },
store,
propsData: {
+ ...props,
tokens,
},
});
@@ -68,11 +65,7 @@ describe('BoardFilteredSearch', () => {
beforeEach(() => {
createComponent();
- jest.spyOn(store, 'dispatch');
- });
-
- it('renders FilteredSearch', () => {
- expect(findFilteredSearch().exists()).toBe(true);
+ jest.spyOn(store, 'dispatch').mockImplementation();
});
it('passes the correct tokens to FilteredSearch', () => {
@@ -99,6 +92,22 @@ describe('BoardFilteredSearch', () => {
});
});
+ describe('when eeFilters is not empty', () => {
+ it('passes the correct initialFilterValue to FitleredSearchBarRoot', () => {
+ createComponent({ props: { eeFilters: { labelName: ['label'] } } });
+
+ expect(findFilteredSearch().props('initialFilterValue')).toEqual([
+ { type: 'label_name', value: { data: 'label', operator: '=' } },
+ ]);
+ });
+ });
+
+ it('renders FilteredSearch', () => {
+ createComponent();
+
+ expect(findFilteredSearch().exists()).toBe(true);
+ });
+
describe('when searching', () => {
beforeEach(() => {
createComponent();
diff --git a/spec/frontend/commit/pipelines/pipelines_table_spec.js b/spec/frontend/commit/pipelines/pipelines_table_spec.js
index 17f7be9d1d7..51f5538b2a0 100644
--- a/spec/frontend/commit/pipelines/pipelines_table_spec.js
+++ b/spec/frontend/commit/pipelines/pipelines_table_spec.js
@@ -6,8 +6,13 @@ import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import Api from '~/api';
import PipelinesTable from '~/commit/pipelines/pipelines_table.vue';
+import { TOAST_MESSAGE } from '~/pipelines/constants';
import axios from '~/lib/utils/axios_utils';
+const $toast = {
+ show: jest.fn(),
+};
+
describe('Pipelines table in Commits and Merge requests', () => {
let wrapper;
let pipeline;
@@ -30,6 +35,9 @@ describe('Pipelines table in Commits and Merge requests', () => {
errorStateSvgPath: 'foo',
...props,
},
+ mocks: {
+ $toast,
+ },
}),
);
};
@@ -178,6 +186,12 @@ describe('Pipelines table in Commits and Merge requests', () => {
await waitForPromises();
});
+ it('displays a toast message during pipeline creation', async () => {
+ await findRunPipelineBtn().trigger('click');
+
+ expect($toast.show).toHaveBeenCalledWith(TOAST_MESSAGE);
+ });
+
it('on desktop, shows a loading button', async () => {
await findRunPipelineBtn().trigger('click');
diff --git a/spec/lib/gitlab/application_rate_limiter_spec.rb b/spec/lib/gitlab/application_rate_limiter_spec.rb
index e13475d1108..ab6ac024af7 100644
--- a/spec/lib/gitlab/application_rate_limiter_spec.rb
+++ b/spec/lib/gitlab/application_rate_limiter_spec.rb
@@ -3,53 +3,29 @@
require 'spec_helper'
RSpec.describe Gitlab::ApplicationRateLimiter do
- let(:redis) { double('redis') }
- let(:user) { create(:user) }
- let(:project) { create(:project) }
- let(:rate_limits) do
- {
- test_action: {
- threshold: 1,
- interval: 2.minutes
- }
- }
- end
-
- let(:key) { rate_limits.keys[0] }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project) }
subject { described_class }
- before do
- allow(Gitlab::Redis::RateLimiting).to receive(:with).and_yield(redis)
- allow(described_class).to receive(:rate_limits).and_return(rate_limits)
- end
-
- shared_examples 'action rate limiter' do
- it 'increases the throttle count and sets the expiration time' do
- expect(redis).to receive(:incr).with(cache_key).and_return(1)
- expect(redis).to receive(:expire).with(cache_key, 120)
-
- expect(subject.throttled?(key, scope: scope)).to be_falsy
- end
-
- it 'returns true if the key is throttled' do
- expect(redis).to receive(:incr).with(cache_key).and_return(2)
- expect(redis).not_to receive(:expire)
-
- expect(subject.throttled?(key, scope: scope)).to be_truthy
+ describe '.throttled?' do
+ let(:rate_limits) do
+ {
+ test_action: {
+ threshold: 1,
+ interval: 2.minutes
+ },
+ another_action: {
+ threshold: 2,
+ interval: 3.minutes
+ }
+ }
end
- context 'when throttling is disabled' do
- it 'returns false and does not set expiration time' do
- expect(redis).not_to receive(:incr)
- expect(redis).not_to receive(:expire)
-
- expect(subject.throttled?(key, scope: scope, threshold: 0)).to be_falsy
- end
+ before do
+ allow(described_class).to receive(:rate_limits).and_return(rate_limits)
end
- end
- describe '.throttled?' do
context 'when the key is invalid' do
context 'is provided as a Symbol' do
context 'but is not defined in the rate_limits Hash' do
@@ -80,27 +56,116 @@ RSpec.describe Gitlab::ApplicationRateLimiter do
end
end
- context 'when the key is an array of only ActiveRecord models' do
- let(:scope) { [user, project] }
+ context 'when rate_limiter_safe_increment is disabled' do
+ let(:redis) { double('redis') }
+ let(:key) { rate_limits.keys[0] }
+
+ before do
+ allow(Gitlab::Redis::RateLimiting).to receive(:with).and_yield(redis)
+
+ stub_feature_flags(rate_limiter_safe_increment: false)
+ end
+
+ shared_examples 'action rate limiter' do
+ it 'increases the throttle count and sets the expiration time' do
+ expect(redis).to receive(:incr).with(cache_key).and_return(1)
+ expect(redis).to receive(:expire).with(cache_key, 120)
+
+ expect(subject.throttled?(key, scope: scope)).to be_falsy
+ end
+
+ it 'returns true if the key is throttled' do
+ expect(redis).to receive(:incr).with(cache_key).and_return(2)
+ expect(redis).not_to receive(:expire)
+
+ expect(subject.throttled?(key, scope: scope)).to be_truthy
+ end
+
+ context 'when throttling is disabled' do
+ it 'returns false and does not set expiration time' do
+ expect(redis).not_to receive(:incr)
+ expect(redis).not_to receive(:expire)
+
+ expect(subject.throttled?(key, scope: scope, threshold: 0)).to be_falsy
+ end
+ end
+ end
+
+ context 'when the key is an array of only ActiveRecord models' do
+ let(:scope) { [user, project] }
- let(:cache_key) do
- "application_rate_limiter:test_action:user:#{user.id}:project:#{project.id}"
+ let(:cache_key) do
+ "application_rate_limiter:test_action:user:#{user.id}:project:#{project.id}"
+ end
+
+ it_behaves_like 'action rate limiter'
end
- it_behaves_like 'action rate limiter'
+ context 'when the key is a combination of ActiveRecord models and strings' do
+ let(:project) { create(:project, :public, :repository) }
+ let(:commit) { project.repository.commit }
+ let(:path) { 'app/controllers/groups_controller.rb' }
+ let(:scope) { [project, commit, path] }
+
+ let(:cache_key) do
+ "application_rate_limiter:test_action:project:#{project.id}:commit:#{commit.sha}:#{path}"
+ end
+
+ it_behaves_like 'action rate limiter'
+ end
end
- context 'when they key a combination of ActiveRecord models and strings' do
- let(:project) { create(:project, :public, :repository) }
- let(:commit) { project.repository.commit }
- let(:path) { 'app/controllers/groups_controller.rb' }
- let(:scope) { [project, commit, path] }
+ context 'when rate_limiter_safe_increment is enabled', :clean_gitlab_redis_rate_limiting do
+ before do
+ stub_feature_flags(rate_limiter_safe_increment: true)
+ end
+
+ shared_examples 'throttles based on key and scope' do
+ let(:start_time) { Time.current.beginning_of_hour }
+
+ it 'returns true when threshold is exceeded' do
+ travel_to(start_time) do
+ expect(subject.throttled?(:test_action, scope: scope)).to eq(false)
+ end
+
+ travel_to(start_time + 1.minute) do
+ expect(subject.throttled?(:test_action, scope: scope)).to eq(true)
- let(:cache_key) do
- "application_rate_limiter:test_action:project:#{project.id}:commit:#{commit.sha}:#{path}"
+ # Assert that it does not affect other actions or scope
+ expect(subject.throttled?(:another_action, scope: scope)).to eq(false)
+ expect(subject.throttled?(:test_action, scope: [user])).to eq(false)
+ end
+ end
+
+ it 'returns false when interval has elapsed' do
+ travel_to(start_time) do
+ expect(subject.throttled?(:test_action, scope: scope)).to eq(false)
+
+ # another_action has a threshold of 3 so we simulate 2 requests
+ expect(subject.throttled?(:another_action, scope: scope)).to eq(false)
+ expect(subject.throttled?(:another_action, scope: scope)).to eq(false)
+ end
+
+ travel_to(start_time + 2.minutes) do
+ expect(subject.throttled?(:test_action, scope: scope)).to eq(false)
+
+ # Assert that another_action has its own interval that hasn't elapsed
+ expect(subject.throttled?(:another_action, scope: scope)).to eq(true)
+ end
+ end
end
- it_behaves_like 'action rate limiter'
+ context 'when using ActiveRecord models as scope' do
+ let(:scope) { [user, project] }
+
+ it_behaves_like 'throttles based on key and scope'
+ end
+
+ context 'when using ActiveRecord models and strings as scope' do
+ let(:scope) { [project, 'app/controllers/groups_controller.rb'] }
+
+ it_behaves_like 'throttles based on key and scope'
+ end
end
end
@@ -134,7 +199,7 @@ RSpec.describe Gitlab::ApplicationRateLimiter do
end
context 'with a current_user' do
- let(:current_user) { create(:user) }
+ let(:current_user) { user }
let(:attributes) do
base_attributes.merge({
diff --git a/spec/requests/api/lint_spec.rb b/spec/requests/api/lint_spec.rb
index d7f22b9d619..ac30da99afe 100644
--- a/spec/requests/api/lint_spec.rb
+++ b/spec/requests/api/lint_spec.rb
@@ -102,6 +102,13 @@ RSpec.describe API::Lint do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to have_key('merged_yaml')
end
+
+ it 'outputs jobs' do
+ post api('/ci/lint', api_user), params: { content: yaml_content, include_jobs: true }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to have_key('jobs')
+ end
end
context 'with valid .gitlab-ci.yaml with warnings' do
@@ -136,6 +143,13 @@ RSpec.describe API::Lint do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to have_key('merged_yaml')
end
+
+ it 'outputs jobs' do
+ post api('/ci/lint', api_user), params: { content: yaml_content, include_jobs: true }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to have_key('jobs')
+ end
end
context 'with invalid configuration' do
@@ -156,6 +170,13 @@ RSpec.describe API::Lint do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to have_key('merged_yaml')
end
+
+ it 'outputs jobs' do
+ post api('/ci/lint', api_user), params: { content: yaml_content, include_jobs: true }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to have_key('jobs')
+ end
end
end
@@ -171,10 +192,11 @@ RSpec.describe API::Lint do
end
describe 'GET /projects/:id/ci/lint' do
- subject(:ci_lint) { get api("/projects/#{project.id}/ci/lint", api_user), params: { dry_run: dry_run } }
+ subject(:ci_lint) { get api("/projects/#{project.id}/ci/lint", api_user), params: { dry_run: dry_run, include_jobs: include_jobs } }
let(:project) { create(:project, :repository) }
let(:dry_run) { nil }
+ let(:include_jobs) { nil }
RSpec.shared_examples 'valid config with warnings' do
it 'passes validation with warnings' do
@@ -359,6 +381,30 @@ RSpec.describe API::Lint do
it_behaves_like 'valid config without warnings'
end
+ context 'when running with include jobs' do
+ let(:include_jobs) { true }
+
+ it_behaves_like 'valid config without warnings'
+
+ it 'returns jobs key' do
+ ci_lint
+
+ expect(json_response).to have_key('jobs')
+ end
+ end
+
+ context 'when running without include jobs' do
+ let(:include_jobs) { false }
+
+ it_behaves_like 'valid config without warnings'
+
+ it 'does not return jobs key' do
+ ci_lint
+
+ expect(json_response).not_to have_key('jobs')
+ end
+ end
+
context 'With warnings' do
let(:yaml_content) { { job: { script: 'ls', rules: [{ when: 'always' }] } }.to_yaml }
@@ -386,15 +432,40 @@ RSpec.describe API::Lint do
it_behaves_like 'invalid config'
end
+
+ context 'when running with include jobs' do
+ let(:include_jobs) { true }
+
+ it_behaves_like 'invalid config'
+
+ it 'returns jobs key' do
+ ci_lint
+
+ expect(json_response).to have_key('jobs')
+ end
+ end
+
+ context 'when running without include jobs' do
+ let(:include_jobs) { false }
+
+ it_behaves_like 'invalid config'
+
+ it 'does not return jobs key' do
+ ci_lint
+
+ expect(json_response).not_to have_key('jobs')
+ end
+ end
end
end
end
describe 'POST /projects/:id/ci/lint' do
- subject(:ci_lint) { post api("/projects/#{project.id}/ci/lint", api_user), params: { dry_run: dry_run, content: yaml_content } }
+ subject(:ci_lint) { post api("/projects/#{project.id}/ci/lint", api_user), params: { dry_run: dry_run, content: yaml_content, include_jobs: include_jobs } }
let(:project) { create(:project, :repository) }
let(:dry_run) { nil }
+ let(:include_jobs) { nil }
let_it_be(:api_user) { create(:user) }
@@ -562,6 +633,30 @@ RSpec.describe API::Lint do
it_behaves_like 'valid project config'
end
+
+ context 'when running with include jobs param' do
+ let(:include_jobs) { true }
+
+ it_behaves_like 'valid project config'
+
+ it 'contains jobs key' do
+ ci_lint
+
+ expect(json_response).to have_key('jobs')
+ end
+ end
+
+ context 'when running without include jobs param' do
+ let(:include_jobs) { false }
+
+ it_behaves_like 'valid project config'
+
+ it 'does not contain jobs key' do
+ ci_lint
+
+ expect(json_response).not_to have_key('jobs')
+ end
+ end
end
context 'with invalid .gitlab-ci.yml content' do
@@ -580,6 +675,30 @@ RSpec.describe API::Lint do
it_behaves_like 'invalid project config'
end
+
+ context 'when running with include jobs set to false' do
+ let(:include_jobs) { false }
+
+ it_behaves_like 'invalid project config'
+
+ it 'does not contain jobs key' do
+ ci_lint
+
+ expect(json_response).not_to have_key('jobs')
+ end
+ end
+
+ context 'when running with param include jobs' do
+ let(:include_jobs) { true }
+
+ it_behaves_like 'invalid project config'
+
+ it 'contains jobs key' do
+ ci_lint
+
+ expect(json_response).to have_key('jobs')
+ end
+ end
end
end
end