Initial commit

This commit is contained in:
Senad Uka
2020-05-31 22:38:19 +02:00
commit 858fafc3c5
1280 changed files with 65918 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
require 'rails_helper'
RSpec.describe AccountAuth, type: :model do
describe "associations" do
it { is_expected.to belong_to(:user) }
it { is_expected.to belong_to(:account) }
end
describe "enums" do
it { is_expected.to define_enum_for(:role).with_values(associate: 0, project_manager: 1, account_manager: 2) }
end
describe "validations" do
describe "#user_id" do
it { is_expected.to validate_uniqueness_of(:user_id).scoped_to(:account_id).with_message("already added to account.") }
end
end
end

236
spec/models/account_spec.rb Normal file
View File

@@ -0,0 +1,236 @@
require "rails_helper"
RSpec.describe Account do
describe "associations" do
it { is_expected.to have_many(:users).through(:account_auths) }
it { is_expected.to have_many(:projects).dependent(:destroy) }
it { is_expected.to have_many(:contract_templates).through(:projects) }
end
describe "validations" do
it { is_expected.to validate_presence_of(:name) }
it { is_expected.to validate_presence_of(:slug) }
describe "#slug uniqueness" do
subject { build(:account) }
it "validates uniqueness of slug" do
allow(subject).to receive(:set_slug)
expect(subject).to validate_presence_of(:slug)
end
end
end
describe "generating a slug" do
context "when name and slug are not present" do
it "does not generate a slug" do
account = build(:account, name: nil, slug: nil)
account.save
expect(account.slug).to be_nil
end
end
context "when a name is present and a slug is not present" do
it "generates a slug" do
account = build(:account, name: "Half Pint Courter", slug: nil)
account.save
expect(account.slug).to eq "half-pint-courter"
end
end
context "when name and slug are both present" do
it "does not generate a slug" do
account = build(:account, name: "Half Pint Courter", slug: "half-pint-courter2")
account.save
expect(account.slug).to eq "half-pint-courter2"
end
end
context "when name is not unique" do
it "generates a unique slug" do
account_one = create(:account, name: "Half Pint Courter", slug: "half-pint-courter")
account_two = create(:account, name: "Half Pint Courter", slug: "half-pint-courter-2")
account_three = build(:account, name: "Half Pint Courter", slug: nil)
account_three.save
expect(account_three.slug).to eq "half-pint-courter-3"
end
end
end
describe "#storage_total" do
it "sums videos, release photos, contracts, signatures, recordings" do
video_file = Rack::Test::UploadedFile.new(Rails.root.join("spec", "fixtures", "files", "video_file.mp4"), "video/mp4")
recording_file = Rack::Test::UploadedFile.new(Rails.root.join("spec", "fixtures", "files", "video_file.mp4"), "video/mp4")
photo_file = Rack::Test::UploadedFile.new(Rails.root.join("spec", "fixtures", "files", "person_photo.png"), "image/png")
contract_file = Rack::Test::UploadedFile.new(Rails.root.join("spec", "fixtures", "files", "contract.pdf"), "application/pdf")
signature_file = Rack::Test::UploadedFile.new(Rails.root.join("spec", "fixtures", "files", "signature.png"), "image/png")
edl_file = Rack::Test::UploadedFile.new(Rails.root.join("spec", "fixtures", "files", "sample-edl.edl"), "application/octet-stream")
expect(video_file.size).to eq 1_055_736
expect(recording_file.size).to eq 1_055_736
expect(edl_file.size).to eq 440
expect(photo_file.size).to eq 910
expect(contract_file.size).to eq 12
expect(signature_file.size).to eq 2_509
account = create(:account)
project = create(:project, account: account)
video = create(:video, project: project, file: video_file, edl_file: edl_file)
appearance_release = create(:appearance_release, project: project, person_photo: photo_file, contract: contract_file, signature: signature_file)
talent_release = create(:talent_release, project: project, photos: [photo_file], contract: contract_file, signature: signature_file)
material_release = create(:material_release, project: project, photos: [photo_file], contract: contract_file, signature: signature_file)
location_release = create(:location_release, project: project, photos: [photo_file], contract: contract_file, signature: signature_file)
acquired_media_release = create(:acquired_media_release, project: project, contract: contract_file)
import = create(:import, project: project, file: contract_file)
music_release = create(:music_release, project: project, contract: contract_file)
zoom_meeting = create(:zoom_meeting, project: project, recording: recording_file)
expect(account.storage_total).to eq 2_125_672
end
it "sums only for projects tied to account" do
video_file = Rack::Test::UploadedFile.new(Rails.root.join("spec", "fixtures", "files", "video_file.mp4"), "video/mp4")
edl_file = Rack::Test::UploadedFile.new(Rails.root.join("spec", "fixtures", "files", "sample-edl.edl"), "application/octet-stream")
expect(video_file.size).to eq 1_055_736
expect(edl_file.size).to eq 440
account = create(:account)
project = create(:project, account: account)
other_account_project = create(:project, account: create(:account))
create(:video, project: project, file: video_file, edl_file: edl_file)
create(:video, project: other_account_project, file: video_file, edl_file: edl_file)
expect(account.storage_total).to eq 1_056_176
end
it "fails when we do not account for models that have attachments" do
models_with_attachments = [
AppearanceRelease,
TalentRelease,
MaterialRelease,
LocationRelease,
AcquiredMediaRelease,
Import,
MusicRelease,
Video,
SampleAppearanceRelease,
ActiveStorage::Blob,
ActionText::RichText,
Directory,
Download,
User,
Broadcast,
Account,
ZoomMeeting
]
Rails.application.eager_load!
ActiveRecord::Base.descendants.each do |model|
if model.reflections.keys.any? { |x| x.match? /_attachments?/ }
unless models_with_attachments.include?(model)
fail("Warning! #{model} may have an unaccounted for attachment, please add to #storage_total")
end
end
end
end
end
describe "#me_suite_enabled?" do
it "returns true when plan_uid is me_suite" do
expect(build(:account, plan_uid: "me_suite").me_suite_enabled?).to eq true
end
it "returns false when plan_uid is not me_suite" do
expect(build(:account, plan_uid: "deliverme").me_suite_enabled?).to eq false
end
end
describe "#deliverme_enabled?" do
it "returns true when plan_uid is me_suite" do
expect(build(:account, plan_uid: "me_suite").deliverme_enabled?).to eq true
end
it "returns true when plan_uid is deliverme" do
expect(build(:account, plan_uid: "deliverme").deliverme_enabled?).to eq true
end
it "returns false when plan_uid is not deliverme" do
expect(build(:account, plan_uid: "releaseme").deliverme_enabled?).to eq false
end
end
describe "#directme_enabled?" do
it "returns true when plan_uid is me_suite" do
expect(build(:account, plan_uid: "me_suite").directme_enabled?).to eq true
end
it "returns true when plan_uid is directme" do
expect(build(:account, plan_uid: "directme").directme_enabled?).to eq true
end
it "returns false when plan_uid is not directme" do
expect(build(:account, plan_uid: "releaseme").directme_enabled?).to eq false
end
end
describe "#releaseme_enabled?" do
it "returns true when plan_uid is me_suite" do
expect(build(:account, plan_uid: "me_suite").releaseme_enabled?).to eq true
end
it "returns true when plan_uid is releaseme" do
expect(build(:account, plan_uid: "releaseme").releaseme_enabled?).to eq true
end
it "returns false when plan_uid is not releaseme" do
expect(build(:account, plan_uid: "deliverme").releaseme_enabled?).to eq false
end
end
describe "#plan_name" do
context "when plan_uid deliverme" do
it "returns DeliverME" do
expect(build(:account, plan_uid: "deliverme").plan_name).to eq "DeliverME"
end
end
context "when plan_uid directme" do
it "returns DirectME" do
expect(build(:account, plan_uid: "directme").plan_name).to eq "DirectME"
end
end
context "when plan_uid releaseme" do
it "returns ReleaseME" do
expect(build(:account, plan_uid: "releaseme").plan_name).to eq "ReleaseME"
end
end
context "when plan_uid me_suite" do
it "returns ME Suite" do
expect(build(:account, plan_uid: "me_suite").plan_name).to eq "ME Suite"
end
end
end
describe "#managers" do
it "returns users who have the account manager role" do
account = build(:account)
account_manager = create(:user, :account_manager, accounts: [account])
project_manager = create(:user, :manager, accounts: [account])
managers = account.managers
expect(managers).to include(account_manager)
expect(managers).not_to include(project_manager)
end
end
end

View File

@@ -0,0 +1,61 @@
require "rails_helper"
RSpec.describe AcquiredMediaRelease do
it_behaves_like "a contractable"
it_behaves_like "an exploitable"
it_behaves_like "a notable"
it_behaves_like "a releasable"
it_behaves_like "a taggable"
context "for native releases" do
it { is_expected.to validate_attachment_of(:signature).on(:native) }
end
context "for non-native releases" do
it { is_expected.to validate_attachment_of(:contract).on(:non_native) }
end
describe "associations" do
it { is_expected.to have_many(:file_infos).dependent(:destroy) }
end
describe "nested attributes" do
it { is_expected.to accept_nested_attributes_for(:file_infos) }
end
describe "validations" do
it { is_expected.to validate_presence_of(:name) }
describe "#person_email" do
it { is_expected.to allow_value("test@test.com", nil).for(:person_email) }
it { is_expected.not_to allow_values("foo", "test@foo", "N/A").for(:person_email) }
end
end
describe "attachments" do
it { is_expected.to respond_to(:contract) }
end
describe "#uses_edl?" do
it { is_expected.to be_uses_edl }
end
describe "#contract_file_name" do
it "includes project name, release type, signed at date, release number and release name" do
release = create(:acquired_media_release_with_contract_template, signed_at: Date.new(2020, 2, 10), name: "sample release")
expect(release.contract_file_name).to eq("my-video-project_acquired_media_2020.02.10_1_sample-release")
end
context "when signed at is nil" do
it "uses the created at date" do
release = create(:acquired_media_release_with_contract_template,
signed_at: nil,
created_at: DateTime.new(2020, 2, 10, 12, 0, 0),
name: "sample release")
expect(release.contract_file_name).to eq("my-video-project_acquired_media_2020.02.10_1_sample-release")
end
end
end
end

View File

@@ -0,0 +1,77 @@
require "rails_helper"
describe Address do
describe "#format" do
it "prints the address in a single line" do
address = Address.new("100 Test Lane", "Suite 1", "New York", "NY", "10001", "US")
expect(address.to_s).to eq("100 Test Lane, Suite 1, New York, NY 10001, US")
end
it "prints the address condensed into two lines" do
address = Address.new("100 Test Lane", "Suite 1", "New York", "NY", "10001", "US")
actual = address.to_s(format: :condensed)
expected = <<~END
100 Test Lane, Suite 1
New York, NY 10001, US
END
expect(actual).to eq(expected.chomp)
end
it "prints the address in full postal format" do
address = Address.new("100 Test Lane", "Suite 1", "New York", "NY", "10001", "US")
actual = address.to_s(format: :full)
expected = <<~END
100 Test Lane
Suite 1
New York, NY 10001
US
END
expect(actual).to eq(expected.chomp)
end
context "when there is no 2nd street line" do
it "does not add extra commas to the single line format" do
address = Address.new("100 Test Lane", "", "New York", "NY", "10001", "US")
expect(address.to_s).to eq("100 Test Lane, New York, NY 10001, US")
end
it "does not add extra newlines to the full format" do
address = Address.new("100 Test Lane", "", "New York", "NY", "10001", "US")
actual = address.to_s(format: :full)
expected = <<~END
100 Test Lane
New York, NY 10001
US
END
expect(actual).to eq(expected.chomp)
end
end
end
describe "#present?" do
it "returns false when no parts of the address are present" do
address = Address.new("", "", "", "", "", "")
expect(address).not_to be_present
end
it "returns true when any part of the address is present" do
%w(street1 street2 city state zip country).each do |part|
address = Address.new("", "", "", "", "", "")
expect(address).not_to be_present
address.public_send("#{part}=", "value")
expect(address).to be_present
end
end
end
end

View File

@@ -0,0 +1,75 @@
require "rails_helper"
RSpec.describe AnalysisNotification, type: :model do
describe "#build" do
context "for audio type" do
it "returns AudioAnalysisNotification subclass" do
notification = described_class.build("audio", "job_id")
expect(notification).to be_a(AnalysisNotification::AudioAnalysisNotification)
expect(notification.job_id).to eq "job_id"
end
end
context "for video type" do
it "returns VideoAnalysisNotification subclass" do
notification = described_class.build("video", "job_id")
expect(notification).to be_a(AnalysisNotification::VideoAnalysisNotification)
expect(notification.job_id).to eq "job_id"
end
end
end
describe AnalysisNotification::VideoAnalysisNotification do
let!(:video) { create(:video, analysis_uid: "job_id") }
subject { described_class.new("job_id") }
describe "#video" do
it "fetches video using job id" do
expect(subject.video).to eq video
end
end
describe "#success!" do
it "updates status of the video" do
subject.success!
expect(video.reload).to be_analysis_success
end
end
describe "#failure!" do
it "updates status of the video" do
subject.failure!
expect(video.reload).to be_analysis_failure
end
end
end
describe AnalysisNotification::AudioAnalysisNotification do
let!(:video) { create(:video, audio_analysis_uid: "job_id") }
subject { described_class.new("job_id") }
describe "#video" do
it "fetches video using job id" do
expect(subject.video).to eq video
end
end
describe "#success!" do
it "updates status of the video" do
subject.success!
expect(video.reload).to be_audio_analysis_success
end
end
describe "#failure!" do
it "updates status of the video" do
subject.failure!
expect(video.reload).to be_audio_analysis_failure
end
end
end
end

View File

@@ -0,0 +1,156 @@
require "rails_helper"
describe AppHost do
describe "#domain" do
it "returns the domain set in the environment" do
env = { "DOMAIN" => "test-domain.com" }
app_domain = AppHost.new(env, "development")
expect(app_domain.domain).to eq("test-domain.com")
end
context "when domain is not set in the environment" do
it "returns the default domain for the development environment" do
env = {}
app_domain = AppHost.new(env, "development")
expect(app_domain.domain).to eq("localhost")
end
it "returns the default domain for the test environment" do
env = {}
app_domain = AppHost.new(env, "test")
expect(app_domain.domain).to eq("localhost")
end
it "returns the default domain for the production environment" do
env = {}
app_domain = AppHost.new(env, "production")
expect(app_domain.domain).to eq("bigmedia.ai")
end
end
end
describe "#port" do
it "returns the port set in the environment" do
env = { "WEB_PORT" => 4000 }
app_domain = AppHost.new(env, "development")
expect(app_domain.port).to eq(4000)
end
context "when port is not set in the environment" do
it "returns the port domain for the development environment" do
env = {}
app_domain = AppHost.new(env, "development")
expect(app_domain.port).to eq(3000)
end
it "returns the default port for the test environment" do
env = {}
app_domain = AppHost.new(env, "test")
expect(app_domain.port).to eq(31337)
end
it "returns the default port for the production environment" do
env = {}
app_domain = AppHost.new(env, "production")
expect(app_domain.port).to eq(nil)
end
end
end
describe "#domain_with_port" do
it "returns the combination of domain with the port" do
env = { "DOMAIN" => "test-domain.com", "WEB_PORT" => 4000 }
app_domain = AppHost.new(env, "development")
expect(app_domain.domain_with_port).to eq("test-domain.com:4000")
end
context "when port is not specified at all" do
it "omits the port portion of the URL" do
env = { "DOMAIN" => "test-domain.com" }
app_domain = AppHost.new(env, "production")
expect(app_domain.domain_with_port).to eq("test-domain.com")
end
end
end
describe "#use_ssl" do
it "returns true if the value set in the environment" do
env = { "USE_SSL" => "true" }
app_domain = AppHost.new(env, "development")
expect(app_domain).to be_using_ssl
end
context "when the value is not set in the environment" do
it "returns the default value for the development environment" do
env = {}
app_domain = AppHost.new(env, "development")
expect(app_domain).not_to be_using_ssl
end
it "returns the default value for the test environment" do
env = {}
app_domain = AppHost.new(env, "test")
expect(app_domain).not_to be_using_ssl
end
it "returns the default value for the production environment" do
env = {}
app_domain = AppHost.new(env, "production")
expect(app_domain).to be_using_ssl
end
end
end
describe "#protocol" do
it "returns 'https' when using SSL" do
env = { "USE_SSL" => true }
app_domain = AppHost.new(env)
expect(app_domain.protocol).to eq :https
end
it "returns 'http's when not using SSL" do
env = {}
app_domain = AppHost.new(env)
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

View File

@@ -0,0 +1,176 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe AppearanceRelease do
it_behaves_like 'a contractable'
it_behaves_like 'an exploitable'
it_behaves_like 'a notable'
it_behaves_like 'a releasable'
it_behaves_like 'a taggable'
it { is_expected.to respond_to(:photos) }
it { is_expected.to respond_to(:photo) }
describe 'associations' do
it { is_expected.to have_many(:video_release_confirmations).dependent(:destroy) }
it { is_expected.to have_many(:confirmed_videos).source(:video).through(:video_release_confirmations) }
end
describe 'validations' do
it { is_expected.to allow_content_types('image/png', 'image/jpeg').for(:person_photo) }
it { is_expected.not_to allow_content_types('application/pdf', 'image/gif').for(:person_photo) }
it { is_expected.to allow_value('test@test.com', nil).for(:person_email) }
it { is_expected.not_to allow_values('foo', 'test@foo', 'N/A').for(:person_email) }
it { is_expected.to validate_presence_of(:person_first_name) }
it { is_expected.to validate_presence_of(:person_last_name) }
context 'for native releases' do
it { is_expected.to validate_attachment_of(:person_photo).on(:native) }
it { is_expected.to validate_attachment_of(:signature).on(:native) }
it 'validates person_photo_is_acceptable on new records' do
appearance_release = build(:appearance_release)
allow(BrayniacAI::Validation).to receive(:create).and_return(double(:validation, valid: false, error: 'api error'))
expect(appearance_release.valid?(:native)).to eq false
expect(appearance_release.errors[:person_photo]).to eq ['api error']
end
it 'does not validate person_photo_is_acceptable on existing records' do
appearance_release = create(:appearance_release, :native)
expect(appearance_release.valid?(:native)).to eq true
end
end
context 'for non-native releases' do
it 'fails to create release if nothing is attached' do
release = create(:appearance_release, :without_person_photo)
expect(release.valid?(:non_native)).to eq false
end
it 'creates release if only contract is attached' do
release = create(:appearance_release, :without_person_photo, :non_native)
expect(release.valid?(:non_native)).to eq true
end
it 'creates release if only person_photo is attached' do
release = create(:appearance_release, :with_person_photo_only)
expect(release.valid?(:non_native)).to eq true
end
end
context 'when the signer is a minor' do
subject { build(:appearance_release, minor: true) }
it { is_expected.to validate_presence_of(:guardian_first_name) }
it { is_expected.to validate_presence_of(:guardian_last_name) }
end
end
describe 'attachments' do
it { is_expected.to respond_to(:contract) }
it { is_expected.to respond_to(:person_photo) }
it { is_expected.to respond_to(:signature) }
end
describe 'scopes' do
describe '.complete' do
it 'returns records that have both a person photo and a contract' do
skip "Test is inconsistently failing in CI"
without_photo_or_contract = create(:appearance_release, person_photo: nil, contract: nil)
with_photo_without_contract = create(:appearance_release, contract: nil)
without_photo_with_contract = create(:appearance_release, :non_native, person_photo: nil)
with_photo_and_contract = create(:appearance_release, :non_native)
complete_releases = described_class.complete
all_releases = described_class.all
expect(complete_releases).not_to include(all_releases[0])
expect(complete_releases).not_to include(all_releases[1])
expect(complete_releases).not_to include(all_releases[2])
expect(complete_releases).to include(all_releases[3])
end
end
describe '.incomplete' do
it 'returns records that are missing either a person photo or a contract' do
skip "Test is inconsistently failing in CI"
without_photo_or_contract = create(:appearance_release, person_photo: nil, contract: nil)
with_photo_without_contract = create(:appearance_release, contract: nil)
without_photo_with_contract = create(:appearance_release, :non_native, person_photo: nil)
with_photo_and_contract = create(:appearance_release, :non_native)
incomplete_releases = described_class.incomplete
all_releases = described_class.all
expect(incomplete_releases).to include(all_releases[0])
expect(incomplete_releases).to include(all_releases[1])
expect(incomplete_releases).to include(all_releases[2])
expect(incomplete_releases).not_to include(all_releases[3])
end
end
describe '.with_person_photo' do
it 'returns records that have a person photo attachment' do
with_photo = create(:appearance_release, :with_person_photo)
without_photo = create(:appearance_release, :without_person_photo)
results = described_class.with_person_photo
expect(results.size).to eq 1
expect(results).to include(with_photo)
expect(results).not_to include(without_photo)
end
end
end
describe '#native?' do
it 'returns true when the release has a signature' do
release = build(:appearance_release, :native)
expect(release).to be_native
end
end
describe '#uses_edl?' do
it { is_expected.to be_uses_edl }
end
describe '#photos' do
it 'returns photo if it is attached' do
ar = create(:appearance_release)
expect(ar.photos).to eq [ar.photo]
end
it 'returns empty list if photo is not attached' do
ar = AppearanceRelease.new
expect(ar.photos).to eq []
end
end
describe '#contract_file_name' do
it 'includes signed timestamp, release number, and person name' do
release = create(:appearance_release_with_contract_template, signed_at: Date.new(2020, 2, 10), person_first_name: 'John', person_last_name: 'Doe')
expect(release.contract_file_name).to eq('my-video-project_appearance_2020.02.10_1_doe-john')
end
context 'when signed at is nil' do
it 'uses the created at date' do
release = create(:appearance_release_with_contract_template,
signed_at: nil,
created_at: DateTime.new(2020, 2, 10, 12, 0, 0),
person_first_name: 'John', person_last_name: 'Doe')
expect(release.contract_file_name).to eq('my-video-project_appearance_2020.02.10_1_doe-john')
end
end
end
end

View File

@@ -0,0 +1,5 @@
require "rails_helper"
RSpec.describe ApplicableMedium, type: :model do
it_behaves_like "a freeformable"
end

View File

