diff options
Diffstat (limited to 'spec/services/wikis')
-rw-r--r-- | spec/services/wikis/create_attachment_service_spec.rb | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/spec/services/wikis/create_attachment_service_spec.rb b/spec/services/wikis/create_attachment_service_spec.rb new file mode 100644 index 00000000000..3f4da873ce4 --- /dev/null +++ b/spec/services/wikis/create_attachment_service_spec.rb @@ -0,0 +1,202 @@ +# frozen_string_literal: true +require 'spec_helper' + +describe Wikis::CreateAttachmentService do + let(:project) { create(:project, :wiki_repo) } + let(:user) { create(:user) } + let(:file_name) { 'filename.txt' } + let(:file_path_regex) { %r{#{described_class::ATTACHMENT_PATH}/\h{32}/#{file_name}} } + + let(:file_opts) do + { + file_name: file_name, + file_content: 'Content of attachment' + } + end + let(:opts) { file_opts } + + subject(:service) { described_class.new(project, user, opts) } + + before do + project.add_developer(user) + end + + describe 'initialization' do + context 'author commit info' do + it 'does not raise error if user is nil' do + service = described_class.new(project, nil, opts) + + expect(service.instance_variable_get(:@author_email)).to be_nil + expect(service.instance_variable_get(:@author_name)).to be_nil + end + + it 'fills file_path from the repository uploads folder' do + expect(service.instance_variable_get(:@file_path)).to match(file_path_regex) + end + + context 'when no author info provided' do + it 'fills author_email and author_name from current_user info' do + expect(service.instance_variable_get(:@author_email)).to eq user.email + expect(service.instance_variable_get(:@author_name)).to eq user.name + end + end + + context 'when author info provided' do + let(:author_email) { 'author_email' } + let(:author_name) { 'author_name' } + let(:opts) { file_opts.merge(author_email: author_email, author_name: author_name) } + + it 'fills author_email and author_name from params' do + expect(service.instance_variable_get(:@author_email)).to eq author_email + expect(service.instance_variable_get(:@author_name)).to eq author_name + end + end + end + + context 'commit message' do + context 'when no commit message provided' do + it 'sets a default commit message' do + expect(service.instance_variable_get(:@commit_message)).to eq "Upload attachment #{opts[:file_name]}" + end + end + + context 'when commit message provided' do + let(:commit_message) { 'whatever' } + let(:opts) { file_opts.merge(commit_message: commit_message) } + + it 'use the commit message from params' do + expect(service.instance_variable_get(:@commit_message)).to eq commit_message + end + end + end + + context 'branch name' do + context 'when no branch provided' do + it 'sets the branch from the wiki default_branch' do + expect(service.instance_variable_get(:@branch_name)).to eq project.wiki.default_branch + end + end + + context 'when branch provided' do + let(:branch_name) { 'whatever' } + let(:opts) { file_opts.merge(branch_name: branch_name) } + + it 'use the commit message from params' do + expect(service.instance_variable_get(:@branch_name)).to eq branch_name + end + end + end + end + + describe 'validations' do + context 'when file_name' do + context 'is not present' do + let(:file_name) { nil } + + it 'returns error' do + result = service.execute + + expect(result[:status]).to eq :error + expect(result[:message]).to eq 'The file name cannot be empty' + end + end + + context 'length' do + context 'is bigger than 255' do + let(:file_name) { "#{'0' * 256}.jpg" } + + it 'truncates file name' do + result = service.execute + + expect(result[:status]).to eq :success + expect(result[:result][:file_name].length).to eq 255 + expect(result[:result][:file_name]).to match(/0{251}\.jpg/) + end + end + + context 'is less or equal to 255 does not return error' do + let(:file_name) { '0' * 255 } + + it 'does not return error' do + result = service.execute + + expect(result[:status]).to eq :success + end + end + end + end + + context 'when user' do + shared_examples 'wiki attachment user validations' do + it 'returns error' do + result = described_class.new(project, user2, opts).execute + + expect(result[:status]).to eq :error + expect(result[:message]).to eq 'You are not allowed to push to the wiki' + end + end + + context 'does not have permission' do + let(:user2) { create(:user) } + + it_behaves_like 'wiki attachment user validations' + end + + context 'is nil' do + let(:user2) { nil } + + it_behaves_like 'wiki attachment user validations' + end + end + end + + describe '#execute' do + let(:wiki) { project.wiki } + subject(:service_execute) { service.execute[:result] } + + context 'creates branch if it does not exists' do + let(:branch_name) { 'new_branch' } + let(:opts) { file_opts.merge(branch_name: branch_name) } + + it do + expect(wiki.repository.branches).to be_empty + expect { service.execute }.to change { wiki.repository.branches.count }.by(1) + expect(wiki.repository.branches.first.name).to eq branch_name + end + end + + it 'adds file to the repository' do + expect(wiki.repository.ls_files('HEAD')).to be_empty + + service.execute + + files = wiki.repository.ls_files('HEAD') + expect(files.count).to eq 1 + expect(files.first).to match(file_path_regex) + end + + context 'returns' do + before do + allow(SecureRandom).to receive(:hex).and_return('fixed_hex') + + service_execute + end + + it 'returns the file name' do + expect(service_execute[:file_name]).to eq file_name + end + + it 'returns the path where file was stored' do + expect(service_execute[:file_path]).to eq 'uploads/fixed_hex/filename.txt' + end + + it 'returns the branch where the file was pushed' do + expect(service_execute[:branch]).to eq wiki.default_branch + end + + it 'returns the commit id' do + expect(service_execute[:commit]).not_to be_empty + end + end + end +end |