2019-10-21 17:06:14 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
require 'spec_helper'
|
|
|
|
|
2020-06-24 02:09:01 -04:00
|
|
|
RSpec.describe ZoomMeeting do
|
2019-10-21 17:06:14 -04:00
|
|
|
let(:project) { build(:project) }
|
|
|
|
|
|
|
|
describe 'Factory' do
|
|
|
|
subject { build(:zoom_meeting) }
|
|
|
|
|
|
|
|
it { is_expected.to be_valid }
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'Associations' do
|
2020-12-16 10:10:18 -05:00
|
|
|
it { is_expected.to belong_to(:project) }
|
|
|
|
it { is_expected.to belong_to(:issue) }
|
2019-10-21 17:06:14 -04:00
|
|
|
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
|
2020-12-16 10:10:18 -05:00
|
|
|
it { is_expected.to validate_presence_of(:project) }
|
|
|
|
it { is_expected.to validate_presence_of(:issue) }
|
|
|
|
|
|
|
|
describe 'when importing' do
|
|
|
|
subject { build(:zoom_meeting, importing: true) }
|
|
|
|
|
|
|
|
it { is_expected.not_to validate_presence_of(:project) }
|
|
|
|
it { is_expected.not_to validate_presence_of(:issue) }
|
|
|
|
end
|
|
|
|
|
2019-10-21 17:06:14 -04:00
|
|
|
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
|