@@ -0,0 +1,68 @@
require "rails_helper"
RSpec.describe AudioAnalysis, type: :model do
let(:video) { build(:video, :with_audio_only_edl_file, audio_analysis_uid: "123abc") }
subject { AudioAnalysis.new(video) }
describe "#to_hash" do
it "includes edl" do
allow(ENV).to receive(:[])
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("mybucket")
expect(subject.to_hash).to include({
edl_bucket_name: "mybucket",
edl_object_name: video.audio_only_edl_file.key,
})
end
it "includes acquired media audio file infos" do
create(:acquired_media_release, project: video.project, file_infos: [
build(:file_info, id: 1, filename: "acquired_media_1.mp3", content_type: "audio/mp3"),
build(:file_info, id: 2, filename: "acquired_media_2.aif", content_type: "audio/aif"),
build(:file_info, id: 3, filename: "acquired_media_3.wav", content_type: "audio/wav"),
build(:file_info, id: 4, filename: "acquired_media_4.mov", content_type: "video/mov"),
build(:file_info, id: 5, filename: "acquired_media_4.mp4", content_type: "video/mp4"),
])
expect(subject.to_hash).to have_key(:acquired_audio)
expect(subject.to_hash[:acquired_audio]).to include(id: 1, filename: "acquired_media_1.mp3")
expect(subject.to_hash[:acquired_audio]).to include(id: 2, filename: "acquired_media_2.aif")
expect(subject.to_hash[:acquired_audio]).to include(id: 3, filename: "acquired_media_3.wav")
expect(subject.to_hash[:acquired_audio]).not_to include(id: 4, filename: "acquired_media_4.mov")
expect(subject.to_hash[:acquired_audio]).not_to include(id: 5, filename: "acquired_media_5.mp4")
end
it "includes music release file infos" do
create(:music_release,
project: video.project,
file_infos: [
build(:file_info, id: 1, filename: "original_music_1.mp3"),
build(:file_info, id: 2, filename: "original_music_2.mp3"),
],
composers: build_list(:composer, 1),
publishers: build_list(:publisher, 1),
)
expect(subject.to_hash).to have_key(:original_music)
expect(subject.to_hash[:original_music]).to include(id: 1, filename: "original_music_1.mp3",
composers: "Beethoven, Affiliation, 100.0",
publishers: "Jingle Punks, Affiliation, 100.0")
expect(subject.to_hash[:original_music]).to include(id: 2, filename: "original_music_2.mp3",
composers: "Beethoven, Affiliation, 100.0",
publishers: "Jingle Punks, Affiliation, 100.0")
end
end
describe "#results" do
it "returns response from API request using audio analysis uid" do
response = double("response", results: [])
edl_event_gateway = double("edl_event_gateway", fps: 29.97, edl_offset_seconds: 0)
allow(EdlEventGateway).to receive(:new).and_return(edl_event_gateway)
allow(BrayniacAI::AudioRecognition).to receive(:find).and_return(response)
expect(subject.results).to eq(response.results)
expect(BrayniacAI::AudioRecognition).to have_received(:find).with(video.audio_analysis_uid, params: { fps: 29.97, edl_offset_seconds: 0 })
end
end
end

View File

@@ -0,0 +1,55 @@
require "rails_helper"
RSpec.describe AudioConfirmation do
describe "associations" do
it { is_expected.to belong_to(:video) }
end
describe "validations" do
it { is_expected.to validate_presence_of(:time_elapsed) }
describe "confirmation_type" do
it "validates only original_music and library_music are allowed" do
expect(build(:audio_confirmation, confirmation_type: "original_music").valid?).to eq true
expect(build(:audio_confirmation, confirmation_type: "library_music").valid?).to eq true
expect(build(:audio_confirmation, confirmation_type: "unknown_music").valid?).to eq false
end
end
end
describe "#appears_at" do
it "returns formatted timecode" do
audio_confirmation = build(:audio_confirmation, time_elapsed: "1.039")
expect(audio_confirmation.appears_at).to eq "00:00:01:01"
end
end
describe "#presented_source_file_name" do
context "when confirmation_type is original_music" do
it "returns source_file_name with (O) prefix" do
audio_confirmation = build(:audio_confirmation, confirmation_type: "original_music", source_file_name: "source_file_name")
expect(audio_confirmation.presented_source_file_name).to eq "(O) source_file_name"
end
end
context "when confirmation_type is library_music" do
it "returns source_file_name with (L) prefix" do
audio_confirmation = build(:audio_confirmation, confirmation_type: "library_music", source_file_name: "source_file_name")
expect(audio_confirmation.presented_source_file_name).to eq "(L) source_file_name"
end
end
end
describe "#confirmation_type_library?" do
it "returns true when confirmation_type is library" do
expect(build(:audio_confirmation, :library)).to be_confirmation_type_library
end
it "returns false when confirmation_type is not library" do
expect(build(:audio_confirmation, :original)).not_to be_confirmation_type_library
end
end
end

View File

@@ -0,0 +1,54 @@
require "rails_helper"
RSpec.describe AudioFilesForRequest do
let(:video) do
create(:video, :with_audio_only_edl_file, analysis_uid: "analysis_uid") do |video|
video.file.key = "awesome"
video.audio_only_edl_file.key = "sauce"
end
end
subject { described_class.new(video, "offset") }
describe "#start_timecode_offset" do
it "returns given start_timecode_offset" do
expect(subject.start_timecode_offset).to eq "offset"
end
end
describe "#file_object_name" do
it "returns file key" do
expect(subject.file_object_name).to eq "awesome"
end
it "returns nil when no video file attached" do
video.file.purge
expect(subject.file_object_name).to be_nil
end
end
describe "#edl_file_object_name" do
it "returns audio edl file key" do
expect(subject.edl_file_object_name).to eq "sauce"
end
it "returns nil when no video file attached" do
video.audio_only_edl_file.purge
expect(subject.edl_file_object_name).to be_nil
end
end
describe "#aws_bucket_name" do
it "returns AWS bucket name" do
allow(ENV).to receive(:[])
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("bucket")
expect(subject.aws_bucket_name).to eq "bucket"
end
end
describe "#job_id" do
it "returns the analysis uid of the video" do
expect(subject.job_id).to eq "analysis_uid"
end
end
end

View File

@@ -0,0 +1,56 @@
# frozen_string_literal: true
require 'rails_helper'
describe BlankContract do
describe 'rendering the contract' do
let(:project) { build(:project) }
it 'works with appearance releases' do
appearance_release = create(:appearance_release_with_contract_template, project: project, person_name: 'Jane Doe')
result = render_contract_html_for(appearance_release)
expect(result).not_to be_nil
end
it 'works with talent releases' do
talent_release = create(:talent_release_with_contract_template, project: project, person_name: 'Jane Doe')
result = render_contract_html_for(talent_release)
expect(result).not_to be_nil
end
it 'works with location releases' do
location_release = create(:location_release_with_contract_template, project: project, person_name: 'Jane Doe')
result = render_contract_html_for(location_release)
expect(result).not_to be_nil
end
it 'works with material releases' do
material_release = create(:material_release_with_contract_template, project: project, person_name: 'Jane Doe')
result = render_contract_html_for(material_release)
expect(result).not_to be_nil
end
it 'renders a QR code, serial number and warning not to copy' do
material_release = create(:material_release_with_contract_template, project: project, person_name: 'Jane Doe')
result = render_contract_html_for(material_release)
expect(result).to include 'serial-number'
expect(result).to include 'DO NOT COPY'
end
end
private
# Reaching into the object's internals a bit here to avoid generating a PDF unnecessarily
def render_contract_html_for(releasable)
BlankContract.new(releasable).send(:as_html)
end
end

View File

@@ -0,0 +1,11 @@
require 'rails_helper'
describe Bookmark do
describe 'associations' do
it { is_expected.to belong_to(:video) }
end
describe "enums" do
it { is_expected.to define_enum_for(:category).with_values("Other": 0, "Audio": 1, "Graphics": 2, "Video": 3) }
end
end

View File

@@ -0,0 +1,46 @@
require 'rails_helper'
RSpec.describe BroadcastRecording, type: :model do
describe "associations" do
it { is_expected.to belong_to(:broadcast) }
end
describe "validations" do
subject { described_class.new(asset_uid: "asset_uid", asset_playback_uid: "playback_uid", file_name: "medium.mp4") }
it { is_expected.to validate_uniqueness_of(:asset_uid) }
end
describe "#delegations" do
it { should delegate_method(:name).to(:broadcast).with_prefix(:broadcast) }
end
describe "#order_by_recent" do
subject { described_class }
it { is_expected.to respond_to(:order_by_recent) }
end
describe "#download_url" do
let(:broadcast) { create(:broadcast, :with_stream, skip_create_callback: true, name: "My Broadcast") }
let(:broadcast_recording) { create(:broadcast_recording, broadcast: broadcast) }
it "should have a download url" do
download_file_name = broadcast_recording.send(:download_file_name)
expect(broadcast_recording.download_url).to eq("https://stream.mux.com/asset_playback_uid/high.mp4?download=#{download_file_name}")
end
end
describe "#download_file_name" do
it "includes the name of the live stream and the created datetime" do
broadcast = create(:broadcast, skip_create_callback: true, name: "My Broadcast")
recording = create(:broadcast_recording, broadcast: broadcast, created_at: DateTime.new(2020, 05, 14, 15, 30, 00))
file_name = recording.download_file_name
expect(file_name).to eq "my-broadcast_date_2020-05-14_time_15-30-00"
end
end
after do
# Set the callback again or it will affect other test cases where the callback is required
Broadcast.set_callback(:create, :after, :create_mux_live_stream)
end
end

View File

@@ -0,0 +1,62 @@
require 'rails_helper'
RSpec.describe Broadcast, type: :model do
describe "associations" do
it { is_expected.to belong_to(:project) }
end
describe "validations" do
it { is_expected.to validate_presence_of(:name) }
it { is_expected.to have_secure_token(:token) }
end
describe "enums" do
it { is_expected.to define_enum_for(:status).with_values([:created, :active, :idle]) }
it { is_expected.to define_enum_for(:streamer_status).with_values([:idle, :connected, :recording, :disconnected]).with_prefix(:streamer) }
end
describe "callbacks" do
context "#after_create" do
let(:broadcast) { build(:broadcast, name: "My Broadcast") }
let(:live_stream_data) { OpenStruct.new(data: OpenStruct.new(id: "stream_id", stream_key: "stream_key")) }
let(:live_stream_playback_data) { OpenStruct.new(data: OpenStruct.new(id: "playback_id")) }
it 'triggers create_mux_live_stream' do
expect(broadcast).to receive(:create_mux_live_stream)
broadcast.run_callbacks(:create)
end
it 'assigns stream_id, stream_key and stream_playback_id to broadcast' do
allow_any_instance_of(MuxRuby::LiveStreamsApi).to receive(:create_live_stream).and_return(live_stream_data)
allow_any_instance_of(MuxRuby::LiveStreamsApi).to receive(:create_live_stream_playback_id).and_return(live_stream_playback_data)
broadcast.save
expect(broadcast.stream_uid).to eq "stream_id"
expect(broadcast.stream_key).to eq "stream_key"
expect(broadcast.stream_playback_uid).to eq "playback_id"
end
end
context "#after_destroy" do
let(:broadcast) { create(:broadcast, :with_stream, skip_create_callback: true, name: "My Broadcast") }
it "triggers destroy_mux_live_stream" do
allow(broadcast).to receive(:destroy_mux_live_stream)
broadcast.run_callbacks(:destroy)
expect(broadcast).to have_received(:destroy_mux_live_stream)
end
end
end
describe "#zoom_meeting_url" do
it { is_expected.to delegate_method(:zoom_meeting_url).to(:project) }
end
describe "#order_by_recent" do
subject { described_class }
it { is_expected.to respond_to(:order_by_recent) }
end
end

View File

@@ -0,0 +1,9 @@
require "rails_helper"
RSpec.describe Composer do
describe "validations" do
it { is_expected.to validate_presence_of(:name) }
it { is_expected.to validate_presence_of(:affiliation) }
it { is_expected.to validate_presence_of(:percentage) }
end
end

View File

@@ -0,0 +1,58 @@
require 'rails_helper'
describe Contract do
describe '#filename' do
it 'delegates to the releasable for the name' do
project = build_stubbed(:project, name: "My Project")
releasable = double("releasable", contract_file_name: "test")
contract = Contract.new(releasable)
expect(contract.filename).to eq("test.pdf")
expect(contract.filename("xls")).to eq("test.xls")
end
end
describe "rendering the contract" do
let(:project) { build(:project) }
it 'works with appearance releases' do
appearance_release = create(:appearance_release_with_contract_template, project: project, person_name: "Jane Doe")
result = render_contract_html_for(appearance_release)
expect(result).not_to be_nil
end
it 'works with talent releases' do
talent_release = create(:talent_release_with_contract_template, project: project, person_name: "Jane Doe")
result = render_contract_html_for(talent_release)
expect(result).not_to be_nil
end
it 'works with location releases' do
location_release = create(:location_release_with_contract_template, project: project, person_name: "Jane Doe")
result = render_contract_html_for(location_release)
expect(result).not_to be_nil
end
it 'works with material releases' do
material_release = create(:material_release_with_contract_template, project: project, person_name: "Jane Doe")
result = render_contract_html_for(material_release)
expect(result).not_to be_nil
end
end
private
# Reaching into the object's internals a bit here to avoid generating a PDF unnecessarily
def render_contract_html_for(releasable)
Contract.new(releasable).send(:as_html)
end
end

View File

@@ -0,0 +1,79 @@
# frozen_string_literal: true
require 'rails_helper'
describe ContractTemplatePreview do
describe '#build_releasable' do
it 'fills missing contract template data' do
ct = ContractTemplate.new
ct.release_type = :talent
preview = ContractTemplatePreview.new(ct)
expect do
preview.build_releasable
end.to change { ct.name }
.and change { ct.body.to_s }
.and change { ct.guardian_clause.to_s }
end
it 'does not overwrite existing contract template data' do
ct = build(:contract_template)
preview = ContractTemplatePreview.new(ct)
expect do
preview.build_releasable
end.to not_change { ct.name }
.and not_change { ct.body.to_s }
.and not_change { ct.guardian_clause.to_s }
end
describe 'fills releasable with dummy data' do
it 'with guardian details when guardian clause is present' do
ct = build(:contract_template)
preview = ContractTemplatePreview.new(ct)
releasable = preview.build_releasable
expect(releasable.attributes).to include(expected_dummy_data)
end
it 'with guardian details when guardian clause is not present' do
ct = ContractTemplate.new
ct.release_type = :appearance
preview = ContractTemplatePreview.new(ct)
releasable = preview.build_releasable
expect(releasable.attributes).to include(expected_dummy_data)
end
end
end
private
def expected_dummy_data
{
'id' => nil,
'person_first_name' => 'Dummy',
'person_last_name' => 'Person',
'person_address' => 'Street 1, Street 2, City, State 12345, Country',
'person_phone' => '00 111 222 333 4444',
'updated_at' => nil,
'minor' => true,
'guardian_address' => 'Street 3, Street 4, City-2, State-2 112233, Country-2',
"guardian_first_name" => nil,
"guardian_last_name" => nil,
"guardian_name_old" => nil,
'guardian_phone' => '00 123 456 7890',
'person_email' => 'email@email.com',
'locale' => nil,
'tagging_status' => 'pending',
'contract_template_id' => nil,
'applicable_medium_id' => nil,
'applicable_medium_text' => '',
'territory_id' => nil,
'territory_text' => '',
'term_id' => nil,
'term_text' => '',
'restriction_id' => nil,
'restriction_text' => '',
'signed_at' => nil,
'internal_tag_list' => nil,
'tag_list' => nil
}
end
end

View File

@@ -0,0 +1,44 @@
# frozen_string_literal: true
require 'rails_helper'
describe ContractTemplate do
it_behaves_like 'an exploitable'
describe 'associations' do
it { is_expected.to belong_to(:project) }
it { is_expected.to belong_to(:parent).optional }
it { is_expected.to have_many(:duplicates) }
it { is_expected.to have_many(:talent_releases).dependent(:restrict_with_error) }
it { is_expected.to have_many(:appearance_releases).dependent(:restrict_with_error) }
it { is_expected.to have_many(:location_releases).dependent(:restrict_with_error) }
it { is_expected.to have_many(:material_releases).dependent(:restrict_with_error) }
end
describe 'validations' do
it { is_expected.to validate_presence_of(:name) }
it { is_expected.to validate_presence_of(:release_type) }
end
describe '#fee' do
it { is_expected.to monetize(:fee) }
end
describe '#fee?' do
it 'returns true when there is a fee amount' do
fee_contract = build(:contract_template, fee: 500)
no_fee_contract = build(:contract_template, fee: 0)
expect(fee_contract).to be_fee
expect(no_fee_contract).not_to be_fee
end
end
describe '#duplicated?' do
it 'returns true when there is a parent association' do
contract_template = build(:contract_template, parent: build(:contract_template))
expect(contract_template).to be_duplicated
end
end
end

View File

@@ -0,0 +1,67 @@
require 'rails_helper'
RSpec.describe Directory, type: :model do
describe "associations" do
it { is_expected.to belong_to(:project) }
it { is_expected.to belong_to(:user) }
end
describe "validations" do
it { is_expected.to validate_presence_of(:name) }
describe "#name uniqueness validation" do
subject { build(:directory) }
it { is_expected.to validate_uniqueness_of(:name).scoped_to(:project_id) }
end
end
describe "enums" do
it { is_expected.to define_enum_for(:permissions).with_values("Everyone": 0, "Account Managers & Project Managers": 1, "Account Managers Only": 2) }
it { is_expected.to define_enum_for(:category).with_values("Other": 0, "Finance": 1, "Scripts": 2, "Call Sheets": 3, "Photos": 4, "Videos": 5) }
end
describe "scopes" do
it "should return directories in alphabetical order" do
directory = create(:directory, name: "Payrolls", category: "Finance")
directory_2 = create(:directory, name: "Actors", category: "Videos")
directories = Directory.order_by_name
# Directory one was created earlier than Directory 2
expect(directory.created_at < directory_2.created_at).to be true
# Directories ordered in alphabetical order
expect(directories.first.name).to eq "Actors"
expect(directories.last.name).to eq "Payrolls"
end
it "should return directories with permission 'Everyone'" do
directory = create(:directory, name: "Payrolls", category: "Finance")
directory_2 = create(:directory, :for_manager, name: "Actors", category: "Videos")
directories = Directory.for_associates
expect(directories).to include(directory)
expect(directories).not_to include(directory_2)
end
it "should return directories with permission 'Account Managers & Project Managers'" do
directory = create(:directory, name: "Payrolls", category: "Finance")
directory_2 = create(:directory, :for_manager, name: "Actors", category: "Videos")
directories = Directory.for_project_managers
expect(directories).to include(directory)
expect(directories).to include(directory_2)
end
end
describe "search_files" do
it "should return directories in alphabetical order" do
directory = create(:directory, :with_files)
results = directory.search_files('loc')
expect(results.first.filename).to eq "location_photo.png"
end
end
end

View File

@@ -0,0 +1,11 @@
require 'rails_helper'
RSpec.describe Download, type: :model do
describe "associations" do
it { is_expected.to belong_to(:project) }
end
it "has an attached file" do
expect(subject).to respond_to(:file)
end
end

View File

@@ -0,0 +1,60 @@
require "spec_helper"
require_relative "../../app/models/duration_timecode"
describe DurationTimecode do
describe ".parse" do
it "returns a new instance from a HH:MM:SS formatted string" do
duration = described_class.parse("00:30:20")
expect(duration).to be_a(described_class)
expect(duration.hours).to be_zero
expect(duration.minutes).to eq(30)
expect(duration.seconds).to eq(20)
end
context "with an invalid format" do
it "raises an error" do
expect {
described_class.parse("bad format")
}.to raise_error(ArgumentError)
end
end
end
describe ".from_seconds" do
it "returns a new instance from total seconds" do
duration = described_class.from_seconds(3662)
expect(duration.hours).to eq(1)
expect(duration.minutes).to eq(1)
expect(duration.seconds).to eq(2)
end
end
describe "#to_i" do
it "returns the total number of seconds" do
duration = described_class.parse("01:01:02")
expect(duration.to_i).to eq(3662)
end
end
describe "#to_s" do
it "returns a string in HH:MM:SS format" do
duration = described_class.new(0, 15, 30)
expect(duration.to_s).to eq("00:15:30")
end
end
describe "#+" do
it "returns an instance representing the sum" do
duration1 = described_class.new(0, 15, 40)
duration2 = described_class.new(0, 3, 25)
sum = duration1 + duration2
expect(sum.to_s).to eq("00:19:05")
end
end
end

View File

