diff options
Diffstat (limited to 'spec/models/iteration_spec.rb')
-rw-r--r-- | spec/models/iteration_spec.rb | 100 |
1 files changed, 82 insertions, 18 deletions
diff --git a/spec/models/iteration_spec.rb b/spec/models/iteration_spec.rb index ef638330208..5c684fa9771 100644 --- a/spec/models/iteration_spec.rb +++ b/spec/models/iteration_spec.rb @@ -8,11 +8,11 @@ RSpec.describe Iteration do describe "#iid" do it "is properly scoped on project and group" do - iteration1 = create(:iteration, project: project) - iteration2 = create(:iteration, project: project) + iteration1 = create(:iteration, :skip_project_validation, project: project) + iteration2 = create(:iteration, :skip_project_validation, project: project) iteration3 = create(:iteration, group: group) iteration4 = create(:iteration, group: group) - iteration5 = create(:iteration, project: project) + iteration5 = create(:iteration, :skip_project_validation, project: project) want = { iteration1: 1, @@ -35,6 +35,15 @@ RSpec.describe Iteration do context 'Validations' do subject { build(:iteration, group: group, start_date: start_date, due_date: due_date) } + describe '#not_belonging_to_project' do + subject { build(:iteration, project: project, start_date: Time.current, due_date: 1.day.from_now) } + + it 'is invalid' do + expect(subject).not_to be_valid + expect(subject.errors[:project_id]).to include('is not allowed. We do not currently support project-level iterations') + end + end + describe '#dates_do_not_overlap' do let_it_be(:existing_iteration) { create(:iteration, group: group, start_date: 4.days.from_now, due_date: 1.week.from_now) } @@ -54,7 +63,10 @@ RSpec.describe Iteration do end context 'when dates overlap' do - context 'same group' do + let(:start_date) { 5.days.from_now } + let(:due_date) { 6.days.from_now } + + shared_examples_for 'overlapping dates' do context 'when start_date is in range' do let(:start_date) { 5.days.from_now } let(:due_date) { 3.weeks.from_now } @@ -63,6 +75,11 @@ RSpec.describe Iteration do expect(subject).not_to be_valid expect(subject.errors[:base]).to include('Dates cannot overlap with other existing Iterations') end + + it 'is not valid even if forced' do + subject.validate # to generate iid/etc + expect { subject.save!(validate: false) }.to raise_exception(ActiveRecord::StatementInvalid, /#{constraint_name}/) + end end context 'when end_date is in range' do @@ -73,25 +90,72 @@ RSpec.describe Iteration do expect(subject).not_to be_valid expect(subject.errors[:base]).to include('Dates cannot overlap with other existing Iterations') end + + it 'is not valid even if forced' do + subject.validate # to generate iid/etc + expect { subject.save!(validate: false) }.to raise_exception(ActiveRecord::StatementInvalid, /#{constraint_name}/) + end end context 'when both overlap' do - let(:start_date) { 5.days.from_now } - let(:due_date) { 6.days.from_now } - it 'is not valid' do expect(subject).not_to be_valid expect(subject.errors[:base]).to include('Dates cannot overlap with other existing Iterations') end + + it 'is not valid even if forced' do + subject.validate # to generate iid/etc + expect { subject.save!(validate: false) }.to raise_exception(ActiveRecord::StatementInvalid, /#{constraint_name}/) + end end end - context 'different group' do - let(:start_date) { 5.days.from_now } - let(:due_date) { 6.days.from_now } - let(:group) { create(:group) } + context 'group' do + it_behaves_like 'overlapping dates' do + let(:constraint_name) { 'iteration_start_and_due_daterange_group_id_constraint' } + end + + context 'different group' do + let(:group) { create(:group) } - it { is_expected.to be_valid } + it { is_expected.to be_valid } + + it 'does not trigger exclusion constraints' do + expect { subject.save! }.not_to raise_exception + end + end + end + + context 'project' do + let_it_be(:existing_iteration) { create(:iteration, :skip_project_validation, project: project, start_date: 4.days.from_now, due_date: 1.week.from_now) } + + subject { build(:iteration, :skip_project_validation, project: project, start_date: start_date, due_date: due_date) } + + it_behaves_like 'overlapping dates' do + let(:constraint_name) { 'iteration_start_and_due_daterange_project_id_constraint' } + end + + context 'different project' do + let(:project) { create(:project) } + + it { is_expected.to be_valid } + + it 'does not trigger exclusion constraints' do + expect { subject.save! }.not_to raise_exception + end + end + + context 'in a group' do + let(:group) { create(:group) } + + subject { build(:iteration, group: group, start_date: start_date, due_date: due_date) } + + it { is_expected.to be_valid } + + it 'does not trigger exclusion constraints' do + expect { subject.save! }.not_to raise_exception + end + end end end end @@ -148,9 +212,9 @@ RSpec.describe Iteration do context 'time scopes' do let_it_be(:project) { create(:project, :empty_repo) } - let_it_be(:iteration_1) { create(:iteration, :skip_future_date_validation, project: project, start_date: 3.days.ago, due_date: 1.day.from_now) } - let_it_be(:iteration_2) { create(:iteration, :skip_future_date_validation, project: project, start_date: 10.days.ago, due_date: 4.days.ago) } - let_it_be(:iteration_3) { create(:iteration, project: project, start_date: 4.days.from_now, due_date: 1.week.from_now) } + let_it_be(:iteration_1) { create(:iteration, :skip_future_date_validation, :skip_project_validation, project: project, start_date: 3.days.ago, due_date: 1.day.from_now) } + let_it_be(:iteration_2) { create(:iteration, :skip_future_date_validation, :skip_project_validation, project: project, start_date: 10.days.ago, due_date: 4.days.ago) } + let_it_be(:iteration_3) { create(:iteration, :skip_project_validation, project: project, start_date: 4.days.from_now, due_date: 1.week.from_now) } describe 'start_date_passed' do it 'returns iterations where start_date is in the past but due_date is in the future' do @@ -168,9 +232,9 @@ RSpec.describe Iteration do describe '.within_timeframe' do let_it_be(:now) { Time.current } let_it_be(:project) { create(:project, :empty_repo) } - let_it_be(:iteration_1) { create(:iteration, project: project, start_date: now, due_date: 1.day.from_now) } - let_it_be(:iteration_2) { create(:iteration, project: project, start_date: 2.days.from_now, due_date: 3.days.from_now) } - let_it_be(:iteration_3) { create(:iteration, project: project, start_date: 4.days.from_now, due_date: 1.week.from_now) } + let_it_be(:iteration_1) { create(:iteration, :skip_project_validation, project: project, start_date: now, due_date: 1.day.from_now) } + let_it_be(:iteration_2) { create(:iteration, :skip_project_validation, project: project, start_date: 2.days.from_now, due_date: 3.days.from_now) } + let_it_be(:iteration_3) { create(:iteration, :skip_project_validation, project: project, start_date: 4.days.from_now, due_date: 1.week.from_now) } it 'returns iterations with start_date and/or end_date between timeframe' do iterations = described_class.within_timeframe(2.days.from_now, 3.days.from_now) |