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,101 @@
require "rails_helper"
RSpec.describe AccountAuthsController, type: :controller do
render_views
let(:current_user) { create(:user) }
let(:other_user) { create(:user, :accountless) }
before do
sign_in current_user
end
describe "#index" do
it "responds successfully" do
get :index
expect(response).to be_ok
end
it "includes all users in the table" do
account = current_user.primary_account
associate = create(:user, :associate, primary_account: account)
project_manager = create(:user, :manager, primary_account: account)
account_manager = create(:user, :account_manager, primary_account: account)
get :index
expect(response.body).to have_content(associate.email)
expect(response.body).to have_content(project_manager.email)
expect(response.body).to have_content(account_manager.email)
end
end
describe "#create" do
let(:new_account) { create(:account) }
it "responds successfully" do
post :create, params: { account_auth: account_auth_params(other_user, new_account) }
expect(response).to redirect_to account_auths_path({ account_id: new_account.id })
end
it "creates a new record" do
expect {
post :create, params: { account_auth: account_auth_params(other_user, new_account) }
}.to change(AccountAuth, :count).by(1)
end
end
describe "#update" do
let(:account_auth) { current_user.account_auths.first }
it "responds with redirect" do
patch :update, params: { id: account_auth, account_auth: { role: "project_manager" } }
expect(response).to be_redirect
expect(response).to redirect_to(account_auths_path)
expect(flash.notice).to be_present
end
it "updates the record" do
patch :update, params: { id: account_auth, account_auth: { role: "project_manager" } }
expect(account_auth.reload.role).to eq "project_manager"
end
context "when record could not be updated" do
before do
allow_any_instance_of(AccountAuth).to receive(:update).and_return(false)
end
it "responds with redirect" do
patch :update, params: { id: account_auth, account_auth: { role: "project_manager" } }
expect(response).to be_redirect
expect(response).to redirect_to(account_auths_path)
expect(flash.alert).to be_present
end
end
end
describe "#destroy" do
let(:account_auth) { create(:account_auth, account: current_user.primary_account, user: other_user, role: :account_manager) }
it "responds with redirect" do
delete :destroy, params: { id: account_auth.id }
expect(response).to be_redirect
expect(response).to redirect_to(account_auths_path)
expect(flash.alert).to be_present
end
end
private
def account_auth_params(user, account)
{ user_email: user.email, account_id: account.id }
end
end

View File

@@ -0,0 +1,24 @@
require "rails_helper"
RSpec.describe AccountSessionsController, type: :controller do
let(:second_account) { create(:account) }
let(:current_user) { create(:user) }
before do
AccountAuth.create(user: current_user, account: second_account, role: :account_manager)
sign_in current_user
end
describe "#update" do
it "responds successfully" do
post :update, params: { account_session: account_sessions_params(second_account) }
expect(response).to redirect_to signed_in_root_path
end
end
private
def account_sessions_params(account)
{ account_id: account.id }
end
end

View File

@@ -0,0 +1,118 @@
require "rails_helper"
RSpec.describe AccountsController, type: :controller do
render_views
describe "#new" do
it "returns a successful response" do
get :new
expect(response).to be_successful
end
end
describe "#create" do
let(:params) do
{
user: {
first_name: "John",
last_name: "Doe",
email: "test_user+1@test.com",
password: "password",
account_name: "Test Dev account",
interested_product_name: "DirectME"
}
}
end
context "when valid account and user parameters are passed" do
it "creates account successfully" do
expect {
post :create, params: params
}.to change(Account, :count).by(1)
end
it "creates user successfully" do
expect {
post :create, params: params
}.to change(User, :count).by(1)
expect(User.last.first_name).to eq("John")
expect(User.last.last_name).to eq("Doe")
end
it "signs in user successfully" do
post :create, params: params
expect(response).to redirect_to(signed_in_root_path)
end
it "creates guest_sign_up event" do
expect {
post :create, params: params
}.to have_enqueued_job(TrackAnalyticsJob).with(be_kind_of(User), be_kind_of(Account), :track_guest_sign_up, user_agent: "Rails Testing", user_ip: "0.0.0.0")
end
it "enqueues hubspot form submission job" do
expect {
post :create, params: params
}.to have_enqueued_job(SubmitHubspotFormJob).with(
"test_user+1@test.com",
"Test Dev account",
i_m_interested_in: "DirectME"
)
end
end
context "when user is not able to sign in immediately after signup" do
before do
allow(@controller).to receive(:sign_in).and_return(nil)
end
it "redirects to the sign in page" do
post :create, params: params
expect(response).to redirect_to(new_session_path)
end
end
context "when account creation fails" do
it "redirects to the new account page" do
post :create, params: { user: { email: "test_user+1@test.com", password: "password", account_name: "" }}
expect(response).to redirect_to(new_account_path)
end
end
context "when user is invalid" do
it "redirects to the new account page" do
post :create, params: { user: { email: "", password: "password", account_name: "Test Dev account" }}
expect(response).to redirect_to(new_account_path)
end
end
end
describe "#update" do
let(:current_user) { create(:user, :account_manager) }
before do
sign_in(current_user)
end
context "when account successfully updated" do
it "returns updated account" do
patch :update, params: { id: current_user.primary_account, account: account_params }, format: :js
expect(current_user.primary_account.reload.logo.attached?).to be(true)
expect(current_user.primary_account.logo.filename).to eq "person_photo.png"
end
end
end
def account_params
logo = Rack::Test::UploadedFile.new(file_fixture("person_photo.png"), "image/png")
{ logo: logo }
end
end

View File

@@ -0,0 +1,209 @@
require "rails_helper"
RSpec.describe AcquiredMediaReleasesController, type: :controller do
render_views
let(:user) { create(:user) }
let(:account) { user.primary_account }
let(:project) { create(:project, account: user.primary_account) }
before do
sign_in user
end
describe "#index" do
it "responds successfully" do
get :index, params: { project_id: project }
expect(response).to be_successful
end
it "renders content" do
release = create(:acquired_media_release, project: project, name: "My Release")
create(:note, notable: release, content: "Some notes here")
get :index, params: { project_id: project }
expect(response.body).to have_content "My Release"
expect(response.body).to have_content "0"
expect(response.body).to have_content "Some notes here"
expect(response.body).to have_link "Import Release"
expect(response.body).to have_content "Manage"
end
context "when there are no acquired_media releases" do
it "renders an empty message" do
get :index, params: { project_id: project }
expect(response.body).to have_content("Acquired Media Releases will appear here")
end
end
context "when there are many records" do
it "paginates the table" do
create_list(:acquired_media_release, 20, project: project)
get :index, params: { project_id: project }
expect(response.body).to have_link("2", href: project_acquired_media_releases_path(project, page: 2))
end
end
context "for xhr request" do
it "filters the releases by a query param" do
acquired_media_releases = [
create(:acquired_media_release, name: "OJ Simpson Trial Audio", project: project),
create(:acquired_media_release, name: "Shark Footage", project: project),
]
get :index, params: { project_id: project, query: "Shark" }, xhr: true
expect(response.body).not_to have_content("OJ")
expect(response.body).to have_content("Shark")
end
end
end
describe "#new" do
it "responds successfully" do
get :new, params: { project_id: project }
expect(response).to be_successful
end
end
describe "#create" do
it "responds successfully" do
expect {
post :create, params: { project_id: project, acquired_media_release: acquired_media_release_params }
}.to change(AcquiredMediaRelease, :count).by(1)
expect(response).to redirect_to [project, :acquired_media_releases]
expect(flash.notice).not_to be_nil
end
it "enqueues tagging job" do
expect {
post :create, params: { project_id: project, acquired_media_release: acquired_media_release_params }
}.to have_enqueued_job(SetTagsForReleasableJob).with(AcquiredMediaRelease.last)
end
it "creates nested file info records" do
expect {
post :create, params: {
project_id: project,
acquired_media_release: acquired_media_release_params.merge(
file_infos_attributes: {
0 => attributes_for(:file_info)
}
)
}
}.to change(FileInfo, :count).by(1)
expect(AcquiredMediaRelease.last.file_infos.size).to eq(1)
end
it "logs analytics" do
expect {
post :create, params: { project_id: project, acquired_media_release: acquired_media_release_params }
}.to(
have_enqueued_job(TrackAnalyticsJob).with(user, account, :track_create_non_native_release, release_type: "AcquiredMediaRelease", user_agent: "Rails Testing", user_ip: "0.0.0.0")
)
end
context "when the record would be invalid" do
before :each do
allow_any_instance_of(AcquiredMediaRelease).to receive(:save).and_return(false)
end
it "re-renders the form" do
expect {
post :create, params: { project_id: project, acquired_media_release: { name: "" } }
}.not_to change(AcquiredMediaRelease, :count)
expect(response).to be_successful
expect(response.body).to include "Import Acquired Media Release"
end
it "does not enqueue any jobs" do
expect {
post :create, params: { project_id: project, acquired_media_release: acquired_media_release_params }
}.not_to have_enqueued_job
end
end
end
describe "#edit" do
let(:non_native_acquired_media_release) { create(:acquired_media_release, project: project ) }
let(:native_acquired_media_release) { create(:acquired_media_release, :native, project: project ) }
it "responds successfully for non-native release" do
get :edit, params: { id: non_native_acquired_media_release }
expect(response).to be_successful
end
it "responds with error for native release" do
expect{get :edit, params: { id: native_acquired_media_release }}.to raise_exception Pundit::NotAuthorizedError
end
end
describe "#update" do
let(:acquired_media_release) { create(:acquired_media_release, project: project) }
it "responds successfully" do
put :update, params: { id: acquired_media_release, acquired_media_release: { name: "Updated name" } }
expect(response).to redirect_to [project, :acquired_media_releases]
expect(flash.notice).to eq "The acquired media release has been updated"
expect(acquired_media_release.reload.name).to eq "Updated name"
end
context "when the record would be invalid" do
before :each do
allow_any_instance_of(AcquiredMediaRelease).to receive(:update).and_return(false)
end
it "re-renders the form" do
put :update, params: { id: acquired_media_release, acquired_media_release: acquired_media_release_params }
expect(response).to render_template :edit
expect(flash.notice).to be_nil
end
end
end
describe "#destroy" do
let!(:acquired_media_release) { create(:acquired_media_release, project: project) }
it "destroys the record" do
expect {
delete :destroy, params: { id: acquired_media_release }
}.to change(AcquiredMediaRelease, :count).by(-1)
end
it "redirects to project and sets alert" do
delete :destroy, params: { id: acquired_media_release }
expect(response).to redirect_to [project, :acquired_media_releases]
expect(flash.alert).to eq "The acquired media release has been deleted"
end
end
private
def acquired_media_release_params
attributes_for(:acquired_media_release).merge(exploitable_rights_params)
end
def exploitable_rights_params
{
applicable_medium_id: ApplicableMedium.last.id,
applicable_medium_text: "applicable_media",
territory_id: Territory.last.id,
territory_text: "territory",
term_id: Term.last.id,
term_text: "term",
restriction_id: Restriction.last.id,
restriction_text: "restrictions",
}
end
end

View File

@@ -0,0 +1,172 @@
require "rails_helper"
RSpec.describe Admin::AccountsController, type: :controller do
render_views
let(:current_user) { create(:user, :admin) }
before do
sign_in(current_user)
end
describe "#index" do
it "returns a successful response" do
get :index
expect(response).to be_successful
end
it "has a search field form" do
get :index
expect(response.body).to have_button("search-button")
end
it "paginates the results" do
create_list(:account, 20)
get :index
expect(response.body).to have_link("2", href: admin_accounts_path(page: 2))
end
it "filters the account by a query param" do
create(:account, name: "First account")
create(:account, name: "Second account")
get :index, params: { query: "Second" }
expect(response.body).not_to have_content("First account")
expect(response.body).to have_content("Second account")
end
end
describe "#new" do
it "returns a successful response" do
get :new
expect(response).to be_successful
end
it "assigns 'account'" do
get :new
expect(assigns(:account)).not_to be_nil
end
end
describe "#create" do
it "responds with a redirect" do
post :create, params: { account: account_params }
expect(response).to be_redirect
end
it "sets a flash notice" do
post :create, params: { account: account_params }
expect(flash.notice).to eq "The account was created"
end
it "creates a new Account record" do
expect {
post :create, params: { account: account_params }
}.to change(Account, :count).by(1)
expect(assigns(:account)).not_to be_nil
end
context "when record cannot be saved" do
before do
allow_any_instance_of(Account).to receive(:save).and_return(false)
end
it "re-displays the form" do
post :create, params: { account: account_params }
expect(response).to be_successful
expect(flash.notice).to be_nil
end
it "does not create a new Account record" do
expect {
post :create, params: { account: account_params }
}.not_to change(Account, :count)
end
end
end
describe "#show" do
it "returns a successful response" do
get :show, params: { id: current_user.primary_account }
expect(response).to be_successful
end
it "has a video search field form" do
get :index
expect(response.body).to have_button("search-button")
end
it "paginates the video list" do
project = create(:project, account: current_user.primary_account)
create_list(:video, 20, project: project )
get :show, params: { id: current_user.primary_account }
expect(response.body).to have_link("2", href: admin_account_path(current_user.primary_account, page: 2))
end
it "filters the videos by a query param" do
project = create(:project, account: current_user.primary_account)
create(:video, project: project, name: "First video")
create(:video, project: project, name: "Second video")
get :show, params: { id: current_user.primary_account, query: "Second"}
expect(response.body).not_to have_content("First video")
expect(response.body).to have_content("Second video")
end
end
describe "#edit" do
it "assigns account" do
get :show, params: { id: current_user.primary_account }
expect(response).to be_successful
expect(assigns(:account)).to eq current_user.primary_account
end
end
describe "#update" do
context "when account successfully updated" do
it "returns updates account" do
patch :update, params: { id: current_user.primary_account, account: { name: "Fred", plan_uid: "deliverme" } }
expect(current_user.primary_account.reload.name).to eq "Fred"
expect(current_user.primary_account.plan_uid).to eq "deliverme"
end
it "redirects to accounts page" do
patch :update, params: { id: current_user.primary_account, account: account_params }
expect(response).to redirect_to admin_accounts_path
end
end
context "when account update fails" do
before :each do
allow_any_instance_of(Account).to receive(:update).and_return(false)
end
it "renders edit" do
patch :update, params: { id: current_user.primary_account, account: account_params }
expect(response).to render_template :edit
end
end
end
def account_params
attributes_for(:account)
end
end

View File

@@ -0,0 +1,28 @@
require 'rails_helper'
RSpec.describe Admin::ApplicationController, type: :controller do
controller do
def new
authorize Account
render plain: "Hello world"
end
end
it "allows admin users" do
admin = create(:user, :admin)
sign_in(admin)
get :new
expect(response).to be_successful
end
it "redirects non-admin users" do
non_admin = create(:user, admin: false)
sign_in(non_admin)
get :new
expect(response).to be_redirect
end
end

View File

@@ -0,0 +1,30 @@
require "rails_helper"
RSpec.describe Admin::MasqueradesController, type: :controller do
render_views
let!(:current_user) { create(:user, :admin) }
let!(:unprivileged_user) { create(:user) }
before do
sign_in(current_user)
end
describe "#create" do
it "redirects to the first page" do
post :create, params: { user_id: unprivileged_user.id }
expect(response).to redirect_to signed_in_root_path
end
end
describe "#destroy" do
it "returns to the users page" do
post :create, params: { user_id: unprivileged_user.id }
delete :destroy
expect(response).to redirect_to admin_users_path
end
end
end

View File

@@ -0,0 +1,233 @@
require "rails_helper"
RSpec.describe Admin::UsersController, type: :controller do
render_views
let!(:current_user) { create(:user, :admin) }
before do
sign_in(current_user)
end
describe "#index" do
it "returns a successful response" do
get :index
expect(response).to be_successful
end
describe "for xhr request" do
before do
users = [
create(:user, :with_name),
create(:user, :with_different_name)
]
end
it "shows all users if search field is empty" do
get :index, xhr: true
expect(response.body).to have_content("John")
expect(response.body).to have_content("Specimen")
end
it "shows only users with first name, last name or email matching search query" do
get :index, params: { query: "John" }, xhr: true
expect(response.body).to have_content("John")
expect(response.body).not_to have_content("Specimen")
get :index, params: { query: "Simpson" }, xhr: true
expect(response.body).not_to have_content("John")
expect(response.body).to have_content("Specimen")
get :index, params: { query: "different@" }, xhr: true
expect(response.body).not_to have_content("John")
expect(response.body).to have_content("Specimen")
end
end
end
describe "#new" do
it "returns a successful response" do
get :new
expect(response).to be_successful
end
it "assigns user, accounts" do
get :new
expect(assigns(:user)).not_to be_nil
expect(assigns(:accounts)).to eq Account.all
end
end
describe "#create" do
it "responds with a redirect" do
post :create, params: { user: user_create_params }
expect(response).to be_redirect
expect(response).to redirect_to [:admin, :users]
end
it "sets a flash notice" do
post :create, params: { user: user_create_params }
expect(flash.notice).to eq "The user was created"
end
it "creates a new User record" do
expect {
post :create, params: { user: user_create_params }
}.to change(User, :count).by(1)
expect(assigns(:user)).to have_attributes(
email: "bob@example.com",
admin: false,
)
end
it "sends a welcome email" do
assert_enqueued_emails 1 do
post :create, params: { user: user_create_params }
end
end
context "when record cannot be saved" do
before do
allow_any_instance_of(User).to receive(:valid?).and_return(false)
end
it "re-displays the form" do
post :create, params: { user: user_create_params }
expect(response).to be_successful
expect(flash.notice).to be_nil
end
it "does not create a new User record" do
expect {
post :create, params: { user: user_create_params }
}.not_to change(User, :count)
end
it "assigns accounts" do
post :create, params: { user: user_create_params }
expect(assigns(:accounts)).to eq Account.all
end
end
end
describe "#edit" do
let(:user) { create(:user) }
it "returns a successful response" do
get :edit, params: { id: user }
expect(response).to be_successful
end
it "assigns user, accounts" do
get :edit, params: { id: user }
expect(assigns(:user)).to eq user
expect(assigns(:accounts)).to eq Account.all
end
end
describe "#update" do
let(:user) { create(:user) }
it "redirects to users page" do
patch :update, params: { id: user, user: user_update_params }
expect(response).to be_redirect
expect(response).to redirect_to admin_users_path
end
it "sets a flash notice" do
patch :update, params: { id: user, user: user_update_params }
expect(flash.notice).to eq "The user was updated"
end
it "updates the user record" do
patch :update, params: { id: user, user: { email: "new-email@example.com" } }
expect(assigns(:user)).to have_attributes(
email: "new-email@example.com",
admin: false,
)
end
it "updates user's password" do
patch :update, params: { id: user, user: { email: "new-email@example.com", password: "New Pass" } }
expect(user.reload.password_digest).to eq("New Pass")
end
context "when record cannot be saved" do
before do
allow_any_instance_of(User).to receive(:update).and_return(false)
end
it "re-displays the form" do
patch :update, params: { id: user, user: user_update_params }
expect(response).to be_successful
expect(flash.notice).to be_nil
end
it "assigns accounts" do
patch :update, params: { id: user, user: user_update_params }
expect(assigns(:accounts)).to eq Account.all
end
end
end
describe "#destroy" do
let!(:user) { create(:user, accounts: current_user.accounts) }
let(:note_author_user) { create(:user, accounts: current_user.accounts) }
it "deletes user" do
expect {
delete :destroy, params: { id: user }
}.to change(User, :count).by(-1)
end
it "redirects to account edit page" do
delete :destroy, params: { id: user }
expect(response).to redirect_to admin_users_path
end
it "deletes user who posted notes" do
note = create(:note, user: note_author_user, email: note_author_user.email)
expect {
delete :destroy, params: { id: note_author_user }
}.to change(User, :count).by(-1)
expect(response).to redirect_to admin_users_path
expect(Note.find(note.id).email).to eq note.email
end
end
private
def user_create_params
{
email: "bob@example.com",
password: "password",
account_id: current_user.primary_account.id,
admin: false,
role: "account_manager",
}
end
def user_update_params
{
email: "bob@example.com",
}
end
end

View File

@@ -0,0 +1,101 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Api::AcquiredMediaReleasesController, type: :controller do
let(:current_user) { create(:user) }
let(:project) { create(:project, name: 'first', account: current_user.primary_account) }
describe '#index' do
it 'returns a succesful response' do
create(:acquired_media_release, name: 'ct1', project_id: project.id)
sign_in_to_api(current_user)
get :index, params: { project_id: project.id }
expect(response).to be_successful
old_body = response.body
get :index, params: { project_id: project.id, updated_since: (DateTime.current + 10.days).to_date.to_s }
expect(response.body).not_to eq(old_body)
end
end
describe '#show' do
it 'returns a succesful response' do
tested_release = create(:acquired_media_release, name: 'ct1', project_id: project.id)
sign_in_to_api(current_user)
get :show, params: { id: tested_release.id }
expect(response).to be_successful
end
end
describe '#create' do
before do
template = create(:contract_template, name: 'ct1', project_id: project.id)
signature = signature_base64
@parameters = {
contract_template_id: template.id,
acquired_media_release: {
signature: signature,
person_phone: '123',
name: 'aaa',
signed_at: '2020-01-01 16:50:26 UTC'
}
}
sign_in_to_api(current_user)
end
it 'returns 201 - created response' do
post :create, params: @parameters
expect(response.status).to eq 201
expect(AcquiredMediaRelease.last.signature).to be_attached
end
it 'saves signed on date correctly' do
post :create, params: @parameters
expect(response.status).to eq 201
expect(AcquiredMediaRelease.last.signed_on).to eq '01/01/20'
end
it 'runs attach contract to background job' do
expect do
post :create, params: @parameters
end.to have_enqueued_job(AttachContractToReleasableJob).with(AcquiredMediaRelease.last)
end
it 'runs set tags for background releasable job' do
expect do
post :create, params: @parameters
end.to have_enqueued_job(SetTagsForReleasableJob).with(AcquiredMediaRelease.last)
end
it 'fails if there is no signature' do
template = create(:contract_template, name: 'ct1', project_id: project.id)
parameters = {
contract_template_id: template.id,
acquired_media_release: {
name: 'aaa'
}
}
sign_in_to_api(current_user)
expect do
post :create, params: parameters
end.to raise_error(ActiveRecord::RecordInvalid)
end
end
private
def signature_base64
@signature_base64 ||= Base64Image.from_image(file_fixture('signature.png')).data_uri
end
def response_body_data_attributes
JSON.parse(response.body).dig('data', 'attributes')
end
end

View File

@@ -0,0 +1,219 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Api::AppearanceReleasesController, type: :controller do
let(:current_user) { create(:user) }
let(:project) { create(:project, name: 'first', account: current_user.primary_account) }
before do
allow(BrayniacAI::Validation).to receive(:create).and_return(double(:validation, valid: true))
end
describe '#index' do
it 'returns a succesful response' do
create(:appearance_release, person_first_name: 'ct1', person_last_name: 'ct12', project_id: project.id)
sign_in_to_api(current_user)
get :index, params: { project_id: project.id }
expect(response).to be_successful
old_body = response.body
get :index, params: { project_id: project.id, updated_since: (DateTime.current + 10.days).to_date.to_s }
expect(response.body).not_to eq(old_body)
end
end
describe '#show' do
it 'returns a succesful response' do
tested_release = create(:appearance_release, person_first_name: 'ct1', person_last_name: 'ct12', project_id: project.id)
sign_in_to_api(current_user)
get :show, params: { id: tested_release.id }
expect(response).to be_successful
end
it 'includes photos' do
project = create(:project, account_id: current_user.primary_account.id)
appearance_release = create(:appearance_release, person_first_name: 'Release', person_last_name: 'Name', project: project)
sign_in_to_api(current_user)
get :show, params: { id: appearance_release.id }
photo = appearance_release.person_photo
data = {
'id' => photo.id.to_s,
'type' => 'active_storage_attachment',
'attributes' => {
'content_type' => photo.content_type,
'filename' => photo.filename.to_s,
'url' => photo_path_for(photo),
'thumbnail_url' => photo_variant_path_for(photo, '150x150')
}
}
expect(response_body_included_attributes).to include(data)
end
end
describe '#create' do
before do
template = create(:contract_template, name: 'ct1', project_id: project.id)
small_photo = photo_base64
guardian_photo = guardian_photo_base64
signature = signature_base64
@parameters = {
contract_template_id: template.id,
appearance_release: {
signature: signature,
person_phone: '123',
person_first_name: 'aaa',
person_last_name: 'bbb',
minor: true,
guardian_first_name: 'John',
guardian_last_name: 'Doe',
guardian_phone: '9191919191',
signed_at: '2020-01-01 16:50:26 UTC',
person_photo: {
io: small_photo,
filename: 'filenameee.jpg'
}
}
}
@guardian_info = {
minor: true,
guardian_name: 'Guardian',
guardian_phone: '101010'
}
@guardian_photo = {
guardian_photo: {
io: guardian_photo,
filename: 'guardianPhoto.jpeg'
}
}
sign_in_to_api(current_user)
end
it 'returns 201 - created response' do
post :create, params: @parameters
expect(response.status).to eq 201
expect(AppearanceRelease.last.signature).to be_attached
end
it 'saves signed on date correctly' do
post :create, params: @parameters
expect(response.status).to eq 201
expect(AppearanceRelease.last.signed_on).to eq '01/01/20'
end
it 'runs attach contract to background job' do
expect do
post :create, params: @parameters
end.to have_enqueued_job(AttachContractToReleasableJob).with(AppearanceRelease.last)
end
it 'runs add headshot collection uid background job' do
expect do
post :create, params: @parameters
end.to have_enqueued_job(AddHeadshotCollectionUidToProjectJob).with(project)
end
it 'runs set tags for background releasable job' do
expect do
post :create, params: @parameters
end.to have_enqueued_job(SetTagsForReleasableJob).with(AppearanceRelease.last)
end
it 'fails if there is no signature' do
template = create(:contract_template, name: 'ct1', project_id: project.id)
small_photo = photo_base64
parameters = {
contract_template_id: template.id,
appearance_release: {
person_name: 'aaa'
}
}
parameters[:appearance_release][:person_photo] = {
io: small_photo,
filename: 'filenameee.jpg'
}
sign_in_to_api(current_user)
expect do
post :create, params: parameters
end.to raise_error(ActiveRecord::RecordInvalid)
end
it 'returns 201 for minor without guardian photo' do
params_without_guardian_photo = @parameters
params_without_guardian_photo[:appearance_release].merge!(@guardian_info)
post :create, params: params_without_guardian_photo
expect(response.status).to eq 201
expect(AppearanceRelease.last.signature).to be_attached
expect(AppearanceRelease.last.guardian_photo).not_to be_attached
end
it 'returns 201 for minor with guardian photo' do
params_with_guardian_photo = @parameters
params_with_guardian_photo[:appearance_release].merge!(@guardian_info, @guardian_photo)
post :create, params: params_with_guardian_photo
expect(response.status).to eq 201
appearance_release = AppearanceRelease.last
photo = appearance_release.guardian_photo
data = {
'id' => photo.id.to_s,
'type' => 'active_storage_attachment',
'attributes' => {
'content_type' => photo.content_type,
'filename' => photo.filename.to_s,
'url' => photo_path_for(photo),
'thumbnail_url' => photo_variant_path_for(photo, '150x150')
}
}
expect(response_body_included_attributes).to include(data)
expect(appearance_release.signature).to be_attached
expect(appearance_release.guardian_photo).to be_attached
end
end
private
def photo_base64
@photo_base64 ||= Base64Image.from_image(file_fixture('person_photo.png')).data_uri
end
def guardian_photo_base64
@guardian_photo_base64 ||= Base64Image.from_image(file_fixture('pratt.jpg')).data_uri
end
def signature_base64
@signature_base64 ||= Base64Image.from_image(file_fixture('signature.png')).data_uri
end
def photo_path_for(attachment)
Rails.application.routes.url_helpers.rails_blob_url(attachment, host: AppHost.new.domain_with_port)
end
def photo_variant_path_for(attachment, _size)
Rails.application.routes.url_helpers.rails_representation_url(attachment.variant(resize: '150x150'), host: AppHost.new.domain_with_port)
end
def response_body_data_attributes
JSON.parse(response.body).dig('data', 'attributes')
end
def response_body_included_attributes
JSON.parse(response.body).dig('included')
end
end

