Enable RSpec/FilePath cop
- Ignore JS fixtures - Ignore qa directory - Rewrite concern specs to put concern name first
This commit is contained in:
parent
6dc424c949
commit
5069682d8e
36 changed files with 361 additions and 604 deletions
10
.rubocop.yml
10
.rubocop.yml
|
@ -983,10 +983,12 @@ RSpec/ExpectActual:
|
||||||
|
|
||||||
# Checks the file and folder naming of the spec file.
|
# Checks the file and folder naming of the spec file.
|
||||||
RSpec/FilePath:
|
RSpec/FilePath:
|
||||||
Enabled: false
|
Enabled: true
|
||||||
CustomTransform:
|
IgnoreMethods: true
|
||||||
RuboCop: rubocop
|
Exclude:
|
||||||
RSpec: rspec
|
- 'qa/**/*'
|
||||||
|
- 'spec/javascripts/fixtures/*'
|
||||||
|
- 'spec/requests/api/v3/*'
|
||||||
|
|
||||||
# Checks if there are focused specs.
|
# Checks if there are focused specs.
|
||||||
RSpec/Focus:
|
RSpec/Focus:
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe Projects::BlobController do
|
|
||||||
let(:project) { create(:project, :repository) }
|
|
||||||
let(:user) { create(:user) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
sign_in(user)
|
|
||||||
|
|
||||||
project.team << [user, :master]
|
|
||||||
|
|
||||||
allow(project).to receive(:branches).and_return(['master', 'foo/bar/baz'])
|
|
||||||
allow(project).to receive(:tags).and_return(['v1.0.0', 'v2.0.0'])
|
|
||||||
controller.instance_variable_set(:@project, project)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "GET show" do
|
|
||||||
render_views
|
|
||||||
|
|
||||||
before do
|
|
||||||
get(:show,
|
|
||||||
namespace_id: project.namespace,
|
|
||||||
project_id: project,
|
|
||||||
id: id)
|
|
||||||
end
|
|
||||||
|
|
||||||
context "valid branch, valid file" do
|
|
||||||
let(:id) { 'master/README.md' }
|
|
||||||
it { is_expected.to respond_with(:success) }
|
|
||||||
end
|
|
||||||
|
|
||||||
context "valid branch, invalid file" do
|
|
||||||
let(:id) { 'master/invalid-path.rb' }
|
|
||||||
it { is_expected.to respond_with(:not_found) }
|
|
||||||
end
|
|
||||||
|
|
||||||
context "invalid branch, valid file" do
|
|
||||||
let(:id) { 'invalid-branch/README.md' }
|
|
||||||
it { is_expected.to respond_with(:not_found) }
|
|
||||||
end
|
|
||||||
|
|
||||||
context "binary file" do
|
|
||||||
let(:id) { 'binary-encoding/encoding/binary-1.bin' }
|
|
||||||
it { is_expected.to respond_with(:success) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'GET show with tree path' do
|
|
||||||
render_views
|
|
||||||
|
|
||||||
before do
|
|
||||||
get(:show,
|
|
||||||
namespace_id: project.namespace,
|
|
||||||
project_id: project,
|
|
||||||
id: id)
|
|
||||||
controller.instance_variable_set(:@blob, nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'redirect to tree' do
|
|
||||||
let(:id) { 'markdown/doc' }
|
|
||||||
it 'redirects' do
|
|
||||||
expect(subject).
|
|
||||||
to redirect_to("/#{project.path_with_namespace}/tree/markdown/doc")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -3,6 +3,57 @@ require 'rails_helper'
|
||||||
describe Projects::BlobController do
|
describe Projects::BlobController do
|
||||||
let(:project) { create(:project, :public, :repository) }
|
let(:project) { create(:project, :public, :repository) }
|
||||||
|
|
||||||
|
describe "GET show" do
|
||||||
|
render_views
|
||||||
|
|
||||||
|
context 'with file path' do
|
||||||
|
before do
|
||||||
|
get(:show,
|
||||||
|
namespace_id: project.namespace,
|
||||||
|
project_id: project,
|
||||||
|
id: id)
|
||||||
|
end
|
||||||
|
|
||||||
|
context "valid branch, valid file" do
|
||||||
|
let(:id) { 'master/README.md' }
|
||||||
|
it { is_expected.to respond_with(:success) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context "valid branch, invalid file" do
|
||||||
|
let(:id) { 'master/invalid-path.rb' }
|
||||||
|
it { is_expected.to respond_with(:not_found) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context "invalid branch, valid file" do
|
||||||
|
let(:id) { 'invalid-branch/README.md' }
|
||||||
|
it { is_expected.to respond_with(:not_found) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context "binary file" do
|
||||||
|
let(:id) { 'binary-encoding/encoding/binary-1.bin' }
|
||||||
|
it { is_expected.to respond_with(:success) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with tree path' do
|
||||||
|
before do
|
||||||
|
get(:show,
|
||||||
|
namespace_id: project.namespace,
|
||||||
|
project_id: project,
|
||||||
|
id: id)
|
||||||
|
controller.instance_variable_set(:@blob, nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'redirect to tree' do
|
||||||
|
let(:id) { 'markdown/doc' }
|
||||||
|
it 'redirects' do
|
||||||
|
expect(subject).
|
||||||
|
to redirect_to("/#{project.path_with_namespace}/tree/markdown/doc")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe 'GET diff' do
|
describe 'GET diff' do
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe Gitlab::Checks::ChangeAccess, lib: true do
|
describe Gitlab::Checks::ForcePush, lib: true do
|
||||||
let(:project) { create(:project, :repository) }
|
let(:project) { create(:project, :repository) }
|
||||||
|
|
||||||
context "exit code checking" do
|
context "exit code checking" do
|
||||||
it "does not raise a runtime error if the `popen` call to git returns a zero exit code" do
|
it "does not raise a runtime error if the `popen` call to git returns a zero exit code" do
|
||||||
allow(Gitlab::Popen).to receive(:popen).and_return(['normal output', 0])
|
allow(Gitlab::Popen).to receive(:popen).and_return(['normal output', 0])
|
||||||
|
|
||||||
expect { Gitlab::Checks::ForcePush.force_push?(project, 'oldrev', 'newrev') }.not_to raise_error
|
expect { described_class.force_push?(project, 'oldrev', 'newrev') }.not_to raise_error
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises a runtime error if the `popen` call to git returns a non-zero exit code" do
|
it "raises a runtime error if the `popen` call to git returns a non-zero exit code" do
|
||||||
allow(Gitlab::Popen).to receive(:popen).and_return(['error', 1])
|
allow(Gitlab::Popen).to receive(:popen).and_return(['error', 1])
|
||||||
|
|
||||||
expect { Gitlab::Checks::ForcePush.force_push?(project, 'oldrev', 'newrev') }.to raise_error(RuntimeError)
|
expect { described_class.force_push?(project, 'oldrev', 'newrev') }.to raise_error(RuntimeError)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,119 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe Gitlab::UrlBuilder, lib: true do
|
|
||||||
describe '.build' do
|
|
||||||
context 'when passing a Commit' do
|
|
||||||
it 'returns a proper URL' do
|
|
||||||
commit = build_stubbed(:commit)
|
|
||||||
|
|
||||||
url = described_class.build(commit)
|
|
||||||
|
|
||||||
expect(url).to eq "#{Settings.gitlab['url']}/#{commit.project.path_with_namespace}/commit/#{commit.id}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when passing an Issue' do
|
|
||||||
it 'returns a proper URL' do
|
|
||||||
issue = build_stubbed(:issue, iid: 42)
|
|
||||||
|
|
||||||
url = described_class.build(issue)
|
|
||||||
|
|
||||||
expect(url).to eq "#{Settings.gitlab['url']}/#{issue.project.path_with_namespace}/issues/#{issue.iid}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when passing a MergeRequest' do
|
|
||||||
it 'returns a proper URL' do
|
|
||||||
merge_request = build_stubbed(:merge_request, iid: 42)
|
|
||||||
|
|
||||||
url = described_class.build(merge_request)
|
|
||||||
|
|
||||||
expect(url).to eq "#{Settings.gitlab['url']}/#{merge_request.project.path_with_namespace}/merge_requests/#{merge_request.iid}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when passing a Note' do
|
|
||||||
context 'on a Commit' do
|
|
||||||
it 'returns a proper URL' do
|
|
||||||
note = build_stubbed(:note_on_commit)
|
|
||||||
|
|
||||||
url = described_class.build(note)
|
|
||||||
|
|
||||||
expect(url).to eq "#{Settings.gitlab['url']}/#{note.project.path_with_namespace}/commit/#{note.commit_id}#note_#{note.id}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'on a Commit Diff' do
|
|
||||||
it 'returns a proper URL' do
|
|
||||||
note = build_stubbed(:diff_note_on_commit)
|
|
||||||
|
|
||||||
url = described_class.build(note)
|
|
||||||
|
|
||||||
expect(url).to eq "#{Settings.gitlab['url']}/#{note.project.path_with_namespace}/commit/#{note.commit_id}#note_#{note.id}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'on an Issue' do
|
|
||||||
it 'returns a proper URL' do
|
|
||||||
issue = create(:issue, iid: 42)
|
|
||||||
note = build_stubbed(:note_on_issue, noteable: issue)
|
|
||||||
|
|
||||||
url = described_class.build(note)
|
|
||||||
|
|
||||||
expect(url).to eq "#{Settings.gitlab['url']}/#{issue.project.path_with_namespace}/issues/#{issue.iid}#note_#{note.id}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'on a MergeRequest' do
|
|
||||||
it 'returns a proper URL' do
|
|
||||||
merge_request = create(:merge_request, iid: 42)
|
|
||||||
note = build_stubbed(:note_on_merge_request, noteable: merge_request)
|
|
||||||
|
|
||||||
url = described_class.build(note)
|
|
||||||
|
|
||||||
expect(url).to eq "#{Settings.gitlab['url']}/#{merge_request.project.path_with_namespace}/merge_requests/#{merge_request.iid}#note_#{note.id}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'on a MergeRequest Diff' do
|
|
||||||
it 'returns a proper URL' do
|
|
||||||
merge_request = create(:merge_request, iid: 42)
|
|
||||||
note = build_stubbed(:diff_note_on_merge_request, noteable: merge_request)
|
|
||||||
|
|
||||||
url = described_class.build(note)
|
|
||||||
|
|
||||||
expect(url).to eq "#{Settings.gitlab['url']}/#{merge_request.project.path_with_namespace}/merge_requests/#{merge_request.iid}#note_#{note.id}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'on a ProjectSnippet' do
|
|
||||||
it 'returns a proper URL' do
|
|
||||||
project_snippet = create(:project_snippet)
|
|
||||||
note = build_stubbed(:note_on_project_snippet, noteable: project_snippet)
|
|
||||||
|
|
||||||
url = described_class.build(note)
|
|
||||||
|
|
||||||
expect(url).to eq "#{Settings.gitlab['url']}/#{project_snippet.project.path_with_namespace}/snippets/#{note.noteable_id}#note_#{note.id}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'on another object' do
|
|
||||||
it 'returns a proper URL' do
|
|
||||||
project = build_stubbed(:empty_project)
|
|
||||||
|
|
||||||
expect { described_class.build(project) }.
|
|
||||||
to raise_error(NotImplementedError, 'No URL builder defined for Project')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when passing a WikiPage' do
|
|
||||||
it 'returns a proper URL' do
|
|
||||||
wiki_page = build(:wiki_page)
|
|
||||||
url = described_class.build(wiki_page)
|
|
||||||
|
|
||||||
expect(url).to eq "#{Gitlab.config.gitlab.url}#{wiki_page.wiki.wiki_base_path}/#{wiki_page.slug}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,7 +1,7 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
require 'email_spec'
|
require 'email_spec'
|
||||||
|
|
||||||
describe Notify, "merge request notifications" do
|
describe Emails::MergeRequests do
|
||||||
include EmailSpec::Matchers
|
include EmailSpec::Matchers
|
||||||
|
|
||||||
describe "#resolved_all_discussions_email" do
|
describe "#resolved_all_discussions_email" do
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
require 'email_spec'
|
require 'email_spec'
|
||||||
|
|
||||||
describe Notify do
|
describe Emails::Profile do
|
||||||
include EmailSpec::Matchers
|
include EmailSpec::Matchers
|
||||||
include_context 'gitlab email notification'
|
include_context 'gitlab email notification'
|
||||||
|
|
||||||
|
@ -15,106 +15,104 @@ describe Notify do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'profile notifications' do
|
describe 'for new users, the email' do
|
||||||
describe 'for new users, the email' do
|
let(:example_site_path) { root_path }
|
||||||
let(:example_site_path) { root_path }
|
let(:new_user) { create(:user, email: new_user_address, created_by_id: 1) }
|
||||||
let(:new_user) { create(:user, email: new_user_address, created_by_id: 1) }
|
let(:token) { 'kETLwRaayvigPq_x3SNM' }
|
||||||
let(:token) { 'kETLwRaayvigPq_x3SNM' }
|
|
||||||
|
|
||||||
subject { Notify.new_user_email(new_user.id, token) }
|
subject { Notify.new_user_email(new_user.id, token) }
|
||||||
|
|
||||||
it_behaves_like 'an email sent from GitLab'
|
it_behaves_like 'an email sent from GitLab'
|
||||||
it_behaves_like 'a new user email'
|
it_behaves_like 'a new user email'
|
||||||
it_behaves_like 'it should not have Gmail Actions links'
|
it_behaves_like 'it should not have Gmail Actions links'
|
||||||
it_behaves_like 'a user cannot unsubscribe through footer link'
|
it_behaves_like 'a user cannot unsubscribe through footer link'
|
||||||
|
|
||||||
it 'contains the password text' do
|
it 'contains the password text' do
|
||||||
is_expected.to have_body_text /Click here to set your password/
|
is_expected.to have_body_text /Click here to set your password/
|
||||||
end
|
|
||||||
|
|
||||||
it 'includes a link for user to set password' do
|
|
||||||
params = "reset_password_token=#{token}"
|
|
||||||
is_expected.to have_body_text(
|
|
||||||
%r{http://#{Gitlab.config.gitlab.host}(:\d+)?/users/password/edit\?#{params}}
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'explains the reset link expiration' do
|
|
||||||
is_expected.to have_body_text(/This link is valid for \d+ (hours?|days?)/)
|
|
||||||
is_expected.to have_body_text(new_user_password_url)
|
|
||||||
is_expected.to have_body_text(/\?user_email=.*%40.*/)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'for users that signed up, the email' do
|
it 'includes a link for user to set password' do
|
||||||
let(:example_site_path) { root_path }
|
params = "reset_password_token=#{token}"
|
||||||
let(:new_user) { create(:user, email: new_user_address, password: "securePassword") }
|
is_expected.to have_body_text(
|
||||||
|
%r{http://#{Gitlab.config.gitlab.host}(:\d+)?/users/password/edit\?#{params}}
|
||||||
subject { Notify.new_user_email(new_user.id) }
|
)
|
||||||
|
|
||||||
it_behaves_like 'an email sent from GitLab'
|
|
||||||
it_behaves_like 'a new user email'
|
|
||||||
it_behaves_like 'it should not have Gmail Actions links'
|
|
||||||
it_behaves_like 'a user cannot unsubscribe through footer link'
|
|
||||||
|
|
||||||
it 'does not contain the new user\'s password' do
|
|
||||||
is_expected.not_to have_body_text /password/
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'user added ssh key' do
|
it 'explains the reset link expiration' do
|
||||||
let(:key) { create(:personal_key) }
|
is_expected.to have_body_text(/This link is valid for \d+ (hours?|days?)/)
|
||||||
|
is_expected.to have_body_text(new_user_password_url)
|
||||||
|
is_expected.to have_body_text(/\?user_email=.*%40.*/)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
subject { Notify.new_ssh_key_email(key.id) }
|
describe 'for users that signed up, the email' do
|
||||||
|
let(:example_site_path) { root_path }
|
||||||
|
let(:new_user) { create(:user, email: new_user_address, password: "securePassword") }
|
||||||
|
|
||||||
it_behaves_like 'an email sent from GitLab'
|
subject { Notify.new_user_email(new_user.id) }
|
||||||
it_behaves_like 'it should not have Gmail Actions links'
|
|
||||||
it_behaves_like 'a user cannot unsubscribe through footer link'
|
|
||||||
|
|
||||||
it 'is sent to the new user' do
|
it_behaves_like 'an email sent from GitLab'
|
||||||
is_expected.to deliver_to key.user.email
|
it_behaves_like 'a new user email'
|
||||||
end
|
it_behaves_like 'it should not have Gmail Actions links'
|
||||||
|
it_behaves_like 'a user cannot unsubscribe through footer link'
|
||||||
|
|
||||||
it 'has the correct subject' do
|
it 'does not contain the new user\'s password' do
|
||||||
is_expected.to have_subject /^SSH key was added to your account$/i
|
is_expected.not_to have_body_text /password/
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
it 'contains the new ssh key title' do
|
describe 'user added ssh key' do
|
||||||
is_expected.to have_body_text /#{key.title}/
|
let(:key) { create(:personal_key) }
|
||||||
end
|
|
||||||
|
|
||||||
it 'includes a link to ssh keys page' do
|
subject { Notify.new_ssh_key_email(key.id) }
|
||||||
is_expected.to have_body_text /#{profile_keys_path}/
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with SSH key that does not exist' do
|
it_behaves_like 'an email sent from GitLab'
|
||||||
it { expect { Notify.new_ssh_key_email('foo') }.not_to raise_error }
|
it_behaves_like 'it should not have Gmail Actions links'
|
||||||
end
|
it_behaves_like 'a user cannot unsubscribe through footer link'
|
||||||
|
|
||||||
|
it 'is sent to the new user' do
|
||||||
|
is_expected.to deliver_to key.user.email
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'user added email' do
|
it 'has the correct subject' do
|
||||||
let(:email) { create(:email) }
|
is_expected.to have_subject /^SSH key was added to your account$/i
|
||||||
|
end
|
||||||
|
|
||||||
subject { Notify.new_email_email(email.id) }
|
it 'contains the new ssh key title' do
|
||||||
|
is_expected.to have_body_text /#{key.title}/
|
||||||
|
end
|
||||||
|
|
||||||
it_behaves_like 'it should not have Gmail Actions links'
|
it 'includes a link to ssh keys page' do
|
||||||
it_behaves_like 'a user cannot unsubscribe through footer link'
|
is_expected.to have_body_text /#{profile_keys_path}/
|
||||||
|
end
|
||||||
|
|
||||||
it 'is sent to the new user' do
|
context 'with SSH key that does not exist' do
|
||||||
is_expected.to deliver_to email.user.email
|
it { expect { Notify.new_ssh_key_email('foo') }.not_to raise_error }
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
it 'has the correct subject' do
|
describe 'user added email' do
|
||||||
is_expected.to have_subject /^Email was added to your account$/i
|
let(:email) { create(:email) }
|
||||||
end
|
|
||||||
|
|
||||||
it 'contains the new email address' do
|
subject { Notify.new_email_email(email.id) }
|
||||||
is_expected.to have_body_text /#{email.email}/
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'includes a link to emails page' do
|
it_behaves_like 'it should not have Gmail Actions links'
|
||||||
is_expected.to have_body_text /#{profile_emails_path}/
|
it_behaves_like 'a user cannot unsubscribe through footer link'
|
||||||
end
|
|
||||||
|
it 'is sent to the new user' do
|
||||||
|
is_expected.to deliver_to email.user.email
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'has the correct subject' do
|
||||||
|
is_expected.to have_subject /^Email was added to your account$/i
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'contains the new email address' do
|
||||||
|
is_expected.to have_body_text /#{email.email}/
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'includes a link to emails page' do
|
||||||
|
is_expected.to have_body_text /#{profile_emails_path}/
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe Issue, "Awardable" do
|
describe Awardable do
|
||||||
let!(:issue) { create(:issue) }
|
let!(:issue) { create(:issue) }
|
||||||
let!(:award_emoji) { create(:award_emoji, :downvote, awardable: issue) }
|
let!(:award_emoji) { create(:award_emoji, :downvote, awardable: issue) }
|
||||||
|
|
||||||
describe "Associations" do
|
describe "Associations" do
|
||||||
|
subject { build(:issue) }
|
||||||
|
|
||||||
it { is_expected.to have_many(:award_emoji).dependent(:destroy) }
|
it { is_expected.to have_many(:award_emoji).dependent(:destroy) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe DiffDiscussion, DiscussionOnDiff, model: true do
|
describe DiscussionOnDiff, model: true do
|
||||||
subject { create(:diff_note_on_merge_request).to_discussion }
|
subject { create(:diff_note_on_merge_request).to_discussion }
|
||||||
|
|
||||||
describe "#truncated_diff_lines" do
|
describe "#truncated_diff_lines" do
|
||||||
|
@ -8,9 +8,9 @@ describe DiffDiscussion, DiscussionOnDiff, model: true do
|
||||||
|
|
||||||
context "when diff is greater than allowed number of truncated diff lines " do
|
context "when diff is greater than allowed number of truncated diff lines " do
|
||||||
it "returns fewer lines" do
|
it "returns fewer lines" do
|
||||||
expect(subject.diff_lines.count).to be > described_class::NUMBER_OF_TRUNCATED_DIFF_LINES
|
expect(subject.diff_lines.count).to be > DiffDiscussion::NUMBER_OF_TRUNCATED_DIFF_LINES
|
||||||
|
|
||||||
expect(truncated_lines.count).to be <= described_class::NUMBER_OF_TRUNCATED_DIFF_LINES
|
expect(truncated_lines.count).to be <= DiffDiscussion::NUMBER_OF_TRUNCATED_DIFF_LINES
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe Issue, "Issuable" do
|
describe Issuable do
|
||||||
|
let(:issuable_class) { Issue }
|
||||||
let(:issue) { create(:issue) }
|
let(:issue) { create(:issue) }
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
|
|
||||||
describe "Associations" do
|
describe "Associations" do
|
||||||
|
subject { build(:issue) }
|
||||||
|
|
||||||
it { is_expected.to belong_to(:project) }
|
it { is_expected.to belong_to(:project) }
|
||||||
it { is_expected.to belong_to(:author) }
|
it { is_expected.to belong_to(:author) }
|
||||||
it { is_expected.to belong_to(:assignee) }
|
it { is_expected.to belong_to(:assignee) }
|
||||||
|
@ -23,10 +26,14 @@ describe Issue, "Issuable" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'Included modules' do
|
describe 'Included modules' do
|
||||||
|
let(:described_class) { issuable_class }
|
||||||
|
|
||||||
it { is_expected.to include_module(Awardable) }
|
it { is_expected.to include_module(Awardable) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "Validation" do
|
describe "Validation" do
|
||||||
|
subject { build(:issue) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow(subject).to receive(:set_iid).and_return(false)
|
allow(subject).to receive(:set_iid).and_return(false)
|
||||||
end
|
end
|
||||||
|
@ -39,9 +46,11 @@ describe Issue, "Issuable" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "Scope" do
|
describe "Scope" do
|
||||||
it { expect(described_class).to respond_to(:opened) }
|
subject { build(:issue) }
|
||||||
it { expect(described_class).to respond_to(:closed) }
|
|
||||||
it { expect(described_class).to respond_to(:assigned) }
|
it { expect(issuable_class).to respond_to(:opened) }
|
||||||
|
it { expect(issuable_class).to respond_to(:closed) }
|
||||||
|
it { expect(issuable_class).to respond_to(:assigned) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'author_name' do
|
describe 'author_name' do
|
||||||
|
@ -115,16 +124,16 @@ describe Issue, "Issuable" do
|
||||||
let!(:searchable_issue) { create(:issue, title: "Searchable issue") }
|
let!(:searchable_issue) { create(:issue, title: "Searchable issue") }
|
||||||
|
|
||||||
it 'returns notes with a matching title' do
|
it 'returns notes with a matching title' do
|
||||||
expect(described_class.search(searchable_issue.title)).
|
expect(issuable_class.search(searchable_issue.title)).
|
||||||
to eq([searchable_issue])
|
to eq([searchable_issue])
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns notes with a partially matching title' do
|
it 'returns notes with a partially matching title' do
|
||||||
expect(described_class.search('able')).to eq([searchable_issue])
|
expect(issuable_class.search('able')).to eq([searchable_issue])
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns notes with a matching title regardless of the casing' do
|
it 'returns notes with a matching title regardless of the casing' do
|
||||||
expect(described_class.search(searchable_issue.title.upcase)).
|
expect(issuable_class.search(searchable_issue.title.upcase)).
|
||||||
to eq([searchable_issue])
|
to eq([searchable_issue])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -135,31 +144,31 @@ describe Issue, "Issuable" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns notes with a matching title' do
|
it 'returns notes with a matching title' do
|
||||||
expect(described_class.full_search(searchable_issue.title)).
|
expect(issuable_class.full_search(searchable_issue.title)).
|
||||||
to eq([searchable_issue])
|
to eq([searchable_issue])
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns notes with a partially matching title' do
|
it 'returns notes with a partially matching title' do
|
||||||
expect(described_class.full_search('able')).to eq([searchable_issue])
|
expect(issuable_class.full_search('able')).to eq([searchable_issue])
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns notes with a matching title regardless of the casing' do
|
it 'returns notes with a matching title regardless of the casing' do
|
||||||
expect(described_class.full_search(searchable_issue.title.upcase)).
|
expect(issuable_class.full_search(searchable_issue.title.upcase)).
|
||||||
to eq([searchable_issue])
|
to eq([searchable_issue])
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns notes with a matching description' do
|
it 'returns notes with a matching description' do
|
||||||
expect(described_class.full_search(searchable_issue.description)).
|
expect(issuable_class.full_search(searchable_issue.description)).
|
||||||
to eq([searchable_issue])
|
to eq([searchable_issue])
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns notes with a partially matching description' do
|
it 'returns notes with a partially matching description' do
|
||||||
expect(described_class.full_search(searchable_issue.description)).
|
expect(issuable_class.full_search(searchable_issue.description)).
|
||||||
to eq([searchable_issue])
|
to eq([searchable_issue])
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns notes with a matching description regardless of the casing' do
|
it 'returns notes with a matching description regardless of the casing' do
|
||||||
expect(described_class.full_search(searchable_issue.description.upcase)).
|
expect(issuable_class.full_search(searchable_issue.description.upcase)).
|
||||||
to eq([searchable_issue])
|
to eq([searchable_issue])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe MergeRequest, Noteable, model: true do
|
describe Noteable, model: true do
|
||||||
let!(:active_diff_note1) { create(:diff_note_on_merge_request) }
|
let!(:active_diff_note1) { create(:diff_note_on_merge_request) }
|
||||||
let(:project) { active_diff_note1.project }
|
let(:project) { active_diff_note1.project }
|
||||||
subject { active_diff_note1.noteable }
|
subject { active_diff_note1.noteable }
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe Issue, 'RelativePositioning' do
|
describe RelativePositioning do
|
||||||
let(:project) { create(:empty_project) }
|
let(:project) { create(:empty_project) }
|
||||||
let(:issue) { create(:issue, project: project) }
|
let(:issue) { create(:issue, project: project) }
|
||||||
let(:issue1) { create(:issue, project: project) }
|
let(:issue1) { create(:issue, project: project) }
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe Issue, 'Spammable' do
|
describe Spammable do
|
||||||
let(:issue) { create(:issue, description: 'Test Desc.') }
|
let(:issue) { create(:issue, description: 'Test Desc.') }
|
||||||
|
|
||||||
describe 'Associations' do
|
describe 'Associations' do
|
||||||
|
subject { build(:issue) }
|
||||||
|
|
||||||
it { is_expected.to have_one(:user_agent_detail).dependent(:destroy) }
|
it { is_expected.to have_one(:user_agent_detail).dependent(:destroy) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe Milestone, "StripAttribute" do
|
describe StripAttribute do
|
||||||
let(:milestone) { create(:milestone) }
|
let(:milestone) { create(:milestone) }
|
||||||
|
|
||||||
describe ".strip_attributes" do
|
describe ".strip_attributes" do
|
||||||
|
|
|
@ -1,118 +1,192 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe IssuePolicy, models: true do
|
describe IssuePolicy, models: true do
|
||||||
let(:user) { create(:user) }
|
let(:guest) { create(:user) }
|
||||||
|
let(:author) { create(:user) }
|
||||||
|
let(:assignee) { create(:user) }
|
||||||
|
let(:reporter) { create(:user) }
|
||||||
|
let(:group) { create(:group, :public) }
|
||||||
|
let(:reporter_from_group_link) { create(:user) }
|
||||||
|
|
||||||
describe '#rules' do
|
def permissions(user, issue)
|
||||||
context 'using a regular issue' do
|
described_class.abilities(user, issue).to_set
|
||||||
let(:project) { create(:empty_project, :public) }
|
end
|
||||||
let(:issue) { create(:issue, project: project) }
|
|
||||||
let(:policies) { described_class.abilities(user, issue).to_set }
|
|
||||||
|
|
||||||
context 'with a regular user' do
|
context 'a private project' do
|
||||||
it 'includes the read_issue permission' do
|
let(:non_member) { create(:user) }
|
||||||
expect(policies).to include(:read_issue)
|
let(:project) { create(:empty_project, :private) }
|
||||||
end
|
let(:issue) { create(:issue, project: project, assignee: assignee, author: author) }
|
||||||
|
let(:issue_no_assignee) { create(:issue, project: project) }
|
||||||
|
|
||||||
it 'does not include the admin_issue permission' do
|
before do
|
||||||
expect(policies).not_to include(:admin_issue)
|
project.team << [guest, :guest]
|
||||||
end
|
project.team << [author, :guest]
|
||||||
|
project.team << [assignee, :guest]
|
||||||
|
project.team << [reporter, :reporter]
|
||||||
|
|
||||||
it 'does not include the update_issue permission' do
|
group.add_reporter(reporter_from_group_link)
|
||||||
expect(policies).not_to include(:update_issue)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with a user that is a project reporter' do
|
create(:project_group_link, group: group, project: project)
|
||||||
before do
|
|
||||||
project.team << [user, :reporter]
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'includes the read_issue permission' do
|
|
||||||
expect(policies).to include(:read_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'includes the admin_issue permission' do
|
|
||||||
expect(policies).to include(:admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'includes the update_issue permission' do
|
|
||||||
expect(policies).to include(:update_issue)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with a user that is a project guest' do
|
|
||||||
before do
|
|
||||||
project.team << [user, :guest]
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'includes the read_issue permission' do
|
|
||||||
expect(policies).to include(:read_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'does not include the admin_issue permission' do
|
|
||||||
expect(policies).not_to include(:admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'does not include the update_issue permission' do
|
|
||||||
expect(policies).not_to include(:update_issue)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'using a confidential issue' do
|
it 'does not allow non-members to read issues' do
|
||||||
let(:issue) { create(:issue, :confidential) }
|
expect(permissions(non_member, issue)).not_to include(:read_issue, :update_issue, :admin_issue)
|
||||||
|
expect(permissions(non_member, issue_no_assignee)).not_to include(:read_issue, :update_issue, :admin_issue)
|
||||||
|
end
|
||||||
|
|
||||||
context 'with a regular user' do
|
it 'allows guests to read issues' do
|
||||||
let(:policies) { described_class.abilities(user, issue).to_set }
|
expect(permissions(guest, issue)).to include(:read_issue)
|
||||||
|
expect(permissions(guest, issue)).not_to include(:update_issue, :admin_issue)
|
||||||
|
|
||||||
it 'does not include the read_issue permission' do
|
expect(permissions(guest, issue_no_assignee)).to include(:read_issue)
|
||||||
expect(policies).not_to include(:read_issue)
|
expect(permissions(guest, issue_no_assignee)).not_to include(:update_issue, :admin_issue)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not include the admin_issue permission' do
|
it 'allows reporters to read, update, and admin issues' do
|
||||||
expect(policies).not_to include(:admin_issue)
|
expect(permissions(reporter, issue)).to include(:read_issue, :update_issue, :admin_issue)
|
||||||
end
|
expect(permissions(reporter, issue_no_assignee)).to include(:read_issue, :update_issue, :admin_issue)
|
||||||
|
end
|
||||||
|
|
||||||
it 'does not include the update_issue permission' do
|
it 'allows reporters from group links to read, update, and admin issues' do
|
||||||
expect(policies).not_to include(:update_issue)
|
expect(permissions(reporter_from_group_link, issue)).to include(:read_issue, :update_issue, :admin_issue)
|
||||||
end
|
expect(permissions(reporter_from_group_link, issue_no_assignee)).to include(:read_issue, :update_issue, :admin_issue)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'allows issue authors to read and update their issues' do
|
||||||
|
expect(permissions(author, issue)).to include(:read_issue, :update_issue)
|
||||||
|
expect(permissions(author, issue)).not_to include(:admin_issue)
|
||||||
|
|
||||||
|
expect(permissions(author, issue_no_assignee)).to include(:read_issue)
|
||||||
|
expect(permissions(author, issue_no_assignee)).not_to include(:update_issue, :admin_issue)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'allows issue assignees to read and update their issues' do
|
||||||
|
expect(permissions(assignee, issue)).to include(:read_issue, :update_issue)
|
||||||
|
expect(permissions(assignee, issue)).not_to include(:admin_issue)
|
||||||
|
|
||||||
|
expect(permissions(assignee, issue_no_assignee)).to include(:read_issue)
|
||||||
|
expect(permissions(assignee, issue_no_assignee)).not_to include(:update_issue, :admin_issue)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with confidential issues' do
|
||||||
|
let(:confidential_issue) { create(:issue, :confidential, project: project, assignee: assignee, author: author) }
|
||||||
|
let(:confidential_issue_no_assignee) { create(:issue, :confidential, project: project) }
|
||||||
|
|
||||||
|
it 'does not allow non-members to read confidential issues' do
|
||||||
|
expect(permissions(non_member, confidential_issue)).not_to include(:read_issue, :update_issue, :admin_issue)
|
||||||
|
expect(permissions(non_member, confidential_issue_no_assignee)).not_to include(:read_issue, :update_issue, :admin_issue)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with a user that is a project member' do
|
it 'does not allow guests to read confidential issues' do
|
||||||
let(:policies) { described_class.abilities(user, issue).to_set }
|
expect(permissions(guest, confidential_issue)).not_to include(:read_issue, :update_issue, :admin_issue)
|
||||||
|
expect(permissions(guest, confidential_issue_no_assignee)).not_to include(:read_issue, :update_issue, :admin_issue)
|
||||||
before do
|
|
||||||
issue.project.team << [user, :reporter]
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'includes the read_issue permission' do
|
|
||||||
expect(policies).to include(:read_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'includes the admin_issue permission' do
|
|
||||||
expect(policies).to include(:admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'includes the update_issue permission' do
|
|
||||||
expect(policies).to include(:update_issue)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'without a user' do
|
it 'allows reporters to read, update, and admin confidential issues' do
|
||||||
let(:policies) { described_class.abilities(nil, issue).to_set }
|
expect(permissions(reporter, confidential_issue)).to include(:read_issue, :update_issue, :admin_issue)
|
||||||
|
expect(permissions(reporter, confidential_issue_no_assignee)).to include(:read_issue, :update_issue, :admin_issue)
|
||||||
|
end
|
||||||
|
|
||||||
it 'does not include the read_issue permission' do
|
it 'allows reporters from group links to read, update, and admin confidential issues' do
|
||||||
expect(policies).not_to include(:read_issue)
|
expect(permissions(reporter_from_group_link, confidential_issue)).to include(:read_issue, :update_issue, :admin_issue)
|
||||||
end
|
expect(permissions(reporter_from_group_link, confidential_issue_no_assignee)).to include(:read_issue, :update_issue, :admin_issue)
|
||||||
|
end
|
||||||
|
|
||||||
it 'does not include the admin_issue permission' do
|
it 'allows issue authors to read and update their confidential issues' do
|
||||||
expect(policies).not_to include(:admin_issue)
|
expect(permissions(author, confidential_issue)).to include(:read_issue, :update_issue)
|
||||||
end
|
expect(permissions(author, confidential_issue)).not_to include(:admin_issue)
|
||||||
|
|
||||||
it 'does not include the update_issue permission' do
|
expect(permissions(author, confidential_issue_no_assignee)).not_to include(:read_issue, :update_issue, :admin_issue)
|
||||||
expect(policies).not_to include(:update_issue)
|
end
|
||||||
end
|
|
||||||
|
it 'allows issue assignees to read and update their confidential issues' do
|
||||||
|
expect(permissions(assignee, confidential_issue)).to include(:read_issue, :update_issue)
|
||||||
|
expect(permissions(assignee, confidential_issue)).not_to include(:admin_issue)
|
||||||
|
|
||||||
|
expect(permissions(assignee, confidential_issue_no_assignee)).not_to include(:read_issue, :update_issue, :admin_issue)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'a public project' do
|
||||||
|
let(:project) { create(:empty_project, :public) }
|
||||||
|
let(:issue) { create(:issue, project: project, assignee: assignee, author: author) }
|
||||||
|
let(:issue_no_assignee) { create(:issue, project: project) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
project.team << [guest, :guest]
|
||||||
|
project.team << [reporter, :reporter]
|
||||||
|
|
||||||
|
group.add_reporter(reporter_from_group_link)
|
||||||
|
|
||||||
|
create(:project_group_link, group: group, project: project)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'allows guests to read issues' do
|
||||||
|
expect(permissions(guest, issue)).to include(:read_issue)
|
||||||
|
expect(permissions(guest, issue)).not_to include(:update_issue, :admin_issue)
|
||||||
|
|
||||||
|
expect(permissions(guest, issue_no_assignee)).to include(:read_issue)
|
||||||
|
expect(permissions(guest, issue_no_assignee)).not_to include(:update_issue, :admin_issue)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'allows reporters to read, update, and admin issues' do
|
||||||
|
expect(permissions(reporter, issue)).to include(:read_issue, :update_issue, :admin_issue)
|
||||||
|
expect(permissions(reporter, issue_no_assignee)).to include(:read_issue, :update_issue, :admin_issue)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'allows reporters from group links to read, update, and admin issues' do
|
||||||
|
expect(permissions(reporter_from_group_link, issue)).to include(:read_issue, :update_issue, :admin_issue)
|
||||||
|
expect(permissions(reporter_from_group_link, issue_no_assignee)).to include(:read_issue, :update_issue, :admin_issue)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'allows issue authors to read and update their issues' do
|
||||||
|
expect(permissions(author, issue)).to include(:read_issue, :update_issue)
|
||||||
|
expect(permissions(author, issue)).not_to include(:admin_issue)
|
||||||
|
|
||||||
|
expect(permissions(author, issue_no_assignee)).to include(:read_issue)
|
||||||
|
expect(permissions(author, issue_no_assignee)).not_to include(:update_issue, :admin_issue)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'allows issue assignees to read and update their issues' do
|
||||||
|
expect(permissions(assignee, issue)).to include(:read_issue, :update_issue)
|
||||||
|
expect(permissions(assignee, issue)).not_to include(:admin_issue)
|
||||||
|
|
||||||
|
expect(permissions(assignee, issue_no_assignee)).to include(:read_issue)
|
||||||
|
expect(permissions(assignee, issue_no_assignee)).not_to include(:update_issue, :admin_issue)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with confidential issues' do
|
||||||
|
let(:confidential_issue) { create(:issue, :confidential, project: project, assignee: assignee, author: author) }
|
||||||
|
let(:confidential_issue_no_assignee) { create(:issue, :confidential, project: project) }
|
||||||
|
|
||||||
|
it 'does not allow guests to read confidential issues' do
|
||||||
|
expect(permissions(guest, confidential_issue)).not_to include(:read_issue, :update_issue, :admin_issue)
|
||||||
|
expect(permissions(guest, confidential_issue_no_assignee)).not_to include(:read_issue, :update_issue, :admin_issue)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'allows reporters to read, update, and admin confidential issues' do
|
||||||
|
expect(permissions(reporter, confidential_issue)).to include(:read_issue, :update_issue, :admin_issue)
|
||||||
|
expect(permissions(reporter, confidential_issue_no_assignee)).to include(:read_issue, :update_issue, :admin_issue)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'allows reporter from group links to read, update, and admin confidential issues' do
|
||||||
|
expect(permissions(reporter_from_group_link, confidential_issue)).to include(:read_issue, :update_issue, :admin_issue)
|
||||||
|
expect(permissions(reporter_from_group_link, confidential_issue_no_assignee)).to include(:read_issue, :update_issue, :admin_issue)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'allows issue authors to read and update their confidential issues' do
|
||||||
|
expect(permissions(author, confidential_issue)).to include(:read_issue, :update_issue)
|
||||||
|
expect(permissions(author, confidential_issue)).not_to include(:admin_issue)
|
||||||
|
|
||||||
|
expect(permissions(author, confidential_issue_no_assignee)).not_to include(:read_issue, :update_issue, :admin_issue)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'allows issue assignees to read and update their confidential issues' do
|
||||||
|
expect(permissions(assignee, confidential_issue)).to include(:read_issue, :update_issue)
|
||||||
|
expect(permissions(assignee, confidential_issue)).not_to include(:admin_issue)
|
||||||
|
|
||||||
|
expect(permissions(assignee, confidential_issue_no_assignee)).not_to include(:read_issue, :update_issue, :admin_issue)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,193 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe IssuePolicy, models: true do
|
|
||||||
let(:guest) { create(:user) }
|
|
||||||
let(:author) { create(:user) }
|
|
||||||
let(:assignee) { create(:user) }
|
|
||||||
let(:reporter) { create(:user) }
|
|
||||||
let(:group) { create(:group, :public) }
|
|
||||||
let(:reporter_from_group_link) { create(:user) }
|
|
||||||
|
|
||||||
def permissions(user, issue)
|
|
||||||
IssuePolicy.abilities(user, issue).to_set
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'a private project' do
|
|
||||||
let(:non_member) { create(:user) }
|
|
||||||
let(:project) { create(:empty_project, :private) }
|
|
||||||
let(:issue) { create(:issue, project: project, assignee: assignee, author: author) }
|
|
||||||
let(:issue_no_assignee) { create(:issue, project: project) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
project.team << [guest, :guest]
|
|
||||||
project.team << [author, :guest]
|
|
||||||
project.team << [assignee, :guest]
|
|
||||||
project.team << [reporter, :reporter]
|
|
||||||
|
|
||||||
group.add_reporter(reporter_from_group_link)
|
|
||||||
|
|
||||||
create(:project_group_link, group: group, project: project)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'does not allow non-members to read issues' do
|
|
||||||
expect(permissions(non_member, issue)).not_to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
expect(permissions(non_member, issue_no_assignee)).not_to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'allows guests to read issues' do
|
|
||||||
expect(permissions(guest, issue)).to include(:read_issue)
|
|
||||||
expect(permissions(guest, issue)).not_to include(:update_issue, :admin_issue)
|
|
||||||
|
|
||||||
expect(permissions(guest, issue_no_assignee)).to include(:read_issue)
|
|
||||||
expect(permissions(guest, issue_no_assignee)).not_to include(:update_issue, :admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'allows reporters to read, update, and admin issues' do
|
|
||||||
expect(permissions(reporter, issue)).to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
expect(permissions(reporter, issue_no_assignee)).to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'allows reporters from group links to read, update, and admin issues' do
|
|
||||||
expect(permissions(reporter_from_group_link, issue)).to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
expect(permissions(reporter_from_group_link, issue_no_assignee)).to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'allows issue authors to read and update their issues' do
|
|
||||||
expect(permissions(author, issue)).to include(:read_issue, :update_issue)
|
|
||||||
expect(permissions(author, issue)).not_to include(:admin_issue)
|
|
||||||
|
|
||||||
expect(permissions(author, issue_no_assignee)).to include(:read_issue)
|
|
||||||
expect(permissions(author, issue_no_assignee)).not_to include(:update_issue, :admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'allows issue assignees to read and update their issues' do
|
|
||||||
expect(permissions(assignee, issue)).to include(:read_issue, :update_issue)
|
|
||||||
expect(permissions(assignee, issue)).not_to include(:admin_issue)
|
|
||||||
|
|
||||||
expect(permissions(assignee, issue_no_assignee)).to include(:read_issue)
|
|
||||||
expect(permissions(assignee, issue_no_assignee)).not_to include(:update_issue, :admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with confidential issues' do
|
|
||||||
let(:confidential_issue) { create(:issue, :confidential, project: project, assignee: assignee, author: author) }
|
|
||||||
let(:confidential_issue_no_assignee) { create(:issue, :confidential, project: project) }
|
|
||||||
|
|
||||||
it 'does not allow non-members to read confidential issues' do
|
|
||||||
expect(permissions(non_member, confidential_issue)).not_to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
expect(permissions(non_member, confidential_issue_no_assignee)).not_to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'does not allow guests to read confidential issues' do
|
|
||||||
expect(permissions(guest, confidential_issue)).not_to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
expect(permissions(guest, confidential_issue_no_assignee)).not_to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'allows reporters to read, update, and admin confidential issues' do
|
|
||||||
expect(permissions(reporter, confidential_issue)).to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
expect(permissions(reporter, confidential_issue_no_assignee)).to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'allows reporters from group links to read, update, and admin confidential issues' do
|
|
||||||
expect(permissions(reporter_from_group_link, confidential_issue)).to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
expect(permissions(reporter_from_group_link, confidential_issue_no_assignee)).to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'allows issue authors to read and update their confidential issues' do
|
|
||||||
expect(permissions(author, confidential_issue)).to include(:read_issue, :update_issue)
|
|
||||||
expect(permissions(author, confidential_issue)).not_to include(:admin_issue)
|
|
||||||
|
|
||||||
expect(permissions(author, confidential_issue_no_assignee)).not_to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'allows issue assignees to read and update their confidential issues' do
|
|
||||||
expect(permissions(assignee, confidential_issue)).to include(:read_issue, :update_issue)
|
|
||||||
expect(permissions(assignee, confidential_issue)).not_to include(:admin_issue)
|
|
||||||
|
|
||||||
expect(permissions(assignee, confidential_issue_no_assignee)).not_to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'a public project' do
|
|
||||||
let(:project) { create(:empty_project, :public) }
|
|
||||||
let(:issue) { create(:issue, project: project, assignee: assignee, author: author) }
|
|
||||||
let(:issue_no_assignee) { create(:issue, project: project) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
project.team << [guest, :guest]
|
|
||||||
project.team << [reporter, :reporter]
|
|
||||||
|
|
||||||
group.add_reporter(reporter_from_group_link)
|
|
||||||
|
|
||||||
create(:project_group_link, group: group, project: project)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'allows guests to read issues' do
|
|
||||||
expect(permissions(guest, issue)).to include(:read_issue)
|
|
||||||
expect(permissions(guest, issue)).not_to include(:update_issue, :admin_issue)
|
|
||||||
|
|
||||||
expect(permissions(guest, issue_no_assignee)).to include(:read_issue)
|
|
||||||
expect(permissions(guest, issue_no_assignee)).not_to include(:update_issue, :admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'allows reporters to read, update, and admin issues' do
|
|
||||||
expect(permissions(reporter, issue)).to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
expect(permissions(reporter, issue_no_assignee)).to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'allows reporters from group links to read, update, and admin issues' do
|
|
||||||
expect(permissions(reporter_from_group_link, issue)).to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
expect(permissions(reporter_from_group_link, issue_no_assignee)).to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'allows issue authors to read and update their issues' do
|
|
||||||
expect(permissions(author, issue)).to include(:read_issue, :update_issue)
|
|
||||||
expect(permissions(author, issue)).not_to include(:admin_issue)
|
|
||||||
|
|
||||||
expect(permissions(author, issue_no_assignee)).to include(:read_issue)
|
|
||||||
expect(permissions(author, issue_no_assignee)).not_to include(:update_issue, :admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'allows issue assignees to read and update their issues' do
|
|
||||||
expect(permissions(assignee, issue)).to include(:read_issue, :update_issue)
|
|
||||||
expect(permissions(assignee, issue)).not_to include(:admin_issue)
|
|
||||||
|
|
||||||
expect(permissions(assignee, issue_no_assignee)).to include(:read_issue)
|
|
||||||
expect(permissions(assignee, issue_no_assignee)).not_to include(:update_issue, :admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with confidential issues' do
|
|
||||||
let(:confidential_issue) { create(:issue, :confidential, project: project, assignee: assignee, author: author) }
|
|
||||||
let(:confidential_issue_no_assignee) { create(:issue, :confidential, project: project) }
|
|
||||||
|
|
||||||
it 'does not allow guests to read confidential issues' do
|
|
||||||
expect(permissions(guest, confidential_issue)).not_to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
expect(permissions(guest, confidential_issue_no_assignee)).not_to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'allows reporters to read, update, and admin confidential issues' do
|
|
||||||
expect(permissions(reporter, confidential_issue)).to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
expect(permissions(reporter, confidential_issue_no_assignee)).to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'allows reporter from group links to read, update, and admin confidential issues' do
|
|
||||||
expect(permissions(reporter_from_group_link, confidential_issue)).to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
expect(permissions(reporter_from_group_link, confidential_issue_no_assignee)).to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'allows issue authors to read and update their confidential issues' do
|
|
||||||
expect(permissions(author, confidential_issue)).to include(:read_issue, :update_issue)
|
|
||||||
expect(permissions(author, confidential_issue)).not_to include(:admin_issue)
|
|
||||||
|
|
||||||
expect(permissions(author, confidential_issue_no_assignee)).not_to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'allows issue assignees to read and update their confidential issues' do
|
|
||||||
expect(permissions(assignee, confidential_issue)).to include(:read_issue, :update_issue)
|
|
||||||
expect(permissions(assignee, confidential_issue)).not_to include(:admin_issue)
|
|
||||||
|
|
||||||
expect(permissions(assignee, confidential_issue_no_assignee)).not_to include(:read_issue, :update_issue, :admin_issue)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,6 +1,6 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe API::API do
|
describe 'doorkeeper access' do
|
||||||
let!(:user) { create(:user) }
|
let!(:user) { create(:user) }
|
||||||
let!(:application) { Doorkeeper::Application.create!(name: "MyApp", redirect_uri: "https://app.com", owner: user) }
|
let!(:application) { Doorkeeper::Application.create!(name: "MyApp", redirect_uri: "https://app.com", owner: user) }
|
||||||
let!(:token) { Doorkeeper::AccessToken.create! application_id: application.id, resource_owner_id: user.id, scopes: "api" }
|
let!(:token) { Doorkeeper::AccessToken.create! application_id: application.id, resource_owner_id: user.id, scopes: "api" }
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe API::API do
|
describe 'OAuth tokens' do
|
||||||
context 'Resource Owner Password Credentials' do
|
context 'Resource Owner Password Credentials' do
|
||||||
def request_oauth_token(user)
|
def request_oauth_token(user)
|
||||||
post '/oauth/token', username: user.username, password: user.password, grant_type: 'password'
|
post '/oauth/token', username: user.username, password: user.password, grant_type: 'password'
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe Projects::EnvironmentsController, :routing do
|
describe 'environments routing', :routing do
|
||||||
let(:project) { create(:empty_project) }
|
let(:project) { create(:empty_project) }
|
||||||
|
|
||||||
let(:environment) do
|
let(:environment) do
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
require "spec_helper"
|
require "spec_helper"
|
||||||
|
|
||||||
describe Profiles::NotificationsController do
|
describe "notifications routing" do
|
||||||
describe "routing" do
|
it "routes to #show" do
|
||||||
it "routes to #show" do
|
expect(get("/profile/notifications")).to route_to("profiles/notifications#show")
|
||||||
expect(get("/profile/notifications")).to route_to("profiles/notifications#show")
|
end
|
||||||
end
|
|
||||||
|
|
||||||
it "routes to #update" do
|
it "routes to #update" do
|
||||||
expect(put("/profile/notifications")).to route_to("profiles/notifications#update")
|
expect(put("/profile/notifications")).to route_to("profiles/notifications#update")
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
require 'spec_helper.rb'
|
require 'spec_helper.rb'
|
||||||
|
|
||||||
class DummyService < Issues::BaseService
|
describe Issues::ResolveDiscussions, services: true do
|
||||||
include ::Issues::ResolveDiscussions
|
class DummyService < Issues::BaseService
|
||||||
|
include ::Issues::ResolveDiscussions
|
||||||
|
|
||||||
def initialize(*args)
|
def initialize(*args)
|
||||||
super
|
super
|
||||||
filter_resolve_discussion_params
|
filter_resolve_discussion_params
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
describe DummyService, services: true do
|
|
||||||
let(:project) { create(:project, :repository) }
|
let(:project) { create(:project, :repository) }
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ describe DummyService, services: true do
|
||||||
let(:other_merge_request) { create(:merge_request, source_project: project, source_branch: "other") }
|
let(:other_merge_request) { create(:merge_request, source_project: project, source_branch: "other") }
|
||||||
|
|
||||||
describe "#merge_request_for_resolving_discussion" do
|
describe "#merge_request_for_resolving_discussion" do
|
||||||
let(:service) { described_class.new(project, user, merge_request_to_resolve_discussions_of: merge_request.iid) }
|
let(:service) { DummyService.new(project, user, merge_request_to_resolve_discussions_of: merge_request.iid) }
|
||||||
|
|
||||||
it "finds the merge request" do
|
it "finds the merge request" do
|
||||||
expect(service.merge_request_to_resolve_discussions_of).to eq(merge_request)
|
expect(service.merge_request_to_resolve_discussions_of).to eq(merge_request)
|
||||||
|
@ -43,7 +43,7 @@ describe DummyService, services: true do
|
||||||
|
|
||||||
describe "#discussions_to_resolve" do
|
describe "#discussions_to_resolve" do
|
||||||
it "contains a single discussion when matching merge request and discussion are passed" do
|
it "contains a single discussion when matching merge request and discussion are passed" do
|
||||||
service = described_class.new(
|
service = DummyService.new(
|
||||||
project,
|
project,
|
||||||
user,
|
user,
|
||||||
discussion_to_resolve: discussion.id,
|
discussion_to_resolve: discussion.id,
|
||||||
|
@ -61,7 +61,7 @@ describe DummyService, services: true do
|
||||||
noteable: merge_request,
|
noteable: merge_request,
|
||||||
project: merge_request.target_project,
|
project: merge_request.target_project,
|
||||||
line_number: 15)])
|
line_number: 15)])
|
||||||
service = described_class.new(
|
service = DummyService.new(
|
||||||
project,
|
project,
|
||||||
user,
|
user,
|
||||||
merge_request_to_resolve_discussions_of: merge_request.iid
|
merge_request_to_resolve_discussions_of: merge_request.iid
|
||||||
|
@ -79,7 +79,7 @@ describe DummyService, services: true do
|
||||||
project: merge_request.target_project,
|
project: merge_request.target_project,
|
||||||
line_number: 15,
|
line_number: 15,
|
||||||
)])
|
)])
|
||||||
service = described_class.new(
|
service = DummyService.new(
|
||||||
project,
|
project,
|
||||||
user,
|
user,
|
||||||
merge_request_to_resolve_discussions_of: merge_request.iid
|
merge_request_to_resolve_discussions_of: merge_request.iid
|
||||||
|
@ -92,7 +92,7 @@ describe DummyService, services: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "is empty when a discussion and another merge request are passed" do
|
it "is empty when a discussion and another merge request are passed" do
|
||||||
service = described_class.new(
|
service = DummyService.new(
|
||||||
project,
|
project,
|
||||||
user,
|
user,
|
||||||
discussion_to_resolve: discussion.id,
|
discussion_to_resolve: discussion.id,
|
||||||
|
|
Loading…
Reference in a new issue