@@ -0,0 +1,265 @@
require "rails_helper"
RSpec.describe EdlEventGateway do
let(:files_for_request) do
instance_double(FilesForRequest,
file_object_name: "file_object_name",
edl_file_object_name: "edl_file_object_name",
aws_bucket_name: "aws_bucket_name",
start_timecode_offset: nil,
job_id: "video_analysis_uid",
)
end
describe "#edl_events" do
it "filters edl events by channel_filter" do
video_event = BrayniacAI::EdlParseResult.new({
"channel" => "V",
"start_time" => 0,
"timecode_in" => "00:00:00:00",
"timecode_out" => "00:00:01:00",
"duration" => 1,
"source_file_name" => "my_file.mp4",
"clip_name" => "my_clip.mp4",
"description" => "This is a great clip",
"matches" => [1, 2],
})
audio_event = BrayniacAI::EdlParseResult.new({
"channel" => "A1",
"start_time" => 0,
"timecode_in" => "00:00:00:00",
"timecode_out" => "00:00:01:00",
"duration" => 1,
"source_file_name" => "my_file.mp3",
"clip_name" => "my_clip.mp3",
"description" => "This is a great clip",
"matches" => [1, 2],
})
allow(BrayniacAI::EdlParse).to receive(:create).and_return(
BrayniacAI::EdlParse.new({ results: [video_event, audio_event] })
)
edl_events = EdlEventGateway.new(
files_for_request,
"00:00:02:00",
"00:00:02:00",
channel_filter: "A",
).edl_events
expect(edl_events.size).to eq(1)
expect(edl_events).to include(EdlEvent.new({
"channel" => "A1",
"start_time" => 0,
"timecode_in" => "00:00:00:00",
"timecode_out" => "00:00:01:00",
"duration" => 1,
"source_file_name" => "my_file.mp3",
"clip_name" => "my_clip.mp3",
"description" => "This is a great clip",
"matches" => [1, 2],
}))
end
describe "calling the API" do
it "includes location information about the video file and EDL file" do
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("test-bucket")
allow(BrayniacAI::EdlParse).to receive(:create)
EdlEventGateway.new(
files_for_request,
"00:00:02:00",
"00:00:02:00",
).edl_events
expect(BrayniacAI::EdlParse).to have_received(:create).with(
job_id: "video_analysis_uid",
video_bucket_name: "aws_bucket_name",
video_object_name: "file_object_name",
edl_bucket_name: "aws_bucket_name",
edl_object_name: "edl_file_object_name",
timecode_start: "00:00:02:00",
timecode_end: "00:00:02:00",
collection: {},
)
end
it "includes collection when provided" do
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("test-bucket")
allow(BrayniacAI::EdlParse).to receive(:create)
EdlEventGateway.new(
files_for_request,
"00:00:02:00",
"00:00:02:00",
collection: { 1 => "source file name" },
).edl_events
expect(BrayniacAI::EdlParse).to have_received(:create).with(
job_id: "video_analysis_uid",
video_bucket_name: "aws_bucket_name",
video_object_name: "file_object_name",
edl_bucket_name: "aws_bucket_name",
edl_object_name: "edl_file_object_name",
timecode_start: "00:00:02:00",
timecode_end: "00:00:02:00",
collection: { 1 => "source file name" },
)
end
it "includes start_timecode_offset when provided" do
allow(files_for_request).to receive(:start_timecode_offset).and_return("start_timecode_offset")
allow(BrayniacAI::EdlParse).to receive(:create)
EdlEventGateway.new(
files_for_request,
"00:00:02:00",
"00:00:02:00",
).edl_events
expect(BrayniacAI::EdlParse).to have_received(:create).with(
job_id: "video_analysis_uid",
video_bucket_name: "aws_bucket_name",
video_object_name: "file_object_name",
edl_bucket_name: "aws_bucket_name",
edl_object_name: "edl_file_object_name",
timecode_start: "00:00:02:00",
timecode_end: "00:00:02:00",
collection: {},
edl_timecode_start: "start_timecode_offset",
)
end
it "does not include timecode_end, edl_timecode_start, job_id when given nil" do
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("test-bucket")
allow(BrayniacAI::EdlParse).to receive(:create)
allow(files_for_request).to receive(:job_id).and_return(nil)
EdlEventGateway.new(
files_for_request,
"00:00:02:00",
nil,
collection: { 1 => "source file name" },
).edl_events
expect(BrayniacAI::EdlParse).to have_received(:create).with(
video_bucket_name: "aws_bucket_name",
video_object_name: "file_object_name",
edl_bucket_name: "aws_bucket_name",
edl_object_name: "edl_file_object_name",
timecode_start: "00:00:02:00",
collection: { 1 => "source file name" },
)
end
end
it "returns the collection of edl events from response" do
edl_event = BrayniacAI::EdlParseResult.new({
"channel" => "V",
"start_time" => 0,
"timecode_in" => "00:00:00:00",
"timecode_out" => "00:00:01:00",
"duration" => 1,
"source_file_name" => "my_file.mp4",
"clip_name" => "my_clip.mp4",
"description" => "This is a great clip",
"matches" => [1, 2],
})
allow(BrayniacAI::EdlParse).to receive(:create).and_return(
BrayniacAI::EdlParse.new({ results: [edl_event] })
)
edl_events = EdlEventGateway.new(
files_for_request,
"00:00:02:00",
"00:00:02:00",
).edl_events
expect(edl_events.size).to eq(1)
expect(edl_events).to include(EdlEvent.new({
"channel" => "V",
"start_time" => 0,
"timecode_in" => "00:00:00:00",
"timecode_out" => "00:00:01:00",
"duration" => 1,
"source_file_name" => "my_file.mp4",
"clip_name" => "my_clip.mp4",
"description" => "This is a great clip",
"matches" => [1, 2],
}))
end
end
describe "#edl_timecode_start" do
it "returns edl_timecode_start from response" do
allow(BrayniacAI::EdlParse).to receive(:create).and_return(BrayniacAI::EdlParse.new(edl_timecode_start: "edl_timecode_start"))
expect(described_class.new(
files_for_request,
"00:00:00:00",
"00:00:00:00"
).edl_timecode_start).to eq "edl_timecode_start"
end
context "when response nil" do
it "returns edl_timecode_start from response" do
allow(BrayniacAI::EdlParse).to receive(:create).and_return(nil)
expect(described_class.new(
files_for_request,
"00:00:00:00",
"00:00:00:00"
).edl_timecode_start).to be_nil
end
end
end
describe "#fps" do
it "returns fps from response" do
allow(BrayniacAI::EdlParse).to receive(:create).and_return(BrayniacAI::EdlParse.new(fps: 29.97))
expect(described_class.new(
files_for_request,
"00:00:00:00",
"00:00:00:00"
).fps).to eq 29.97
end
context "when response nil" do
it "returns nil" do
allow(BrayniacAI::EdlParse).to receive(:create).and_return(nil)
expect(described_class.new(
files_for_request,
"00:00:00:00",
"00:00:00:00"
).fps).to be_nil
end
end
end
describe "#edl_offset_seconds" do
it "returns edl_offset_seconds from response" do
allow(BrayniacAI::EdlParse).to receive(:create).and_return(BrayniacAI::EdlParse.new(edl_offset_seconds: 100))
expect(described_class.new(
files_for_request,
"00:00:00:00",
"00:00:00:00"
).edl_offset_seconds).to eq 100
end
context "when response nil" do
it "returns edl_offset_seconds from response" do
allow(BrayniacAI::EdlParse).to receive(:create).and_return(nil)
expect(described_class.new(
files_for_request,
"00:00:00:00",
"00:00:00:00"
).edl_offset_seconds).to be_nil
end
end
end
end

View File

@@ -0,0 +1,138 @@
require "rails_helper"
module ExcelReports
module AudioReports
RSpec.describe AudioConfirmationData do
let(:audio_confirmation) do
build(:audio_confirmation,
music_type: "Vocal",
music_category: "Feature",
title: "title",
source_file_name: "source_file_name",
)
end
subject { described_class.new(audio_confirmation) }
describe "#music_type" do
it "returns first letter of music_type" do
expect(subject.music_type).to eq "V"
end
context "when music_type nil" do
before :each do
audio_confirmation.music_type = nil
end
it "returns empty string" do
expect(subject.music_type).to eq ""
end
end
end
describe "#music_category" do
it "returns first letter of music_category" do
expect(subject.music_category).to eq "F"
end
context "when music_category nil" do
before :each do
audio_confirmation.music_category = nil
end
it "returns empty string" do
expect(subject.music_category).to eq ""
end
end
end
describe "#title_and_source_file_name" do
it "returns title_and_source_file_name and source filename separated by dash" do
expect(subject.title_and_source_file_name).to eq("title - source_file_name")
end
context "when source filename is blank" do
it "returns title_and_source_file_name alone" do
audio_confirmation.source_file_name = nil
expect(subject.title_and_source_file_name).to eq("title")
end
end
end
describe "#origin" do
context "for library music" do
let(:audio_confirmation) { build(:audio_confirmation, :library) }
it "returns 'Production Library (Non-affiliated)'" do
expect(subject.origin).to eq("Production Library (Non-affiliated)")
end
end
context "for original music" do
let(:audio_confirmation) { build(:audio_confirmation, :original) }
it "returns 'Commissioned'" do
expect(subject.origin).to eq("Commissioned")
end
end
end
describe "#composers_with_split" do
let(:audio_confirmation) { build(:audio_confirmation, composer_info: "John Doe, BMI, 50%") }
it "includes name, affiliation, and percentage split" do
expect(subject.composers_with_split).to eq "John Doe (BMI) 50.0%"
end
context "when there are co-writers " do
let(:audio_confirmation) { build(:audio_confirmation, composer_info: "John Doe, Jane Doe, BMI, 50%") }
it "includes both names" do
expect(subject.composers_with_split).to eq "John Doe, Jane Doe (BMI) 50.0%"
end
end
context "when there are multiple composers" do
let(:audio_confirmation) { build(:audio_confirmation, composer_info: "John Doe, BMI, 50% | Jane Doe, Universal, 50%") }
it "includes both composers separated by a newline" do
expect(subject.composers_with_split).to eq "John Doe (BMI) 50.0%\n Jane Doe (Universal) 50.0%"
end
end
context "when there is a cae number" do
let(:audio_confirmation) { build(:audio_confirmation, composer_info: "John Doe, Jane Doe, BMI, 50%, $cae:abc123 | James Doe, Universal, 50%, $cae:def456") }
it "does not include the cae number" do
expect(subject.composers_with_split).to eq "John Doe, Jane Doe (BMI) 50.0%\n James Doe (Universal) 50.0%"
end
end
end
describe "#composers_cae_numbers" do
let(:audio_confirmation) { build(:audio_confirmation, composer_info: "John Doe, BMI, 50%, $cae:abc123") }
it "includes cae number" do
expect(subject.composers_cae_numbers).to eq("abc123")
end
context "when there are multiple composers" do
let(:audio_confirmation) { build(:audio_confirmation, composer_info: "John Doe, BMI, 50%, $cae:abc123 | Jane Doe, Universal, 50%, $cae:def456") }
it "includes all cae numbers separated by a newline" do
expect(subject.composers_cae_numbers).to eq("abc123\ndef456")
end
end
context "when cae numbers are not present" do
let(:audio_confirmation) { build(:audio_confirmation, composer_info: "John Doe, BMI, 50%") }
it "returns an empty string" do
expect(subject.composers_cae_numbers).to be_empty
end
end
end
end
end
end

View File

@@ -0,0 +1,69 @@
require "rails_helper"
module ExcelReports
module AudioReports
RSpec.describe BrayInnovationGroupMusicCueReport do
let(:video) { create(:video) }
subject { described_class.new(video) }
describe "#to_xls" do
it "builds report" do
package = instance_double(Axlsx::Package)
workbook = instance_double(Axlsx::Workbook)
stream = double(:stream, read: "my-report")
allow(Axlsx::Package).to receive(:new).and_return(package)
allow(package).to receive(:workbook).and_return(workbook)
allow(package).to receive(:to_stream).and_return(stream)
allow(BrayInnovationGroupMusicCueSheet).to receive(:build)
create(:audio_confirmation, :library, video: video)
create(:audio_confirmation, :original, video: video)
result = subject.to_xls
expect(package).to have_received(:to_stream)
expect(BrayInnovationGroupMusicCueSheet).to have_received(:build).with(
workbook,
[instance_of(AudioConfirmationData), instance_of(AudioConfirmationData)],
instance_of(BrayInnovationGroupMusicCueHeaderData)
)
expect(stream).to have_received(:read)
expect(result).to eq("my-report")
end
it "sorts audio data by ascending timecode_in" do
package = instance_double(Axlsx::Package)
workbook = instance_double(Axlsx::Workbook)
stream = double(:stream, read: "my-report")
allow(Axlsx::Package).to receive(:new).and_return(package)
allow(package).to receive(:workbook).and_return(workbook)
allow(package).to receive(:to_stream).and_return(stream)
allow(BrayInnovationGroupMusicCueSheet).to receive(:build)
earlier = create(:audio_confirmation, :original, video: video, timecode_in: "00:00:00:02")
earliest = create(:audio_confirmation, :library, video: video, timecode_in: "00:00:00:01")
early = create(:audio_confirmation, :library, video: video, timecode_in: "00:00:00:03")
subject.to_xls
expect(BrayInnovationGroupMusicCueSheet).to have_received(:build).with(
workbook,
[
AudioConfirmationData.new(earliest),
AudioConfirmationData.new(earlier),
AudioConfirmationData.new(early),
],
instance_of(BrayInnovationGroupMusicCueHeaderData)
)
end
end
describe "#filename" do
it "returns video filename with 'big-cue-sheet'" do
expect(subject.filename).to eq "video_file-mp4_big-cue-sheet.xlsx"
end
end
end
end
end

View File

@@ -0,0 +1,176 @@
require "rails_helper"
module ExcelReports
module AudioReports
RSpec.describe BrayInnovationGroupMusicCueSheet do
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
subject { described_class.new(workbook) }
it_behaves_like "a worksheet"
describe "#title" do
it "returns 'BiG Music Cue Sheet'" do
expect(subject.title).to eq "BiG Music Cue Sheet"
end
end
describe "#fill_content" do
it "adds headers and data to given sheet" do
sheet = instance_double(Axlsx::Worksheet)
allow(sheet).to receive(:add_row)
video = create(:video,
name: "video name",
project: build(:project,
producer_name: "company name",
producer_address: "company address",
),
)
original_confirmation = create(:audio_confirmation, :original,
video: video,
title: "title_1",
source_file_name: "filename_1",
timecode_in: "01:00:00:00",
timecode_out: "01:05:00:00",
duration: "00:05:00",
music_type: "Vocal",
music_category: "Background",
composer_info: "composer1, affiliation, 50%|composer2, affiliation, 50%",
publisher_info: "publisher1, affiliation, 50%|publisher2, affiliation, 50%",
)
library_confirmation = create(:audio_confirmation, :library,
video: video,
title: "title_2",
source_file_name: "filename_2",
timecode_in: "01:00:00:00",
timecode_out: "01:05:00:00",
duration: "00:05:00",
music_type: "Vocal",
music_category: "Background",
composer_info: "composer1, affiliation, 50%|composer2, affiliation, 50%",
publisher_info: "publisher1, affiliation, 50%|publisher2, affiliation, 50%",
)
header_data = BrayInnovationGroupMusicCueHeaderData.new(video)
data = [AudioConfirmationData.new(original_confirmation), AudioConfirmationData.new(library_confirmation)]
described_class.new(workbook, data, header_data).fill_content(sheet)
expect(sheet).to have_received(:add_row).with(["TITLE", "video name"])
expect(sheet).to have_received(:add_row).with(["COMPANY NAME", "company name"])
expect(sheet).to have_received(:add_row).with(["ADDRESS", "company address"])
expect(sheet).to have_received(:add_row).with(["LENGTH", ""])
expect(sheet).to have_received(:add_row).with(["TYPE", ""])
expect(sheet).to have_received(:add_row).with(no_args)
expect(sheet).to have_received(:add_row).with([
"Cue #",
"Cue Title",
"Composer(s)/Affiliation",
"%",
"Publisher(s)/Affiliation",
"%",
"Use",
"",
"In Time",
"Out Time",
"Duration",
])
expect(sheet).to have_received(:add_row).with([
"",
"",
"",
"",
"",
"",
"I = Instr.\nV = Vocal",
"B = Bckgrnd\nF = Feature\nT = Theme",
"",
"",
"",
])
expect(sheet).to have_received(:add_row).with([
"",
"title_1 - filename_1",
"composer1 (affiliation)\ncomposer2 (affiliation)",
"50.0\n50.0",
"publisher1 (affiliation)\npublisher2 (affiliation)",
"50.0\n50.0",
"V",
"B",
"01:00:00:00",
"01:05:00:00",
"00:05:00",
])
expect(sheet).to have_received(:add_row).with([
"",
"title_2 - filename_2",
"composer1 (affiliation)\ncomposer2 (affiliation)",
"50.0\n50.0",
"publisher1 (affiliation)\npublisher2 (affiliation)",
"50.0\n50.0",
"V",
"B",
"01:00:00:00",
"01:05:00:00",
"00:05:00",
])
end
end
describe "#format" do
it "sets column widths" do
sheet = instance_double(Axlsx::Worksheet)
allow(sheet).to receive(:column_widths)
allow(sheet).to receive(:merge_cells)
subject.format(sheet)
expect(sheet).to have_received(:column_widths).with(15, 40, 20, 10, 20, 10, 20, 20, 15, 15, 15)
expect(sheet).to have_received(:merge_cells).with("G7:H7")
end
end
describe "#style" do
it "sets sheet style" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
expect(sheet).to receive(:add_style).with("A1:A5",
{
bg_color: "97CBFC",
b: true,
border: { :style => :thick, :color => "000000" },
alignment: { :horizontal => :center, :wrap_text => true },
sz: 12,
}
)
expect(sheet).to receive(:add_style).with(
"B1:B5",
{
border: { :style => :thick, :color => "000000" },
alignment: { :wrap_text => true, :horizontal => :left },
sz: 10,
}
)
expect(sheet).to receive(:add_style).with(
"A7:K7",
{
bg_color: "97CBFC",
b: true,
border: { :style => :thick, :color => "000000" },
alignment: { :horizontal => :center, :vertical => :center, :wrap_text => true },
sz: 8,
}
)
expect(sheet).to receive(:add_style).at_least(1).with("A9:K10",
{
border: { style: :thick, color: "000000" },
alignment: { wrap_text: true },
sz: 10
}
)
described_class.new(workbook, ["data1", "data2"]).style(sheet)
end
end
end
end
end

View File

@@ -0,0 +1,69 @@
require "rails_helper"
module ExcelReports
module AudioReports
RSpec.describe DiscoveryMusicCueReport do
let(:video) { create(:video) }
subject { described_class.new(video) }
describe "#to_xls" do
it "builds report" do
package = instance_double(Axlsx::Package)
workbook = instance_double(Axlsx::Workbook)
stream = double(:stream, read: "my-report")
allow(Axlsx::Package).to receive(:new).and_return(package)
allow(package).to receive(:workbook).and_return(workbook)
allow(package).to receive(:to_stream).and_return(stream)
allow(DiscoveryMusicCueSheet).to receive(:build)
create(:audio_confirmation, :original, video: video)
create(:audio_confirmation, :library, video: video)
result = subject.to_xls
expect(package).to have_received(:to_stream)
expect(DiscoveryMusicCueSheet).to have_received(:build).with(
workbook,
[instance_of(AudioConfirmationData), instance_of(AudioConfirmationData)],
instance_of(DiscoveryMusicCueHeaderData)
)
expect(stream).to have_received(:read)
expect(result).to eq("my-report")
end
it "sorts audio data by ascending timecode_in" do
package = instance_double(Axlsx::Package)
workbook = instance_double(Axlsx::Workbook)
stream = double(:stream, read: "my-report")
allow(Axlsx::Package).to receive(:new).and_return(package)
allow(package).to receive(:workbook).and_return(workbook)
allow(package).to receive(:to_stream).and_return(stream)
allow(DiscoveryMusicCueSheet).to receive(:build)
earlier = create(:audio_confirmation, :original, video: video, timecode_in: "00:00:00:02")
earliest = create(:audio_confirmation, :library, video: video, timecode_in: "00:00:00:01")
early = create(:audio_confirmation, :library, video: video, timecode_in: "00:00:00:03")
subject.to_xls
expect(DiscoveryMusicCueSheet).to have_received(:build).with(
workbook,
[
AudioConfirmationData.new(earliest),
AudioConfirmationData.new(earlier),
AudioConfirmationData.new(early),
],
instance_of(DiscoveryMusicCueHeaderData)
)
end
end
describe "#filename" do
it "returns video filename with 'discovery-cue-sheet'" do
expect(subject.filename).to eq "video_file-mp4_discovery-cue-sheet.xlsx"
end
end
end
end
end

View File

@@ -0,0 +1,195 @@
require "rails_helper"
module ExcelReports
module AudioReports
RSpec.describe DiscoveryMusicCueSheet do
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
subject { described_class.new(workbook) }
it_behaves_like "a worksheet"
describe "#title" do
it "returns 'Discovery Music Cue Sheet'" do
expect(subject.title).to eq "Discovery Music Cue Sheet"
end
end
describe "#fill_content" do
it "adds headers and data to given sheet for both types of audio confirmations" do
sheet = instance_double(Axlsx::Worksheet)
allow(sheet).to receive(:add_row)
project = create(:project, client_name: "client_name", producer_name: "producer_name")
video = create(:video, project: project, number: 42, name: "video_name")
header_data = DiscoveryMusicCueHeaderData.new(video)
data = [
AudioConfirmationData.new(
build(:audio_confirmation,
timecode_in: "timecode_in_1",
title: "title_1",
catalog: "catalog_1",
duration: "duration_1",
music_type: "music_type_1",
music_category: "music_category_1",
composer_info: "composer_info_1",
publisher_info: "publisher_info_1",
source_file_name: "source_file_name_1",
)
),
AudioConfirmationData.new(
build(:audio_confirmation,
timecode_in: "timecode_in_2",
title: "title_2",
catalog: "catalog_2",
duration: "duration_2",
music_type: "music_type_2",
music_category: "music_category_2",
composer_info: "composer_info_2",
publisher_info: "publisher_info_2",
source_file_name: "source_file_name_2",
)
)
]
described_class.new(workbook, data, header_data).fill_content(sheet)
expect(sheet).to have_received(:add_row).with(["Original Production Title", "video_name", "Original Series Title", "", "Broadcaster", ""])
expect(sheet).to have_received(:add_row).with(["Alternative Production Title", "", "Alternative Series Title", "", "Production Company", "producer_name"])
expect(sheet).to have_received(:add_row).with(["Local Production Title", "", "Local Series Title", "", "", ""])
expect(sheet).to have_received(:add_row).with(["Working Production Title", "", "Working Series Title", "", "Production Number", ""])
expect(sheet).to have_received(:add_row).with(["Version Production Title", "", "Version Series Title", "", "Director", ""])
expect(sheet).to have_received(:add_row).with(["Episode No.", "42", "Season No.", "", "Production Parent Identifier", ""])
expect(sheet).to have_received(:add_row).with(["Year", "", "Country", "", "Soundmouse Legacy Identifier", ""])
expect(sheet).to have_received(:add_row).with(["Duration", "", "Type", "", "Production ID", ""])
expect(sheet).to have_received(:add_row).with(["First Transmission", "", "Source", ""])
expect(sheet).to have_received(:add_row).with(["Product Name", ""])
expect(sheet).to have_received(:add_row).with(["Client Name", "client_name"])
expect(sheet).to have_received(:add_row).with(["Narrative", ""])
expect(sheet).to have_received(:add_row).with(["End Line", ""])
expect(sheet).to have_received(:add_row).with(["Clock Number", ""])
expect(sheet).to have_received(:add_row).with(["ISAN", ""])
expect(sheet).to have_received(:add_row).with(no_args)
expect(sheet).to have_received(:add_row).with([
"No.",
"Timecode",
"Title",
"Music Origin",
"Use (Theme/Description)",
"Interested Parties",
"Identifiers",
"Duration",
])
expect(sheet).to have_received(:add_row).with([
1,
"timecode_in_1",
"title_1 - source_file_name_1",
"catalog_1",
"music_type_1 music_category_1",
"Composers:\ncomposer_info_1\nPublishers:\npublisher_info_1",
"",
"duration_1",
])
expect(sheet).to have_received(:add_row).with([
2,
"timecode_in_2",
"title_2 - source_file_name_2",
"catalog_2",
"music_type_2 music_category_2",
"Composers:\ncomposer_info_2\nPublishers:\npublisher_info_2",
"",
"duration_2",
])
end
end
describe "#format" do
it "sets column widths" do
sheet = instance_double(Axlsx::Worksheet)
allow(sheet).to receive(:column_widths)
subject.format(sheet)
expect(sheet).to have_received(:column_widths).with(20, 20, 40, 20, 20, 20, 20, 20)
end
end
describe "#style" do
it "sets sheet style" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
expect(sheet).to receive(:add_style).with("A1:A15",
{
bg_color: "97CBFC",
b: true,
border: { :style => :thick, :color => "000000" },
alignment: { :horizontal => :center, :wrap_text => true },
sz: 12,
}
)
expect(sheet).to receive(:add_style).with("C1:C9",
{
bg_color: "97CBFC",
b: true,
border: { :style => :thick, :color => "000000" },
alignment: { :horizontal => :center, :wrap_text => true },
sz: 12,
}
)
expect(sheet).to receive(:add_style).with("E1:E8",
{
bg_color: "97CBFC",
b: true,
border: { :style => :thick, :color => "000000" },
alignment: { :horizontal => :center, :wrap_text => true },
sz: 12,
}
)
expect(sheet).to receive(:add_style).with(
"B1:B15",
{
border: { :style => :thick, :color => "000000" },
alignment: { :wrap_text => true, :horizontal => :left },
sz: 10,
}
)
expect(sheet).to receive(:add_style).with(
"D1:D9",
{
border: { :style => :thick, :color => "000000" },
alignment: { :wrap_text => true, :horizontal => :left },
sz: 10,
}
)
expect(sheet).to receive(:add_style).with(
"F1:F8",
{
border: { :style => :thick, :color => "000000" },
alignment: { :wrap_text => true, :horizontal => :left },
sz: 10,
}
)
expect(sheet).to receive(:add_style).with(
"A17:H17",
{
bg_color: "97CBFC",
b: true,
border: { :style => :thick, :color => "000000" },
alignment: { :horizontal => :center, :vertical => :center, :wrap_text => true },
sz: 8,
}
)
expect(sheet).to receive(:add_style).at_least(1).with(
"A18:H19",
{
border: { style: :thick, color: "000000" },
alignment: { wrap_text: true },
sz: 10
}
)
described_class.new(workbook, ["data1", "data2"]).style(sheet)
end
end
end
end
end