View File

@@ -0,0 +1,156 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Api::BroadcastsController, type: :controller do
let(:current_user) { create(:user, :admin) }
describe '#index' do
before do
allow(MuxLiveStream).to receive(:new).and_return(double(id: 'id', key: 'key', playback_id: 'playback_id'))
end
it 'returns a list of all broadcasts ready for streaming in the project' do
project = create(:project, name: 'first', account_id: current_user.primary_account.id)
br1 = create(:broadcast, project: project, name: 'Created Bc', status: 'created')
br2 = create(:broadcast, project: project, name: 'Idle Bc', status: 'idle')
sign_in_to_api(current_user)
get :index, params: { project_id: project.id }
expect(response).to be_successful
expect(response.body).to have_content('Created Bc')
expect(response.body).to have_content('Idle Bc')
expect(response.body).to have_content('created')
expect(response.body).to have_content('idle')
expect(response.body).to have_content('created_at')
end
it 'returns empty list if there are no broadcasts' do
project = create(:project, name: 'empty', account_id: current_user.primary_account.id)
sign_in_to_api(current_user)
get :index, params: { project_id: project.id }
expect(response).to be_successful
expect(response.body).to have_content('[]')
end
it 'does not return broadcasts that are not ready to stream' do
project = create(:project, name: 'first', account_id: current_user.primary_account.id)
br1 = create(:broadcast, project: project, name: 'Created Bc', status: 'created')
br2 = create(:broadcast, project: project, name: 'Active Bc', status: 'active')
sign_in_to_api(current_user)
get :index, params: { project_id: project.id }
expect(response).to be_successful
expect(response.body).to have_content('Created Bc')
expect(response.body).to have_content('created')
expect(response.body).not_to have_content('Active Bc')
expect(response.body).not_to have_content('active')
end
it 'does not return broadcasts from another project' do
project = create(:project, name: 'empty', account_id: current_user.primary_account.id)
project2 = create(:project, name: 'with broadcasts', account_id: current_user.primary_account.id)
create(:broadcast, project: project2, name: 'Created Bc', status: 'created')
sign_in_to_api(current_user)
get :index, params: { project_id: project.id }
expect(response).to be_successful
expect(response.body).to have_content('[]')
end
it 'does not return broadcasts from another account' do
second_account = create(:account, name: 'second')
project = create(:project, name: 'empty', account_id: current_user.primary_account.id)
project2 = create(:project, name: 'with broadcasts', account_id: second_account.id)
create(:broadcast, project: project2, name: 'Created Bc', status: 'created')
sign_in_to_api(current_user)
get :index, params: { project_id: project.id }
expect(response).to be_successful
expect(response.body).to have_content('[]')
end
end
describe '#show' do
it 'returns a single broadcast' do
project = create(:project, name: 'first', account_id: current_user.primary_account.id)
br1 = create(:broadcast, :with_stream, skip_create_callback: true, project: project, name: 'Created Bc', status: 'created')
sign_in_to_api(current_user)
get :show, params: { project_id: project.id, id: br1.id }
expect(response).to be_successful
expect(response.body).to have_content('Created Bc')
expect(response.body).to have_content('created')
expect(response.body).to have_content('created_at')
end
it 'includes files relationship' do
project = create(:project, name: 'first', account_id: current_user.primary_account.id)
broadcast = create(:broadcast, :with_stream, :with_files, skip_create_callback: true, project: project)
sign_in_to_api(current_user)
get :show, params: { project_id: project.id, id: broadcast.id }
expect(response).to be_successful
relationships = JSON.parse(response.body).dig('data', 'relationships')
included = JSON.parse(response.body).dig('included')
expect(relationships.keys).to include('files')
expect(included.size).to eq 1
expect(included.first.dig("id")).to eq broadcast.files.first.id.to_s
expect(included.first.dig("type")).to eq 'active_storage_attachment'
end
end
describe "#update" do
it "uploads files to broadcast" do
project = create(:project, name: 'first', account_id: current_user.primary_account.id)
broadcast = create(:broadcast, :with_stream, skip_create_callback: true, project: project, name: 'Created Bc', status: 'created')
sign_in_to_api(current_user)
patch :update, params: file_params(project, broadcast)
relationships = JSON.parse(response.body).dig('data', 'relationships')
included = JSON.parse(response.body).dig('included')
expect(relationships.keys).to include('files')
expect(included.size).to eq 1
expect(included.first.dig("id")).to eq broadcast.files.first.id.to_s
expect(included.first.dig("type")).to eq 'active_storage_attachment'
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
private
def file_params(project, broadcast)
{
:project_id => project.id,
:id => broadcast.id,
:broadcast => {
files: [{
io: file_base64,
filename: "person_photo.png"
}]
}
}
end
def file_base64
Base64Image.from_image(file_fixture('person_photo.png')).data_uri
end
end

View File

@@ -0,0 +1,44 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Api::ContractTemplatesController, type: :controller do
let(:current_user) { create(:user) }
let(:project) { create(:project, name: 'first', account: current_user.primary_account) }
describe '#index' do
it 'returns a succesful response' do
create(:contract_template, name: 'ct1', project_id: project.id)
sign_in_to_api(current_user)
get :index, params: { project_id: project.id }
expect(response).to be_successful
old_body = response.body
get :index, params: { project_id: project.id, updated_since: (DateTime.current + 10.days).to_date.to_s }
expect(response.body).not_to eq(old_body)
end
end
describe '#show' do
it 'returns a succesful response' do
tested_release = create(:contract_template, name: 'ct1', project_id: project.id)
sign_in_to_api(current_user)
get :show, params: { id: tested_release.id }
expect(response).to be_successful
end
end
private
def response_body_data_attributes
JSON.parse(response.body).dig('data', 'attributes')
end
def response_body_included_attributes
JSON.parse(response.body).dig('included')
end
end

View File

@@ -0,0 +1,48 @@
# frozen_string_literal: true
require 'rails_helper'
releases = [
{
type: :appearance_release,
obligatory_attribute: :person_name
},
{
type: :talent_release,
obligatory_attribute: :person_name
},
{
type: :location_release,
obligatory_attribute: :name
},
{
type: :material_release,
obligatory_attribute: :name
}
]
releases.each do |release|
RSpec.describe Api::NotesController, type: :controller do
let(:current_user) { create(:user, :admin) }
describe '#create' do
it 'creates a note and returns a created response' do
project = create(:project, name: 'first', account_id: current_user.primary_account.id)
tested_release = create(release[:type], release[:obligatory_attribute] => 'contract template 1', :project_id => project.id)
sign_in_to_api(current_user)
post :create, params: { "#{release[:type]}_id": tested_release.id, note: { content: 'blah blah' } }
expect(response.status).to eq 201
end
end
describe '#index' do
it 'returns all notes for the release' do
project = create(:project, name: 'first', account_id: current_user.primary_account.id)
tested_release = create(release[:type], release[:obligatory_attribute] => 'contract template 1', :project_id => project.id)
sign_in_to_api(current_user)
get :index, params: { "#{release[:type]}_id": tested_release.id }
expect(response).to be_successful
end
end
end
end

View File

@@ -0,0 +1,29 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Api::ProfilesController, type: :controller do
let(:current_user) { create(:user) }
describe '#show' do
it 'responds with profile info for the current user' do
sign_in_to_api(current_user)
get :show
expect(response).to be_successful
expect(response_body_data).to include('id' => current_user.to_param, 'type' => 'user')
expect(response_body_data_attributes).to include('email' => current_user.email)
end
end
private
def response_body_data
JSON.parse(response.body).dig('data')
end
def response_body_data_attributes
response_body_data.dig('attributes')
end
end

View File

@@ -0,0 +1,22 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Api::ProjectsController, type: :controller do
let(:current_user) { create(:user, :admin) }
describe '#index' do
it 'returns a succesful response with and without updated_since param' do
create(:project, name: 'first', account_id: current_user.primary_account.id, updated_at: 10.days.ago)
create(:project, name: 'second', account_id: current_user.primary_account.id, updated_at: 10.days.ago)
sign_in_to_api(current_user)
get :index
expect(response).to be_successful
expect(response.body).to have_content('first')
expect(response.body).to have_content('second')
end
end
end

View File

@@ -0,0 +1,204 @@
# frozen_string_literal: true
require 'rails_helper'
releases = [
{
type: :location_release,
obligatory_attribute: :name
},
{
type: :material_release,
obligatory_attribute: :name
}
]
releases.each do |release|
controller = "Api::#{release[:type].to_s.pluralize.camelize}Controller".constantize
RSpec.describe controller, type: :controller do
let(:current_user) { create(:user) }
let(:project) { create(:project, name: 'first', account: current_user.primary_account) }
describe '#index' do
it 'returns a succesful response' do
r = create(release[:type], release[:obligatory_attribute] => 'contract template 1', :project_id => project.id)
sign_in_to_api(current_user)
get :index, params: { project_id: project.id }
expect(response).to be_successful
old_body = response.body
get :index, params: { project_id: project.id, updated_since: (DateTime.current + 10.days).to_date.to_s }
expect(response.body).not_to eq(old_body)
end
end
describe '#show' do
it 'returns a succesful response' do
tested_release = create(release[:type], release[:obligatory_attribute] => 'contract template 1', :project_id => project.id)
sign_in_to_api(current_user)
get :show, params: { id: tested_release.id }
expect(response).to be_successful
end
it 'includes photos' do
tested_release = create("#{release[:type]}_with_photo", release[:obligatory_attribute] => 'Release Name', project: project)
sign_in_to_api(current_user)
get :show, params: { id: tested_release.id }
tested_release.photos.each do |photo|
data = {
'id' => photo.id.to_s,
'type' => 'active_storage_attachment',
'attributes' => {
'content_type' => photo.content_type,
'filename' => photo.filename.to_s,
'url' => photo_path_for(photo),
'thumbnail_url' => photo_variant_path_for(photo, '150x150')
}
}
expect(response_body_included_attributes).to include(data)
end
end
end
describe '#create' do
before do
template = create(:contract_template, name: 'contract template 1', project_id: project.id)
small_photo = photo_base64
signature = signature_base64
@parameters = {
contract_template_id: template.id,
release[:type] => {
release[:obligatory_attribute] => 'aaa',
:signature => signature,
:person_phone => '123',
:person_first_name => 'aaa',
:person_last_name => 'aaa',
:signed_at => '2020-01-01 16:50:26 UTC',
:photos => [{
io: small_photo,
filename: 'photo1.jpg'
}]
}
}
sign_in_to_api(current_user)
end
it 'returns 201 - created response' do
post :create, params: @parameters
releasable = release[:type].to_s.classify.constantize.last
expect(response.status).to eq 201
expect(releasable.signature).to be_attached
end
it 'saves signed on date correctly' do
post :create, params: @parameters
expect(response.status).to eq 201
expect(release[:type].to_s.classify.constantize.last.signed_on).to eq '01/01/20'
end
it 'runs attach contract to background job' do
expect do
post :create, params: @parameters
end.to have_enqueued_job(AttachContractToReleasableJob).with(release[:type].to_s.classify.constantize.last)
end
it 'runs set tags for releasable background job' do
expect do
post :create, params: @parameters
end.to have_enqueued_job(SetTagsForReleasableJob).with(release[:type].to_s.classify.constantize.last)
end
it 'fails if there is no signature' do
template = create(:contract_template, name: 'ct1', project_id: project.id)
small_photo = photo_base64
parameters = {
contract_template_id: template.id,
release[:type] => {
release[:obligatory_attribute] => 'aaa bbb'
}
}
if release[:type] == :appearance_release
parameters[release[:type]][:person_photo] = {
io: small_photo,
filename: 'filenameee.jpg'
}
else
parameters[release[:type]][:photos] = [{
io: small_photo,
filename: 'photo1.jpg'
}]
end
sign_in_to_api(current_user)
expect do
post :create, params: parameters
end.to raise_error(ActiveRecord::RecordInvalid)
end
end
describe '#update' do
it 'returns 200 - successful response' do
tested_release = create(release[:type], release[:obligatory_attribute] => 'contract template 1',
:project_id => project.id,
:person_phone => '123',
:person_name => 'aaa bbb')
small_photo = photo_base64
parameters = {
:id => tested_release.id,
release[:type] => {
photos: [{
io: small_photo,
filename: 'photo1.jpg'
}]
}
}
sign_in_to_api(current_user)
put :update, params: parameters
expect(response.status).to eq 200
end
end
end
private
def photo_base64
@photo_base64 ||= Base64Image.from_image(file_fixture('person_photo.png')).data_uri
end
def signature_base64
@signature_base64 ||= Base64Image.from_image(file_fixture('signature.png')).data_uri
end
def photo_path_for(attachment)
Rails.application.routes.url_helpers.rails_blob_url(attachment, host: AppHost.new.domain_with_port)
end
def photo_variant_path_for(attachment, _size)
Rails.application.routes.url_helpers.rails_representation_url(attachment.variant(resize: '150x150'), host: AppHost.new.domain_with_port)
end
def response_body_data_attributes
JSON.parse(response.body).dig('data', 'attributes')
end
def response_body_included_attributes
JSON.parse(response.body).dig('included')
end
end

View File

@@ -0,0 +1,141 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Api::SyncController, type: :controller do
let(:current_user) { create(:user, :admin) }
before do
sign_in_to_api(current_user)
end
describe '#index' do
it 'dumps all the data when parameter since not suplied' do
create_default_data
get :index
expect(response).to be_successful
end
it 'does not leak data from other accounts' do
another_user = create(:user)
my_project = create(:project, account: current_user.primary_account)
their_project = create(:project, account: another_user.primary_account)
my_contract_template = create(:contract_template, project: my_project)
their_contract_template = create(:contract_template, project: their_project)
my_appearance_release = create(:appearance_release, project: my_project)
their_appearance_release = create(:appearance_release, project: their_project)
my_talent_release = create(:talent_release, project: my_project)
their_talent_release = create(:talent_release, project: their_project)
my_location_release = create(:location_release, project: my_project)
their_location_release = create(:location_release, project: their_project)
my_material_release = create(:material_release, project: my_project)
their_material_release = create(:material_release, project: their_project)
my_note = create(:note, notable: my_appearance_release, user: current_user)
their_note = create(:note, notable: their_appearance_release, user: another_user)
get :index
account_ids = ids_for_type('accounts')
project_ids = ids_for_type('projects')
contract_template_ids = ids_for_type('contract_templates')
appearance_release_ids = ids_for_type('appearance_releases')
talent_release_ids = ids_for_type('talent_releases')
location_release_ids = ids_for_type('location_releases')
material_release_ids = ids_for_type('material_releases')
note_ids = ids_for_type('notes')
expect(account_ids).to include(current_user.primary_account.id.to_s)
expect(account_ids).not_to include(another_user.primary_account.id.to_s)
expect(project_ids).to include(my_project.id.to_s)
expect(project_ids).not_to include(their_project.id.to_s)
expect(contract_template_ids).to include(my_contract_template.id.to_s)
expect(contract_template_ids).not_to include(their_contract_template.id.to_s)
expect(appearance_release_ids).to include(my_appearance_release.id.to_s)
expect(appearance_release_ids).not_to include(their_appearance_release.id.to_s)
expect(location_release_ids).to include(my_location_release.id.to_s)
expect(location_release_ids).not_to include(their_location_release.id.to_s)
expect(talent_release_ids).to include(my_talent_release.id.to_s)
expect(talent_release_ids).not_to include(their_talent_release.id.to_s)
expect(material_release_ids).to include(my_material_release.id.to_s)
expect(material_release_ids).not_to include(their_material_release.id.to_s)
expect(note_ids).to include(my_note.id.to_s)
expect(note_ids).not_to include(their_note.id.to_s)
end
it 'returns only the notes that belong to the accessible projects (the note bug)' do
create_default_data
my_appearance_release = AppearanceRelease.last
my_note = create(:note, notable: my_appearance_release, user: current_user)
another_user = create(:user)
their_project = create(:project, account: another_user.primary_account)
their_appearance_release = create(:appearance_release, project: their_project)
their_note = create(:note, notable: their_appearance_release, user: another_user)
another_user.account_auths.create(account: current_user.primary_account, role: :account_manager)
get :index
note_ids = ids_for_type('notes')
expect(note_ids).to eq [my_note.id.to_s]
end
it 'shows guardian_photo property for appearance and talent releases and not for other release types' do
create_default_data
get :index
appearance_releases = attributes_for_type('appearance_releases')
talent_releases = attributes_for_type('talent_releases')
location_releases = attributes_for_type('location_releases')
material_releases = attributes_for_type('material_releases')
expect(appearance_releases.first).to include('guardian_photo')
expect(talent_releases.first).to include('guardian_photo')
expect(location_releases.first).not_to include('guardian_photo')
expect(material_releases.first).not_to include('guardian_photo')
end
it 'guardian photo has same format as other photos' do
create_default_data_with_guardian_info
get :index
appearance_releases = attributes_for_type('appearance_releases')
guardian_photo = appearance_releases.first['guardian_photo']
photo_attributes = guardian_photo['attributes']
expect(appearance_releases.first).to include('guardian_photo')
expect(guardian_photo).to include('id', 'type', 'attributes')
expect(photo_attributes).to include('filename', 'content_type', 'url', 'thumbnail_url')
end
end
private
def create_default_data
project = create(:project, name: 'first', account: current_user.primary_account)
create(:appearance_release, project: project)
create(:talent_release, project: project)
create(:location_release, project: project)
create(:material_release, project: project)
end
def create_default_data_with_guardian_info
project = create(:project, name: 'first', account: current_user.primary_account)
create(:appearance_release, :minor_with_guardian_photo, project: project)
end
def response_body_json
JSON.parse(response.body)
end
def ids_for_type(name)
response_body_json.dig('data', name).flat_map { |json| json.dig('attributes', 'id') }
end
def attributes_for_type(name)
response_body_json.dig('data', name).flat_map { |json| json['attributes'] }
end
end

View File

@@ -0,0 +1,214 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Api::TalentReleasesController, type: :controller do
let(:current_user) { create(:user) }
let(:project) { create(:project, name: 'first', account: current_user.primary_account) }
describe '#index' do
it 'returns a succesful response' do
create(:talent_release, person_first_name: 'ct1', person_last_name: 'ct12', project_id: project.id)
sign_in_to_api(current_user)
get :index, params: { project_id: project.id }
expect(response).to be_successful
old_body = response.body
get :index, params: { project_id: project.id, updated_since: (DateTime.current + 10.days).to_date.to_s }
expect(response.body).not_to eq(old_body)
end
end
describe '#show' do
it 'returns a succesful response' do
tested_release = create(:talent_release, person_first_name: 'ct1', person_last_name: 'ct12', project_id: project.id)
sign_in_to_api(current_user)
get :show, params: { id: tested_release.id }
expect(response).to be_successful
end
it 'includes photos' do
tested_release = create("talent_release_with_photo", person_name: 'Release 1', project: project)
sign_in_to_api(current_user)
get :show, params: { id: tested_release.id }
tested_release.photos.each do |photo|
data = {
'id' => photo.id.to_s,
'type' => 'active_storage_attachment',
'attributes' => {
'content_type' => photo.content_type,
'filename' => photo.filename.to_s,
'url' => photo_path_for(photo),
'thumbnail_url' => photo_variant_path_for(photo, '150x150')
}
}
expect(response_body_included_attributes).to include(data)
end
end
end
describe '#create' do
before do
template = create(:contract_template, name: 'ct1', project_id: project.id)
small_photo = photo_base64
guardian_photo = guardian_photo_base64
signature = signature_base64
@parameters = {
contract_template_id: template.id,
talent_release: {
signature: signature,
person_phone: '123',
person_first_name: 'aaa',
person_last_name: 'bbb',
minor: true,
guardian_first_name: 'John',
guardian_last_name: 'Doe',
guardian_phone: '9191919191',
signed_at: '2020-01-01 16:50:26 UTC',
photos: [{
io: small_photo,
filename: 'filenameee.jpg'
}]
}
}
@guardian_info = {
minor: true,
guardian_name: 'Guardian',
guardian_phone: '101010'
}
@guardian_photo = {
guardian_photo: {
io: guardian_photo,
filename: 'guardianPhoto.jpeg'
}
}
sign_in_to_api(current_user)
end
it 'returns 201 - created response' do
post :create, params: @parameters
expect(response.status).to eq 201
expect(TalentRelease.last.signature).to be_attached
expect(TalentRelease.last.guardian_first_name).to eq('John')
expect(TalentRelease.last.guardian_last_name).to eq('Doe')
end
it 'saves signed on date correctly' do
post :create, params: @parameters
expect(response.status).to eq 201
expect(TalentRelease.last.signed_on).to eq '01/01/20'
end
it 'runs attach contract to background job' do
expect do
post :create, params: @parameters
end.to have_enqueued_job(AttachContractToReleasableJob).with(TalentRelease.last)
end
it 'runs add headshot collection uid background job' do
expect do
post :create, params: @parameters
end.to have_enqueued_job(AddHeadshotCollectionUidToProjectJob).with(project)
end
it 'runs set tags for background releasable job' do
expect do
post :create, params: @parameters
end.to have_enqueued_job(SetTagsForReleasableJob).with(TalentRelease.last)
end
it 'fails if there is no signature' do
template = create(:contract_template, name: 'ct1', project_id: project.id)
small_photo = photo_base64
parameters = {
contract_template_id: template.id,
talent_release: {
person_name: 'aaa bbb'
}
}
parameters[:talent_release][:photos] = [{
io: small_photo,
filename: 'filenameee.jpg'
}]
sign_in_to_api(current_user)
expect do
post :create, params: parameters
end.to raise_error(ActiveRecord::RecordInvalid)
end
it 'returns 201 for minor without guardian photo' do
params_without_guardian_photo = @parameters
params_without_guardian_photo[:talent_release].merge!(@guardian_info)
post :create, params: params_without_guardian_photo
expect(response.status).to eq 201
expect(TalentRelease.last.signature).to be_attached
expect(TalentRelease.last.guardian_photo).not_to be_attached
end
it 'returns 201 for minor with guardian photo' do
params_with_guardian_photo = @parameters
params_with_guardian_photo[:talent_release].merge!(@guardian_info, @guardian_photo)
post :create, params: params_with_guardian_photo
expect(response.status).to eq 201
talent_release = TalentRelease.last
photo = talent_release.guardian_photo
data = {
'id' => photo.id.to_s,
'type' => 'active_storage_attachment',
'attributes' => {
'content_type' => photo.content_type,
'filename' => photo.filename.to_s,
'url' => photo_path_for(photo),
'thumbnail_url' => photo_variant_path_for(photo, '150x150')
}
}
expect(talent_release.signature).to be_attached
expect(talent_release.guardian_photo).to be_attached
end
end
private
def photo_base64
@photo_base64 ||= Base64Image.from_image(file_fixture('person_photo.png')).data_uri
end
def guardian_photo_base64
@guardian_photo_base64 ||= Base64Image.from_image(file_fixture('pratt.jpg')).data_uri
end
def signature_base64
@signature_base64 ||= Base64Image.from_image(file_fixture('signature.png')).data_uri
end
def photo_path_for(attachment)
Rails.application.routes.url_helpers.rails_blob_url(attachment, host: AppHost.new.domain_with_port)
end
def photo_variant_path_for(attachment, _size)
Rails.application.routes.url_helpers.rails_representation_url(attachment.variant(resize: '150x150'), host: AppHost.new.domain_with_port)
end
def response_body_data_attributes
JSON.parse(response.body).dig('data', 'attributes')
end
def response_body_included_attributes
JSON.parse(response.body).dig('included')
end
end

View File

