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>2020-03-10 21:08:17 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-03-10 21:08:17 +0300
commit219eead23f9feb5da9ec378c451d773aea2dfe61 (patch)
treeeec14421a05ca8eb79f3cc782abe99532bb6070c /spec
parent7c38405be9e79099f399aa429503ea7b463bbf5a (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/import/gitlab_projects_controller_spec.rb58
-rw-r--r--spec/features/issues/user_creates_issue_spec.rb2
-rw-r--r--spec/features/projects/tags/user_edits_tags_spec.rb2
-rw-r--r--spec/features/uploads/user_uploads_file_to_note_spec.rb2
-rw-r--r--spec/frontend/diffs/components/commit_item_spec.js4
-rw-r--r--spec/frontend/error_tracking/components/error_details_spec.js81
-rw-r--r--spec/helpers/markup_helper_spec.rb2
-rw-r--r--spec/lib/banzai/filter/repository_link_filter_spec.rb8
-rw-r--r--spec/models/concerns/bulk_insertable_associations_spec.rb8
-rw-r--r--spec/support/capybara.rb26
-rw-r--r--spec/support/helpers/test_env.rb51
-rw-r--r--spec/support/shared_examples/features/wiki_file_attachments_shared_examples.rb2
12 files changed, 213 insertions, 33 deletions
diff --git a/spec/controllers/import/gitlab_projects_controller_spec.rb b/spec/controllers/import/gitlab_projects_controller_spec.rb
index a9aaefda0f6..0b74e2bbcbf 100644
--- a/spec/controllers/import/gitlab_projects_controller_spec.rb
+++ b/spec/controllers/import/gitlab_projects_controller_spec.rb
@@ -39,4 +39,62 @@ describe Import::GitlabProjectsController do
it_behaves_like 'project import rate limiter'
end
+
+ describe 'POST authorize' do
+ let(:workhorse_token) { JWT.encode({ 'iss' => 'gitlab-workhorse' }, Gitlab::Workhorse.secret, 'HS256') }
+
+ before do
+ request.headers['GitLab-Workhorse'] = '1.0'
+ request.headers[Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER] = workhorse_token
+ end
+
+ it 'authorizes importing project with workhorse header' do
+ post :authorize, format: :json
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
+ end
+
+ it 'rejects requests that bypassed gitlab-workhorse or have invalid header' do
+ request.headers[Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER] = 'INVALID_HEADER'
+
+ expect { post :authorize, format: :json }.to raise_error(JWT::DecodeError)
+ end
+
+ context 'when using remote storage' do
+ context 'when direct upload is enabled' do
+ before do
+ stub_uploads_object_storage(ImportExportUploader, enabled: true, direct_upload: true)
+ end
+
+ it 'responds with status 200, location of file remote store and object details' do
+ post :authorize, format: :json
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
+ expect(json_response).not_to have_key('TempPath')
+ expect(json_response['RemoteObject']).to have_key('ID')
+ expect(json_response['RemoteObject']).to have_key('GetURL')
+ expect(json_response['RemoteObject']).to have_key('StoreURL')
+ expect(json_response['RemoteObject']).to have_key('DeleteURL')
+ expect(json_response['RemoteObject']).to have_key('MultipartUpload')
+ end
+ end
+
+ context 'when direct upload is disabled' do
+ before do
+ stub_uploads_object_storage(ImportExportUploader, enabled: true, direct_upload: false)
+ end
+
+ it 'handles as a local file' do
+ post :authorize, format: :json
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
+ expect(json_response['TempPath']).to eq(ImportExportUploader.workhorse_local_upload_path)
+ expect(json_response['RemoteObject']).to be_nil
+ end
+ end
+ end
+ end
end
diff --git a/spec/features/issues/user_creates_issue_spec.rb b/spec/features/issues/user_creates_issue_spec.rb
index b0a2a734877..efcaa8247df 100644
--- a/spec/features/issues/user_creates_issue_spec.rb
+++ b/spec/features/issues/user_creates_issue_spec.rb
@@ -156,7 +156,7 @@ describe "User creates issue" do
expect(page.find_field("issue_description").value).not_to match /\n\n$/
end
- it "cancels a file upload correctly" do
+ it "cancels a file upload correctly", :capybara_ignore_server_errors do
slow_requests do
dropzone_file([Rails.root.join('spec', 'fixtures', 'dk.png')], 0, false)
diff --git a/spec/features/projects/tags/user_edits_tags_spec.rb b/spec/features/projects/tags/user_edits_tags_spec.rb
index b1cb7685f63..6388875a619 100644
--- a/spec/features/projects/tags/user_edits_tags_spec.rb
+++ b/spec/features/projects/tags/user_edits_tags_spec.rb
@@ -68,7 +68,7 @@ describe 'Project > Tags', :js do
end
end
- it 'shows "Attaching a file" message on uploading 1 file', :js do
+ it 'shows "Attaching a file" message on uploading 1 file', :js, :capybara_ignore_server_errors do
slow_requests do
dropzone_file([Rails.root.join('spec', 'fixtures', 'dk.png')], 0, false)
diff --git a/spec/features/uploads/user_uploads_file_to_note_spec.rb b/spec/features/uploads/user_uploads_file_to_note_spec.rb
index 30b5cf267ae..570ecad41fa 100644
--- a/spec/features/uploads/user_uploads_file_to_note_spec.rb
+++ b/spec/features/uploads/user_uploads_file_to_note_spec.rb
@@ -22,7 +22,7 @@ describe 'User uploads file to note' do
end
end
- context 'uploading is in progress' do
+ context 'uploading is in progress', :capybara_ignore_server_errors do
it 'cancels uploading on clicking to "Cancel" button', :js do
slow_requests do
dropzone_file([Rails.root.join('spec', 'fixtures', 'dk.png')], 0, false)
diff --git a/spec/frontend/diffs/components/commit_item_spec.js b/spec/frontend/diffs/components/commit_item_spec.js
index ecc28c78fb7..61bab77964e 100644
--- a/spec/frontend/diffs/components/commit_item_spec.js
+++ b/spec/frontend/diffs/components/commit_item_spec.js
@@ -59,7 +59,9 @@ describe('diffs/components/commit_item', () => {
expect(titleElement.text()).toBe(commit.title_html);
});
- it('renders commit description', () => {
+ // https://gitlab.com/gitlab-org/gitlab/-/issues/209776
+ // eslint-disable-next-line jest/no-disabled-tests
+ it.skip('renders commit description', () => {
const descElement = getDescElement();
const descExpandElement = getDescExpandElement();
diff --git a/spec/frontend/error_tracking/components/error_details_spec.js b/spec/frontend/error_tracking/components/error_details_spec.js
index 2baec5f37fb..72b0466a1f0 100644
--- a/spec/frontend/error_tracking/components/error_details_spec.js
+++ b/spec/frontend/error_tracking/components/error_details_spec.js
@@ -1,6 +1,7 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
import { __ } from '~/locale';
+import createFlash from '~/flash';
import {
GlButton,
GlLoadingIcon,
@@ -18,6 +19,8 @@ import {
errorStatus,
} from '~/error_tracking/components/constants';
+jest.mock('~/flash');
+
const localVue = createLocalVue();
localVue.use(Vuex);
@@ -49,18 +52,6 @@ describe('ErrorDetails', () => {
csrfToken: 'fakeToken',
},
});
- wrapper.setData({
- error: {
- id: 'gid://gitlab/Gitlab::ErrorTracking::DetailedError/129381',
- sentryId: 129381,
- title: 'Issue title',
- externalUrl: 'http://sentry.gitlab.net/gitlab',
- firstSeen: '2017-05-26T13:32:48Z',
- lastSeen: '2018-05-26T13:32:48Z',
- count: 12,
- userCount: 2,
- },
- });
}
beforeEach(() => {
@@ -78,6 +69,7 @@ describe('ErrorDetails', () => {
const state = {
stacktraceData: {},
loadingStacktrace: true,
+ errorStatus: '',
};
store = new Vuex.Store({
@@ -99,6 +91,7 @@ describe('ErrorDetails', () => {
error: {
loading: true,
stopPolling: jest.fn(),
+ setOptions: jest.fn(),
},
},
},
@@ -123,10 +116,61 @@ describe('ErrorDetails', () => {
});
});
+ describe('sentry response timeout', () => {
+ const initTime = 300000;
+ const endTime = initTime + 10000;
+
+ beforeEach(() => {
+ mocks.$apollo.queries.error.loading = false;
+ jest.spyOn(Date, 'now').mockReturnValue(initTime);
+ mountComponent();
+ });
+
+ it('when before timeout, still shows loading', () => {
+ Date.now.mockReturnValue(endTime - 1);
+
+ wrapper.vm.onNoApolloResult();
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
+ expect(createFlash).not.toHaveBeenCalled();
+ expect(mocks.$apollo.queries.error.stopPolling).not.toHaveBeenCalled();
+ });
+ });
+
+ it('when timeout is hit and no apollo result, stops loading and shows flash', () => {
+ Date.now.mockReturnValue(endTime + 1);
+
+ wrapper.vm.onNoApolloResult();
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
+ expect(wrapper.find(GlLink).exists()).toBe(false);
+ expect(createFlash).toHaveBeenCalledWith(
+ 'Could not connect to Sentry. Refresh the page to try again.',
+ 'warning',
+ );
+ expect(mocks.$apollo.queries.error.stopPolling).toHaveBeenCalled();
+ });
+ });
+ });
+
describe('Error details', () => {
beforeEach(() => {
mocks.$apollo.queries.error.loading = false;
mountComponent();
+ wrapper.setData({
+ error: {
+ id: 'gid://gitlab/Gitlab::ErrorTracking::DetailedError/129381',
+ sentryId: 129381,
+ title: 'Issue title',
+ externalUrl: 'http://sentry.gitlab.net/gitlab',
+ firstSeen: '2017-05-26T13:32:48Z',
+ lastSeen: '2018-05-26T13:32:48Z',
+ count: 12,
+ userCount: 2,
+ },
+ });
});
it('should show Sentry error details without stacktrace', () => {
@@ -232,10 +276,6 @@ describe('ErrorDetails', () => {
});
describe('When a user clicks the create issue button', () => {
- beforeEach(() => {
- mountComponent();
- });
-
it('should send sentry_issue_identifier', () => {
const sentryErrorIdInput = findInput(
'issue[sentry_issue_attributes][sentry_issue_identifier]',
@@ -275,7 +315,8 @@ describe('ErrorDetails', () => {
describe('when error is unresolved', () => {
beforeEach(() => {
store.state.details.errorStatus = errorStatus.UNRESOLVED;
- mountComponent();
+
+ return wrapper.vm.$nextTick();
});
it('displays Ignore and Resolve buttons', () => {
@@ -301,7 +342,8 @@ describe('ErrorDetails', () => {
describe('when error is ignored', () => {
beforeEach(() => {
store.state.details.errorStatus = errorStatus.IGNORED;
- mountComponent();
+
+ return wrapper.vm.$nextTick();
});
it('displays Undo Ignore and Resolve buttons', () => {
@@ -327,7 +369,8 @@ describe('ErrorDetails', () => {
describe('when error is resolved', () => {
beforeEach(() => {
store.state.details.errorStatus = errorStatus.RESOLVED;
- mountComponent();
+
+ return wrapper.vm.$nextTick();
});
it('displays Ignore and Unresolve buttons', () => {
diff --git a/spec/helpers/markup_helper_spec.rb b/spec/helpers/markup_helper_spec.rb
index 96c8b557625..33347f20de8 100644
--- a/spec/helpers/markup_helper_spec.rb
+++ b/spec/helpers/markup_helper_spec.rb
@@ -114,7 +114,7 @@ describe MarkupHelper do
let(:requested_path) { nil }
it 'returns the link to the image path as a relative path' do
- expanded_path = "/#{project.full_path}/master/./#{image_file}"
+ expanded_path = "/#{project.full_path}/-/blob/master/./#{image_file}"
expect(subject.css('a')[0].attr('href')).to eq(expanded_path)
end
diff --git a/spec/lib/banzai/filter/repository_link_filter_spec.rb b/spec/lib/banzai/filter/repository_link_filter_spec.rb
index f093a5b0a79..460c76acd78 100644
--- a/spec/lib/banzai/filter/repository_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/repository_link_filter_spec.rb
@@ -145,7 +145,7 @@ describe Banzai::Filter::RepositoryLinkFilter do
it 'ignores ref if commit is passed' do
doc = filter(link('non/existent.file'), commit: project.commit('empty-branch') )
expect(doc.at_css('a')['href'])
- .to eq "/#{project_path}/#{ref}/non/existent.file" # non-existent files have no leading blob/raw/tree
+ .to eq "/#{project_path}/-/blob/#{ref}/non/existent.file"
end
shared_examples :valid_repository do
@@ -201,6 +201,12 @@ describe Banzai::Filter::RepositoryLinkFilter do
.to eq "/#{project_path}/-/blob/#{ref}/doc/api/README.md"
end
+ it 'rebuilds relative URL for a missing file in the repo' do
+ doc = filter(link('missing-file'))
+ expect(doc.at_css('a')['href'])
+ .to eq "/#{project_path}/-/blob/#{ref}/missing-file"
+ end
+
it 'rebuilds relative URL for a file in the repo with leading ./' do
doc = filter(link('./doc/api/README.md'))
expect(doc.at_css('a')['href'])
diff --git a/spec/models/concerns/bulk_insertable_associations_spec.rb b/spec/models/concerns/bulk_insertable_associations_spec.rb
index 9e584417697..6359b2c57ef 100644
--- a/spec/models/concerns/bulk_insertable_associations_spec.rb
+++ b/spec/models/concerns/bulk_insertable_associations_spec.rb
@@ -57,16 +57,12 @@ describe BulkInsertableAssociations do
end
end
- before do
- ActiveRecord::Base.connection.execute('TRUNCATE bulk_foos RESTART IDENTITY')
- end
-
context 'saving bulk insertable associations' do
let(:parent) { BulkParent.new(name: 'parent') }
context 'when items already have IDs' do
it 'stores nothing and raises an error' do
- build_items(parent: parent) { |n, item| item.id = 100 + n }
+ build_items(parent: parent) { |n, item| item.id = n }
expect { save_with_bulk_inserts(parent) }.to raise_error(BulkInsertSafe::PrimaryKeySetError)
expect(BulkFoo.count).to eq(0)
@@ -79,7 +75,7 @@ describe BulkInsertableAssociations do
expect(BulkFoo).to receive(:bulk_insert!).once.and_call_original
expect { save_with_bulk_inserts(parent) }.to change { BulkFoo.count }.from(0).to(items.size)
- expect(parent.bulk_foos.pluck(:id)).to contain_exactly(*(1..10))
+ expect(parent.bulk_foos.pluck(:id)).to all(be_a Integer)
end
end
diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb
index af179e81b08..ca4a81773aa 100644
--- a/spec/support/capybara.rb
+++ b/spec/support/capybara.rb
@@ -23,6 +23,18 @@ JS_CONSOLE_FILTER = Regexp.union([
CAPYBARA_WINDOW_SIZE = [1366, 768].freeze
+# Run Workhorse on the given host and port, proxying to Puma on a UNIX socket,
+# for a closer-to-production experience
+Capybara.register_server :puma_via_workhorse do |app, port, host, **options|
+ file = Tempfile.new
+ socket_path = file.path
+ file.close! # We just want the filename
+
+ TestEnv.with_workhorse(TestEnv.workhorse_dir, host, port, socket_path) do
+ Capybara.servers[:puma].call(app, nil, socket_path, **options)
+ end
+end
+
Capybara.register_driver :chrome do |app|
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
# This enables access to logs with `page.driver.manage.get_log(:browser)`
@@ -60,7 +72,7 @@ Capybara.register_driver :chrome do |app|
)
end
-Capybara.server = :puma
+Capybara.server = :puma_via_workhorse
Capybara.javascript_driver = :chrome
Capybara.default_max_wait_time = timeout
Capybara.ignore_hidden_elements = true
@@ -101,6 +113,18 @@ RSpec.configure do |config|
end
end
+ # The :capybara_ignore_server_errors metadata means unhandled exceptions raised
+ # by the application under test will not necessarily fail the server. This is
+ # useful when testing conditions that are expected to raise a 500 error in
+ # production; it should not be used on the happy path.
+ config.around(:each, :capybara_ignore_server_errors) do |example|
+ Capybara.raise_server_errors = false
+
+ example.run
+ ensure
+ Capybara.raise_server_errors = true
+ end
+
config.after(:example, :js) do |example|
# when a test fails, display any messages in the browser's console
# but fail don't add the message if the failure is a pending test that got
diff --git a/spec/support/helpers/test_env.rb b/spec/support/helpers/test_env.rb
index bd945fe6409..0320f966c37 100644
--- a/spec/support/helpers/test_env.rb
+++ b/spec/support/helpers/test_env.rb
@@ -104,6 +104,9 @@ module TestEnv
setup_gitaly
+ # Feature specs are run through Workhorse
+ setup_workhorse
+
# Create repository for FactoryBot.create(:project)
setup_factory_repo
@@ -218,6 +221,52 @@ module TestEnv
ENV.fetch('GITALY_REPO_URL', nil)
end
+ def setup_workhorse
+ install_workhorse_args = [workhorse_dir, workhorse_url].compact.join(',')
+
+ component_timed_setup(
+ 'GitLab Workhorse',
+ install_dir: workhorse_dir,
+ version: Gitlab::Workhorse.version,
+ task: "gitlab:workhorse:install[#{install_workhorse_args}]"
+ )
+ end
+
+ def workhorse_dir
+ @workhorse_path ||= File.join('tmp', 'tests', 'gitlab-workhorse')
+ end
+
+ def with_workhorse(workhorse_dir, host, port, upstream, &blk)
+ host = "[#{host}]" if host.include?(':')
+ listen_addr = [host, port].join(':')
+
+ workhorse_pid = spawn(
+ File.join(workhorse_dir, 'gitlab-workhorse'),
+ '-authSocket', upstream,
+ '-documentRoot', Rails.root.join('public').to_s,
+ '-listenAddr', listen_addr,
+ '-secretPath', Gitlab::Workhorse.secret_path.to_s,
+ # TODO: Needed for workhorse + redis features.
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/209245
+ #
+ # '-config', '',
+ '-logFile', 'log/workhorse-test.log',
+ '-logFormat', 'structured',
+ '-developmentMode' # to serve assets and rich error messages
+ )
+
+ begin
+ yield
+ ensure
+ Process.kill('TERM', workhorse_pid)
+ Process.wait(workhorse_pid)
+ end
+ end
+
+ def workhorse_url
+ ENV.fetch('GITLAB_WORKHORSE_URL', nil)
+ end
+
def setup_factory_repo
setup_repo(factory_repo_path, factory_repo_path_bare, factory_repo_name,
BRANCH_SHA)
@@ -347,6 +396,8 @@ module TestEnv
gitlab-test_bare
gitlab-test-fork
gitlab-test-fork_bare
+ gitlab-workhorse
+ gitlab_workhorse_secret
]
end
diff --git a/spec/support/shared_examples/features/wiki_file_attachments_shared_examples.rb b/spec/support/shared_examples/features/wiki_file_attachments_shared_examples.rb
index 867290fb2d6..d30e8241da0 100644
--- a/spec/support/shared_examples/features/wiki_file_attachments_shared_examples.rb
+++ b/spec/support/shared_examples/features/wiki_file_attachments_shared_examples.rb
@@ -20,7 +20,7 @@ RSpec.shared_examples 'wiki file attachments' do
end
end
- context 'uploading is in progress' do
+ context 'uploading is in progress', :capybara_ignore_server_errors do
it 'cancels uploading on clicking to "Cancel" button' do
slow_requests do
attach_with_dropzone