Commit d4fbd67a authored by Peter Leitzen's avatar Peter Leitzen

Merge branch 'sarnold-issue-model-specs-perf' into 'master'

Improve spec performance in `issues_spec.rb`

See merge request gitlab-org/gitlab!43082
parents 84e1fbdd e178f397
...@@ -31,7 +31,7 @@ RSpec.describe Issue do ...@@ -31,7 +31,7 @@ RSpec.describe Issue do
describe 'versions.most_recent' do describe 'versions.most_recent' do
it 'returns the most recent version' do it 'returns the most recent version' do
issue = create(:issue) issue = create(:issue, project: reusable_project)
create_list(:design_version, 2, issue: issue) create_list(:design_version, 2, issue: issue)
last_version = create(:design_version, issue: issue) last_version = create(:design_version, issue: issue)
...@@ -79,19 +79,19 @@ RSpec.describe Issue do ...@@ -79,19 +79,19 @@ RSpec.describe Issue do
end end
end end
subject { create(:issue) } subject { create(:issue, project: reusable_project) }
describe 'callbacks' do describe 'callbacks' do
describe '#ensure_metrics' do describe '#ensure_metrics' do
it 'creates metrics after saving' do it 'creates metrics after saving' do
issue = create(:issue) issue = create(:issue, project: reusable_project)
expect(issue.metrics).to be_persisted expect(issue.metrics).to be_persisted
expect(Issue::Metrics.count).to eq(1) expect(Issue::Metrics.count).to eq(1)
end end
it 'does not create duplicate metrics for an issue' do it 'does not create duplicate metrics for an issue' do
issue = create(:issue) issue = create(:issue, project: reusable_project)
issue.close! issue.close!
...@@ -102,7 +102,7 @@ RSpec.describe Issue do ...@@ -102,7 +102,7 @@ RSpec.describe Issue do
it 'records current metrics' do it 'records current metrics' do
expect_any_instance_of(Issue::Metrics).to receive(:record!) expect_any_instance_of(Issue::Metrics).to receive(:record!)
create(:issue) create(:issue, project: reusable_project)
end end
end end
end end
...@@ -111,8 +111,8 @@ RSpec.describe Issue do ...@@ -111,8 +111,8 @@ RSpec.describe Issue do
subject { described_class.with_alert_management_alerts } subject { described_class.with_alert_management_alerts }
it 'gets only issues with alerts' do it 'gets only issues with alerts' do
alert = create(:alert_management_alert, issue: create(:issue)) alert = create(:alert_management_alert, project: reusable_project, issue: create(:issue, project: reusable_project))
issue = create(:issue) issue = create(:issue, project: reusable_project)
expect(subject).to contain_exactly(alert.issue) expect(subject).to contain_exactly(alert.issue)
expect(subject).not_to include(issue) expect(subject).not_to include(issue)
...@@ -130,10 +130,9 @@ RSpec.describe Issue do ...@@ -130,10 +130,9 @@ RSpec.describe Issue do
end end
describe '.with_issue_type' do describe '.with_issue_type' do
let_it_be(:project) { create(:project) } let_it_be(:issue) { create(:issue, project: reusable_project) }
let_it_be(:issue) { create(:issue, project: project) } let_it_be(:incident) { create(:incident, project: reusable_project) }
let_it_be(:incident) { create(:incident, project: project) } let_it_be(:test_case) { create(:quality_test_case, project: reusable_project) }
let_it_be(:test_case) { create(:quality_test_case, project: project) }
it 'gives issues with the given issue type' do it 'gives issues with the given issue type' do
expect(described_class.with_issue_type('issue')) expect(described_class.with_issue_type('issue'))
...@@ -195,7 +194,7 @@ RSpec.describe Issue do ...@@ -195,7 +194,7 @@ RSpec.describe Issue do
end end
describe '#close' do describe '#close' do
subject(:issue) { create(:issue, state: 'opened') } subject(:issue) { create(:issue, project: reusable_project, state: 'opened') }
it 'sets closed_at to Time.current when an issue is closed' do it 'sets closed_at to Time.current when an issue is closed' do
expect { issue.close }.to change { issue.closed_at }.from(nil) expect { issue.close }.to change { issue.closed_at }.from(nil)
...@@ -210,7 +209,7 @@ RSpec.describe Issue do ...@@ -210,7 +209,7 @@ RSpec.describe Issue do
end end
describe '#reopen' do describe '#reopen' do
let(:issue) { create(:issue, state: 'closed', closed_at: Time.current, closed_by: user) } let(:issue) { create(:issue, project: reusable_project, state: 'closed', closed_at: Time.current, closed_by: user) }
it 'sets closed_at to nil when an issue is reopend' do it 'sets closed_at to nil when an issue is reopend' do
expect { issue.reopen }.to change { issue.closed_at }.to(nil) expect { issue.reopen }.to change { issue.closed_at }.to(nil)
...@@ -293,7 +292,7 @@ RSpec.describe Issue do ...@@ -293,7 +292,7 @@ RSpec.describe Issue do
end end
describe '#assignee_or_author?' do describe '#assignee_or_author?' do
let(:issue) { create(:issue) } let(:issue) { create(:issue, project: reusable_project) }
it 'returns true for a user that is assigned to an issue' do it 'returns true for a user that is assigned to an issue' do
issue.assignees << user issue.assignees << user
...@@ -313,22 +312,21 @@ RSpec.describe Issue do ...@@ -313,22 +312,21 @@ RSpec.describe Issue do
end end
describe '#related_issues' do describe '#related_issues' do
let(:user) { create(:user) } let_it_be(:authorized_project) { create(:project) }
let(:authorized_project) { create(:project) } let_it_be(:authorized_project2) { create(:project) }
let(:authorized_project2) { create(:project) } let_it_be(:unauthorized_project) { create(:project) }
let(:unauthorized_project) { create(:project) }
let(:authorized_issue_a) { create(:issue, project: authorized_project) } let_it_be(:authorized_issue_a) { create(:issue, project: authorized_project) }
let(:authorized_issue_b) { create(:issue, project: authorized_project) } let_it_be(:authorized_issue_b) { create(:issue, project: authorized_project) }
let(:authorized_issue_c) { create(:issue, project: authorized_project2) } let_it_be(:authorized_issue_c) { create(:issue, project: authorized_project2) }
let(:unauthorized_issue) { create(:issue, project: unauthorized_project) } let_it_be(:unauthorized_issue) { create(:issue, project: unauthorized_project) }
let!(:issue_link_a) { create(:issue_link, source: authorized_issue_a, target: authorized_issue_b) } let_it_be(:issue_link_a) { create(:issue_link, source: authorized_issue_a, target: authorized_issue_b) }
let!(:issue_link_b) { create(:issue_link, source: authorized_issue_a, target: unauthorized_issue) } let_it_be(:issue_link_b) { create(:issue_link, source: authorized_issue_a, target: unauthorized_issue) }
let!(:issue_link_c) { create(:issue_link, source: authorized_issue_a, target: authorized_issue_c) } let_it_be(:issue_link_c) { create(:issue_link, source: authorized_issue_a, target: authorized_issue_c) }
before do before_all do
authorized_project.add_developer(user) authorized_project.add_developer(user)
authorized_project2.add_developer(user) authorized_project2.add_developer(user)
end end
...@@ -366,17 +364,16 @@ RSpec.describe Issue do ...@@ -366,17 +364,16 @@ RSpec.describe Issue do
end end
context 'user is reporter in project issue belongs to' do context 'user is reporter in project issue belongs to' do
let(:project) { create(:project) } let(:issue) { create(:issue, project: reusable_project) }
let(:issue) { create(:issue, project: project) }
before do before_all do
project.add_reporter(user) reusable_project.add_reporter(user)
end end
it { is_expected.to eq true } it { is_expected.to eq true }
context 'issue not persisted' do context 'issue not persisted' do
let(:issue) { build(:issue, project: project) } let(:issue) { build(:issue, project: reusable_project) }
it { is_expected.to eq false } it { is_expected.to eq false }
end end
...@@ -384,7 +381,7 @@ RSpec.describe Issue do ...@@ -384,7 +381,7 @@ RSpec.describe Issue do
context 'checking destination project also' do context 'checking destination project also' do
subject { issue.can_move?(user, to_project) } subject { issue.can_move?(user, to_project) }
let(:to_project) { create(:project) } let_it_be(:to_project) { create(:project) }
context 'destination project allowed' do context 'destination project allowed' do
before do before do
...@@ -420,7 +417,7 @@ RSpec.describe Issue do ...@@ -420,7 +417,7 @@ RSpec.describe Issue do
end end
describe '#duplicated?' do describe '#duplicated?' do
let(:issue) { create(:issue) } let(:issue) { create(:issue, project: reusable_project) }
subject { issue.duplicated? } subject { issue.duplicated? }
...@@ -429,7 +426,7 @@ RSpec.describe Issue do ...@@ -429,7 +426,7 @@ RSpec.describe Issue do
end end
context 'issue already duplicated' do context 'issue already duplicated' do
let(:duplicated_to_issue) { create(:issue) } let(:duplicated_to_issue) { create(:issue, project: reusable_project) }
let(:issue) { create(:issue, duplicated_to: duplicated_to_issue) } let(:issue) { create(:issue, duplicated_to: duplicated_to_issue) }
it { is_expected.to eq true } it { is_expected.to eq true }
...@@ -440,13 +437,13 @@ RSpec.describe Issue do ...@@ -440,13 +437,13 @@ RSpec.describe Issue do
subject { issue.from_service_desk? } subject { issue.from_service_desk? }
context 'when issue author is support bot' do context 'when issue author is support bot' do
let(:issue) { create(:issue, author: ::User.support_bot) } let(:issue) { create(:issue, project: reusable_project, author: ::User.support_bot) }
it { is_expected.to be_truthy } it { is_expected.to be_truthy }
end end
context 'when issue author is not support bot' do context 'when issue author is not support bot' do
let(:issue) { create(:issue) } let(:issue) { create(:issue, project: reusable_project) }
it { is_expected.to be_falsey } it { is_expected.to be_falsey }
end end
...@@ -495,7 +492,7 @@ RSpec.describe Issue do ...@@ -495,7 +492,7 @@ RSpec.describe Issue do
end end
describe '#has_related_branch?' do describe '#has_related_branch?' do
let(:issue) { create(:issue, title: "Blue Bell Knoll") } let(:issue) { create(:issue, project: reusable_project, title: "Blue Bell Knoll") }
subject { issue.has_related_branch? } subject { issue.has_related_branch? }
...@@ -528,7 +525,7 @@ RSpec.describe Issue do ...@@ -528,7 +525,7 @@ RSpec.describe Issue do
end end
describe "#to_branch_name" do describe "#to_branch_name" do
let(:issue) { create(:issue, title: 'testing-issue') } let_it_be(:issue) { create(:issue, project: reusable_project, title: 'testing-issue') }
it 'starts with the issue iid' do it 'starts with the issue iid' do
expect(issue.to_branch_name).to match(/\A#{issue.iid}-[A-Za-z\-]+\z/) expect(issue.to_branch_name).to match(/\A#{issue.iid}-[A-Za-z\-]+\z/)
...@@ -539,12 +536,12 @@ RSpec.describe Issue do ...@@ -539,12 +536,12 @@ RSpec.describe Issue do
end end
it "does not contain the issue title if confidential" do it "does not contain the issue title if confidential" do
issue = create(:issue, title: 'testing-issue', confidential: true) issue = create(:issue, project: reusable_project, title: 'testing-issue', confidential: true)
expect(issue.to_branch_name).to match(/confidential-issue\z/) expect(issue.to_branch_name).to match(/confidential-issue\z/)
end end
context 'issue title longer than 100 characters' do context 'issue title longer than 100 characters' do
let(:issue) { create(:issue, iid: 999, title: 'Lorem ipsum dolor sit amet consectetur adipiscing elit Mauris sit amet ipsum id lacus custom fringilla convallis') } let_it_be(:issue) { create(:issue, project: reusable_project, iid: 999, title: 'Lorem ipsum dolor sit amet consectetur adipiscing elit Mauris sit amet ipsum id lacus custom fringilla convallis') }
it "truncates branch name to at most 100 characters" do it "truncates branch name to at most 100 characters" do
expect(issue.to_branch_name.length).to be <= 100 expect(issue.to_branch_name.length).to be <= 100
...@@ -581,15 +578,14 @@ RSpec.describe Issue do ...@@ -581,15 +578,14 @@ RSpec.describe Issue do
describe '#participants' do describe '#participants' do
context 'using a public project' do context 'using a public project' do
let(:project) { create(:project, :public) } let_it_be(:issue) { create(:issue, project: reusable_project) }
let(:issue) { create(:issue, project: project) }
let!(:note1) do let!(:note1) do
create(:note_on_issue, noteable: issue, project: project, note: 'a') create(:note_on_issue, noteable: issue, project: reusable_project, note: 'a')
end end
let!(:note2) do let!(:note2) do
create(:note_on_issue, noteable: issue, project: project, note: 'b') create(:note_on_issue, noteable: issue, project: reusable_project, note: 'b')
end end
it 'includes the issue author' do it 'includes the issue author' do
...@@ -604,8 +600,8 @@ RSpec.describe Issue do ...@@ -604,8 +600,8 @@ RSpec.describe Issue do
context 'using a private project' do context 'using a private project' do
it 'does not include mentioned users that do not have access to the project' do it 'does not include mentioned users that do not have access to the project' do
project = create(:project) project = create(:project)
user = create(:user)
issue = create(:issue, project: project) issue = create(:issue, project: project)
user = create(:user)
create(:note_on_issue, create(:note_on_issue,
noteable: issue, noteable: issue,
...@@ -621,10 +617,9 @@ RSpec.describe Issue do ...@@ -621,10 +617,9 @@ RSpec.describe Issue do
it 'updates when assignees change' do it 'updates when assignees change' do
user1 = create(:user) user1 = create(:user)
user2 = create(:user) user2 = create(:user)
project = create(:project) issue = create(:issue, assignees: [user1], project: reusable_project)
issue = create(:issue, assignees: [user1], project: project) reusable_project.add_developer(user1)
project.add_developer(user1) reusable_project.add_developer(user2)
project.add_developer(user2)
expect(user1.assigned_open_issues_count).to eq(1) expect(user1.assigned_open_issues_count).to eq(1)
expect(user2.assigned_open_issues_count).to eq(0) expect(user2.assigned_open_issues_count).to eq(0)
...@@ -638,9 +633,8 @@ RSpec.describe Issue do ...@@ -638,9 +633,8 @@ RSpec.describe Issue do
end end
describe '#visible_to_user?' do describe '#visible_to_user?' do
let(:project) { build(:project) } let(:project) { reusable_project }
let(:issue) { build(:issue, project: project) } let(:issue) { build(:issue, project: project) }
let(:user) { create(:user) }
subject { issue.visible_to_user?(user) } subject { issue.visible_to_user?(user) }
...@@ -661,6 +655,10 @@ RSpec.describe Issue do ...@@ -661,6 +655,10 @@ RSpec.describe Issue do
context 'without a user' do context 'without a user' do
let(:user) { nil } let(:user) { nil }
before do
project.project_feature.update_attribute(:issues_access_level, ProjectFeature::PUBLIC)
end
it 'returns true when the issue is publicly visible' do it 'returns true when the issue is publicly visible' do
expect(issue).to receive(:publicly_visible?).and_return(true) expect(issue).to receive(:publicly_visible?).and_return(true)
...@@ -995,7 +993,8 @@ RSpec.describe Issue do ...@@ -995,7 +993,8 @@ RSpec.describe Issue do
with_them do with_them do
it 'checks for spam on issues that can be seen anonymously' do it 'checks for spam on issues that can be seen anonymously' do
project = create(:project, visibility_level: visibility_level) project = reusable_project
project.update(visibility_level: visibility_level)
issue = create(:issue, project: project, confidential: confidential, description: 'original description') issue = create(:issue, project: project, confidential: confidential, description: 'original description')
issue.assign_attributes(new_attributes) issue.assign_attributes(new_attributes)
...@@ -1016,8 +1015,8 @@ RSpec.describe Issue do ...@@ -1016,8 +1015,8 @@ RSpec.describe Issue do
describe '.public_only' do describe '.public_only' do
it 'only returns public issues' do it 'only returns public issues' do
public_issue = create(:issue) public_issue = create(:issue, project: reusable_project)
create(:issue, confidential: true) create(:issue, project: reusable_project, confidential: true)
expect(described_class.public_only).to eq([public_issue]) expect(described_class.public_only).to eq([public_issue])
end end
...@@ -1025,15 +1024,15 @@ RSpec.describe Issue do ...@@ -1025,15 +1024,15 @@ RSpec.describe Issue do
describe '.confidential_only' do describe '.confidential_only' do
it 'only returns confidential_only issues' do it 'only returns confidential_only issues' do
create(:issue) create(:issue, project: reusable_project)
confidential_issue = create(:issue, confidential: true) confidential_issue = create(:issue, project: reusable_project, confidential: true)
expect(described_class.confidential_only).to eq([confidential_issue]) expect(described_class.confidential_only).to eq([confidential_issue])
end end
end end
describe '.by_project_id_and_iid' do describe '.by_project_id_and_iid' do
let_it_be(:issue_a) { create(:issue) } let_it_be(:issue_a) { create(:issue, project: reusable_project) }
let_it_be(:issue_b) { create(:issue, iid: issue_a.iid) } let_it_be(:issue_b) { create(:issue, iid: issue_a.iid) }
let_it_be(:issue_c) { create(:issue, project: issue_a.project) } let_it_be(:issue_c) { create(:issue, project: issue_a.project) }
let_it_be(:issue_d) { create(:issue, project: issue_a.project) } let_it_be(:issue_d) { create(:issue, project: issue_a.project) }
...@@ -1050,8 +1049,8 @@ RSpec.describe Issue do ...@@ -1050,8 +1049,8 @@ RSpec.describe Issue do
describe '.service_desk' do describe '.service_desk' do
it 'returns the service desk issue' do it 'returns the service desk issue' do
service_desk_issue = create(:issue, author: ::User.support_bot) service_desk_issue = create(:issue, project: reusable_project, author: ::User.support_bot)
regular_issue = create(:issue) regular_issue = create(:issue, project: reusable_project)
expect(described_class.service_desk).to include(service_desk_issue) expect(described_class.service_desk).to include(service_desk_issue)
expect(described_class.service_desk).not_to include(regular_issue) expect(described_class.service_desk).not_to include(regular_issue)
...@@ -1064,7 +1063,7 @@ RSpec.describe Issue do ...@@ -1064,7 +1063,7 @@ RSpec.describe Issue do
describe "#labels_hook_attrs" do describe "#labels_hook_attrs" do
let(:label) { create(:label) } let(:label) { create(:label) }
let(:issue) { create(:labeled_issue, labels: [label]) } let(:issue) { create(:labeled_issue, project: reusable_project, labels: [label]) }
it "returns a list of label hook attributes" do it "returns a list of label hook attributes" do
expect(issue.labels_hook_attrs).to eq([label.hook_attrs]) expect(issue.labels_hook_attrs).to eq([label.hook_attrs])
...@@ -1073,7 +1072,7 @@ RSpec.describe Issue do ...@@ -1073,7 +1072,7 @@ RSpec.describe Issue do
context "relative positioning" do context "relative positioning" do
it_behaves_like "a class that supports relative positioning" do it_behaves_like "a class that supports relative positioning" do
let_it_be(:project) { create(:project) } let_it_be(:project) { reusable_project }
let(:factory) { :issue } let(:factory) { :issue }
let(:default_params) { { project: project } } let(:default_params) { { project: project } }
end end
...@@ -1083,7 +1082,7 @@ RSpec.describe Issue do ...@@ -1083,7 +1082,7 @@ RSpec.describe Issue do
describe "#previous_updated_at" do describe "#previous_updated_at" do
let_it_be(:updated_at) { Time.zone.local(2012, 01, 06) } let_it_be(:updated_at) { Time.zone.local(2012, 01, 06) }
let_it_be(:issue) { create(:issue, updated_at: updated_at) } let_it_be(:issue) { create(:issue, project: reusable_project, updated_at: updated_at) }
it 'returns updated_at value if updated_at did not change at all' do it 'returns updated_at value if updated_at did not change at all' do
allow(issue).to receive(:previous_changes).and_return({}) allow(issue).to receive(:previous_changes).and_return({})
...@@ -1121,7 +1120,7 @@ RSpec.describe Issue do ...@@ -1121,7 +1120,7 @@ RSpec.describe Issue do
end end
describe 'current designs' do describe 'current designs' do
let(:issue) { create(:issue) } let(:issue) { create(:issue, project: reusable_project) }
subject { issue.designs.current } subject { issue.designs.current }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment