diff options
Diffstat (limited to 'spec/models/zoom_meeting_spec.rb')
-rw-r--r-- | spec/models/zoom_meeting_spec.rb | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/spec/models/zoom_meeting_spec.rb b/spec/models/zoom_meeting_spec.rb new file mode 100644 index 00000000000..3dad957a1ce --- /dev/null +++ b/spec/models/zoom_meeting_spec.rb @@ -0,0 +1,154 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe ZoomMeeting do + let(:project) { build(:project) } + + describe 'Factory' do + subject { build(:zoom_meeting) } + + it { is_expected.to be_valid } + end + + describe 'Associations' do + it { is_expected.to belong_to(:project).required } + it { is_expected.to belong_to(:issue).required } + end + + describe 'scopes' do + let(:issue) { create(:issue, project: project) } + let!(:added_meeting) { create(:zoom_meeting, :added_to_issue, issue: issue) } + let!(:removed_meeting) { create(:zoom_meeting, :removed_from_issue, issue: issue) } + + describe '.added_to_issue' do + it 'gets only added meetings' do + meetings_added = described_class.added_to_issue.pluck(:id) + + expect(meetings_added).to include(added_meeting.id) + expect(meetings_added).not_to include(removed_meeting.id) + end + end + describe '.removed_from_issue' do + it 'gets only removed meetings' do + meetings_removed = described_class.removed_from_issue.pluck(:id) + + expect(meetings_removed).to include(removed_meeting.id) + expect(meetings_removed).not_to include(added_meeting.id) + end + end + end + + describe 'Validations' do + describe 'url' do + it { is_expected.to validate_presence_of(:url) } + it { is_expected.to validate_length_of(:url).is_at_most(255) } + + shared_examples 'invalid Zoom URL' do + it do + expect(subject).to be_invalid + expect(subject.errors[:url]) + .to contain_exactly('must contain one valid Zoom URL') + end + end + + context 'with non-Zoom URL' do + before do + subject.url = %{https://non-zoom.url} + end + + include_examples 'invalid Zoom URL' + end + + context 'with multiple Zoom-URLs' do + before do + subject.url = %{https://zoom.us/j/123 https://zoom.us/j/456} + end + + include_examples 'invalid Zoom URL' + end + end + + describe 'issue association' do + let(:issue) { build(:issue, project: project) } + + subject { build(:zoom_meeting, project: project, issue: issue) } + + context 'for the same project' do + it { is_expected.to be_valid } + end + + context 'for a different project' do + let(:issue) { build(:issue) } + + it do + expect(subject).to be_invalid + expect(subject.errors[:issue]) + .to contain_exactly('must associate the same project') + end + end + end + end + + describe 'limit number of meetings per issue' do + shared_examples 'can add meetings' do + it 'can add new Zoom meetings' do + create(:zoom_meeting, :added_to_issue, issue: issue) + end + end + + shared_examples 'can remove meetings' do + it 'can remove Zoom meetings' do + create(:zoom_meeting, :removed_from_issue, issue: issue) + end + end + + shared_examples 'cannot add meetings' do + it 'fails to add a new meeting' do + expect do + create(:zoom_meeting, :added_to_issue, issue: issue) + end.to raise_error ActiveRecord::RecordNotUnique + end + end + + let(:issue) { create(:issue, project: project) } + + context 'without meetings' do + it_behaves_like 'can add meetings' + end + + context 'when no other meeting is added' do + before do + create(:zoom_meeting, :removed_from_issue, issue: issue) + end + + it_behaves_like 'can add meetings' + end + + context 'when meeting is added' do + before do + create(:zoom_meeting, :added_to_issue, issue: issue) + end + + it_behaves_like 'cannot add meetings' + end + + context 'when meeting is added to another issue' do + let(:another_issue) { create(:issue, project: project) } + + before do + create(:zoom_meeting, :added_to_issue, issue: another_issue) + end + + it_behaves_like 'can add meetings' + end + + context 'when second meeting is removed' do + before do + create(:zoom_meeting, :removed_from_issue, issue: issue) + end + + it_behaves_like 'can remove meetings' + end + end +end |