summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-07-06 18:09:13 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-07-06 18:09:13 +0000
commit691ed55a053853e58f36635524d2615ac60e445e (patch)
tree923c7097cfe2c4beaee82d0b5227f443b760bbed /spec
parentce06ce825b9ef5204a84aaa37d0dfc7742da5037 (diff)
downloadgitlab-ce-691ed55a053853e58f36635524d2615ac60e445e.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/concerns/controller_with_feature_category/config_spec.rb53
-rw-r--r--spec/controllers/concerns/controller_with_feature_category_spec.rb66
-rw-r--r--spec/controllers/every_controller_spec.rb82
-rw-r--r--spec/controllers/import/bitbucket_server_controller_spec.rb20
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb4
-rw-r--r--spec/frontend/fixtures/branches.rb50
-rw-r--r--spec/frontend/fixtures/commit.rb49
-rw-r--r--spec/frontend/fixtures/tags.rb28
-rw-r--r--spec/frontend/pipelines/test_reports/stores/actions_spec.js51
-rw-r--r--spec/frontend/pipelines/test_reports/stores/mutations_spec.js18
-rw-r--r--spec/frontend/pipelines/test_reports/test_reports_spec.js11
-rw-r--r--spec/frontend/pipelines/test_reports/test_suite_table_spec.js6
-rw-r--r--spec/helpers/gitlab_routing_helper_spec.rb17
-rw-r--r--spec/lib/gitlab/class_attributes_spec.rb41
-rw-r--r--spec/lib/gitlab/danger/roulette_spec.rb8
-rw-r--r--spec/lib/gitlab/metrics/web_transaction_spec.rb37
-rw-r--r--spec/models/namespace/root_storage_statistics_spec.rb44
-rw-r--r--spec/presenters/snippet_blob_presenter_spec.rb38
-rw-r--r--spec/requests/api/import_bitbucket_server_spec.rb214
-rw-r--r--spec/services/import/bitbucket_server_service_spec.rb113
-rw-r--r--spec/support/shared_examples/snippet_blob_shared_examples.rb24
21 files changed, 627 insertions, 347 deletions
diff --git a/spec/controllers/concerns/controller_with_feature_category/config_spec.rb b/spec/controllers/concerns/controller_with_feature_category/config_spec.rb
deleted file mode 100644
index 9b8ffd2baab..00000000000
--- a/spec/controllers/concerns/controller_with_feature_category/config_spec.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-# frozen_string_literal: true
-
-require "fast_spec_helper"
-require "rspec-parameterized"
-require_relative "../../../../app/controllers/concerns/controller_with_feature_category/config"
-
-RSpec.describe ControllerWithFeatureCategory::Config do
- describe "#matches?" do
- using RSpec::Parameterized::TableSyntax
-
- where(:only_actions, :except_actions, :if_proc, :unless_proc, :test_action, :expected) do
- nil | nil | nil | nil | "action" | true
- [:included] | nil | nil | nil | "action" | false
- [:included] | nil | nil | nil | "included" | true
- nil | [:excluded] | nil | nil | "excluded" | false
- nil | nil | true | nil | "action" | true
- [:included] | nil | true | nil | "action" | false
- [:included] | nil | true | nil | "included" | true
- nil | [:excluded] | true | nil | "excluded" | false
- nil | nil | false | nil | "action" | false
- [:included] | nil | false | nil | "action" | false
- [:included] | nil | false | nil | "included" | false
- nil | [:excluded] | false | nil | "excluded" | false
- nil | nil | nil | true | "action" | false
- [:included] | nil | nil | true | "action" | false
- [:included] | nil | nil | true | "included" | false
- nil | [:excluded] | nil | true | "excluded" | false
- nil | nil | nil | false | "action" | true
- [:included] | nil | nil | false | "action" | false
- [:included] | nil | nil | false | "included" | true
- nil | [:excluded] | nil | false | "excluded" | false
- nil | nil | true | false | "action" | true
- [:included] | nil | true | false | "action" | false
- [:included] | nil | true | false | "included" | true
- nil | [:excluded] | true | false | "excluded" | false
- nil | nil | false | true | "action" | false
- [:included] | nil | false | true | "action" | false
- [:included] | nil | false | true | "included" | false
- nil | [:excluded] | false | true | "excluded" | false
- end
-
- with_them do
- let(:config) do
- if_to_proc = if_proc.nil? ? nil : -> (_) { if_proc }
- unless_to_proc = unless_proc.nil? ? nil : -> (_) { unless_proc }
-
- described_class.new(:category, only_actions, except_actions, if_to_proc, unless_to_proc)
- end
-
- specify { expect(config.matches?(test_action)).to be(expected) }
- end
- end
-end
diff --git a/spec/controllers/concerns/controller_with_feature_category_spec.rb b/spec/controllers/concerns/controller_with_feature_category_spec.rb
deleted file mode 100644
index e603a7d14c4..00000000000
--- a/spec/controllers/concerns/controller_with_feature_category_spec.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-# frozen_string_literal: true
-
-require 'fast_spec_helper'
-require_relative "../../../app/controllers/concerns/controller_with_feature_category"
-require_relative "../../../app/controllers/concerns/controller_with_feature_category/config"
-
-RSpec.describe ControllerWithFeatureCategory do
- describe ".feature_category_for_action" do
- let(:base_controller) do
- Class.new do
- include ControllerWithFeatureCategory
- end
- end
-
- let(:controller) do
- Class.new(base_controller) do
- feature_category :baz
- feature_category :foo, except: %w(update edit)
- feature_category :bar, only: %w(index show)
- feature_category :quux, only: %w(destroy)
- feature_category :quuz, only: %w(destroy)
- end
- end
-
- let(:subclass) do
- Class.new(controller) do
- feature_category :qux, only: %w(index)
- end
- end
-
- it "is nil when nothing was defined" do
- expect(base_controller.feature_category_for_action("hello")).to be_nil
- end
-
- it "returns the expected category", :aggregate_failures do
- expect(controller.feature_category_for_action("update")).to eq(:baz)
- expect(controller.feature_category_for_action("hello")).to eq(:foo)
- expect(controller.feature_category_for_action("index")).to eq(:bar)
- end
-
- it "returns the closest match for categories defined in subclasses" do
- expect(subclass.feature_category_for_action("index")).to eq(:qux)
- expect(subclass.feature_category_for_action("show")).to eq(:bar)
- end
-
- it "returns the last defined feature category when multiple match" do
- expect(controller.feature_category_for_action("destroy")).to eq(:quuz)
- end
-
- it "raises an error when using including and excluding the same action" do
- expect do
- Class.new(base_controller) do
- feature_category :hello, only: [:world], except: [:world]
- end
- end.to raise_error(%r(cannot configure both `only` and `except`))
- end
-
- it "raises an error when using unknown arguments" do
- expect do
- Class.new(base_controller) do
- feature_category :hello, hello: :world
- end
- end.to raise_error(%r(unknown arguments))
- end
- end
-end
diff --git a/spec/controllers/every_controller_spec.rb b/spec/controllers/every_controller_spec.rb
deleted file mode 100644
index 4785ee9ed8f..00000000000
--- a/spec/controllers/every_controller_spec.rb
+++ /dev/null
@@ -1,82 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe "Every controller" do
- context "feature categories" do
- let_it_be(:feature_categories) do
- YAML.load_file(Rails.root.join('config', 'feature_categories.yml')).map(&:to_sym).to_set
- end
-
- let_it_be(:controller_actions) do
- # This will return tuples of all controller actions defined in the routes
- # Only for controllers inheriting ApplicationController
- # Excluding controllers from gems (OAuth, Sidekiq)
- Rails.application.routes.routes
- .map { |route| route.required_defaults.presence }
- .compact
- .select { |route| route[:controller].present? && route[:action].present? }
- .map { |route| [constantize_controller(route[:controller]), route[:action]] }
- .reject { |route| route.first.nil? || !route.first.include?(ControllerWithFeatureCategory) }
- end
-
- let_it_be(:routes_without_category) do
- controller_actions.map do |controller, action|
- "#{controller}##{action}" unless controller.feature_category_for_action(action)
- end.compact
- end
-
- it "has feature categories" do
- pending("We'll work on defining categories for all controllers: "\
- "https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/463")
-
- expect(routes_without_category).to be_empty, "#{routes_without_category.first(10)} did not have a category"
- end
-
- it "completed controllers don't get new routes without categories" do
- completed_controllers = [Projects::MergeRequestsController].map(&:to_s)
-
- newly_introduced_missing_category = routes_without_category.select do |route|
- completed_controllers.any? { |controller| route.start_with?(controller) }
- end
-
- expect(newly_introduced_missing_category).to be_empty
- end
-
- it "recognizes the feature categories" do
- routes_unknown_category = controller_actions.map do |controller, action|
- used_category = controller.feature_category_for_action(action)
- next unless used_category
- next if used_category == :not_owned
-
- ["#{controller}##{action}", used_category] unless feature_categories.include?(used_category)
- end.compact
-
- expect(routes_unknown_category).to be_empty, "#{routes_unknown_category.first(10)} had an unknown category"
- end
-
- it "doesn't define or exclude categories on removed actions", :aggregate_failures do
- controller_actions.group_by(&:first).each do |controller, controller_action|
- existing_actions = controller_action.map(&:last)
- used_actions = actions_defined_in_feature_category_config(controller)
- non_existing_used_actions = used_actions - existing_actions
-
- expect(non_existing_used_actions).to be_empty,
- "#{controller} used #{non_existing_used_actions} to define feature category, but the route does not exist"
- end
- end
- end
-
- def constantize_controller(name)
- "#{name.camelize}Controller".constantize
- rescue NameError
- nil # some controllers, like the omniauth ones are dynamic
- end
-
- def actions_defined_in_feature_category_config(controller)
- feature_category_configs = controller.send(:class_attributes)[:feature_category_config]
- feature_category_configs.map do |config|
- Array(config.send(:only)) + Array(config.send(:except))
- end.flatten.uniq.map(&:to_s)
- end
-end
diff --git a/spec/controllers/import/bitbucket_server_controller_spec.rb b/spec/controllers/import/bitbucket_server_controller_spec.rb
index af471b478fa..3292a1ab39e 100644
--- a/spec/controllers/import/bitbucket_server_controller_spec.rb
+++ b/spec/controllers/import/bitbucket_server_controller_spec.rb
@@ -46,7 +46,7 @@ RSpec.describe Import::BitbucketServerController do
.to receive(:new).with(project_key, repo_slug, anything, project_name, user.namespace, user, anything)
.and_return(double(execute: project))
- post :create, params: { project: project_key, repository: repo_slug }, format: :json
+ post :create, params: { bitbucketServerProject: project_key, bitbucketServerRepo: repo_slug }, format: :json
expect(response).to have_gitlab_http_status(:ok)
end
@@ -59,20 +59,20 @@ RSpec.describe Import::BitbucketServerController do
.to receive(:new).with(project_key, repo_slug, anything, project_name, user.namespace, user, anything)
.and_return(double(execute: project))
- post :create, params: { project: project_key, repository: repo_slug, format: :json }
+ post :create, params: { bitbucketServerProject: project_key, bitbucketServerRepo: repo_slug, format: :json }
expect(response).to have_gitlab_http_status(:ok)
end
end
it 'returns an error when an invalid project key is used' do
- post :create, params: { project: 'some&project' }
+ post :create, params: { bitbucket_server_project: 'some&project' }
expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
it 'returns an error when an invalid repository slug is used' do
- post :create, params: { project: 'some-project', repository: 'try*this' }
+ post :create, params: { bitbucket_server_project: 'some-project', bitbucket_server_repo: 'try*this' }
expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
@@ -80,7 +80,7 @@ RSpec.describe Import::BitbucketServerController do
it 'returns an error when the project cannot be found' do
allow(client).to receive(:repo).with(project_key, repo_slug).and_return(nil)
- post :create, params: { project: project_key, repository: repo_slug }, format: :json
+ post :create, params: { bitbucket_server_project: project_key, bitbucket_server_repo: repo_slug }, format: :json
expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
@@ -90,15 +90,15 @@ RSpec.describe Import::BitbucketServerController do
.to receive(:new).with(project_key, repo_slug, anything, project_name, user.namespace, user, anything)
.and_return(double(execute: build(:project)))
- post :create, params: { project: project_key, repository: repo_slug }, format: :json
+ post :create, params: { bitbucket_server_project: project_key, bitbucket_server_repo: repo_slug }, format: :json
expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
it "returns an error when the server can't be contacted" do
- expect(client).to receive(:repo).with(project_key, repo_slug).and_raise(::BitbucketServer::Connection::ConnectionError)
+ allow(client).to receive(:repo).with(project_key, repo_slug).and_return([nil, nil])
- post :create, params: { project: project_key, repository: repo_slug }, format: :json
+ post :create, params: { bitbucket_server_project: project_key, bitbucket_server_repo: repo_slug }, format: :json
expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
@@ -123,7 +123,9 @@ RSpec.describe Import::BitbucketServerController do
end
it 'sets the session variables' do
- post :configure, params: { personal_access_token: token, bitbucket_username: username, bitbucket_server_url: url }
+ allow(controller).to receive(:allow_local_requests?).and_return(true)
+
+ post :configure, params: { personal_access_token: token, bitbucket_server_username: username, bitbucket_server_url: url }
expect(session[:bitbucket_server_url]).to eq(url)
expect(session[:bitbucket_server_username]).to eq(username)
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index c6a002ad18b..78024b2e93c 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -383,8 +383,8 @@ RSpec.describe 'Pipeline', :js do
context 'without test reports' do
let(:pipeline) { create(:ci_pipeline, project: project) }
- it 'shows nothing' do
- expect(page.find('.js-test-report-badge-counter', visible: :all).text).to eq("")
+ it 'shows zero' do
+ expect(page.find('.js-test-report-badge-counter', visible: :all).text).to eq("0")
end
end
end
diff --git a/spec/frontend/fixtures/branches.rb b/spec/frontend/fixtures/branches.rb
index 4667dfb69f8..df2d1af7ecf 100644
--- a/spec/frontend/fixtures/branches.rb
+++ b/spec/frontend/fixtures/branches.rb
@@ -2,33 +2,51 @@
require 'spec_helper'
-RSpec.describe Projects::BranchesController, '(JavaScript fixtures)', type: :controller do
+RSpec.describe 'Branches (JavaScript fixtures)' do
include JavaScriptFixturesHelpers
- let(:admin) { create(:admin) }
- let(:namespace) { create(:namespace, name: 'frontend-fixtures' )}
- let(:project) { create(:project, :repository, namespace: namespace, path: 'branches-project') }
-
- render_views
+ let_it_be(:admin) { create(:admin) }
+ let_it_be(:namespace) { create(:namespace, name: 'frontend-fixtures' )}
+ let_it_be(:project) { create(:project, :repository, namespace: namespace, path: 'branches-project') }
before(:all) do
clean_frontend_fixtures('branches/')
+ clean_frontend_fixtures('api/branches/')
end
- before do
- sign_in(admin)
+ after(:all) do
+ remove_repository(project)
end
- after do
- remove_repository(project)
+ describe Projects::BranchesController, '(JavaScript fixtures)', type: :controller do
+ render_views
+
+ before do
+ sign_in(admin)
+ end
+
+ it 'branches/new_branch.html' do
+ get :new, params: {
+ namespace_id: project.namespace.to_param,
+ project_id: project
+ }
+
+ expect(response).to be_successful
+ end
end
- it 'branches/new_branch.html' do
- get :new, params: {
- namespace_id: project.namespace.to_param,
- project_id: project
- }
+ describe API::Branches, '(JavaScript fixtures)', type: :request do
+ include ApiHelpers
+
+ it 'api/branches/branches.json' do
+ # The search query "ma" matches a few branch names in the test
+ # repository with a variety of different properties, including:
+ # - "master": default, protected
+ # - "markdown": non-default, protected
+ # - "many_files": non-default, not protected
+ get api("/projects/#{project.id}/repository/branches?search=ma", admin)
- expect(response).to be_successful
+ expect(response).to be_successful
+ end
end
end
diff --git a/spec/frontend/fixtures/commit.rb b/spec/frontend/fixtures/commit.rb
index c5c00afd4ca..9175a757b73 100644
--- a/spec/frontend/fixtures/commit.rb
+++ b/spec/frontend/fixtures/commit.rb
@@ -2,34 +2,55 @@
require 'spec_helper'
-RSpec.describe Projects::CommitController, '(JavaScript fixtures)', type: :controller do
+RSpec.describe 'Commit (JavaScript fixtures)' do
include JavaScriptFixturesHelpers
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
- let(:commit) { project.commit("master") }
-
- render_views
+ let_it_be(:commit) { project.commit("master") }
before(:all) do
clean_frontend_fixtures('commit/')
+ clean_frontend_fixtures('api/commits/')
+
+ project.add_maintainer(user)
end
before do
- project.add_maintainer(user)
- sign_in(user)
allow(SecureRandom).to receive(:hex).and_return('securerandomhex:thereisnospoon')
end
- it 'commit/show.html' do
- params = {
- namespace_id: project.namespace,
- project_id: project,
- id: commit.id
- }
+ after(:all) do
+ remove_repository(project)
+ end
+
+ describe Projects::CommitController, '(JavaScript fixtures)', type: :controller do
+ render_views
+
+ before do
+ sign_in(user)
+ end
+
+ it 'commit/show.html' do
+ params = {
+ namespace_id: project.namespace,
+ project_id: project,
+ id: commit.id
+ }
+
+ get :show, params: params
+
+ expect(response).to be_successful
+ end
+ end
+
+ describe API::Commits, '(JavaScript fixtures)', type: :request do
+ include ApiHelpers
- get :show, params: params
+ it 'api/commits/commit.json' do
+ get api("/projects/#{project.id}/repository/commits/#{commit.id}", user)
- expect(response).to be_successful
+ expect(response).to be_successful
+ end
end
end
diff --git a/spec/frontend/fixtures/tags.rb b/spec/frontend/fixtures/tags.rb
new file mode 100644
index 00000000000..b2a5429fac8
--- /dev/null
+++ b/spec/frontend/fixtures/tags.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Tags (JavaScript fixtures)' do
+ include JavaScriptFixturesHelpers
+
+ let_it_be(:admin) { create(:admin) }
+ let_it_be(:project) { create(:project, :repository, path: 'tags-project') }
+
+ before(:all) do
+ clean_frontend_fixtures('api/tags/')
+ end
+
+ after(:all) do
+ remove_repository(project)
+ end
+
+ describe API::Tags, '(JavaScript fixtures)', type: :request do
+ include ApiHelpers
+
+ it 'api/tags/tags.json' do
+ get api("/projects/#{project.id}/repository/tags", admin)
+
+ expect(response).to be_successful
+ end
+ end
+end
diff --git a/spec/frontend/pipelines/test_reports/stores/actions_spec.js b/spec/frontend/pipelines/test_reports/stores/actions_spec.js
index 56148361e0a..bd42db36645 100644
--- a/spec/frontend/pipelines/test_reports/stores/actions_spec.js
+++ b/spec/frontend/pipelines/test_reports/stores/actions_spec.js
@@ -14,12 +14,16 @@ describe('Actions TestReports Store', () => {
let state;
const testReports = getJSONFixture('pipelines/test_report.json');
+ const summary = { total_count: 1 };
- const endpoint = `${TEST_HOST}/test_reports.json`;
+ const fullReportEndpoint = `${TEST_HOST}/test_reports.json`;
+ const summaryEndpoint = `${TEST_HOST}/test_reports/summary.json`;
const defaultState = {
- endpoint,
+ fullReportEndpoint,
+ summaryEndpoint,
testReports: {},
selectedSuite: {},
+ summary: {},
};
beforeEach(() => {
@@ -31,14 +35,47 @@ describe('Actions TestReports Store', () => {
mock.restore();
});
- describe('fetch reports', () => {
+ describe('fetch report summary', () => {
beforeEach(() => {
- mock.onGet(`${TEST_HOST}/test_reports.json`).replyOnce(200, testReports, {});
+ mock.onGet(summaryEndpoint).replyOnce(200, summary, {});
});
it('sets testReports and shows tests', done => {
testAction(
- actions.fetchReports,
+ actions.fetchSummary,
+ null,
+ state,
+ [{ type: types.SET_SUMMARY, payload: summary }],
+ [],
+ done,
+ );
+ });
+
+ it('should create flash on API error', done => {
+ testAction(
+ actions.fetchSummary,
+ null,
+ {
+ summaryEndpoint: null,
+ },
+ [],
+ [],
+ () => {
+ expect(createFlash).toHaveBeenCalled();
+ done();
+ },
+ );
+ });
+ });
+
+ describe('fetch full report', () => {
+ beforeEach(() => {
+ mock.onGet(fullReportEndpoint).replyOnce(200, testReports, {});
+ });
+
+ it('sets testReports and shows tests', done => {
+ testAction(
+ actions.fetchFullReport,
null,
state,
[{ type: types.SET_REPORTS, payload: testReports }],
@@ -49,10 +86,10 @@ describe('Actions TestReports Store', () => {
it('should create flash on API error', done => {
testAction(
- actions.fetchReports,
+ actions.fetchFullReport,
null,
{
- endpoint: null,
+ fullReportEndpoint: null,
},
[],
[{ type: 'toggleLoading' }, { type: 'toggleLoading' }],
diff --git a/spec/frontend/pipelines/test_reports/stores/mutations_spec.js b/spec/frontend/pipelines/test_reports/stores/mutations_spec.js
index a0eb93c4e6b..cf54cacab60 100644
--- a/spec/frontend/pipelines/test_reports/stores/mutations_spec.js
+++ b/spec/frontend/pipelines/test_reports/stores/mutations_spec.js
@@ -18,15 +18,6 @@ describe('Mutations TestReports Store', () => {
mockState = defaultState;
});
- describe('set endpoint', () => {
- it('should set endpoint', () => {
- const expectedState = { ...mockState, endpoint: 'foo' };
- mutations[types.SET_ENDPOINT](mockState, 'foo');
-
- expect(mockState.endpoint).toEqual(expectedState.endpoint);
- });
- });
-
describe('set reports', () => {
it('should set testReports', () => {
const expectedState = { ...mockState, testReports };
@@ -45,6 +36,15 @@ describe('Mutations TestReports Store', () => {
});
});
+ describe('set summary', () => {
+ it('should set summary', () => {
+ const summary = { total_count: 1 };
+ mutations[types.SET_SUMMARY](mockState, summary);
+
+ expect(mockState.summary).toEqual(summary);
+ });
+ });
+
describe('toggle loading', () => {
it('should set to true', () => {
const expectedState = { ...mockState, isLoading: true };
diff --git a/spec/frontend/pipelines/test_reports/test_reports_spec.js b/spec/frontend/pipelines/test_reports/test_reports_spec.js
index cc86ba6d46d..dd2b7220d7c 100644
--- a/spec/frontend/pipelines/test_reports/test_reports_spec.js
+++ b/spec/frontend/pipelines/test_reports/test_reports_spec.js
@@ -1,9 +1,12 @@
import Vuex from 'vuex';
-import { shallowMount } from '@vue/test-utils';
+import { shallowMount, createLocalVue } from '@vue/test-utils';
import { getJSONFixture } from 'helpers/fixtures';
import TestReports from '~/pipelines/components/test_reports/test_reports.vue';
import * as actions from '~/pipelines/stores/test_reports/actions';
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
describe('Test reports app', () => {
let wrapper;
let store;
@@ -22,11 +25,15 @@ describe('Test reports app', () => {
testReports,
...state,
},
- actions,
+ actions: {
+ ...actions,
+ fetchSummary: () => {},
+ },
});
wrapper = shallowMount(TestReports, {
store,
+ localVue,
});
};
diff --git a/spec/frontend/pipelines/test_reports/test_suite_table_spec.js b/spec/frontend/pipelines/test_reports/test_suite_table_spec.js
index a5b093cf769..5d448bcb439 100644
--- a/spec/frontend/pipelines/test_reports/test_suite_table_spec.js
+++ b/spec/frontend/pipelines/test_reports/test_suite_table_spec.js
@@ -1,11 +1,14 @@
import Vuex from 'vuex';
-import { shallowMount } from '@vue/test-utils';
+import { shallowMount, createLocalVue } from '@vue/test-utils';
import { getJSONFixture } from 'helpers/fixtures';
import SuiteTable from '~/pipelines/components/test_reports/test_suite_table.vue';
import * as getters from '~/pipelines/stores/test_reports/getters';
import { TestStatus } from '~/pipelines/constants';
import skippedTestCases from './mock_data';
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
describe('Test reports suite table', () => {
let wrapper;
let store;
@@ -32,6 +35,7 @@ describe('Test reports suite table', () => {
wrapper = shallowMount(SuiteTable, {
store,
+ localVue,
});
};
diff --git a/spec/helpers/gitlab_routing_helper_spec.rb b/spec/helpers/gitlab_routing_helper_spec.rb
index 99c3fad660b..bd48fc7cee2 100644
--- a/spec/helpers/gitlab_routing_helper_spec.rb
+++ b/spec/helpers/gitlab_routing_helper_spec.rb
@@ -181,6 +181,23 @@ RSpec.describe GitlabRoutingHelper do
end
end
+ describe '#gitlab_raw_snippet_blob_path' do
+ let(:ref) { 'test-ref' }
+
+ it_behaves_like 'snippet blob raw path' do
+ subject { gitlab_raw_snippet_blob_path(blob, ref) }
+ end
+
+ context 'without a ref' do
+ let(:blob) { personal_snippet.blobs.first }
+ let(:ref) { blob.repository.root_ref }
+
+ it 'uses the root ref' do
+ expect(gitlab_raw_snippet_blob_path(blob)).to eq("/-/snippets/#{personal_snippet.id}/raw/#{ref}/#{blob.path}")
+ end
+ end
+ end
+
describe '#gitlab_raw_snippet_url' do
it 'returns the raw personal snippet url' do
expect(gitlab_raw_snippet_url(personal_snippet)).to eq("http://test.host/snippets/#{personal_snippet.id}/raw")
diff --git a/spec/lib/gitlab/class_attributes_spec.rb b/spec/lib/gitlab/class_attributes_spec.rb
deleted file mode 100644
index f8766f20495..00000000000
--- a/spec/lib/gitlab/class_attributes_spec.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-# frozen_string_literal: true
-require 'fast_spec_helper'
-
-RSpec.describe Gitlab::ClassAttributes do
- let(:klass) do
- Class.new do
- include Gitlab::ClassAttributes
-
- def self.get_attribute(name)
- get_class_attribute(name)
- end
-
- def self.set_attribute(name, value)
- class_attributes[name] = value
- end
- end
- end
-
- let(:subclass) { Class.new(klass) }
-
- describe ".get_class_attribute" do
- it "returns values set on the class" do
- klass.set_attribute(:foo, :bar)
-
- expect(klass.get_attribute(:foo)).to eq(:bar)
- end
-
- it "returns values set on a superclass" do
- klass.set_attribute(:foo, :bar)
-
- expect(subclass.get_attribute(:foo)).to eq(:bar)
- end
-
- it "returns values from the subclass over attributes from a superclass" do
- klass.set_attribute(:foo, :baz)
- subclass.set_attribute(:foo, :bar)
-
- expect(subclass.get_attribute(:foo)).to eq(:bar)
- end
- end
-end
diff --git a/spec/lib/gitlab/danger/roulette_spec.rb b/spec/lib/gitlab/danger/roulette_spec.rb
index 272666fceac..24f547a2e92 100644
--- a/spec/lib/gitlab/danger/roulette_spec.rb
+++ b/spec/lib/gitlab/danger/roulette_spec.rb
@@ -155,8 +155,8 @@ RSpec.describe Gitlab::Danger::Roulette do
context 'when change contains QA category' do
let(:categories) { [:qa] }
- it 'assigns QA reviewer and sets optional QA maintainer' do
- expect(spins).to contain_exactly(matching_spin(:qa, reviewer: software_engineer_in_test, optional: :maintainer))
+ it 'assigns QA reviewer' do
+ expect(spins).to contain_exactly(matching_spin(:qa, reviewer: software_engineer_in_test))
end
end
@@ -171,8 +171,8 @@ RSpec.describe Gitlab::Danger::Roulette do
context 'when change contains test category' do
let(:categories) { [:test] }
- it 'assigns corresponding SET and sets optional test maintainer' do
- expect(spins).to contain_exactly(matching_spin(:test, reviewer: software_engineer_in_test, optional: :maintainer))
+ it 'assigns corresponding SET' do
+ expect(spins).to contain_exactly(matching_spin(:test, reviewer: software_engineer_in_test))
end
end
end
diff --git a/spec/lib/gitlab/metrics/web_transaction_spec.rb b/spec/lib/gitlab/metrics/web_transaction_spec.rb
index 389a0a04904..6ceba186660 100644
--- a/spec/lib/gitlab/metrics/web_transaction_spec.rb
+++ b/spec/lib/gitlab/metrics/web_transaction_spec.rb
@@ -70,9 +70,6 @@ RSpec.describe Gitlab::Metrics::WebTransaction do
end
describe '#labels' do
- let(:request) { double(:request, format: double(:format, ref: :html)) }
- let(:controller_class) { double(:controller_class, name: 'TestController') }
-
context 'when request goes to Grape endpoint' do
before do
route = double(:route, request_method: 'GET', path: '/:version/projects/:id/archive(.:format)')
@@ -80,9 +77,8 @@ RSpec.describe Gitlab::Metrics::WebTransaction do
env['api.endpoint'] = endpoint
end
-
it 'provides labels with the method and path of the route in the grape endpoint' do
- expect(transaction.labels).to eq({ controller: 'Grape', action: 'GET /projects/:id/archive', feature_category: '' })
+ expect(transaction.labels).to eq({ controller: 'Grape', action: 'GET /projects/:id/archive' })
end
it 'does not provide labels if route infos are missing' do
@@ -96,21 +92,24 @@ RSpec.describe Gitlab::Metrics::WebTransaction do
end
context 'when request goes to ActionController' do
+ let(:request) { double(:request, format: double(:format, ref: :html)) }
+
before do
- controller = double(:controller, class: controller_class, action_name: 'show', request: request)
+ klass = double(:klass, name: 'TestController')
+ controller = double(:controller, class: klass, action_name: 'show', request: request)
env['action_controller.instance'] = controller
end
it 'tags a transaction with the name and action of a controller' do
- expect(transaction.labels).to eq({ controller: 'TestController', action: 'show', feature_category: '' })
+ expect(transaction.labels).to eq({ controller: 'TestController', action: 'show' })
end
context 'when the request content type is not :html' do
let(:request) { double(:request, format: double(:format, ref: :json)) }
it 'appends the mime type to the transaction action' do
- expect(transaction.labels).to eq({ controller: 'TestController', action: 'show.json', feature_category: '' })
+ expect(transaction.labels).to eq({ controller: 'TestController', action: 'show.json' })
end
end
@@ -118,31 +117,11 @@ RSpec.describe Gitlab::Metrics::WebTransaction do
let(:request) { double(:request, format: double(:format, ref: 'http://example.com')) }
it 'does not append the MIME type to the transaction action' do
- expect(transaction.labels).to eq({ controller: 'TestController', action: 'show', feature_category: '' })
- end
- end
-
- context 'when the feature category is known' do
- it 'includes it in the feature category label' do
- expect(controller_class).to receive(:feature_category_for_action).with('show').and_return(:source_code_management)
- expect(transaction.labels).to eq({ controller: 'TestController', action: 'show', feature_category: "source_code_management" })
+ expect(transaction.labels).to eq({ controller: 'TestController', action: 'show' })
end
end
end
- it 'returns the same labels for API and controller requests' do
- route = double(:route, request_method: 'GET', path: '/:version/projects/:id/archive(.:format)')
- endpoint = double(:endpoint, route: route)
- api_env = { 'api.endpoint' => endpoint }
- api_labels = described_class.new(api_env).labels
-
- controller = double(:controller, class: controller_class, action_name: 'show', request: request)
- controller_env = { 'action_controller.instance' => controller }
- controller_labels = described_class.new(controller_env).labels
-
- expect(api_labels.keys).to contain_exactly(*controller_labels.keys)
- end
-
it 'returns no labels when no route information is present in env' do
expect(transaction.labels).to eq({})
end
diff --git a/spec/models/namespace/root_storage_statistics_spec.rb b/spec/models/namespace/root_storage_statistics_spec.rb
index 9d516dc5ec2..ce6f875ee09 100644
--- a/spec/models/namespace/root_storage_statistics_spec.rb
+++ b/spec/models/namespace/root_storage_statistics_spec.rb
@@ -70,7 +70,16 @@ RSpec.describe Namespace::RootStorageStatistics, type: :model do
end
end
+ shared_examples 'does not include personal snippets' do
+ specify do
+ expect(root_storage_statistics).not_to receive(:from_personal_snippets)
+
+ root_storage_statistics.recalculate!
+ end
+ end
+
it_behaves_like 'data refresh'
+ it_behaves_like 'does not include personal snippets'
context 'with subgroups' do
let(:subgroup1) { create(:group, parent: namespace)}
@@ -80,12 +89,45 @@ RSpec.describe Namespace::RootStorageStatistics, type: :model do
let(:project2) { create(:project, namespace: subgroup2) }
it_behaves_like 'data refresh'
+ it_behaves_like 'does not include personal snippets'
end
context 'with a personal namespace' do
- let(:namespace) { create(:user).namespace }
+ let_it_be(:user) { create(:user) }
+ let(:namespace) { user.namespace }
it_behaves_like 'data refresh'
+
+ context 'when user has personal snippets' do
+ let(:total_project_snippets_size) { stat1.snippets_size + stat2.snippets_size }
+
+ it 'aggregates personal and project snippets size' do
+ # This is just a a snippet authored by other user
+ # to ensure we only pick snippets from the namespace
+ # user
+ create(:personal_snippet, :repository).statistics.refresh!
+
+ snippets = create_list(:personal_snippet, 3, :repository, author: user)
+ snippets.each { |s| s.statistics.refresh! }
+
+ total_personal_snippets_size = snippets.map { |s| s.statistics.repository_size }.sum
+
+ root_storage_statistics.recalculate!
+
+ expect(root_storage_statistics.snippets_size).to eq(total_personal_snippets_size + total_project_snippets_size)
+ end
+
+ context 'when personal snippets do not have statistics' do
+ it 'does not raise any error' do
+ snippets = create_list(:personal_snippet, 2, :repository, author: user)
+ snippets.last.statistics.refresh!
+
+ root_storage_statistics.recalculate!
+
+ expect(root_storage_statistics.snippets_size).to eq(total_project_snippets_size + snippets.last.statistics.repository_size)
+ end
+ end
+ end
end
end
end
diff --git a/spec/presenters/snippet_blob_presenter_spec.rb b/spec/presenters/snippet_blob_presenter_spec.rb
index 28c86468c78..7464c0ac15b 100644
--- a/spec/presenters/snippet_blob_presenter_spec.rb
+++ b/spec/presenters/snippet_blob_presenter_spec.rb
@@ -109,22 +109,38 @@ RSpec.describe SnippetBlobPresenter do
end
describe '#raw_path' do
- subject { described_class.new(snippet.blob).raw_path }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:personal_snippet) { create(:personal_snippet, :repository, author: user) }
+ let_it_be(:project_snippet) { create(:project_snippet, :repository, project: project, author: user) }
- context 'with ProjectSnippet' do
- let!(:project) { create(:project) }
- let(:snippet) { create(:project_snippet, project: project) }
+ before do
+ project.add_developer(user)
+ end
+
+ subject { described_class.new(snippet.blobs.first, current_user: user).raw_path }
- it 'returns the raw path' do
- expect(subject).to eq "/#{snippet.project.full_path}/snippets/#{snippet.id}/raw"
+ it_behaves_like 'snippet blob raw path'
+
+ context 'with snippet_multiple_files feature disabled' do
+ before do
+ stub_feature_flags(snippet_multiple_files: false)
end
- end
- context 'with PersonalSnippet' do
- let(:snippet) { create(:personal_snippet) }
+ context 'with ProjectSnippet' do
+ let(:snippet) { project_snippet }
- it 'returns the raw path' do
- expect(subject).to eq "/snippets/#{snippet.id}/raw"
+ it 'returns the raw path' do
+ expect(subject).to eq "/#{snippet.project.full_path}/snippets/#{snippet.id}/raw"
+ end
+ end
+
+ context 'with PersonalSnippet' do
+ let(:snippet) { personal_snippet }
+
+ it 'returns the raw path' do
+ expect(subject).to eq "/snippets/#{snippet.id}/raw"
+ end
end
end
end
diff --git a/spec/requests/api/import_bitbucket_server_spec.rb b/spec/requests/api/import_bitbucket_server_spec.rb
new file mode 100644
index 00000000000..be5afdfab61
--- /dev/null
+++ b/spec/requests/api/import_bitbucket_server_spec.rb
@@ -0,0 +1,214 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::ImportBitbucketServer do
+ let(:base_uri) { "https://test:7990" }
+ let(:user) { create(:user) }
+ let(:token) { "asdasd12345" }
+ let(:secret) { "sekrettt" }
+ let(:project_key) { 'TES' }
+ let(:repo_slug) { 'vim' }
+ let(:repo) { { name: 'vim' } }
+
+ describe "POST /import/bitbucket_server" do
+ context 'with no optional parameters' do
+ let_it_be(:project) { create(:project) }
+ let(:client) { double(BitbucketServer::Client) }
+
+ before do
+ Grape::Endpoint.before_each do |endpoint|
+ allow(endpoint).to receive(:client).and_return(client.as_null_object)
+ allow(client).to receive(:repo).with(project_key, repo_slug).and_return(double(name: repo_slug))
+ end
+ end
+
+ after do
+ Grape::Endpoint.before_each nil
+ end
+
+ it 'returns 201 response when the project is imported successfully' do
+ allow(Gitlab::BitbucketServerImport::ProjectCreator)
+ .to receive(:new).with(project_key, repo_slug, anything, repo_slug, user.namespace, user, anything)
+ .and_return(double(execute: project))
+
+ post api("/import/bitbucket_server", user), params: {
+ bitbucket_server_url: base_uri,
+ bitbucket_server_username: user,
+ personal_access_token: token,
+ bitbucket_server_project: project_key,
+ bitbucket_server_repo: repo_slug
+ }
+
+ expect(response).to have_gitlab_http_status(:created)
+ expect(json_response).to be_a Hash
+ expect(json_response['name']).to eq(project.name)
+ end
+ end
+
+ context 'with a new project name' do
+ let_it_be(:project) { create(:project, name: 'new-name') }
+ let(:client) { instance_double(BitbucketServer::Client) }
+
+ before do
+ Grape::Endpoint.before_each do |endpoint|
+ allow(endpoint).to receive(:client).and_return(client)
+ allow(client).to receive(:repo).with(project_key, repo_slug).and_return(double(name: repo_slug))
+ end
+ end
+
+ after do
+ Grape::Endpoint.before_each nil
+ end
+
+ it 'returns 201 response when the project is imported successfully with a new project name' do
+ allow(Gitlab::BitbucketServerImport::ProjectCreator)
+ .to receive(:new).with(project_key, repo_slug, anything, project.name, user.namespace, user, anything)
+ .and_return(double(execute: project))
+
+ post api("/import/bitbucket_server", user), params: {
+ bitbucket_server_url: base_uri,
+ bitbucket_server_username: user,
+ personal_access_token: token,
+ bitbucket_server_project: project_key,
+ bitbucket_server_repo: repo_slug,
+ new_name: 'new-name'
+ }
+
+ expect(response).to have_gitlab_http_status(:created)
+ expect(json_response).to be_a Hash
+ expect(json_response['name']).to eq('new-name')
+ end
+ end
+
+ context 'with an invalid URL' do
+ let_it_be(:project) { create(:project, name: 'new-name') }
+ let(:client) { instance_double(BitbucketServer::Client) }
+
+ before do
+ Grape::Endpoint.before_each do |endpoint|
+ allow(endpoint).to receive(:client).and_return(client)
+ allow(client).to receive(:repo).with(project_key, repo_slug).and_return(double(name: repo_slug))
+ end
+ end
+
+ after do
+ Grape::Endpoint.before_each nil
+ end
+
+ it 'returns 400 response due to a blcoked URL' do
+ allow(Gitlab::BitbucketServerImport::ProjectCreator)
+ .to receive(:new).with(project_key, repo_slug, anything, project.name, user.namespace, user, anything)
+ .and_return(double(execute: project))
+
+ allow(Gitlab::UrlBlocker)
+ .to receive(:blocked_url?)
+ .and_return(true)
+ post api("/import/bitbucket_server", user), params: {
+ bitbucket_server_url: base_uri,
+ bitbucket_server_username: user,
+ personal_access_token: token,
+ bitbucket_server_project: project_key,
+ bitbucket_server_repo: repo_slug,
+ new_name: 'new-name'
+ }
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
+ end
+
+ context 'with a new namespace' do
+ let(:bitbucket_client) { instance_double(BitbucketServer::Client) }
+
+ before do
+ Grape::Endpoint.before_each do |endpoint|
+ allow(endpoint).to receive(:client).and_return(bitbucket_client)
+ repo = double(name: repo_slug, full_path: "/other-namespace/#{repo_slug}")
+ allow(bitbucket_client).to receive(:repo).with(project_key, repo_slug).and_return(repo)
+ end
+ end
+
+ after do
+ Grape::Endpoint.before_each nil
+ end
+
+ it 'returns 201 response when the project is imported successfully to a new namespace' do
+ allow(Gitlab::BitbucketServerImport::ProjectCreator)
+ .to receive(:new).with(project_key, repo_slug, anything, repo_slug, an_instance_of(Group), user, anything)
+ .and_return(double(execute: create(:project, name: repo_slug)))
+
+ post api("/import/bitbucket_server", user), params: {
+ bitbucket_server_url: base_uri,
+ bitbucket_server_username: user,
+ personal_access_token: token,
+ bitbucket_server_project: project_key,
+ bitbucket_server_repo: repo_slug,
+ new_namespace: 'new-namespace'
+ }
+
+ expect(response).to have_gitlab_http_status(:created)
+ expect(json_response).to be_a Hash
+ expect(json_response['full_path']).not_to eq("/#{user.namespace}/#{repo_slug}")
+ end
+ end
+
+ context 'with a private inaccessible namespace' do
+ let(:bitbucket_client) { instance_double(BitbucketServer::Client) }
+ let(:project) { create(:project, import_type: 'bitbucket', creator_id: user.id, import_source: 'asd/vim', namespace: 'private-group/vim') }
+
+ before do
+ Grape::Endpoint.before_each do |endpoint|
+ allow(endpoint).to receive(:client).and_return(bitbucket_client)
+ repo = double(name: repo_slug, full_path: "/private-group/#{repo_slug}")
+ allow(bitbucket_client).to receive(:repo).with(project_key, repo_slug).and_return(repo)
+ end
+ end
+
+ after do
+ Grape::Endpoint.before_each nil
+ end
+
+ it 'returns 401 response when user can not create projects in the chosen namespace' do
+ allow(Gitlab::BitbucketServerImport::ProjectCreator)
+ .to receive(:new).with(project_key, repo_slug, anything, repo_slug, an_instance_of(Group), user, anything)
+ .and_return(double(execute: build(:project)))
+
+ other_namespace = create(:group, :private, name: 'private-group')
+
+ post api("/import/bitbucket_server", user), params: {
+ bitbucket_server_url: base_uri,
+ bitbucket_server_username: user,
+ personal_access_token: token,
+ bitbucket_server_project: project_key,
+ bitbucket_server_repo: repo_slug,
+ new_namespace: other_namespace.name
+ }
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
+ end
+
+ context 'with an inaccessible bitbucket server instance' do
+ let(:bitbucket_client) { instance_double(BitbucketServer::Client) }
+ let(:project) { create(:project, import_type: 'bitbucket', creator_id: user.id, import_source: 'asd/vim', namespace: 'private-group/vim') }
+
+ before do
+ Grape::Endpoint.before_each do |endpoint|
+ allow(endpoint).to receive(:client).and_return(bitbucket_client)
+ allow(bitbucket_client).to receive(:repo).with(project_key, repo_slug).and_raise(::BitbucketServer::Connection::ConnectionError)
+ end
+ end
+
+ it 'raises a connection error' do
+ post api("/import/bitbucket_server", user), params: {
+ bitbucket_server_url: base_uri,
+ bitbucket_server_username: user,
+ personal_access_token: token,
+ bitbucket_server_project: project_key,
+ bitbucket_server_repo: repo_slug,
+ new_namespace: 'new-namespace'
+ }
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
+ end
+ end
+end
diff --git a/spec/services/import/bitbucket_server_service_spec.rb b/spec/services/import/bitbucket_server_service_spec.rb
new file mode 100644
index 00000000000..c548e87b040
--- /dev/null
+++ b/spec/services/import/bitbucket_server_service_spec.rb
@@ -0,0 +1,113 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Import::BitbucketServerService do
+ let_it_be(:user) { create(:user) }
+ let(:base_uri) { "https://test:7990" }
+ let(:token) { "asdasd12345" }
+ let(:secret) { "sekrettt" }
+ let(:project_key) { 'TES' }
+ let(:repo_slug) { 'vim' }
+ let(:repo) do
+ {
+ name: 'vim',
+ description: 'test',
+ visibility_level: Gitlab::VisibilityLevel::PUBLIC,
+ browse_url: 'http://repo.com/repo/repo',
+ clone_url: 'http://repo.com/repo/repo.git'
+ }
+ end
+
+ let(:client) { double(BitbucketServer::Client) }
+
+ let(:credentials) { { base_uri: base_uri, user: user, password: token } }
+ let(:params) { { bitbucket_server_url: base_uri, bitbucket_server_username: user, personal_access_token: token, bitbucket_server_project: project_key, bitbucket_server_repo: repo_slug } }
+
+ subject { described_class.new(client, user, params) }
+
+ before do
+ allow(subject).to receive(:authorized?).and_return(true)
+ end
+
+ context 'when no repo is found' do
+ before do
+ allow(subject).to receive(:authorized?).and_return(true)
+ allow(client).to receive(:repo).and_return(nil)
+ end
+
+ it 'returns an error' do
+ result = subject.execute(credentials)
+
+ expect(result).to include(
+ message: "Project #{project_key}/#{repo_slug} could not be found",
+ status: :error,
+ http_status: :unprocessable_entity
+ )
+ end
+ end
+
+ context 'when user is unauthorized' do
+ before do
+ allow(subject).to receive(:authorized?).and_return(false)
+ end
+
+ it 'returns an error' do
+ result = subject.execute(credentials)
+
+ expect(result).to include(
+ message: "You don't have permissions to create this project",
+ status: :error,
+ http_status: :unauthorized
+ )
+ end
+ end
+
+ context 'verify url' do
+ shared_examples 'denies local request' do
+ before do
+ allow(client).to receive(:repo).with(project_key, repo_slug).and_return(double(repo))
+ end
+
+ it 'does not allow requests' do
+ result = subject.execute(credentials)
+ expect(result[:status]).to eq(:error)
+ expect(result[:message]).to include("Invalid URL:")
+ end
+ end
+
+ context 'when host is localhost' do
+ before do
+ allow(subject).to receive(:url).and_return('https://localhost:3000')
+ end
+
+ include_examples 'denies local request'
+ end
+
+ context 'when host is on local network' do
+ before do
+ allow(subject).to receive(:url).and_return('https://192.168.0.191')
+ end
+
+ include_examples 'denies local request'
+ end
+
+ context 'when host is ftp protocol' do
+ before do
+ allow(subject).to receive(:url).and_return('ftp://testing')
+ end
+
+ include_examples 'denies local request'
+ end
+ end
+
+ it 'raises an exception for unknown error causes' do
+ exception = StandardError.new('Not Implemented')
+
+ allow(client).to receive(:repo).and_raise(exception)
+
+ expect(Gitlab::Import::Logger).not_to receive(:error)
+
+ expect { subject.execute(credentials) }.to raise_error(exception)
+ end
+end
diff --git a/spec/support/shared_examples/snippet_blob_shared_examples.rb b/spec/support/shared_examples/snippet_blob_shared_examples.rb
new file mode 100644
index 00000000000..ba97688d017
--- /dev/null
+++ b/spec/support/shared_examples/snippet_blob_shared_examples.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.shared_examples 'snippet blob raw path' do
+ let(:blob) { snippet.blobs.first }
+ let(:ref) { blob.repository.root_ref }
+
+ context 'for PersonalSnippets' do
+ let(:snippet) { personal_snippet }
+
+ it 'returns the raw personal snippet blob path' do
+ expect(subject).to eq("/-/snippets/#{snippet.id}/raw/#{ref}/#{blob.path}")
+ end
+ end
+
+ context 'for ProjectSnippets' do
+ let(:snippet) { project_snippet }
+
+ it 'returns the raw project snippet blob path' do
+ expect(subject).to eq("/#{snippet.project.full_path}/-/snippets/#{snippet.id}/raw/#{ref}/#{blob.path}")
+ end
+ end
+end