diff --git a/app/controllers/acquired_media_releases_controller.rb b/app/controllers/acquired_media_releases_controller.rb index 8d572ab..9c1858e 100644 --- a/app/controllers/acquired_media_releases_controller.rb +++ b/app/controllers/acquired_media_releases_controller.rb @@ -61,7 +61,8 @@ class AcquiredMediaReleasesController < ApplicationController :name, :territory, :term, - :person_name, + :person_first_name, + :person_last_name, :person_phone, :person_email, :person_company, diff --git a/app/controllers/location_releases_controller.rb b/app/controllers/location_releases_controller.rb index 5ece1f0..898032a 100644 --- a/app/controllers/location_releases_controller.rb +++ b/app/controllers/location_releases_controller.rb @@ -68,7 +68,8 @@ class LocationReleasesController < ApplicationController :territory_id, :territory_text, :term_id, :term_text, :restriction_id, :restriction_text, - :filming_started_on, :filming_ended_on + :filming_started_on, :filming_ended_on, + :filming_hours ) end diff --git a/app/controllers/public/acquired_media_releases_controller.rb b/app/controllers/public/acquired_media_releases_controller.rb index 1d6bd11..5288601 100644 --- a/app/controllers/public/acquired_media_releases_controller.rb +++ b/app/controllers/public/acquired_media_releases_controller.rb @@ -45,6 +45,9 @@ class Public::AcquiredMediaReleasesController < Public::BaseController params.require(:acquired_media_release).permit( :name, :description, + :person_first_name, + :person_last_name, + :person_email, :person_title, :person_phone, :person_fax, diff --git a/app/controllers/public/location_releases_controller.rb b/app/controllers/public/location_releases_controller.rb index 563e188..a88de75 100644 --- a/app/controllers/public/location_releases_controller.rb +++ b/app/controllers/public/location_releases_controller.rb @@ -63,7 +63,8 @@ class Public::LocationReleasesController < Public::BaseController :person_address_zip, :person_address_country, :signature_base64, - :locale, :contract_template, :filming_started_on, :filming_ended_on + :locale, :contract_template, :filming_started_on, :filming_ended_on, + :filming_hours ) end diff --git a/app/models/project.rb b/app/models/project.rb index 29ab01c..0001c1f 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -117,7 +117,7 @@ class Project < ApplicationRecord current_zoom_meeting = zoom_meetings.active.first unless current_zoom_meeting.present? - zoom_user = ZoomUser.free.first || ZoomUser.create + zoom_user = ZoomUser.for_new_meeting current_zoom_meeting = ZoomMeeting.create(zoom_user: zoom_user, project: self) end diff --git a/app/models/zoom_user.rb b/app/models/zoom_user.rb index 6185ea1..e96f55b 100644 --- a/app/models/zoom_user.rb +++ b/app/models/zoom_user.rb @@ -1,19 +1,28 @@ require 'zoom_gateway' +require 'securerandom' class ZoomUser < ApplicationRecord has_many :zoom_meetings, dependent: :nullify + enum tier: [:basic, :pro] + after_create :create_api_user, if: -> { api_id.nil? } before_destroy :abort_destroy + scope :current_account, -> { where(account_number: ZoomGateway.ACCOUNT_NUMBER) } scope :free, -> { where.not(id: ZoomMeeting.active.pluck(:zoom_user_id)) } - def api_email - self.class.api_email(self.id) - end - def create_api_user - self.api_id = gateway.create_host(api_email) + retries ||= 0 + self.api_id = gateway.create_host(self.class.generate_api_email) + self.account_number = ZoomGateway.ACCOUNT_NUMBER save + rescue ZoomGateway::UserAlreadyExists => e + retries += 1 + if retries < 3 + retry # new api email will be generated automatically + else + raise e + end end def delete_api_user @@ -22,9 +31,22 @@ class ZoomUser < ApplicationRecord save end + def current_account? + account_number == ZoomGateway.ACCOUNT_NUMBER + end + + # Static methods class << self - def api_email(id) - "host#{id}@directme" + def generate_api_email + "host#{SecureRandom.random_number(10000)}@directme" + end + + def for_new_meeting + user = public_send(ZoomGateway.USER_TYPE_NAME).current_account.free.first + if user.nil? + user = public_send(ZoomGateway.USER_TYPE_NAME).current_account.create + end + user end end diff --git a/app/views/acquired_media_releases/_form.html.erb b/app/views/acquired_media_releases/_form.html.erb index 049c736..4f54715 100644 --- a/app/views/acquired_media_releases/_form.html.erb +++ b/app/views/acquired_media_releases/_form.html.erb @@ -4,7 +4,7 @@
<%= form.text_field :name, required: true, wrapper_class: "col-12" %>
- <%= form.form_group :categories, label: { text: "Categories" } do %> + <%= form.form_group :categories, label: { text: "Licensed property type" } do %> <% AcquiredMediaRelease::CATEGORIES.each do |category| %> <%= form.check_box :categories, { multiple: true, label: category }, category, false %> <% end %> diff --git a/app/views/contracts/_signature_page.html.erb b/app/views/contracts/_signature_page.html.erb index e6ad5d6..e39c8be 100644 --- a/app/views/contracts/_signature_page.html.erb +++ b/app/views/contracts/_signature_page.html.erb @@ -29,6 +29,7 @@ <% if releasable.model_name == "LocationRelease" %> <%= description_list_pair "Filming Started On:", releasable&.filming_started_on&.strftime("%D") %> <%= description_list_pair "Filming Ended On:", releasable&.filming_ended_on&.strftime("%D") %> + <%= description_list_pair "Filming Hours:", releasable&.filming_hours %> <% end %> <% if contract_template.fee? %> <%= description_list_pair "Fee:", number_to_currency(contract_template.fee) %> diff --git a/app/views/location_releases/_form.html.erb b/app/views/location_releases/_form.html.erb index 33aeb45..a0d1290 100644 --- a/app/views/location_releases/_form.html.erb +++ b/app/views/location_releases/_form.html.erb @@ -11,14 +11,10 @@ <%= field_set_tag content_tag(:span, t(".signer_details.heading"), class: "h6 text-muted text-uppercase") do %>
- <%= form.text_field :person_first_name, wrapper_class: "col-sm-3" %> - <%= form.text_field :person_last_name, wrapper_class: "col-sm-3" %> + <%= form.text_field :person_first_name, wrapper_class: "col-sm-6" %> + <%= form.text_field :person_last_name, wrapper_class: "col-sm-6" %> <%= form.phone_field :person_phone, wrapper_class: "col-sm-6" %> -
-
<%= form.email_field :person_email, wrapper_class: "col-sm-6" %> -
-
<%= form.text_field :person_company, wrapper_class: "col-sm-6" %> <%= form.text_field :person_title, wrapper_class: "col-sm-6" %>
@@ -38,6 +34,7 @@
<%= form.text_field :filming_started_on, wrapper_class: "col-sm-6", class: "datepicker-control", readonly: true %> <%= form.text_field :filming_ended_on, wrapper_class: "col-sm-6", class: "datepicker-control", readonly: true %> + <%= form.text_field :filming_hours, wrapper_class: "col-sm-12" %>
<% end %> diff --git a/app/views/material_releases/_form.html.erb b/app/views/material_releases/_form.html.erb index 8a336ca..2256596 100644 --- a/app/views/material_releases/_form.html.erb +++ b/app/views/material_releases/_form.html.erb @@ -13,14 +13,10 @@ <%= field_set_tag content_tag(:span, t(".signer_details.heading"), class: "h6 text-muted text-uppercase") do %>
- <%= form.text_field :person_first_name, wrapper_class: "col-sm-3" %> - <%= form.text_field :person_last_name, wrapper_class: "col-sm-3" %> + <%= form.text_field :person_first_name, wrapper_class: "col-sm-6" %> + <%= form.text_field :person_last_name, wrapper_class: "col-sm-6" %> <%= form.phone_field :person_phone, wrapper_class: "col-sm-6" %> -
-
<%= form.email_field :person_email, wrapper_class: "col-sm-6" %> -
-
<%= form.text_field :person_company, wrapper_class: "col-sm-6" %> <%= form.text_field :person_title, wrapper_class: "col-sm-6" %>
diff --git a/app/views/public/acquired_media_releases/new.html.erb b/app/views/public/acquired_media_releases/new.html.erb index 2380db0..abffa38 100644 --- a/app/views/public/acquired_media_releases/new.html.erb +++ b/app/views/public/acquired_media_releases/new.html.erb @@ -15,12 +15,12 @@ <%= card_field_set_tag t(".acquired_media_info.heading") do %>
- <%= form.text_field :name, required: true, wrapper_class: "col-12", label: 'Licensor ("Owner")' %> + <%= form.text_field :name, required: true, wrapper_class: "col-12" %>
<%= form.text_area :description, wrapper_class: "col-12" %>
- <%= form.form_group :categories, label: { text: "Categories" } do %> + <%= form.form_group :categories, label: { text: "Licensed property type" } do %> <% AcquiredMediaRelease::CATEGORIES.each do |category| %> <%= form.check_box :categories, { multiple: true, label: category }, category, false %> <% end %> @@ -31,8 +31,11 @@ <%= card_field_set_tag t(".personal_info.heading") do %>
+ <%= form.text_field :person_first_name, wrapper_class: "col-sm-6" %> + <%= form.text_field :person_last_name, wrapper_class: "col-sm-6" %> <%= form.text_field :person_title, wrapper_class: "col-sm-6" %> - <%= form.text_field :person_phone, wrapper_class: "col-sm-6", label: 'Phone' %> + <%= form.phone_field :person_phone, wrapper_class: "col-sm-6", label: 'Phone' %> + <%= form.email_field :person_email, wrapper_class: "col-sm-6", label: 'Email' %> <%= form.text_field :person_fax, wrapper_class: "col-sm-6", label: 'Fax' %>
<%= render "shared/address_fields", form: form, subject: "person" %> diff --git a/app/views/public/location_releases/new.html.erb b/app/views/public/location_releases/new.html.erb index 2e3625e..0975f73 100644 --- a/app/views/public/location_releases/new.html.erb +++ b/app/views/public/location_releases/new.html.erb @@ -27,11 +27,7 @@ <%= form.text_field :person_first_name, wrapper_class: "col-sm-6" %> <%= form.text_field :person_last_name, wrapper_class: "col-sm-6" %> <%= form.phone_field :person_phone, wrapper_class: "col-sm-6" %> - -
<%= form.email_field :person_email, wrapper_class: "col-sm-6" %> -
-
<%= form.text_field :person_company, wrapper_class: "col-sm-6" %> <%= form.text_field :person_title, wrapper_class: "col-sm-6" %>
@@ -45,6 +41,7 @@
<%= form.text_field :filming_started_on, wrapper_class: "col-sm-6", class: "datepicker-control", readonly: true %> <%= form.text_field :filming_ended_on, wrapper_class: "col-sm-6", class: "datepicker-control", readonly: true %> + <%= form.text_field :filming_hours, wrapper_class: "col-sm-12" %>
<% end %> diff --git a/app/views/public/material_releases/new.html.erb b/app/views/public/material_releases/new.html.erb index 9396ddd..6fa5c8f 100644 --- a/app/views/public/material_releases/new.html.erb +++ b/app/views/public/material_releases/new.html.erb @@ -27,11 +27,7 @@ <%= form.text_field :person_first_name, wrapper_class: "col-sm-6" %> <%= form.text_field :person_last_name, wrapper_class: "col-sm-6" %> <%= form.phone_field :person_phone, wrapper_class: "col-sm-6" %> - -
<%= form.email_field :person_email, wrapper_class: "col-sm-6" %> -
-
<%= form.text_field :person_company, wrapper_class: "col-sm-6" %> <%= form.text_field :person_title, wrapper_class: "col-sm-6" %>
diff --git a/config/locales/en.yml b/config/locales/en.yml index 6b64360..9d167ff 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -305,6 +305,8 @@ en: graphics_only_edl_file: If you do not upload a Graphics Only EDL, the software will not generate a Graphics Cue List. label: acquired_media_release: + description: Description of licensed property + name: Name of licensed property person_address: Address person_address_city: City person_address_country: Country @@ -314,6 +316,8 @@ en: person_address_zip: Zip code person_company: Company person_email: Email address + person_first_name: Licensor/Owner first name + person_last_name: Licensor/Owner last name person_name: Name person_phone: Phone number person_title: Title @@ -327,16 +331,23 @@ en: address_city: City address_country: Country address_state: State - address_street1: Address + address_street1: Address of Property address_street2: Address (Line 2) address_zip: Zip code + filming_ended_on: Filming end date + filming_started_on: Filming start date + name: Name of property person_address_city: City person_address_country: Country person_address_state: State person_address_street1: Address person_address_street2: Address (Line 2) person_address_zip: Zip code + person_first_name: Owner first name + person_last_name: Owner last name material_release: + description: Description of licensed materials + name: Name of licensed materials person_address: Address person_address_city: City person_address_country: Country @@ -346,6 +357,8 @@ en: person_address_zip: Zip code person_company: Company person_email: Email address + person_first_name: Licensor/Owner first name + person_last_name: Licensor/Owner last name person_name: Name person_phone: Phone number person_title: Title @@ -544,7 +557,7 @@ en: photos: heading: 4 of 4 Photos signer_details: - heading: 2 of 4 Signer Details + heading: 2 of 4 Owner Details index: actions: new: Import Release @@ -578,7 +591,7 @@ en: photos: heading: 4 of 4 Photos signer_details: - heading: 2 of 4 Signer Details + heading: 2 of 4 Licensor/Owner Details index: actions: new: Import Release @@ -741,9 +754,7 @@ en: legal: heading: Legal personal_info: - heading: Person Details - personal_info: - heading: Signer's Contact Information + heading: Licensor/Owner Contact Information signature: heading: Signature appearance_releases: @@ -782,7 +793,7 @@ en: new: cancel: Cancel contact_info: - heading: Signer Information + heading: Owner Contact Information filming_info: heading: Filming Information legal: @@ -797,7 +808,7 @@ en: new: cancel: Cancel contact_info: - heading: Signer's Contact Information + heading: Licensor/Owner Contact Information legal: heading: Legal release_info: diff --git a/db/data_migrations/20200526114957_assign_account_number_and_type_to_zoom_users.rb b/db/data_migrations/20200526114957_assign_account_number_and_type_to_zoom_users.rb new file mode 100644 index 0000000..16b2aee --- /dev/null +++ b/db/data_migrations/20200526114957_assign_account_number_and_type_to_zoom_users.rb @@ -0,0 +1,7 @@ +class AssignAccountNumberAndTypeToZoomUsers < ActiveRecord::DataMigration + def up + ZoomUser.find_each do |zu| + zu.update account_number: ENV.fetch('ZOOM_ACCOUNT_NUMBER'), tier: (ENV['ZOOM_USER_TYPE'] == 'pro' ? 1 : 0) + end + end +end \ No newline at end of file diff --git a/db/migrate/20200526113516_add_account_number_and_type_to_zoom_users.rb b/db/migrate/20200526113516_add_account_number_and_type_to_zoom_users.rb new file mode 100644 index 0000000..8bc0afa --- /dev/null +++ b/db/migrate/20200526113516_add_account_number_and_type_to_zoom_users.rb @@ -0,0 +1,6 @@ +class AddAccountNumberAndTypeToZoomUsers < ActiveRecord::Migration[6.0] + def change + add_column :zoom_users, :account_number, :string + add_column :zoom_users, :tier, :integer, default: 0 + end +end diff --git a/db/migrate/20200603090419_add_filming_hours_to_location_releases.rb b/db/migrate/20200603090419_add_filming_hours_to_location_releases.rb new file mode 100644 index 0000000..f462e35 --- /dev/null +++ b/db/migrate/20200603090419_add_filming_hours_to_location_releases.rb @@ -0,0 +1,5 @@ +class AddFilmingHoursToLocationReleases < ActiveRecord::Migration[6.0] + def change + add_column :location_releases, :filming_hours, :text + end +end diff --git a/db/structure.sql b/db/structure.sql index b748069..d4b1f92 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -1592,7 +1592,9 @@ CREATE TABLE public.zoom_users ( id bigint NOT NULL, api_id character varying, created_at timestamp(6) without time zone NOT NULL, - updated_at timestamp(6) without time zone NOT NULL + updated_at timestamp(6) without time zone NOT NULL, + account_number character varying, + tier integer DEFAULT 0 ); @@ -3499,6 +3501,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20200427073429'), ('20200428091105'), ('20200507110804'), -('20200512161738'); +('20200512161738'), +('20200526113516'); diff --git a/lib/zoom_gateway.rb b/lib/zoom_gateway.rb index 00cd249..21874f7 100644 --- a/lib/zoom_gateway.rb +++ b/lib/zoom_gateway.rb @@ -3,6 +3,7 @@ class ZoomGateway class MeetingExpired < StandardError; end class UserNotFound < StandardError; end class TooManyHosts < StandardError; end + class UserAlreadyExists < StandardError; end class << self def USER_TYPE_NAME @@ -23,6 +24,10 @@ class ZoomGateway "#{self.USER_TYPE_NAME}-directme-host" end + def ACCOUNT_NUMBER + ENV['ZOOM_ACCOUNT_NUMBER'] + end + def enable_recordings? ENV['ZOOM_ENABLE_RECORDINGS'] == '1' end @@ -97,6 +102,8 @@ class ZoomGateway raise UserNotFound, error.message elsif error.status_code == 3001 raise MeetingExpired, error.message + elsif error.status_code == 1005 + raise UserAlreadyExists, error.message else raise error end diff --git a/spec/factories/zoom_users.rb b/spec/factories/zoom_users.rb index 188b749..9fc5e58 100644 --- a/spec/factories/zoom_users.rb +++ b/spec/factories/zoom_users.rb @@ -1,5 +1,9 @@ +require 'zoom_gateway' FactoryBot.define do factory :zoom_user do + account_number ZoomGateway.ACCOUNT_NUMBER + trait ZoomGateway.USER_TYPE_NAME + trait :with_api_id do api_id "api_user_id" end diff --git a/spec/features/user_managing_location_releases_spec.rb b/spec/features/user_managing_location_releases_spec.rb index 8a2c916..9e8a32f 100644 --- a/spec/features/user_managing_location_releases_spec.rb +++ b/spec/features/user_managing_location_releases_spec.rb @@ -17,6 +17,7 @@ feature "User managing location releases" do fill_in person_phone_field, with: "555-555-5555" fill_in person_email_field, with: "jane.doe@test.com" fill_in person_address_street1_field, with: "100 Broadway" + fill_in filming_hours_field, with: "04:00 - 22:00" draw_signature file_fixture("signature.png"), "location_release_signature_base64" end @@ -51,6 +52,7 @@ feature "User managing location releases" do by "filling out the remaining information" do fill_in_release_fields name: "Test Location Release" + fill_in filming_hours_field, with: "04:00 - 22:00" click_button create_release_button expect(page).to have_content(create_release_notice) expect(page).to have_photo("location_photo.png") @@ -136,6 +138,7 @@ feature "User managing location releases" do :native, project: project, name: "Benny's Burritos", + filming_hours: "06:00 - 20:00", tag_list: "Restaurant", notes: [ build(:note, @@ -172,6 +175,8 @@ feature "User managing location releases" do expect(pdf_body).to have_content("Restaurant") expect(pdf_body).to have_content photos_heading.upcase expect(pdf_body).to have_content("location_photo.png") + expect(pdf_body).to have_content("Filming Hours") + expect(pdf_body).to have_content("06:00 - 20:00") end context "when the user is associate" do @@ -222,6 +227,10 @@ feature "User managing location releases" do "location_release[person_phone]" end + def filming_hours_field + "location_release[filming_hours]" + end + def have_photo(filename, attr: "src") have_selector("img[#{attr}*='#{filename}']") end diff --git a/spec/lib/zoom_gateway_spec.rb b/spec/lib/zoom_gateway_spec.rb index a30887a..9154ada 100644 --- a/spec/lib/zoom_gateway_spec.rb +++ b/spec/lib/zoom_gateway_spec.rb @@ -79,6 +79,13 @@ RSpec.describe ZoomGateway do expect(ZoomGateway.enable_recordings?).to be_falsey end end + + context '.ACCOUNT_NUMBER' do + it 'depends on ENV["ZOOM_ACCOUNT_NUMBER"]' do + stub_env_variable('ZOOM_ACCOUNT_NUMBER', 'xxx-yyy-zzz') + expect(ZoomGateway.ACCOUNT_NUMBER).to eq('xxx-yyy-zzz') + end + end end describe ".find_meeting" do @@ -117,9 +124,7 @@ RSpec.describe ZoomGateway do end it 'raises an exception' do - allow(ENV).to receive(:[]).and_call_original - allow(ENV).to receive(:[]).with('ZOOM_USER_TYPE').and_return('pro') - allow(ENV).to receive(:[]).with('ZOOM_PRO_USERS_LIMIT').and_return('2') + stub_env_variables(ZOOM_USER_TYPE: 'pro', ZOOM_PRO_USERS_LIMIT: 2) expect { gateway.create_host('host-email@address') }.to raise_error(ZoomGateway::TooManyHosts) end @@ -133,11 +138,4 @@ RSpec.describe ZoomGateway do end end - private - - def stub_env_variable(name, value) - allow(ENV).to receive(:[]).and_call_original - allow(ENV).to receive(:[]).with(name.to_s).and_return(value.to_s) - end - end diff --git a/spec/models/app_host_spec.rb b/spec/models/app_host_spec.rb index 851d2d6..b3753cd 100644 --- a/spec/models/app_host_spec.rb +++ b/spec/models/app_host_spec.rb @@ -147,10 +147,4 @@ describe AppHost do expect(app_domain.protocol).to eq :http end end - - private - - def stub_env(key, value) - allow(ENV).to receive(:fetch).with(key).and_return(value) - end end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index e5e437c..4cad165 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -79,7 +79,7 @@ RSpec.describe Project, type: :model do context 'there is no meeting' do context 'there is a free user available' do - let!(:free_zoom_user) { create(:zoom_user, api_id: 'user_id') } + let!(:free_zoom_user) { create(:zoom_user, :with_api_id) } before do allow_any_instance_of(ZoomGateway).to receive(:create_meeting).and_return('new-meeting-id') diff --git a/spec/models/zoom_user_spec.rb b/spec/models/zoom_user_spec.rb index c53f78b..2f79533 100644 --- a/spec/models/zoom_user_spec.rb +++ b/spec/models/zoom_user_spec.rb @@ -1,3 +1,4 @@ +require 'zoom_gateway' require 'rails_helper' RSpec.describe ZoomUser, type: :model do @@ -5,6 +6,10 @@ RSpec.describe ZoomUser, type: :model do it { is_expected.to have_many(:zoom_meetings).dependent(:nullify) } end + describe "enums" do + it { is_expected.to define_enum_for(:tier).with_values([:basic, :pro]) } + end + describe 'callbacks' do let(:zoom_user) { build(:zoom_user) } @@ -22,10 +27,120 @@ RSpec.describe ZoomUser, type: :model do zoom_user.save expect(zoom_user.api_id).to eq "retrieved_api_id" end + + it 'assigns current account number' do + allow_any_instance_of(ZoomGateway).to receive(:create_host).and_return("retrieved_api_id") + ENV['ZOOM_ACCOUNT_NUMBER'] = 'xxx-yyy-zzz' + + zoom_user.save + expect(zoom_user.account_number).to eq 'xxx-yyy-zzz' + end end context '#before_destroy' do pending 'aborts if there is api_id assigned' end end + + describe 'scopes' do + context '.current_account' do + before do + create_list(:zoom_user, 10, :with_api_id, account_number: 'first-account-id') + create_list(:zoom_user, 25, :with_api_id, account_number: 'second-account-id') + end + + it 'only returns users from currently set account' do + ENV['ZOOM_ACCOUNT_NUMBER'] = 'first-account-id' + expect(ZoomUser.current_account.count).to eq 10 + expect(ZoomUser.current_account.pluck(:account_number).uniq.count).to eq 1 + expect(ZoomUser.current_account.pluck(:account_number).uniq.first).to eq 'first-account-id' + end + end + + context '.free' do + let(:free_user) { create(:zoom_user, :with_api_id) } + let(:busy_user) { create(:zoom_user, :with_api_id) } + let(:second_busy_user) { create(:zoom_user, :with_api_id) } + let!(:meeting_started) { create(:zoom_meeting, zoom_user: busy_user, status: :started) } + let!(:meeting_created) { create(:zoom_meeting, zoom_user: second_busy_user, status: :created) } + + it 'returns only the users without started / created meetings' do + users = ZoomUser.free + + expect(users).to include(free_user) + expect(users).not_to include(busy_user) + expect(users).not_to include(second_busy_user) + end + end + end + + + describe '.current_account?' do + let(:zoom_user) { create(:zoom_user, :with_api_id, account_number: 'xxx-xxx-xxx') } + + it 'returns true if it belongs to currently set account' do + ENV['ZOOM_ACCOUNT_NUMBER'] = 'xxx-xxx-xxx' + expect(zoom_user.current_account?).to be_truthy + end + + it 'returns false if it doesn\'t belong to currently set account' do + ENV['ZOOM_ACCOUNT_NUMBER'] = 'yyy-yyy-yyy' + expect(zoom_user.current_account?).to be_falsey + end + end + + + context 'static methods' do + describe '.generate_api_email' do + it 'contains @' do + expect(ZoomUser.generate_api_email).to include('@') + end + end + + describe '.for_new_meeting' do + let(:a_basic) { create(:zoom_user, :with_api_id, account_number: 'aaa', tier: :basic) } + let(:b_basic) { create(:zoom_user, :with_api_id, account_number: 'bbb', tier: :basic) } + let(:a_pro) { create(:zoom_user, :with_api_id, account_number: 'aaa', tier: :pro) } + let(:b_pro) { create(:zoom_user, :with_api_id, account_number: 'bbb', tier: :pro) } + + it 'picks free user of requested type from current account' do + [a_basic, a_pro, b_basic, b_pro] + + stub_env_variables(ZOOM_USER_TYPE: 'basic', ZOOM_ACCOUNT_NUMBER: 'aaa') + expect(ZoomUser.for_new_meeting).to eq(a_basic) + + stub_env_variables(ZOOM_USER_TYPE: 'pro', ZOOM_ACCOUNT_NUMBER: 'aaa') + expect(ZoomUser.for_new_meeting).to eq(a_pro) + + stub_env_variables(ZOOM_USER_TYPE: 'basic', ZOOM_ACCOUNT_NUMBER: 'bbb') + expect(ZoomUser.for_new_meeting).to eq(b_basic) + + stub_env_variables(ZOOM_USER_TYPE: 'pro', ZOOM_ACCOUNT_NUMBER: 'bbb') + expect(ZoomUser.for_new_meeting).to eq(b_pro) + end + + context 'no free user' do + before do + allow_any_instance_of(ZoomGateway).to receive(:create_host).and_return('host-id') + end + + it 'creates new user if there is no requested user free available under account' do + [a_basic, a_pro, b_basic] + stub_env_variables(ZOOM_USER_TYPE: 'pro', ZOOM_ACCOUNT_NUMBER: 'bbb') + + expect_any_instance_of(ZoomGateway).to receive(:create_host) + ZoomUser.for_new_meeting + end + + it 'creates new user if requested user is busy' do + [a_basic, a_pro, b_basic, b_pro] + stub_env_variables(ZOOM_USER_TYPE: 'pro', ZOOM_ACCOUNT_NUMBER: 'aaa') + create(:zoom_meeting, zoom_user: a_pro, status: :started) + + expect_any_instance_of(ZoomGateway).to receive(:create_host) + ZoomUser.for_new_meeting + end + end + end + end end diff --git a/spec/support/env_helper.rb b/spec/support/env_helper.rb new file mode 100644 index 0000000..257a1ca --- /dev/null +++ b/spec/support/env_helper.rb @@ -0,0 +1,16 @@ +module EnvHelper + def stub_env_variables(vars) + allow(ENV).to receive(:[]).and_call_original + vars.each do |variable, value| + allow(ENV).to receive(:[]).with(variable.to_s).and_return(value) + end + end + + def stub_env_variable(key, value) + stub_env_variables({key => value}) + end +end + +RSpec.configure do |config| + config.include EnvHelper +end