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:
authorPhil Hughes <me@iamphill.com>2017-06-07 12:26:48 +0300
committerPhil Hughes <me@iamphill.com>2017-06-07 12:26:48 +0300
commit563ea34692a18d82d9d1bc481002f19b8a407508 (patch)
tree6aa991974f140b42534e06abe18e4e5287afc49a /spec
parent7adddf49965a1808e7a3a0d1a70b08172c74a762 (diff)
parent2e311d9d1aac58bbd9c7d6c97c7cbcccf2715347 (diff)
Merge branch '12910-snippets-description' into 'master'
Support descriptions for snippets Closes #31894 See merge request !11071
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/projects/snippets_controller_spec.rb12
-rw-r--r--spec/controllers/snippets_controller_spec.rb40
-rw-r--r--spec/controllers/uploads_controller_spec.rb34
-rw-r--r--spec/factories/snippets.rb1
-rw-r--r--spec/features/projects/snippets/create_snippet_spec.rb86
-rw-r--r--spec/features/snippets/create_snippet_spec.rb73
-rw-r--r--spec/features/snippets/edit_snippet_spec.rb38
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml1
-rw-r--r--spec/requests/api/project_snippets_spec.rb28
-rw-r--r--spec/requests/api/snippets_spec.rb27
-rw-r--r--spec/uploaders/file_mover_spec.rb63
-rw-r--r--spec/uploaders/records_uploads_spec.rb9
12 files changed, 405 insertions, 7 deletions
diff --git a/spec/controllers/projects/snippets_controller_spec.rb b/spec/controllers/projects/snippets_controller_spec.rb
index 24a59caff4e..8c23c46798e 100644
--- a/spec/controllers/projects/snippets_controller_spec.rb
+++ b/spec/controllers/projects/snippets_controller_spec.rb
@@ -78,8 +78,18 @@ describe Projects::SnippetsController do
post :create, {
namespace_id: project.namespace.to_param,
project_id: project,
- project_snippet: { title: 'Title', content: 'Content' }.merge(snippet_params)
+ project_snippet: { title: 'Title', content: 'Content', description: 'Description' }.merge(snippet_params)
}.merge(additional_params)
+
+ Snippet.last
+ end
+
+ it 'creates the snippet correctly' do
+ snippet = create_snippet(project, visibility_level: Snippet::PRIVATE)
+
+ expect(snippet.title).to eq('Title')
+ expect(snippet.content).to eq('Content')
+ expect(snippet.description).to eq('Description')
end
context 'when the snippet is spam' do
diff --git a/spec/controllers/snippets_controller_spec.rb b/spec/controllers/snippets_controller_spec.rb
index 930415a4778..9073c39f562 100644
--- a/spec/controllers/snippets_controller_spec.rb
+++ b/spec/controllers/snippets_controller_spec.rb
@@ -171,12 +171,50 @@ describe SnippetsController do
sign_in(user)
post :create, {
- personal_snippet: { title: 'Title', content: 'Content' }.merge(snippet_params)
+ personal_snippet: { title: 'Title', content: 'Content', description: 'Description' }.merge(snippet_params)
}.merge(additional_params)
Snippet.last
end
+ it 'creates the snippet correctly' do
+ snippet = create_snippet(visibility_level: Snippet::PRIVATE)
+
+ expect(snippet.title).to eq('Title')
+ expect(snippet.content).to eq('Content')
+ expect(snippet.description).to eq('Description')
+ end
+
+ context 'when the snippet description contains a file' do
+ let(:picture_file) { '/temp/secret56/picture.jpg' }
+ let(:text_file) { '/temp/secret78/text.txt' }
+ let(:description) do
+ "Description with picture: ![picture](/uploads#{picture_file}) and "\
+ "text: [text.txt](/uploads#{text_file})"
+ end
+
+ before do
+ allow(FileUtils).to receive(:mkdir_p)
+ allow(FileUtils).to receive(:move)
+ end
+
+ subject { create_snippet({ description: description }, { files: [picture_file, text_file] }) }
+
+ it 'creates the snippet' do
+ expect { subject }.to change { Snippet.count }.by(1)
+ end
+
+ it 'stores the snippet description correctly' do
+ snippet = subject
+
+ expected_description = "Description with picture: "\
+ "![picture](/uploads/personal_snippet/#{snippet.id}/secret56/picture.jpg) and "\
+ "text: [text.txt](/uploads/personal_snippet/#{snippet.id}/secret78/text.txt)"
+
+ expect(snippet.description).to eq(expected_description)
+ end
+ end
+
context 'when the snippet is spam' do
before do
allow_any_instance_of(AkismetService).to receive(:is_spam?).and_return(true)
diff --git a/spec/controllers/uploads_controller_spec.rb b/spec/controllers/uploads_controller_spec.rb
index 8000c9dec61..01a0659479b 100644
--- a/spec/controllers/uploads_controller_spec.rb
+++ b/spec/controllers/uploads_controller_spec.rb
@@ -92,6 +92,40 @@ describe UploadsController do
end
end
end
+
+ context 'temporal with valid image' do
+ subject do
+ post :create, model: 'personal_snippet', file: jpg, format: :json
+ end
+
+ it 'returns a content with original filename, new link, and correct type.' do
+ subject
+
+ expect(response.body).to match '\"alt\":\"rails_sample\"'
+ expect(response.body).to match "\"url\":\"/uploads/temp"
+ end
+
+ it 'does not create an Upload record' do
+ expect { subject }.not_to change { Upload.count }
+ end
+ end
+
+ context 'temporal with valid non-image file' do
+ subject do
+ post :create, model: 'personal_snippet', file: txt, format: :json
+ end
+
+ it 'returns a content with original filename, new link, and correct type.' do
+ subject
+
+ expect(response.body).to match '\"alt\":\"doc_sample.txt\"'
+ expect(response.body).to match "\"url\":\"/uploads/temp"
+ end
+
+ it 'does not create an Upload record' do
+ expect { subject }.not_to change { Upload.count }
+ end
+ end
end
end
diff --git a/spec/factories/snippets.rb b/spec/factories/snippets.rb
index 18cb0f5de26..388f662e6e5 100644
--- a/spec/factories/snippets.rb
+++ b/spec/factories/snippets.rb
@@ -3,6 +3,7 @@ FactoryGirl.define do
author
title { generate(:title) }
content { generate(:title) }
+ description { generate(:title) }
file_name { generate(:filename) }
trait :public do
diff --git a/spec/features/projects/snippets/create_snippet_spec.rb b/spec/features/projects/snippets/create_snippet_spec.rb
new file mode 100644
index 00000000000..5ac1ca45c74
--- /dev/null
+++ b/spec/features/projects/snippets/create_snippet_spec.rb
@@ -0,0 +1,86 @@
+require 'rails_helper'
+
+feature 'Create Snippet', :js, feature: true do
+ include DropzoneHelper
+
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :repository, :public) }
+
+ def fill_form
+ fill_in 'project_snippet_title', with: 'My Snippet Title'
+ fill_in 'project_snippet_description', with: 'My Snippet **Description**'
+ page.within('.file-editor') do
+ find('.ace_editor').native.send_keys('Hello World!')
+ end
+ end
+
+ context 'when a user is authenticated' do
+ before do
+ project.team << [user, :master]
+ login_as(user)
+
+ visit namespace_project_snippets_path(project.namespace, project)
+
+ click_on('New snippet')
+ end
+
+ it 'creates a new snippet' do
+ fill_form
+ click_button('Create snippet')
+ wait_for_requests
+
+ expect(page).to have_content('My Snippet Title')
+ expect(page).to have_content('Hello World!')
+ page.within('.snippet-header .description') do
+ expect(page).to have_content('My Snippet Description')
+ expect(page).to have_selector('strong')
+ end
+ end
+
+ it 'uploads a file when dragging into textarea' do
+ fill_form
+ dropzone_file Rails.root.join('spec', 'fixtures', 'banana_sample.gif')
+
+ expect(page.find_field("project_snippet_description").value).to have_content('banana_sample')
+
+ click_button('Create snippet')
+ wait_for_requests
+
+ link = find('a.no-attachment-icon img[alt="banana_sample"]')['src']
+ expect(link).to match(%r{/#{Regexp.escape(project.full_path) }/uploads/\h{32}/banana_sample\.gif\z})
+ end
+
+ it 'creates a snippet when all reuiqred fields are filled in after validation failing' do
+ fill_in 'project_snippet_title', with: 'My Snippet Title'
+ click_button('Create snippet')
+
+ expect(page).to have_selector('#error_explanation')
+
+ fill_form
+ dropzone_file Rails.root.join('spec', 'fixtures', 'banana_sample.gif')
+
+ click_button('Create snippet')
+ wait_for_requests
+
+ expect(page).to have_content('My Snippet Title')
+ expect(page).to have_content('Hello World!')
+ page.within('.snippet-header .description') do
+ expect(page).to have_content('My Snippet Description')
+ expect(page).to have_selector('strong')
+ end
+ link = find('a.no-attachment-icon img[alt="banana_sample"]')['src']
+ expect(link).to match(%r{/#{Regexp.escape(project.full_path) }/uploads/\h{32}/banana_sample\.gif\z})
+ end
+ end
+
+ context 'when a user is not authenticated' do
+ it 'shows a public snippet on the index page but not the New snippet button' do
+ snippet = create(:project_snippet, :public, project: project)
+
+ visit namespace_project_snippets_path(project.namespace, project)
+
+ expect(page).to have_content(snippet.title)
+ expect(page).not_to have_content('New snippet')
+ end
+ end
+end
diff --git a/spec/features/snippets/create_snippet_spec.rb b/spec/features/snippets/create_snippet_spec.rb
index 31a2d4ae984..ddd31ede064 100644
--- a/spec/features/snippets/create_snippet_spec.rb
+++ b/spec/features/snippets/create_snippet_spec.rb
@@ -1,24 +1,93 @@
require 'rails_helper'
feature 'Create Snippet', :js, feature: true do
+ include DropzoneHelper
+
before do
login_as :user
visit new_snippet_path
end
- scenario 'Authenticated user creates a snippet' do
+ def fill_form
fill_in 'personal_snippet_title', with: 'My Snippet Title'
+ fill_in 'personal_snippet_description', with: 'My Snippet **Description**'
page.within('.file-editor') do
find('.ace_editor').native.send_keys 'Hello World!'
end
+ end
- click_button 'Create snippet'
+ scenario 'Authenticated user creates a snippet' do
+ fill_form
+
+ click_button('Create snippet')
wait_for_requests
expect(page).to have_content('My Snippet Title')
+ page.within('.snippet-header .description') do
+ expect(page).to have_content('My Snippet Description')
+ expect(page).to have_selector('strong')
+ end
expect(page).to have_content('Hello World!')
end
+ scenario 'previews a snippet with file' do
+ fill_in 'personal_snippet_description', with: 'My Snippet'
+ dropzone_file Rails.root.join('spec', 'fixtures', 'banana_sample.gif')
+ find('.js-md-preview-button').click
+
+ page.within('#new_personal_snippet .md-preview') do
+ expect(page).to have_content('My Snippet')
+
+ link = find('a.no-attachment-icon img[alt="banana_sample"]')['src']
+ expect(link).to match(%r{/uploads/temp/\h{32}/banana_sample\.gif\z})
+
+ visit(link)
+ expect(page.status_code).to eq(200)
+ end
+ end
+
+ scenario 'uploads a file when dragging into textarea' do
+ fill_form
+
+ dropzone_file Rails.root.join('spec', 'fixtures', 'banana_sample.gif')
+
+ expect(page.find_field("personal_snippet_description").value).to have_content('banana_sample')
+
+ click_button('Create snippet')
+ wait_for_requests
+
+ link = find('a.no-attachment-icon img[alt="banana_sample"]')['src']
+ expect(link).to match(%r{/uploads/personal_snippet/#{Snippet.last.id}/\h{32}/banana_sample\.gif\z})
+
+ visit(link)
+ expect(page.status_code).to eq(200)
+ end
+
+ scenario 'validation fails for the first time' do
+ fill_in 'personal_snippet_title', with: 'My Snippet Title'
+ click_button('Create snippet')
+
+ expect(page).to have_selector('#error_explanation')
+
+ fill_form
+ dropzone_file Rails.root.join('spec', 'fixtures', 'banana_sample.gif')
+
+ click_button('Create snippet')
+ wait_for_requests
+
+ expect(page).to have_content('My Snippet Title')
+ page.within('.snippet-header .description') do
+ expect(page).to have_content('My Snippet Description')
+ expect(page).to have_selector('strong')
+ end
+ expect(page).to have_content('Hello World!')
+ link = find('a.no-attachment-icon img[alt="banana_sample"]')['src']
+ expect(link).to match(%r{/uploads/personal_snippet/#{Snippet.last.id}/\h{32}/banana_sample\.gif\z})
+
+ visit(link)
+ expect(page.status_code).to eq(200)
+ end
+
scenario 'Authenticated user creates a snippet with + in filename' do
fill_in 'personal_snippet_title', with: 'My Snippet Title'
page.within('.file-editor') do
diff --git a/spec/features/snippets/edit_snippet_spec.rb b/spec/features/snippets/edit_snippet_spec.rb
new file mode 100644
index 00000000000..89ae593db88
--- /dev/null
+++ b/spec/features/snippets/edit_snippet_spec.rb
@@ -0,0 +1,38 @@
+require 'rails_helper'
+
+feature 'Edit Snippet', :js, feature: true do
+ include DropzoneHelper
+
+ let(:file_name) { 'test.rb' }
+ let(:content) { 'puts "test"' }
+
+ let(:user) { create(:user) }
+ let(:snippet) { create(:personal_snippet, :public, file_name: file_name, content: content, author: user) }
+
+ before do
+ login_as(user)
+
+ visit edit_snippet_path(snippet)
+ wait_for_requests
+ end
+
+ it 'updates the snippet' do
+ fill_in 'personal_snippet_title', with: 'New Snippet Title'
+
+ click_button('Save changes')
+ wait_for_requests
+
+ expect(page).to have_content('New Snippet Title')
+ end
+
+ it 'updates the snippet with files attached' do
+ dropzone_file Rails.root.join('spec', 'fixtures', 'banana_sample.gif')
+ expect(page.find_field("personal_snippet_description").value).to have_content('banana_sample')
+
+ click_button('Save changes')
+ wait_for_requests
+
+ link = find('a.no-attachment-icon img[alt="banana_sample"]')['src']
+ expect(link).to match(%r{/uploads/personal_snippet/#{snippet.id}/\h{32}/banana_sample\.gif\z})
+ end
+end
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index 54ce8051f30..3b6bba9ffdd 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -92,6 +92,7 @@ Milestone:
ProjectSnippet:
- id
- title
+- description
- content
- author_id
- project_id
diff --git a/spec/requests/api/project_snippets_spec.rb b/spec/requests/api/project_snippets_spec.rb
index 3ab1764f5c3..4d4631322b1 100644
--- a/spec/requests/api/project_snippets_spec.rb
+++ b/spec/requests/api/project_snippets_spec.rb
@@ -36,11 +36,34 @@ describe API::ProjectSnippets do
end
end
+ describe 'GET /projects/:project_id/snippets/:id' do
+ let(:user) { create(:user) }
+ let(:snippet) { create(:project_snippet, :public, project: project) }
+
+ it 'returns snippet json' do
+ get api("/projects/#{project.id}/snippets/#{snippet.id}", user)
+
+ expect(response).to have_http_status(200)
+
+ expect(json_response['title']).to eq(snippet.title)
+ expect(json_response['description']).to eq(snippet.description)
+ expect(json_response['file_name']).to eq(snippet.file_name)
+ end
+
+ it 'returns 404 for invalid snippet id' do
+ get api("/projects/#{project.id}/snippets/1234", user)
+
+ expect(response).to have_http_status(404)
+ expect(json_response['message']).to eq('404 Not found')
+ end
+ end
+
describe 'POST /projects/:project_id/snippets/' do
let(:params) do
{
title: 'Test Title',
file_name: 'test.rb',
+ description: 'test description',
code: 'puts "hello world"',
visibility: 'public'
}
@@ -52,6 +75,7 @@ describe API::ProjectSnippets do
expect(response).to have_http_status(201)
snippet = ProjectSnippet.find(json_response['id'])
expect(snippet.content).to eq(params[:code])
+ expect(snippet.description).to eq(params[:description])
expect(snippet.title).to eq(params[:title])
expect(snippet.file_name).to eq(params[:file_name])
expect(snippet.visibility_level).to eq(Snippet::PUBLIC)
@@ -106,12 +130,14 @@ describe API::ProjectSnippets do
it 'updates snippet' do
new_content = 'New content'
+ new_description = 'New description'
- put api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/", admin), code: new_content
+ put api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/", admin), code: new_content, description: new_description
expect(response).to have_http_status(200)
snippet.reload
expect(snippet.content).to eq(new_content)
+ expect(snippet.description).to eq(new_description)
end
it 'returns 404 for invalid snippet id' do
diff --git a/spec/requests/api/snippets_spec.rb b/spec/requests/api/snippets_spec.rb
index e429cddcf6a..8741cbd4e80 100644
--- a/spec/requests/api/snippets_spec.rb
+++ b/spec/requests/api/snippets_spec.rb
@@ -80,11 +80,33 @@ describe API::Snippets do
end
end
+ describe 'GET /snippets/:id' do
+ let(:snippet) { create(:personal_snippet, author: user) }
+
+ it 'returns snippet json' do
+ get api("/snippets/#{snippet.id}", user)
+
+ expect(response).to have_http_status(200)
+
+ expect(json_response['title']).to eq(snippet.title)
+ expect(json_response['description']).to eq(snippet.description)
+ expect(json_response['file_name']).to eq(snippet.file_name)
+ end
+
+ it 'returns 404 for invalid snippet id' do
+ get api("/snippets/1234", user)
+
+ expect(response).to have_http_status(404)
+ expect(json_response['message']).to eq('404 Not found')
+ end
+ end
+
describe 'POST /snippets/' do
let(:params) do
{
title: 'Test Title',
file_name: 'test.rb',
+ description: 'test description',
content: 'puts "hello world"',
visibility: 'public'
}
@@ -97,6 +119,7 @@ describe API::Snippets do
expect(response).to have_http_status(201)
expect(json_response['title']).to eq(params[:title])
+ expect(json_response['description']).to eq(params[:description])
expect(json_response['file_name']).to eq(params[:file_name])
end
@@ -150,12 +173,14 @@ describe API::Snippets do
it 'updates snippet' do
new_content = 'New content'
+ new_description = 'New description'
- put api("/snippets/#{snippet.id}", user), content: new_content
+ put api("/snippets/#{snippet.id}", user), content: new_content, description: new_description
expect(response).to have_http_status(200)
snippet.reload
expect(snippet.content).to eq(new_content)
+ expect(snippet.description).to eq(new_description)
end
it 'returns 404 for invalid snippet id' do
diff --git a/spec/uploaders/file_mover_spec.rb b/spec/uploaders/file_mover_spec.rb
new file mode 100644
index 00000000000..896cb410ed5
--- /dev/null
+++ b/spec/uploaders/file_mover_spec.rb
@@ -0,0 +1,63 @@
+require 'spec_helper'
+
+describe FileMover do
+ let(:filename) { 'banana_sample.gif' }
+ let(:file) { fixture_file_upload(Rails.root.join('spec', 'fixtures', filename)) }
+ let(:temp_description) do
+ 'test ![banana_sample](/uploads/temp/secret55/banana_sample.gif) same ![banana_sample]'\
+ '(/uploads/temp/secret55/banana_sample.gif)'
+ end
+ let(:temp_file_path) { File.join('secret55', filename).to_s }
+ let(:file_path) { File.join('uploads', 'personal_snippet', snippet.id.to_s, 'secret55', filename).to_s }
+
+ let(:snippet) { create(:personal_snippet, description: temp_description) }
+
+ subject { described_class.new(file_path, snippet).execute }
+
+ describe '#execute' do
+ before do
+ expect(FileUtils).to receive(:mkdir_p).with(a_string_including(File.dirname(file_path)))
+ expect(FileUtils).to receive(:move).with(a_string_including(temp_file_path), a_string_including(file_path))
+ allow_any_instance_of(CarrierWave::SanitizedFile).to receive(:exists?).and_return(true)
+ allow_any_instance_of(CarrierWave::SanitizedFile).to receive(:size).and_return(10)
+ end
+
+ context 'when move and field update successful' do
+ it 'updates the description correctly' do
+ subject
+
+ expect(snippet.reload.description)
+ .to eq(
+ "test ![banana_sample](/uploads/personal_snippet/#{snippet.id}/secret55/banana_sample.gif)"\
+ " same ![banana_sample](/uploads/personal_snippet/#{snippet.id}/secret55/banana_sample.gif)"
+ )
+ end
+
+ it 'creates a new update record' do
+ expect { subject }.to change { Upload.count }.by(1)
+ end
+ end
+
+ context 'when update_markdown fails' do
+ before do
+ expect(FileUtils).to receive(:move).with(a_string_including(file_path), a_string_including(temp_file_path))
+ end
+
+ subject { described_class.new(file_path, snippet, :non_existing_field).execute }
+
+ it 'does not update the description' do
+ subject
+
+ expect(snippet.reload.description)
+ .to eq(
+ "test ![banana_sample](/uploads/temp/secret55/banana_sample.gif)"\
+ " same ![banana_sample](/uploads/temp/secret55/banana_sample.gif)"
+ )
+ end
+
+ it 'does not create a new update record' do
+ expect { subject }.not_to change { Upload.count }
+ end
+ end
+ end
+end
diff --git a/spec/uploaders/records_uploads_spec.rb b/spec/uploaders/records_uploads_spec.rb
index 5c26e334a6e..bb32ee62ccb 100644
--- a/spec/uploaders/records_uploads_spec.rb
+++ b/spec/uploaders/records_uploads_spec.rb
@@ -1,7 +1,7 @@
require 'rails_helper'
describe RecordsUploads do
- let(:uploader) do
+ let!(:uploader) do
class RecordsUploadsExampleUploader < GitlabUploader
include RecordsUploads
@@ -57,6 +57,13 @@ describe RecordsUploads do
uploader.store!(upload_fixture('rails_sample.jpg'))
end
+ it 'does not create an Upload record if model is missing' do
+ expect_any_instance_of(RecordsUploadsExampleUploader).to receive(:model).and_return(nil)
+ expect(Upload).not_to receive(:record).with(uploader)
+
+ uploader.store!(upload_fixture('rails_sample.jpg'))
+ end
+
it 'it destroys Upload records at the same path before recording' do
existing = Upload.create!(
path: File.join('uploads', 'rails_sample.jpg'),