View File

@@ -0,0 +1,67 @@
require "rails_helper"
module ExcelReports
module AudioReports
RSpec.describe NatGeoMusicCueSheet do
let(:video) { create(:video) }
subject { described_class.new(video) }
describe "#to_xls" do
it "builds report" do
package = instance_double(Axlsx::Package)
workbook = instance_double(Axlsx::Workbook)
stream = double(:stream, read: "my-report")
allow(Axlsx::Package).to receive(:new).and_return(package)
allow(package).to receive(:workbook).and_return(workbook)
allow(package).to receive(:to_stream).and_return(stream)
allow(NatGeoMusicCueSheets::MainSheet).to receive(:build)
create(:audio_confirmation, :original, video: video)
create(:audio_confirmation, :library, video: video)
result = subject.to_xls
expect(package).to have_received(:to_stream)
expect(NatGeoMusicCueSheets::MainSheet).to have_received(:build).with(
workbook,
[instance_of(AudioConfirmationData), instance_of(AudioConfirmationData)],
)
expect(stream).to have_received(:read)
expect(result).to eq("my-report")
end
it "sorts audio data by ascending timecode_in" do
package = instance_double(Axlsx::Package)
workbook = instance_double(Axlsx::Workbook)
stream = double(:stream, read: "my-report")
allow(Axlsx::Package).to receive(:new).and_return(package)
allow(package).to receive(:workbook).and_return(workbook)
allow(package).to receive(:to_stream).and_return(stream)
allow(NatGeoMusicCueSheets::MainSheet).to receive(:build)
earlier = create(:audio_confirmation, :original, video: video, timecode_in: "00:00:00:02")
earliest = create(:audio_confirmation, :library, video: video, timecode_in: "00:00:00:01")
early = create(:audio_confirmation, :library, video: video, timecode_in: "00:00:00:03")
subject.to_xls
expect(NatGeoMusicCueSheets::MainSheet).to have_received(:build).with(
workbook,
[
AudioConfirmationData.new(earliest),
AudioConfirmationData.new(earlier),
AudioConfirmationData.new(early),
]
)
end
end
describe "#filename" do
it "returns video filename with 'discovery-cue-sheet'" do
expect(subject.filename).to eq "video_file-mp4_music-cue-sheet.xlsx"
end
end
end
end
end

View File

@@ -0,0 +1,129 @@
require "rails_helper"
module ExcelReports
module AudioReports
module NatGeoMusicCueSheets
RSpec.describe MainSheet do
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
subject { described_class.new(workbook) }
it_behaves_like "a worksheet"
describe "#title" do
it "returns the title of the sheet" do
expect(subject.title).to eq "Nat Geo Music Cue Sheet"
end
end
describe "#fill_content" do
it "adds headers and data to given sheet for both types of audio confirmations" do
sheet = instance_double(Axlsx::Worksheet)
allow(sheet).to receive(:add_row)
video = create(:video)
header_data = video
data = [
AudioConfirmationData.new(
build(:audio_confirmation,
:library,
timecode_in: "timecode_in_1",
timecode_out: "timecode_out_1",
title: "title_1",
catalog: "catalog_1",
duration: "00:02:30",
music_type: "music_type_1",
music_category: "music_category_1",
composer_info: "composer1, affiliation, 50%|composer2, affiliation, 50%",
publisher_info: "publisher1, affiliation, 50%|publisher2, affiliation, 50%",
source_file_name: "source_file_name_1",
)
),
AudioConfirmationData.new(
build(:audio_confirmation,
:original,
timecode_in: "timecode_in_2",
timecode_out: "timecode_out_2",
title: "title_2",
catalog: "catalog_2",
duration: "00:03:50",
music_type: "music_type_2",
music_category: "music_category_2",
composer_info: "composer1, affiliation, 50%|composer2, affiliation, 50%",
publisher_info: "publisher1, affiliation, 50%|publisher2, affiliation, 50%",
source_file_name: "source_file_name_2",
)
)
]
described_class.new(workbook, data, header_data).fill_content(sheet)
expect(sheet).to have_received(:add_row).with([
"No.",
"Title",
"In",
"Out",
"Composer",
"Publisher",
"Record Label / Library",
"Music Origin",
"Use",
"Duration",
])
expect(sheet).to have_received(:add_row).with([
1,
"title_1 - source_file_name_1",
"timecode_in_1",
"timecode_out_1",
"composer1 (affiliation) 50.0%\ncomposer2 (affiliation) 50.0%",
"publisher1 (affiliation) 50.0%\npublisher2 (affiliation) 50.0%",
"catalog_1",
"Production Library (Non-affiliated)",
"music_type_1 music_category_1",
"00:02:30",
])
expect(sheet).to have_received(:add_row).with([
2,
"title_2 - source_file_name_2",
"timecode_in_2",
"timecode_out_2",
"composer1 (affiliation) 50.0%\ncomposer2 (affiliation) 50.0%",
"publisher1 (affiliation) 50.0%\npublisher2 (affiliation) 50.0%",
"catalog_2",
"Commissioned",
"music_type_2 music_category_2",
"00:03:50",
])
expect(sheet).to have_received(:add_row).with([
"", "", "", "", "", "", "", "", "Total Music Duration:", "00:06:20"
])
end
end
describe "#format" do
it "sets column widths and merges cells" do
sheet = instance_double(Axlsx::Worksheet)
allow(sheet).to receive(:column_widths)
allow(sheet).to receive(:merge_cells)
subject.format(sheet)
expect(sheet).to have_received(:column_widths)
expect(sheet).to have_received(:merge_cells).at_least(1).times
end
end
describe "#style" do
it "sets sheet style" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
allow(sheet).to receive(:add_style)
described_class.new(workbook, ["data1", "data2"]).style(sheet)
expect(sheet).to have_received(:add_style).at_least(1).times
end
end
end
end
end
end

View File

@@ -0,0 +1,87 @@
require "rails_helper"
module ExcelReports
module AudioReports
RSpec.describe NatGeoOriginalMusicLog do
let(:video) { create(:video) }
subject { described_class.new(video) }
describe "#to_xls" do
it "builds report" do
package = instance_double(Axlsx::Package)
workbook = instance_double(Axlsx::Workbook)
stream = double(:stream, read: "my-report")
allow(Axlsx::Package).to receive(:new).and_return(package)
allow(package).to receive(:workbook).and_return(workbook)
allow(package).to receive(:to_stream).and_return(stream)
allow(NatGeoOriginalMusicLogs::MainSheet).to receive(:build)
create(:audio_confirmation, :original, video: video)
create(:audio_confirmation, :original, video: video)
result = subject.to_xls
expect(package).to have_received(:to_stream)
expect(NatGeoOriginalMusicLogs::MainSheet).to have_received(:build).with(
workbook,
[instance_of(AudioConfirmationData), instance_of(AudioConfirmationData)],
)
expect(stream).to have_received(:read)
expect(result).to eq("my-report")
end
it "sorts audio data by ascending timecode_in" do
package = instance_double(Axlsx::Package)
workbook = instance_double(Axlsx::Workbook)
stream = double(:stream, read: "my-report")
allow(Axlsx::Package).to receive(:new).and_return(package)
allow(package).to receive(:workbook).and_return(workbook)
allow(package).to receive(:to_stream).and_return(stream)
allow(NatGeoOriginalMusicLogs::MainSheet).to receive(:build)
earlier = create(:audio_confirmation, :original, video: video, timecode_in: "00:00:00:02")
earliest = create(:audio_confirmation, :original, video: video, timecode_in: "00:00:00:01")
early = create(:audio_confirmation, :original, video: video, timecode_in: "00:00:00:03")
subject.to_xls
expect(NatGeoOriginalMusicLogs::MainSheet).to have_received(:build).with(
workbook,
[
AudioConfirmationData.new(earliest),
AudioConfirmationData.new(earlier),
AudioConfirmationData.new(early),
]
)
end
it "only includes original music" do
package = instance_double(Axlsx::Package)
workbook = instance_double(Axlsx::Workbook)
stream = double(:stream, read: "my-report")
allow(Axlsx::Package).to receive(:new).and_return(package)
allow(package).to receive(:workbook).and_return(workbook)
allow(package).to receive(:to_stream).and_return(stream)
allow(NatGeoOriginalMusicLogs::MainSheet).to receive(:build)
original = create(:audio_confirmation, :original, video: video)
library = create(:audio_confirmation, :library, video: video)
subject.to_xls
expect(NatGeoOriginalMusicLogs::MainSheet).to have_received(:build).with(
workbook,
[AudioConfirmationData.new(original)]
)
end
end
describe "#filename" do
it "returns video filename with 'discovery-cue-sheet'" do
expect(subject.filename).to eq "video_file-mp4_original-music-log.xlsx"
end
end
end
end
end

View File

@@ -0,0 +1,85 @@
require "rails_helper"
module ExcelReports
module AudioReports
module NatGeoOriginalMusicLogs
RSpec.describe MainSheet do
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
subject { described_class.new(workbook) }
it_behaves_like "a worksheet"
describe "#title" do
it "returns the title of the sheet" do
expect(subject.title).to eq "Nat Geo Original Music Log"
end
end
describe "#fill_content" do
it "adds headers and data to given sheet for both types of audio confirmations" do
sheet = instance_double(Axlsx::Worksheet)
allow(sheet).to receive(:add_row)
allow(BigMediaTime).to receive(:time_zone_now).and_return(DateTime.new(2019,10,9))
video = create(:video)
header_data = video
data = [
AudioConfirmationData.new(
build(:audio_confirmation,
:original,
title: "title_1",
composer_info: "composer1a, composer1b, affiliation, 50%, $cae:cae123|composer2, affiliation, 50%, $cae:cae456",
publisher_info: "publisher1, affiliation, 50%|publisher2, affiliation, 50%",
source_file_name: "source_file_name_1",
)
),
]
described_class.new(workbook, data, header_data).fill_content(sheet)
expect(sheet).to have_received(:add_row).with([
"10/09/19", "", "", ""
])
expect(sheet).to have_received(:add_row).with([
"CUE TITLE",
"COMPOSER(S), % SPLIT & PRO",
"COMPOSER CAE/IPI#",
"PUBLISHER(S), % SPLIT & PRO",
])
expect(sheet).to have_received(:add_row).with([
"title_1 - source_file_name_1",
"composer1a, composer1b (affiliation) 50.0%\ncomposer2 (affiliation) 50.0%",
"cae123\ncae456",
"publisher1 (affiliation) 50.0%\npublisher2 (affiliation) 50.0%",
])
end
end
describe "#format" do
it "sets column widths and merge cells" do
sheet = instance_double(Axlsx::Worksheet)
allow(sheet).to receive(:column_widths)
allow(sheet).to receive(:merge_cells)
subject.format(sheet)
expect(sheet).to have_received(:column_widths)
expect(sheet).to have_received(:merge_cells).at_least(1).times
end
end
describe "#style" do
it "sets sheet style" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
allow(sheet).to receive(:add_style)
described_class.new(workbook, ["data1", "data2"]).style(sheet)
expect(sheet).to have_received(:add_style).at_least(1).times
end
end
end
end
end
end

View File

@@ -0,0 +1,91 @@
require 'rails_helper'
module ExcelReports
module GraphicReports
RSpec.describe DiscoveryGfxCueList do
let(:project) { create(:project) }
describe '#to_xls' do
it 'builds xls file' do
graphics_element = create(:graphics_element)
video = create(:video, graphics_elements: [graphics_element], project: project)
package = double(:package)
workbook = double(:workbook)
stream = double(:stream)
allow(Axlsx::Package).to receive(:new).and_return(package)
allow(package).to receive(:workbook).and_return(workbook)
expect(DiscoveryGfxCueLists::TextedElementsSheet).to receive(:build).with(
workbook,
[
DiscoveryGfxCueList::GraphicsElementsData.new(
"some text",
nil,
nil,
nil,
)
],
DiscoveryGfxCueList::GraphicsElementsHeaderData.new(
nil,
nil,
"My Client",
"My Team",
)
)
expect(package).to receive(:to_stream).and_return(stream)
expect(stream).to receive(:read)
described_class.new(video).to_xls
end
it 'sorts the element data by timecode' do
graphics_elements = [
build(:graphics_element, timecode_in: "00:00:10:00"),
build(:graphics_element, timecode_in: "00:00:05:00"),
build(:graphics_element, timecode_in: nil )
]
video = create(:video, graphics_elements: graphics_elements, project: project)
package = double(:package)
workbook = double(:workbook)
stream = double(:stream)
allow(Axlsx::Package).to receive(:new).and_return(package)
allow(package).to receive(:workbook).and_return(workbook)
allow(package).to receive(:to_stream).and_return(stream)
allow(stream).to receive(:read)
expect(DiscoveryGfxCueLists::TextedElementsSheet).to receive(:build).with(
workbook,
[
DiscoveryGfxCueList::GraphicsElementsData.new(
"some text",
"00:00:05:00",
nil,
nil,
),
DiscoveryGfxCueList::GraphicsElementsData.new(
"some text",
"00:00:10:00",
nil,
nil,
),
DiscoveryGfxCueList::GraphicsElementsData.new(
"some text",
nil,
nil,
nil,
),
],
DiscoveryGfxCueList::GraphicsElementsHeaderData.new(
nil,
nil,
"My Client",
"My Team",
)
)
described_class.new(video).to_xls
end
end
end
end
end

View File

@@ -0,0 +1,73 @@
require "rails_helper"
module ExcelReports
module GraphicReports
module DiscoveryGfxCueLists
RSpec.describe TextedElementsSheet do
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
it_behaves_like "a worksheet" do
subject { described_class.new(workbook) }
end
describe "#title" do
it "returns 'Texted Elements List'" do
expect(described_class.new(workbook).title).to eq "Texted Elements List"
end
end
describe "#format" do
it "sets sheet column widths to 60, 20, 20" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
expect(sheet).to receive(:column_widths).with(60, 20, 20)
described_class.new(workbook).format(sheet)
end
end
describe "#style" do
it "sets sheet style" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
expect(sheet).to receive(:add_style).with("A1", { b: true }, { sz: 12 })
expect(sheet).to receive(:add_style).with(
"A9:D9",
{
bg_color: "97CBFC",
b: true,
border: { :style => :thick, :color => "000000" },
alignment: { :horizontal => :center, :vertical => :center, :wrap_text => true },
sz: 8,
}
)
expect(sheet).to receive(:add_style).with("A3:A7",
{
bg_color: "97CBFC",
b: true,
border: { :style => :thick, :color => "000000" },
alignment: { :horizontal => :center, :wrap_text => true },
sz: 12,
}
)
expect(sheet).to receive(:add_style).with(
"B3:B7",
{
border: { :style => :thick, :color => "000000" },
alignment: { :wrap_text => true, :horizontal => :left },
sz: 10,
}
)
expect(sheet).to receive(:add_style).at_least(1).with("A10:D11",
{
border: { style: :thick, color: "000000" },
alignment: { wrap_text: true },
sz: 10
}
)
described_class.new(workbook, ["data1", "data2"]).style(sheet)
end
end
end
end
end
end

View File

@@ -0,0 +1,53 @@
require 'rails_helper'
module ExcelReports
module GraphicReports
RSpec.describe NatGeoTextGraphicsLog do
let(:project) { create(:project) }
describe '#to_xls' do
it 'builds xls file' do
graphics_element = create(:graphics_element)
video = create(:video, graphics_elements: [graphics_element], project: project)
package = double(:package)
workbook = double(:workbook)
stream = double(:stream)
allow(Axlsx::Package).to receive(:new).and_return(package)
allow(package).to receive(:workbook).and_return(workbook)
expect(NatGeoTextGraphicsLogs::InternalProgramGfxLogSheet).to receive(:build).with(
workbook,
[graphics_element],
video,
)
expect(package).to receive(:to_stream).and_return(stream)
expect(stream).to receive(:read)
described_class.new(video).to_xls
end
it 'sorts the element data by timecode' do
graphics_elements = [
build(:graphics_element, timecode_in: "00:00:10:00"),
build(:graphics_element, timecode_in: "00:00:05:00"),
build(:graphics_element, timecode_in: nil )
]
video = create(:video, graphics_elements: graphics_elements, project: project)
package = double(:package)
workbook = double(:workbook)
stream = double(:stream)
allow(Axlsx::Package).to receive(:new).and_return(package)
allow(package).to receive(:workbook).and_return(workbook)
allow(package).to receive(:to_stream).and_return(stream)
allow(stream).to receive(:read)
expect(NatGeoTextGraphicsLogs::InternalProgramGfxLogSheet).to receive(:build).with(
workbook, [graphics_elements.second, graphics_elements.first, graphics_elements.last], video,
)
described_class.new(video).to_xls
end
end
end
end
end

View File

@@ -0,0 +1,66 @@
require "rails_helper"
module ExcelReports
module GraphicReports
module NatGeoTextGraphicsLogs
RSpec.describe InternalProgramGfxLogSheet do
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
let(:video) { build(:video, name: "My Video", number: 10) }
let(:graphics_element) do
build(:graphics_element,
graphic_type: "Logo",text: "Some Text",
timecode_in: "00:00:05:00", timecode_out: "00:00:10:00")
end
subject { described_class.new(workbook, [graphics_element], video) }
it_behaves_like "a worksheet"
describe "#title" do
it "returns the title of the sheet" do
expect(subject.title).to eq "Internal Program GFX Log"
end
end
describe "#fill_content" do
it "adds content from the data" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
allow(sheet).to receive(:add_row)
allow(BigMediaTime).to receive(:time_zone_now).and_return(Date.new(2019,10,4))
subject.fill_content(sheet)
expect(sheet).to have_received(:add_row).with(["", "Episode Title:", "My Video", "", "", "", "",])
expect(sheet).to have_received(:add_row).with(["", "Episode Number:", "10", "", "", "", "",])
expect(sheet).to have_received(:add_row).with(["", "Date:", "10/04/19", "", "", "", "",])
expect(sheet).to have_received(:add_row).with(["Logo", "Some Text", "00:00:05:00", "00:00:10:00", "", "", "",])
end
end
describe "#format" do
it "sets sheet column widths and merges cells" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
allow(sheet).to receive(:column_widths)
allow(sheet).to receive(:merge_cells)
subject.format(sheet)
expect(sheet).to have_received(:column_widths)
expect(sheet).to have_received(:merge_cells).at_least(1).times
end
end
describe "#style" do
it "sets sheet style" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
allow(sheet).to receive(:add_style)
subject.style(sheet)
expect(sheet).to have_received(:add_style).at_least(1).times
end
end
end
end
end
end

View File

@@ -0,0 +1,23 @@
require "rails_helper"
module ExcelReports
module IssuesAndConcernsReports
RSpec.describe IssuesAndConcernsReport do
let(:video) { create(:video) }
subject { described_class.new(video) }
describe "#to_xls" do
it "returns xls file" do
expect(subject.to_xls).not_to be_nil
end
end
describe "#filename" do
it "return 'video_file-mp4_issues-and-concerns.xlsx'" do
expect(subject.filename).to eq "video_file-mp4_issues-and-concerns.xlsx"
end
end
end
end
end

View File

@@ -0,0 +1,116 @@
require "rails_helper"
module ExcelReports
module IssuesAndConcernsReports
RSpec.describe IssuesAndConcernsWorksheet do
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
it_behaves_like "a worksheet" do
subject { described_class.new(workbook) }
end
describe "#title" do
it "returns 'Issues and Concerns Report'" do
expect(described_class.new(workbook).title).to eq "Issues and Concerns Report"
end
end
describe "#fill_content" do
it "adds content from acquired media release" do
presenter = instance_double(
IssuesAndConcernsReportPresenter,
project_name: "Broadcast across the nation",
video_name: "The News",
date_of_report: "Today",
unreleased_appearances: [
instance_double(UnreleasedAppearance,
timecode_in: "timecode_in",
timecode_out: "timecode_out",
channel: "channel",
source_file_name: "source_file_name",
clip_name: "clip_name",
note_text: "Great notes",
)],
)
sheet = instance_double(Axlsx::Worksheet, :sheet)
expect(sheet).to receive(:add_row).with(["ISSUES AND CONCERNS REPORT"])
expect(sheet).to receive(:add_row).with(["Project Name", "Broadcast across the nation"])
expect(sheet).to receive(:add_row).with(["Video Name", "The News"])
expect(sheet).to receive(:add_row).with(["Date of Report", "Today"])
expect(sheet).to receive(:add_row).with([])
expect(sheet).to receive(:add_row).with(["Track", "TC In", "TC Out", "Clip Name", "Source File Name", "Notes"])
expect(sheet).to receive(:add_row).with(["channel", "timecode_in", "timecode_out", "clip_name", "source_file_name", "Great notes"])
described_class.new(workbook, presenter).fill_content(sheet)
end
end
describe "#format" do
let(:sheet) { instance_double(Axlsx::Worksheet, :sheet) }
before :each do
allow(sheet).to receive(:column_widths)
end
it "sets sheet column widths to 15, 15, 15, 15, 15, 50" do
expect(sheet).to receive(:column_widths).with(15, 15, 15, 15, 15, 50)
described_class.new(workbook).format(sheet)
end
end
describe "#style" do
it "sets sheet style" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
expect(sheet).to receive(:add_style).with("A1", { b: true }, { sz: 14 })
expect(sheet).to receive(:add_style).with(
"A2:A4",
{
bg_color: "97CBFC",
b: true,
border: { :style => :thick, :color => "000000" },
alignment: { :horizontal => :center, :wrap_text => true },
sz: 12,
}
)
expect(sheet).to receive(:add_style).with(
"B2:B4",
{
border: { :style => :thick, :color => "000000" },
alignment: { :wrap_text => true, :horizontal => :left },
sz: 10,
}
)
expect(sheet).to receive(:add_style).with(
"A6:F6",
{
bg_color: "97CBFC",
b: true,
border: { :style => :thick, :color => "000000" },
alignment: { :horizontal => :center, :vertical => :center, :wrap_text => true },
sz: 8,
}
)
expect(sheet).to receive(:add_style).at_least(1).with(
"A7:F8",
{
border: { style: :thick, color: "000000" },
alignment: { wrap_text: true },
sz: 10
}
)
presenter = instance_double(
IssuesAndConcernsReportPresenter,
unreleased_appearances: [
instance_double(UnreleasedAppearance, timecode_in: "yesterday", notes: "Great notes"),
instance_double(UnreleasedAppearance, timecode_in: "yesterday", notes: "Great notes"),
],
)
described_class.new(workbook, presenter).style(sheet)
end
end
end
end
end

View File