@@ -0,0 +1,288 @@
require "rails_helper"
RSpec.describe AppearanceReleasesController, tye: :controller do
render_views
let(:user) { create(:user) }
let(:account) { user.primary_account }
let(:project) { create(:project, account: user.primary_account) }
before do
sign_in(user)
end
describe "#index" do
it "responds successfully" do
get :index, params: { project_id: project }
expect(response).to be_successful
end
it "renders content" do
release = create(:appearance_release, project: project,
person_first_name: "John", person_last_name: "Doe", person_phone: "5551234567", person_email: "jane.doe@test.com")
create(:note, notable: release, content: "Some notes here")
get :index, params: { project_id: project }
expect(response.body).to have_content "John Doe"
expect(response.body).to have_content "P: 5551234567E: jane.doe@test.com"
expect(response.body).to have_content "Some notes here"
expect(response.body).to have_button "Import Release"
expect(response.body).to have_content "Manage"
end
context "when there are no appearance releases" do
it "renders an empty message" do
get :index, params: { project_id: project }
expect(response.body).to have_content("Appearance Releases will appear here")
end
end
context "when there are many records" do
it "paginates the table" do
create_list(:appearance_release, 20, project: project)
get :index, params: { project_id: project }
expect(response.body).to have_link("2", href: project_appearance_releases_path(project, page: 2))
end
end
context "for xhr request" do
it "filters the releases by a query param" do
appearance_releases = [
create(:appearance_release, person_first_name: "Adam", person_last_name: "Sandler", project: project),
create(:appearance_release, person_first_name: "Zoe", person_last_name: "Saldana", project: project),
]
get :index, params: { project_id: project, query: "Zoe" }, xhr: true
expect(response.body).not_to have_content("Adam")
expect(response.body).to have_content("Zoe")
end
it "filters the releases by a type_filter param" do
appearance_releases = [
create(:appearance_release, :without_person_photo, :non_native, person_first_name: "Adam", person_last_name: "Sandler", project: project),
create(:appearance_release, :non_native, person_first_name: "Zoe", person_last_name: "Saldana", project: project),
]
get :index, params: { project_id: project, type_filter: 'all' }, xhr: true
expect(response.body).to have_content("Adam")
expect(response.body).to have_content("Zoe")
get :index, params: { project_id: project, type_filter: 'complete' }, xhr: true
expect(response.body).not_to have_content("Adam")
expect(response.body).to have_content("Zoe")
get :index, params: { project_id: project, type_filter: 'incomplete' }, xhr: true
expect(response.body).to have_content("Adam")
expect(response.body).not_to have_content("Zoe")
end
it "filters the releases by a type_filter and query params simultaneously" do
appearance_releases = [
create(:appearance_release, :without_person_photo, :non_native, person_first_name: "Adam", person_last_name: "Sandler Incomplete", project: project),
create(:appearance_release, :non_native, person_first_name: "Adam", person_last_name: "Sandler Complete", project: project),
create(:appearance_release, :without_person_photo, :non_native, person_first_name: "Zoe", person_last_name: "Saldana Incomplete", project: project),
create(:appearance_release, :non_native, person_first_name: "Zoe", person_last_name: "Saldana Complete", project: project),
]
get :index, params: { project_id: project, type_filter: 'complete', query: 'Adam' }, xhr: true
expect(response.body).to have_content("Adam Sandler Complete")
expect(response.body).not_to have_content("Adam Sandler Incomplete")
expect(response.body).not_to have_content("Zoe Saldana Incomplete")
expect(response.body).not_to have_content("Zoe Saldana Complete")
get :index, params: { project_id: project, type_filter: 'incomplete', query: 'Zoe' }, xhr: true
expect(response.body).not_to have_content("Adam Sandler Complete")
expect(response.body).not_to have_content("Adam Sandler Incomplete")
expect(response.body).to have_content("Zoe Saldana Incomplete")
expect(response.body).not_to have_content("Zoe Saldana Complete")
end
end
end
describe "#new" do
it "responds successfully" do
get :new, params: { project_id: project }
expect(response).to be_successful
end
end
describe "#create" do
it "responds successfully when guardian_photo is not sent" do
expect {
post :create, params: { project_id: project, appearance_release: appearance_release_params }
}.to change(AppearanceRelease, :count).by(1)
expect(response).to be_redirect
expect(response).to redirect_to [project, :appearance_releases]
expect(flash.notice).to be_present
end
it "responds successfully when guardian_photo is sent" do
expect {
post :create, params: { project_id: project, appearance_release: minor_appearance_release_params }
}.to change(AppearanceRelease, :count).by(1)
expect(response).to be_redirect
expect(response).to redirect_to [project, :appearance_releases]
expect(flash.notice).to be_present
end
it "enqueues headshot collection job" do
expect {
post :create, params: { project_id: project, appearance_release: appearance_release_params }
}.to have_enqueued_job(AddHeadshotCollectionUidToProjectJob).with(project)
end
it "enqueues tagging job" do
expect {
post :create, params: { project_id: project, appearance_release: appearance_release_params }
}.to have_enqueued_job(SetTagsForReleasableJob).with(AppearanceRelease.last)
end
it "logs analytics" do
expect {
post :create, params: { project_id: project, appearance_release: appearance_release_params }
}.to(
have_enqueued_job(TrackAnalyticsJob).with(user, account, :track_create_non_native_release, release_type: "AppearanceRelease", user_agent: "Rails Testing", user_ip: "0.0.0.0")
)
end
context "when the record would be invalid" do
before do
allow_any_instance_of(AppearanceRelease).to receive(:save).and_return(false)
end
it "re-renders the form" do
expect {
post :create, params: { project_id: project, appearance_release: appearance_release_params }
}.not_to change(AppearanceRelease, :count)
expect(response).to be_successful
expect(flash.notice).to be_nil
end
it "does not enqueue any jobs" do
expect {
post :create, params: { project_id: project, appearance_release: appearance_release_params }
}.not_to have_enqueued_job
end
end
end
describe "#edit" do
let(:non_native_appearance_release) { create(:appearance_release, project: project) }
let(:native_appearance_release) { create(:appearance_release, :native, project: project) }
it "responds successfully for non-native release" do
get :edit, params: { project_id: project, id: non_native_appearance_release }
expect(response).to be_successful
end
it "responds with error for native release" do
expect { get :edit, params: { id: native_appearance_release } }.to raise_exception Pundit::NotAuthorizedError
end
end
describe "#update" do
let(:appearance_release) { create(:appearance_release, project: project) }
it "responds successfully" do
patch :update, params: { project_id: project, id: appearance_release, appearance_release: appearance_release_params }
expect(response).to redirect_to [project, :appearance_releases]
expect(flash.notice).to be_present
end
it "enqueues headshot collection job" do
expect {
patch :update, params: { project_id: project, id: appearance_release, appearance_release: appearance_release_params }
}.to have_enqueued_job(AddHeadshotCollectionUidToProjectJob).with(project)
end
context "when the record would be invalid" do
before do
allow_any_instance_of(AppearanceRelease).to receive(:save).and_return(false)
end
it "re-renders the form" do
patch :update, params: { project_id: project, id: appearance_release, appearance_release: appearance_release_params }
expect(response).to be_successful
expect(flash.notice).to be_nil
end
it "does not enqueue any jobs" do
expect {
patch :update, params: { project_id: project, id: appearance_release, appearance_release: appearance_release_params }
}.not_to have_enqueued_job(AddHeadshotCollectionUidToProjectJob)
end
end
end
describe "#destroy" do
let!(:appearance_release) { create(:appearance_release, project: project) }
it "responds with redirect" do
delete :destroy, params: { project_id: project, id: appearance_release }
expect(response).to be_redirect
expect(response).to redirect_to [project, :appearance_releases]
end
it "sets the flash" do
delete :destroy, params: { project_id: project, id: appearance_release }
expect(flash.alert).not_to be_nil
end
it "destroys the record" do
expect {
delete :destroy, params: { project_id: project, id: appearance_release }
}.to change(AppearanceRelease, :count).by(-1)
end
end
private
def appearance_release_params
attributes_for(:appearance_release, :non_native).except(:contract).merge(contract_param, exploitable_rights_params)
end
def minor_appearance_release_params
attributes_for(:appearance_release, :non_native, :minor_with_guardian_photo).except(:contract).merge(contract_param, exploitable_rights_params)
end
def exploitable_rights_params
{
applicable_medium_id: ApplicableMedium.last.id,
applicable_medium_text: "applicable_media",
territory_id: Territory.last.id,
territory_text: "territory",
term_id: Term.last.id,
term_text: "term",
restriction_id: Restriction.last.id,
restriction_text: "restrictions",
}
end
def contract_param
path = Rails.root.join("spec", "fixtures", "files", "contract.pdf")
contract_file = Rack::Test::UploadedFile.new(path, "application/pdf")
{ contract: contract_file }
end
end

View File

@@ -0,0 +1,216 @@
require "rails_helper"
RSpec.describe VideoAnalyses::AudioConfirmationsController, type: :controller do
let(:user) { create(:user) }
let(:project) { create(:project, account: user.primary_account) }
let(:video) { create(:video, project: project) }
before :each do
sign_in user
end
render_views
describe "#new" do
let(:edl_gateway) { double(:edl_gateway) }
before :each do
allow(EdlEventGateway).to receive(:new).and_return(edl_gateway)
allow(edl_gateway).to receive(:edl_events).and_return(build_list(:edl_event, 1))
end
it "responds successfully and sets audio_confirmation, edl_events_data, matched_filename" do
get :new, params: {
video_id: video.id,
audio_confirmation: {
time_elapsed: "00:01:00",
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
music_type: "music_type",
music_category: "music_category",
composer_info: "composer_info",
publisher_info: "publisher_info",
catalog: "catalog",
title: "title",
confirmation_type: "library_music",
edl_type: "audio",
},
matched_file_name: "matched_file_name",
}, xhr: true
expect(EdlEventGateway).to have_received(:new).with(
instance_of(AudioFilesForRequest),
"00:00:00:00",
"00:00:00:00",
channel_filter: "A",
)
expect(response).to be_successful
expect(assigns(:audio_confirmation)).to have_attributes(
id: nil,
time_elapsed: "00:01:00",
clip_name: "clip_name",
description: "description",
duration: "duration",
source_file_name: "source_file_name",
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
music_type: "music_type",
music_category: "music_category",
composer_info: "composer_info",
publisher_info: "publisher_info",
catalog: "catalog",
title: "title",
confirmation_type: "library_music",
)
expect(assigns(:edl_events_data)).to eq({
edl_events: build_list(:edl_event, 1),
edl_attributes: {
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
},
info_message: "An EDL event was found. Data is shown below",
})
expect(assigns(:matched_file_name)).to eq "matched_file_name"
end
context "when edl_type param is all_tracks" do
it "uses the all tracks edl" do
get :new, params: {
video_id: video.id,
audio_confirmation: {
time_elapsed: "00:01:00",
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
music_type: "music_type",
music_category: "music_category",
composer_info: "composer_info",
publisher_info: "publisher_info",
catalog: "catalog",
title: "title",
confirmation_type: "library_music",
edl_type: "all_tracks",
},
matched_file_name: "matched_file_name",
}, xhr: true
expect(EdlEventGateway).to have_received(:new).with(
instance_of(FilesForRequest),
"00:00:00:00",
"00:00:00:00",
channel_filter: "A",
)
end
end
end
describe "#create" do
it "responds successfully and creates audio_confirmation" do
expect {
post :create, params: {
video_id: video.id,
audio_confirmation: {
time_elapsed: "00:01:00",
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
music_type: "music_type",
music_category: "music_category",
composer_info: "composer_info",
publisher_info: "publisher_info",
catalog: "catalog",
title: "title",
confirmation_type: "library_music",
},
}, xhr: true
}.to change(AudioConfirmation, :count).by(1)
expect(response).to be_successful
end
it "sets audio_confirmation_data, audio_confirmations_data" do
expect {
post :create, params: {
video_id: video.id,
audio_confirmation: {
time_elapsed: "00:01:00",
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
music_type: "music_type",
music_category: "music_category",
composer_info: "composer_info",
publisher_info: "publisher_info",
catalog: "catalog",
title: "title",
confirmation_type: "library_music",
},
}, xhr: true
}.to change(AudioConfirmation, :count).by(1)
expect(response).to be_successful
expect(assigns(:audio_confirmation_data)).to have_attributes(
source_file_name: "source_file_name",
presented_source_file_name: "(L) source_file_name",
timecode_in: "timecode_in",
should_toggle_checkmark: true,
is_valid: true,
)
expect(assigns(:audio_confirmations_data)).to have_attributes(
audio_confirmations: [AudioConfirmation.last]
)
end
end
describe "#destroy" do
let!(:audio_confirmation) do
create(:audio_confirmation,
source_file_name: "source_file_name",
timecode_in: "timecode_in",
confirmation_type: "original_music"
)
end
it "sets audio_confirmation_data, audio_confirmations_data" do
delete :destroy, params: { id: audio_confirmation.id }, xhr: true
expect(assigns(:audio_confirmation_data)).to have_attributes(
source_file_name: "source_file_name",
presented_source_file_name: "(O) source_file_name",
timecode_in: "timecode_in",
should_toggle_checkmark: true,
is_valid: true,
)
expect(assigns(:audio_confirmations_data).audio_confirmations).to eq([])
end
it "destroys given audio_confirmation" do
expect {
delete :destroy, params: { id: audio_confirmation.id }, xhr: true
}.to change(AudioConfirmation, :count).from(1).to(0)
end
end
end

View File

@@ -0,0 +1,56 @@
require "rails_helper"
RSpec.describe AudioReportsController, type: :controller do
let(:user) { create(:user) }
let(:video) { create(:video, project: create(:project, account: user.primary_account)) }
before :each do
sign_in user
end
describe "show" do
context "when type is big" do
it "builds the report and responds successfully" do
get :show, params: { video_id: video, format: "xlsx", type: "big" }
expect(response).to be_successful
expect(response.body.unpack("C*").pack("U*")).to_not be_blank
expect(response.header["Content-Type"]).to eq "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
expect(response.header["Content-Disposition"]).to match "video_file-mp4_big-cue-sheet.xlsx"
end
end
context "when type is discovery music" do
it "builds the report and responds successfully" do
get :show, params: { video_id: video, format: "xlsx", type: "discovery" }
expect(response).to be_successful
expect(response.body.unpack("C*").pack("U*")).to_not be_blank
expect(response.header["Content-Type"]).to eq "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
expect(response.header["Content-Disposition"]).to match "discovery-cue-sheet.xlsx"
end
end
context "when type is nat geo music" do
it "builds the report and responds successfully" do
get :show, params: { video_id: video, format: "xlsx", type: "nat_geo" }
expect(response).to be_successful
expect(response.body.unpack("C*").pack("U*")).to_not be_blank
expect(response.header["Content-Type"]).to eq "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
expect(response.header["Content-Disposition"]).to match "music-cue-sheet.xlsx"
end
end
context "when type is nat geo original music" do
it "builds the report and responds successfully" do
get :show, params: { video_id: video, format: "xlsx", type: "nat_geo-original" }
expect(response).to be_successful
expect(response.body.unpack("C*").pack("U*")).to_not be_blank
expect(response.header["Content-Type"]).to eq "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
expect(response.header["Content-Disposition"]).to match "original-music-log.xlsx"
end
end
end
end

View File

@@ -0,0 +1,240 @@
require 'rails_helper'
RSpec.describe BroadcastsController, type: :controller do
render_views
let(:user) { create(:user) }
let(:account) { user.primary_account }
let(:project) { create(:project, account: user.primary_account) }
before do
sign_in user
end
describe "#index" do
before do
allow(MuxLiveStream).to receive(:new).and_return(double(id: "id", key: "key", playback_id: "playback_id"))
end
it "responds successfully" do
get :index, params: { project_id: project }
expect(response).to be_successful
end
it "renders content" do
create(:broadcast, project: project, name: "Another Broadcast")
get :index, params: { project_id: project }
expect(response.body).to have_content "Another Broadcast"
expect(response.body).to have_content "Created"
expect(response.body).to have_content "less than a minute ago"
expect(response.body).to have_link "Create New Live Stream"
end
context "when there are no active broadcasts" do
it "renders an empty message" do
Broadcast.destroy_all
get :index, params: { project_id: project }
expect(response.body).to have_content("Live streams will appear here")
end
end
context "when there are many records" do
it "paginates the table" do
create_list(:broadcast, 20, project: project)
get :index, params: { project_id: project }
expect(response.body).to have_link("2", href: project_broadcasts_path(project, page: 2))
end
end
context "for xhr request" do
it "filters the broadcasts by a query param" do
appearance_releases = [
create(:broadcast, skip_create_callback: true, name: "Stream by Adam"),
create(:broadcast, skip_create_callback: true, name: "Stream by Zoe"),
]
get :index, params: { project_id: project, query: "Zoe" }, xhr: true
expect(response.body).not_to have_content("Adam")
expect(response.body).to have_content("Zoe")
end
end
end
describe "#new" do
it "responds successfully" do
get :new, params: { project_id: project }
expect(response).to be_successful
expect(assigns(:broadcast)).to be_a_new(Broadcast)
expect(response).to render_template(:new)
end
end
describe "#create" do
before do
allow(MuxLiveStream).to receive(:new).and_return(double(id: "id", key: "key", playback_id: "playback_id"))
end
it "responds with a redirect" do
post :create, params: { project_id: project.id, broadcast: broadcast_params }
expect(response).to be_redirect
expect(flash.notice).not_to be_nil
end
it "does create a new record" do
expect {
post :create, params: { project_id: project.id, broadcast: broadcast_params }
}.to change(Broadcast, :count)
end
it "logs an event" do
expect {
post :create, params: { project_id: project.id, broadcast: broadcast_params }
}.to have_enqueued_job(TrackAnalyticsJob).with(user, account, :track_create_live_stream, user_agent: "Rails Testing", user_ip: "0.0.0.0")
end
context "with invalid data" do
it "does not create a new record" do
expect {
post :create, params: { project_id: project.id, broadcast: { name: "" } }
}.not_to change(Broadcast, :count)
end
end
end
describe "#update" do
let!(:broadcast) { create(:broadcast, :with_stream, skip_create_callback: true, project: project ) }
it "uploads files to broadcast" do
patch :update, params: { project_id: project.id, id: broadcast.id, broadcast: file_params }, xhr: true
expect(broadcast.files.count).to eq(1)
expect(broadcast.files.first.filename).to eq("contract.pdf")
end
end
describe "#show" do
let(:broadcast) { create(:broadcast, project: project, name: "Another Broadcast") }
before do
allow(MuxLiveStream).to receive(:new).and_return(double(id: "id", key: "key", playback_id: "playback_id"))
end
it "responds successfully" do
get :show, params: { project_id: project.id, id: broadcast.id }
expect(response).to be_successful
expect(assigns(:broadcast)).to eq(broadcast)
end
it "renders readonly share url" do
get :show, params: { project_id: project.id, id: broadcast.id }
expect(response.body).to have_button "Copy URL"
expect(response.body).to have_xpath "//input[@readonly][@value='#{broadcast_url(broadcast.token)}']"
end
it "displays zoom meeting button" do
get :show, params: { project_id: project.id, id: broadcast.id }
expect(response.body).to have_link("Video Conference", href: project_broadcast_zoom_meeting_url(project, broadcast))
end
it "assigns required variables" do
get :show, params: { project_id: project.id, id: broadcast.id }
expect(assigns(:conference_url)).to eq project_broadcast_zoom_meeting_url(project, broadcast)
expect(assigns(:broadcast)).to eq broadcast
end
context "when there are no multi-view broadcasts" do
it "renders the view dropdown with just the current broadcast" do
get :show, params: { project_id: project, id: broadcast }
expect(response.body).to have_content "Switch View"
expect(response.body).to have_selector(".dropdown-menu .dropdown-item.active", text: "Another Broadcast")
end
end
context "when there are multi-view broadcasts" do
it "renders the view dropdown with all the broadcasts" do
other_broadcast = create(:broadcast, project: project, name: "Some Other Broadcast")
get :show, params: { project_id: project, id: broadcast, multi_view_ids: [broadcast.id, other_broadcast.id] }
expect(response.body).to have_content "Switch View"
expect(response.body).to have_selector(".dropdown-menu .dropdown-item.active", text: "Another Broadcast")
expect(response.body).to have_selector(".dropdown-menu a.dropdown-item", text: "Some Other Broadcast")
end
end
context "when there are no recordings for the current broadcast" do
it "renders the view dropdown with a message" do
get :show, params: { project_id: project, id: broadcast }
expect(response.body).to have_content "Switch View"
expect(response.body).to have_selector(".dropdown-menu .dropdown-item", text: "Recordings will appear here")
end
end
context "when there are recordings available" do
it "renders the view dropdown with the recordings" do
recording = create(:broadcast_recording, broadcast: broadcast)
get :show, params: { project_id: project, id: broadcast }
expect(response.body).to have_content "Switch View"
expect(response.body).to have_selector(".dropdown-menu a.dropdown-item", text: recording.download_file_name)
end
end
end
describe "#destroy" do
let!(:broadcast_2) { create(:broadcast, :with_stream, skip_create_callback: true, project: project, name: "Another Broadcast") }
before do
allow_any_instance_of(MuxLiveStream).to receive(:destroy_stream).with(broadcast_2.stream_uid)
end
it "responds with redirect" do
delete :destroy, params: { project_id: project.id, id: broadcast_2.id }
expect(response).to be_redirect
expect(response).to redirect_to(project_broadcasts_path(project))
expect(flash.alert).not_to be_nil
end
it "destroys the record" do
expect {
delete :destroy, params: { project_id: project.id, id: broadcast_2.id }
}.to change(Broadcast, :count).by(-1)
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
private
def broadcast_params
attributes_for(:broadcast)
end
def file_params
path = Rails.root.join("spec", "fixtures", "files", "contract.pdf")
contract_file = Rack::Test::UploadedFile.new(path, "application/pdf")
{ files: [contract_file] }
end
end

View File

@@ -0,0 +1,37 @@
require "rails_helper"
RSpec.describe BulkTaggingsController, type: :controller do
render_views
let(:user) { create(:user) }
let(:project) { create(:project, account: user.primary_account) }
let(:acquired_media_releases) { create_list(:acquired_media_release, 5, project: project) }
before do
sign_in user
end
describe "#new" do
it "responds successfully" do
tagged_ids = acquired_media_releases.map(&:id).sample(3).to_s
get :new, params: { releasable_ids: tagged_ids, releasable_name: "acquired_media_releases", project_id: project.id }, xhr: true
expect(response).to be_successful
end
end
describe "#create" do
it "tags multiple releases" do
tagged_ids = acquired_media_releases.map(&:id).sample(3).to_s
post :create, params: acquired_media_release_params(tagged_ids), xhr: true
expect(response.body).to have_content('Approved', count: 3)
end
end
private
def acquired_media_release_params(tagged_ids)
{ name: "Approved", releasable_ids: tagged_ids, releasable_name: "acquired_media_releases", project_id: project.id }
end
end

View File

@@ -0,0 +1,60 @@
require "rails_helper"
RSpec.describe ContractDownloadsController, type: :controller do
render_views
let(:current_user) { create(:user) }
let(:project) { create(:project, :discovery_client, account: current_user.primary_account) }
before do
sign_in current_user
end
describe "#create" do
it "enqueues zip file generation job" do
create_list(:download, 4, project_id: project.id, name: "#{project.name.parameterize}_appearance-releases")
expect {
post :create, params: { project_id: project.id, release_type: "AppearanceRelease" }, format: :js
}.to have_enqueued_job(GenerateContractsZipJob)
end
it "creates a download record with 'not_started' status" do
create_list(:download, 4, project_id: project.id, name: "#{project.name.parameterize}_appearance-releases")
expect {
post :create, params: { project_id: project.id, release_type: "AppearanceRelease" }, format: :js
}.to change(Download, :count).by(1)
expect(Download.last.status).to eq('not_started')
end
context "When there is no existing job" do
it "shows a notification to user" do
allow(ProjectsChannel).to receive(:broadcast_download_generation_update).with(be_kind_of(Download), I18n.t("contract_downloads.download.pending", release_type: "Appearance Release"))
post :create, params: { project_id: project.id, release_type: "AppearanceRelease" }, format: :js
expect(ProjectsChannel).to have_received(:broadcast_download_generation_update).with(be_kind_of(Download), I18n.t("contract_downloads.download.pending", release_type: "Appearance Release"))
end
end
context "When there are existing jobs" do
let(:appearance_release_download) { create(:download, project_id: project.id, name: "#{project.name.parameterize}_appearance-releases") }
let(:acquired_media_release_download) { create(:download, project_id: project.id, name: "#{project.name.parameterize}_acquired-media-releases", release_type: "AcquiredMediaRelease") }
before do
allow(Download).to receive_message_chain(:unfinished_desc_order, :offset).and_return([acquired_media_release_download, appearance_release_download])
allow(ProjectsChannel).to receive(:broadcast_download_generation_update)
end
it "shows names of other contracts in the notification, which are in progress" do
broadcast_message = "<p>Your Music Release contracts are being prepared for download. You will be notified when it's ready.\n</p>\n<p class=\"mt-3\">The following downloads are also in progress:</p> \n<ul>\n <li>Acquired Media Release contracts (as of less than a minute ago)\n </li>\n <li>Appearance Release contracts (as of less than a minute ago)\n </li>\n</ul>\n"
post :create, params: { project_id: project.id, release_type: "MusicRelease" }, format: :js
expect(ProjectsChannel).to have_received(:broadcast_download_generation_update).with(be_kind_of(Download), broadcast_message)
end
end
end
end

View File

@@ -0,0 +1,60 @@
# frozen_string_literal: true
require 'rails_helper'
describe ContractTemplates::BlankContractsController do
let(:account) { build(:account) }
let(:current_user) { create(:user, :manager, primary_account: account) }
let(:project) { create(:project, members: [current_user], account: account) }
let(:contract_template) { create(:contract_template, project: project) }
before do
sign_in(current_user)
end
describe '#show' do
it 'responds with success' do
get :show, params: { contract_template_id: contract_template }
expect(response).to be_successful
end
it "responds with a PDF" do
pdf_body = Tempfile.new
allow_any_instance_of(Contract).to receive(:to_pdf).and_return(pdf_body)
get :show, params: { contract_template_id: contract_template }
expect(response).to be_successful
expect(content_type).to eq("application/pdf")
expect(content_disposition).to include("inline")
end
end
describe '#new' do
it 'responds with success' do
get :new, params: { contract_template_id: contract_template }
expect(response).to be_successful
end
end
describe '#create' do
it "responds with redirect for invalid number of copies" do
post :create, params: { contract_template_id: contract_template, number_of_copies: -2 }
expect(response).to redirect_to [:new, contract_template, :blank_contracts]
end
it "responds with PDF" do
pdf_body = Tempfile.new
allow_any_instance_of(Contract).to receive(:to_pdf).and_return(pdf_body)
get :show, params: { contract_template_id: contract_template, number_of_copies: 2 }
expect(response).to be_successful
expect(content_type).to eq("application/pdf")
expect(content_disposition).to include("inline")
end
end
end

View File

@@ -0,0 +1,20 @@
require 'rails_helper'
describe ContractTemplates::QrCodesController do
let(:account) { build(:account) }
let(:current_user) { create(:user, :manager, primary_account: account) }
let(:project) { create(:project, members: [current_user], account: account) }
let(:contract_template) { create(:contract_template, project: project) }
before do
sign_in(current_user)
end
describe "#show" do
it "responds with success" do
get :show, params: { contract_template_id: contract_template }
expect(response).to be_successful
end
end
end

