diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-02-25 12:09:10 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-02-25 12:09:10 +0300 |
commit | b98fa9ef3d5bead417ae2f325cb64637883264e9 (patch) | |
tree | 409f2002dd056f12d82d3959b3e6f012c4087123 /spec | |
parent | 7e3005967df23a957fe1998c8de4f50b412e69e7 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
18 files changed, 398 insertions, 135 deletions
diff --git a/spec/controllers/projects/snippets_controller_spec.rb b/spec/controllers/projects/snippets_controller_spec.rb index 4d1537ae787..900569af6c6 100644 --- a/spec/controllers/projects/snippets_controller_spec.rb +++ b/spec/controllers/projects/snippets_controller_spec.rb @@ -3,9 +3,11 @@ require 'spec_helper' describe Projects::SnippetsController do + include Gitlab::Routing + + let_it_be(:user) { create(:user) } + let_it_be(:user2) { create(:user) } let(:project) { create(:project_empty_repo, :public) } - let(:user) { create(:user) } - let(:user2) { create(:user) } before do project.add_maintainer(user) @@ -318,14 +320,45 @@ describe Projects::SnippetsController do end end + shared_examples 'successful response' do + it 'renders the snippet' do + subject + + expect(assigns(:snippet)).to eq(project_snippet) + expect(response).to have_gitlab_http_status(:ok) + end + + it 'renders the blob from the repository' do + subject + + expect(assigns(:blob)).to eq(project_snippet.blobs.first) + end + + context 'when feature flag version_snippets is disabled' do + before do + stub_feature_flags(version_snippets: false) + end + + it 'returns the snippet database content' do + subject + + blob = assigns(:blob) + + expect(blob.data).to eq(project_snippet.content) + end + end + end + %w[show raw].each do |action| describe "GET ##{action}" do context 'when the project snippet is private' do - let(:project_snippet) { create(:project_snippet, :private, project: project, author: user) } + let(:project_snippet) { create(:project_snippet, :private, :repository, project: project, author: user) } + + subject { get action, params: { namespace_id: project.namespace, project_id: project, id: project_snippet.to_param } } context 'when anonymous' do it 'responds with status 404' do - get action, params: { namespace_id: project.namespace, project_id: project, id: project_snippet.to_param } + subject expect(response).to have_gitlab_http_status(:not_found) end @@ -336,12 +369,7 @@ describe Projects::SnippetsController do sign_in(user) end - it 'renders the snippet' do - get action, params: { namespace_id: project.namespace, project_id: project, id: project_snippet.to_param } - - expect(assigns(:snippet)).to eq(project_snippet) - expect(response).to have_gitlab_http_status(:ok) - end + it_behaves_like 'successful response' end context 'when signed in as a project member' do @@ -349,19 +377,16 @@ describe Projects::SnippetsController do sign_in(user2) end - it 'renders the snippet' do - get action, params: { namespace_id: project.namespace, project_id: project, id: project_snippet.to_param } - - expect(assigns(:snippet)).to eq(project_snippet) - expect(response).to have_gitlab_http_status(:ok) - end + it_behaves_like 'successful response' end end context 'when the project snippet does not exist' do + subject { get action, params: { namespace_id: project.namespace, project_id: project, id: 42 } } + context 'when anonymous' do it 'responds with status 404' do - get action, params: { namespace_id: project.namespace, project_id: project, id: 42 } + subject expect(response).to have_gitlab_http_status(:not_found) end @@ -373,7 +398,7 @@ describe Projects::SnippetsController do end it 'responds with status 404' do - get action, params: { namespace_id: project.namespace, project_id: project, id: 42 } + subject expect(response).to have_gitlab_http_status(:not_found) end @@ -383,18 +408,20 @@ describe Projects::SnippetsController do end describe "GET #show for embeddable content" do - let(:project_snippet) { create(:project_snippet, snippet_permission, project: project, author: user) } + let(:project_snippet) { create(:project_snippet, :repository, snippet_permission, project: project, author: user) } before do sign_in(user) - - get :show, params: { namespace_id: project.namespace, project_id: project, id: project_snippet.to_param }, format: :js end + subject { get :show, params: { namespace_id: project.namespace, project_id: project, id: project_snippet.to_param }, format: :js } + context 'when snippet is private' do let(:snippet_permission) { :private } it 'responds with status 404' do + subject + expect(response).to have_gitlab_http_status(:not_found) end end @@ -402,10 +429,7 @@ describe Projects::SnippetsController do context 'when snippet is public' do let(:snippet_permission) { :public } - it 'responds with status 200' do - expect(assigns(:snippet)).to eq(project_snippet) - expect(response).to have_gitlab_http_status(:ok) - end + it_behaves_like 'successful response' end context 'when the project is private' do @@ -415,6 +439,8 @@ describe Projects::SnippetsController do let(:project_snippet) { create(:project_snippet, :public, project: project, author: user) } it 'responds with status 404' do + subject + expect(assigns(:snippet)).to eq(project_snippet) expect(response).to have_gitlab_http_status(:not_found) end @@ -423,14 +449,17 @@ describe Projects::SnippetsController do end describe 'GET #raw' do + let(:content) { "first line\r\nsecond line\r\nthird line" } + let(:formatted_content) { content.gsub(/\r\n/, "\n") } let(:project_snippet) do create( - :project_snippet, :public, + :project_snippet, :public, :repository, project: project, author: user, - content: "first line\r\nsecond line\r\nthird line" + content: content ) end + let(:blob) { project_snippet.blobs.first } context 'CRLF line ending' do let(:params) do @@ -441,16 +470,22 @@ describe Projects::SnippetsController do } end + before do + allow_next_instance_of(Blob) do |instance| + allow(instance).to receive(:data).and_return(content) + end + end + it 'returns LF line endings by default' do get :raw, params: params - expect(response.body).to eq("first line\nsecond line\nthird line") + expect(response.body).to eq(formatted_content) end it 'does not convert line endings when parameter present' do get :raw, params: params.merge(line_ending: :raw) - expect(response.body).to eq("first line\r\nsecond line\r\nthird line") + expect(response.body).to eq(content) end end end diff --git a/spec/controllers/snippets_controller_spec.rb b/spec/controllers/snippets_controller_spec.rb index daa560649f0..16947f4d3be 100644 --- a/spec/controllers/snippets_controller_spec.rb +++ b/spec/controllers/snippets_controller_spec.rb @@ -3,11 +3,9 @@ require 'spec_helper' describe SnippetsController do - let(:user) { create(:user) } + let_it_be(:user) { create(:user) } describe 'GET #index' do - let(:user) { create(:user) } - context 'when username parameter is present' do it_behaves_like 'paginated collection' do let(:collection) { Snippet.all } @@ -75,8 +73,37 @@ describe SnippetsController do end describe 'GET #show' do + shared_examples 'successful response' do + it 'renders the snippet' do + subject + + expect(assigns(:snippet)).to eq(personal_snippet) + expect(response).to have_gitlab_http_status(:ok) + end + + it 'renders the blob from the repository' do + subject + + expect(assigns(:blob)).to eq(personal_snippet.blobs.first) + end + + context 'when feature flag version_snippets is disabled' do + before do + stub_feature_flags(version_snippets: false) + end + + it 'returns the snippet database content' do + subject + + blob = assigns(:blob) + + expect(blob.data).to eq(personal_snippet.content) + end + end + end + context 'when the personal snippet is private' do - let(:personal_snippet) { create(:personal_snippet, :private, author: user) } + let_it_be(:personal_snippet) { create(:personal_snippet, :private, :repository, author: user) } context 'when signed in' do before do @@ -95,11 +122,8 @@ describe SnippetsController do end context 'when signed in user is the author' do - it 'renders the snippet' do - get :show, params: { id: personal_snippet.to_param } - - expect(assigns(:snippet)).to eq(personal_snippet) - expect(response).to have_gitlab_http_status(:ok) + it_behaves_like 'successful response' do + subject { get :show, params: { id: personal_snippet.to_param } } end it 'responds with status 404 when embeddable content is requested' do @@ -120,18 +144,15 @@ describe SnippetsController do end context 'when the personal snippet is internal' do - let(:personal_snippet) { create(:personal_snippet, :internal, author: user) } + let_it_be(:personal_snippet) { create(:personal_snippet, :internal, :repository, author: user) } context 'when signed in' do before do sign_in(user) end - it 'renders the snippet' do - get :show, params: { id: personal_snippet.to_param } - - expect(assigns(:snippet)).to eq(personal_snippet) - expect(response).to have_gitlab_http_status(:ok) + it_behaves_like 'successful response' do + subject { get :show, params: { id: personal_snippet.to_param } } end it 'responds with status 404 when embeddable content is requested' do @@ -151,18 +172,15 @@ describe SnippetsController do end context 'when the personal snippet is public' do - let(:personal_snippet) { create(:personal_snippet, :public, author: user) } + let_it_be(:personal_snippet) { create(:personal_snippet, :public, :repository, author: user) } context 'when signed in' do before do sign_in(user) end - it 'renders the snippet' do - get :show, params: { id: personal_snippet.to_param } - - expect(assigns(:snippet)).to eq(personal_snippet) - expect(response).to have_gitlab_http_status(:ok) + it_behaves_like 'successful response' do + subject { get :show, params: { id: personal_snippet.to_param } } end it 'responds with status 200 when embeddable content is requested' do @@ -481,8 +499,82 @@ describe SnippetsController do end describe "GET #raw" do + shared_examples '200 status' do + before do + subject + end + + it 'responds with status 200' do + expect(assigns(:snippet)).to eq(snippet) + expect(response).to have_gitlab_http_status(:ok) + end + + it 'has expected headers' do + expect(response.header['Content-Type']).to eq('text/plain; charset=utf-8') + expect(response.header['Content-Disposition']).to match(/inline/) + end + + it "sets #{Gitlab::Workhorse::DETECT_HEADER} header" do + expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq 'true' + end + end + + shared_examples 'CRLF line ending' do + let(:content) { "first line\r\nsecond line\r\nthird line" } + let(:formatted_content) { content.gsub(/\r\n/, "\n") } + let(:snippet) do + create(:personal_snippet, :public, :repository, author: user, content: content) + end + + before do + allow_next_instance_of(Blob) do |instance| + allow(instance).to receive(:data).and_return(content) + end + + subject + end + + it 'returns LF line endings by default' do + expect(response.body).to eq(formatted_content) + end + + context 'when parameter present' do + let(:params) { { id: snippet.to_param, line_ending: :raw } } + + it 'does not convert line endings when parameter present' do + expect(response.body).to eq(content) + end + end + end + + shared_examples 'successful response' do + it_behaves_like '200 status' + it_behaves_like 'CRLF line ending' + + it 'returns snippet first blob data' do + subject + + expect(response.body).to eq snippet.blobs.first.data + end + + context 'when feature flag version_snippets is disabled' do + before do + stub_feature_flags(version_snippets: false) + end + + it_behaves_like '200 status' + it_behaves_like 'CRLF line ending' + + it 'returns snippet database content' do + subject + + expect(response.body).to eq snippet.content + end + end + end + context 'when the personal snippet is private' do - let(:personal_snippet) { create(:personal_snippet, :private, author: user) } + let_it_be(:personal_snippet) { create(:personal_snippet, :private, :repository, author: user) } context 'when signed in' do before do @@ -501,24 +593,11 @@ describe SnippetsController do end context 'when signed in user is the author' do - before do - get :raw, params: { id: personal_snippet.to_param } - end + it_behaves_like 'successful response' do + let(:snippet) { personal_snippet } + let(:params) { { id: snippet.to_param } } - it 'responds with status 200' do - expect(assigns(:snippet)).to eq(personal_snippet) - expect(response).to have_gitlab_http_status(:ok) - end - - it 'has expected headers' do - expect(response.header['Content-Type']).to eq('text/plain; charset=utf-8') - - expect(response.header['Content-Disposition']).to match(/inline/) - end - - it "sets #{Gitlab::Workhorse::DETECT_HEADER} header" do - expect(response).to have_gitlab_http_status(:ok) - expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" + subject { get :raw, params: params } end end end @@ -533,18 +612,18 @@ describe SnippetsController do end context 'when the personal snippet is internal' do - let(:personal_snippet) { create(:personal_snippet, :internal, author: user) } + let_it_be(:personal_snippet) { create(:personal_snippet, :internal, :repository, author: user) } context 'when signed in' do before do sign_in(user) end - it 'responds with status 200' do - get :raw, params: { id: personal_snippet.to_param } + it_behaves_like 'successful response' do + let(:snippet) { personal_snippet } + let(:params) { { id: snippet.to_param } } - expect(assigns(:snippet)).to eq(personal_snippet) - expect(response).to have_gitlab_http_status(:ok) + subject { get :raw, params: params } end end @@ -558,36 +637,18 @@ describe SnippetsController do end context 'when the personal snippet is public' do - let(:personal_snippet) { create(:personal_snippet, :public, author: user) } + let_it_be(:personal_snippet) { create(:personal_snippet, :public, :repository, author: user) } context 'when signed in' do before do sign_in(user) end - it 'responds with status 200' do - get :raw, params: { id: personal_snippet.to_param } - - expect(assigns(:snippet)).to eq(personal_snippet) - expect(response).to have_gitlab_http_status(:ok) - end - - context 'CRLF line ending' do - let(:personal_snippet) do - create(:personal_snippet, :public, author: user, content: "first line\r\nsecond line\r\nthird line") - end + it_behaves_like 'successful response' do + let(:snippet) { personal_snippet } + let(:params) { { id: snippet.to_param } } - it 'returns LF line endings by default' do - get :raw, params: { id: personal_snippet.to_param } - - expect(response.body).to eq("first line\nsecond line\nthird line") - end - - it 'does not convert line endings when parameter present' do - get :raw, params: { id: personal_snippet.to_param, line_ending: :raw } - - expect(response.body).to eq("first line\r\nsecond line\r\nthird line") - end + subject { get :raw, params: params } end end diff --git a/spec/features/discussion_comments/snippets_spec.rb b/spec/features/discussion_comments/snippets_spec.rb index 0dccb7f5bb3..bf78a5261c5 100644 --- a/spec/features/discussion_comments/snippets_spec.rb +++ b/spec/features/discussion_comments/snippets_spec.rb @@ -3,9 +3,9 @@ require 'spec_helper' describe 'Thread Comments Snippet', :js do - let(:user) { create(:user) } - let(:project) { create(:project) } - let(:snippet) { create(:project_snippet, :private, project: project, author: user) } + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project) } + let_it_be(:snippet) { create(:project_snippet, :private, :repository, project: project, author: user) } before do stub_feature_flags(snippets_vue: false) diff --git a/spec/features/projects/snippets/create_snippet_spec.rb b/spec/features/projects/snippets/create_snippet_spec.rb index 5a425fb5d27..33113dce620 100644 --- a/spec/features/projects/snippets/create_snippet_spec.rb +++ b/spec/features/projects/snippets/create_snippet_spec.rb @@ -5,8 +5,8 @@ require 'spec_helper' describe 'Projects > Snippets > Create Snippet', :js do include DropzoneHelper - let(:user) { create(:user) } - let(:project) { create(:project, :public) } + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project, :public) } def description_field find('.js-description-input input,textarea') @@ -102,7 +102,7 @@ describe 'Projects > Snippets > Create Snippet', :js do end it 'shows a public snippet on the index page but not the New snippet button' do - snippet = create(:project_snippet, :public, project: project) + snippet = create(:project_snippet, :public, :repository, project: project) visit project_snippets_path(project) diff --git a/spec/features/projects/snippets/user_comments_on_snippet_spec.rb b/spec/features/projects/snippets/user_comments_on_snippet_spec.rb index 11707378996..9d11b55228b 100644 --- a/spec/features/projects/snippets/user_comments_on_snippet_spec.rb +++ b/spec/features/projects/snippets/user_comments_on_snippet_spec.rb @@ -3,9 +3,9 @@ require 'spec_helper' describe 'Projects > Snippets > User comments on a snippet', :js do - let(:project) { create(:project) } - let!(:snippet) { create(:project_snippet, project: project, author: user) } - let(:user) { create(:user) } + let_it_be(:project) { create(:project) } + let_it_be(:user) { create(:user) } + let_it_be(:snippet) { create(:project_snippet, :repository, project: project, author: user) } before do stub_feature_flags(snippets_vue: false) diff --git a/spec/features/reportable_note/snippets_spec.rb b/spec/features/reportable_note/snippets_spec.rb index bd37675315f..a4e609ce40c 100644 --- a/spec/features/reportable_note/snippets_spec.rb +++ b/spec/features/reportable_note/snippets_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' describe 'Reportable note on snippets', :js do - let(:user) { create(:user) } - let(:project) { create(:project) } + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project) } before do stub_feature_flags(snippets_vue: false) @@ -13,8 +13,8 @@ describe 'Reportable note on snippets', :js do end describe 'on project snippet' do - let(:snippet) { create(:project_snippet, :public, project: project, author: user) } - let!(:note) { create(:note_on_project_snippet, noteable: snippet, project: project) } + let_it_be(:snippet) { create(:project_snippet, :public, :repository, project: project, author: user) } + let_it_be(:note) { create(:note_on_project_snippet, noteable: snippet, project: project) } before do visit project_snippet_path(project, snippet) diff --git a/spec/frontend/fixtures/labels.rb b/spec/frontend/fixtures/labels.rb index e4d66dbcd0a..e5a0501ac03 100644 --- a/spec/frontend/fixtures/labels.rb +++ b/spec/frontend/fixtures/labels.rb @@ -41,6 +41,23 @@ describe 'Labels (JavaScript fixtures)' do end end + describe API::Helpers::LabelHelpers, type: :request do + include JavaScriptFixturesHelpers + include ApiHelpers + + let(:user) { create(:user) } + + before do + group.add_owner(user) + end + + it 'api/group_labels.json' do + get api("/groups/#{group.id}/labels", user) + + expect(response).to be_successful + end + end + describe Projects::LabelsController, '(JavaScript fixtures)', type: :controller do render_views diff --git a/spec/frontend/ide/lib/files_spec.js b/spec/frontend/ide/lib/files_spec.js index 34eb57ae0d3..2b15aef6454 100644 --- a/spec/frontend/ide/lib/files_spec.js +++ b/spec/frontend/ide/lib/files_spec.js @@ -1,7 +1,6 @@ import { viewerInformationForPath } from '~/vue_shared/components/content_viewer/lib/viewer_utils'; import { decorateFiles, splitParent } from '~/ide/lib/files'; import { decorateData } from '~/ide/stores/utils'; -import { escapeFileUrl } from '~/lib/utils/url_utility'; const TEST_BRANCH_ID = 'lorem-ipsum'; const TEST_PROJECT_ID = 10; @@ -22,7 +21,7 @@ const createEntries = paths => { id: path, name, path, - url: createUrl(`/${TEST_PROJECT_ID}/${type}/${TEST_BRANCH_ID}/-/${escapeFileUrl(path)}`), + url: createUrl(`/${TEST_PROJECT_ID}/${type}/${TEST_BRANCH_ID}/-/${path}`), type, previewMode, binary: (previewMode && previewMode.binary) || false, diff --git a/spec/frontend/ide/stores/mutations_spec.js b/spec/frontend/ide/stores/mutations_spec.js index 9fe75d596fb..d9ce59ad378 100644 --- a/spec/frontend/ide/stores/mutations_spec.js +++ b/spec/frontend/ide/stores/mutations_spec.js @@ -494,7 +494,7 @@ describe('Multi-file store mutations', () => { it('properly handles files with spaces in name', () => { const path = 'my fancy path'; const newPath = 'new path'; - const oldEntry = { ...file(path, path, 'blob'), url: `project/-/${encodeURI(path)}` }; + const oldEntry = { ...file(path, path, 'blob'), url: `project/-/${path}` }; localState.entries[path] = oldEntry; @@ -510,12 +510,12 @@ describe('Multi-file store mutations', () => { id: newPath, path: newPath, name: newPath, - url: `project/-/new%20path`, + url: `project/-/new path`, key: expect.stringMatching(newPath), prevId: path, prevName: path, prevPath: path, - prevUrl: `project/-/my%20fancy%20path`, + prevUrl: `project/-/my fancy path`, prevKey: oldEntry.key, prevParentPath: oldEntry.parentPath, }); diff --git a/spec/frontend/vue_shared/components/file_row_spec.js b/spec/frontend/vue_shared/components/file_row_spec.js index 420281e844c..b3ced84ddb5 100644 --- a/spec/frontend/vue_shared/components/file_row_spec.js +++ b/spec/frontend/vue_shared/components/file_row_spec.js @@ -1,13 +1,19 @@ import { file } from 'jest/ide/helpers'; import FileRow from '~/vue_shared/components/file_row.vue'; -import { mount } from '@vue/test-utils'; +import FileHeader from '~/vue_shared/components/file_row_header.vue'; +import { shallowMount } from '@vue/test-utils'; +import { nextTick } from 'vue'; +import { escapeFileUrl } from '~/lib/utils/url_utility'; describe('File row component', () => { let wrapper; - function createComponent(propsData) { - wrapper = mount(FileRow, { + function createComponent(propsData, $router = undefined) { + wrapper = shallowMount(FileRow, { propsData, + mocks: { + $router, + }, }); } @@ -61,7 +67,7 @@ describe('File row component', () => { }), }); - return wrapper.vm.$nextTick().then(() => { + return nextTick().then(() => { expect(wrapper.vm.scrollIntoView).toHaveBeenCalled(); }); }); @@ -85,6 +91,27 @@ describe('File row component', () => { level: 0, }); - expect(wrapper.element.classList).toContain('js-file-row-header'); + expect(wrapper.contains(FileHeader)).toBe(true); + }); + + it('matches the current route against encoded file URL', () => { + const fileName = 'with space'; + const rowFile = Object.assign({}, file(fileName), { + url: `/${fileName}`, + }); + const routerPath = `/project/${escapeFileUrl(fileName)}`; + createComponent( + { + file: rowFile, + level: 0, + }, + { + currentRoute: { + path: routerPath, + }, + }, + ); + + expect(wrapper.vm.hasUrlAtCurrentRoute()).toBe(true); }); }); diff --git a/spec/graphql/types/snippet_type_spec.rb b/spec/graphql/types/snippet_type_spec.rb index a06d372f668..97573f8c46b 100644 --- a/spec/graphql/types/snippet_type_spec.rb +++ b/spec/graphql/types/snippet_type_spec.rb @@ -16,4 +16,47 @@ describe GitlabSchema.types['Snippet'] do describe 'authorizations' do it { expect(described_class).to require_graphql_authorizations(:read_snippet) } end + + describe '#blob' do + let_it_be(:user) { create(:user) } + let(:query_blob) { subject.dig('data', 'snippets', 'edges')[0]['node']['blob'] } + let(:query) do + %( + { + snippets { + edges { + node { + blob { + name + path + } + } + } + } + } + ) + end + + subject { GitlabSchema.execute(query, context: { current_user: user }).as_json } + + context 'when snippet has repository' do + let!(:snippet) { create(:personal_snippet, :repository, :public, author: user) } + let(:blob) { snippet.blobs.first } + + it 'returns blob from the repository' do + expect(query_blob['name']).to eq blob.name + expect(query_blob['path']).to eq blob.path + end + end + + context 'when snippet does not have a repository' do + let!(:snippet) { create(:personal_snippet, :public, author: user) } + let(:blob) { snippet.blob } + + it 'returns SnippetBlob type' do + expect(query_blob['name']).to eq blob.name + expect(query_blob['path']).to eq blob.path + end + end + end end diff --git a/spec/lib/gitlab/quick_actions/extractor_spec.rb b/spec/lib/gitlab/quick_actions/extractor_spec.rb index 2536e4a372b..1843acb0cc0 100644 --- a/spec/lib/gitlab/quick_actions/extractor_spec.rb +++ b/spec/lib/gitlab/quick_actions/extractor_spec.rb @@ -216,6 +216,22 @@ describe Gitlab::QuickActions::Extractor do expect(msg).to eq "hello\nworld\nthis is great? SHRUG" end + it 'extracts and performs multiple substitution commands' do + msg = %(hello\nworld\n/reopen\n/shrug this is great?\n/shrug meh) + msg, commands = extractor.extract_commands(msg) + + expect(commands).to eq [['reopen'], ['shrug', 'this is great?'], %w(shrug meh)] + expect(msg).to eq "hello\nworld\nthis is great? SHRUG\nmeh SHRUG" + end + + it 'does not extract substitution command in inline code' do + msg = %(hello\nworld\n/reopen\n`/tableflip this is great`?) + msg, commands = extractor.extract_commands(msg) + + expect(commands).to eq [['reopen']] + expect(msg).to eq "hello\nworld\n`/tableflip this is great`?" + end + it 'extracts and performs substitution commands case insensitive' do msg = %(hello\nworld\n/reOpen\n/sHRuG this is great?) msg, commands = extractor.extract_commands(msg) diff --git a/spec/lib/gitlab/quick_actions/substitution_definition_spec.rb b/spec/lib/gitlab/quick_actions/substitution_definition_spec.rb index a09aca31cdc..d1a44e2feeb 100644 --- a/spec/lib/gitlab/quick_actions/substitution_definition_spec.rb +++ b/spec/lib/gitlab/quick_actions/substitution_definition_spec.rb @@ -7,6 +7,7 @@ describe Gitlab::QuickActions::SubstitutionDefinition do <<EOF Hello! Let's do this! /sub_name I like this stuff +/sub_name second substitution EOF end @@ -24,6 +25,7 @@ EOF expect(subject.perform_substitution(self, content)).to eq <<EOF Hello! Let's do this! I like this stuff foo +/sub_name second substitution EOF end end diff --git a/spec/models/concerns/blob_language_from_git_attributes_spec.rb b/spec/models/concerns/blob_language_from_git_attributes_spec.rb index 7f05073b08e..4cb8f042b1d 100644 --- a/spec/models/concerns/blob_language_from_git_attributes_spec.rb +++ b/spec/models/concerns/blob_language_from_git_attributes_spec.rb @@ -11,13 +11,20 @@ describe BlobLanguageFromGitAttributes do subject(:blob) { fake_blob(path: 'file.md') } it 'returns return value from gitattribute' do - expect(blob.project.repository).to receive(:gitattribute).with(blob.path, 'gitlab-language').and_return('erb?parent=json') + allow(blob.repository).to receive(:exists?).and_return(true) + expect(blob.repository).to receive(:gitattribute).with(blob.path, 'gitlab-language').and_return('erb?parent=json') expect(blob.language_from_gitattributes).to eq('erb?parent=json') end - it 'returns nil if project is absent' do - allow(blob).to receive(:project).and_return(nil) + it 'returns nil if repository is absent' do + allow(blob).to receive(:repository).and_return(nil) + + expect(blob.language_from_gitattributes).to eq(nil) + end + + it 'returns nil if repository does not exist' do + allow(blob.repository).to receive(:exists?).and_return(false) expect(blob.language_from_gitattributes).to eq(nil) end diff --git a/spec/presenters/snippet_blob_presenter_spec.rb b/spec/presenters/snippet_blob_presenter_spec.rb index fa10d1a7f30..89f4d65b47f 100644 --- a/spec/presenters/snippet_blob_presenter_spec.rb +++ b/spec/presenters/snippet_blob_presenter_spec.rb @@ -76,18 +76,18 @@ describe SnippetBlobPresenter do context 'with ProjectSnippet' do let!(:project) { create(:project) } - let(:snippet) { build(:project_snippet, project: project, id: 1) } + let(:snippet) { create(:project_snippet, project: project) } it 'returns the raw path' do - expect(subject).to eq "/#{snippet.project.full_path}/snippets/1/raw" + expect(subject).to eq "/#{snippet.project.full_path}/snippets/#{snippet.id}/raw" end end context 'with PersonalSnippet' do - let(:snippet) { build(:personal_snippet, id: 1) } + let(:snippet) { create(:personal_snippet) } it 'returns the raw path' do - expect(subject).to eq "/snippets/1/raw" + expect(subject).to eq "/snippets/#{snippet.id}/raw" end end end diff --git a/spec/presenters/snippet_presenter_spec.rb b/spec/presenters/snippet_presenter_spec.rb index e2117905559..591d86652b6 100644 --- a/spec/presenters/snippet_presenter_spec.rb +++ b/spec/presenters/snippet_presenter_spec.rb @@ -143,4 +143,24 @@ describe SnippetPresenter do expect(subject).to be_truthy end end + + describe '#blob' do + let(:snippet) { personal_snippet } + + subject { presenter.blob } + + context 'when snippet does not have a repository' do + it 'returns SnippetBlob' do + expect(subject).to eq snippet.blob + end + end + + context 'when snippet has a repository' do + let(:snippet) { create(:snippet, :repository, author: user) } + + it 'returns repository first blob' do + expect(subject).to eq snippet.blobs.first + end + end + end end diff --git a/spec/requests/api/issues/put_projects_issues_spec.rb b/spec/requests/api/issues/put_projects_issues_spec.rb index b4332c555e1..51037f701e1 100644 --- a/spec/requests/api/issues/put_projects_issues_spec.rb +++ b/spec/requests/api/issues/put_projects_issues_spec.rb @@ -4,8 +4,9 @@ require 'spec_helper' describe API::Issues do let_it_be(:user) { create(:user) } + let_it_be(:owner) { create(:owner) } let_it_be(:project, reload: true) do - create(:project, :public, creator_id: user.id, namespace: user.namespace) + create(:project, :public, creator_id: owner.id, namespace: owner.namespace) end let(:user2) { create(:user) } @@ -97,7 +98,7 @@ describe API::Issues do labels: 'label, label?, label&foo, ?, &' } - expect(response.status).to eq(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['labels']).to include 'label' expect(json_response['labels']).to include 'label?' expect(json_response['labels']).to include 'label&foo' @@ -112,7 +113,7 @@ describe API::Issues do labels: ['label', 'label?', 'label&foo, ?, &'] } - expect(response.status).to eq(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['labels']).to include 'label' expect(json_response['labels']).to include 'label?' expect(json_response['labels']).to include 'label&foo' @@ -349,7 +350,7 @@ describe API::Issues do it 'allows special label names' do put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { labels: 'label:foo, label-bar,label_bar,label/bar,label?bar,label&bar,?,&' } - expect(response.status).to eq(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['labels']).to include 'label:foo' expect(json_response['labels']).to include 'label-bar' expect(json_response['labels']).to include 'label_bar' @@ -363,7 +364,7 @@ describe API::Issues do it 'allows special label names with labels param as array' do put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { labels: ['label:foo', 'label-bar', 'label_bar', 'label/bar,label?bar,label&bar,?,&'] } - expect(response.status).to eq(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['labels']).to include 'label:foo' expect(json_response['labels']).to include 'label-bar' expect(json_response['labels']).to include 'label_bar' @@ -400,15 +401,49 @@ describe API::Issues do expect(response).to have_gitlab_http_status(:ok) expect(json_response['state']).to eq 'opened' end + end - context 'when an admin or owner makes the request' do + describe 'PUT /projects/:id/issues/:issue_iid to update updated_at param' do + context 'when reporter makes request' do it 'accepts the update date to be set' do update_time = 2.weeks.ago + put api("/projects/#{project.id}/issues/#{issue.iid}", user), - params: { labels: 'label3', state_event: 'close', updated_at: update_time } + params: { title: 'some new title', updated_at: update_time } + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response['title']).to include 'some new title' + expect(Time.parse(json_response['updated_at'])).not_to be_like_time(update_time) + end + end + + context 'when admin or owner makes the request' do + it 'not allow to set null for updated_at' do + put api("/projects/#{project.id}/issues/#{issue.iid}", owner), params: { updated_at: nil } + + expect(response).to have_gitlab_http_status(:bad_request) + end + + it 'not allow to set blank for updated_at' do + put api("/projects/#{project.id}/issues/#{issue.iid}", owner), params: { updated_at: '' } + + expect(response).to have_gitlab_http_status(:bad_request) + end + + it 'not allow to set invalid format for updated_at' do + put api("/projects/#{project.id}/issues/#{issue.iid}", owner), params: { updated_at: 'invalid-format' } + + expect(response).to have_gitlab_http_status(:bad_request) + end + + it 'accepts the update date to be set' do + update_time = 2.weeks.ago + put api("/projects/#{project.id}/issues/#{issue.iid}", owner), + params: { title: 'some new title', updated_at: update_time } expect(response).to have_gitlab_http_status(:ok) - expect(json_response['labels']).to include 'label3' + expect(json_response['title']).to include 'some new title' + expect(Time.parse(json_response['updated_at'])).to be_like_time(update_time) end end diff --git a/spec/support/shared_examples/lib/gitlab/import_export/project_tree_restorer_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/import_export/project_tree_restorer_shared_examples.rb index 4ef9a9930f7..968423176f1 100644 --- a/spec/support/shared_examples/lib/gitlab/import_export/project_tree_restorer_shared_examples.rb +++ b/spec/support/shared_examples/lib/gitlab/import_export/project_tree_restorer_shared_examples.rb @@ -30,7 +30,8 @@ RSpec.shared_examples 'restores project successfully' do |**results| expect(project.issues.size).to eq(results.fetch(:issues, 0)) end - it 'does not set params that are excluded from import_export settings' do + # This test is quarantined because the use of magic number 999 causes failure on CI + it 'does not set params that are excluded from import_export settings', quarantine: 'https://gitlab.com/gitlab-org/gitlab/issues/207932#note_293724442' do expect(project.import_type).to be_nil expect(project.creator_id).not_to eq 999 end |