@@ -0,0 +1,56 @@
require "rails_helper"
module ExcelReports
module VideoReports
RSpec.describe DiscoveryProductionElementsLog do
let(:video) { create(:video) }
describe "#to_xls" do
it "generates an excel report" do
expect(described_class.new(video).to_xls).not_to be_nil
end
it "builds the necessary worksheets" do
allow(DiscoveryProductionElementsLogs::MediaRightsCertificationSheet).to receive(:build)
allow(DiscoveryProductionElementsLogs::AcquiredFootageAndStillsSheet).to receive(:build)
allow(DiscoveryProductionElementsLogs::MusicSheet).to receive(:build)
allow(DiscoveryProductionElementsLogs::TalentSheet).to receive(:build)
allow(DiscoveryProductionElementsLogs::AppearanceSheet).to receive(:build)
allow(DiscoveryProductionElementsLogs::LocationSheet).to receive(:build)
allow(DiscoveryProductionElementsLogs::NameProductLogoSheet).to receive(:build)
allow(DiscoveryProductionElementsLogs::ProductIntegrationSheet).to receive(:build)
described_class.new(video).to_xls
expect(DiscoveryProductionElementsLogs::MediaRightsCertificationSheet).to have_received(:build)
expect(DiscoveryProductionElementsLogs::AcquiredFootageAndStillsSheet).to have_received(:build)
expect(DiscoveryProductionElementsLogs::MusicSheet).to have_received(:build)
expect(DiscoveryProductionElementsLogs::TalentSheet).to have_received(:build)
expect(DiscoveryProductionElementsLogs::AppearanceSheet).to have_received(:build)
expect(DiscoveryProductionElementsLogs::LocationSheet).to have_received(:build)
expect(DiscoveryProductionElementsLogs::NameProductLogoSheet).to have_received(:build)
expect(DiscoveryProductionElementsLogs::ProductIntegrationSheet).to have_received(:build)
end
it "sorts the worksheet data by timecode in" do
confirmations = double(:video_release_confirmations)
allow(video).to receive(:video_release_confirmations).and_return(confirmations)
allow(confirmations).to receive(:where).and_return(confirmations)
allow(confirmations).to receive(:order).and_return([])
described_class.new(video).to_xls
expect(video).to have_received(:video_release_confirmations).exactly(6).times
expect(confirmations).to have_received(:where).exactly(6).times
expect(confirmations).to have_received(:order).with(timecode_in: :asc).exactly(6).times
end
end
describe "#filename" do
it "returns video file filename concatenated with production-elements-log and given format" do
expect(described_class.new(video).filename("csv")).to eq "video_file-mp4_production-elements-log.csv"
end
end
end
end
end

View File

@@ -0,0 +1,146 @@
require "rails_helper"
module ExcelReports
module VideoReports
module DiscoveryProductionElementsLogs
RSpec.describe AcquiredFootageAndStillsSheet do
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
it_behaves_like "a worksheet" do
subject { described_class.new(workbook) }
end
describe "#title" do
it "returns 'Acquired Footage & Stills'" do
expect(described_class.new(workbook).title).to eq "Acquired Footage & Stills"
end
end
describe "#fill_content" do
it "adds content from acquired media release" do
instructions = <<~INSTRUCTIONS
All licenses must conform to the DCI contractual requirements and must be fully executed.
Releases, licenses and agreements should only be logged once, based on the order of their appearance in the program.
If an image does not appear in the final Program, log that release after those in the final Program; indicate on the Log sheet NOT IN FINAL PROGRAM and list the camera tape only.
Refer to the source of all third party footage in the exact form as it appears on the release.
Please note that if it is not possible to deliver an English language agreement, an English language translation must accompany any agreement delivered in a foreign language (if applicable).
INSTRUCTIONS
user = create(:user)
project = create(:project, account:user.primary_account)
video = create(:video,
project: project,
number: "45",
name: "Amazing Race",
)
acquired_media_release = create(:acquired_media_release,
project: project,
applicable_medium: ApplicableMedium.last,
territory: Territory.last,
term: Term.last,
restriction: Restriction.last,
name: "Licensor",
person_phone: "1-800-978-2343",
)
confirmation = create(:video_release_confirmation,
video: video,
releasable: acquired_media_release,
source_file_name: "source_file_name",
clip_name: "clippy",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
description: "description",
)
wrapped_confirmation = ReleasableDataAdapter.new(confirmation)
sheet = instance_double(Axlsx::Worksheet, :sheet)
expect(sheet).to receive(:add_row).with(["ACQUIRED FOOTAGE/STILLS/ PUBLIC DOMAIN LOG (for all episodes/programs)"])
expect(sheet).to receive(:add_row).with([instructions])
expect(sheet).to receive(:add_row).with(no_args)
expect(sheet).to receive(:add_row).with(["EPISODE NUMBER", "EPISODE TITLE", "CLIP #", "PROGRAM MASTER TC", "", "TOTAL TIME", "BRIEF VIDEO DESCRIPTION", "LICENSOR\n(incl phone number)", "EXPLOITABLE RIGHTS", "", "", "DCL Rights Waiver Uploaded?"])
expect(sheet).to receive(:add_row).with(["", "", "", "IN", "OUT", "", "", "", "MEDIA", "TERRITORY", "TERM", ""])
expect(sheet).to receive(:add_row).with(["45", "Amazing Race", "source_file_name - clippy", "timecode_in", "timecode_out", "duration", "description", "Licensor\n1-800-978-2343", "All", "Worldwide", "In perpetuity", "None"])
described_class.new(workbook, [wrapped_confirmation]).fill_content(sheet)
end
end
describe "#format" do
let(:sheet) { instance_double(Axlsx::Worksheet, :sheet) }
before :each do
allow(sheet).to receive(:column_widths)
allow(sheet).to receive(:merge_cells)
end
it "sets sheet column widths to 10, 20, 25, 15, 15, 15, 20, 15, 15, 15, 15, 10" do
expect(sheet).to receive(:column_widths).with(10, 20, 25, 15, 15, 15, 20, 15, 15, 15, 15, 10)
described_class.new(workbook).format(sheet)
end
it "merges columns A1:M1 A2:M2 A4:A5 B4:B5 C4:C5 D4:E4 F4:F5 G4:G5 H4:H5 I4:K4 L4:L5" do
%w(A1:M1 A2:M2 A4:A5 B4:B5 C4:C5 D4:E4 F4:F5 G4:G5 H4:H5 I4:K4 L4:L5).each do |cell|
expect(sheet).to receive(:merge_cells).with(cell)
end
described_class.new(workbook).format(sheet)
end
end
describe "#style" do
it "sets sheet style" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
expect(sheet).to receive(:add_style).with("A1", { b: true }, { sz: 14 })
expect(sheet).to receive(:add_style).with("A2", { sz: 10 })
expect(sheet).to receive(:add_style).with(
"A4:L4",
{
bg_color: "97CBFC",
b: true,
border: { :style => :thick, :color => "000000" },
alignment: { :horizontal => :center, :vertical => :center, :wrap_text => true },
sz: 8,
}
)
expect(sheet).to receive(:add_style).with(
"B5:L5",
{
bg_color: "97CBFC",
b: true,
border: { :style => :thick, :color => "000000" },
alignment: { :horizontal => :center, :vertical => :center, :wrap_text => true },
sz: 8,
}
)
expect(sheet).to receive(:add_style).with(
"A4",
{
alignment: { :wrap_text => true },
}
)
expect(sheet).to receive(:add_style).with(
"L4",
{
alignment: { :wrap_text => true },
}
)
expect(sheet).to receive(:add_style).at_least(1).with("A6:L7",
{
border: { style: :thick, color: "000000" },
alignment: { wrap_text: true },
sz: 10
}
)
described_class.new(workbook, ["data1", "data2"]).style(sheet)
end
end
end
end
end
end

View File

@@ -0,0 +1,74 @@
require "rails_helper"
module ExcelReports
module VideoReports
module DiscoveryProductionElementsLogs
RSpec.describe AppearanceSheet do
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
it_behaves_like "a worksheet" do
subject { described_class.new(workbook) }
end
describe "#title" do
it "returns 'Appearance'" do
expect(described_class.new(workbook).title).to eq "Appearance"
end
end
describe "#fill_content" do
it "adds content from the data" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
releasable_datum = ReleasableDataAdapter.new(
build(:video_release_confirmation,
timecode_in: "00:00:05:00",
time_elapsed: 1,
source_file_name: "source",
clip_name: "clip",
description: "old, male, brunette",
video: build(:video, name: "My Video", number: 1),
releasable: build(:appearance_release, person_first_name: "John", person_last_name: "Doe")
)
)
allow(sheet).to receive(:add_row)
release_log = described_class.new(workbook, [releasable_datum])
release_log.fill_content(sheet)
expect(sheet).to have_received(:add_row).with([
"1",
"My Video",
"00:00:05:00",
"source - clip",
"John Doe",
"old, male, brunette",
])
end
end
describe "#format" do
let(:sheet) { instance_double(Axlsx::Worksheet, :sheet) }
before :each do
allow(sheet).to receive(:column_widths)
allow(sheet).to receive(:merge_cells)
end
it "sets sheet column widths to 20, 25, 20, 20, 25, 30" do
expect(sheet).to receive(:column_widths).with(20, 25, 20, 20, 25, 30)
described_class.new(workbook).format(sheet)
end
it "merges columns A2:F2" do
%w(A2:F2).each do |cell|
expect(sheet).to receive(:merge_cells).with(cell)
end
described_class.new(workbook).format(sheet)
end
end
end
end
end
end

View File

@@ -0,0 +1,65 @@
require "rails_helper"
module ExcelReports
module VideoReports
module DiscoveryProductionElementsLogs
RSpec.describe LocationSheet do
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
it_behaves_like "a worksheet" do
subject { described_class.new(workbook) }
end
describe "#title" do
it "returns 'Location'" do
expect(described_class.new(workbook).title).to eq "Location"
end
end
describe "#fill_content" do
it "adds content from the data" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
releasable_datum = ReleasableDataAdapter.new(
build(:video_release_confirmation,
timecode_in: "00:00:05:00",
time_elapsed: 1,
source_file_name: "source",
clip_name: "clip",
description: "restaurant",
video: build(:video, name: "My Video", number: 1),
releasable: build(:location_release, name: "Frank's Taco Shack")
)
)
allow(sheet).to receive(:add_row)
release_log = described_class.new(workbook, [releasable_datum])
release_log.fill_content(sheet)
expect(sheet).to have_received(:add_row).with([
"1",
"My Video",
"00:00:05:00",
"source - clip",
"Frank's Taco Shack restaurant",
])
end
end
describe "#format" do
let(:sheet) { instance_double(Axlsx::Worksheet, :sheet) }
before :each do
allow(sheet).to receive(:column_widths)
allow(sheet).to receive(:merge_cells)
end
it "sets sheet column widths to 20, 20, 15, 20, 40" do
expect(sheet).to receive(:column_widths).with(20, 20, 15, 20, 40)
described_class.new(workbook).format(sheet)
end
end
end
end
end
end

View File

@@ -0,0 +1,44 @@
require "rails_helper"
module ExcelReports
module VideoReports
module DiscoveryProductionElementsLogs
RSpec.describe MediaRightsCertificationSheet do
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
it_behaves_like "a worksheet" do
subject { described_class.new(workbook) }
end
describe "#title" do
it "returns 'Media Rights Certification'" do
expect(described_class.new(workbook).title).to eq "Media Rights Certification"
end
end
describe "#format" do
let(:sheet) { instance_double(Axlsx::Worksheet, :sheet) }
before :each do
allow(sheet).to receive(:column_widths)
allow(sheet).to receive(:merge_cells)
end
it "sets sheet column widths to 10, 20, 10, 10, 10, 10, 10, 10, 10, 10" do
expect(sheet).to receive(:column_widths).with(10, 20, 10, 10, 10, 10, 10, 10, 10, 10)
described_class.new(workbook).format(sheet)
end
it "merges columns A1:J1 A2:J2 A3:J3 B4:J4 B5:J5 B6:J6 A8:J8 B9:J9 B10:J10 B11:J11 B12:J12 B13:J13 A14:J14 A15:J15" do
%w(A1:J1 A2:J2 A3:J3 B4:J4 B5:J5 B6:J6 A8:J8 B9:J9 B10:J10 B11:J11 B12:J12 B13:J13 A14:J14 A15:J15).each do |cell|
expect(sheet).to receive(:merge_cells).with(cell)
end
described_class.new(workbook).format(sheet)
end
end
end
end
end
end

View File

@@ -0,0 +1,98 @@
require "rails_helper"
module ExcelReports
module VideoReports
module DiscoveryProductionElementsLogs
RSpec.describe MusicSheet do
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
it_behaves_like "a worksheet" do
subject { described_class.new(workbook) }
end
describe "#title" do
it "returns 'Music'" do
expect(described_class.new(workbook).title).to eq "Music"
end
end
describe "#fill_content" do
it "adds content from music release" do
user = create(:user)
project = create(:project, account:user.primary_account)
video = create(:video,
project: project,
number: "45",
name: "Amazing Race",
)
confirmation = create(:audio_confirmation,
video: video,
source_file_name: "source_file_name",
composer_info: "composer1, affiliation, 50%|composer2, affiliation, 50%",
publisher_info: "publisher1, affiliation, 50%|publisher2, affiliation, 50%",
confirmation_type: "original_music"
)
wrapped_confirmation = ReleasableDataAdapter.new(confirmation)
sheet = instance_double(Axlsx::Worksheet, :sheet)
expect(sheet).to receive(:add_row).with(["MUSIC LOG (for all episodes/programs) for commissioned work-for-hire music only"])
expect(sheet).to receive(:add_row).with(["Not applicable if program contains 100% library"])
expect(sheet).to receive(:add_row).with(["Episode Title(s) or list \"All\"", "TRACK TITLE", "COMPOSER", "PUBLISHER"])
expect(sheet).to receive(:add_row).with(["Amazing Race", "source_file_name", "composer1, affiliation, 50%\ncomposer2, affiliation, 50%", "publisher1, affiliation, 50%\npublisher2, affiliation, 50%"])
described_class.new(workbook, [wrapped_confirmation]).fill_content(sheet)
end
end
describe "#format" do
let(:sheet) { instance_double(Axlsx::Worksheet, :sheet) }
before :each do
allow(sheet).to receive(:column_widths)
allow(sheet).to receive(:merge_cells)
end
it "sets sheet column widths to 20, 20, 30, 60" do
expect(sheet).to receive(:column_widths).with(20, 20, 30, 60)
described_class.new(workbook).format(sheet)
end
end
describe "#style" do
it "sets sheet style" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
expect(sheet).to receive(:add_style).with("A1", { b: true }, { sz: 14 })
expect(sheet).to receive(:add_style).with("A2", { sz: 14 })
expect(sheet).to receive(:add_style).with(
"A3:D3",
{
bg_color: "97CBFC",
b: true,
border: { :style => :thick, :color => "000000" },
alignment: { :horizontal => :center, :vertical => :center, :wrap_text => true },
sz: 8,
}
)
expect(sheet).to receive(:add_style).with(
"A3",
{
alignment: { :wrap_text => true },
}
)
expect(sheet).to receive(:add_style).at_least(1).with(
"A4:D5",
{
border: { style: :thick, color: "000000" },
alignment: { wrap_text: true },
sz: 10
}
)
described_class.new(workbook, ["data1", "data2"]).style(sheet)
end
end
end
end
end
end

View File

@@ -0,0 +1,65 @@
require "rails_helper"
module ExcelReports
module VideoReports
module DiscoveryProductionElementsLogs
RSpec.describe NameProductLogoSheet do
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
it_behaves_like "a worksheet" do
subject { described_class.new(workbook) }
end
describe "#title" do
it "returns 'Name Product Logo'" do
expect(described_class.new(workbook).title).to eq "Name Product Logo"
end
end
describe "#fill_content" do
it "adds content from the data" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
releasable_datum = ReleasableDataAdapter.new(
build(:video_release_confirmation,
timecode_in: "00:00:05:00",
time_elapsed: 1,
source_file_name: "source",
clip_name: "clip",
description: "brand, can, soda",
video: build(:video, name: "My Video", number: 1),
releasable: build(:material_release, name: "Coca Cola")
)
)
allow(sheet).to receive(:add_row)
release_log = described_class.new(workbook, [releasable_datum])
release_log.fill_content(sheet)
expect(sheet).to have_received(:add_row).with([
"1",
"My Video",
"00:00:05:00",
"source - clip",
"Coca Cola",
])
end
end
describe "#format" do
let(:sheet) { instance_double(Axlsx::Worksheet, :sheet) }
before :each do
allow(sheet).to receive(:column_widths)
allow(sheet).to receive(:merge_cells)
end
it "sets sheet column widths to 15, 25, 15, 20, 40" do
expect(sheet).to receive(:column_widths).with(15, 25, 15, 20, 40)
described_class.new(workbook).format(sheet)
end
end
end
end
end
end

View File

@@ -0,0 +1,44 @@
require "rails_helper"
module ExcelReports
module VideoReports
module DiscoveryProductionElementsLogs
RSpec.describe ProductIntegrationSheet do
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
it_behaves_like "a worksheet" do
subject { described_class.new(workbook) }
end
describe "#title" do
it "returns 'Product Integration'" do
expect(described_class.new(workbook).title).to eq "Product Integration"
end
end
describe "#format" do
let(:sheet) { instance_double(Axlsx::Worksheet, :sheet) }
before :each do
allow(sheet).to receive(:column_widths)
allow(sheet).to receive(:merge_cells)
end
it "sets sheet column widths to 15, 15, 15, 15, 15, 15, 15, 15, 15, 15" do
expect(sheet).to receive(:column_widths).with(15, 15, 15, 15, 15, 15, 15, 15, 15, 15)
described_class.new(workbook).format(sheet)
end
it "merges columns A4:A5 B4:B5 C4:C5 D4:D5 E4:E5 F4:F5 G4:G5 H4:H5 I4:J4" do
%w(A4:A5 B4:B5 C4:C5 D4:D5 E4:E5 F4:F5 G4:G5 H4:H5 I4:J4).each do |cell|
expect(sheet).to receive(:merge_cells).with(cell)
end
described_class.new(workbook).format(sheet)
end
end
end
end
end
end

View File

@@ -0,0 +1,59 @@
require "rails_helper"
module ExcelReports
module VideoReports
module DiscoveryProductionElementsLogs
RSpec.describe TalentSheet do
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
it_behaves_like "a worksheet" do
subject { described_class.new(workbook) }
end
describe "#title" do
it "returns 'Talent'" do
expect(described_class.new(workbook).title).to eq "Talent"
end
end
describe "#fill_content" do
it "adds content from the data" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
releasable_datum = ReleasableDataAdapter.new(
build(:video_release_confirmation,
video: build(:video, name: "My Video", number: 1),
releasable: build(:talent_release, person_first_name: "John", person_last_name: "Doe")
)
)
allow(sheet).to receive(:add_row)
release_log = described_class.new(workbook, [releasable_datum])
release_log.fill_content(sheet)
expect(sheet).to have_received(:add_row).with([
"1",
"My Video",
"",
"John Doe",
])
end
end
describe "#format" do
let(:sheet) { instance_double(Axlsx::Worksheet, :sheet) }
before :each do
allow(sheet).to receive(:column_widths)
allow(sheet).to receive(:merge_cells)
end
it "sets sheet column widths to 20, 20, 30, 60" do
expect(sheet).to receive(:column_widths).with(20, 20, 30, 60)
described_class.new(workbook).format(sheet)
end
end
end
end
end
end

View File

@@ -0,0 +1,53 @@
require "rails_helper"
module ExcelReports
module VideoReports
RSpec.describe NatGeoLegalBinderLog, type: :model do
let(:video) { create(:video) }
subject { described_class.new(video) }
describe "#to_xls" do
it "generates an excel report" do
expect(subject.to_xls).not_to be_nil
end
it "builds the necessary worksheets" do
allow(NatGeoLegalBinderLogs::LegalBinderChecklistSheet).to receive(:build)
allow(NatGeoLegalBinderLogs::AppearanceReleaseLogSheet).to receive(:build)
allow(NatGeoLegalBinderLogs::LocationReleaseLogSheet).to receive(:build)
allow(NatGeoLegalBinderLogs::AcquiredFootageLogSheet).to receive(:build)
allow(NatGeoLegalBinderLogs::ThirdPartyContractLogSheet).to receive(:build)
allow(NatGeoLegalBinderLogs::ProductionPersonnelLogSheet).to receive(:build)
described_class.new(video).to_xls
expect(NatGeoLegalBinderLogs::LegalBinderChecklistSheet).to have_received(:build)
expect(NatGeoLegalBinderLogs::LocationReleaseLogSheet).to have_received(:build)
expect(NatGeoLegalBinderLogs::AcquiredFootageLogSheet).to have_received(:build)
expect(NatGeoLegalBinderLogs::ThirdPartyContractLogSheet).to have_received(:build)
expect(NatGeoLegalBinderLogs::ProductionPersonnelLogSheet).to have_received(:build)
end
it "sorts the worksheet data by timecode in" do
confirmations = double(:video_release_confirmations)
allow(video).to receive(:video_release_confirmations).and_return(confirmations)
allow(confirmations).to receive(:where).and_return(confirmations)
allow(confirmations).to receive(:order).and_return([])
described_class.new(video).to_xls
expect(video).to have_received(:video_release_confirmations).exactly(3).times
expect(confirmations).to have_received(:where).exactly(3).times
expect(confirmations).to have_received(:order).with(timecode_in: :asc).exactly(3).times
end
end
describe "#filename" do
it "includes video file filename, report title, and format" do
expect(subject.filename).to eq "video_file-mp4_legal-binder-log.xlsx"
end
end
end
end
end

View File

@@ -0,0 +1,88 @@
require "rails_helper"
module ExcelReports
module VideoReports
module NatGeoLegalBinderLogs
RSpec.describe AcquiredFootageLogSheet, type: :model do
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
subject { described_class.new(workbook, []) }
it_behaves_like "a worksheet"
describe "#title" do
it "returns the title of the sheet" do
expect(subject.title).to eq "Acquired Footage-Stills Log"
end
end
describe "#fill_content" do
it "adds content from the data" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
releasable_datum = ReleasableDataAdapter.new(
build(:video_release_confirmation,
source_file_name: "source",
clip_name: "clippy",
timecode_in: "00:00:05:00",
timecode_out: "00:00:10:00",
duration: "00:00:15",
description: "Media description",
releasable: build(:acquired_media_release,
applicable_medium: ApplicableMedium.last,
territory: Territory.last,
term: Term.last,
restriction: Restriction.last,
name: "Licensor",
person_address_street1: "123 Main Street",
person_address_city: "New York",
person_address_state: "NY",
person_address_zip: "10000",
)
)
)
allow(sheet).to receive(:add_row)
release_log = described_class.new(workbook, [releasable_datum])
release_log.fill_content(sheet)
expect(sheet).to have_received(:add_row).with([
1,
"Media description",
"00:00:05:00",
"00:00:10:00",
"Licensor\n123 Main Street, New York, NY 10000",
"All",
"Worldwide",
"In perpetuity",
"None",
])
end
end
describe "#format" do
it "sets column widths and merges cells" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
allow(sheet).to receive(:column_widths)
allow(sheet).to receive(:merge_cells)
subject.format(sheet)
expect(sheet).to have_received(:column_widths)
expect(sheet).to have_received(:merge_cells).at_least(1).times
end
end
describe "#style" do
it "sets sheet style" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
allow(sheet).to receive(:add_style)
subject.style(sheet)
expect(sheet).to have_received(:add_style).at_least(1).times
end
end
end
end
end
end