View File

@@ -0,0 +1,169 @@
# frozen_string_literal: true
require 'rails_helper'
describe ContractTemplatesController do
render_views
let(:current_user) { create(:user, :manager) }
let(:project) { create(:project, members: current_user, account: current_user.primary_account) }
before do
sign_in(current_user)
end
describe '#index' do
it 'responds successfully' do
get :index, params: { project_id: project }
expect(response).to be_successful
end
it 'renders content' do
contract_template = create(:contract_template,
name: 'My Contract Template', fee: 50, release_type: 'appearance',
project: project)
sign_path = new_account_project_contract_template_appearance_release_path(project.account, project, contract_template)
sign_url = new_account_project_contract_template_appearance_release_url(project.account, project, contract_template)
get :index, params: { project_id: project }
expect(response.body).to have_content('My Contract Template')
expect(response.body).to have_link('Create New Release Template', href: new_project_contract_template_path(project))
expect(response.body).to have_link('Import Release Template', href: new_project_release_template_imports_path(project))
expect(response.body).to have_link('Copy Release URL', href: sign_url)
expect(response.body).to have_content('Manage')
expect(response.body).to have_link('Sign', href: sign_path)
expect(response.body).to have_link('Print')
end
context 'when there are no contract templates' do
it 'renders an empty message' do
get :index, params: { project_id: project }
expect(response.body).to have_content('Release Templates will appear here')
end
end
context 'when current user is an associate' do
let(:current_user) { create(:user, :associate) }
it 'does not show the new contract template button' do
get :index, params: { project_id: project }
expect(response.body).not_to have_link('Create New Release Template')
expect(response.body).not_to have_link('Import Release Template')
expect(response.body).not_to have_link('Delete')
end
end
context 'when there are many records' do
it 'paginates the table' do
create_list(:contract_template, 20, project: project)
get :index, params: { project_id: project }
expect(response.body).to have_link('2', href: project_contract_templates_path(project, page: 2))
end
end
end
describe '#new' do
it 'responds ok' do
get :new, params: { project_id: project }
expect(response).to be_successful
end
end
describe '#create' do
it 'redirects' do
post :create, params: { project_id: project, contract_template: contract_template_params(valid: true) }
expect(response).to redirect_to(project_contract_templates_path(project))
end
it 'sends pdf file for a preview' do
post :create, params: { project_id: project, contract_template: contract_template_params(valid: true), commit: 'preview' }
expect(response.header['Content-Type']).to include('application/pdf')
expect(response.header['Content-Disposition']).to include('inline')
end
it 'creates a new record' do
expect do
post :create, params: { project_id: project, contract_template: contract_template_params }
end.to change(ContractTemplate, :count).by(1)
end
context 'when save fails' do
it 'responds ok' do
post :create, params: { project_id: project, contract_template: contract_template_params(valid: false) }
expect(response).to be_successful
end
end
context 'when current user is an associate' do
let(:current_user) { create(:user, :associate) }
it 'raises exception' do
expect do
post :create, params: { project_id: project, contract_template: contract_template_params }
end.to raise_error(Pundit::NotAuthorizedError)
end
end
end
describe '#destroy' do
let!(:contract_template) { create(:contract_template, project: project) }
it 'redirects' do
delete :destroy, params: { id: contract_template }
expect(response).to be_redirect
expect(response).to redirect_to [project, :contract_templates]
end
it 'archives the record but does not delete' do
expect do
delete :destroy, params: { id: contract_template }
end.to change(ContractTemplate, :count).by(0)
expect(ContractTemplate.find(contract_template.id).archived_at).not_to be_nil
end
context 'when contract template has associated releases' do
let(:contract_template) { create(:contract_template, appearance_releases: build_list(:appearance_release, 1), project: project) }
it 'does not raise error' do
expect do
delete :destroy, params: { id: contract_template }
end.not_to raise_error
end
end
end
private
def contract_template_params(valid: true)
if valid
attributes_for(:contract_template).merge(exploitable_rights_params)
else
attributes_for(:contract_template).except(:name)
end
end
def exploitable_rights_params
{
applicable_medium_id: ApplicableMedium.last.id,
applicable_medium_text: 'applicable_media',
territory_id: Territory.last.id,
territory_text: 'territory',
term_id: Term.last.id,
term_text: 'term',
restriction_id: Restriction.last.id,
restriction_text: 'restrictions'
}
end
end

View File

@@ -0,0 +1,66 @@
require "rails_helper"
RSpec.describe ContractsController, type: :controller do
let(:current_user) { create(:user) }
before do
sign_in current_user
end
shared_examples "a contracts controller" do
describe "#show" do
context "for a native release" do
it "responds with a PDF contract generated dynamically" do
pdf_body = Tempfile.new
allow_any_instance_of(Contract).to receive(:to_pdf).and_return(pdf_body)
get :show, params: { format: :pdf, "#{native_releasable.model_name.singular}_id" => native_releasable }
expect(response).to be_successful
expect(content_type).to eq("application/pdf")
expect(content_disposition).to include("inline")
end
end
context "for a non-native release" do
it "responds with the attached contract" do
contract = double(:contract, service_url: "http://example.org/contract.pdf")
allow_any_instance_of(non_native_releasable.class).to receive(:contract).and_return(contract)
get :show, params: { format: :pdf, "#{non_native_releasable.model_name.singular}_id" => non_native_releasable }
expect(response).to be_redirect
expect(response).to redirect_to("http://example.org/contract.pdf")
end
end
end
end
context "for appearance releases" do
let(:native_releasable) { create(:appearance_release_with_contract_template, :native) }
let(:non_native_releasable) { create(:appearance_release_with_contract_template, :non_native) }
it_behaves_like "a contracts controller"
end
context "for location releases" do
let(:native_releasable) { create(:location_release_with_contract_template, :native) }
let(:non_native_releasable) { create(:location_release_with_contract_template, :non_native) }
it_behaves_like "a contracts controller"
end
context "for material releases" do
let(:native_releasable) { create(:material_release_with_contract_template, :native) }
let(:non_native_releasable) { create(:material_release_with_contract_template, :non_native) }
it_behaves_like "a contracts controller"
end
context "for talent releases" do
let(:native_releasable) { create(:talent_release_with_contract_template, :native) }
let(:non_native_releasable) { create(:talent_release_with_contract_template, :non_native) }
it_behaves_like "a contracts controller"
end
end

View File

@@ -0,0 +1,194 @@
require 'rails_helper'
RSpec.describe DirectoriesController, type: :controller do
render_views
let(:user) { create(:user) }
let(:account) { user.primary_account }
let(:project) { create(:project, account: user.primary_account) }
let(:directory) { create(:directory, project: project) }
let(:directory_with_files) { create(:directory, :with_files, project: project) }
let(:directory_with_many_files) { create(:directory, :many_files, project: project) }
before do
sign_in user
end
describe "#new" do
it "responds successfully" do
get :new, params: { project_id: project }
expect(response).to be_successful
expect(assigns(:directory)).to be_a_new(Directory)
expect(response).to render_template(:new)
end
end
describe "#create" do
it "responds with a redirect" do
post :create, params: { project_id: project.id, directory: directory_params }
expect(response).to be_redirect
expect(flash.notice).not_to be_nil
end
it "does create a new record" do
expect {
post :create, params: { project_id: project.id, directory: directory_params }
}.to change(Directory, :count)
end
it "logs an event" do
expect {
post :create, params: { project_id: project.id, directory: directory_params }
}.to have_enqueued_job(TrackAnalyticsJob).with(user, account, :track_create_custom_folder, user_agent: "Rails Testing", user_ip: "0.0.0.0")
end
context "with invalid data" do
it "does not create a new record" do
expect {
post :create, params: { project_id: project.id, directory: { name: "", category: "Other" } }
}.not_to change(Directory, :count)
end
end
context "with permissions" do
it "assigns selected permission to directory" do
post :create, params: { project_id: project.id, directory: directory_params_with_permissions }
expect(Directory.last.permissions).to eq("Account Managers & Project Managers")
end
it "sets permissions to everyone when no permission is selected by user" do
post :create, params: { project_id: project.id, directory: directory_params }
expect(Directory.last.permissions).to eq("Everyone")
end
end
end
describe "#show" do
it "responds successfully" do
get :show, params: { project_id: project.id, id: directory_with_files.id }
expect(response).to be_successful
end
it "renders files" do
get :show, params: { project_id: project.id, id: directory_with_files.id }
expect(response.body).to have_content "location_photo.png"
expect(response.body).to have_link "Add File"
expect(response.body).to have_content "Manage"
end
context "when there are no files" do
it "renders an empty message" do
get :show, params: { project_id: project.id, id: directory.id }
expect(response.body).to have_content("Uploaded files will appear here")
end
end
context "when there are many files" do
it "paginates the table" do
get :show, params: { project_id: project.id, id: directory_with_many_files.id }
expect(response.body).to have_link("2", href: project_directory_path(project, directory_with_many_files.id, page: 2))
end
end
context "for xhr request" do
it "filters the files by a query param" do
get :show, params: { project_id: project.id, id: directory_with_many_files.id, query: "loc" }, xhr: true
expect(response.body).to have_content("location_photo.png")
expect(response.body).not_to have_content("material_photo.png")
expect(response.body).not_to have_content("person_photo.png")
end
end
end
describe "#edit" do
it "sets directory" do
get :edit, params: { project_id: project.id, id: directory.id }
expect(response).to be_successful
expect(assigns(:directory)).to eq directory
end
end
describe "#update" do
it "responds with redirect" do
patch :update, params: { project_id: project.id, id: directory.id, directory: directory_params }
expect(response).to be_redirect
expect(flash.notice).not_to be_nil
end
it "updates directory with files and redirects" do
patch :update, params: { project_id: project.id, id: directory.id, directory: directory_params_with_files }
expect(directory.files.count).to eq(2)
expect(directory.files.first.filename).to eq("location_photo.png")
expect(response).to be_redirect
expect(flash.notice).not_to be_nil
end
context "with permissions" do
let(:directory) { create(:directory, project: project) }
it "updates directory with permissions" do
expect {
patch :update, params: { project_id: project.id, id: directory.id, directory: directory_params_with_permissions }
directory.reload
}.to change(directory, :permissions).from("Everyone").to("Account Managers & Project Managers")
end
end
end
describe "#destroy_file" do
it "responds with redirect after deleting file" do
delete :destroy_file, params: { project_id: project.id, id: directory_with_files.id, file_id: directory_with_files.files.first.id }
expect(directory_with_files.files.count).to eq(0)
expect(response).to be_redirect
expect(response).to redirect_to(project_directory_path(project, directory_with_files))
expect(flash.alert).not_to be_nil
end
end
describe "#destroy" do
let!(:directory_2) { create(:directory, project: project, name: "Stories") }
it "responds with redirect" do
delete :destroy, params: { project_id: project.id, id: directory.id }
expect(response).to be_redirect
expect(response).to redirect_to(project_path(project))
expect(flash.alert).not_to be_nil
end
it "destroys the record" do
expect {
delete :destroy, params: { project_id: project.id, id: directory_2.id }
}.to change(Directory, :count).by(-1)
end
end
private
def directory_params
attributes_for(:directory)
end
def directory_params_with_files
files = 2.times.map { Rack::Test::UploadedFile.new(file_fixture("location_photo.png"), "image/png") }
directory_params.merge({ files: files })
end
def directory_params_with_permissions
directory_params.merge({ permissions: "Account Managers & Project Managers" })
end
end

View File

@@ -0,0 +1,92 @@
require "rails_helper"
RSpec.describe DownloadsController, type: :controller do
render_views
let(:current_user) { create(:user) }
let(:project) { create(:project, :discovery_client, account: current_user.primary_account) }
before do
sign_in current_user
end
describe "#index" do
it "responds successfully" do
get :index, params: { project_id: project }
expect(response).to be_successful
end
context "when there are no reports" do
it "renders an empty message" do
get :index, params: { project_id: project }
expect(response.body).to have_content("Downloads will appear here")
end
end
context "when there are many records" do
it "paginates the table" do
create_list(:download, 20, project: project, name: "#{project.name.parameterize}_appearance-releases")
get :index, params: { project_id: project }
expect(response.body).to have_link("Download", href: project_downloads_path(project))
expect(response.body).to have_link("2", href: project_downloads_path(project, page: 2))
end
end
describe "for xhr request" do
before do
downloads = [
create(:download_release_type_appearance, project: project),
create(:download_release_type_music, project: project)
]
end
it "shows all downloads if search field is empty" do
get :index, params: { project_id: project }, xhr: true
expect(response.body).to have_content("Natgeo Contract")
expect(response.body).to have_content("Discovery Contract")
end
it "shows only downloads with file name or type matching search query" do
get :index, params: { project_id: project, query: "Natgeo" }, xhr: true
expect(response.body).not_to have_content("Discovery Contract")
expect(response.body).to have_content("Natgeo Contract")
get :index, params: { project_id: project, query: "Music" }, xhr: true
expect(response.body).to have_content("Music Release")
expect(response.body).not_to have_content("Appearance Release")
end
it "removes pagination in case of limited search results" do
create_list(:download_release_type_music, 20, project: project)
get :index, params: { project_id: project, query: "Appearance" }, xhr: true
expect(response.body).to have_no_link("1", href: project_downloads_path(project, page: 1))
end
end
end
describe "#destroy" do
let!(:download) { create(:download, project: project) }
it "responds with redirect" do
delete :destroy, params: { project_id: project.id, id: download.id }
expect(response).to be_redirect
expect(response).to redirect_to(project_downloads_path(project))
expect(flash.alert).not_to be_nil
end
it "destroys the record" do
expect {
delete :destroy, params: { project_id: project.id, id: download.id }
}.to change(Download, :count).by(-1)
end
end
end

View File

@@ -0,0 +1,73 @@
require "rails_helper"
RSpec.describe FileInfosController, type: :controller do
render_views
let(:current_user) { create(:user) }
let(:project) { create(:project, account: current_user.accounts.first) }
let(:acquired_media_release) { create(:acquired_media_release, project: project) }
before do
sign_in(current_user)
end
shared_examples "a file infoable releases controller" do
describe "#edit" do
it "responds successfully" do
get :edit, params: { "#{subject.model_name.param_key}_id" => subject }
expect(response).to be_successful
end
end
describe "#update" do
context "when releasable updated successfully" do
it "responds with a redirect" do
patch :update, params: { "#{subject.model_name.param_key}_id": subject, subject.model_name.param_key => release_params }
expect(response).to be_redirect
expect(response).to redirect_to [project, subject.model_name.plural]
expect(flash.notice).to eq(t("file_infos.update.notice"))
end
it "enqueues tagging job" do
expect {
patch :update, params: { "#{subject.model_name.param_key}_id": subject, subject.model_name.param_key => {} }
}.to have_enqueued_job(SetTagsForReleasableJob).with(subject.class.last)
end
end
end
context "when releasable NOT updated successfully" do
before do
allow_any_instance_of(subject.class).to receive(:update).and_return(false)
end
it "renders edit with flash message" do
patch :update, params: { "#{subject.model_name.param_key}_id": subject, subject.model_name.param_key => release_params }
expect(controller).to have_rendered(:edit)
end
it "does not enqueue tagging job" do
expect {
patch :update, params: { "#{subject.model_name.param_key}_id": subject, subject.model_name.param_key => release_params }
}.not_to have_enqueued_job(SetTagsForReleasableJob)
end
end
end
context "for acquired media releases" do
subject { create(:acquired_media_release, project: project) }
it_behaves_like "a file infoable releases controller"
end
private
def release_params
files = 2.times.map { Rack::Test::UploadedFile.new(file_fixture("audio.mp3"), "audio/mp3") }
{ file_infos_attributes: files }
end
end

View File

@@ -0,0 +1,34 @@
require "rails_helper"
RSpec.describe GraphicReportsController, type: :controller do
let(:user) { create(:user) }
let(:video) { create(:video, project: create(:project, account: user.primary_account)) }
before :each do
sign_in user
end
describe "show" do
context "when type is discovery" do
it "builds the report and responds successfully" do
get :show, params: { video_id: video, format: "xlsx", type: "discovery" }
expect(response).to be_successful
expect(response.body.unpack("C*").pack("U*")).to_not be_blank
expect(response.header["Content-Type"]).to eq "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
expect(response.header["Content-Disposition"]).to match "video_file-mp4_gfx-cue-list.xlsx"
end
end
context "when type is nat_geo" do
it "builds the report and responds successfully" do
get :show, params: { video_id: video, format: "xlsx", type: "nat_geo" }
expect(response).to be_successful
expect(response.body.unpack("C*").pack("U*")).to_not be_blank
expect(response.header["Content-Type"]).to eq "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
expect(response.header["Content-Disposition"]).to match "video_file-mp4_text-graphics-log.xlsx"
end
end
end
end

View File

@@ -0,0 +1,21 @@
require "rails_helper"
RSpec.describe IssuesAndConcernsReportsController, type: :controller do
let(:user) { create(:user) }
let(:project) { create(:project, account: user.primary_account) }
let(:video) { create(:video, project: project) }
before :each do
sign_in user
end
describe "#show" do
context "when format is xls" do
it "returns xls file" do
get :show, params: { video_id: video, format: "xlsx" }
expect(response).to be_successful
end
end
end
end

View File

@@ -0,0 +1,203 @@
require "rails_helper"
RSpec.describe LocationReleasesController, type: :controller do
render_views
let(:user) { create(:user) }
let(:account) { user.primary_account }
let(:project) { create(:project, account: user.primary_account) }
before :each do
sign_in user
end
describe "#index" do
it "responds successfully" do
get :index, params: { project_id: project }
expect(response).to be_successful
end
it "renders content" do
release = create(:location_release, project: project,
name: "My Release",
address_street1: "123 Test Lane", address_city: "New York", address_state: "NY", address_zip: "10000")
create(:note, notable: release, content: "Some notes here")
get :index, params: { project_id: project }
expect(response.body).to have_content "My Release"
expect(response.body).to have_content "123 Test Lane\nNew York, NY 10000"
expect(response.body).to have_content "Some notes here"
expect(response.body).to have_link "Import Release"
expect(response.body).to have_content "Manage"
end
context "when there are no location releases" do
it "renders an empty message" do
get :index, params: { project_id: project }
expect(response.body).to have_content("Location Releases will appear here")
end
end
context "when there are many records" do
it "paginates the table" do
create_list(:location_release, 20, project: project)
get :index, params: { project_id: project }
expect(response.body).to have_link("2", href: project_location_releases_path(project, page: 2))
end
end
context "for xhr request" do
it "filters the releases by a query param" do
location_releases = [
create(:location_release, name: "Benny's Burritos", project: project),
create(:location_release, name: "Chipotle", project: project),
]
get :index, params: { project_id: project, query: "Benny" }, xhr: true
expect(response.body).to have_content("Benny")
expect(response.body).not_to have_content("Chipotle")
end
end
end
describe "#new" do
it "responds successfully" do
get :new, params: { project_id: project }
expect(response).to be_successful
end
end
describe "#create" do
it "responds successfully" do
expect {
post :create, params: { project_id: project, location_release: location_release_params }
}.to change(LocationRelease, :count).by(1)
expect(response).to be_redirect
expect(response).to redirect_to [project, :location_releases]
expect(flash.notice).to be_present
end
it "enqueues tagging job" do
expect {
post :create, params: { project_id: project, location_release: location_release_params }
}.to have_enqueued_job(SetTagsForReleasableJob).with(LocationRelease.last)
end
it "logs analytics" do
expect {
post :create, params: { project_id: project, location_release: location_release_params }
}.to(
have_enqueued_job(TrackAnalyticsJob).with(user, account, :track_create_non_native_release, release_type: "LocationRelease", user_agent: "Rails Testing", user_ip: "0.0.0.0")
)
end
context "when the record would be invalid" do
before do
allow_any_instance_of(LocationRelease).to receive(:save).and_return(false)
end
it "re-renders the form" do
expect {
post :create, params: { project_id: project, location_release: location_release_params }
}.not_to change(LocationRelease, :count)
expect(response).to be_successful
expect(flash.notice).to be_nil
end
it "does not enqueue any jobs" do
expect {
post :create, params: { project_id: project, location_release: location_release_params }
}.not_to have_enqueued_job
end
end
end
describe "#edit" do
let(:non_native_location_release) { create(:location_release, project: project) }
let(:native_location_release) { create(:location_release, :native, project: project) }
it "responds successfully" do
get :edit, params: { project_id: project, id: non_native_location_release }
expect(response).to be_successful
end
it "responds with error for native release" do
expect{get :edit, params: { id: native_location_release }}.to raise_exception Pundit::NotAuthorizedError
end
end
describe "#update" do
let(:location_release) { create(:location_release, project: project) }
it "responds successfully" do
patch :update, params: { project_id: project, id: location_release, location_release: location_release_params }
expect(response).to redirect_to [project, :location_releases]
expect(flash.notice).to be_present
end
context "when the record would be invalid" do
before do
allow_any_instance_of(LocationRelease).to receive(:save).and_return(false)
end
it "re-renders the form" do
patch :update, params: { project_id: project, id: location_release, location_release: location_release_params }
expect(response).to be_successful
expect(flash.notice).to be_nil
end
end
end
describe "#destroy" do
let!(:location_release) { create(:location_release, project: project) }
it "responds with redirect" do
delete :destroy, params: { project_id: project, id: location_release }
expect(response).to be_redirect
expect(response).to redirect_to [project, :location_releases]
end
it "sets the flash" do
delete :destroy, params: { project_id: project, id: location_release }
expect(flash.alert).not_to be_nil
end
it "destroys the record" do
expect {
delete :destroy, params: { project_id: project, id: location_release }
}.to change(LocationRelease, :count).by(-1)
end
end
private
def location_release_params
attributes_for(:location_release).merge(exploitable_rights_params)
end
def exploitable_rights_params
{
applicable_medium_id: ApplicableMedium.last.id,
applicable_medium_text: "applicable_media",
territory_id: Territory.last.id,
territory_text: "territory",
term_id: Term.last.id,
term_text: "term",
restriction_id: Restriction.last.id,
restriction_text: "restrictions",
}
end
end

View File

@@ -0,0 +1,200 @@
require "rails_helper"
RSpec.describe MaterialReleasesController, type: :controller do
render_views
let(:user) { create(:user) }
let(:account) { user.primary_account }
let(:project) { create(:project, account: user.primary_account) }
before :each do
sign_in user
end
describe "#index" do
it "responds successfully" do
get :index, params: { project_id: project }
expect(response).to be_successful
end
it "renders content" do
release = create(:material_release, project: project, name: "My Release")
create(:note, notable: release, content: "Some notes here")
get :index, params: { project_id: project }
expect(response.body).to have_content "My Release"
expect(response.body).to have_content "Some notes here"
expect(response.body).to have_link "Import Release"
expect(response.body).to have_content "Manage"
end
context "when there are no material releases" do
it "renders an empty message" do
get :index, params: { project_id: project }
expect(response.body).to have_content("Material Releases will appear here")
end
end
context "when there are many records" do
it "paginates the table" do
create_list(:material_release, 20, project: project)
get :index, params: { project_id: project }
expect(response.body).to have_link("2", href: project_material_releases_path(project, page: 2))
end
end
context "for xhr request" do
it "filters the releases by a query param" do
material_releases = [
create(:material_release, name: "Coke", project: project),
create(:material_release, name: "Pepsi", project: project),
]
get :index, params: { project_id: project, query: "Pepsi" }, xhr: true
expect(response.body).not_to have_content("Coke")
expect(response.body).to have_content("Pepsi")
end
end
end
describe "#new" do
it "responds successfully" do
get :new, params: { project_id: project }
expect(response).to be_successful
end
end
describe "#create" do
it "responds successfully" do
expect {
post :create, params: { project_id: project, material_release: material_release_params }
}.to change(MaterialRelease, :count).by(1)
expect(response).to be_redirect
expect(response).to redirect_to [project, :material_releases]
expect(flash.notice).to be_present
end
it "enqueues tagging job" do
expect {
post :create, params: { project_id: project, material_release: material_release_params }
}.to have_enqueued_job(SetTagsForReleasableJob).with(MaterialRelease.last)
end
it "logs analytics" do
expect {
post :create, params: { project_id: project, material_release: material_release_params }
}.to(
have_enqueued_job(TrackAnalyticsJob).with(user, account, :track_create_non_native_release, release_type: "MaterialRelease", user_agent: "Rails Testing", user_ip: "0.0.0.0")
)
end
context "when the record would be invalid" do
before do
allow_any_instance_of(MaterialRelease).to receive(:save).and_return(false)
end
it "re-renders the form" do
expect {
post :create, params: { project_id: project, material_release: material_release_params }
}.not_to change(MaterialRelease, :count)
expect(response).to be_successful
expect(flash.notice).to be_nil
end
it "does not enqueue any jobs" do
expect {
post :create, params: { project_id: project, material_release: material_release_params }
}.not_to have_enqueued_job
end
end
end
describe "#edit" do
let(:non_native_material_release) { create(:material_release, project: project) }
let(:native_material_release) { create(:material_release, :native, project: project) }
it "responds successfully for non-native release" do
get :edit, params: { project_id: project, id: non_native_material_release }
expect(response).to be_successful
end
it "responds with error for native release" do
expect{get :edit, params: { id: native_material_release }}.to raise_exception Pundit::NotAuthorizedError
end
end
describe "#update" do
let(:material_release) { create(:material_release, project: project) }
it "responds successfully" do
patch :update, params: { project_id: project, id: material_release, material_release: material_release_params }
expect(response).to redirect_to [project, :material_releases]
expect(flash.notice).to be_present
end
context "when the record would be invalid" do
before do
allow_any_instance_of(MaterialRelease).to receive(:save).and_return(false)
end
it "re-renders the form" do
patch :update, params: { project_id: project, id: material_release, material_release: material_release_params }
expect(response).to be_successful
expect(flash.notice).to be_nil
end
end
end
describe "#destroy" do
let!(:material_release) { create(:material_release, project: project) }
it "responds with redirect" do
delete :destroy, params: { project_id: project, id: material_release }
expect(response).to be_redirect
expect(response).to redirect_to [project, :material_releases]
end
it "sets the flash" do
delete :destroy, params: { project_id: project, id: material_release }
expect(flash.alert).not_to be_nil
end
it "destroys the record" do
expect {
delete :destroy, params: { project_id: project, id: material_release }
}.to change(MaterialRelease, :count).by(-1)
end
end
private
def material_release_params
attributes_for(:material_release).merge(exploitable_rights_params)
end
def exploitable_rights_params
{
applicable_medium_id: ApplicableMedium.last.id,
applicable_medium_text: "applicable_media",
territory_id: Territory.last.id,
territory_text: "territory",
term_id: Term.last.id,
term_text: "term",
restriction_id: Restriction.last.id,
restriction_text: "restrictions",
}
end
end

