2012-08-29 01:52:19 -04:00
|
|
|
require 'spec_helper'
|
|
|
|
|
2013-01-03 02:12:24 -05:00
|
|
|
describe Issue, "Issuable" do
|
2012-08-29 01:52:19 -04:00
|
|
|
let(:issue) { create(:issue) }
|
2015-09-10 23:42:14 -04:00
|
|
|
let(:user) { create(:user) }
|
2012-08-29 01:52:19 -04:00
|
|
|
|
|
|
|
describe "Associations" do
|
2015-02-12 13:17:35 -05:00
|
|
|
it { is_expected.to belong_to(:project) }
|
|
|
|
it { is_expected.to belong_to(:author) }
|
|
|
|
it { is_expected.to belong_to(:assignee) }
|
|
|
|
it { is_expected.to have_many(:notes).dependent(:destroy) }
|
2016-03-23 22:14:02 -04:00
|
|
|
it { is_expected.to have_many(:todos).dependent(:destroy) }
|
2012-08-29 01:52:19 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
describe "Validation" do
|
2015-05-21 17:49:06 -04:00
|
|
|
before do
|
|
|
|
allow(subject).to receive(:set_iid).and_return(false)
|
|
|
|
end
|
|
|
|
|
2015-02-12 13:17:35 -05:00
|
|
|
it { is_expected.to validate_presence_of(:project) }
|
|
|
|
it { is_expected.to validate_presence_of(:iid) }
|
|
|
|
it { is_expected.to validate_presence_of(:author) }
|
|
|
|
it { is_expected.to validate_presence_of(:title) }
|
2015-05-18 16:40:10 -04:00
|
|
|
it { is_expected.to validate_length_of(:title).is_at_least(0).is_at_most(255) }
|
2012-08-29 01:52:19 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
describe "Scope" do
|
2015-02-12 13:17:35 -05:00
|
|
|
it { expect(described_class).to respond_to(:opened) }
|
|
|
|
it { expect(described_class).to respond_to(:closed) }
|
|
|
|
it { expect(described_class).to respond_to(:assigned) }
|
2012-08-29 01:52:19 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
describe ".search" do
|
|
|
|
let!(:searchable_issue) { create(:issue, title: "Searchable issue") }
|
|
|
|
|
2016-03-04 05:54:37 -05:00
|
|
|
it 'returns notes with a matching title' do
|
2016-03-01 10:59:36 -05:00
|
|
|
expect(described_class.search(searchable_issue.title)).
|
|
|
|
to eq([searchable_issue])
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns notes with a partially matching title' do
|
2015-02-12 13:17:35 -05:00
|
|
|
expect(described_class.search('able')).to eq([searchable_issue])
|
2012-08-29 01:52:19 -04:00
|
|
|
end
|
2016-03-01 10:59:36 -05:00
|
|
|
|
|
|
|
it 'returns notes with a matching title regardless of the casing' do
|
|
|
|
expect(described_class.search(searchable_issue.title.upcase)).
|
|
|
|
to eq([searchable_issue])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe ".full_search" do
|
|
|
|
let!(:searchable_issue) do
|
|
|
|
create(:issue, title: "Searchable issue", description: 'kittens')
|
|
|
|
end
|
|
|
|
|
2016-03-04 05:54:37 -05:00
|
|
|
it 'returns notes with a matching title' do
|
2016-03-01 10:59:36 -05:00
|
|
|
expect(described_class.full_search(searchable_issue.title)).
|
|
|
|
to eq([searchable_issue])
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns notes with a partially matching title' do
|
|
|
|
expect(described_class.full_search('able')).to eq([searchable_issue])
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns notes with a matching title regardless of the casing' do
|
|
|
|
expect(described_class.full_search(searchable_issue.title.upcase)).
|
|
|
|
to eq([searchable_issue])
|
|
|
|
end
|
|
|
|
|
2016-03-04 05:54:37 -05:00
|
|
|
it 'returns notes with a matching description' do
|
2016-03-01 10:59:36 -05:00
|
|
|
expect(described_class.full_search(searchable_issue.description)).
|
|
|
|
to eq([searchable_issue])
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns notes with a partially matching description' do
|
|
|
|
expect(described_class.full_search(searchable_issue.description)).
|
|
|
|
to eq([searchable_issue])
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns notes with a matching description regardless of the casing' do
|
|
|
|
expect(described_class.full_search(searchable_issue.description.upcase)).
|
|
|
|
to eq([searchable_issue])
|
|
|
|
end
|
2012-08-29 01:52:19 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
describe "#today?" do
|
|
|
|
it "returns true when created today" do
|
|
|
|
# Avoid timezone differences and just return exactly what we want
|
2015-02-12 13:17:35 -05:00
|
|
|
allow(Date).to receive(:today).and_return(issue.created_at.to_date)
|
|
|
|
expect(issue.today?).to be_truthy
|
2012-08-29 01:52:19 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it "returns false when not created today" do
|
2015-02-12 13:17:35 -05:00
|
|
|
allow(Date).to receive(:today).and_return(Date.yesterday)
|
|
|
|
expect(issue.today?).to be_falsey
|
2012-08-29 01:52:19 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#new?" do
|
|
|
|
it "returns true when created today and record hasn't been updated" do
|
2015-02-12 13:17:35 -05:00
|
|
|
allow(issue).to receive(:today?).and_return(true)
|
|
|
|
expect(issue.new?).to be_truthy
|
2012-08-29 01:52:19 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it "returns false when not created today" do
|
2015-02-12 13:17:35 -05:00
|
|
|
allow(issue).to receive(:today?).and_return(false)
|
|
|
|
expect(issue.new?).to be_falsey
|
2012-08-29 01:52:19 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it "returns false when record has been updated" do
|
2015-02-12 13:17:35 -05:00
|
|
|
allow(issue).to receive(:today?).and_return(true)
|
2012-08-29 01:52:19 -04:00
|
|
|
issue.touch
|
2015-02-12 13:17:35 -05:00
|
|
|
expect(issue.new?).to be_falsey
|
2012-08-29 01:52:19 -04:00
|
|
|
end
|
|
|
|
end
|
2015-09-10 23:42:14 -04:00
|
|
|
|
2016-03-01 11:33:13 -05:00
|
|
|
describe '#subscribed?' do
|
|
|
|
context 'user is not a participant in the issue' do
|
|
|
|
before { allow(issue).to receive(:participants).with(user).and_return([]) }
|
|
|
|
|
|
|
|
it 'returns false when no subcription exists' do
|
|
|
|
expect(issue.subscribed?(user)).to be_falsey
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns true when a subcription exists and subscribed is true' do
|
|
|
|
issue.subscriptions.create(user: user, subscribed: true)
|
|
|
|
|
|
|
|
expect(issue.subscribed?(user)).to be_truthy
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns false when a subcription exists and subscribed is false' do
|
|
|
|
issue.subscriptions.create(user: user, subscribed: false)
|
|
|
|
|
|
|
|
expect(issue.subscribed?(user)).to be_falsey
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'user is a participant in the issue' do
|
|
|
|
before { allow(issue).to receive(:participants).with(user).and_return([user]) }
|
|
|
|
|
|
|
|
it 'returns false when no subcription exists' do
|
|
|
|
expect(issue.subscribed?(user)).to be_truthy
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns true when a subcription exists and subscribed is true' do
|
|
|
|
issue.subscriptions.create(user: user, subscribed: true)
|
|
|
|
|
|
|
|
expect(issue.subscribed?(user)).to be_truthy
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns false when a subcription exists and subscribed is false' do
|
|
|
|
issue.subscriptions.create(user: user, subscribed: false)
|
|
|
|
|
|
|
|
expect(issue.subscribed?(user)).to be_falsey
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-09-10 23:42:14 -04:00
|
|
|
describe "#to_hook_data" do
|
Add new data to project in push, issue, merge-request and note webhooks data
- Add `avatar_url`, `description`, `git_ssh_url`, `git_http_url`,
`path_with_namespace` and `default_branch` in `project` in push, issue,
merge-request and note webhooks data
- Deprecate the `ssh_url` in favor of `git_ssh_url` and `http_url` in
favor of `git_http_url` in `project` for push, issue, merge-request and
note webhooks data
- Deprecate the `repository` key in push, issue, merge-request and
note webhooks data, use `project` instead
2016-02-06 09:20:21 -05:00
|
|
|
let(:data) { issue.to_hook_data(user) }
|
|
|
|
let(:project) { issue.project }
|
|
|
|
|
2015-09-10 23:42:14 -04:00
|
|
|
|
|
|
|
it "returns correct hook data" do
|
Add new data to project in push, issue, merge-request and note webhooks data
- Add `avatar_url`, `description`, `git_ssh_url`, `git_http_url`,
`path_with_namespace` and `default_branch` in `project` in push, issue,
merge-request and note webhooks data
- Deprecate the `ssh_url` in favor of `git_ssh_url` and `http_url` in
favor of `git_http_url` in `project` for push, issue, merge-request and
note webhooks data
- Deprecate the `repository` key in push, issue, merge-request and
note webhooks data, use `project` instead
2016-02-06 09:20:21 -05:00
|
|
|
expect(data[:object_kind]).to eq("issue")
|
|
|
|
expect(data[:user]).to eq(user.hook_attrs)
|
|
|
|
expect(data[:object_attributes]).to eq(issue.hook_attrs)
|
|
|
|
expect(data).to_not have_key(:assignee)
|
2015-10-17 18:11:36 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
context "issue is assigned" do
|
|
|
|
before { issue.update_attribute(:assignee, user) }
|
|
|
|
|
|
|
|
it "returns correct hook data" do
|
Add new data to project in push, issue, merge-request and note webhooks data
- Add `avatar_url`, `description`, `git_ssh_url`, `git_http_url`,
`path_with_namespace` and `default_branch` in `project` in push, issue,
merge-request and note webhooks data
- Deprecate the `ssh_url` in favor of `git_ssh_url` and `http_url` in
favor of `git_http_url` in `project` for push, issue, merge-request and
note webhooks data
- Deprecate the `repository` key in push, issue, merge-request and
note webhooks data, use `project` instead
2016-02-06 09:20:21 -05:00
|
|
|
expect(data[:object_attributes]['assignee_id']).to eq(user.id)
|
|
|
|
expect(data[:assignee]).to eq(user.hook_attrs)
|
2015-10-17 18:11:36 -04:00
|
|
|
end
|
2015-09-10 23:42:14 -04:00
|
|
|
end
|
Add new data to project in push, issue, merge-request and note webhooks data
- Add `avatar_url`, `description`, `git_ssh_url`, `git_http_url`,
`path_with_namespace` and `default_branch` in `project` in push, issue,
merge-request and note webhooks data
- Deprecate the `ssh_url` in favor of `git_ssh_url` and `http_url` in
favor of `git_http_url` in `project` for push, issue, merge-request and
note webhooks data
- Deprecate the `repository` key in push, issue, merge-request and
note webhooks data, use `project` instead
2016-02-06 09:20:21 -05:00
|
|
|
|
|
|
|
include_examples 'project hook data'
|
|
|
|
include_examples 'deprecated repository hook data'
|
2015-09-10 23:42:14 -04:00
|
|
|
end
|
2015-12-24 17:03:54 -05:00
|
|
|
|
|
|
|
describe '#card_attributes' do
|
|
|
|
it 'includes the author name' do
|
|
|
|
allow(issue).to receive(:author).and_return(double(name: 'Robert'))
|
|
|
|
allow(issue).to receive(:assignee).and_return(nil)
|
|
|
|
|
|
|
|
expect(issue.card_attributes).
|
2015-12-25 07:22:32 -05:00
|
|
|
to eq({ 'Author' => 'Robert', 'Assignee' => nil })
|
2015-12-24 17:03:54 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'includes the assignee name' do
|
|
|
|
allow(issue).to receive(:author).and_return(double(name: 'Robert'))
|
|
|
|
allow(issue).to receive(:assignee).and_return(double(name: 'Douwe'))
|
|
|
|
|
|
|
|
expect(issue.card_attributes).
|
2015-12-25 07:22:32 -05:00
|
|
|
to eq({ 'Author' => 'Robert', 'Assignee' => 'Douwe' })
|
2015-12-24 17:03:54 -05:00
|
|
|
end
|
|
|
|
end
|
2015-12-25 11:13:55 -05:00
|
|
|
|
|
|
|
describe "votes" do
|
|
|
|
before do
|
|
|
|
author = create :user
|
|
|
|
project = create :empty_project
|
|
|
|
issue.notes.awards.create!(note: "thumbsup", author: author, project: project)
|
|
|
|
issue.notes.awards.create!(note: "thumbsdown", author: author, project: project)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns correct values" do
|
|
|
|
expect(issue.upvotes).to eq(1)
|
|
|
|
expect(issue.downvotes).to eq(1)
|
|
|
|
end
|
|
|
|
end
|
2016-04-20 04:56:28 -04:00
|
|
|
|
|
|
|
describe ".with_label" do
|
2016-04-21 07:20:00 -04:00
|
|
|
let(:project) { create(:project, :public) }
|
|
|
|
let(:bug) { create(:label, project: project, title: 'bug') }
|
|
|
|
let(:feature) { create(:label, project: project, title: 'feature') }
|
|
|
|
let(:enhancement) { create(:label, project: project, title: 'enhancement') }
|
|
|
|
let(:issue1) { create(:issue, title: "Bugfix1", project: project) }
|
|
|
|
let(:issue2) { create(:issue, title: "Bugfix2", project: project) }
|
|
|
|
let(:issue3) { create(:issue, title: "Feature1", project: project) }
|
2016-04-20 04:56:28 -04:00
|
|
|
|
2016-04-21 03:12:03 -04:00
|
|
|
before(:each) do
|
2016-04-21 07:20:00 -04:00
|
|
|
issue1.labels << bug
|
|
|
|
issue1.labels << feature
|
|
|
|
issue2.labels << bug
|
|
|
|
issue2.labels << enhancement
|
|
|
|
issue3.labels << feature
|
2016-04-21 03:12:03 -04:00
|
|
|
end
|
|
|
|
|
2016-04-21 07:20:00 -04:00
|
|
|
it 'finds the correct issue containing just enhancement label' do
|
|
|
|
expect(Issue.with_label(enhancement.title)).to match_array([issue2])
|
2016-04-20 04:56:28 -04:00
|
|
|
end
|
|
|
|
|
2016-04-21 07:20:00 -04:00
|
|
|
it 'finds the correct issues containing the same label' do
|
|
|
|
expect(Issue.with_label(bug.title)).to match_array([issue1, issue2])
|
2016-04-20 04:56:28 -04:00
|
|
|
end
|
2016-04-21 03:12:03 -04:00
|
|
|
|
2016-04-21 07:20:00 -04:00
|
|
|
it 'finds the correct issues containing only both labels' do
|
|
|
|
expect(Issue.with_label([bug.title, enhancement.title])).to match_array([issue2])
|
2016-04-21 03:12:03 -04:00
|
|
|
end
|
2016-04-20 04:56:28 -04:00
|
|
|
end
|
2016-04-20 05:50:07 -04:00
|
|
|
end
|