View File

@@ -0,0 +1,75 @@
require "rails_helper"
module ExcelReports
module VideoReports
module NatGeoLegalBinderLogs
RSpec.describe AppearanceReleaseLogSheet, type: :model do
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
subject { described_class.new(workbook, []) }
it_behaves_like "a worksheet"
describe "#title" do
it "returns the title of the sheet" do
expect(subject.title).to eq "Appearance Release Log"
end
end
describe "#fill_content" do
it "adds content from the data" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
releasable_datum = ReleasableDataAdapter.new(
build(:video_release_confirmation,
timecode_in: "00:00:05:00",
releasable: build(:appearance_release,
applicable_medium: ApplicableMedium.last,
territory: Territory.last,
term: Term.last,
restriction: Restriction.last,
person_first_name: "John",
person_last_name: "Doe",
person_address: "123 Main Street, New York, NY 10000")
)
)
allow(sheet).to receive(:add_row)
release_log = described_class.new(workbook, [releasable_datum])
release_log.fill_content(sheet)
expect(sheet).to have_received(:add_row).with([
1,
"00:00:05:00",
"John Doe\n123 Main Street, New York, NY 10000",
"All", "Worldwide", "In perpetuity", "", "None",
])
end
end
describe "#format" do
it "sets column widths and merges cells" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
allow(sheet).to receive(:column_widths)
allow(sheet).to receive(:merge_cells)
subject.format(sheet)
expect(sheet).to have_received(:column_widths)
expect(sheet).to have_received(:merge_cells).at_least(1).times
end
end
describe "#style" do
it "sets sheet style" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
allow(sheet).to receive(:add_style)
subject.style(sheet)
expect(sheet).to have_received(:add_style).at_least(1).times
end
end
end
end
end
end

View File

@@ -0,0 +1,59 @@
require "rails_helper"
module ExcelReports
module VideoReports
module NatGeoLegalBinderLogs
RSpec.describe LegalBinderChecklistSheet, type: :model do
let(:video) { build(:video, number: 1, name: "My Episode") }
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
subject { described_class.new(workbook, [], video) }
it_behaves_like "a worksheet"
describe "#title" do
it "returns the title of the sheet" do
expect(subject.title).to eq "Legal Binder Checklist"
end
end
describe "#fill_content" do
it "adds content from the video" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
allow(sheet).to receive(:add_row)
subject.fill_content(sheet)
expect(sheet).to have_received(:add_row).with(["SERIES TITLE:", ""])
expect(sheet).to have_received(:add_row).with(["EPISODE NUMBER:","1"])
expect(sheet).to have_received(:add_row).with(["EPISODE TITLE:", "My Episode"])
end
end
describe "#format" do
it "sets column widths and merges cells" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
allow(sheet).to receive(:column_widths)
allow(sheet).to receive(:merge_cells)
subject.format(sheet)
expect(sheet).to have_received(:column_widths)
expect(sheet).to have_received(:merge_cells).at_least(1).times
end
end
describe "#style" do
it "sets sheet style" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
allow(sheet).to receive(:add_style)
subject.style(sheet)
expect(sheet).to have_received(:add_style).at_least(1).times
end
end
end
end
end
end

View File

@@ -0,0 +1,78 @@
require "rails_helper"
module ExcelReports
module VideoReports
module NatGeoLegalBinderLogs
RSpec.describe LocationReleaseLogSheet, type: :model do
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
subject { described_class.new(workbook, []) }
it_behaves_like "a worksheet"
describe "#title" do
it "returns the title of the sheet" do
expect(subject.title).to eq "Location Release Log"
end
end
describe "#fill_content" do
it "adds content from the data" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
releasable_datum = ReleasableDataAdapter.new(
build(:video_release_confirmation,
timecode_in: "00:00:05:00",
releasable: build(:location_release,
applicable_medium: ApplicableMedium.last,
territory: Territory.last,
term: Term.last,
restriction: Restriction.last,
name: "My Location",
address_street1: "123 Main Street",
address_city: "New York",
address_state: "NY",
address_zip: "10000")
)
)
allow(sheet).to receive(:add_row)
release_log = described_class.new(workbook, [releasable_datum])
release_log.fill_content(sheet)
expect(sheet).to have_received(:add_row).with([
1,
"00:00:05:00",
"My Location\n123 Main Street, New York, NY 10000",
"",
"All", "Worldwide", "In perpetuity", "", "None",
])
end
end
describe "#format" do
it "sets column widths and merges cells" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
allow(sheet).to receive(:column_widths)
allow(sheet).to receive(:merge_cells)
subject.format(sheet)
expect(sheet).to have_received(:column_widths)
expect(sheet).to have_received(:merge_cells).at_least(1).times
end
end
describe "#style" do
it "sets sheet style" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
allow(sheet).to receive(:add_style)
subject.style(sheet)
expect(sheet).to have_received(:add_style).at_least(1).times
end
end
end
end
end
end

View File

@@ -0,0 +1,54 @@
require "rails_helper"
module ExcelReports
module VideoReports
module NatGeoLegalBinderLogs
RSpec.describe ProductionPersonnelLogSheet, type: :model do
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
subject { described_class.new(workbook, []) }
it_behaves_like "a worksheet"
describe "#title" do
it "returns the title of the sheet" do
expect(subject.title).to eq "Production Personnel Log"
end
end
describe "#fill_content" do
it "adds content for the table" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
allow(sheet).to receive(:add_row)
subject.fill_content(sheet)
expect(sheet).to have_received(:add_row).exactly(12).times
end
end
describe "#format" do
it "sets column widths and merges cells" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
allow(sheet).to receive(:column_widths)
subject.format(sheet)
expect(sheet).to have_received(:column_widths)
end
end
describe "#style" do
it "sets sheet style" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
allow(sheet).to receive(:add_style)
subject.style(sheet)
expect(sheet).to have_received(:add_style).at_least(1).times
end
end
end
end
end
end

View File

@@ -0,0 +1,56 @@
require "rails_helper"
module ExcelReports
module VideoReports
module NatGeoLegalBinderLogs
RSpec.describe ThirdPartyContractLogSheet, type: :model do
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
subject { described_class.new(workbook, []) }
it_behaves_like "a worksheet"
describe "#title" do
it "returns the title of the sheet" do
expect(subject.title).to eq "Third Party Contract Log"
end
end
describe "#fill_content" do
it "adds content for the table" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
allow(sheet).to receive(:add_row)
subject.fill_content(sheet)
expect(sheet).to have_received(:add_row).exactly(13).times
end
end
describe "#format" do
it "sets column widths and merges cells" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
allow(sheet).to receive(:column_widths)
allow(sheet).to receive(:merge_cells)
subject.format(sheet)
expect(sheet).to have_received(:column_widths)
expect(sheet).to have_received(:merge_cells).at_least(1).times
end
end
describe "#style" do
it "sets sheet style" do
sheet = instance_double(Axlsx::Worksheet, :sheet)
allow(sheet).to receive(:add_style)
subject.style(sheet)
expect(sheet).to have_received(:add_style).at_least(1).times
end
end
end
end
end
end

View File

@@ -0,0 +1,134 @@
require "rails_helper"
module ExcelReports
module VideoReports
RSpec.describe ReleasableDataAdapter do
let(:user) { create(:user) }
let(:project) { create(:project, account:user.primary_account, description: "This is the video project description.") }
let(:video) { create(:video, project: project, number: "45", name: "Amazing Race") }
let(:acquired_media_release) { create(:acquired_media_release, project: project, name: "releasable name", person_address_street1: "contact_address") }
let(:confirmation) do
create(:video_release_confirmation,
video: video,
releasable: acquired_media_release,
clip_name: "clippy",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
description: "description",
source_file_name: "cat.mov"
)
end
subject { described_class.new(confirmation) }
describe "#description" do
context "when confirmation contains description" do
it "returns description from confirmation" do
expect(subject.description).to eq "description"
end
end
context "when confirmation does NOT contain description" do
it "returns project description" do
confirmation.description = nil
expect(subject.description).to eq "This is the video project description."
end
end
end
describe "#episode_number" do
it "returns video number" do
expect(subject.episode_number).to eq "45"
end
end
describe "#episode_title" do
it "returns video name" do
expect(subject.episode_title).to eq "Amazing Race"
end
end
describe "#name" do
it "returns releasable name" do
expect(subject.name).to eq "releasable name"
end
end
describe "#source_file_name" do
it "returns source_file_name from confirmation" do
expect(subject.source_file_name).to eq "cat.mov"
end
end
describe "#clip_name" do
it "returns clip_name from confirmation" do
expect(subject.clip_name).to eq "clippy"
end
end
describe "#source_file_and_clip_names" do
context "when source_file_name and clip_name present" do
it "returns source_file_name and clip_name from confirmation joined by -" do
expect(subject.source_file_and_clip_names).to eq "cat.mov - clippy"
end
end
context "when only source_file_name present" do
it "returns source_file_name from confirmation" do
confirmation.source_file_name = "cat.mov"
confirmation.clip_name = nil
expect(subject.source_file_and_clip_names).to eq "cat.mov"
end
end
context "when only clip_name present" do
it "returns clip_name from confirmation" do
confirmation.source_file_name = nil
confirmation.clip_name = "clippy"
expect(subject.source_file_and_clip_names).to eq "clippy"
end
end
context "when source_file_name and clip_name present" do
it "returns empty string" do
confirmation.source_file_name = nil
confirmation.clip_name = ""
expect(subject.source_file_and_clip_names).to eq ""
end
end
end
describe "#timecode_in" do
it "returns timecode_in from confirmation" do
expect(subject.timecode_in).to eq "timecode_in"
end
end
describe "#timecode_out" do
it "returns timecode_out from confirmation" do
expect(subject.timecode_out).to eq "timecode_out"
end
end
describe "#duration" do
it "returns duration from confirmation" do
expect(subject.duration).to eq "duration"
end
end
describe "#confirmation" do
it "returns given confirmation" do
expect(subject.confirmation).to eq confirmation
end
end
describe "#contact_address" do
it "returns address from contact info" do
expect(subject.contact_address).to eq("contact_address")
end
end
end
end
end

View File

@@ -0,0 +1,32 @@
require 'rails_helper'
RSpec.describe FileInfo, type: :model do
describe "associations" do
it { is_expected.to belong_to(:releasable) }
end
describe ".audio" do
it "returns only audio files" do
audio_content_types = %w(audio/mpeg audio/x-aiff audio/aiff audio/wav audio/vnd.wave audio/wav audio/wave audio/x-wav)
audio_files = audio_content_types.map do |content_type|
create(:file_info, content_type: content_type)
end
non_audio_files = [
create(:file_info, content_type: "video/mp4"),
create(:file_info, content_type: ""),
]
results = FileInfo.audio
audio_files.each do |audio_file|
expect(results).to include(audio_file)
end
non_audio_files.each do |non_audio_file|
expect(results).not_to include(non_audio_file)
end
end
end
end

View File

@@ -0,0 +1,54 @@
require "rails_helper"
RSpec.describe FilesForRequest do
let(:video) do
create(:video, analysis_uid: "analysis_uid") do |video|
video.file.key = "awesome"
video.edl_file.key = "sauce"
end
end
subject { described_class.new(video) }
describe "#start_timecode_offset" do
it "returns nil" do
expect(subject.start_timecode_offset).to be_nil
end
end
describe "#file_object_name" do
it "returns file key" do
expect(subject.file_object_name).to eq "awesome"
end
it "returns nil when no video file attached" do
video.file.purge
expect(subject.file_object_name).to be_nil
end
end
describe "#edl_file_object_name" do
it "returns edl file key" do
expect(subject.edl_file_object_name).to eq "sauce"
end
it "returns nil when no video file attached" do
video.edl_file.purge
expect(subject.edl_file_object_name).to be_nil
end
end
describe "#aws_bucket_name" do
it "returns AWS bucket name" do
allow(ENV).to receive(:[])
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("bucket")
expect(subject.aws_bucket_name).to eq "bucket"
end
end
describe "#job_id" do
it "returns the analysis uid of the video" do
expect(subject.job_id).to eq "analysis_uid"
end
end
end

View File

@@ -0,0 +1,21 @@
require "rails_helper"
RSpec.describe GraphicsElement do
describe "associations" do
it { is_expected.to belong_to(:video) }
end
describe "validations" do
it { is_expected.to validate_presence_of(:graphic_type) }
it { is_expected.to validate_presence_of(:text) }
it { is_expected.to validate_presence_of(:time_elapsed) }
end
describe "#appears_at" do
it "returns formatted timecode" do
graphics_element = build(:graphics_element, time_elapsed: "1.039")
expect(graphics_element.appears_at).to eq "00:00:01:01"
end
end
end

View File

@@ -0,0 +1,54 @@
require "rails_helper"
RSpec.describe GraphicsFilesForRequest do
let(:video) do
create(:video, :with_graphics_only_edl_file, analysis_uid: "analysis_uid") do |video|
video.file.key = "awesome"
video.graphics_only_edl_file.key = "sauce"
end
end
subject { described_class.new(video, "offset") }
describe "#start_timecode_offset" do
it "returns given start_timecode_offset" do
expect(subject.start_timecode_offset).to eq "offset"
end
end
describe "#file_object_name" do
it "returns file key" do
expect(subject.file_object_name).to eq "awesome"
end
it "returns nil when no video file attached" do
video.file.purge
expect(subject.file_object_name).to be_nil
end
end
describe "#edl_file_object_name" do
it "returns graphics edl file key" do
expect(subject.edl_file_object_name).to eq "sauce"
end
it "returns nil when no video file attached" do
video.graphics_only_edl_file.purge
expect(subject.edl_file_object_name).to be_nil
end
end
describe "#aws_bucket_name" do
it "returns AWS bucket name" do
allow(ENV).to receive(:[])
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("bucket")
expect(subject.aws_bucket_name).to eq "bucket"
end
end
describe "#job_id" do
it "returns the analysis uid of the video" do
expect(subject.job_id).to eq "analysis_uid"
end
end
end

View File

@@ -0,0 +1,114 @@
require "rails_helper"
describe HeadshotCollection do
describe ".for_project" do
it "generates a collection for a given project" do
project = create(:project,
appearance_releases: create_list(:appearance_release, 1),
talent_releases: create_list(:talent_release, 1),
headshot_collection_uid: "123abc"
)
collection = HeadshotCollection.for_project(project)
expect(collection).not_to be_nil
expect(collection).to be_a(HeadshotCollection)
expect(collection.releasables).to include(project.appearance_releases.first)
expect(collection.releasables).to include(project.talent_releases.first)
expect(collection.collection_uid).to eq(project.headshot_collection_uid)
end
context "when a release has no headshot photo attachment" do
it "excludes that release from the headshot collection" do
project = create(:project,
appearance_releases: build_list(:appearance_release, 1, :without_person_photo),
talent_releases: [],
)
collection = HeadshotCollection.for_project(project)
expect(collection).to be_a(HeadshotCollection)
expect(collection.releasables).not_to include(project.appearance_releases.first)
end
end
end
describe "#as_json" do
it "uses the custom hash format" do
collection = HeadshotCollection.new "uid", []
expect(collection.as_json).to eq(collection.to_hash)
end
end
describe "#to_hash" do
it "includes the name of the bucket where the headshots are stored" do
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("test-bucket")
collection = HeadshotCollection.new("uid", [])
bucket_name = collection.to_hash[:bucket_name]
expect(bucket_name).to eq("test-bucket")
end
it "includes the collection UID" do
collection = HeadshotCollection.new("uid", [])
collection_uid = collection.to_hash[:collection_uid]
expect(collection_uid).to eq("uid")
end
it "forces the collection UID to be a string" do
collection = HeadshotCollection.new(10, [])
collection_uid = collection.to_hash[:collection_uid]
expect(collection_uid).to eq("10")
end
it "includes a mapping of IDs to headshot keys" do
releases = build_releases_with_photo_keys(["123", "456"])
collection = HeadshotCollection.new("uid", releases)
mapping = collection.to_hash[:ids_to_images]
expect(mapping["appearance_release_#{releases.first.id}"]).to include("123")
expect(mapping["appearance_release_#{releases.last.id}"]).to include("456")
end
it "differentiates between release types" do
releases = [
build_release_with_photo_key("123", release_type: :appearance_release),
build_release_with_photo_key("456", release_type: :talent_release),
]
collection = HeadshotCollection.new("uid", releases)
mapping = collection.to_hash[:ids_to_images]
expect(mapping["appearance_release_#{releases.first.id}"]).to include("123")
expect(mapping["talent_release_#{releases.last.id}"]).to include("456")
end
context "when collection uid is blank" do
it "is not included in the hash" do
releases = []
collection = HeadshotCollection.new(nil, releases)
hash = collection.to_hash
expect(hash.keys).not_to include(:collection_uid)
end
end
end
private
def build_release_with_photo_key(key, release_type: :appearance_release)
build_stubbed(release_type).tap do |release|
photo = double(key: key)
allow(release).to receive(:photo).and_return(photo)
end
end
def build_releases_with_photo_keys(keys)
keys.map { |key| build_release_with_photo_key(key) }
end
end

View File

@@ -0,0 +1,21 @@
require "rails_helper"
describe Import do
describe "associations" do
it { is_expected.to belong_to(:project) }
it { is_expected.to belong_to(:releasable).optional }
end
describe "validations" do
it { is_expected.to allow_content_type("application/pdf").for(:file) }
it { is_expected.not_to allow_content_types("image/png", "image/jpeg").for(:file) }
end
describe "enums" do
it { is_expected.to define_enum_for(:status).with_values([:pending, :started, :finished, :failed]) }
end
describe "#file" do
it { is_expected.to respond_to(:file) }
end
end

View File

@@ -0,0 +1,56 @@
require "rails_helper"
RSpec.describe LocationRelease do
it_behaves_like "a contractable"
it_behaves_like "an exploitable"
it_behaves_like "a notable"
it_behaves_like "a photoable"
it_behaves_like "a releasable"
it_behaves_like "a taggable"
describe "associations" do
it { is_expected.to have_many(:video_release_confirmations).dependent(:destroy) }
end
describe "validations" do
it { is_expected.to validate_presence_of(:name) }
it { is_expected.to allow_value("test@test.com", nil).for(:person_email) }
it { is_expected.not_to allow_values("foo", "test@foo", "N/A").for(:person_email) }
context "for native releases" do
it { is_expected.to validate_presence_of(:person_first_name).on(:native) }
it { is_expected.to validate_presence_of(:person_last_name).on(:native) }
it { is_expected.to validate_attachment_of(:signature).on(:native) }
end
it "ensures that film start date is before film end date" do
location_release = build(:location_release, filming_started_on: 1.day.ago, filming_ended_on: 3.days.ago)
expect(location_release).not_to be_valid
expect(location_release.errors[:filming_ended_on]).to include("must be after the filming started on date")
end
end
describe "#uses_edl?" do
it { is_expected.to be_uses_edl }
end
describe "#contract_file_name" do
it "includes project name, release type, signed at date, release number and location name" do
release = create(:location_release_with_contract_template, name: "Benny's Burritos", signed_at: DateTime.new(2020, 2, 10, 12, 0, 0))
expect(release.contract_file_name).to eq("my-video-project_location_2020.02.10_1_benny-s-burritos")
end
context "when signature timestamp is nil" do
it "uses created at date" do
release = create(:location_release_with_contract_template,
name: "Benny's Burritos",
signed_at: nil,
created_at: DateTime.new(2020, 2, 10, 12, 0, 0))
expect(release.contract_file_name).to eq("my-video-project_location_2020.02.10_1_benny-s-burritos")
end
end
end
end

View File

@@ -0,0 +1,46 @@
require "rails_helper"
RSpec.describe MaterialRelease do
it_behaves_like "a contractable"
it_behaves_like "an exploitable"
it_behaves_like "a notable"
it_behaves_like "a photoable"
it_behaves_like "a releasable"
it_behaves_like "a taggable"
describe "associations" do
it { is_expected.to have_many(:video_release_confirmations).dependent(:destroy) }
end
describe "validations" do
it { is_expected.to validate_presence_of(:name) }
it { is_expected.to allow_value("test@test.com", nil).for(:person_email) }
it { is_expected.not_to allow_values("foo", "test@foo", "N/A").for(:person_email) }
context "for native releases" do
it { is_expected.to validate_presence_of(:person_first_name).on(:native) }
it { is_expected.to validate_presence_of(:person_last_name).on(:native) }
it { is_expected.to validate_attachment_of(:signature).on(:native) }
end
end
describe "#uses_edl?" do
it { is_expected.to be_uses_edl }
end
describe "#contract_file_name" do
it "includes project name, release type, signed at date, release number and release name" do
release = create(:material_release_with_contract_template, name: "Coke", person_name: "John Doe", signed_at: DateTime.new(2020, 2, 10, 12, 0, 0))
expect(release.contract_file_name).to eq("my-video-project_material_2020.02.10_1_coke")
end
context "when signer is not present" do
it "includes created at date" do
release = create(:material_release_with_contract_template, name: "Coke", person_name: "John Doe", created_at: DateTime.new(2020, 3, 10, 12, 0, 0))
expect(release.contract_file_name).to eq("my-video-project_material_2020.03.10_1_coke")
end
end
end
end

View File

@@ -0,0 +1,94 @@
require "rails_helper"
RSpec.describe MusicRelease do
it_behaves_like "a contractable"
it_behaves_like "an exploitable"
it_behaves_like "a notable"
it_behaves_like "a releasable"
it_behaves_like "a taggable"
describe "associations" do
it { is_expected.to have_many(:file_infos).dependent(:destroy) }
it { is_expected.to have_many(:composers).dependent(:destroy) }
it { is_expected.to have_many(:publishers).dependent(:destroy) }
end
describe "nested attributes" do
it { is_expected.to accept_nested_attributes_for(:file_infos) }
it { is_expected.to accept_nested_attributes_for(:composers) }
it { is_expected.to accept_nested_attributes_for(:publishers) }
end
describe "validations" do
it { is_expected.to validate_presence_of(:name) }
describe "#person_email" do
it { is_expected.to allow_value("test@test.com", nil).for(:person_email) }
it { is_expected.not_to allow_values("foo", "test@foo", "N/A").for(:person_email) }
end
describe "composers" do
it "validates length 1" do
music_release = build(:music_release)
music_release.composers = []
expect(music_release.valid?).to eq false
expect(music_release.errors[:composers]).to eq ["at least 1 required"]
end
it "validates all percentages add up to 100" do
music_release = build(:music_release, composers: [build(:composer, percentage: 55), build(:composer, percentage: 55)])
expect(music_release.valid?).to eq false
expect(music_release.errors[:base]).to eq ["Composer percentages must add up to 100%"]
end
end
describe "publishers" do
it "validates length 1" do
music_release = build(:music_release)
music_release.publishers = []
expect(music_release.valid?).to eq false
expect(music_release.errors[:publishers]).to eq ["at least 1 required"]
end
it "validates all percentages add up to 100" do
music_release = build(:music_release, publishers: [build(:publisher, percentage: 55), build(:publisher, percentage: 55)])
expect(music_release.valid?).to eq false
expect(music_release.errors[:base]).to eq ["Publisher percentages must add up to 100%"]
end
end
end
describe "attachments" do
it { is_expected.to respond_to(:contract) }
end
describe "#uses_edl?" do
it { is_expected.to be_uses_edl }
end
describe "#composer_info" do
it "returns a single string with all the info included" do
release = build(:music_release, composers: [
build(:composer, name: "composer1", affiliation: "affiliation1", percentage: 50, cae_number: "cae1"),
build(:composer, name: "composer2", affiliation: "affiliation2", percentage: 50, cae_number: "cae2"),
])
expect(release.composer_info).to eq("composer1, affiliation1, 50.0, $cae:cae1|composer2, affiliation2, 50.0, $cae:cae2")
end
context "when a cae number is present" do
it "includes it in the info" do
release = build(:music_release, composers: [
build(:composer, name: "composer1", affiliation: "affiliation1", percentage: 50, cae_number: nil),
build(:composer, name: "composer2", affiliation: "affiliation2", percentage: 50, cae_number: "cae2"),
])
expect(release.composer_info).to eq("composer1, affiliation1, 50.0|composer2, affiliation2, 50.0, $cae:cae2")
end
end
end
end