View File

@@ -0,0 +1,277 @@
require "rails_helper"
RSpec.describe MusicReleasesController, type: :controller do
render_views
let(:user) { create(:user) }
let(:account) { user.primary_account }
let(:project) { create(:project, account: user.primary_account) }
before :each do
sign_in user
end
describe "#index" do
it "responds successfully" do
get :index, params: { project_id: project }
expect(response).to be_successful
end
it "renders content" do
release = create(:music_release, project: project, name: "My Release")
create(:note, notable: release, content: "Some notes here")
get :index, params: { project_id: project }
expect(response.body).to have_content "My Release"
expect(response.body).to have_content "0"
expect(response.body).to have_content "1"
expect(response.body).to have_content "1"
expect(response.body).to have_content "Some notes here"
expect(response.body).to have_link "Import Release"
expect(response.body).to have_content "Manage"
end
context "when there are no music releases" do
it "renders an empty message" do
get :index, params: { project_id: project }
expect(response.body).to have_content("Music Releases will appear here")
end
end
context "when there are many records" do
it "paginates the table" do
create_list(:music_release, 20, project: project)
get :index, params: { project_id: project }
expect(response.body).to have_link("2", href: project_music_releases_path(project, page: 2))
end
end
context "for xhr request" do
it "filters the releases by a query param" do
music_releases = [
create(:music_release, name: "Extreme Music Collection", project: project),
create(:music_release, name: "Audio Networks Music Collection", project: project),
]
get :index, params: { project_id: project, query: "Audio" }, xhr: true
expect(response.body).not_to have_content("Extreme")
expect(response.body).to have_content("Audio")
end
end
end
describe "#new" do
it "responds successfully" do
get :new, params: { project_id: project }
expect(response).to be_successful
end
it "initializes with 5 composers and 2 publishers" do
get :new, params: { project_id: project }
expect(assigns(:music_release).composers.size).to eq 5
expect(assigns(:music_release).publishers.size).to eq 2
end
end
describe "#create" do
it "responds successfully" do
expect {
post :create, params: { project_id: project, music_release: music_release_params }
}.to change(MusicRelease, :count).by(1)
expect(response).to be_redirect
expect(response).to redirect_to [project, :music_releases]
expect(flash.notice).to be_present
end
it "creates nested file info records" do
expect {
post :create, params: {
project_id: project,
music_release: music_release_params.merge(
file_infos_attributes: {
0 => attributes_for(:file_info)
}
)
}
}.to change(FileInfo, :count).by(1)
expect(MusicRelease.last.file_infos.size).to eq(1)
end
it "creates nested composer records" do
expect {
post :create, params: {
project_id: project,
music_release: music_release_params.merge(
composers_attributes: {
0 => {
name: "name",
affiliation: "affiliation",
percentage: 100,
cae_number: "cae123456789",
},
}
)
}
}.to change(Composer, :count).by(1)
expect(MusicRelease.last.composers.size).to eq(1)
end
it "creates nested publisher records" do
expect {
post :create, params: {
project_id: project,
music_release: music_release_params.merge(
publishers_attributes: {
0 => attributes_for(:publisher),
}
)
}
}.to change(Publisher, :count).by(1)
expect(MusicRelease.last.publishers.size).to eq(1)
end
it "enqueues tagging job" do
expect {
post :create, params: { project_id: project, music_release: music_release_params }
}.to have_enqueued_job(SetTagsForReleasableJob).with(MusicRelease.last)
end
it "logs analytics" do
expect {
post :create, params: { project_id: project, music_release: music_release_params }
}.to(
have_enqueued_job(TrackAnalyticsJob).with(user, account, :track_create_non_native_release, release_type: "MusicRelease", user_agent: "Rails Testing", user_ip: "0.0.0.0")
)
end
context "when the record would be invalid" do
before :each do
allow_any_instance_of(MusicRelease).to receive(:save).and_return(false)
end
it "re-renders the form" do
post :create, params: {
project_id: project,
music_release: music_release_params.merge(
publishers_attributes: {
0 => attributes_for(:publisher),
}
)
}
expect(response).to render_template :new
expect(flash.notice).to be_nil
end
it "does not enqueue any jobs" do
expect {
post :create, params: { project_id: project, music_release: music_release_params }
}.not_to have_enqueued_job
end
it "initializes with 5 composers and 2 publishers" do
post :create, params: {
project_id: project,
music_release: music_release_params.merge(
publishers_attributes: {
0 => attributes_for(:publisher),
}
)
}
expect(assigns(:music_release).composers.size).to eq 5
expect(assigns(:music_release).publishers.size).to eq 2
end
end
end
describe "#edit" do
let(:music_release) { create(:music_release, project: project) }
it "responds successfully" do
get :edit, params: { id: music_release }
expect(response).to be_successful
end
it "initializes with 5 composers and 2 publishers" do
get :edit, params: { id: music_release }
expect(assigns(:music_release).composers.size).to eq 5
expect(assigns(:music_release).publishers.size).to eq 2
end
end
describe "#update" do
let(:music_release) { create(:music_release, project: project) }
it "responds successfully" do
put :update, params: { id: music_release, music_release: { name: "Updated name" } }
expect(response).to redirect_to [project, :music_releases]
expect(flash.notice).to eq "The music release has been updated"
expect(music_release.reload.name).to eq "Updated name"
end
context "when the record would be invalid" do
before :each do
allow_any_instance_of(MusicRelease).to receive(:update).and_return(false)
end
it "re-renders the form" do
put :update, params: { id: music_release, music_release: music_release_params }
expect(response).to render_template :edit
expect(flash.notice).to be_nil
end
end
end
describe "#destroy" do
let!(:music_release) { create(:music_release, project: project) }
it "destroys the record" do
expect {
delete :destroy, params: { id: music_release }
}.to change(MusicRelease, :count).by(-1)
end
it "redirects to project and sets alert" do
delete :destroy, params: { id: music_release }
expect(response).to redirect_to [project, :music_releases]
expect(flash.alert).to eq "The music release has been deleted"
end
end
private
def music_release_params
attributes_for(:music_release).merge(
composers_attributes: [attributes_for(:composer)],
publishers_attributes: [attributes_for(:publisher)],
).merge(exploitable_rights_params)
end
def exploitable_rights_params
{
applicable_medium_id: ApplicableMedium.last.id,
applicable_medium_text: "applicable_media",
territory_id: Territory.last.id,
territory_text: "territory",
term_id: Term.last.id,
term_text: "term",
restriction_id: Restriction.last.id,
restriction_text: "restrictions",
}
end
end

View File

@@ -0,0 +1,56 @@
require "rails_helper"
RSpec.describe NotesController, type: :controller do
let(:current_user) { create(:user) }
let(:releasable) { create(:appearance_release) }
before do
sign_in current_user
end
describe "#index" do
it "responds successfully" do
get :index, xhr: true, params: { "#{releasable.model_name.singular}_id" => releasable }
expect(response).to be_successful
end
end
describe "#new" do
it "responds successfully" do
get :new, xhr: true, params: { "#{releasable.model_name.singular}_id" => releasable }
end
end
describe "#create" do
it "responds successfully" do
post :create, xhr: true, params: { "#{releasable.model_name.singular}_id" => releasable, note: note_params }
expect(response).to be_successful
end
it "creates a new Note record" do
expect {
post :create, xhr: true, params: { "#{releasable.model_name.singular}_id" => releasable, note: note_params }
}.to change(Note, :count).by(1)
end
context "when the new note is not valid" do
before do
allow_any_instance_of(Note).to receive(:save).and_return(false)
end
it "does not create a new Note record" do
expect {
post :create, xhr: true, params: { "#{releasable.model_name.singular}_id" => releasable, note: note_params }
}.not_to change(Note, :count)
end
end
end
private
def note_params
attributes_for(:note)
end
end

View File

@@ -0,0 +1,147 @@
require "rails_helper"
RSpec.describe NotificationsController, type: :controller do
describe "#create" do
context "for a subscription confirmation" do
it "responds ok" do
post :create, body: subscription_confirmation_body_json
expect(response).to be_ok
end
it "log the subscribe url" do
allow(Rails.logger).to receive(:info)
post :create, body: subscription_confirmation_body_json
expect(Rails.logger).to have_received(:info).with("http://example.com")
end
end
context "for a notification" do
context "for video analysis" do
let!(:video) { create(:video, analysis_uid: "job_id") }
context "when successful" do
it "responds ok" do
post :create, body: successful_notification_body_json
expect(response).to be_ok
end
it "updates video analysis status" do
post :create, body: successful_notification_body_json
expect(video.reload).to be_analysis_success
end
it "broadcasts analysis update" do
allow(ProjectsChannel).to receive(:broadcast_video_analysis_update)
post :create, body: successful_notification_body_json
expect(ProjectsChannel).to have_received(:broadcast_video_analysis_update).with(video)
end
end
context "when failed" do
it "responds ok" do
post :create, body: failure_notification_body_json
expect(response).to be_ok
end
it "updates video analysis status" do
post :create, body: failure_notification_body_json
expect(video.reload).to be_analysis_failure
end
it "broadcasts analysis update" do
allow(ProjectsChannel).to receive(:broadcast_video_analysis_update)
post :create, body: successful_notification_body_json
expect(ProjectsChannel).to have_received(:broadcast_video_analysis_update).with(video)
end
end
end
context "for audio analysis" do
let!(:video) { create(:video, audio_analysis_uid: "job_id") }
context "when successful" do
it "responds ok" do
post :create, body: successful_notification_body_json("audio")
expect(response).to be_ok
end
it "updates video analysis status" do
post :create, body: successful_notification_body_json("audio")
expect(video.reload).to be_audio_analysis_success
end
it "broadcasts analysis update" do
allow(ProjectsChannel).to receive(:broadcast_video_analysis_update)
post :create, body: successful_notification_body_json("audio")
expect(ProjectsChannel).to have_received(:broadcast_video_analysis_update).with(video)
end
end
context "when failed" do
it "responds ok" do
post :create, body: failure_notification_body_json("audio")
expect(response).to be_ok
end
it "updates video analysis status" do
post :create, body: failure_notification_body_json("audio")
expect(video.reload).to be_audio_analysis_failure
end
it "broadcasts analysis update" do
allow(ProjectsChannel).to receive(:broadcast_video_analysis_update)
post :create, body: successful_notification_body_json("audio")
expect(ProjectsChannel).to have_received(:broadcast_video_analysis_update).with(video)
end
end
end
end
end
private
def subscription_confirmation_body_json
{ "Type" => "SubscriptionConfirmation", "SubscribeURL" => "http://example.com" }.to_json
end
def successful_notification_body_json(analysis_type = "video")
{
"Type" => "Notification",
"Message" => {
"JobId" => "job_id",
"Status" => "SUCCEEDED",
"AnalysisType" => analysis_type,
}.to_json
}.to_json
end
def failure_notification_body_json(analysis_type = "video")
{
"Type" => "Notification",
"Message" => {
"JobId" => "job_id",
"Status" => "FAILED",
"AnalysisType" => analysis_type,
}.to_json
}.to_json
end
end

View File

@@ -0,0 +1,113 @@
require "rails_helper"
RSpec.describe PasswordResetsController, type: :controller do
render_views
let(:user) { create(:user) }
describe "#new" do
it "responds successfully" do
get :new
expect(response).to be_successful
end
it "renders the content" do
get :new
expect(response.body).to have_content("Password Reset")
expect(response.body).to have_field("Email")
end
end
describe "#create" do
it "redirects to new_session_path" do
post :create, params: { password_reset: { email: user.email } }
expect(response).to be_redirect
expect(response).to redirect_to(new_session_path)
end
it "shows an alert message" do
post :create, params: { password_reset: { email: user.email } }
expect(flash.notice).not_to be_nil
end
it "sends the reset email" do
assert_enqueued_emails 1 do
post :create, params: { password_reset: { email: user.email } }
end
end
end
describe "#edit" do
it "responds successfully" do
get :edit, params: { id: user.password_reset_token }
expect(response).to be_successful
end
it "renders the right content" do
user = create(:user)
get :edit, params: { id: user.password_reset_token }
expect(response.body).to have_content("Password Reset")
expect(response.body).to have_selector("input[name='password_reset[password]']")
end
context "when reset token is invalid" do
it "redirects to the sign in page" do
get :edit, params: { id: "bad token" }
expect(response).to be_redirect
expect(response).to redirect_to(new_session_path)
expect(flash.notice).to be_present
end
end
end
describe "#update" do
it "redirects to new_session_path" do
patch :update, params: { id: user.password_reset_token, password_reset: { password: "newpassword" } }
expect(response).to be_redirect
expect(response).to redirect_to(new_session_path)
end
it "shows an alert message" do
patch :update, params: { id: user.password_reset_token, password_reset: { password: "newpassword" } }
expect(flash.notice).not_to be_nil
end
it "resets the user password" do
expect {
patch :update, params: { id: user.password_reset_token, password_reset: { password: "newpassword" } }
}.to change { user.reload.password_digest }
end
it "generates a new password reset token for the user" do
user = create(:user)
expect {
patch :update, params: { id: user.password_reset_token, password_reset: { password: "foo" } }
}.to change { user.reload.password_reset_token }
end
context "when no new password is set" do
it "responds successfully" do
patch :update, params: { id: user.password_reset_token, password_reset: { password: "" } }
expect(response).to be_successful
end
it "shows an alert message" do
patch :update, params: { id: user.password_reset_token, password_reset: { password: "" } }
expect(flash.alert).not_to be_nil
end
end
end
end

View File

@@ -0,0 +1,85 @@
require "rails_helper"
RSpec.describe PhotosController, type: :controller do
render_views
let(:current_user) { create(:user) }
let(:project) { create(:project, account: current_user.primary_account) }
let(:location_release) { create(:location_release, project: project) }
before do
sign_in(current_user)
end
shared_examples "a photoable releases controller" do
describe "#edit" do
it "responds successfully" do
get :edit, params: { "#{subject.model_name.param_key}_id" => subject }
expect(response).to be_successful
end
end
describe "#update" do
context "when releasable updated successfully" do
it "responds with a redirect" do
patch :update, params: { "#{subject.model_name.param_key}_id": subject, subject.model_name.param_key => release_params }
expect(response).to be_redirect
expect(response).to redirect_to [project, subject.model_name.plural]
expect(flash.notice).to eq(t("photos.update.notice"))
end
it "enqueues tagging job" do
expect {
patch :update, params: { "#{subject.model_name.param_key}_id": subject, subject.model_name.param_key => {} }
}.to have_enqueued_job(SetTagsForReleasableJob).with(subject.class.last)
end
end
end
context "when releasable NOT updated successfully" do
before do
allow_any_instance_of(subject.class).to receive(:update).and_return(false)
end
it "renders edit with flash message" do
patch :update, params: { "#{subject.model_name.param_key}_id": subject, subject.model_name.param_key => release_params }
expect(controller).to have_rendered(:edit)
end
it "does not enqueue tagging job" do
expect {
patch :update, params: { "#{subject.model_name.param_key}_id": subject, subject.model_name.param_key => release_params }
}.not_to have_enqueued_job(SetTagsForReleasableJob)
end
end
end
context "for talent releases" do
subject { create(:talent_release, project: project) }
it_behaves_like "a photoable releases controller"
end
context "for location releases" do
subject { create(:location_release, project: project) }
it_behaves_like "a photoable releases controller"
end
context "for material releases" do
subject { create(:material_release, project: project) }
it_behaves_like "a photoable releases controller"
end
private
def release_params
files = 2.times.map { Rack::Test::UploadedFile.new(file_fixture("location_photo.png"), "image/png") }
{ photos: files }
end
end

View File

@@ -0,0 +1,85 @@
require "rails_helper"
RSpec.describe ProfilesController, type: :controller do
render_views
let(:current_user) { create(:user) }
before do
sign_in current_user
end
describe "#show" do
it "responds successfully" do
get :show
expect(response).to be_successful
end
it "renders content" do
get :show
expect(response.body).to have_content(current_user.primary_account.name)
expect(response.body).to have_content "Account Manager"
end
it "renders form for updating first, last name and time zone" do
get :show
expect(response.body).to have_content("First name")
expect(response.body).to have_content("Last name")
expect(response.body).to have_content("Time zone")
end
end
describe "#update" do
it "responds with redirect" do
patch :update, params: { user: user_params }
expect(response).to be_redirect
expect(flash.notice).not_to be_nil
end
it "updates user's first and last name" do
patch :update, params: { user: user_params }
expect(current_user.first_name).to eq("John")
expect(current_user.last_name).to eq("Doe")
expect(current_user.full_name).to eq("John Doe")
expect(response).to be_redirect
expect(flash.notice).not_to be_nil
end
it "updates user's avatar" do
patch :update, params: { user: user_params_with_avatar }
expect(current_user.first_name).to eq("John")
expect(current_user.last_name).to eq("Doe")
expect(current_user.full_name).to eq("John Doe")
expect(current_user.avatar.filename).to eq("person_photo.png")
expect(current_user.avatar.signed_id).not_to be_nil
expect(response).to be_redirect
expect(flash.notice).not_to be_nil
end
it "updates user's time zone" do
patch :update, params: { user: user_params }
expect(current_user.time_zone).to eq("Berlin")
expect(response).to be_redirect
expect(flash.notice).not_to be_nil
end
end
private
def user_params
{ first_name: "John", last_name: "Doe", time_zone: "Berlin" }
end
def user_params_with_avatar
avatar = Rack::Test::UploadedFile.new(file_fixture("person_photo.png"), "image/png")
user_params.merge({ avatar: avatar })
end
end

View File

@@ -0,0 +1,223 @@
require "rails_helper"
RSpec.describe ProjectMembershipsController, type: :controller do
render_views
let(:current_user) { create(:user, :manager) }
let!(:project) { create(:project, members: current_user, account: current_user.primary_account) }
before do
sign_in current_user
end
describe "#index" do
it "responds successfully" do
get :index, params: { project_id: project }
expect(response).to be_successful
end
it "renders content" do
project = create(:project, name: "My Project", account: current_user.primary_account, members: [
current_user,
create(:user, :manager, email: "jane.doe@test.com", accounts: current_user.accounts),
create(:user, :associate, email: "john.doe@test.com", accounts: current_user.accounts),
])
get :index, params: { project_id: project }
expect(response.body).to have_content "Team"
expect(response.body).to have_content "3 Team Members"
expect(response.body).to have_content current_user.email
expect(response.body).to have_content "jane.doe@test.com"
expect(response.body).to have_content "Project Manager"
expect(response.body).to have_content "john.doe@test.com"
expect(response.body).to have_content "Associate"
end
it "includes account managers in the team roster" do
project = create(:project, name: "My Project", account: current_user.primary_account, members: current_user)
account_manager = create(:user, :account_manager, accounts: current_user.accounts)
get :index, params: { project_id: project }
expect(response.body).to have_content "Team"
expect(response.body).to have_content "2 Team Members"
expect(response.body).to have_content current_user.email
expect(response.body).to have_content account_manager.email
end
context "for an associate" do
let(:current_user) { create(:user, :associate) }
it "does not render invite form" do
get :index, params: { project_id: project }
expect(response.body).not_to have_content "Invite New Member"
expect(response.body).not_to have_field "project_membership[user_email]"
expect(response.body).not_to have_button "Send Invite"
end
it "does not render remove links for any users" do
project.users << create(:user, :associate, email: "another.user@test.com", primary_account: current_user.primary_account)
get :index, params: { project_id: project }
expect(response.body).to have_content("another.user@test.com")
expect(response.body).not_to have_link("Remove")
end
end
context "for a manager" do
let(:current_user) { create(:user, :manager) }
it "renders invite form" do
get :index, params: { project_id: project }
expect(response.body).to have_content "Invite New Member"
expect(response.body).to have_field "project_membership[user_email]"
expect(response.body).to have_button "Send Invite"
end
it "renders a remove link for other users" do
my_project_membership = project.project_memberships.first
their_project_membership = create(:project_membership,
project: project,
user: create(:user, :associate,
email: "another.user@test.com",
primary_account: project.account))
get :index, params: { project_id: project }
expect(response.body).to have_content("another.user@test.com")
expect(response.body).to have_link("Remove", href: project_membership_path(their_project_membership))
expect(response.body).not_to have_link("Remove", href: project_membership_path(my_project_membership))
end
end
end
describe "#create" do
let!(:user) { create(:user, email: "user@test.com") }
it "responds with redirect" do
post :create, params: { project_id: project, project_membership: { user_email: "user@test.com" } }
expect(response).to be_redirect
expect(response).to redirect_to [project, :project_memberships]
expect(flash.notice).to be_present
end
it "creates a new membership for the invited user" do
expect {
post :create, params: { project_id: project, project_membership: { user_email: "user@test.com" } }
}.to change(ProjectMembership, :count).by(1)
membership = ProjectMembership.last
expect(membership.project).to eq(project)
expect(membership.user).to eq(user)
end
it "sends an email notification" do
post :create, params: { project_id: project, project_membership: { user_email: "user@test.com" } }
assert_enqueued_email_with UserMailer, :project_invitation, args: [user, project, user_is_new: false]
end
context "when invitation cannot be saved" do
before do
allow_any_instance_of(ProjectMembership).to receive(:save_and_update_account_membership).and_return(false)
end
it "responds with redirect" do
post :create, params: { project_id: project, project_membership: { user_email: "user@test.com" } }
expect(response).to be_redirect
expect(response).to redirect_to [project, :project_memberships]
expect(flash.alert).to be_present
end
it "creates a new membership for the invited user" do
expect {
post :create, params: { project_id: project, project_membership: { user_email: "user@test.com" } }
}.not_to change(ProjectMembership, :count)
end
end
context "when invited user does not exist yet" do
it "creates a new user record" do
expect {
post :create, params: { project_id: project, project_membership: { user_email: "new.user@test.com" } }
}.to change(User, :count)
project_membership = ProjectMembership.last
user = User.last
expect(project_membership.project).to eq(project)
expect(project_membership.user).to eq(user)
expect(user.email).to eq("new.user@test.com")
expect(user.accounts).to include(current_user.primary_account)
expect(user.associate?(current_user.primary_account)).to be_truthy
end
it "sends an email to the new user" do
post :create, params: { project_id: project, project_membership: { user_email: "new.user@test.com" } }
assert_enqueued_email_with UserMailer, :project_invitation, args: [User.last, project, user_is_new: true]
end
end
context "when invited user does not have access to the account yet" do
let!(:existing_user) { create(:user, email: "existing.user@test.com") }
it "creates a new account membership record" do
expect {
post :create, params: { project_id: project, project_membership: { user_email: "existing.user@test.com" } }
}.to change(AccountAuth, :count)
account_auth = AccountAuth.last
project_membership = ProjectMembership.last
expect(account_auth.user).to eq existing_user
expect(account_auth.account).to eq project.account
expect(account_auth.role).to eq "associate"
expect(project_membership.user).to eq existing_user
expect(project_membership.project).to eq project
end
it "sends an email to the new user" do
post :create, params: { project_id: project, project_membership: { user_email: "new.user@test.com" } }
assert_enqueued_email_with UserMailer, :project_invitation, args: [User.last, project, user_is_new: true]
end
end
context "for an associate" do
let(:current_user) { create(:user, :associate) }
it "raises exception" do
expect {
post :create, params: { project_id: project, project_membership: { user_email: "new.user@test.com" } }
}.to raise_error(Pundit::NotAuthorizedError)
end
end
end
describe "#destroy" do
let(:project_membership) { current_user.project_memberships.first }
it "responds with redirect" do
delete :destroy, params: { id: project_membership }
expect(response).to be_redirect
expect(response).to redirect_to([project, :project_memberships])
expect(flash.alert).to be_present
end
it "destroys the project membership record" do
expect {
delete :destroy, params: { id: project_membership }
}.to change(ProjectMembership, :count).by(-1)
end
end
end

View File