View File

@@ -0,0 +1,88 @@
require 'rails_helper'
RSpec.describe MuxLiveStream, type: :model do
let(:broadcast) { build(:broadcast, name: "My Broadcast") }
let(:broadcast_2) { create(:broadcast, :with_stream, skip_create_callback: true, name: "My Broadcast") }
let(:live_stream_data) { OpenStruct.new(data: OpenStruct.new(id: "stream_id", stream_key: "stream_key")) }
let(:live_stream_playback_data) { OpenStruct.new(data: OpenStruct.new(id: "playback_id")) }
it "creates live stream and live stream playback URL" do
allow_any_instance_of(MuxRuby::LiveStreamsApi).to receive(:create_live_stream).and_return(live_stream_data)
allow_any_instance_of(MuxRuby::LiveStreamsApi).to receive(:create_live_stream_playback_id).and_return(live_stream_playback_data)
live_stream = MuxLiveStream.new
expect(live_stream.id).to eq "stream_id"
expect(live_stream.key).to eq "stream_key"
expect(live_stream.playback_id).to eq "playback_id"
end
it "destroys live stream" do
expect_any_instance_of(MuxRuby::LiveStreamsApi).to receive(:delete_live_stream).with(broadcast_2.stream_uid)
stream = MuxLiveStream.new
stream.destroy_stream(broadcast_2.stream_uid)
end
context "when reduced latency is enabled via the environment" do
it "turns on reduced latency mode when creating the live stream" do
allow(ENV).to receive(:[]).with("MUX_REDUCED_LATENCY_ENABLED").and_return("true")
allow(ENV).to receive(:[]).with("MUX_TEST_MODE_DISABLED").and_return("false")
request = instance_double(MuxRuby::CreateLiveStreamRequest)
allow(request).to receive(:reduced_latency=)
allow(request).to receive(:new_asset_settings=)
allow(request).to receive(:playback_policy=)
allow(request).to receive(:test=)
allow(MuxRuby::CreateLiveStreamRequest).to receive(:new).and_return(request)
allow_any_instance_of(MuxRuby::LiveStreamsApi).to receive(:create_live_stream).and_return(live_stream_data)
allow_any_instance_of(MuxRuby::LiveStreamsApi).to receive(:create_live_stream_playback_id).and_return(live_stream_playback_data)
live_stream = MuxLiveStream.new
expect(live_stream.id).to eq "stream_id"
expect(request).to have_received(:reduced_latency=).with(true)
end
end
context "when test mode is enabled" do
it "creates live streams in test mode" do
allow(ENV).to receive(:[]).with("MUX_REDUCED_LATENCY_ENABLED").and_return("true")
allow(ENV).to receive(:[]).with("MUX_TEST_MODE_DISABLED").and_return(nil)
request = instance_double(MuxRuby::CreateLiveStreamRequest)
allow(request).to receive(:reduced_latency=)
allow(request).to receive(:new_asset_settings=)
allow(request).to receive(:playback_policy=)
allow(request).to receive(:test=)
allow(MuxRuby::CreateLiveStreamRequest).to receive(:new).and_return(request)
allow_any_instance_of(MuxRuby::LiveStreamsApi).to receive(:create_live_stream).and_return(live_stream_data)
allow_any_instance_of(MuxRuby::LiveStreamsApi).to receive(:create_live_stream_playback_id).and_return(live_stream_playback_data)
live_stream = MuxLiveStream.new
expect(live_stream.id).to eq "stream_id"
expect(request).to have_received(:reduced_latency=).with(true)
expect(request).to have_received(:test=).with(true)
end
end
context "when test mode is disabled" do
it "creates live streams in test mode" do
allow(ENV).to receive(:[]).with("MUX_REDUCED_LATENCY_ENABLED").and_return("true")
allow(ENV).to receive(:[]).with("MUX_TEST_MODE_DISABLED").and_return("true")
request = instance_double(MuxRuby::CreateLiveStreamRequest)
allow(request).to receive(:reduced_latency=)
allow(request).to receive(:new_asset_settings=)
allow(request).to receive(:playback_policy=)
allow(request).to receive(:test=)
allow(MuxRuby::CreateLiveStreamRequest).to receive(:new).and_return(request)
allow_any_instance_of(MuxRuby::LiveStreamsApi).to receive(:create_live_stream).and_return(live_stream_data)
allow_any_instance_of(MuxRuby::LiveStreamsApi).to receive(:create_live_stream_playback_id).and_return(live_stream_playback_data)
live_stream = MuxLiveStream.new
expect(live_stream.id).to eq "stream_id"
expect(request).to have_received(:reduced_latency=).with(true)
expect(request).to have_received(:test=).with(false)
end
end
end

12
spec/models/note_spec.rb Normal file
View File

@@ -0,0 +1,12 @@
require "rails_helper"
RSpec.describe Note, type: :model do
describe "associations" do
it { is_expected.to belong_to(:user).optional }
it { is_expected.to belong_to(:notable) }
end
describe "validations" do
it { is_expected.to validate_presence_of(:content) }
end
end

View File

@@ -0,0 +1,381 @@
require 'rails_helper'
describe PendingAnalysis do
describe '.poll' do
it 'polls videos with pending video analysis' do
allow(PendingAnalysis::PendingVideoAnalysis).to receive(:poll)
PendingAnalysis.poll
expect(PendingAnalysis::PendingVideoAnalysis).to have_received(:poll)
end
it 'polls videos with pending audio analysis' do
allow(PendingAnalysis::PendingAudioAnalysis).to receive(:poll)
PendingAnalysis.poll
expect(PendingAnalysis::PendingAudioAnalysis).to have_received(:poll)
end
end
describe '.expire' do
let(:age_threshold) { 2.days.ago }
it 'expires videos with pending video analysis' do
allow(PendingAnalysis::PendingVideoAnalysis).to receive(:expire)
PendingAnalysis.expire(age_threshold)
expect(PendingAnalysis::PendingVideoAnalysis).to have_received(:expire).with(age_threshold)
end
it 'expires videos with pending audio analysis' do
allow(PendingAnalysis::PendingAudioAnalysis).to receive(:expire)
PendingAnalysis.expire(age_threshold)
expect(PendingAnalysis::PendingAudioAnalysis).to have_received(:expire).with(age_threshold)
end
end
describe PendingAnalysis::PendingVideoAnalysis do
describe '.poll' do
it 'polls all videos with pending analysis' do
pending_analysis = create(:video, analysis_status: :pending, analysis_uid: "pending_uid")
not_pending_analysis = create(:video, analysis_status: :success, analysis_uid: "not_pending_uid")
allow(described_class).to receive(:new).and_return(spy)
described_class.poll
expect(described_class).to have_received(:new).with("pending_uid")
expect(described_class).not_to have_received(:new).with("not_pending_uid")
end
end
describe '.expire' do
it 'expires all videos with pending analysis older than a given time' do
pending_analysis_inside_range = create(:video,
analysis_status: :pending,
analysis_uid: "pending_inside_uid",
analysis_started_at: 1.week.ago)
pending_analysis_outside_range = create(:video,
analysis_status: :pending,
analysis_uid: "pending_outside_uid",
analysis_started_at: 1.minute.ago)
not_pending_analysis = create(:video,
analysis_status: :success,
analysis_uid: "not_pending_uid")
allow(described_class).to receive(:new).and_return(spy)
described_class.expire(1.day.ago)
expect(described_class).to have_received(:new).with("pending_inside_uid")
expect(described_class).not_to have_received(:new).with("pending_outside_uid")
expect(described_class).not_to have_received(:new).with("not_pending_uid")
end
end
describe '#poll' do
let(:video) { create(:video, analysis_status: :pending, analysis_uid: "analysis_uid") }
subject { PendingAnalysis::PendingVideoAnalysis.new(video.analysis_uid) }
context 'when API results are present' do
it 'updates the video analysis status to success' do
allow(BrayniacAI::FacialRecognition).to(
receive(:find).and_return(BrayniacAI::FacialRecognition.new({ results: {} }))
)
subject.poll
expect(video.reload).to be_analysis_success
end
end
context 'when API results are not present' do
it 'does nothing' do
allow(BrayniacAI::FacialRecognition).to receive(:find).and_return(BrayniacAI::FacialRecognition.new)
subject.poll
expect(video.reload).to be_analysis_pending
end
end
context 'when API resource is not found' do
it 'does nothing' do
error = ActiveResource::ResourceNotFound.new('')
allow(BrayniacAI::FacialRecognition).to receive(:find).and_raise(error)
subject.poll
expect(video.reload).to be_analysis_pending
end
end
context 'when API server error occurs' do
before do
allow(Rails.logger).to receive(:error)
allow(subject).to receive(:puts)
end
it 'does nothing' do
error = ActiveResource::ServerError.new('')
allow(BrayniacAI::FacialRecognition).to receive(:find).and_raise(error)
subject.poll
expect(video.reload).to be_analysis_pending
end
it 'prints error message to logger' do
error = ActiveResource::ServerError.new('')
allow(BrayniacAI::FacialRecognition).to receive(:find).and_raise(error)
subject.poll
expect(Rails.logger).to have_received(:error)
expect(subject).to have_received(:puts)
end
end
end
describe '#expire' do
let(:video) { create(:video, analysis_status: :pending, analysis_uid: "analysis_uid") }
subject { PendingAnalysis::PendingVideoAnalysis.new(video.analysis_uid) }
context 'when API results are present' do
it 'updates the video analysis status to success' do
allow(BrayniacAI::FacialRecognition).to(
receive(:find).and_return(BrayniacAI::FacialRecognition.new({ results: {} }))
)
subject.expire
expect(video.reload).to be_analysis_success
end
end
context 'when API results are not present' do
it 'updates the video analysis status to failure' do
allow(BrayniacAI::FacialRecognition).to receive(:find).and_return(BrayniacAI::FacialRecognition.new)
subject.expire
expect(video.reload).to be_analysis_failure
end
end
context 'when API resource is not found' do
it 'updates the video analysis status to failure' do
error = ActiveResource::ResourceNotFound.new('')
allow(BrayniacAI::FacialRecognition).to receive(:find).and_raise(error)
subject.expire
expect(video.reload).to be_analysis_failure
end
end
context 'when API server error occurs' do
before do
allow(Rails.logger).to receive(:error)
allow(subject).to receive(:puts)
end
it 'does nothing' do
error = ActiveResource::ServerError.new('')
allow(BrayniacAI::FacialRecognition).to receive(:find).and_raise(error)
subject.poll
expect(video.reload).to be_analysis_pending
end
it 'prints error message to logger' do
error = ActiveResource::ServerError.new('')
allow(BrayniacAI::FacialRecognition).to receive(:find).and_raise(error)
subject.poll
expect(Rails.logger).to have_received(:error)
expect(subject).to have_received(:puts)
end
end
end
end
describe PendingAnalysis::PendingAudioAnalysis do
describe '.poll' do
it 'polls all videos with pending audio analysis' do
pending_analysis = create(:video, audio_analysis_status: :pending, audio_analysis_uid: "pending_uid")
not_pending_analysis = create(:video, audio_analysis_status: :success, audio_analysis_uid: "not_pending_uid")
allow(described_class).to receive(:new).and_return(spy)
described_class.poll
expect(described_class).to have_received(:new).with("pending_uid")
expect(described_class).not_to have_received(:new).with("not_pending_uid")
end
end
describe '.expire' do
it 'expires all videos with pending analysis older than a given time' do
pending_analysis_inside_range = create(:video,
audio_analysis_status: :pending,
audio_analysis_uid: "pending_inside_uid",
audio_analysis_started_at: 1.week.ago)
pending_analysis_outside_range = create(:video,
audio_analysis_status: :pending,
audio_analysis_uid: "pending_outside_uid",
audio_analysis_started_at: 1.minute.ago)
not_pending_analysis = create(:video,
analysis_status: :success,
analysis_uid: "not_pending_uid")
allow(described_class).to receive(:new).and_return(spy)
described_class.expire(1.day.ago)
expect(described_class).to have_received(:new).with("pending_inside_uid")
expect(described_class).not_to have_received(:new).with("pending_outside_uid")
expect(described_class).not_to have_received(:new).with("not_pending_uid")
end
end
describe '#poll' do
let(:video) { create(:video, audio_analysis_status: :pending, audio_analysis_uid: "analysis_uid") }
subject { PendingAnalysis::PendingAudioAnalysis.new(video.audio_analysis_uid) }
context 'when API results are present' do
it 'updates the audio analysis status to success' do
allow(BrayniacAI::AudioRecognition).to(
receive(:find).and_return(OpenStruct.new({ results: {} }))
)
subject.poll
expect(video.reload).to be_audio_analysis_success
end
end
context 'when API results are not present' do
it 'does nothing' do
allow(BrayniacAI::AudioRecognition).to receive(:find).and_return(BrayniacAI::AudioRecognition.new)
subject.poll
expect(video.reload).to be_audio_analysis_pending
end
end
context 'when API resource is not found' do
it 'does nothing' do
error = ActiveResource::ResourceNotFound.new('')
allow(BrayniacAI::AudioRecognition).to receive(:find).and_raise(error)
subject.poll
expect(video.reload).to be_audio_analysis_pending
end
end
context 'when API server error occurs' do
before do
allow(Rails.logger).to receive(:error)
allow(subject).to receive(:puts)
end
it 'does nothing' do
error = ActiveResource::ServerError.new('')
allow(BrayniacAI::AudioRecognition).to receive(:find).and_raise(error)
subject.poll
expect(video.reload).to be_audio_analysis_pending
end
it 'prints error message to logger' do
error = ActiveResource::ServerError.new('')
allow(BrayniacAI::AudioRecognition).to receive(:find).and_raise(error)
subject.poll
expect(Rails.logger).to have_received(:error)
expect(subject).to have_received(:puts)
end
end
end
describe '#expire' do
let(:video) { create(:video, audio_analysis_status: :pending, audio_analysis_uid: "analysis_uid") }
subject { PendingAnalysis::PendingAudioAnalysis.new(video.audio_analysis_uid) }
context 'when API results are present' do
it 'updates the audio analysis status to success' do
allow(BrayniacAI::AudioRecognition).to(
receive(:find).and_return(BrayniacAI::AudioRecognition.new({ results: {} }))
)
subject.expire
expect(video.reload).to be_audio_analysis_success
end
end
context 'when API results are not present' do
it 'updates the audio analysis status to failure' do
allow(BrayniacAI::AudioRecognition).to receive(:find).and_return(BrayniacAI::AudioRecognition.new)
subject.expire
expect(video.reload).to be_audio_analysis_failure
end
end
context 'when API resource is not found' do
it 'updates the audio analysis status to failure' do
error = ActiveResource::ResourceNotFound.new('')
allow(BrayniacAI::AudioRecognition).to receive(:find).and_raise(error)
subject.expire
expect(video.reload).to be_audio_analysis_failure
end
end
context 'when API server error occurs' do
before do
allow(Rails.logger).to receive(:error)
allow(subject).to receive(:puts)
end
it 'does nothing' do
error = ActiveResource::ServerError.new('')
allow(BrayniacAI::AudioRecognition).to receive(:find).and_raise(error)
subject.poll
expect(video.reload).to be_audio_analysis_pending
end
it 'prints error message to logger' do
error = ActiveResource::ServerError.new('')
allow(BrayniacAI::AudioRecognition).to receive(:find).and_raise(error)
subject.poll
expect(Rails.logger).to have_received(:error)
expect(subject).to have_received(:puts)
end
end
end
end
end

View File

@@ -0,0 +1,168 @@
require "rails_helper"
RSpec.describe ProjectMembership, type: :model do
describe "associations" do
it { is_expected.to belong_to(:project) }
it { is_expected.to belong_to(:user) }
end
describe "validations" do
describe "#user_id" do
subject do
account = build(:account)
build(:project_membership,
user: build(:user, primary_account: account),
project: build(:project, account: account))
end
it { is_expected.to validate_uniqueness_of(:user_id).scoped_to(:project_id).with_message("already belongs to this Project") }
end
it "does not allow account managers" do
account = build(:account)
account_manager = create(:user, :account_manager, accounts: [account])
project = build(:project, account: account)
project_membership = ProjectMembership.new(user: account_manager, project: project)
expect(project_membership).to be_invalid
expect(project_membership.errors[:user]).not_to be_empty
expect(project_membership.errors.full_messages.first).to eq "User is already an account manager"
end
end
describe "#save_and_update_account_membership" do
let(:project) { create(:project) }
context "when no user exists for the given email" do
let(:membership) { ProjectMembership.new(project: project, user_email: "new.user@test.com") }
it "returns true" do
expect(membership.save_and_update_account_membership).to be_truthy
end
it "creates the user" do
expect {
membership.save_and_update_account_membership
}.to change(User, :count).by(1)
user = User.last
expect(user.email).to eq "new.user@test.com"
end
it "creates account membership" do
expect {
membership.save_and_update_account_membership
}.to change(AccountAuth, :count).by(1)
account_auth = AccountAuth.last
user = User.last
expect(account_auth.account).to eq project.account
expect(account_auth.user).to eq user
end
it "creates project membership" do
expect {
membership.save_and_update_account_membership
}.to change(ProjectMembership, :count).by(1)
user = User.last
expect(membership.project).to eq project
expect(membership.user).to eq user
end
end
context "when user exists but has no account access" do
let!(:user) { create(:user, email: "existing.user@test.com") }
let(:membership) { ProjectMembership.new(project: project, user_email: "existing.user@test.com") }
it "returns true" do
expect(membership.save_and_update_account_membership).to be_truthy
end
it "creates account membership" do
expect {
membership.save_and_update_account_membership
}.to change(AccountAuth, :count).by(1)
account_auth = AccountAuth.last
expect(account_auth.account).to eq project.account
expect(account_auth.user).to eq user
end
it "creates project membership" do
expect {
membership.save_and_update_account_membership
}.to change(ProjectMembership, :count).by(1)
expect(membership.project).to eq project
expect(membership.user).to eq user
end
end
context "when user exists and has account access" do
let!(:user) { create(:user, email: "existing.user@test.com", accounts: [project.account]) }
let(:membership) { ProjectMembership.new(project: project, user_email: "existing.user@test.com") }
it "returns true" do
expect(membership.save_and_update_account_membership).to be_truthy
end
it "creates project membership" do
expect {
membership.save_and_update_account_membership
}.to change(ProjectMembership, :count).by(1)
expect(membership.project).to eq project
expect(membership.user).to eq user
end
end
shared_examples "creates no records and returns false" do
it "returns false" do
expect(membership.save_and_update_account_membership).to be_falsey
end
it "does not create new records" do
expect { membership.save_and_update_account_membership }.
to change(ProjectMembership, :count).by(0).
and change(AccountAuth, :count).by(0).
and change(User, :count).by(0)
end
end
context "when user cannot be saved" do
let(:membership) { ProjectMembership.new(project: project, user_email: "new.user@test.com") }
before do
allow_any_instance_of(Oath::Services::SignUp).to receive(:perform).and_return(build(:user))
allow_any_instance_of(User).to receive(:save).and_return(false)
end
include_examples "creates no records and returns false"
end
context "when account auth cannot be saved" do
let(:membership) { ProjectMembership.new(project: project, user_email: "new.user@test.com") }
before do
allow_any_instance_of(AccountAuth).to receive(:save).and_return(false)
end
include_examples "creates no records and returns false"
end
context "when project membership cannot be saved" do
let(:membership) { ProjectMembership.new(project: project, user_email: "new.user@test.com") }
before do
allow_any_instance_of(ProjectMembership).to receive(:save).and_return(false)
end
include_examples "creates no records and returns false"
end
end
end

117
spec/models/project_spec.rb Normal file
View File

@@ -0,0 +1,117 @@
require "rails_helper"
require "zoom_gateway"
RSpec.describe Project, type: :model do
describe "associations" do
it { is_expected.to belong_to(:account) }
it { is_expected.to have_many(:acquired_media_releases).dependent(:destroy) }
it { is_expected.to have_many(:appearance_releases).dependent(:destroy) }
it { is_expected.to have_many(:location_releases).dependent(:destroy) }
it { is_expected.to have_many(:material_releases).dependent(:destroy) }
it { is_expected.to have_many(:music_releases).dependent(:destroy) }
it { is_expected.to have_many(:talent_releases).dependent(:destroy) }
it { is_expected.to have_many(:videos).dependent(:destroy) }
it { is_expected.to have_many(:contract_templates).dependent(:destroy) }
it { is_expected.to have_many(:project_memberships).dependent(:destroy) }
it { is_expected.to have_many(:users).through(:project_memberships) }
it { is_expected.to have_many(:directories).dependent(:destroy) }
it { is_expected.to have_many(:broadcasts).dependent(:destroy) }
it { is_expected.to have_many(:downloads).dependent(:destroy) }
it { is_expected.to have_many(:zoom_meetings).dependent(:destroy) }
end
describe "nested attributes" do
it { is_expected.to accept_nested_attributes_for(:project_memberships) }
end
describe "validations" do
it { is_expected.to validate_presence_of(:name) }
describe "#name uniqueness validation" do
subject { build(:project) }
it { is_expected.to validate_uniqueness_of(:name).scoped_to(:account_id) }
end
end
describe "#import_contract_templates" do
it "imports contract templates from other projects within the account" do
existing_project = create(:project_with_contract_template)
new_project = create(:project, name: "New Project", account: existing_project.account)
expect {
expect(new_project.import_contract_templates(existing_project.contract_templates.pluck(:id))).to be_truthy
}.to change(ContractTemplate, :count).by(1)
expect(new_project.reload.contract_templates.size).to eq(1)
expect(new_project.contract_templates.first.body.to_s).to eq(existing_project.contract_templates.first.body.to_s)
expect(new_project.contract_templates.first.guardian_clause.to_s).to eq(existing_project.contract_templates.first.guardian_clause.to_s)
end
end
describe "#members" do
it "returns users who have membership to the project and account managers" do
account = build(:account)
account_manager = create(:user, :account_manager, primary_account: account)
associate = create(:user, :associate, primary_account: account)
project = create(:project, members: associate, account: account)
members = project.members
expect(members).to include(associate)
expect(members).to include(account_manager)
end
end
describe '#zoom_meeting' do
before(:all) do
WebMock.disable_net_connect!(allow_localhost: true)
end
let(:project) { create(:project) }
context 'there is a meeting already going' do
let!(:zoom_meeting) { create(:zoom_meeting, status: :started, project: project, api_meeting_id: 'meeting-id') }
it 'returns the active meeting' do
expect(project.zoom_meeting).to eq(zoom_meeting)
end
end
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') }
before do
allow_any_instance_of(ZoomGateway).to receive(:create_meeting).and_return('new-meeting-id')
end
it 'creates new meeting' do
expect { project.zoom_meeting }.to change { ZoomMeeting.count }.by(1)
end
it 'returns new meeting' do
expect(project.zoom_meeting.api_meeting_id).to eq('new-meeting-id')
end
end
context 'there is no free user available' do
before do
allow_any_instance_of(ZoomGateway).to receive(:create_host).and_return('new-host-id')
allow_any_instance_of(ZoomGateway).to receive(:create_meeting).and_return('new-meeting-id')
end
it 'creates new user' do
expect { project.zoom_meeting }.to change { ZoomUser.count }.by(1)
end
it 'creates new meeting' do
expect { project.zoom_meeting }.to change { ZoomMeeting.count }.by(1)
end
it 'returns new meeting' do
expect(project.zoom_meeting.api_meeting_id).to eq('new-meeting-id')
end
end
end
end
end