@@ -0,0 +1,307 @@
require "rails_helper"
RSpec.describe ProjectsController, type: :controller do
render_views
let(:current_user) { create(:user, :account_manager) }
let(:user) { current_user }
let(:account) { user.primary_account }
let!(:project) { create(:project, name: "My Project", client_name: "My Client", members: current_user, account: current_user.primary_account) }
before do
sign_in(current_user)
end
describe "#index" do
let!(:project_one) { create(:project, name: "Avengers", members: current_user, account: current_user.primary_account) }
let!(:project_two) { create(:project, name: "Justice League", members: [], account: current_user.primary_account) }
it "responds successfully" do
get :index
expect(response).to be_successful
end
it "redirects to accountless page if user is accountless" do
sign_in(create(:user, :accountless))
get :index
expect(response).to redirect_to(accountless_user_path)
end
context "for an associate" do
let(:current_user) { create(:user, :associate) }
it "only shows projects that the user has been invited to" do
get :index
expect(response.body).to have_content("Avengers")
expect(response.body).not_to have_content("Justice League")
end
end
context "for a project manager" do
let(:current_user) { create(:user, :manager) }
it "only shows projects that the user has been invited to" do
get :index
expect(response.body).to have_content("Avengers")
expect(response.body).not_to have_content("Justice League")
end
end
context "for an account manager" do
let(:current_user) { create(:user, :account_manager) }
it "shows all projects" do
get :index
expect(response.body).to have_content("Avengers")
expect(response.body).to have_content("Justice League")
end
end
end
describe "#new" do
it "sets project" do
get :new
expect(response).to be_successful
expect(assigns(:project)).to have_attributes(account: current_user.primary_account)
end
it "renders project content" do
get :index
expect(response.body).to have_link("Create New Project", href: new_project_path)
expect(response.body).to have_link("My Project", href: project_path(project))
expect(response.body).to have_content("My Client")
expect(response.body).to have_link(href: project_project_memberships_path(project))
end
context "when there are no projects" do
it "renders prompt to create new one" do
Project.destroy_all
get :index
expect(response.body).to have_link("Create Your First Project", href: new_project_path)
end
end
context "for an associate" do
let(:current_user) { create(:user, :associate) }
it "renders doesn't prompt to create new one" do
current_user.project_memberships.delete_all
get :index
expect(response.body).to have_content("Click on a project you are invited to and get started.")
expect(response.body).not_to have_content("Create New Project")
end
end
end
describe "#show" do
it "responds successfully" do
get :show, params: { id: project }
expect(response).to be_successful
end
it "renders content" do
create(:talent_release, project: project)
create(:appearance_release, project: project)
create(:location_release, project: project)
create(:acquired_media_release, project: project)
create(:material_release, project: project)
create(:music_release, project: project)
get :show, params: { id: project }
expect(response.body).to have_content("My Project")
expect(response.body).to have_content("My Client")
expect(response.body).to have_link("Files", href: project_path(project))
expect(response.body).to have_link("Release", href: project_contract_templates_path(project))
expect(response.body).to have_link("Edit", href: "#")
expect(response.body).to have_link("Deliver", href: project_videos_path(project))
expect(response.body).to have_content("1 Team Member")
expect(response.body).to have_link("Talent Releases (1)", href: project_talent_releases_path(project))
expect(response.body).to have_link("Appearance Releases (1)", href: project_appearance_releases_path(project))
expect(response.body).to have_link("Location Releases (1)", href: project_location_releases_path(project))
expect(response.body).to have_link("Acquired Media Releases (1)", href: project_acquired_media_releases_path(project))
expect(response.body).to have_link("Material Releases (1)", href: project_material_releases_path(project))
expect(response.body).to have_link("Music Releases (1)", href: project_music_releases_path(project))
expect(response.body).to have_link("Reports", href: project_reports_path(project))
expect(response.body).to have_link(href: project_project_memberships_path(project))
end
context "for associates" do
let(:current_user) { create(:user, :associate) }
let!(:project) { create(:project_with_directories, name: "My Project", client_name: "My Client", members: current_user, account: current_user.primary_account) }
it "only returns directories with 'Everyone' permissons" do
get :show, params: { id: project }
expect(response.body).to have_content("Shared")
expect(response.body).not_to have_content("Financial Documents")
expect(response.body).not_to have_content("Salaries")
end
it "does not show reports folder" do
get :show, params: { id: project }
expect(response.body).not_to have_content("Reports")
end
end
context "for project managers" do
let(:current_user) { create(:user, :manager) }
let!(:project) { create(:project_with_directories, name: "My Project", client_name: "My Client", members: current_user, account: current_user.primary_account) }
it "only returns directories with 'Everyone' & 'Account Managers & Project Managers' permissons" do
get :show, params: { id: project }
expect(response.body).to have_content("Shared")
expect(response.body).to have_content("Financial Documents")
expect(response.body).not_to have_content("Salaries")
end
end
context "for account managers" do
let(:current_user) { create(:user, :account_manager) }
let!(:project) { create(:project_with_directories, name: "My Project", client_name: "My Client", account: current_user.primary_account) }
it "returns all directories" do
get :show, params: { id: project }
expect(response.body).to have_content("Shared")
expect(response.body).to have_content("Financial Documents")
expect(response.body).to have_content("Salaries")
end
end
end
describe "#new" do
it "sets project" do
get :new
expect(response).to be_successful
end
end
describe "#create" do
it "responds with redirect" do
post :create, params: { project: project_params }
expect(response).to be_redirect
expect(flash.notice).not_to be_nil
end
it "creates a new record" do
expect {
post :create, params: { project: project_params }
}.to change(Project, :count).by(1)
end
it "logs an event" do
expect {
post :create, params: { project: project_params }
}.to have_enqueued_job(TrackAnalyticsJob).with(user, account, :track_create_project, user_agent: "Rails Testing", user_ip: "0.0.0.0")
end
context "with invalid data" do
before do
allow_any_instance_of(Project).to receive(:save).and_return(false)
end
it "shows the video analysis status and button" do
project = create(:project, account: current_user.primary_account, videos: create_list(:video, 1))
expect(response).to be_successful
end
it "does not create a new record" do
expect {
post :create, params: { project: project_params }
}.not_to change(Project, :count)
end
end
context "for associates" do
let(:current_user) { create(:user, :associate) }
it "raises exception" do
expect {
post :create, params: { project: project_params }
}.to raise_error(Pundit::NotAuthorizedError)
end
end
end
describe "#edit" do
it "sets project, available_release_types" do
get :edit, params: { id: project }
expect(response).to be_successful
expect(assigns(:project)).to eq project
end
end
describe "#update" do
it "responds with redirect" do
patch :update, params: { id: project, project: project_params }
expect(response).to be_redirect
expect(flash.notice).not_to be_nil
end
context "for associates" do
let(:current_user) { create(:user, :associate) }
it "raises exception" do
expect {
patch :update, params: { id: project, project: project_params }
}.to raise_error(Pundit::NotAuthorizedError)
end
end
end
describe "#destroy" do
it "responds with redirect" do
skip "This functionality is no longer available"
delete :destroy, params: { id: project }
expect(response).to be_redirect
expect(response).to redirect_to(signed_in_root_path)
expect(flash.alert).not_to be_nil
end
it "destroys the record" do
skip "This functionality is no longer available"
expect {
delete :destroy, params: { id: project }
}.to change(Project, :count).by(-1)
end
context "for associates" do
let(:current_user) { create(:user, :associate) }
it "raises exception" do
expect {
delete :destroy, params: { id: project }
}.to raise_error(Pundit::NotAuthorizedError)
end
end
end
private
def project_params
attributes_for(:project)
end
end

View File

@@ -0,0 +1,74 @@
require "rails_helper"
RSpec.describe Public::AcquiredMediaReleasesController, type: :controller do
let(:user) { create(:user) }
let(:project) { create(:project, account: user.primary_account) }
render_views
describe "#create" do
it "logs analytics" do
contract_template = create(:contract_template, project: project)
expect {
post :create, params: { account_id: project.account.to_param, project_id: project, contract_template_id: contract_template, acquired_media_release: acquired_media_release_params }
}.to(
have_enqueued_job(TrackAnalyticsJob)
.with(nil, nil, :track_create_native_release, release_type: "AcquiredMediaRelease", account: project.account, user_agent: "Rails Testing", user_ip: "0.0.0.0")
)
end
it "displays validation errors" do
contract_template = create(:contract_template, project: project)
sign_in(user)
post :create, params: { account_id: user.primary_account.to_param, project_id: project, contract_template_id: contract_template, acquired_media_release: { name: "" } }
body = CGI.unescape_html(response.body)
expect(body).to match /Name can't be blank/
expect(body).to match />can't be blank</
end
it "responds with success " do
contract_template = create(:contract_template, project: project)
post :create, params: { account_id: user.primary_account.to_param, project_id: project, contract_template_id: contract_template, acquired_media_release: acquired_media_release_params }
expect(response).to be_successful
end
it "runs set tags for releasable job" do
contract_template = create(:contract_template, project: project)
expect {
post :create, params: { account_id: project.account.to_param, project_id: project, contract_template_id: contract_template, acquired_media_release: acquired_media_release_params }
}.to(
have_enqueued_job(SetTagsForReleasableJob)
.with(TalentRelease.last)
)
end
it "runs attach contract to releasable job" do
contract_template = create(:contract_template, project: project)
expect {
post :create, params: { account_id: project.account.to_param, project_id: project, contract_template_id: contract_template, acquired_media_release: acquired_media_release_params }
}.to(
have_enqueued_job(AttachContractToReleasableJob)
.with(TalentRelease.last)
)
end
end
private
def acquired_media_release_params
attributes_for(:acquired_media_release_with_file_infos, :native).except(:signature).merge(signature_param)
end
def signature_param
file = file_fixture("signature.png")
data_uri = Base64Image.from_image(file).data_uri
{ signature_base64: data_uri }
end
end

View File

@@ -0,0 +1,132 @@
require "rails_helper"
describe Public::AppearanceReleasesController do
let(:user) { create(:user) }
let(:project) { create(:project, account: user.primary_account) }
render_views
before :each do
allow(BrayniacAI::Validation).to receive(:create).and_return(double(:validation, valid: true))
end
describe "#create" do
it "logs analytics" do
contract_template = create(:contract_template, project: project)
expect {
post :create, params: {
account_id: project.account.to_param,
project_id: project,
contract_template_id: contract_template,
appearance_release: appearance_release_params
}
}.to(
have_enqueued_job(TrackAnalyticsJob)
.with(nil, nil, :track_create_native_release, release_type: "AppearanceRelease", account: project.account, user_agent: "Rails Testing", user_ip: "0.0.0.0")
)
end
it "displays validation errors" do
contract_template = create(:contract_template, project: project)
sign_in(user)
post :create, params: { account_id: user.primary_account.to_param, project_id: project, contract_template_id: contract_template, appearance_release: { person_address: "Albuquerque" } }
body = CGI.unescape_html(response.body)
expect(body).to match /Person first name can't be blank/
expect(body).to match /Person last name can't be blank/
expect(body).to match /Photo is not attached/
expect(body).to match />can't be blank</
end
it "responds with success " do
contract_template = create(:contract_template, project: project)
post :create, params: { account_id: project.account.to_param, project_id: project, contract_template_id: contract_template, appearance_release: appearance_release_params }
expect(response).to be_successful
end
it "responds with success when guardian photo is attached for minor" do
contract_template = create(:contract_template, project: project)
post :create, params: { account_id: project.account.to_param, project_id: project, contract_template_id: contract_template, appearance_release: minor_appearance_release_params }
expect(response).to be_successful
end
it "responds with success when guardian photo is not attached for minor" do
contract_template = create(:contract_template, project: project)
post :create, params: { account_id: project.account.to_param, project_id: project, contract_template_id: contract_template, appearance_release: minor_appearance_release_params(false) }
expect(response).to be_successful
end
it "runs headshots job" do
contract_template = create(:contract_template, project: project)
expect {
post :create, params: {
account_id: project.account.to_param,
project_id: project,
contract_template_id: contract_template,
appearance_release: appearance_release_params
}
}.to(
have_enqueued_job(AddHeadshotCollectionUidToProjectJob)
.with(project)
)
end
it "runs set tags for releasable job" do
contract_template = create(:contract_template, project: project)
expect {
post :create, params: {
account_id: project.account.to_param,
project_id: project,
contract_template_id: contract_template,
appearance_release: appearance_release_params
}
}.to(
have_enqueued_job(SetTagsForReleasableJob)
.with(AppearanceRelease.last)
)
end
it "runs attach contract to releasable job" do
contract_template = create(:contract_template, project: project)
expect {
post :create, params: {
account_id: project.account.to_param,
project_id: project,
contract_template_id: contract_template,
appearance_release: appearance_release_params
}
}.to(
have_enqueued_job(AttachContractToReleasableJob)
.with(AppearanceRelease.last)
)
end
end
private
def appearance_release_params
attributes_for(:appearance_release, :native).except(:signature).merge(signature_param)
end
def minor_appearance_release_params(with_guardian_photo = true)
minor_type = with_guardian_photo ? :minor_with_guardian_photo : :minor
attributes_for(:appearance_release, minor_type).merge(signature_param)
end
def signature_param
file = file_fixture("signature.png")
data_uri = Base64Image.from_image(file).data_uri
{ signature_base64: data_uri }
end
end

View File

@@ -0,0 +1,110 @@
require 'rails_helper'
RSpec.describe Public::BroadcastsController, type: :controller do
render_views
let(:user) { create(:user) }
let(:account) { user.primary_account }
let(:project) { create(:project, account: user.primary_account) }
before do
allow(MuxLiveStream).to receive(:new).and_return(double(id: "id", key: "key", playback_id: "playback_id"))
end
describe "#show" do
let(:broadcast) { create(:broadcast, project: project, name: "Broadcast") }
it "responds successfully" do
get :show, params: { token: broadcast.token }
expect(response).to be_successful
expect(assigns(:broadcast)).to eq(broadcast)
end
it "renders zoom meeting button" do
get :show, params: { token: broadcast.token }
expect(response.body).to have_link("Video Conference", href: broadcast_zoom_meeting_url(broadcast.token))
end
it "doesn't render share url" do
get :show, params: { token: broadcast.token }
expect(response.body).not_to have_button "Copy Share URL"
expect(response.body).not_to have_xpath "//input[@value='#{broadcast_url(broadcast.token)}']"
end
it "assigns required variables" do
get :show, params: { token: broadcast.token }
expect(assigns(:conference_url)).to eq broadcast_zoom_meeting_url(broadcast.token)
expect(assigns(:broadcast)).to eq broadcast
end
context "when there are no multi-view broadcasts" do
it "renders the view dropdown with just the current broadcast" do
get :show, params: { token: broadcast.token }
expect(response.body).to have_content "Switch View"
expect(response.body).to have_selector(".dropdown-menu .dropdown-item.active", text: "Broadcast")
end
end
context "when there are multi-view broadcasts" do
it "renders the view dropdown with all the broadcasts" do
other_broadcast = create(:broadcast, project: project, name: "Some Other Broadcast")
get :show, params: { token: broadcast.token, multi_view_tokens: [broadcast.token, other_broadcast.token] }
expect(response.body).to have_content "Switch View"
expect(response.body).to have_selector(".dropdown-menu .dropdown-item.active", text: "Broadcast")
expect(response.body).to have_selector(".dropdown-menu a.dropdown-item", text: "Some Other Broadcast")
end
end
context "when there are no recordings for the current broadcast" do
it "renders the view dropdown with a message" do
get :show, params: { token: broadcast.token }
expect(response.body).to have_content "Switch View"
expect(response.body).to have_selector(".dropdown-menu .dropdown-item", text: "Recordings will appear here")
end
end
context "when there are recordings available" do
it "renders the view dropdown with the recordings" do
recording = create(:broadcast_recording, broadcast: broadcast)
get :show, params: { token: broadcast.token }
expect(response.body).to have_content "Switch View"
expect(response.body).to have_selector(".dropdown-menu a.dropdown-item", text: recording.download_file_name)
end
end
end
describe "#update" do
let!(:broadcast) { create(:broadcast, :with_stream, skip_create_callback: true, project: project ) }
it "uploads files to broadcast" do
patch :update, params: { token: broadcast.token, broadcast: file_params }, xhr: true
expect(broadcast.files.count).to eq(1)
expect(broadcast.files.first.filename).to eq("contract.pdf")
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
private
def file_params
path = Rails.root.join("spec", "fixtures", "files", "contract.pdf")
contract_file = Rack::Test::UploadedFile.new(path, "application/pdf")
{ files: [contract_file] }
end
end

View File

@@ -0,0 +1,86 @@
require "rails_helper"
describe Public::LocationReleasesController do
let(:user) { create(:user) }
let(:project) { create(:project, account: user.primary_account) }
render_views
describe "#create" do
it "logs analytics" do
contract_template = create(:contract_template, project: project)
expect {
post :create, params: { account_id: project.account.to_param, project_id: project, contract_template_id: contract_template, location_release: location_release_params }
}.to(
have_enqueued_job(TrackAnalyticsJob)
.with(nil, nil, :track_create_native_release, release_type: "LocationRelease", account: project.account, user_agent: "Rails Testing", user_ip: "0.0.0.0")
)
end
it "displays validation errors" do
contract_template = create(:contract_template, project: project)
sign_in(user)
post :create, params: { account_id: user.primary_account.to_param, project_id: project, contract_template_id: contract_template, location_release: { person_address_city: "Albuquerque", filming_started_on: '02/02/02', filming_ended_on: '01/01/02' } }
body = CGI.unescape_html(response.body)
expect(body).to match /Name can't be blank/
expect(body).to match />can't be blank</
# expect(body).to match /must be after the filming started on date/
end
it "renders a success page" do
contract_template = create(:contract_template, project: project)
post :create, params: { account_id: user.primary_account.to_param, project_id: project, contract_template_id: contract_template, location_release: location_release_params, filming_started_on: '01/02/20', filming_ended_on: '03/18/20' }
expect(response).to be_successful
end
it "runs set tags for releasable job" do
contract_template = create(:contract_template, project: project)
expect {
post :create, params: { account_id: project.account.to_param, project_id: project, contract_template_id: contract_template, location_release: location_release_params }
}.to(
have_enqueued_job(SetTagsForReleasableJob)
.with(LocationRelease.last)
)
end
it "runs attach contract to releasable job" do
contract_template = create(:contract_template, project: project)
expect {
post :create, params: { account_id: project.account.to_param, project_id: project, contract_template_id: contract_template, location_release: location_release_params }
}.to(
have_enqueued_job(AttachContractToReleasableJob)
.with(LocationRelease.last)
)
end
end
private
def location_release_params
attributes_for(:location_release, :native).except(:signature).merge(signature_param).merge(person_address_params)
end
def person_address_params
{
person_address_street1: "123 Broadway",
person_address_city: "New York",
person_address_state: "NY",
person_address_zip: "10001",
person_address_country: "United States"
}
end
def signature_param
file = file_fixture("signature.png")
data_uri = Base64Image.from_image(file).data_uri
{ signature_base64: data_uri }
end
end

View File

@@ -0,0 +1,74 @@
require "rails_helper"
describe Public::MaterialReleasesController do
let(:user) { create(:user) }
let(:project) { create(:project, account: user.primary_account) }
render_views
describe "#create" do
it "logs analytics" do
contract_template = create(:contract_template, project: project)
expect {
post :create, params: { account_id: project.account.to_param, project_id: project, contract_template_id: contract_template, material_release: material_release_params }
}.to(
have_enqueued_job(TrackAnalyticsJob)
.with(nil, nil, :track_create_native_release, release_type: "MaterialRelease", account: project.account, user_agent: "Rails Testing", user_ip: "0.0.0.0")
)
end
it "displays validation errors" do
contract_template = create(:contract_template, project: project)
sign_in(user)
post :create, params: { account_id: user.primary_account.to_param, project_id: project, contract_template_id: contract_template, material_release: { person_address_city: "Albuquerque" } }
body = CGI.unescape_html(response.body)
expect(body).to match /Person first name can't be blank/
expect(body).to match /Person last name can't be blank/
expect(body).to match />can't be blank</
end
it "renders a confirmation page" do
contract_template = create(:contract_template, project: project)
post :create, params: { account_id: user.primary_account, project_id: project, contract_template_id: contract_template, material_release: material_release_params }
expect(response).to be_successful
end
it "runs set tags for releasable job" do
contract_template = create(:contract_template, project: project)
expect {
post :create, params: { account_id: project.account.to_param, project_id: project, contract_template_id: contract_template, material_release: material_release_params }
}.to(
have_enqueued_job(SetTagsForReleasableJob)
.with(MaterialRelease.last)
)
end
it "runs attach contract to releasable job" do
contract_template = create(:contract_template, project: project)
expect {
post :create, params: { account_id: project.account.to_param, project_id: project, contract_template_id: contract_template, material_release: material_release_params }
}.to(
have_enqueued_job(AttachContractToReleasableJob)
.with(MaterialRelease.last)
)
end
end
private
def material_release_params
attributes_for(:material_release, :native).except(:signature).merge(signature_param)
end
def signature_param
file = file_fixture("signature.png")
data_uri = Base64Image.from_image(file).data_uri
{ signature_base64: data_uri }
end
end

View File

@@ -0,0 +1,115 @@
require "rails_helper"
RSpec.describe Public::TalentReleasesController, type: :controller do
let(:user) { create(:user) }
let(:project) { create(:project, account: user.primary_account) }
render_views
describe "#create" do
it "logs analytics" do
contract_template = create(:contract_template, project: project)
expect {
post :create, params: { account_id: project.account.to_param, project_id: project, contract_template_id: contract_template, talent_release: talent_release_params }
}.to(
have_enqueued_job(TrackAnalyticsJob)
.with(nil, nil, :track_create_native_release, release_type: "TalentRelease", account: project.account, user_agent: "Rails Testing", user_ip: "0.0.0.0")
)
end
it "displays validation errors" do
contract_template = create(:contract_template, project: project)
sign_in(user)
post :create, params: { account_id: user.primary_account.to_param, project_id: project, contract_template_id: contract_template, talent_release: { person_address_city: "Albuquerque" } }
body = CGI.unescape_html(response.body)
expect(body).to match /Person first name can't be blank/
expect(body).to match /Person last name can't be blank/
expect(body).to match /Photos must be included/
expect(body).to match />can't be blank</
end
it "responds with success " do
contract_template = create(:contract_template, project: project)
post :create, params: { account_id: user.primary_account.to_param, project_id: project, contract_template_id: contract_template, talent_release: talent_release_params }
expect(response).to be_successful
end
it "responds with success when guardian photo is attached for minor" do
contract_template = create(:contract_template, project: project)
post :create, params: { account_id: project.account.to_param, project_id: project, contract_template_id: contract_template, talent_release: minor_appearance_release_params }
expect(response).to be_successful
end
it "responds with success when guardian photo is not attached for minor" do
contract_template = create(:contract_template, project: project)
post :create, params: { account_id: project.account.to_param, project_id: project, contract_template_id: contract_template, talent_release: minor_appearance_release_params(false) }
expect(response).to be_successful
end
it "runs headshots job" do
contract_template = create(:contract_template, project: project)
expect {
post :create, params: { account_id: project.account.to_param, project_id: project, contract_template_id: contract_template, talent_release: talent_release_params }
}.to(
have_enqueued_job(AddHeadshotCollectionUidToProjectJob)
.with(project)
)
end
it "runs set tags for releasable job" do
contract_template = create(:contract_template, project: project)
expect {
post :create, params: { account_id: project.account.to_param, project_id: project, contract_template_id: contract_template, talent_release: talent_release_params }
}.to(
have_enqueued_job(SetTagsForReleasableJob)
.with(TalentRelease.last)
)
end
it "runs attach contract to releasable job" do
contract_template = create(:contract_template, project: project)
expect {
post :create, params: { account_id: project.account.to_param, project_id: project, contract_template_id: contract_template, talent_release: talent_release_params }
}.to(
have_enqueued_job(AttachContractToReleasableJob)
.with(TalentRelease.last)
)
end
end
private
def talent_release_params
attributes_for(:talent_release, :native).except(:signature).merge(signature_param, photos_param)
end
def minor_appearance_release_params(with_guardian_photo = true)
minor_type = with_guardian_photo ? :minor_with_guardian_photo : :minor
attributes_for(:talent_release, minor_type).merge(signature_param, photos_param)
end
def photos_param
path = Rails.root.join("spec", "fixtures", "files", "person_photo.png")
photo = Rack::Test::UploadedFile.new(path, "image/png")
{ photos: [photo] }
end
def signature_param
file = file_fixture("signature.png")
data_uri = Base64Image.from_image(file).data_uri
{ signature_base64: data_uri }
end
end

View File

@@ -0,0 +1,26 @@
require 'rails_helper'
require 'zoom_gateway'
RSpec.describe Public::ZoomMeetingsController, type: :controller do
let(:user) { create(:user) }
let(:account) { user.primary_account }
let(:project) { create(:project, account: user.primary_account) }
let(:broadcast) { create(:broadcast, name: "Broadcast", project: project) }
let(:meeting_start_url) { "http://meeting_start_url" }
let(:meeting_hash) { HashWithIndifferentAccess.new(start_url: meeting_start_url) }
before :each do
allow_any_instance_of(ZoomGateway).to receive(:find_meeting).and_return(meeting_hash)
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")
allow(MuxLiveStream).to receive(:new).and_return OpenStruct.new(id: 'id', key: 'key', playback_id: 'playback_id')
end
describe "#show" do
it "redirects to meeting start url" do
get :show, params: { broadcast_token: broadcast.token }
expect(response).to redirect_to(meeting_start_url)
end
end
end

View File

@@ -0,0 +1,123 @@
require "rails_helper"
describe ReleaseTemplateImportsController do
render_views
let(:current_user) { create(:user, :account_manager) }
let(:project) { create(:project, members: current_user, account: current_user.primary_account) }
let(:project_one) { create(:project, name: "Avengers", members: [current_user], account: current_user.primary_account) }
let!(:project_one_template) { create(:contract_template, name: "First Contract Template", fee: 50, release_type: "appearance", project: project_one) }
let(:project_two) { create(:project, name: "Justice League", members: [], account: current_user.primary_account) }
let!(:project_two_template) { create(:contract_template, name: "Second Contract Template", fee: 50, release_type: "talent", project: project_two) }
before do
sign_in(current_user)
end
describe "#new" do
it "responds ok" do
get :new, params: { project_id: project }
expect(response).to be_successful
end
it "has a search field form" do
get :new, params: { project_id: project }
expect(response.body).to have_button("search-button")
end
it "paginates the templates" do
create_list(:contract_template, 20, project: project_one)
get :new, params: { project_id: project }
expect(response.body).to have_link("2", href: new_project_release_template_imports_path(project, page: 2))
end
it "doesn't render release templates from current project" do
template = create(:contract_template, name: "Current Project Template", fee: 100, release_type: "appearance", project: project)
get :new, params: { project_id: project }
expect(response.body).not_to have_content("Current Project Template")
end
it "filters the templates by a query param" do
get :new, params: { project_id: project, query: "Second" }, xhr: true
expect(response.body).not_to have_content("First Contract Template")
expect(response.body).to have_content("Second Contract Template")
end
context "for account manager" do
it "renders all the available release templates from other projects" do
get :new, params: { project_id: project }
expect(response.body).to have_content("Avengers")
expect(response.body).to have_content("First Contract Template")
expect(response.body).to have_content("Appearance")
expect(response.body).to have_content("Justice League")
expect(response.body).to have_content("Second Contract Template")
expect(response.body).to have_content("Talent")
expect(response.body).to have_button("Import Selected Templates")
end
end
context "for manager" do
let(:manager) { create(:user, :manager, accounts: [current_user.primary_account]) }
it "renders the release templates only from projects that he's member of" do
project_one.project_memberships.create(user: manager)
project.project_memberships.create(user: manager)
sign_in(manager)
get :new, params: { project_id: project }
expect(response.body).to have_content("Avengers")
expect(response.body).to have_content("First Contract Template")
expect(response.body).to have_content("Appearance")
expect(response.body).not_to have_content("Justice League")
expect(response.body).to have_button("Import Selected Templates")
end
end
context "for associate" do
let(:current_user) { create(:user, :associate) }
it "raises authorization error" do
expect {
get :new, params: { project_id: project }
}.to raise_error(Pundit::NotAuthorizedError)
end
end
end
describe "#create" do
let(:template_ids) { [project_one_template.id, project_two_template.id] }
it "redirects" do
post :create, params: { project_id: project, template_ids: template_ids }
expect(response).to redirect_to(project_contract_templates_path(project))
end
it "copies selected templates" do
expect {
post :create, params: { project_id: project, template_ids: template_ids }
}.to change(ContractTemplate, :count).by(2)
end
context "when current user is an associate" do
let(:current_user) { create(:user, :associate) }
it "raises authorization error" do
expect {
post :create, params: { project_id: project, template_ids: template_ids }
}.to raise_error(Pundit::NotAuthorizedError)
end
end
end
end

View File

@@ -0,0 +1,126 @@
require "rails_helper"
RSpec.describe ReportsController, type: :controller do
render_views
let(:current_user) { create(:user) }
let(:project) { create(:project, :discovery_client, account: current_user.primary_account) }
before do
sign_in current_user
end
describe "#index" do
it "responds successfully" do
get :index, params: { project_id: project }
expect(response).to be_successful
end
context "for a Discovery client" do
let(:project) { create(:project, :discovery_client, account: current_user.primary_account) }
it "renders content" do
create(:video, :published, project: project, name: "My Video", number: "001")
get :index, params: { project_id: project }
expect(response.body).to have_content "My Video"
expect(response.body).to have_content "001"
expect(response.body).to have_content "Production Elements Log"
expect(response.body).to have_content "GFX Cue List"
expect(response.body).to have_content "Music Cue Sheet"
expect(response.body).to have_content "BiG Music Cue Sheet"
expect(response.body).to have_content "Issues and Concerns Report"
end
end
context "for a Nat Geo client" do
let(:project) { create(:project, :nat_geo_client, account: current_user.primary_account) }
it "renders content" do
create(:video, :published, project: project, name: "My Video", number: "001")
get :index, params: { project_id: project }
expect(response.body).to have_content "My Video"
expect(response.body).to have_content "001"
expect(response.body).to have_content "Legal Binder Log"
expect(response.body).to have_content "Text Graphics Log"
expect(response.body).to have_content "Music Cue Sheet"
expect(response.body).to have_content "Original Music Log"
expect(response.body).to have_content "BiG Music Cue Sheet"
expect(response.body).to have_content "Issues and Concerns Report"
end
end
context "for another client" do
let(:project) { create(:project, account: current_user.primary_account) }
it "renders content" do
create(:video, :published, project: project, name: "My Video", number: "001")
get :index, params: { project_id: project }
expect(response.body).to have_content "My Video"
expect(response.body).to have_content "001"
expect(response.body).to have_content "Production Elements Log"
expect(response.body).to have_content "GFX Cue List"
expect(response.body).to have_content "Music Cue Sheet"
expect(response.body).to have_content "BiG Music Cue Sheet"
expect(response.body).to have_content "Issues and Concerns Report"
end
end
context "when there are no reports" do
it "renders an empty message" do
get :index, params: { project_id: project }
expect(response.body).to have_content("Reports will appear here")
end
end
context "when there are many records" do
it "paginates the table" do
create_list(:video, 4, :published, project: project)
get :index, params: { project_id: project }
expect(response.body).to have_link("2", href: project_reports_path(project, page: 2))
end
end
describe "xhr request" do
let(:project) { create(:project, :discovery_client, account: current_user.primary_account) }
before do
create(:video, :published, project: project, name: "My Video", number: "001")
end
context "when search field is empty" do
it "shows all reports" do
get :index, params: { project_id: project }, xhr: true
expect(response.body).to have_content "Production Elements Log"
expect(response.body).to have_content "GFX Cue List"
expect(response.body).to have_content "Music Cue Sheet"
expect(response.body).to have_content "BiG Music Cue Sheet"
expect(response.body).to have_content "Issues and Concerns Report"
end
end
context "when search field is not empty" do
it "shows only reports with name matching search query" do
get :index, params: { project_id: project, query: "Production" }, xhr: true
expect(response.body).to have_content("Production Elements Log")
expect(response.body).not_to have_content("GFX Cue List")
expect(response.body).not_to have_content("Music Cue Sheet")
expect(response.body).not_to have_content("BiG Music Cue Sheet")
expect(response.body).not_to have_content("Issues and Concerns Report")
end
end
end
end
end

View File

@@ -0,0 +1,40 @@
require "rails_helper"
RSpec.describe ReportDownloadsController, type: :controller do
render_views
let(:current_user) { create(:user) }
let(:project) { create(:project, :discovery_client, account: current_user.primary_account) }
before do
sign_in current_user
end
describe "#create" do
it "Enques zip file generation job" do
create_list(:download, 4, project_id: project.id, name: "#{project.name.parameterize}_appearance-releases")
expect {
post :create, params: { project_id: project.id }, format: :js
}.to have_enqueued_job(GenerateReportsZipJob)
end
it "creates a download record with 'not_started' status" do
create_list(:download, 4, project_id: project.id, name: "#{project.name.parameterize}_appearance-releases")
expect {
post :create, params: { project_id: project.id }, format: :js
}.to change(Download, :count).by(1)
expect(Download.last.status).to eq('not_started')
end
it "shows a notification to user" do
allow(ProjectsChannel).to receive(:broadcast_download_generation_update).with(be_kind_of(Download), I18n.t("report_downloads.download.pending"))
post :create, params: { project_id: project.id }, format: :js
expect(ProjectsChannel).to have_received(:broadcast_download_generation_update).with(be_kind_of(Download), I18n.t("report_downloads.download.pending"))
end
end
end

View File

@@ -0,0 +1,92 @@
require "rails_helper"
RSpec.describe SessionsController, type: :controller do
render_views
let(:user) { create(:user) }
let(:account) { user.primary_account }
describe "#new" do
it "responds successfully" do
get :new
expect(response).to be_successful
end
it "renders the content" do
get :new
expect(response.body).to have_content("Sign In")
expect(response.body).to have_field("Email")
expect(response.body).to have_field("Password")
end
end
describe "#create" do
context "when sign in successful" do
it "creates user_sign_in event" do
expect {
post :create, params: { session: { email: user.email, password: user.password_digest } }
}.to have_enqueued_job(TrackAnalyticsJob).with(user, account, :track_user_sign_in, user_agent: "Rails Testing", user_ip: "0.0.0.0")
end
it "redirects to root" do
post :create, params: { session: { email: user.email, password: user.password_digest } }
expect(response).to redirect_to(signed_in_root_path)
end
context "when remember me true" do
it "updates remember_created_at" do
post :create, params: { session: { email: user.email, password: user.password_digest }, remember_me: 1 }
expect(user.reload.remember_created_at).not_to be_nil
end
end
context "when remember me not given" do
it "does not save remember_me_created" do
post :create, params: { session: { email: user.email, password: user.password_digest } }
expect(user.reload.remember_created_at).to be_nil
end
end
end
context "when sign in not successful" do
it "redirects to 'new_session_path'" do
post :create, params: { session: { email: "bad_email@example.com", password: user.password_digest } }
expect(response).to redirect_to(new_session_path)
end
it "displays a flash message" do
post :create, params: { session: { email: "bad_email@example.com", password: user.password_digest } }
expect(flash.alert).to eq t("sessions.create.alert")
end
end
end
describe "#destroy" do
context "when user is signed in" do
before :each do
sign_in(user)
end
it "redirects to new_session_path" do
delete :destroy, params: {}
expect(response).to redirect_to(new_session_path)
end
end
context "when user is not signed in" do
it "renders session new" do
delete :destroy, params: {}
expect(response).to redirect_to(new_session_path)
end
end
end
end

View File

@@ -0,0 +1,68 @@
require "rails_helper"
RSpec.describe StreamNotificationsController, type: :controller do
render_views
let!(:broadcast) { create(:broadcast, :with_stream, skip_create_callback: true, name: "Live Stream") }
let(:active_status) { {type: "video.live_stream.active", object: { id: "mux_stream" }} }
let(:disconnected_status) { {type: "video.live_stream.disconnected", object: { id: "mux_stream" }} }
let(:idle_status) { {type: "video.live_stream.idle", object: { id: "mux_stream" }} }
let(:asset_ready) { {
type: "video.asset.static_renditions.ready",
object: { id: "asset_uid" },
data: {
playback_ids: [
{id: "playback_uid"}
],
static_renditions: {
files: [{name: "high.mp4"}]
}
},
stream_notification: {
data: {
live_stream_id: "mux_stream"
}
}
} }
describe "#create" do
before do
allow(BroadcastsChannel).to receive(:broadcast_stream_updates).with(be_kind_of(Broadcast))
allow(BroadcastsChannel).to receive(:stream_recording_ready)
end
it "updates the broadcast when active status is received in notification" do
post :create, params: active_status
expect(broadcast.reload).to be_active
expect(BroadcastsChannel).to have_received(:broadcast_stream_updates).with(be_kind_of(Broadcast))
end
it "updates the broadcast when disconnected status is received in notification" do
post :create, params: disconnected_status
expect(broadcast.reload).to be_streamer_disconnected
expect(BroadcastsChannel).to have_received(:broadcast_stream_updates).with(be_kind_of(Broadcast))
end
it "updates the broadcast when idle status is received in notification" do
post :create, params: idle_status
expect(broadcast.reload).to be_idle
expect(BroadcastsChannel).to have_received(:broadcast_stream_updates).with(be_kind_of(Broadcast))
end
it "creates a broadcast recording when static_renditions.ready is received in notification" do
expect {
post :create, params: asset_ready
}.to change(BroadcastRecording, :count).by(1)
expect(BroadcastsChannel).to have_received(:stream_recording_ready)
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,36 @@
require "rails_helper"
RSpec.describe TagsController, type: :controller do
let(:current_user) { create(:user) }
let(:releasable) { create(:appearance_release) }
before do
sign_in current_user
end
describe "#new" do
it "responds successfully" do
get :new, xhr: true, params: { "#{releasable.model_name.singular}_id" => releasable }
end
end
describe "#create" do
it "responds successfully" do
post :create, xhr: true, params: { "#{releasable.model_name.singular}_id" => releasable, acts_as_taggable_on_tag: tag_params }
expect(response).to be_successful
end
it "creates a new tag" do
expect {
post :create, xhr: true, params: { "#{releasable.model_name.singular}_id" => releasable, acts_as_taggable_on_tag: tag_params }
}.to change(releasable.taggings, :count).by(1)
end
end
private
def tag_params
{ name: "Fresh" }
end
end

View File

@@ -0,0 +1,239 @@
require "rails_helper"
RSpec.describe TalentReleasesController, type: :controller do
render_views
let(:user) { create(:user) }
let(:account) { user.primary_account }
let(:project) { create(:project, account: user.primary_account) }
before do
sign_in user
end
describe "#index" do
it "responds successfully" do
get :index, params: { project_id: project }
expect(response).to be_successful
end
it "renders content" do
release = create(:talent_release, project: project,
person_first_name: "My",
person_last_name: "Release",
person_phone: "5551234567",
person_email: "jane.doe@test.com")
create(:note, notable: release, content: "Some notes here")
get :index, params: { project_id: project }
expect(response.body).to have_content "My Release"
expect(response.body).to have_content "555-123-4567"
expect(response.body).to have_content "jane.doe@test.com"
expect(response.body).to have_content "Some notes here"
expect(response.body).to have_link "Import Release"
expect(response.body).to have_content "Manage"
end
context "when there are no talent releases" do
it "renders an empty message" do
get :index, params: { project_id: project }
expect(response.body).to have_content("Talent Releases will appear here")
end
end
context "when there are many records" do
it "paginates the table" do
create_list(:talent_release, 20, project: project)
get :index, params: { project_id: project }
expect(response.body).to have_link("2", href: project_talent_releases_path(project, page: 2))
end
end
context "for xhr request" do
it "filters the releases by a query param" do
talent_releases = [
create(:talent_release, person_name: "Adam Sandler", project: project),
create(:talent_release, person_name: "Zoe Perry", project: project),
]
get :index, params: { project_id: project, query: "Zoe" }, xhr: true
expect(response.body).not_to have_content("Adam Sandler")
expect(response.body).to have_content("Zoe Perry")
end
end
end
describe "#new" do
it "responds successfully" do
get :new, params: { project_id: project }
expect(response).to be_successful
end
end
describe "#create" do
it "responds successfully when guardian photo is not sent" do
expect {
post :create, params: { project_id: project, talent_release: talent_release_params }
}.to change(TalentRelease, :count).by(1)
expect(response).to be_redirect
expect(response).to redirect_to [project, :talent_releases]
expect(flash.notice).to be_present
end
it "responds successfully when guardian photo is sent" do
expect {
post :create, params: { project_id: project, talent_release: minor_talent_release_params }
}.to change(TalentRelease, :count).by(1)
expect(response).to be_redirect
expect(response).to redirect_to [project, :talent_releases]
expect(flash.notice).to be_present
end
it "enqueues headshot collection job" do
expect {
post :create, params: { project_id: project, talent_release: talent_release_params }
}.to have_enqueued_job(AddHeadshotCollectionUidToProjectJob).with(project)
end
it "enqueues tagging job" do
expect {
post :create, params: { project_id: project, talent_release: talent_release_params }
}.to have_enqueued_job(SetTagsForReleasableJob).with(TalentRelease.last)
end
it "logs analytics" do
expect {
post :create, params: { project_id: project, talent_release: talent_release_params }
}.to(
have_enqueued_job(TrackAnalyticsJob).with(user, account, :track_create_non_native_release, release_type: "TalentRelease", user_agent: "Rails Testing", user_ip: "0.0.0.0")
)
end
context "when the record would be invalid" do
before do
allow_any_instance_of(TalentRelease).to receive(:save).and_return(false)
end
it "re-renders the form" do
expect {
post :create, params: { project_id: project, talent_release: talent_release_params }
}.not_to change(TalentRelease, :count)
expect(response).to be_successful
expect(flash.notice).to be_nil
end
it "does not enqueue any jobs" do
expect {
post :create, params: { project_id: project, talent_release: talent_release_params }
}.not_to have_enqueued_job
end
end
end
describe "#edit" do
let(:non_native_talent_release) { create(:talent_release, project: project) }
let(:native_talent_release) { create(:talent_release, :native, project: project) }
it "responds successfully for non-native release" do
get :edit, params: { project_id: project, id: non_native_talent_release }
expect(response).to be_successful
end
it "responds with error for native release" do
expect{get :edit, params: { id: native_talent_release }}.to raise_exception Pundit::NotAuthorizedError
end
end
describe "#update" do
let(:talent_release) { create(:talent_release, project: project) }
it "responds successfully" do
patch :update, params: { project_id: project, id: talent_release, talent_release: talent_release_params }
expect(response).to redirect_to [project, :talent_releases]
expect(flash.notice).to be_present
end
it "enqueues headshot collection job" do
expect {
patch :update, params: { project_id: project, id: talent_release, talent_release: talent_release_params }
}.to have_enqueued_job(AddHeadshotCollectionUidToProjectJob).with(project)
end
context "when the record would be invalid" do
before do
allow_any_instance_of(TalentRelease).to receive(:save).and_return(false)
end
it "re-renders the form" do
patch :update, params: { project_id: project, id: talent_release, talent_release: talent_release_params }
expect(response).to be_successful
expect(flash.notice).to be_nil
end
it "does not enqueue any jobs" do
expect {
patch :update, params: { project_id: project, id: talent_release, talent_release: talent_release_params }
}.not_to have_enqueued_job(AddHeadshotCollectionUidToProjectJob)
end
end
end
describe "#destroy" do
let!(:talent_release) { create(:talent_release, project: project) }
it "responds with redirect" do
delete :destroy, params: { project_id: project, id: talent_release }
expect(response).to be_redirect
expect(response).to redirect_to [project, :talent_releases]
end
it "sets the flash" do
delete :destroy, params: { project_id: project, id: talent_release }
expect(flash.alert).not_to be_nil
end
it "destroys the record" do
expect {
delete :destroy, params: { project_id: project, id: talent_release }
}.to change(TalentRelease, :count).by(-1)
end
end
private
def talent_release_params
attributes_for(:talent_release).merge(exploitable_rights_params)
end
def minor_talent_release_params
attributes_for(:talent_release, :minor_with_guardian_photo).merge(exploitable_rights_params)
end
def exploitable_rights_params
{
applicable_medium_id: ApplicableMedium.last.id,
applicable_medium_text: "applicable_media",
territory_id: Territory.last.id,
territory_text: "territory",
term_id: Term.last.id,
term_text: "term",
restriction_id: Restriction.last.id,
restriction_text: "restrictions",
}
end
end

View File

@@ -0,0 +1,203 @@
require "rails_helper"
RSpec.describe VideoAnalyses::UnreleasedAppearancesController, type: :controller do
let(:user) { create(:user) }
let(:project) { create(:project, account: user.primary_account) }
let!(:video) { create(:video, project: project) }
before :each do
sign_in user
end
render_views
describe "#new" do
let(:edl_event_gateway) { instance_double(EdlEventGateway) }
before :each do
allow(EdlEventGateway).to receive(:new).and_return(edl_event_gateway)
allow(edl_event_gateway).to receive(:edl_events).and_return(build_list(:edl_event, 1))
end
it "sets unreleased_appearance, edl_events_data" do
get :new, params: {
unreleased_appearance: { time_elapsed: "1", notes: "great work" },
video_id: video,
}, xhr: true
expect(response).to be_successful
expect(assigns(:unreleased_appearance)).to have_attributes({
video_id: video.id,
time_elapsed: "1",
notes: "great work",
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
})
expect(assigns(:edl_events_data)).to eq({
edl_events: build_list(:edl_event, 1),
edl_attributes: {
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
},
info_message: "An EDL event was found. Data is shown below",
})
end
end
describe "#create" do
it "creates unreleased_appearance" do
expect {
post :create, params: {
unreleased_appearance: {
time_elapsed: "1",
notes: "great work",
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
note_category: "other",
},
video_id: video,
}, xhr: true
}.to change(UnreleasedAppearance, :count).from(0).to(1)
end
it "sets unreleased_appearances_data" do
post :create, params: {
unreleased_appearance: {
time_elapsed: "1",
notes: "great work",
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
note_category: "other",
},
video_id: video,
}, xhr: true
expect(assigns(:unreleased_appearances_data).unreleased_appearances.first).to have_attributes(
notes: "great work",
time_elapsed: "1",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
note_category: "other",
)
end
end
describe "#edit" do
let(:edl_gateway) { double(:edl_gateway) }
before :each do
allow(EdlEventGateway).to receive(:new).and_return(edl_gateway)
allow(edl_gateway).to receive(:edl_events).and_return(build_list(:edl_event, 1))
end
it "sets unreleased_appearance, edl_events_data" do
unreleased_appearance = create(:unreleased_appearance, video: video)
get :edit, params: { id: unreleased_appearance }, xhr: true
expect(EdlEventGateway).to have_received(:new).with(
instance_of(FilesForRequest),
"00:00:01:13",
"00:00:01:13",
)
expect(response).to be_successful
expect(assigns(:unreleased_appearance)).to eq unreleased_appearance
expect(assigns(:edl_events_data)).to eq({
edl_events: build_list(:edl_event, 1),
edl_attributes: {
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
},
info_message: "An EDL event was found. Data is shown below",
})
end
end
describe "#update" do
let(:edl_gateway) { double(:edl_gateway) }
before :each do
allow(EdlEventGateway).to receive(:new).and_return(edl_gateway)
allow(edl_gateway).to receive(:edl_events).and_return(build_list(:edl_event, 1))
end
it "sets unreleased_appearances_data" do
unreleased_appearance = create(:unreleased_appearance, video: video)
put :update, params: {
id: unreleased_appearance,
unreleased_appearance: {
notes: "notes",
time_elapsed: "time_elapsed",
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
note_category: "other",
}
}, xhr: true
expect(response).to be_successful
expect(assigns(:unreleased_appearances_data).unreleased_appearances.first).to have_attributes(
notes: "notes",
time_elapsed: "time_elapsed",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
note_category: "other",
)
end
end
describe "#destroy" do
let!(:unreleased_appearance) { create(:unreleased_appearance) }
it "sets unreleased_appearances_data" do
delete :destroy, params: { id: unreleased_appearance.id }, xhr: true
expect(assigns(:unreleased_appearances_data).unreleased_appearances).to eq([])
end
it "destroys given unreleased_appearance" do
expect {
delete :destroy, params: { id: unreleased_appearance.id }, xhr: true
}.to change(UnreleasedAppearance, :count).from(1).to(0)
end
end
end

View File

@@ -0,0 +1,19 @@
require "rails_helper"
describe VideoAnalyses::AcquiredMediaReleasesController do
let(:current_user) { create(:user) }
let(:project) { create(:project, account: current_user.primary_account) }
let(:video) { create(:video, project: project) }
before do
sign_in(current_user)
end
describe "#index" do
it "responds with success" do
get :index, params: { video_id: video }, xhr: true
expect(response).to be_successful
end
end
end

View File

@@ -0,0 +1,116 @@
require "rails_helper"
describe VideoAnalyses::EdlEventsController do
let(:user) { create(:user) }
let(:project) { create(:project, account: user.primary_account) }
let(:video) { create(:video, project: project) }
before :each do
sign_in(user)
end
describe "#create" do
context "when 1 EDL event" do
before :each do
allow(EdlEventGateway).to receive(:new).and_return(
double("gateway", edl_events: [
EdlEvent.new(
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
)
])
)
end
it "sets timecode, edl_events, info_message" do
post :create, xhr: true, params: { video_id: video, edl_event: { time_elapsed: 2.5 } }
expect(response).to be_successful
expect(assigns(:timecode)).to eq(Timecode.from_seconds(2.5).to_s)
expect(assigns(:edl_events)).to eq([
EdlEvent.new(
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
)
])
expect(assigns(:info_message)).to eq "One EDL event for this timecode was found and is shown below"
end
end
context "when no EDL events" do
before :each do
allow(EdlEventGateway).to receive(:new).and_return(
double("gateway", edl_events: [])
)
end
it "sets timecode, edl_events, info_message" do
post :create, xhr: true, params: { video_id: video, edl_event: { time_elapsed: 2.5 } }
expect(response).to be_successful
expect(assigns(:timecode)).to eq(Timecode.from_seconds(2.5).to_s)
expect(assigns(:edl_events)).to eq([])
expect(assigns(:info_message)).to eq "No EDL events for this timecode were found"
end
end
context "when multiple EDL events" do
before :each do
allow(EdlEventGateway).to receive(:new).and_return(
double("gateway", edl_events: [
EdlEvent.new(
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
),
EdlEvent.new(
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
),
])
)
end
it "sets timecode, edl_events, info_message" do
post :create, xhr: true, params: { video_id: video, edl_event: { time_elapsed: 2.5 } }
expect(response).to be_successful
expect(assigns(:timecode)).to eq(Timecode.from_seconds(2.5).to_s)
expect(assigns(:edl_events)).to eq([
EdlEvent.new(
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
),
EdlEvent.new(
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
),
])
expect(assigns(:info_message)).to eq "Multiple EDL events for this timecode were found and are shown below"
end
end
end
end

View File

@@ -0,0 +1,289 @@
require "rails_helper"
RSpec.describe VideoAnalyses::GraphicsElementsController, type: :controller do
let(:user) { create(:user) }
let(:project) { create(:project, account: user.primary_account) }
let(:video) { create(:video, project: project) }
before :each do
sign_in(user)
end
render_views
describe "#new" do
let(:edl_gateway) { double(:edl_gateway) }
before :each do
allow(EdlEventGateway).to receive(:new).and_return(edl_gateway)
allow(edl_gateway).to receive(:edl_events).and_return(build_list(:edl_event, 1))
end
it "responds successfully and sets graphics_element, edl_events_data, matched_filename" do
get :new, params: {
video_id: video.id,
graphics_element: {
text: "asdf",
time_elapsed: "00:01:00",
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
edl_type: "edl_type",
},
matched_file_name: "matched_file_name",
}, xhr: true
expect(EdlEventGateway).to have_received(:new).with(
instance_of(GraphicsFilesForRequest),
"00:00:00:00",
"00:00:00:00",
channel_filter: "V",
)
expect(response).to be_successful
expect(assigns(:graphics_element)).to have_attributes(
id: nil,
text: "asdf",
time_elapsed: "00:01:00",
clip_name: "clip_name",
description: "description",
duration: "duration",
source_file_name: "source_file_name",
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
edl_type: "edl_type",
)
expect(assigns(:edl_events_data)).to eq({
edl_events: build_list(:edl_event, 1),
edl_attributes: {
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
},
info_message: "An EDL event was found. Data is shown below",
})
expect(assigns(:matched_file_name)).to eq "matched_file_name"
end
context "when edl_type param is all_tracks" do
it "uses the all tracks edl" do
get :new, params: {
video_id: video.id,
graphics_element: {
text: "asdf",
time_elapsed: "00:01:00",
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
edl_type: "all_tracks",
},
matched_file_name: "matched_file_name",
}, xhr: true
expect(EdlEventGateway).to have_received(:new).with(
instance_of(FilesForRequest),
"00:00:00:00",
"00:00:00:00",
channel_filter: "V",
)
end
end
end
describe "#create" do
it "responds successfully and creates graphics_element" do
expect {
post :create, params: {
video_id: video.id,
graphics_element: {
graphic_type: "Subtitle",
text: "asdf",
time_elapsed: "00:01:00",
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
edl_type: "edl_type",
},
}, xhr: true
}.to change(GraphicsElement, :count).by(1)
expect(response).to be_successful
end
it "sets graphics_element_data, graphics_elements_data" do
post :create, params: {
video_id: video.id,
graphics_element: {
graphic_type: "Subtitle",
text: "asdf",
time_elapsed: "00:01:00",
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
edl_type: "edl_type",
},
}, xhr: true
expect(assigns(:graphics_element_data)).to have_attributes(
source_file_name: "source_file_name",
timecode_in: "timecode_in",
should_toggle_checkmark: true,
is_valid: true,
)
expect(assigns(:graphics_elements_data)).to have_attributes(
graphics_elements: [GraphicsElement.last]
)
end
end
describe "#edit" do
let(:edl_gateway) { double(:edl_gateway) }
before :each do
allow(EdlEventGateway).to receive(:new).and_return(edl_gateway)
allow(edl_gateway).to receive(:edl_events).and_return(build_list(:edl_event, 1))
end
it "sets graphics_element, edl_events_data" do
graphics_element = create(:graphics_element, video: video)
get :edit, params: { id: graphics_element }, xhr: true
expect(EdlEventGateway).to have_received(:new).with(
instance_of(GraphicsFilesForRequest),
"00:00:05:00",
"00:00:05:00",
channel_filter: "V",
)
expect(response).to be_successful
expect(assigns(:graphics_element)).to eq graphics_element
expect(assigns(:edl_events_data)).to eq({
edl_events: build_list(:edl_event, 1),
edl_attributes: {
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
},
info_message: "An EDL event was found. Data is shown below",
})
end
context "when edl_type param is all_tracks" do
it "uses the all tracks edl" do
graphics_element = create(:graphics_element, video: video, edl_type: "all_tracks")
get :edit, params: { id: graphics_element }, xhr: true
expect(EdlEventGateway).to have_received(:new).with(
instance_of(FilesForRequest),
"00:00:05:00",
"00:00:05:00",
channel_filter: "V",
)
end
end
end
describe "#update" do
let(:edl_gateway) { double(:edl_gateway) }
before :each do
allow(EdlEventGateway).to receive(:new).and_return(edl_gateway)
allow(edl_gateway).to receive(:edl_events).and_return(build_list(:edl_event, 1))
end
it "sets graphics_element_data, graphics_elements_data" do
graphics_element = create(:graphics_element, video: video)
put :update, params: {
id: graphics_element,
graphics_element: {
graphic_type: "Subtitle",
text: "text",
time_elapsed: "time_elapsed",
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
}
}, xhr: true
expect(response).to be_successful
expect(assigns(:graphics_element_data)).to have_attributes(
source_file_name: "source_file_name",
timecode_in: "timecode_in",
should_toggle_checkmark: true,
is_valid: true,
)
expect(assigns(:graphics_elements_data).graphics_elements.first).to have_attributes(
text: "text",
time_elapsed: "time_elapsed",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
)
end
end
describe "#delete" do
it "deletes given graphics_element" do
graphics_element = create(:graphics_element)
expect {
delete :destroy, params: { id: graphics_element }, xhr: true }.to change { GraphicsElement.count
}.from(1).to(0)
end
it "responds with graphics element data, graphics elements data" do
graphics_element = create(:graphics_element,
video: video,
source_file_name: "source_file_name",
timecode_in: "timecode_in",
)
delete :destroy, params: { id: graphics_element }, xhr: true
expect(assigns(:graphics_element_data)).to have_attributes(
source_file_name: "source_file_name",
timecode_in: "timecode_in",
should_toggle_checkmark: true,
is_valid: true,
)
expect(assigns(:graphics_elements_data)).to have_attributes(
graphics_elements: []
)
end
end
end