View File

@@ -0,0 +1,9 @@
require "rails_helper"
RSpec.describe Publisher do
describe "validations" do
it { is_expected.to validate_presence_of(:name) }
it { is_expected.to validate_presence_of(:affiliation) }
it { is_expected.to validate_presence_of(:percentage) }
end
end

View File

@@ -0,0 +1,21 @@
require "rails_helper"
RSpec.describe ReleasableParam do
describe "#id" do
it "returns id from first releasable param" do
expect(described_class.new({location_release_id: 1, talent_release_id: 4, another: "param"}).id).to eq 1
end
end
describe "#name" do
it "returns name from first releasable param" do
expect(described_class.new({location_release_id: 1, talent_release_id: 4, another: "param"}).name).to eq "location_release"
end
end
describe "#type" do
it "returns type from first releasable param" do
expect(described_class.new({location_release_id: 1, talent_release_id: 4, another: "param"}).type).to eq LocationRelease
end
end
end

View File

@@ -0,0 +1,54 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe ReleaseNumber, type: :model do
let(:project) { create(:project) }
describe 'value' do
it 'returns a number corresponding to the order in which the release was signed within the project' do
later = create(:appearance_release, signed_at: 1.days.ago, project: project)
earlier = create(:appearance_release, signed_at: 2.day.ago, project: project)
expect(release_number_for(earlier)).to eq 1
expect(release_number_for(later)).to eq 2
end
it 'does not count other release types' do
appearance = create(:appearance_release, project: project)
talent = create(:talent_release, project: project)
expect(release_number_for(appearance)).to eq 1
expect(release_number_for(talent)).to eq 1
end
it 'returns 1 if there are no saved releases' do
appearance = build(:appearance_release, project: project)
expect(release_number_for(appearance)).to eq 1
end
it 'does not count releases from other projects' do
my_appearance = create(:appearance_release, project: project)
their_appearance = create(:appearance_release, project: build(:project))
expect(release_number_for(my_appearance)).to eq 1
expect(release_number_for(their_appearance)).to eq 1
end
it 'uses creation timestamp when signed timestamp is not present' do
third = create(:appearance_release, signed_at: 1.day.ago, created_at: Time.zone.now, project: project)
second = create(:appearance_release, signed_at: nil, created_at: 2.days.ago, project: project)
first = create(:appearance_release, signed_at: 3.days.ago, created_at: Time.zone.now, project: project)
expect(release_number_for(first)).to eq 1
expect(release_number_for(second)).to eq 2
expect(release_number_for(third)).to eq 3
end
end
private
def release_number_for(release)
ReleaseNumber.new(release).value
end
end

View File

@@ -0,0 +1,5 @@
require "rails_helper"
RSpec.describe Restriction, type: :model do
it_behaves_like "a freeformable"
end

View File

@@ -0,0 +1,12 @@
require 'rails_helper'
describe SampleProject do
describe '#new' do
it 'returns a new Project record with filled-in data' do
project = SampleProject.new
attrs = %w(name client_name producer_name producer_address details description)
attrs.all? { |attr| expect(project.send(attr)).to be_present }
end
end
end

View File

@@ -0,0 +1,75 @@
require "rails_helper"
RSpec.describe TalentRelease do
it_behaves_like "a contractable"
it_behaves_like "an exploitable"
it_behaves_like "a notable"
it_behaves_like "a photoable"
it_behaves_like "a releasable"
it_behaves_like "a taggable"
describe "associations" do
it { is_expected.to have_many(:video_release_confirmations).dependent(:destroy) }
it { is_expected.to have_many(:confirmed_videos).source(:video).through(:video_release_confirmations) }
end
describe "validations" do
it { is_expected.to validate_presence_of(:person_first_name) }
it { is_expected.to validate_presence_of(:person_last_name) }
it "requires one or more photo" do
talent_release = build(:talent_release, photos: [])
expect(talent_release).not_to be_valid
expect(talent_release.errors[:photos]).to include("must be included")
end
context "for #person_email" do
it { is_expected.to allow_value("test@test.com", nil).for(:person_email) }
it { is_expected.not_to allow_values("foo", "test@foo", "N/A").for(:person_email) }
end
context "for native releases" do
it { is_expected.to validate_presence_of(:person_phone).on(:native) }
it { is_expected.to validate_attachment_of(:signature).on(:native) }
end
context "for non-native releases" do
it { is_expected.to validate_attachment_of(:contract).on(:non_native) }
end
context "when the signer is a minor" do
subject { build(:talent_release, :minor) }
it { is_expected.to validate_presence_of(:guardian_first_name) }
it { is_expected.to validate_presence_of(:guardian_last_name) }
it { is_expected.to validate_presence_of(:guardian_phone) }
end
end
describe "attachments" do
it { is_expected.to respond_to(:signature) }
end
describe "#uses_edl?" do
it { is_expected.not_to be_uses_edl }
end
describe "#contract_file_name" do
it "includes project name, signed at date, release type, release number and person name" do
release = create(:talent_release_with_contract_template, id: 100, signed_at: Date.new(2020, 2, 10), person_first_name: "John", person_last_name: "Doe")
expect(release.contract_file_name).to eq("my-video-project_talent_2020.02.10_1_doe-john")
end
context "when signed at is nil" do
it "uses the created at date" do
release = create(:talent_release_with_contract_template,
signed_at: nil,
created_at: DateTime.new(2020, 2, 10, 12, 0, 0),
person_first_name: "John", person_last_name: "Doe")
expect(release.contract_file_name).to eq("my-video-project_talent_2020.02.10_1_doe-john")
end
end
end
end

5
spec/models/term_spec.rb Normal file
View File

@@ -0,0 +1,5 @@
require "rails_helper"
RSpec.describe Term, type: :model do
it_behaves_like "a freeformable"
end

View File

@@ -0,0 +1,5 @@
require "rails_helper"
RSpec.describe Territory, type: :model do
it_behaves_like "a freeformable"
end

View File

@@ -0,0 +1,39 @@
require 'rails_helper'
describe UnreleasedAppearance do
describe 'associations' do
it { is_expected.to belong_to(:video) }
end
describe 'validations' do
it do
is_expected.to validate_presence_of(:time_elapsed)
is_expected.to validate_presence_of(:note_category)
end
end
describe "enums" do
it { is_expected.to define_enum_for(:note_category).with_values([:other, :missing_talent_release, :missing_appearance_release, :missing_location_release, :missing_acquired_media_license, :missing_materials_release, :missing_music_license, :logo_may_require_blurring]) }
end
describe ".note_text" do
let(:unreleased_appearance) do
create(:unreleased_appearance)
end
it "returns notes field in case category is 'other'" do
unreleased_appearance.notes = "good note"
result = unreleased_appearance.note_text
expect(result).to eq "good note"
end
it "returns human readable predefined value if category is not 'other'" do
UnreleasedAppearance.note_categories.each_pair do |category, value|
next if category == 'other'
unreleased_appearance.note_category = category
result = unreleased_appearance.note_text
expect(result).to eq unreleased_appearance.note_category.humanize
end
end
end
end

153
spec/models/user_spec.rb Normal file
View File

@@ -0,0 +1,153 @@
require "rails_helper"
RSpec.describe User, type: :model do
describe "associations" do
it { is_expected.to have_many(:accounts).through(:account_auths) }
it { is_expected.to have_many(:account_auths).dependent(:destroy) }
it { is_expected.to have_many(:project_memberships).dependent(:destroy) }
end
describe "validations" do
it { is_expected.to validate_presence_of(:email) }
it { is_expected.to validate_presence_of(:password_digest) }
it { is_expected.to validate_presence_of(:time_zone) }
describe "#email uniqueness validation" do
subject { build(:user) }
it { is_expected.to validate_uniqueness_of(:email) }
end
end
describe "#associate?" do
it "returns true if the user is an associate for the given account" do
account_auth = create(:account_auth, role: :associate)
user = account_auth.user
account = account_auth.account
expect(user.associate?(account)).to be_truthy
end
context "when user does not belong to the given account" do
it "raises an error" do
account = build(:account)
user = build(:user)
expect { user.associate?(account) }.to raise_error(ActiveRecord::RecordNotFound)
end
end
end
describe "#manager?" do
it "returns true if the user is a project manager for the given account" do
account_auth = create(:account_auth, role: :project_manager)
user = account_auth.user
account = account_auth.account
expect(user.manager?(account)).to be_truthy
end
context "when user does not belong to the given account" do
it "raises an error" do
account = build(:account)
user = build(:user)
expect { user.manager?(account) }.to raise_error(ActiveRecord::RecordNotFound)
end
end
end
describe "#account_manager?" do
it "returns true if the user is an account manager for the given account" do
account_auth = create(:account_auth, role: :account_manager)
user = account_auth.user
account = account_auth.account
expect(user.account_manager?(account)).to be_truthy
end
context "when user does not belong to the given account" do
it "raises an error" do
account = build(:account)
user = build(:user)
expect { user.account_manager?(account) }.to raise_error(ActiveRecord::RecordNotFound)
end
end
end
describe "#role_for" do
it "returns the name of the role for the given account" do
account_auth = create(:account_auth, role: :associate)
user = account_auth.user
account = account_auth.account
expect(user.role_for(account)).to eq "associate"
account_auth.update(role: :project_manager)
expect(user.role_for(account)).to eq "project_manager"
account_auth.update(role: :account_manager)
expect(user.role_for(account)).to eq "account_manager"
end
context "when the user does not belong to the given account" do
it "raises an error" do
account = build(:account)
user = build(:user)
expect { user.role_for(account) }.to raise_error(ActiveRecord::RecordNotFound)
end
end
end
describe "#primary_account" do
it "returns the first account the user has access to" do
user = build(:user, accounts: build_list(:account, 2))
expect(user.primary_account).to eq user.primary_account
end
it "adds a given account to the collection" do
account = build(:account)
user = build(:user, accounts: [])
user.primary_account = account
expect(user.accounts).to include account
end
end
describe "#accessible_projects_for" do
context "when user is an account manager" do
it "returns all projects belonging to that account" do
account = create(:account)
account_manager = create(:user, :account_manager, primary_account: account)
member_project = create(:project, name: "Member Project", account: account)
non_member_project = create(:project, name: "Non-Member Project", account: account)
outside_project = create(:project, name: "Outside Project", account: build(:account))
results = account_manager.accessible_projects_for(account)
expect(results).to include(member_project)
expect(results).to include(non_member_project)
expect(results).not_to include(outside_project)
end
end
context "when user is not an account manager" do
it "returns all projects for which the user has a membership" do
account = create(:account)
associate = create(:user, :associate, primary_account: account)
member_project = create(:project, members: associate, name: "Member Project", account: account)
non_member_project = create(:project, members: [], name: "Non-Member Project", account: account)
outside_project = create(:project, name: "Outside Project", account: build(:account))
results = associate.accessible_projects_for(account)
expect(results).to include(member_project)
expect(results).not_to include(non_member_project)
expect(results).not_to include(outside_project)
end
end
end
end

View File

@@ -0,0 +1,120 @@
require "rails_helper"
RSpec.describe VideoAnalysis do
let(:project) { create(:project, headshot_collection_uid: "collection_id") }
let(:video) { create(:video, project: project) }
before :each do
video.file.update(key: "generated-key")
end
describe "#to_hash" do
context "when reanalysis is true" do
it "returns hash of bucket_name, collection_id, video_object_name, reanalysis" do
allow(ENV).to receive(:[])
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("video-dumping-ground")
expect(described_class.new(video, true).to_hash).to eq({
bucket_name: "video-dumping-ground",
collection_id: "collection_id",
video_object_name: "generated-key",
reanalysis: true,
})
end
end
context "when reanalysis is not true" do
it "returns hash of bucket_name, collection_id, video_object_name" do
allow(ENV).to receive(:[])
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("video-dumping-ground")
expect(described_class.new(video, false).to_hash).to eq({
bucket_name: "video-dumping-ground",
collection_id: "collection_id",
video_object_name: "generated-key",
reanalysis: false,
})
end
end
end
describe "#as_json" do
context "when reanalysis is true" do
it "returns json with bucket_name, collection_id, video_object_name, reanalysis" do
allow(ENV).to receive(:[])
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("video-dumping-ground")
expect(described_class.new(video, true).as_json).to eq({
bucket_name: "video-dumping-ground",
collection_id: "collection_id",
video_object_name: "generated-key",
reanalysis: true,
})
end
end
context "when reanalysis is not true" do
it "returns json with bucket_name, collection_id, video_object_name" do
allow(ENV).to receive(:[])
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("video-dumping-ground")
expect(described_class.new(video, false).as_json).to eq({
bucket_name: "video-dumping-ground",
collection_id: "collection_id",
video_object_name: "generated-key",
reanalysis: false,
})
end
end
end
describe "#overlay_video_url" do
let(:video_analysis) { described_class.new(video, false) }
context "when use_overlay_video false" do
before :each do
video_analysis.use_overlay_video = false
end
it "returns nil" do
expect(video_analysis.overlay_video_url).to be_nil
end
end
context "when use_overlay_video true" do
before :each do
video_analysis.use_overlay_video = true
end
context "when overlay_video_url is None" do
before :each do
allow(BrayniacAI::FacialRecognition).to receive(:find).and_return(BrayniacAI::FacialRecognition.new({overlay_video_url: "None"}))
end
it "returns nil" do
expect(video_analysis.overlay_video_url).to be_nil
end
end
context "when overlay_video_url is not None" do
before :each do
allow(BrayniacAI::FacialRecognition).to receive(:find).and_return(BrayniacAI::FacialRecognition.new({overlay_video_url: "www.google.com"}))
end
it "returns overlay_video_url" do
expect(video_analysis.overlay_video_url).to eq "www.google.com"
end
end
end
end
describe "#first_appearances" do
before :each do
allow(BrayniacAI::FacialRecognition).to receive(:find).and_return(BrayniacAI::FacialRecognition.new({first_appearances: ["appearance 1"]}))
end
it "returns first_appearances from response" do
expect(described_class.new(video, false).first_appearances).to eq ["appearance 1"]
end
end
end

View File

@@ -0,0 +1,15 @@
require "rails_helper"
RSpec.describe VideoReleaseConfirmation do
describe "associations" do
it { is_expected.to belong_to(:releasable) }
it { is_expected.to belong_to(:video) }
it { is_expected.to belong_to(:file_info).optional }
end
describe "#appears_at" do
it "returns timecode string from time_elapsed" do
expect(described_class.new(time_elapsed: "5").appears_at).to eq "00:00:05:00"
end
end
end

70
spec/models/video_spec.rb Normal file
View File

@@ -0,0 +1,70 @@
require "rails_helper"
RSpec.describe Video do
describe "associations" do
it { is_expected.to belong_to(:project).touch(true) }
it { is_expected.to have_many(:appearance_releases) }
it { is_expected.to have_many(:location_releases) }
it { is_expected.to have_many(:material_releases) }
it { is_expected.to have_many(:talent_releases) }
it { is_expected.to have_many(:bookmarks).dependent(:destroy) }
it { is_expected.to have_many(:video_release_confirmations).dependent(:destroy) }
it { is_expected.to have_many(:unreleased_appearances).dependent(:destroy) }
it { is_expected.to have_many(:confirmed_talent_releases).source(:releasable).through(:video_release_confirmations) }
it { is_expected.to have_many(:confirmed_appearance_releases).source(:releasable).through(:video_release_confirmations) }
it { is_expected.to have_many(:confirmed_location_releases).source(:releasable).through(:video_release_confirmations) }
it { is_expected.to have_many(:confirmed_material_releases).source(:releasable).through(:video_release_confirmations) }
it { is_expected.to have_many(:confirmed_talent_releases).source(:releasable).through(:video_release_confirmations) }
it { is_expected.to have_many(:confirmed_acquired_media_releases).source(:releasable).through(:video_release_confirmations) }
it { is_expected.to have_many(:graphics_elements).dependent(:destroy) }
it { is_expected.to have_many(:audio_confirmations).dependent(:destroy) }
end
describe "attachments" do
it { is_expected.to respond_to(:file) }
it { is_expected.to respond_to(:edl_file) }
it { is_expected.to respond_to(:graphics_only_edl_file) }
it { is_expected.to respond_to(:audio_only_edl_file) }
end
describe "validations" do
context '#file' do
it { is_expected.to validate_attachment_of(:file) }
it { is_expected.to allow_content_type("video/mp4", "video/quicktime").for(:file) }
it { is_expected.not_to allow_content_types("image/png").for(:file) }
end
context '#edl_file' do
it { is_expected.to validate_attachment_of(:edl_file) }
it { is_expected.to allow_content_type("application/octet-stream").for(:edl_file) }
it { is_expected.not_to allow_content_types("text/plain", "image/png", "image/jpeg").for(:edl_file) }
end
context '#graphics_only_edl_file' do
it { is_expected.to allow_content_type("application/octet-stream").for(:graphics_only_edl_file) }
it { is_expected.not_to allow_content_types("text/plain", "image/png", "image/jpeg").for(:graphics_only_edl_file) }
end
context '#audio_only_edl_file' do
context "when video_editing_system is adobe_premiere" do
subject { build(:video, video_editing_system: "adobe_premiere") }
it { is_expected.to validate_attachment_of(:audio_only_edl_file) }
it { is_expected.to allow_content_type("application/octet-stream").for(:audio_only_edl_file) }
it { is_expected.not_to allow_content_types("text/plain", "image/png", "image/jpeg").for(:audio_only_edl_file) }
end
context "when video_editing_system is not adobe_premiere" do
subject { build(:video, video_editing_system: "avid") }
it { is_expected.not_to validate_attachment_of(:audio_only_edl_file) }
end
end
end
describe "enums" do
it { is_expected.to define_enum_for(:analysis_status).with_values(not_started: 0, pending: 1, success: 2, failure: 3).with_prefix(:analysis) }
it { is_expected.to define_enum_for(:audio_analysis_status).with_values(not_started: 0, pending: 1, success: 2, failure: 3).with_prefix(:audio_analysis) }
it { is_expected.to define_enum_for(:video_editing_system).with_values(avid: 0, adobe_premiere: 1) }
end
end

View File

@@ -0,0 +1,104 @@
require 'rails_helper'
require 'zoom_gateway'
RSpec.describe ZoomMeeting, type: :model do
let(:zoom_meeting) { build(:zoom_meeting, api_meeting_id: nil) }
let(:meeting_dictionary) { {"start_url" => "https://start_url", "join_url" => "https://join_url"} }
before :all do
WebMock.disable_net_connect!(allow_localhost: true)
end
before :each do
allow_any_instance_of(ZoomGateway).to receive(:find_meeting).and_return(meeting_dictionary)
allow_any_instance_of(ZoomGateway).to receive(:create_meeting).and_return("meeting_id")
allow_any_instance_of(ZoomGateway).to receive(:create_host).and_return("host_id")
end
describe "attachments" do
it { is_expected.to respond_to(:recording) }
end
describe "validations" do
context '#recording' do
it { is_expected.to allow_content_type("video/mp4").for(:recording) }
it { is_expected.not_to allow_content_types("image/png").for(:recording) }
end
end
describe 'associations' do
it { is_expected.to belong_to(:zoom_user) }
it { is_expected.to belong_to(:project).optional(true) }
end
describe 'after_create' do
it 'should assign api meeting id' do
expect {
zoom_meeting.save
}.to change { zoom_meeting.api_meeting_id }
end
end
describe ".meeting" do
it 'returns meeting dictionary' do
expect(zoom_meeting.meeting).to eq(meeting_dictionary)
end
it 'recreates meeting if the current on is expired' do
# set the meeting id
zoom_meeting.save
# simulate expiration
allow_any_instance_of(ZoomGateway).to receive(:find_meeting).with("meeting_id").and_raise(ZoomGateway::MeetingExpired)
allow_any_instance_of(ZoomGateway).to receive(:find_meeting).with("new_meeting_id").and_return(meeting_dictionary)
allow_any_instance_of(ZoomGateway).to receive(:create_meeting).and_return("new_meeting_id")
expect {
zoom_meeting.meeting
}.to change { zoom_meeting.api_meeting_id }
end
end
describe '.meeting_url' do
before do
zoom_meeting.api_meeting_id = "meeting_id"
zoom_meeting.save
end
context 'meeting is already started' do
it 'returns join_url' do
zoom_meeting.started!
expect(zoom_meeting.meeting_url).to eq('https://join_url')
end
end
context 'meeting is not started yet' do
it 'return start_url' do
zoom_meeting.created!
expect(zoom_meeting.meeting_url).to eq('https://start_url')
end
end
context 'meeting is ended' do
it 'returns start_url' do
zoom_meeting.ended!
expect(zoom_meeting.meeting_url).to eq('https://start_url')
end
end
end
describe ".join_url" do
it "delegates to the meeting hash" do
expect(zoom_meeting.meeting).to receive(:[]).with("join_url")
zoom_meeting.join_url
end
end
describe ".start_url" do
it "delegates to the meeting hash" do
expect(zoom_meeting.meeting).to receive(:[]).with("start_url")
zoom_meeting.start_url
end
end
end

View File

@@ -0,0 +1,31 @@
require 'rails_helper'
RSpec.describe ZoomUser, type: :model do
describe 'associations' do
it { is_expected.to have_many(:zoom_meetings).dependent(:nullify) }
end
describe 'callbacks' do
let(:zoom_user) { build(:zoom_user) }
context '#after_create' do
it 'triggers create_api_user' do
allow(zoom_user).to receive(:create_api_user)
zoom_user.run_callbacks(:create)
expect(zoom_user).to have_received(:create_api_user)
end
it 'assigns api_id' do
allow_any_instance_of(ZoomGateway).to receive(:create_host).and_return("retrieved_api_id")
zoom_user.save
expect(zoom_user.api_id).to eq "retrieved_api_id"
end
end
context '#before_destroy' do
pending 'aborts if there is api_id assigned'
end
end
end