View File

@@ -0,0 +1,20 @@
require "rails_helper"
describe VideoAnalyses::TalentReleasesController do
let(:current_user) { create(:user) }
let(:project) { create(:project, account: current_user.primary_account) }
let(:video) { create(:video, project: project) }
before do
sign_in(current_user)
end
describe "#index" do
it "responds with success" do
get :index, params: { video_id: video }, xhr: true
expect(response).to be_successful
end
end
end

View File

@@ -0,0 +1,106 @@
require "rails_helper"
RSpec.describe VideoAnalysesController do
let(:admin) { create(:user, :admin) }
let(:project) { create(:project, account: admin.accounts.first) }
let(:video) { create(:video, project: project) }
before do
allow(AnalyzeVideoJob).to receive(:perform_later)
allow(BrayniacAI::EdlParse).to receive(:create)
sign_in admin
end
render_views
describe "#create" do
it "redirects to video analyses" do
post :create, params: { video_id: video, use_route: video_video_analyses_path(video) }
expect(response).to redirect_to(video_video_analyses_path(video))
end
it "reanalyzes the video" do
expect(AnalyzeVideoJob).to receive(:perform_later).with(video, reanalysis: true)
post :create, params: { video_id: video, use_route: video_video_analyses_path(video) }
end
it "reanalyzes the audio" do
expect(AnalyzeAudioJob).to receive(:perform_later).with(video)
post :create, params: { video_id: video, use_route: video_video_analyses_path(video) }
end
end
describe "#show" do
it "sets video_release_confirmations, talent_releases, appearance_releases, location_releases, acquired_media_releases, music_releases, material_releases, graphics_elements_data, audio_confirmations" do
talent_releases = [create(:talent_release)]
appearance_releases = [create(:appearance_release)]
location_releases = [create(:location_release)]
acquired_media_releases = [create(:acquired_media_release)]
music_releases = [create(:music_release)]
material_releases = [create(:material_release)]
project = create(:project,
name: "All the releases",
account: admin.accounts.first,
talent_releases: talent_releases,
appearance_releases: appearance_releases,
location_releases: location_releases,
acquired_media_releases: acquired_media_releases,
music_releases: music_releases,
material_releases: material_releases,
)
video = create(:video,
project: project,
video_release_confirmations: [
create(:video_release_confirmation, releasable: talent_releases.first),
]
)
create(:audio_confirmation, video: video)
get :show, params: { video_id: video, use_route: video_video_analyses_path(video) }
expect(assigns(:video_release_confirmations)).to eq [VideoReleaseConfirmation.first]
expect(assigns(:talent_releases)).to eq talent_releases
expect(assigns(:appearance_releases)).to eq appearance_releases
expect(assigns(:location_releases)).to eq location_releases
expect(assigns(:acquired_media_releases)).to eq acquired_media_releases
expect(assigns(:music_releases)).to eq music_releases
expect(assigns(:material_releases)).to eq material_releases
expect(assigns(:video_analysis_presenter)).to be_an_instance_of(VideoAnalysisPresenter)
expect(assigns(:graphics_elements_data)).to have_attributes(graphics_elements: [])
expect(assigns(:unreleased_appearances_data)).to have_attributes(unreleased_appearances: [])
expect(assigns(:audio_confirmations)).to eq [AudioConfirmation.last]
end
it "sorts confirmations by appears_at" do
talent_releases = [create(:talent_release), create(:talent_release), create(:talent_release)]
project = create(:project,
name: "All the releases",
account: admin.accounts.first,
talent_releases: talent_releases,
)
video = create(:video,
project: project,
video_release_confirmations: [
create(:video_release_confirmation, releasable: talent_releases.first, time_elapsed: "10"),
create(:video_release_confirmation, releasable: talent_releases.second, time_elapsed: "50"),
create(:video_release_confirmation, releasable: talent_releases.last, time_elapsed: "30"),
]
)
get :show, params: { video_id: video, use_route: video_video_analyses_path(video) }
body = response.body
first = body =~ /00:00:10:00/
second = body =~ /00:00:30:00/
last = body =~ /00:00:50:00/
expect(first < second).to eq true
expect(second < last).to eq true
end
end
end

View File

@@ -0,0 +1,321 @@
require "rails_helper"
RSpec.describe VideoReleaseConfirmationsController, type: :controller do
let(:admin) { create(:user, :admin) }
let(:project) { create(:project, account: admin.accounts.first) }
let(:video) { create(:video, project: project) }
before :each do
sign_in admin
end
describe "acquired_media_release" do
let(:acquired_media_release) { create(:acquired_media_release) }
describe "#new" do
let(:edl_event_gateway) { instance_double(EdlEventGateway) }
before :each do
allow(EdlEventGateway).to receive(:new).and_return(edl_event_gateway)
allow(edl_event_gateway).to receive(:edl_events).and_return(build_list(:edl_event, 1))
end
it "assigns video_release_confirmation, video, edl_events_data" do
file_info = create(:file_info)
post :new,
params: {
video_id: video,
acquired_media_release_id: acquired_media_release,
video_release_confirmation: {
time_elapsed: nil,
timecode_in: nil,
timecode_out: nil,
duration: nil,
source_file_name: nil,
clip_name: nil,
description: nil,
file_info_id: file_info,
},
use_route: new_video_acquired_media_release_video_release_confirmation_path(video, acquired_media_release)
},
xhr: true
expect(assigns(:video_release_confirmation)).to have_attributes({
video_id: video.id,
releasable_id: acquired_media_release.id,
time_elapsed: "",
releasable_type: "AcquiredMediaRelease",
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
file_info_id: file_info.id,
})
expect(assigns(:video)).to have_attributes({
id: video.id,
project_id: project.id,
analysis_status: "not_started",
analysis_started_at: nil,
name: nil,
number: nil,
report_published_at: nil
})
expect(assigns(:edl_events_data)).to eq({
edl_events: build_list(:edl_event, 1),
edl_attributes: {
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
},
info_message: "An EDL event was found. Data is shown below",
})
end
end
describe "#create" do
it "assigns video_release_confirmations, video_release_confirmation" do
file_info = create(:file_info)
post :create,
params: {
video_id: video,
acquired_media_release_id: acquired_media_release,
video_release_confirmation: {
channel: "V",
time_elapsed: "5",
timecode_in: "01:00:00:00",
timecode_out: "01:00:05:00",
duration: "5.0",
source_file_name: "DISCLAIMER.AVI",
clip_name: "DISCLAIMER.AVI.NEW.02",
description: "Boat",
file_info_id: file_info,
},
use_route: video_acquired_media_release_video_release_confirmations_path(video, acquired_media_release)
},
xhr: true
expect(assigns(:video_release_confirmations)).to eq(video.video_release_confirmations)
expect(assigns(:video_release_confirmation)).to have_attributes({
time_elapsed: "5",
timecode_in: "01:00:00:00",
timecode_out: "01:00:05:00",
duration: "5.0",
source_file_name: "DISCLAIMER.AVI",
clip_name: "DISCLAIMER.AVI.NEW.02",
description: "Boat",
file_info_id: file_info.id,
})
end
it "creates a video confirmation" do
expect {
post :create,
params: {
video_id: video,
acquired_media_release_id: acquired_media_release,
video_release_confirmation: {
channel: "V",
time_elapsed: "5",
timecode_in: "01:00:00:00",
timecode_out: "01:00:05:00",
duration: "5.0",
source_file_name: "DISCLAIMER.AVI",
clip_name: "DISCLAIMER.AVI.NEW.02",
description: "Boat",
},
use_route: video_acquired_media_release_video_release_confirmations_path(video, acquired_media_release)
},
xhr: true
}.to change { VideoReleaseConfirmation.count }.from(0).to(1)
end
end
describe "#destroy" do
let!(:video_release_confirmation) { create(:video_release_confirmation, video: video, releasable: acquired_media_release) }
it "assigns releasable, video, video_release_confirmations" do
delete :destroy,
params: {
id: video_release_confirmation,
video_id: video,
use_route: video_acquired_media_release_video_release_confirmations_path(video, video_release_confirmation)
}, xhr: true
expect(assigns(:releasable)).to eq(video_release_confirmation.releasable)
expect(assigns(:video)).to eq(video)
expect(assigns(:video_release_confirmations).to_a).to eq([])
end
it "destroys video confirmation" do
expect {
delete :destroy,
params: {
id: video_release_confirmation,
video_id: video,
use_route: video_acquired_media_release_video_release_confirmations_path(video, video_release_confirmation)
},
xhr: true
}.to change { VideoReleaseConfirmation.count }.from(1).to(0)
end
end
end
describe "location_releases" do
let(:location_release) { create(:location_release) }
let(:edl_event_gateway) { instance_double(EdlEventGateway) }
describe "#new" do
before :each do
allow(EdlEventGateway).to receive(:new).and_return(edl_event_gateway)
allow(edl_event_gateway).to receive(:edl_events).and_return(build_list(:edl_event, 1))
end
it "assigns video_release_confirmation, video, edl_events_data" do
post :new,
params: {
video_id: video,
location_release_id: location_release,
video_release_confirmation: {
time_elapsed: nil,
timecode_in: nil,
timecode_out: nil,
duration: nil,
source_file_name: nil,
clip_name: nil,
description: nil,
},
use_route: new_video_location_release_video_release_confirmation_path(video, location_release)
},
xhr: true
expect(assigns(:video_release_confirmation)).to have_attributes({
video_id: video.id,
releasable_id: location_release.id,
time_elapsed: "",
releasable_type: "LocationRelease",
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
})
expect(assigns(:video)).to have_attributes({
id: video.id,
project_id: project.id,
analysis_status: "not_started",
analysis_started_at: nil,
name: nil,
number: nil,
report_published_at: nil
})
expect(assigns(:edl_events_data)).to eq({
edl_events: build_list(:edl_event, 1),
edl_attributes: {
channel: "V",
timecode_in: "timecode_in",
timecode_out: "timecode_out",
duration: "duration",
source_file_name: "source_file_name",
clip_name: "clip_name",
description: "description",
},
info_message: "An EDL event was found. Data is shown below",
})
end
end
describe "#create" do
it "assigns video_release_confirmations, video_release_confirmation" do
post :create,
params: {
video_id: video,
location_release_id: location_release,
video_release_confirmation: {
channel: "V",
time_elapsed: "5",
timecode_in: "01:00:00:00",
timecode_out: "01:00:05:00",
duration: "5.0",
source_file_name: "DISCLAIMER.AVI",
clip_name: "DISCLAIMER.AVI.NEW.02",
description: "Boat",
},
use_route: video_location_release_video_release_confirmations_path(video, location_release)
},
xhr: true
expect(assigns(:video_release_confirmations)).to eq(video.video_release_confirmations)
expect(assigns(:video_release_confirmation)).to have_attributes({
time_elapsed: "5",
timecode_in: "01:00:00:00",
timecode_out: "01:00:05:00",
duration: "5.0",
source_file_name: "DISCLAIMER.AVI",
clip_name: "DISCLAIMER.AVI.NEW.02",
description: "Boat",
})
end
it "creates a video confirmation" do
expect {
post :create,
params: {
video_id: video,
location_release_id: location_release,
video_release_confirmation: {
time_elapsed: "5",
timecode_in: "01:00:00:00",
timecode_out: "01:00:05:00",
duration: "5.0",
source_file_name: "DISCLAIMER.AVI",
clip_name: "DISCLAIMER.AVI.NEW.02",
description: "Boat",
},
use_route: video_location_release_video_release_confirmations_path(video, location_release)
},
xhr: true
}.to change { VideoReleaseConfirmation.count }.from(0).to(1)
end
end
describe "#destroy" do
let!(:video_release_confirmation) { create(:video_release_confirmation, video: video, releasable: location_release) }
it "assigns releasable, video, video_release_confirmations" do
delete :destroy,
params: {
id: video_release_confirmation,
video_id: video,
use_route: video_location_release_video_release_confirmations_path(video, video_release_confirmation)
}, xhr: true
expect(assigns(:releasable)).to eq(video_release_confirmation.releasable)
expect(assigns(:video)).to eq(video)
expect(assigns(:video_release_confirmations).to_a).to eq([])
end
it "destroys video confirmation" do
expect {
delete :destroy,
params: {
id: video_release_confirmation,
video_id: video,
use_route: video_location_release_video_release_confirmations_path(video, video_release_confirmation)
},
xhr: true
}.to change { VideoReleaseConfirmation.count }.from(1).to(0)
end
end
end
end

View File

@@ -0,0 +1,34 @@
require "rails_helper"
RSpec.describe VideoReportsController, type: :controller do
let(:user) { create(:user) }
let(:video) { create(:video, project: create(:project, account: user.primary_account)) }
before :each do
sign_in user
end
describe "show" do
context "when type is discovery" do
it "builds the report and responds successfully" do
get :show, params: { video_id: video, format: "xlsx", type: "discovery" }
expect(response).to be_successful
expect(response.body.unpack("C*").pack("U*")).to_not be_blank
expect(response.header["Content-Type"]).to eq "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
expect(response.header["Content-Disposition"]).to match "video_file-mp4_production-elements-log.xlsx"
end
end
context "when type is nat_geo" do
it "builds the report and responds successfully" do
get :show, params: { video_id: video, format: "xlsx", type: "nat_geo" }
expect(response).to be_successful
expect(response.body.unpack("C*").pack("U*")).to_not be_blank
expect(response.header["Content-Type"]).to eq "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
expect(response.header["Content-Disposition"]).to match "video_file-mp4_legal-binder-log.xlsx"
end
end
end
end

View File

@@ -0,0 +1,30 @@
require "rails_helper"
describe Videos::ReportPublicationsController do
let(:admin) { create(:user, :admin) }
let(:project) { create(:project, account: admin.accounts.first) }
before do
sign_in(admin)
end
describe "#create" do
it "sets the video report publication date" do
video = create(:video, report_published_at: nil, project: project)
post :create, params: { video_id: video }
expect(video.reload).to be_report_published
end
end
describe "#destroy" do
it "unsets the video report publication date" do
video = create(:video, report_published_at: Time.zone.now, project: project)
delete :destroy, params: { video_id: video }
expect(video.reload).not_to be_report_published
end
end
end

View File

@@ -0,0 +1,280 @@
require "rails_helper"
RSpec.describe VideosController, type: :controller do
render_views
let(:user) { create(:user) }
let(:account) { user.primary_account }
let(:project) { create(:project, account: user.primary_account) }
let(:video) { create(:video, project: project) }
before do
sign_in(user)
end
describe "#index" do
it "responds successfully" do
get :index, params: { project_id: project }
expect(response).to be_successful
end
it "has a search form" do
get :index, params: { project_id: project }
expect(response.body).to have_button("search-button")
end
it "filters the videos by a query param" do
create(:video, project: project, name: "First Video")
create(:video, project: project, name: "Second Video")
get :index, params: { project_id: project, query: "Second"}, xhr: true
expect(response.body).not_to have_content("First Video")
expect(response.body).to have_content("Second Video")
end
it "paginates the videos" do
create_list(:video, 20, project: project)
get :index, params: { project_id: project }
expect(response.body).to have_link("2", href: project_videos_path(project, page: 2))
end
it "renders content" do
video = create(:video, project: project, name: "My Video", number: "001", created_at: 1.day.ago)
get :index, params: { project_id: project }
expect(response.body).to have_content("1 day ago")
expect(response.body).to have_content("My Video")
expect(response.body).to have_content("001")
expect(response.body).to have_content("video_file.mp4")
expect(response.body).to have_content("Generating...")
expect(response.body).to have_link("Upload New Video", href: landing_project_videos_path(project))
expect(response.body).to have_link("Edit", href: edit_video_path(video))
end
context "when there are no records" do
it "renders an empty message" do
get :index, params: { project_id: project }
expect(response.body).to have_content("Videos will appear here")
end
end
context "when there are many records" do
it "paginates the table" do
create_list(:video, 20, project: project)
get :index, params: { project_id: project }
expect(response.body).to have_link("2", href: project_videos_path(project, page: 2))
end
end
end
describe "#new" do
it "responds successfully" do
get :new, params: { project_id: project }
expect(response).to be_successful
end
end
describe "#landing" do
it "responds successfully" do
get :landing, params: { project_id: project }
expect(response).to be_successful
end
end
describe "#create" do
it "responds with redirect" do
post :create, params: { project_id: project, video: video_create_params }
expect(response).to redirect_to(project_videos_path(project))
end
it "creates a new video" do
expect {
post :create, params: { project_id: project, video: video_create_params }
}.to change(Video, "count").by(1)
expect(Video.last.video_editing_system).to eq "avid"
end
it "begins analyzing the video" do
expect {
post :create, params: { project_id: project, video: video_create_params }
}.to have_enqueued_job(AnalyzeVideoJob).with(Video.last).and have_enqueued_job(AnalyzeAudioJob).with(Video.last)
end
it "delivers an admin notification" do
assert_enqueued_emails 1 do
post :create, params: { project_id: project, video: video_create_params }
end
end
it "sets the flash" do
post :create, params: { project_id: project, video: video_create_params }
expect(flash.notice).to eq t("videos.create.notice")
end
it "logs analytics" do
expect {
post :create, params: { project_id: project, video: video_create_params }
}.to have_enqueued_job(TrackAnalyticsJob).with(user, account, :track_video_upload, user_agent: "Rails Testing", user_ip: "0.0.0.0")
end
context "when the record is invalid" do
it "responds successfully" do
post :create, params: { project_id: project, video: video_create_params(valid: false) }
expect(response).to be_successful
end
end
end
describe "#edit" do
it "responds successfully" do
get :edit, params: { id: video }
expect(response).to be_successful
end
end
describe "#update" do
it "redirects to the DeliverME page" do
patch :update, params: { id: video, video: video_update_params }
expect(response).to redirect_to(project_videos_path(project))
end
it "updates the video attributes" do
patch :update, params: { id: video, video: { name: "New Name" } }
expect(video.reload.name).to eq "New Name"
end
it "sets the flash" do
patch :update, params: { id: video, video: video_update_params }
expect(flash.notice).to eq t("videos.update.notice")
end
context "when params are invalid" do
it "re-renders the edit view" do
allow_any_instance_of(Video).to receive(:update).and_return(false)
patch :update, params: { id: video, video: video_update_params }
expect(response).to be_successful
end
end
context "with unpermitted file param" do
it "does not update the record" do
new_file = Rack::Test::UploadedFile.new file_fixture("video_file.mp4")
expect {
patch :update, params: { id: video, video: { name: "New Name", file: new_file } }
}.to raise_error ActionController::UnpermittedParameters
end
end
context "when edl_file changes" do
let(:new_edl_file) do
Rack::Test::UploadedFile.new file_fixture("sample-edl.edl"), "application/octet-stream"
end
it "delivers an admin notification" do
assert_enqueued_email_with AdminMailer, :updated_video_edl_file, args: video do
patch :update, params: { id: video, video: { edl_file: new_edl_file } }
end
end
it "unpublishes the video" do
video.publish_report!
patch :update, params: { id: video, video: { edl_file: new_edl_file } }
expect(video.reload).not_to be_report_published
end
end
context "when graphics_only_edl_file changes" do
let(:new_graphics_only_edl_file) do
Rack::Test::UploadedFile.new file_fixture("sample-edl.edl"), "application/octet-stream"
end
it "delivers an admin notification" do
assert_enqueued_email_with AdminMailer, :updated_video_graphics_only_edl_file, args: video do
patch :update, params: { id: video, video: { graphics_only_edl_file: new_graphics_only_edl_file } }
end
end
it "unpublishes the video" do
video.publish_report!
patch :update, params: { id: video, video: { graphics_only_edl_file: new_graphics_only_edl_file } }
expect(video.reload).not_to be_report_published
end
end
context "when audio_only_edl_file changes" do
let(:new_audio_only_edl_file) do
Rack::Test::UploadedFile.new file_fixture("sample-edl.edl"), "application/octet-stream"
end
it "delivers an admin notification" do
assert_enqueued_email_with AdminMailer, :updated_video_audio_only_edl_file, args: video do
patch :update, params: { id: video, video: { audio_only_edl_file: new_audio_only_edl_file } }
end
end
it "unpublishes the video" do
video.publish_report!
patch :update, params: { id: video, video: { audio_only_edl_file: new_audio_only_edl_file } }
expect(video.reload).not_to be_report_published
end
end
context "when edl_file and graphics_only_edl_file and audio_only_edl_file does not change" do
it "does not deliver an admin notification" do
assert_no_enqueued_emails do
patch :update, params: { id: video, video: { name: "New Name" } }
end
end
it "does not unpublish the video" do
video.publish_report!
patch :update, params: { id: video, video: { name: "New Name" } }
expect(video.reload).to be_report_published
end
end
end
private
def video_create_params(valid: true)
if valid
attributes_for(:video, :with_graphics_only_edl_file, :with_audio_only_edl_file, name: "Test Video", video_editing_system: "avid")
else
attributes_for(:video, :with_graphics_only_edl_file, :with_audio_only_edl_file, name: "Test Video").except(:file)
end
end
def video_update_params
attributes_for(:video, :with_graphics_only_edl_file, :with_audio_only_edl_file, name: "Test Video").except(:file)
end
end

View File

@@ -0,0 +1,31 @@
require 'rails_helper'
require 'zoom_gateway'
RSpec.describe ZoomMeetingsController, type: :controller do
let(:user) { create(:user) }
let(:account) { user.primary_account }
let(:project) { create(:project, account: user.primary_account) }
let(:broadcast) { create(:broadcast, name: "Broadcast", project: project) }
let(:meeting_start_url) { "http://meeting_start_url" }
let(:meeting_hash) { HashWithIndifferentAccess.new(start_url: meeting_start_url) }
let(:user_create_response) { {"id" => "new_host_id"} }
let(:roles_assign_response) { {"ids" => ["new_host_id"]} }
let(:roles_list_response) { {"roles" => [{"name" => "directme-host"}]} }
before :each do
allow_any_instance_of(ZoomGateway).to receive(:find_meeting).and_return(meeting_hash)
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")
allow(MuxLiveStream).to receive(:new).and_return OpenStruct.new(id: 'id', key: 'key', playback_id: 'playback_id')
end
describe "#show" do
before { sign_in user }
it "redirects to meeting start url" do
get :show, params: { project_id: project.id, broadcast_id: broadcast.id }
expect(response).to redirect_to(meeting_start_url)
end
end
end

View File

@@ -0,0 +1,82 @@
require "rails_helper"
RSpec.describe ZoomNotificationsController, type: :controller do
render_views
let!(:zoom_meeting) { create(:zoom_meeting, api_meeting_id: 'meeting_id') }
let(:started_status) { {event: 'meeting.started', payload: {object: {id: 'meeting_id' }}} }
let(:ended_status) { {event: 'meeting.ended', payload: {object: {id: 'meeting_id' }}} }
let(:wrong_meeting_id) { {payload: {object: {id: 'wrong_id' }}} }
let(:authorization_header) { {'Authorization' => 'xxx-xxx-xxx'} }
let(:wrong_authorization_header) { {'Authorization' => 'yyy-yyy-yyy'} }
before do
allow(ENV).to receive(:[]).with('ZOOM_VERIFICATION_TOKEN').and_return('xxx-xxx-xxx')
end
describe '#create' do
context 'with no authorization key' do
it 'raises 403 response' do
post :create, params: started_status
expect(response).to have_http_status(403)
end
end
context 'with wrong authorization key' do
it 'raises 403 response' do
request.headers.merge!(wrong_authorization_header)
post :create, params: started_status
expect(response).to have_http_status(403)
end
end
context 'authorized' do
before do
request.headers.merge!(authorization_header)
end
context 'with wrong meeting id' do
it 'raises RecordNotFound' do
expect {
post :create, params: wrong_meeting_id
}.to raise_error(ActiveRecord::RecordNotFound)
end
end
context 'with right meeting id' do
it 'responds with 200' do
post :create, params: started_status
expect(response).to have_http_status(200)
end
it 'assigns the zoom meeting' do
post :create, params: started_status
expect(assigns(:zoom_meeting)).to eq(zoom_meeting)
end
it 'updates the zoom_meeting when started status is received in notification' do
post :create, params: started_status
expect(zoom_meeting.reload).to be_started
end
it 'updates the zoom_meeting when ended status is received in notification' do
post :create, params: ended_status
expect(zoom_meeting.reload).to be_ended
end
it 'updates the recording when recording complete notification is received' do
expect {
post :create, params: recording_complete
}.to change { zoom_meeting.recording }
end
end
end
end
end