Compare commits
8 Commits
add-video-
...
validate-z
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cde81508b4 | ||
|
|
da8e187430 | ||
|
|
4c49a5db03 | ||
|
|
35303cb570 | ||
|
|
1127f09263 | ||
|
|
19b1e75384 | ||
|
|
93a4ce462d | ||
|
|
0e16791d8b |
@@ -17,7 +17,7 @@ class AccountsController < ApplicationController
|
|||||||
|
|
||||||
if sign_in(user)
|
if sign_in(user)
|
||||||
TrackAnalyticsJob.perform_later(user, user.primary_account, :track_guest_sign_up, user_agent: request.user_agent, user_ip: request.remote_ip)
|
TrackAnalyticsJob.perform_later(user, user.primary_account, :track_guest_sign_up, user_agent: request.user_agent, user_ip: request.remote_ip)
|
||||||
SubmitHubspotFormJob.perform_later(user.first_name, user.last_name, user.email, account.name, i_m_interested_in: user.interested_product_name)
|
SubmitHubspotFormJob.perform_later(first_name: user.first_name, last_name: user.last_name, email: user.email, company: account.name, i_m_interested_in: user.interested_product_name, form_guid: ENV["HUBSPOT_FORM_GUID"])
|
||||||
redirect_to signed_in_root_path
|
redirect_to signed_in_root_path
|
||||||
else
|
else
|
||||||
redirect_to new_session_path, alert: t(".notice")
|
redirect_to new_session_path, alert: t(".notice")
|
||||||
|
|||||||
61
app/controllers/admin/casting_call_interviews_controller.rb
Normal file
61
app/controllers/admin/casting_call_interviews_controller.rb
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
class Admin::CastingCallInterviewsController < Admin::ApplicationController
|
||||||
|
before_action :set_casting_call_interview, only: [:edit, :update, :show, :complete]
|
||||||
|
before_action :build_casting_call_interview, only: [:new, :create]
|
||||||
|
before_action :set_accounts, only: %i[new create edit]
|
||||||
|
|
||||||
|
def index
|
||||||
|
@casting_call_interviews = casting_call_interviews.order_by_recent.paginate(page: params[:page])
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@casting_call_interview.attributes = casting_call_interview_params
|
||||||
|
|
||||||
|
if @casting_call_interview.save
|
||||||
|
redirect_to [:admin, :casting_call_interviews], notice: t(".notice")
|
||||||
|
else
|
||||||
|
render :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @casting_call_interview.update(casting_call_interview_params)
|
||||||
|
redirect_to [:admin, :casting_call_interviews], notice: t(".notice")
|
||||||
|
else
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def complete
|
||||||
|
if @casting_call_interview.update(interviewed_at: Time.zone.now)
|
||||||
|
redirect_to [:admin, :casting_call_interviews], notice: t(".notice")
|
||||||
|
else
|
||||||
|
redirect_to [:admin, :casting_call_interviews], notice: t(".alert")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_accounts
|
||||||
|
@accounts = accounts
|
||||||
|
end
|
||||||
|
|
||||||
|
def casting_call_interview_params
|
||||||
|
params.require(:casting_call_interview).permit(:casting_call_id, :performer_name, :interview_date, :zoom_meeting_url)
|
||||||
|
end
|
||||||
|
|
||||||
|
def casting_call_interviews
|
||||||
|
policy_scope CastingCallInterview
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_casting_call_interview
|
||||||
|
@casting_call_interview = authorize policy_scope(CastingCallInterview).find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def accounts
|
||||||
|
policy_scope Account
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_casting_call_interview
|
||||||
|
@casting_call_interview = authorize policy_scope(CastingCallInterview).build
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -17,7 +17,9 @@ class Api::ApiController < ActionController::Base
|
|||||||
def return_error(exception)
|
def return_error(exception)
|
||||||
raise exception if Rails.env.test?
|
raise exception if Rails.env.test?
|
||||||
|
|
||||||
logger.error "==Handled======="
|
Raven.capture_exception(exception)
|
||||||
|
|
||||||
|
logger.error "==Handled======"
|
||||||
logger.error exception.message
|
logger.error exception.message
|
||||||
logger.error exception.backtrace.join("\n")
|
logger.error exception.backtrace.join("\n")
|
||||||
logger.error "==Handled======="
|
logger.error "==Handled======="
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ class Api::UserTokenController < Knock::AuthTokenController
|
|||||||
|
|
||||||
# Catch exception and return JSON-formatted error
|
# Catch exception and return JSON-formatted error
|
||||||
def return_error(exception)
|
def return_error(exception)
|
||||||
|
Raven.capture_exception(exception)
|
||||||
|
|
||||||
logger.error "==Handled======="
|
logger.error "==Handled======="
|
||||||
logger.error exception.message
|
logger.error exception.message
|
||||||
logger.error exception.backtrace.join("\n")
|
logger.error exception.backtrace.join("\n")
|
||||||
|
|||||||
28
app/controllers/casting_call_interviews_controller.rb
Normal file
28
app/controllers/casting_call_interviews_controller.rb
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
class CastingCallInterviewsController < ApplicationController
|
||||||
|
before_action :set_project
|
||||||
|
before_action :set_casting_call_interview, only: [:show]
|
||||||
|
|
||||||
|
include ProjectLayout
|
||||||
|
|
||||||
|
def index
|
||||||
|
@casting_call_interviews = casting_call_interviews.completed.order_by_recent.paginate(page: params[:page])
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@files = @casting_call_interview.files.paginate(page: params[:page])
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_project
|
||||||
|
@project = policy_scope(Project).find(params[:project_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_casting_call_interview
|
||||||
|
@casting_call_interview = authorize casting_call_interviews.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def casting_call_interviews
|
||||||
|
authorize policy_scope(CastingCallInterview)
|
||||||
|
end
|
||||||
|
end
|
||||||
76
app/controllers/casting_calls_controller.rb
Normal file
76
app/controllers/casting_calls_controller.rb
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
class CastingCallsController < ApplicationController
|
||||||
|
layout "project"
|
||||||
|
|
||||||
|
before_action :set_project
|
||||||
|
before_action :build_casting_call, only: [:new, :create]
|
||||||
|
before_action :set_casting_call, only: [:show, :edit, :update, :cancel]
|
||||||
|
|
||||||
|
def index
|
||||||
|
@casting_calls = casting_calls.order_by_recent.paginate(page: params[:page])
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@casting_call.attributes = casting_call_params_with_email
|
||||||
|
|
||||||
|
if @casting_call.save
|
||||||
|
log_create_analytics
|
||||||
|
castme_url = url_for([@project, @casting_call])
|
||||||
|
SubmitHubspotFormJob.perform_later(email: @casting_call.user_email, castme_url: castme_url, form_guid: ENV["HUBSPOT_CASTING_CALL_REQUEST_FORM_GUID"])
|
||||||
|
else
|
||||||
|
render :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
render layout: 'application'
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @casting_call.update(casting_call_params)
|
||||||
|
redirect_to [@project, :casting_calls], notice: t(".notice")
|
||||||
|
else
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def cancel
|
||||||
|
@casting_call.update(cancelled_at: Time.zone.now)
|
||||||
|
redirect_to [@project, :casting_calls], notice: t(".notice")
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def casting_call_params
|
||||||
|
params.require(:casting_call).permit(:title, :description, :project_description, :interview_instructions, :interview_requirements, :questions)
|
||||||
|
end
|
||||||
|
|
||||||
|
def casting_call_params_with_email
|
||||||
|
casting_call_params.merge(user_email: Current.user.email)
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_project
|
||||||
|
@project = policy_scope(Project).find(params[:project_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_casting_call
|
||||||
|
@casting_call = authorize casting_calls.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def casting_calls
|
||||||
|
authorize policy_scope(@project.casting_calls)
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_casting_call
|
||||||
|
@casting_call = authorize @project.casting_calls.build
|
||||||
|
end
|
||||||
|
|
||||||
|
def log_create_analytics
|
||||||
|
TrackAnalyticsJob.perform_later(Current.user, Current.account, :track_create_casting_call, user_agent: request.user_agent, user_ip: request.remote_ip)
|
||||||
|
end
|
||||||
|
end
|
||||||
30
app/controllers/interview_downloads_controller.rb
Normal file
30
app/controllers/interview_downloads_controller.rb
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
class InterviewDownloadsController < ApplicationController
|
||||||
|
include ProjectContext
|
||||||
|
|
||||||
|
before_action :set_project, only: [:create]
|
||||||
|
before_action :set_casting_call_interview, only: :create
|
||||||
|
|
||||||
|
include ProjectLayout
|
||||||
|
|
||||||
|
def create
|
||||||
|
download = @project.downloads.create!(name: @casting_call_interview.zip_file_name, release_type: "CastingCallInterview")
|
||||||
|
|
||||||
|
other_downloads_in_progress = @project.downloads.unfinished_desc_order.offset(1)
|
||||||
|
|
||||||
|
if other_downloads_in_progress.any?
|
||||||
|
in_progress_downloads_details = render_to_string "_other_pending_downloads", locals: { downloads: other_downloads_in_progress, release_type: "CastingCallInterview" }, :layout => false
|
||||||
|
ProjectsChannel.broadcast_download_generation_update(download, in_progress_downloads_details)
|
||||||
|
else
|
||||||
|
ProjectsChannel.broadcast_download_generation_update(download, I18n.t("interview_downloads.download.pending", release_type: "Casting Call Interview"))
|
||||||
|
end
|
||||||
|
|
||||||
|
GenerateInterviewFilesZipJob.perform_later(@project, download, @casting_call_interview)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_casting_call_interview
|
||||||
|
authorize(Download)
|
||||||
|
@casting_call_interview = policy_scope(@project.casting_call_interviews).find(params[:casting_call_interview_id])
|
||||||
|
end
|
||||||
|
end
|
||||||
25
app/controllers/public/casting_call_interviews_controller.rb
Normal file
25
app/controllers/public/casting_call_interviews_controller.rb
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
class Public::CastingCallInterviewsController < Public::BaseController
|
||||||
|
skip_after_action :verify_authorized
|
||||||
|
before_action :set_casting_call_interview, only: [:show, :update]
|
||||||
|
|
||||||
|
def show
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @casting_call_interview.update(casting_call_interview_params)
|
||||||
|
redirect_to casting_call_interview_url(token: @casting_call_interview.token), notice: t(".notice")
|
||||||
|
else
|
||||||
|
render :show
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_casting_call_interview
|
||||||
|
@casting_call_interview = CastingCallInterview.find_by_token(params[:token])
|
||||||
|
end
|
||||||
|
|
||||||
|
def casting_call_interview_params
|
||||||
|
params.require(:casting_call_interview).permit(files: [])
|
||||||
|
end
|
||||||
|
end
|
||||||
14
app/controllers/public/casting_calls_controller.rb
Normal file
14
app/controllers/public/casting_calls_controller.rb
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
class Public::CastingCallsController < Public::BaseController
|
||||||
|
skip_after_action :verify_authorized
|
||||||
|
before_action :set_casting_call, only: [:show]
|
||||||
|
|
||||||
|
def show
|
||||||
|
render layout: 'application'
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_casting_call
|
||||||
|
@casting_call = CastingCall.find_by_token(params[:token])
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -19,7 +19,7 @@ class TaskRequestsController < ApplicationController
|
|||||||
if @task_request.save
|
if @task_request.save
|
||||||
log_create_analytics
|
log_create_analytics
|
||||||
taskme_url = url_for([:admin, @task_request])
|
taskme_url = url_for([:admin, @task_request])
|
||||||
SubmitHubspotTaskRequestFormJob.perform_later(@task_request.user_email, taskme_url)
|
SubmitHubspotFormJob.perform_later(email: @task_request.user_email, taskme_url: taskme_url, form_guid: ENV["HUBSPOT_TASK_REQUEST_FORM_GUID"])
|
||||||
else
|
else
|
||||||
render :new
|
render :new
|
||||||
end
|
end
|
||||||
|
|||||||
43
app/jobs/generate_interview_files_zip_job.rb
Normal file
43
app/jobs/generate_interview_files_zip_job.rb
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
class GenerateInterviewFilesZipJob < ApplicationJob
|
||||||
|
queue_as :default
|
||||||
|
include Rails.application.routes.url_helpers
|
||||||
|
include ActionView::Helpers::UrlHelper
|
||||||
|
|
||||||
|
before_perform do |job|
|
||||||
|
@project = job.arguments.first
|
||||||
|
@download = job.arguments.second
|
||||||
|
@casting_call_interview = job.arguments.third
|
||||||
|
@download.update!(status: :pending)
|
||||||
|
end
|
||||||
|
|
||||||
|
def perform(project, download, casting_call_interview)
|
||||||
|
::InterviewFilesCollectionService.new(casting_call_interview.files, @download.name).build do |dir, files|
|
||||||
|
zipfile_name = "#{dir}/#{@download.name}.zip"
|
||||||
|
Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
|
||||||
|
files.each do |attachment|
|
||||||
|
zipfile.add(attachment, File.join("#{dir}/", attachment))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@download.file.attach(io: File.open(zipfile_name), filename: @download.name)
|
||||||
|
end
|
||||||
|
rescue StandardError => e
|
||||||
|
Raven.extra_context(
|
||||||
|
message: "Failed to generate download for project (##{project.id})",
|
||||||
|
release_type: "CastingCallInterview"
|
||||||
|
)
|
||||||
|
|
||||||
|
@download.failure!
|
||||||
|
ProjectsChannel.broadcast_download_generation_update(@download, I18n.t("interview_downloads.download.failure"))
|
||||||
|
end
|
||||||
|
|
||||||
|
after_perform do |job|
|
||||||
|
if @download.pending? && @download.file.attached?
|
||||||
|
@download.success!
|
||||||
|
|
||||||
|
downloads_folder_link = link_to("Files > Downloads", project_downloads_path(I18n.locale, @project))
|
||||||
|
download_button = link_to("Download", rails_blob_path(@download.file, disposition: "attachment", only_path: true), class: "btn btn-success", target: :_blank)
|
||||||
|
ProjectsChannel.broadcast_download_generation_update(@download, I18n.t("interview_downloads.download.success", downloads_folder_link: downloads_folder_link, download_button: download_button, release_type: "Casting Call Interview"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,19 +1,11 @@
|
|||||||
class SubmitHubspotFormJob < ApplicationJob
|
class SubmitHubspotFormJob < ApplicationJob
|
||||||
queue_as :default
|
queue_as :default
|
||||||
|
|
||||||
def perform(first_name, last_name, email, company_name, additional_params = {})
|
def perform(params = {})
|
||||||
hubspot_form_guid = ENV["HUBSPOT_FORM_GUID"]
|
return unless params[:form_guid].present?
|
||||||
return unless hubspot_form_guid.present?
|
|
||||||
|
|
||||||
submission_params = {
|
form = Hubspot::Form.new("guid" => params[:form_guid])
|
||||||
first_name: first_name,
|
is_form_sumitted = form.submit(params.except(:form_guid))
|
||||||
last_name: last_name,
|
|
||||||
email: email,
|
|
||||||
company: company_name
|
|
||||||
}.merge(additional_params)
|
|
||||||
|
|
||||||
form = Hubspot::Form.new("guid" => hubspot_form_guid)
|
|
||||||
is_form_sumitted = form.submit(submission_params)
|
|
||||||
|
|
||||||
raise StandardError.new "Failed to submit the hubspot form data: #{is_form_sumitted}" unless is_form_sumitted
|
raise StandardError.new "Failed to submit the hubspot form data: #{is_form_sumitted}" unless is_form_sumitted
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
class SubmitHubspotTaskRequestFormJob < ApplicationJob
|
|
||||||
queue_as :default
|
|
||||||
|
|
||||||
def perform(user_email, taskme_url)
|
|
||||||
hubspot_task_request_form_guid = ENV["HUBSPOT_TASK_REQUEST_FORM_GUID"]
|
|
||||||
return unless hubspot_task_request_form_guid.present?
|
|
||||||
|
|
||||||
submission_params = {
|
|
||||||
email: user_email,
|
|
||||||
taskme_url: taskme_url
|
|
||||||
}
|
|
||||||
|
|
||||||
form = Hubspot::Form.new("guid" => hubspot_task_request_form_guid)
|
|
||||||
is_form_sumitted = form.submit(submission_params)
|
|
||||||
|
|
||||||
raise StandardError.new "Failed to submit the task request hubspot form data: #{is_form_sumitted}" unless is_form_sumitted
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -4,6 +4,8 @@ class Account < ApplicationRecord
|
|||||||
has_many :account_auths
|
has_many :account_auths
|
||||||
has_many :users, through: :account_auths
|
has_many :users, through: :account_auths
|
||||||
has_many :projects, dependent: :destroy
|
has_many :projects, dependent: :destroy
|
||||||
|
has_many :casting_calls, through: :projects
|
||||||
|
has_many :casting_call_interviews, through: :projects
|
||||||
has_many :videos, through: :projects
|
has_many :videos, through: :projects
|
||||||
has_many :contract_templates, through: :projects
|
has_many :contract_templates, through: :projects
|
||||||
|
|
||||||
@@ -59,6 +61,8 @@ class Account < ApplicationRecord
|
|||||||
MedicalRelease.where(project: projects),
|
MedicalRelease.where(project: projects),
|
||||||
MiscRelease.where(project: projects),
|
MiscRelease.where(project: projects),
|
||||||
MatchingRequest.where(project: projects),
|
MatchingRequest.where(project: projects),
|
||||||
|
CastingCall.where(project: projects),
|
||||||
|
self.casting_call_interviews,
|
||||||
self
|
self
|
||||||
])).sum(:byte_size).to_f
|
])).sum(:byte_size).to_f
|
||||||
end
|
end
|
||||||
@@ -87,6 +91,10 @@ class Account < ApplicationRecord
|
|||||||
ENV["TASKME_ENABLED"] && (plan_uid.to_s == "me_suite" || plan_uid.to_s == "taskme")
|
ENV["TASKME_ENABLED"] && (plan_uid.to_s == "me_suite" || plan_uid.to_s == "taskme")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def castme_enabled?
|
||||||
|
plan_uid.to_s == "me_suite" || plan_uid.to_s == "castme"
|
||||||
|
end
|
||||||
|
|
||||||
def plan_name
|
def plan_name
|
||||||
case plan_uid.to_s
|
case plan_uid.to_s
|
||||||
when "deliverme"
|
when "deliverme"
|
||||||
@@ -97,6 +105,8 @@ class Account < ApplicationRecord
|
|||||||
"ReleaseME"
|
"ReleaseME"
|
||||||
when "taskme"
|
when "taskme"
|
||||||
"TaskME"
|
"TaskME"
|
||||||
|
when "castme"
|
||||||
|
"CastME"
|
||||||
when "me_suite"
|
when "me_suite"
|
||||||
"ME Suite"
|
"ME Suite"
|
||||||
end
|
end
|
||||||
|
|||||||
18
app/models/casting_call.rb
Normal file
18
app/models/casting_call.rb
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
class CastingCall < ApplicationRecord
|
||||||
|
belongs_to :project
|
||||||
|
has_many :casting_call_interviews, dependent: :destroy
|
||||||
|
|
||||||
|
has_secure_token
|
||||||
|
|
||||||
|
def status
|
||||||
|
if cancelled?
|
||||||
|
"Cancelled"
|
||||||
|
else
|
||||||
|
"Active"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def cancelled?
|
||||||
|
self.cancelled_at.present?
|
||||||
|
end
|
||||||
|
end
|
||||||
38
app/models/casting_call_interview.rb
Normal file
38
app/models/casting_call_interview.rb
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
class CastingCallInterview < ApplicationRecord
|
||||||
|
belongs_to :casting_call
|
||||||
|
has_many_attached :files
|
||||||
|
|
||||||
|
has_secure_token
|
||||||
|
|
||||||
|
validates :performer_name, presence: true
|
||||||
|
validate :zoom_meeting_url_validation
|
||||||
|
|
||||||
|
scope :completed, -> { where.not(interviewed_at: nil) }
|
||||||
|
|
||||||
|
def join_zoom_meeting_url
|
||||||
|
uri = URI.parse(self.zoom_meeting_url)
|
||||||
|
zoom_meeting_id = uri.path.gsub("/j/", "")
|
||||||
|
zoom_meeting_pwd = uri.query.gsub("pwd=", "")
|
||||||
|
|
||||||
|
"zoommtg://zoom.us/join?confno=#{zoom_meeting_id}&pwd=#{zoom_meeting_pwd}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def zip_file_name
|
||||||
|
"#{self.casting_call.title.parameterize}_#{self.performer_name.parameterize}_#{Time.now.strftime('%Y-%m-%d_%H-%M-%S')}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def zoom_meeting_url_validation
|
||||||
|
# valid url format :
|
||||||
|
# https://us01web.zoom.us/j/12345?pwd=Ab103odw3ok343ko
|
||||||
|
valid_url_regex = %r{^https\://[a-z0-9]+\.zoom.us/j/[0-9]+\?pwd\=.+}
|
||||||
|
return true if zoom_meeting_url.match valid_url_regex
|
||||||
|
|
||||||
|
errors.add(:base, invalid_meeting_url_message)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def invalid_meeting_url_message
|
||||||
|
I18n.t('casting_call_interviews.validation_errors.invalid_meeting_url')
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -15,6 +15,8 @@ class Project < ApplicationRecord
|
|||||||
has_many :talent_releases, dependent: :destroy
|
has_many :talent_releases, dependent: :destroy
|
||||||
has_many :medical_releases, dependent: :destroy
|
has_many :medical_releases, dependent: :destroy
|
||||||
has_many :misc_releases, dependent: :destroy
|
has_many :misc_releases, dependent: :destroy
|
||||||
|
has_many :casting_calls, dependent: :destroy
|
||||||
|
has_many :casting_call_interviews, through: :casting_calls
|
||||||
has_many :videos, dependent: :destroy
|
has_many :videos, dependent: :destroy
|
||||||
has_many :imports, dependent: :destroy
|
has_many :imports, dependent: :destroy
|
||||||
has_many :contract_templates, dependent: :destroy
|
has_many :contract_templates, dependent: :destroy
|
||||||
|
|||||||
29
app/policies/casting_call_interview_policy.rb
Normal file
29
app/policies/casting_call_interview_policy.rb
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
class CastingCallInterviewPolicy < ApplicationPolicy
|
||||||
|
def index?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def show?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def create?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def update?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def complete?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def download?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
25
app/policies/casting_call_policy.rb
Normal file
25
app/policies/casting_call_policy.rb
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
class CastingCallPolicy < ApplicationPolicy
|
||||||
|
def index?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def show?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def create?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def update?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def cancel?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -40,4 +40,8 @@ class ProjectPolicy < ApplicationPolicy
|
|||||||
def show_task_results?
|
def show_task_results?
|
||||||
show?
|
show?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def show_casting_call_interview_results?
|
||||||
|
show?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
24
app/services/interview_files_collection_service.rb
Normal file
24
app/services/interview_files_collection_service.rb
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
class InterviewFilesCollectionService
|
||||||
|
def initialize(files, folder_name)
|
||||||
|
@files = files
|
||||||
|
@folder_name = folder_name
|
||||||
|
end
|
||||||
|
|
||||||
|
def build
|
||||||
|
Dir.mktmpdir { |dir|
|
||||||
|
files.each do |file|
|
||||||
|
open("#{dir}/#{file.filename}", 'wb') do |tmp_file|
|
||||||
|
tmp_file << open(file.service_url.to_s).read
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
read_files = Dir.entries("#{dir}/").select { |f| !File.directory? f }
|
||||||
|
raise StandardError.new "Files not found." unless read_files.any?
|
||||||
|
yield(dir, read_files)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
attr_reader :files, :folder_name
|
||||||
|
end
|
||||||
@@ -170,6 +170,24 @@ class Analytics
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def track_create_casting_call(user_agent:, user_ip:)
|
||||||
|
if analytics_enabled?
|
||||||
|
identify
|
||||||
|
track(
|
||||||
|
{
|
||||||
|
user_id: user.id,
|
||||||
|
event: "Casting call created",
|
||||||
|
properties: {
|
||||||
|
account: account.try(:name),
|
||||||
|
account_id: account.try(:id),
|
||||||
|
user_agent: user_agent,
|
||||||
|
ip: user_ip,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
attr_reader :user, :account, :backend
|
attr_reader :user, :account, :backend
|
||||||
|
|||||||
@@ -10,6 +10,9 @@
|
|||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<%= link_to fa_icon("tasks fw", text: "Task Requests"), [:admin, :task_requests], class: class_string("nav-link", "active" => controller_name == "task_requests") %>
|
<%= link_to fa_icon("tasks fw", text: "Task Requests"), [:admin, :task_requests], class: class_string("nav-link", "active" => controller_name == "task_requests") %>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<%= link_to fa_icon("video-camera fw", text: "Casting Call Interviews"), [:admin, :casting_call_interviews], class: class_string("nav-link", "active" => controller_name == "casting_call_interviews") %>
|
||||||
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<%= link_to fa_icon("bug fw", text: "Errors"), "https://sentry.io/bigmedia/", class: "nav-link", target: :_blank %>
|
<%= link_to fa_icon("bug fw", text: "Errors"), "https://sentry.io/bigmedia/", class: "nav-link", target: :_blank %>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<tr id="<%= dom_id(casting_call_interview) %>">
|
||||||
|
<td>
|
||||||
|
<%= casting_call_interview.casting_call.project.account.name.titleize %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= casting_call_interview.casting_call.title.titleize %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= casting_call_interview.performer_name %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= casting_call_interview.interview_date %>
|
||||||
|
</td>
|
||||||
|
<td class="text-right">
|
||||||
|
<div class="btn-group">
|
||||||
|
<%= button_tag "Manage", class: "btn btn-light btn-sm dropdown-toggle border", data: { toggle: "dropdown", boundary: "window" }, aria: { haspopup: true, expanded: false } %>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right">
|
||||||
|
<%= link_to fa_icon("video-camera", text: "View"), casting_call_interview_url(token: casting_call_interview.token), target: "_blank", class: "dropdown-item" %>
|
||||||
|
<%= link_to fa_icon("pencil", text: "Edit"), [:edit, :admin, casting_call_interview], class: "dropdown-item" %>
|
||||||
|
<% unless casting_call_interview.interviewed_at.present? %>
|
||||||
|
<%= link_to fa_icon("check", text: "Complete"), [:complete, :admin, casting_call_interview], method: :post, class: "dropdown-item" %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
15
app/views/admin/casting_call_interviews/_form.html.erb
Normal file
15
app/views/admin/casting_call_interviews/_form.html.erb
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<%= errors_summary_for casting_call_interview %>
|
||||||
|
|
||||||
|
<%= bootstrap_form_with model: model, local: true do |form| %>
|
||||||
|
<%= form.text_field :performer_name, required: true %>
|
||||||
|
<%= form.grouped_collection_select(:casting_call_id, @accounts, :casting_calls, :name, :id, :title, { prompt: "Select a Casting Call", required: true, class: "form-control custom-select" }) %>
|
||||||
|
<%= form.text_field :interview_date, class: "datepicker-control" %>
|
||||||
|
<%= form.text_field :zoom_meeting_url %>
|
||||||
|
|
||||||
|
<div class="row align-items-center text-center mt-4">
|
||||||
|
<%= link_to t("shared.cancel"), [:admin, :casting_call_interviews], class: "col-3 text-reset" %>
|
||||||
|
<div class="col-9">
|
||||||
|
<%= form.submit class: class_string("btn btn-block", ["btn-success", "btn-primary"] => casting_call_interview.new_record?), data: { disable_with: t("shared.disable_with") } %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
6
app/views/admin/casting_call_interviews/edit.html.erb
Normal file
6
app/views/admin/casting_call_interviews/edit.html.erb
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<div class="card shadow-sm">
|
||||||
|
<%= card_header text: "Edit Casting Call Interview", close_action_path: [:admin, :casting_call_interviews] %>
|
||||||
|
<div class="card-body">
|
||||||
|
<%= render "form", model: [:admin, @casting_call_interview], casting_call_interview: @casting_call_interview %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
32
app/views/admin/casting_call_interviews/index.html.erb
Normal file
32
app/views/admin/casting_call_interviews/index.html.erb
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<div class="d-flex flex-row justify-content-between align-items-center mb-3">
|
||||||
|
<% if policy(CastingCall).new? %>
|
||||||
|
<%= link_to fa_icon("plus", text: t(".actions.new")), [:new, :admin, :casting_call_interview], class: "btn btn-primary mb-3" %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="border bg-white rounded shadow-sm pb-3 table-responsive">
|
||||||
|
<table class="table table-striped tr-px-4 align-all-middle">
|
||||||
|
<thead class="thead-light">
|
||||||
|
<tr>
|
||||||
|
<th>Account Name</th>
|
||||||
|
<th>Casting Call Request</th>
|
||||||
|
<th>Perfomer's Name</th>
|
||||||
|
<th>Interview Date</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="users">
|
||||||
|
<% if @casting_call_interviews.any? %>
|
||||||
|
<%= render @casting_call_interviews %>
|
||||||
|
<% else %>
|
||||||
|
<tr>
|
||||||
|
<td colspan="20" class="py-4 text-center text-muted"><%= t(".empty") %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="casting_call_interviews_pagination" class="mt-3">
|
||||||
|
<%= will_paginate @casting_call_interviews %>
|
||||||
|
</div>
|
||||||
6
app/views/admin/casting_call_interviews/new.html.erb
Normal file
6
app/views/admin/casting_call_interviews/new.html.erb
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<div class="card shadow-sm">
|
||||||
|
<%= card_header text: t(".heading"), close_action_path: [:admin, :casting_call_interviews] %>
|
||||||
|
<div class="card-body">
|
||||||
|
<%= render "form", model: [:admin, @casting_call_interview], casting_call_interview: @casting_call_interview, casting_calls: @casting_calls %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -43,6 +43,12 @@
|
|||||||
<%= product_wordmark :deliver_me, class: class_string("d-inline-block", "disabled" => !Current.account.deliverme_enabled?) %>
|
<%= product_wordmark :deliver_me, class: class_string("d-inline-block", "disabled" => !Current.account.deliverme_enabled?) %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<%= link_to [project, :casting_calls], class: class_string("nav-link", "active" => controller_name == "casting_calls") do %>
|
||||||
|
<%= lock_icon_for(Current.account, :castme) %>
|
||||||
|
<%= product_wordmark :cast_me, class: class_string("d-inline-block", "disabled" => !Current.account.castme_enabled?) %>
|
||||||
|
<% end %>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
<hr class="divider-light mx-n4">
|
<hr class="divider-light mx-n4">
|
||||||
|
|||||||
@@ -18,15 +18,7 @@
|
|||||||
<div class="card-body p-0">
|
<div class="card-body p-0">
|
||||||
<div class="embed-responsive embed-responsive-16by9">
|
<div class="embed-responsive embed-responsive-16by9">
|
||||||
<div class="embed-responsive-item">
|
<div class="embed-responsive-item">
|
||||||
<table class="w-100 h-100 bg-secondary">
|
<iframe src="https://player.vimeo.com/video/435200320?app_id=122963" width="426" height="240" frameborder="0" allow="autoplay; fullscreen" allowfullscreen title="DirectME_How to_V5"></iframe>
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td class="text-center align-middle text-white">
|
|
||||||
Video tutorial will be available soon
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<tr id="<%= dom_id(casting_call_interview) %>">
|
||||||
|
<td>
|
||||||
|
<%= casting_call_interview.casting_call.project.account.name.titleize %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= casting_call_interview.casting_call.title&.titleize %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= casting_call_interview.performer_name %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= casting_call_interview.interviewed_at %>
|
||||||
|
</td>
|
||||||
|
<td class="text-right">
|
||||||
|
<div class="btn-group">
|
||||||
|
<%= button_tag "Manage", class: "btn btn-light btn-sm dropdown-toggle border", data: { toggle: "dropdown", boundary: "window" }, aria: { haspopup: true, expanded: false } %>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right">
|
||||||
|
<% if policy(CastingCallInterview).show? %>
|
||||||
|
<%= link_to fa_icon("video-camera", text: "View"), [@project, casting_call_interview], target: "_blank", class: "dropdown-item" %>
|
||||||
|
<% end %>
|
||||||
|
<% if policy(CastingCallInterview).download? %>
|
||||||
|
<%= link_to fa_icon("download", text: "Download"), [@project, :interview_downloads, casting_call_interview_id: casting_call_interview.id], method: :post, remote: true, class: "dropdown-item" %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
6
app/views/casting_call_interviews/_file.html.erb
Normal file
6
app/views/casting_call_interviews/_file.html.erb
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<tr>
|
||||||
|
<td><%= file.filename %></td>
|
||||||
|
<td class="text-right">
|
||||||
|
<%= link_to fa_icon("download"), file, target: "_blank" %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
26
app/views/casting_call_interviews/index.html.erb
Normal file
26
app/views/casting_call_interviews/index.html.erb
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<div class="border bg-white rounded shadow-sm pb-3 table-responsive">
|
||||||
|
<table class="table table-striped tr-px-4 align-all-middle">
|
||||||
|
<thead class="thead-light">
|
||||||
|
<tr>
|
||||||
|
<th>Account Name</th>
|
||||||
|
<th>Casting Call Request</th>
|
||||||
|
<th>Perfomer's Name</th>
|
||||||
|
<th>Interviewed At</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="users">
|
||||||
|
<% if @casting_call_interviews.any? %>
|
||||||
|
<%= render @casting_call_interviews %>
|
||||||
|
<% else %>
|
||||||
|
<tr>
|
||||||
|
<td colspan="20" class="py-4 text-center text-muted"><%= t(".empty") %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="casting_call_interviews_pagination" class="mt-3">
|
||||||
|
<%= will_paginate @casting_call_interviews %>
|
||||||
|
</div>
|
||||||
25
app/views/casting_call_interviews/show.html.erb
Normal file
25
app/views/casting_call_interviews/show.html.erb
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<div class="col-md-12">
|
||||||
|
<h2 class="h6 mt-3">Files:</h2>
|
||||||
|
<div class="pt-2 mx-n3">
|
||||||
|
<table class="table table-striped tr-px-4 align-all-middle">
|
||||||
|
<thead class="thead-light">
|
||||||
|
<tr>
|
||||||
|
<th>Filename</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="task_requests">
|
||||||
|
<% if @files.any? %>
|
||||||
|
<%= render partial: "file", collection: @files %>
|
||||||
|
<% else %>
|
||||||
|
<tr>
|
||||||
|
<td colspan="12" class="py-4 text-center text-muted"><%= t(".empty") %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="mt-4" id="task_requests_pagiantion">
|
||||||
|
<%= will_paginate @files %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
28
app/views/casting_calls/_casting_call.html.erb
Normal file
28
app/views/casting_calls/_casting_call.html.erb
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<%= casting_call.created_at.strftime('%D') %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= casting_call.title %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= casting_call.status %>
|
||||||
|
</td>
|
||||||
|
<td class="text-right">
|
||||||
|
<div class="btn-group">
|
||||||
|
<%= button_tag t(".actions.manage"), class: "btn btn-light btn-sm dropdown-toggle border", data: { toggle: "dropdown", boundary: "window" }, aria: { haspopup: true, expanded: false } %>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right">
|
||||||
|
<%= link_to fa_icon("link fw", text: "Copy Audition URL"), casting_call_url(casting_call.token), class: "dropdown-item", data: { behavior: "clipboard" } %>
|
||||||
|
<% if policy(casting_call).show? %>
|
||||||
|
<%= link_to fa_icon("tasks fw", text: "View"), [casting_call.project, casting_call], class: "dropdown-item", target: '_blank' %>
|
||||||
|
<% end %>
|
||||||
|
<% if policy(casting_call).edit? %>
|
||||||
|
<%= link_to fa_icon("pencil fw", text: "Edit"), [:edit, casting_call.project, casting_call], class: "dropdown-item" %>
|
||||||
|
<% end %>
|
||||||
|
<% if policy(casting_call).cancel? && !casting_call.cancelled? %>
|
||||||
|
<%= link_to fa_icon("ban fw", text: "Cancel"), [:cancel, casting_call.project, casting_call], class: "dropdown-item", method: :post %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
22
app/views/casting_calls/_form.html.erb
Normal file
22
app/views/casting_calls/_form.html.erb
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<%= errors_summary_for casting_call %>
|
||||||
|
|
||||||
|
<%= bootstrap_form_with model: model, url: [@project, @casting_call, show_chat: true], local: true do |form| %>
|
||||||
|
<div class="alert alert-info text-center text-md-left">
|
||||||
|
<%= fa_icon "info-circle" %>
|
||||||
|
<strong><%= t '.info_message' %></strong>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%= form.text_field :title, label: t('.labels.title') %>
|
||||||
|
<%= form.text_area :description, label: t('.labels.description') %>
|
||||||
|
<%= form.text_area :project_description, label: t('.labels.project_description') %>
|
||||||
|
<%= form.text_area :interview_instructions, label: t('.labels.interview_instructions') %>
|
||||||
|
<%= form.text_area :interview_requirements, label: t('.labels.interview_requirements') %>
|
||||||
|
<%= form.text_area :questions, label: t('.labels.questions') %>
|
||||||
|
|
||||||
|
<div class="row align-items-center text-center mt-4">
|
||||||
|
<%= link_to t("shared.cancel"), [project, :casting_calls], class: "col-3 text-reset" %>
|
||||||
|
<div class="col-9">
|
||||||
|
<%= form.submit class: class_string("btn btn-block", ["btn-success", "btn-primary"] => casting_call.new_record?), data: { disable_with: t("shared.disable_with") } %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
2
app/views/casting_calls/create.html.erb
Normal file
2
app/views/casting_calls/create.html.erb
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<%= render "shared/initiate_hubspot_chat" %>
|
||||||
|
<p class="alert alert-success p-3 lead text-center"><%= t '.success_message' %></p>
|
||||||
6
app/views/casting_calls/edit.html.erb
Normal file
6
app/views/casting_calls/edit.html.erb
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<div class="card shadow-sm">
|
||||||
|
<%= card_header text: t(".heading"), close_action_path: [@project, :casting_calls] %>
|
||||||
|
<div class="card-body">
|
||||||
|
<%= render "form", model: [@project, @casting_call], casting_call: @casting_call, project: @project %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
37
app/views/casting_calls/index.html.erb
Normal file
37
app/views/casting_calls/index.html.erb
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<%= product_wordmark :cast_me, class: "small mb-3" %>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="d-md-flex d-sm-flex flex-sm-column flex-md-row flex-md-wrap mb-3">
|
||||||
|
<% if policy(CastingCall).new? %>
|
||||||
|
<%= link_to fa_icon("plus", text: t(".actions.new")), [:new, @project, :casting_call], class: "btn btn-primary mb-2" %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="border bg-white rounded shadow-sm pb-3 table-responsive">
|
||||||
|
<table class="table table-striped tr-px-4 align-all-middle">
|
||||||
|
<thead class="thead-light">
|
||||||
|
<tr>
|
||||||
|
<th><%= t(".table_headers.casting_call_created_on") %></th>
|
||||||
|
<th><%= t(".table_headers.casting_call_title") %></th>
|
||||||
|
<th><%= t(".table_headers.casting_call_status") %></th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="casting_calls">
|
||||||
|
<% if @casting_calls.any? %>
|
||||||
|
<%= render @casting_calls %>
|
||||||
|
<% else %>
|
||||||
|
<tr>
|
||||||
|
<td colspan="20" class="py-4 text-center text-muted"><%= t(".empty") %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="casting_calls_pagination" class="mt-3">
|
||||||
|
<%= will_paginate @casting_calls %>
|
||||||
|
</div>
|
||||||
6
app/views/casting_calls/new.html.erb
Normal file
6
app/views/casting_calls/new.html.erb
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<div class="card shadow-sm">
|
||||||
|
<%= card_header text: t(".heading"), close_action_path: [@project, :casting_calls] %>
|
||||||
|
<div class="card-body">
|
||||||
|
<%= render "form", model: [@project, @casting_call], casting_call: @casting_call, project: @project %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
38
app/views/casting_calls/show.html.erb
Normal file
38
app/views/casting_calls/show.html.erb
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<% content_for :header do %>
|
||||||
|
<header class="container-fluid py-3 border-bottom sticky-top bg-light">
|
||||||
|
<div class="row align-items-center justify-content-center">
|
||||||
|
<div class="col-4 text-center">
|
||||||
|
<%= product_wordmark(:cast_me, class: 'navbar-brand') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="card shadow-sm">
|
||||||
|
<%= card_header text: @casting_call.title, close_action_path: [@project, :casting_calls] %>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 col-sm-12">
|
||||||
|
<dl>
|
||||||
|
<%= description_list_pair_for @casting_call, :title, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :description, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :project_description, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :created_at, append: ":" %>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-sm-12">
|
||||||
|
<dl>
|
||||||
|
<%= description_list_pair_for @casting_call, :status, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :interview_instructions, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :interview_requirements, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :questions, append: ":" %>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% unless @casting_call.cancelled? %>
|
||||||
|
<div class="row align-items-center justify-content-center mt-3">
|
||||||
|
<%= link_to "Schedule an Audition", ENV["CASTME_AUDITION_BOOKING_URL"], target: "_blank", class: "btn btn-primary" %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -18,15 +18,7 @@
|
|||||||
<div class="card-body p-0">
|
<div class="card-body p-0">
|
||||||
<div class="embed-responsive embed-responsive-16by9">
|
<div class="embed-responsive embed-responsive-16by9">
|
||||||
<div class="embed-responsive-item">
|
<div class="embed-responsive-item">
|
||||||
<table class="w-100 h-100 bg-secondary">
|
<iframe src="https://player.vimeo.com/video/435200486?app_id=122963" width="426" height="240" frameborder="0" allow="autoplay; fullscreen" allowfullscreen title="ReleaseME_How to_V5"></iframe>
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td class="text-center align-middle text-white">
|
|
||||||
Video tutorial will be available soon
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<p>Your <%= release_type.titleize %> files are being prepared for download. You will be notified when it's ready.
|
||||||
|
</p>
|
||||||
|
<p class="mt-3">The following downloads are also in progress:</p>
|
||||||
|
<ul>
|
||||||
|
<% downloads.each do |download| %>
|
||||||
|
<% if download.release_type == "reports"%>
|
||||||
|
<li><%= download.release_type.titleize %> (as of <%= time_ago_in_words(download.created_at) %> ago)
|
||||||
|
</li>
|
||||||
|
<% elsif download.release_type == "CastingCallInterview"%>
|
||||||
|
<li><%= download.release_type.titleize %> files (as of <%= time_ago_in_words(download.created_at) %> ago)
|
||||||
|
</li>
|
||||||
|
<% else %>
|
||||||
|
<li><%= download.release_type.titleize %> contracts (as of <%= time_ago_in_words(download.created_at) %> ago)
|
||||||
|
</li>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
@@ -21,6 +21,11 @@
|
|||||||
<%= link_to t("projects.show.tasks"), [@project, :tasks], class: "text-decoration-none text-reset stretched-link" %>
|
<%= link_to t("projects.show.tasks"), [@project, :tasks], class: "text-decoration-none text-reset stretched-link" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
<% if policy(Project).show_casting_call_interview_results? %>
|
||||||
|
<%= render "folder_card" do %>
|
||||||
|
<%= link_to t("projects.show.casting_call_interviews"), [@project, :casting_call_interviews], class: "text-decoration-none text-reset stretched-link" %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|||||||
51
app/views/public/casting_call_interviews/show.html.erb
Normal file
51
app/views/public/casting_call_interviews/show.html.erb
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<div class="card shadow-sm">
|
||||||
|
<%= card_header text: "Casting call interview details" %>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<dl>
|
||||||
|
<%= description_list_pair_for @casting_call_interview, :performer_name, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call_interview, :interview_date, append: ":" %>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h6>INTERVIEW FILES:</h6>
|
||||||
|
<hr/>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<div class="card shadow-sm">
|
||||||
|
<%= card_header text: t(".heading") %>
|
||||||
|
<div class="card-body">
|
||||||
|
<%= errors_summary_for @casting_call_interview %>
|
||||||
|
<%= bootstrap_form_with model: @casting_call_interview, url: casting_call_interview_path(token: @casting_call_interview.token), local: true do |form| %>
|
||||||
|
<div class="field d-none">
|
||||||
|
<%= form.label :files %>
|
||||||
|
<%= form.file_field :files, disable: true, direct_upload: true, multiple: true, id: "casting_call_interivew_files", hide_label: true %>
|
||||||
|
<% @casting_call_interview.files.each do |file| %>
|
||||||
|
<% unless file.persisted? %>
|
||||||
|
<%= hidden_field_tag "#{@casting_call_interview.model_name.param_key}[files][]", file.signed_id %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="dropzone field border-dashed"
|
||||||
|
data-accepted-files="audio/*,image/*,video/*"
|
||||||
|
data-behavior="dropzone"
|
||||||
|
data-file-input-id="casting_call_interivew_files"
|
||||||
|
data-existing-files="<%= mock_photos_json(@casting_call_interview.files) %>"
|
||||||
|
data-placeholder="<%= dropzone_placeholder_message_for(@casting_call_interview) %>"
|
||||||
|
data-submit-button="#submit_folder"></div>
|
||||||
|
|
||||||
|
<div class="mt-5">
|
||||||
|
<%= form.button t(".update"), class: "btn btn-block btn-lg btn-success", data: { disable_with: t("shared.disable_with") } %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row align-items-center justify-content-center mt-3">
|
||||||
|
<%= link_to "Start Interview", @casting_call_interview.join_zoom_meeting_url, target: "_blank", class: "btn btn-primary" %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
38
app/views/public/casting_calls/show.html.erb
Normal file
38
app/views/public/casting_calls/show.html.erb
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<% content_for :header do %>
|
||||||
|
<header class="container-fluid py-3 border-bottom sticky-top bg-light">
|
||||||
|
<div class="row align-items-center justify-content-center">
|
||||||
|
<div class="col-4 text-center">
|
||||||
|
<%= product_wordmark(:cast_me, class: 'navbar-brand') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="card shadow-sm">
|
||||||
|
<%= card_header text: @casting_call.title %>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 col-sm-12">
|
||||||
|
<dl>
|
||||||
|
<%= description_list_pair_for @casting_call, :title, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :description, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :project_description, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :created_at, append: ":" %>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-sm-12">
|
||||||
|
<dl>
|
||||||
|
<%= description_list_pair_for @casting_call, :status, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :interview_instructions, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :interview_requirements, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :questions, append: ":" %>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% unless @casting_call.cancelled? %>
|
||||||
|
<div class="row align-items-center justify-content-center mt-3">
|
||||||
|
<%= link_to "Schedule an Audition", ENV["CASTME_AUDITION_BOOKING_URL"], target: "_blank", class: "btn btn-primary" %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
15
app/views/shared/_initiate_hubspot_chat.html.erb
Normal file
15
app/views/shared/_initiate_hubspot_chat.html.erb
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<% if params[:show_chat] %>
|
||||||
|
<%= javascript_include_tag "//js.hs-scripts.com/7344617.js", defer: "defer", async: true, id: "hs-script-loader" %>
|
||||||
|
<%= javascript_tag nonce: true do %>
|
||||||
|
function onConversationsAPIReady() {
|
||||||
|
window.HubSpotConversations.widget.load({ widgetOpen: true });
|
||||||
|
window.HubSpotConversations.widget.open();
|
||||||
|
}
|
||||||
|
if (window.HubSpotConversations) {
|
||||||
|
onConversationsAPIReady();
|
||||||
|
} else {
|
||||||
|
window.hsConversationsOnReady = [onConversationsAPIReady];
|
||||||
|
}
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
@@ -1,15 +1,2 @@
|
|||||||
<% if params[:show_chat] %>
|
<%= render "shared/initiate_hubspot_chat" %>
|
||||||
<%= javascript_include_tag "//js.hs-scripts.com/7344617.js", defer: "defer", async: true, id: "hs-script-loader" %>
|
|
||||||
<%= javascript_tag nonce: true do %>
|
|
||||||
function onConversationsAPIReady() {
|
|
||||||
window.HubSpotConversations.widget.load({ widgetOpen: true });
|
|
||||||
window.HubSpotConversations.widget.open();
|
|
||||||
}
|
|
||||||
if (window.HubSpotConversations) {
|
|
||||||
onConversationsAPIReady();
|
|
||||||
} else {
|
|
||||||
window.hsConversationsOnReady = [onConversationsAPIReady];
|
|
||||||
}
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
|
||||||
<p class="alert alert-success p-3 lead text-center"><%= t '.success_message' %></p>
|
<p class="alert alert-success p-3 lead text-center"><%= t '.success_message' %></p>
|
||||||
@@ -18,15 +18,7 @@
|
|||||||
<div class="card-body p-0">
|
<div class="card-body p-0">
|
||||||
<div class="embed-responsive embed-responsive-16by9">
|
<div class="embed-responsive embed-responsive-16by9">
|
||||||
<div class="embed-responsive-item">
|
<div class="embed-responsive-item">
|
||||||
<table class="w-100 h-100 bg-secondary">
|
<iframe src="https://player.vimeo.com/video/435200434?app_id=122963" width="426" height="240" frameborder="0" allow="autoplay; fullscreen" allowfullscreen title="DeliverME_How to_V5"></iframe>
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td class="text-center align-middle text-white">
|
|
||||||
Video tutorial will be available soon
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -97,6 +97,22 @@ en:
|
|||||||
application:
|
application:
|
||||||
header:
|
header:
|
||||||
sign_out: Sign Out
|
sign_out: Sign Out
|
||||||
|
casting_call_interviews:
|
||||||
|
complete:
|
||||||
|
notice: The casting call interview has been completed
|
||||||
|
create:
|
||||||
|
notice: The casting call interview has been created
|
||||||
|
index:
|
||||||
|
actions:
|
||||||
|
new: Create Casting Call Interview
|
||||||
|
empty: Casting call interviews will appear here
|
||||||
|
mark_as_completed:
|
||||||
|
alert: Failed to mark casting call interview as completed
|
||||||
|
notice: The casting call interview has been marked as completed
|
||||||
|
new:
|
||||||
|
heading: New Casting Call Interview
|
||||||
|
update:
|
||||||
|
notice: The casting call interview has been updated
|
||||||
task_requests:
|
task_requests:
|
||||||
index:
|
index:
|
||||||
empty: Task requests will appear here
|
empty: Task requests will appear here
|
||||||
@@ -228,6 +244,45 @@ en:
|
|||||||
bulk_taggings:
|
bulk_taggings:
|
||||||
new_bulk_tag_modal:
|
new_bulk_tag_modal:
|
||||||
submit: Add
|
submit: Add
|
||||||
|
casting_call_interviews:
|
||||||
|
index:
|
||||||
|
empty: Casting Call Interview results will appear here.
|
||||||
|
show:
|
||||||
|
empty: Interview files and recorded meeetings will appear here.
|
||||||
|
validation_errors:
|
||||||
|
invalid_meeting_url: Zoom Meeting URL is invalid
|
||||||
|
casting_calls:
|
||||||
|
cancel:
|
||||||
|
notice: The casting call request has been cancelled successfully
|
||||||
|
casting_call:
|
||||||
|
actions:
|
||||||
|
manage: Manage
|
||||||
|
create:
|
||||||
|
notice: The casting call request has been created
|
||||||
|
success_message: Your casting call request was successfully submitted. Thank you. A chat window will pop up on the lower right in a few seconds.
|
||||||
|
edit:
|
||||||
|
heading: Edit Casting Call
|
||||||
|
form:
|
||||||
|
info_message: After submitting this casting call request, you'll be connected via chat with a ME Suite representative.
|
||||||
|
labels:
|
||||||
|
description: Description
|
||||||
|
interview_instructions: Interview instructions
|
||||||
|
interview_requirements: Interview requirements
|
||||||
|
project_description: Project description
|
||||||
|
questions: Questions
|
||||||
|
title: Title
|
||||||
|
index:
|
||||||
|
actions:
|
||||||
|
new: Create Casting Call
|
||||||
|
empty: Casting calls will appear here
|
||||||
|
table_headers:
|
||||||
|
casting_call_created_on: Created On
|
||||||
|
casting_call_status: Status
|
||||||
|
casting_call_title: Title
|
||||||
|
new:
|
||||||
|
heading: New Casting Call
|
||||||
|
update:
|
||||||
|
notice: The casting call request has been updated
|
||||||
contract_downloads:
|
contract_downloads:
|
||||||
download:
|
download:
|
||||||
failure: Your download could not be generated.
|
failure: Your download could not be generated.
|
||||||
@@ -668,6 +723,8 @@ en:
|
|||||||
broadcast:
|
broadcast:
|
||||||
create: Create Live Stream
|
create: Create Live Stream
|
||||||
update: Save Changes
|
update: Save Changes
|
||||||
|
casting_call_interview:
|
||||||
|
create: Create casting call interview
|
||||||
contract_template:
|
contract_template:
|
||||||
create: Create Release Template
|
create: Create Release Template
|
||||||
directory:
|
directory:
|
||||||
@@ -700,6 +757,11 @@ en:
|
|||||||
cards: Cards
|
cards: Cards
|
||||||
heading: Import Releases
|
heading: Import Releases
|
||||||
list: List
|
list: List
|
||||||
|
interview_downloads:
|
||||||
|
download:
|
||||||
|
failure: Your download could not be generated.
|
||||||
|
pending: "Your %{release_type} files are being prepared for download. You will be notified when it's ready."
|
||||||
|
success: "Your %{release_type} files are ready. Download now, or retrieve later in the %{downloads_folder_link} folder. %{download_button}"
|
||||||
location_releases:
|
location_releases:
|
||||||
create:
|
create:
|
||||||
notice: The location release has been created
|
notice: The location release has been created
|
||||||
@@ -931,6 +993,7 @@ en:
|
|||||||
show:
|
show:
|
||||||
acquired_media_release: Acquired Media Releases (%{count})
|
acquired_media_release: Acquired Media Releases (%{count})
|
||||||
appearance_release: Appearance Releases (%{count})
|
appearance_release: Appearance Releases (%{count})
|
||||||
|
casting_call_interviews: Interviews
|
||||||
downloads: Downloads
|
downloads: Downloads
|
||||||
location_release: Location Releases (%{count})
|
location_release: Location Releases (%{count})
|
||||||
material_release: Material Releases (%{count})
|
material_release: Material Releases (%{count})
|
||||||
@@ -993,6 +1056,12 @@ en:
|
|||||||
broadcasts:
|
broadcasts:
|
||||||
show:
|
show:
|
||||||
alert: That broadcast is no longer available
|
alert: That broadcast is no longer available
|
||||||
|
casting_call_interviews:
|
||||||
|
show:
|
||||||
|
heading: Files
|
||||||
|
update: Upload
|
||||||
|
update:
|
||||||
|
notice: Your files have been uploaded successfully
|
||||||
location_releases:
|
location_releases:
|
||||||
create:
|
create:
|
||||||
notice: Your release has been signed. Thank you!
|
notice: Your release has been signed. Thank you!
|
||||||
@@ -1169,6 +1238,7 @@ en:
|
|||||||
ago: ago
|
ago: ago
|
||||||
back: Back
|
back: Back
|
||||||
cancel: Cancel
|
cancel: Cancel
|
||||||
|
cast_me: Cast
|
||||||
clear: Clear
|
clear: Clear
|
||||||
close: Close
|
close: Close
|
||||||
csv: CSV
|
csv: CSV
|
||||||
|
|||||||
@@ -76,6 +76,9 @@ es:
|
|||||||
share_stream: Share live stream link with clients
|
share_stream: Share live stream link with clients
|
||||||
stream_from_mobile_app: Stream from ME Suite Mobile app, or via a professional camera
|
stream_from_mobile_app: Stream from ME Suite Mobile app, or via a professional camera
|
||||||
stream_multiple_cameras: Stream multiple cameras at one time
|
stream_multiple_cameras: Stream multiple cameras at one time
|
||||||
|
casting_call_interviews:
|
||||||
|
validation_errors:
|
||||||
|
invalid_meeting_url: Zoom Meeting URL is invalid (ES)
|
||||||
contract_templates:
|
contract_templates:
|
||||||
blank_contracts:
|
blank_contracts:
|
||||||
create:
|
create:
|
||||||
@@ -272,6 +275,8 @@ es:
|
|||||||
broadcast:
|
broadcast:
|
||||||
create: Create Live Stream (ES)
|
create: Create Live Stream (ES)
|
||||||
update: Save Changes (ES)
|
update: Save Changes (ES)
|
||||||
|
casting_call_interview:
|
||||||
|
create: Create casting call interview (ES)
|
||||||
create: 'Crear %{model}'
|
create: 'Crear %{model}'
|
||||||
update: 'Actualizar %{model}'
|
update: 'Actualizar %{model}'
|
||||||
location_releases:
|
location_releases:
|
||||||
|
|||||||
@@ -32,6 +32,9 @@ Rails.application.routes.draw do
|
|||||||
resource :masquerade, only: :create
|
resource :masquerade, only: :create
|
||||||
end
|
end
|
||||||
resources :task_requests, only: [:index, :edit, :update, :show]
|
resources :task_requests, only: [:index, :edit, :update, :show]
|
||||||
|
resources :casting_call_interviews do
|
||||||
|
post :complete, on: :member
|
||||||
|
end
|
||||||
|
|
||||||
root to: "accounts#index", as: :signed_in_root
|
root to: "accounts#index", as: :signed_in_root
|
||||||
end
|
end
|
||||||
@@ -66,6 +69,7 @@ Rails.application.routes.draw do
|
|||||||
resource :contract_downloads, only: [:create]
|
resource :contract_downloads, only: [:create]
|
||||||
resources :downloads, only: [:index, :destroy]
|
resources :downloads, only: [:index, :destroy]
|
||||||
resource :report_downloads, only: [:create]
|
resource :report_downloads, only: [:create]
|
||||||
|
resource :interview_downloads, only: [:create]
|
||||||
resources :videos, only: [:index, :new, :create, :edit, :update] do
|
resources :videos, only: [:index, :new, :create, :edit, :update] do
|
||||||
collection do
|
collection do
|
||||||
get :landing
|
get :landing
|
||||||
@@ -105,7 +109,13 @@ Rails.application.routes.draw do
|
|||||||
post :cancel
|
post :cancel
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
resources :casting_calls, except: :destroy do
|
||||||
|
member do
|
||||||
|
post :cancel
|
||||||
|
end
|
||||||
|
end
|
||||||
resources :tasks, only: :index
|
resources :tasks, only: :index
|
||||||
|
resources :casting_call_interviews, only: [:index, :show]
|
||||||
end
|
end
|
||||||
resource :profile, only: [:show, :update]
|
resource :profile, only: [:show, :update]
|
||||||
resources :videos, only: [] do
|
resources :videos, only: [] do
|
||||||
@@ -134,6 +144,8 @@ Rails.application.routes.draw do
|
|||||||
resources :broadcasts, param: :token, only: [:show, :update] do
|
resources :broadcasts, param: :token, only: [:show, :update] do
|
||||||
resource :zoom_meeting, only: [:show]
|
resource :zoom_meeting, only: [:show]
|
||||||
end
|
end
|
||||||
|
resources :casting_calls, param: :token, only: [:show]
|
||||||
|
resources :casting_call_interviews, param: :token, only: [:show, :update]
|
||||||
end
|
end
|
||||||
|
|
||||||
RELEASES = [:acquired_media_releases, :appearance_releases, :talent_releases, :material_releases, :location_releases]
|
RELEASES = [:acquired_media_releases, :appearance_releases, :talent_releases, :material_releases, :location_releases]
|
||||||
|
|||||||
17
db/migrate/20200626044744_create_casting_calls.rb
Normal file
17
db/migrate/20200626044744_create_casting_calls.rb
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
class CreateCastingCalls < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
create_table :casting_calls do |t|
|
||||||
|
t.references :project
|
||||||
|
t.string :title
|
||||||
|
t.string :user_email
|
||||||
|
t.text :description
|
||||||
|
t.text :project_description
|
||||||
|
t.text :interview_instructions
|
||||||
|
t.text :interview_requirements
|
||||||
|
t.text :questions
|
||||||
|
t.datetime :cancelled_at
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
12
db/migrate/20200701121237_create_casting_call_interviews.rb
Normal file
12
db/migrate/20200701121237_create_casting_call_interviews.rb
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
class CreateCastingCallInterviews < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
create_table :casting_call_interviews do |t|
|
||||||
|
t.references :casting_call, foreign_key: true
|
||||||
|
t.string :performer_name
|
||||||
|
t.string :zoom_meeting_url
|
||||||
|
t.datetime :interview_date
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
6
db/migrate/20200706193123_add_token_to_casting_calls.rb
Normal file
6
db/migrate/20200706193123_add_token_to_casting_calls.rb
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
class AddTokenToCastingCalls < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
add_column :casting_calls, :token, :string
|
||||||
|
add_index :casting_calls, :token, unique: true
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
class AddTokenToCastingCallInterviews < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
add_column :casting_call_interviews, :token, :string
|
||||||
|
add_index :casting_call_interviews, :token, unique: true
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
class AddInterviewedAtToCastingCallInterview < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
add_column :casting_call_interviews, :interviewed_at, :datetime
|
||||||
|
end
|
||||||
|
end
|
||||||
149
db/structure.sql
149
db/structure.sql
@@ -555,6 +555,82 @@ CREATE SEQUENCE public.broadcasts_id_seq
|
|||||||
ALTER SEQUENCE public.broadcasts_id_seq OWNED BY public.broadcasts.id;
|
ALTER SEQUENCE public.broadcasts_id_seq OWNED BY public.broadcasts.id;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: casting_call_interviews; Type: TABLE; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE public.casting_call_interviews (
|
||||||
|
id bigint NOT NULL,
|
||||||
|
casting_call_id bigint,
|
||||||
|
performer_name character varying,
|
||||||
|
zoom_meeting_url character varying,
|
||||||
|
interview_date timestamp without time zone,
|
||||||
|
created_at timestamp(6) without time zone NOT NULL,
|
||||||
|
updated_at timestamp(6) without time zone NOT NULL,
|
||||||
|
token character varying,
|
||||||
|
interviewed_at timestamp without time zone
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: casting_call_interviews_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE SEQUENCE public.casting_call_interviews_id_seq
|
||||||
|
START WITH 1
|
||||||
|
INCREMENT BY 1
|
||||||
|
NO MINVALUE
|
||||||
|
NO MAXVALUE
|
||||||
|
CACHE 1;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: casting_call_interviews_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER SEQUENCE public.casting_call_interviews_id_seq OWNED BY public.casting_call_interviews.id;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: casting_calls; Type: TABLE; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE public.casting_calls (
|
||||||
|
id bigint NOT NULL,
|
||||||
|
project_id bigint,
|
||||||
|
title character varying,
|
||||||
|
user_email character varying,
|
||||||
|
description text,
|
||||||
|
project_description text,
|
||||||
|
interview_instructions text,
|
||||||
|
interview_requirements text,
|
||||||
|
questions text,
|
||||||
|
cancelled_at timestamp without time zone,
|
||||||
|
created_at timestamp(6) without time zone NOT NULL,
|
||||||
|
updated_at timestamp(6) without time zone NOT NULL,
|
||||||
|
token character varying
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: casting_calls_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE SEQUENCE public.casting_calls_id_seq
|
||||||
|
START WITH 1
|
||||||
|
INCREMENT BY 1
|
||||||
|
NO MINVALUE
|
||||||
|
NO MAXVALUE
|
||||||
|
CACHE 1;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: casting_calls_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER SEQUENCE public.casting_calls_id_seq OWNED BY public.casting_calls.id;
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: composers; Type: TABLE; Schema: public; Owner: -
|
-- Name: composers; Type: TABLE; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
@@ -1963,6 +2039,20 @@ ALTER TABLE ONLY public.broadcast_recordings ALTER COLUMN id SET DEFAULT nextval
|
|||||||
ALTER TABLE ONLY public.broadcasts ALTER COLUMN id SET DEFAULT nextval('public.broadcasts_id_seq'::regclass);
|
ALTER TABLE ONLY public.broadcasts ALTER COLUMN id SET DEFAULT nextval('public.broadcasts_id_seq'::regclass);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: casting_call_interviews id; Type: DEFAULT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.casting_call_interviews ALTER COLUMN id SET DEFAULT nextval('public.casting_call_interviews_id_seq'::regclass);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: casting_calls id; Type: DEFAULT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.casting_calls ALTER COLUMN id SET DEFAULT nextval('public.casting_calls_id_seq'::regclass);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: composers id; Type: DEFAULT; Schema: public; Owner: -
|
-- Name: composers id; Type: DEFAULT; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
@@ -2284,6 +2374,22 @@ ALTER TABLE ONLY public.broadcasts
|
|||||||
ADD CONSTRAINT broadcasts_pkey PRIMARY KEY (id);
|
ADD CONSTRAINT broadcasts_pkey PRIMARY KEY (id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: casting_call_interviews casting_call_interviews_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.casting_call_interviews
|
||||||
|
ADD CONSTRAINT casting_call_interviews_pkey PRIMARY KEY (id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: casting_calls casting_calls_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.casting_calls
|
||||||
|
ADD CONSTRAINT casting_calls_pkey PRIMARY KEY (id);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: composers composers_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
-- Name: composers composers_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
@@ -2701,6 +2807,34 @@ CREATE INDEX index_broadcasts_on_project_id ON public.broadcasts USING btree (pr
|
|||||||
CREATE UNIQUE INDEX index_broadcasts_on_token ON public.broadcasts USING btree (token);
|
CREATE UNIQUE INDEX index_broadcasts_on_token ON public.broadcasts USING btree (token);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: index_casting_call_interviews_on_casting_call_id; Type: INDEX; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE INDEX index_casting_call_interviews_on_casting_call_id ON public.casting_call_interviews USING btree (casting_call_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: index_casting_call_interviews_on_token; Type: INDEX; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE UNIQUE INDEX index_casting_call_interviews_on_token ON public.casting_call_interviews USING btree (token);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: index_casting_calls_on_project_id; Type: INDEX; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE INDEX index_casting_calls_on_project_id ON public.casting_calls USING btree (project_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: index_casting_calls_on_token; Type: INDEX; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE UNIQUE INDEX index_casting_calls_on_token ON public.casting_calls USING btree (token);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: index_composers_on_music_release_id; Type: INDEX; Schema: public; Owner: -
|
-- Name: index_composers_on_music_release_id; Type: INDEX; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
@@ -3298,6 +3432,14 @@ ALTER TABLE ONLY public.bookmarks
|
|||||||
ADD CONSTRAINT fk_rails_15735b7db8 FOREIGN KEY (video_id) REFERENCES public.videos(id);
|
ADD CONSTRAINT fk_rails_15735b7db8 FOREIGN KEY (video_id) REFERENCES public.videos(id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: casting_call_interviews fk_rails_1583f69fbb; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.casting_call_interviews
|
||||||
|
ADD CONSTRAINT fk_rails_1583f69fbb FOREIGN KEY (casting_call_id) REFERENCES public.casting_calls(id);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: acquired_media_releases fk_rails_15b450b040; Type: FK CONSTRAINT; Schema: public; Owner: -
|
-- Name: acquired_media_releases fk_rails_15b450b040; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
@@ -3902,6 +4044,11 @@ INSERT INTO "schema_migrations" (version) VALUES
|
|||||||
('20200619134853'),
|
('20200619134853'),
|
||||||
('20200622180507'),
|
('20200622180507'),
|
||||||
('20200625144713'),
|
('20200625144713'),
|
||||||
('20200702152130');
|
('20200626044744'),
|
||||||
|
('20200701121237'),
|
||||||
|
('20200702152130'),
|
||||||
|
('20200706193123'),
|
||||||
|
('20200706230803'),
|
||||||
|
('20200707070522');
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -54,14 +54,16 @@ RSpec.describe AccountsController, type: :controller do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "enqueues hubspot form submission job" do
|
it "enqueues hubspot form submission job" do
|
||||||
|
ENV["HUBSPOT_FORM_GUID"] = "form_guid"
|
||||||
expect {
|
expect {
|
||||||
post :create, params: params
|
post :create, params: params
|
||||||
}.to have_enqueued_job(SubmitHubspotFormJob).with(
|
}.to have_enqueued_job(SubmitHubspotFormJob).with(
|
||||||
"John",
|
first_name: "John",
|
||||||
"Doe",
|
last_name: "Doe",
|
||||||
"test_user+1@test.com",
|
email: "test_user+1@test.com",
|
||||||
"Test Dev account",
|
company: "Test Dev account",
|
||||||
i_m_interested_in: "DirectME"
|
i_m_interested_in: "DirectME",
|
||||||
|
form_guid: "form_guid"
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,124 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
RSpec.describe Admin::CastingCallInterviewsController, type: :controller do
|
||||||
|
|
||||||
|
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
|
||||||
|
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(:casting_call_interview)).not_to be_nil
|
||||||
|
expect(assigns(:accounts)).to eq Account.all
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#create" do
|
||||||
|
it "does create a new record" do
|
||||||
|
expect {
|
||||||
|
post :create, params: { casting_call_interview: casting_call_interview_params }
|
||||||
|
}.to change(CastingCallInterview, :count)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not create new record if zoom meeting url is not valid" do
|
||||||
|
expect {
|
||||||
|
post :create, params: {
|
||||||
|
casting_call_interview: casting_call_interview_params
|
||||||
|
.except(:zoom_meeting_url)
|
||||||
|
.merge(zoom_meeting_url: "malformed_url")
|
||||||
|
}
|
||||||
|
}.to change(CastingCallInterview, :count).by(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#edit" do
|
||||||
|
let(:casting_call_interview) { create(:casting_call_interview) }
|
||||||
|
|
||||||
|
it "returns a successful response" do
|
||||||
|
get :edit, params: { id: casting_call_interview }
|
||||||
|
|
||||||
|
expect(response).to be_successful
|
||||||
|
end
|
||||||
|
|
||||||
|
it "assigns casting call interview" do
|
||||||
|
get :edit, params: { id: casting_call_interview }
|
||||||
|
|
||||||
|
expect(assigns(:casting_call_interview)).to eq casting_call_interview
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#update" do
|
||||||
|
let(:casting_call_interview) { create(:casting_call_interview) }
|
||||||
|
|
||||||
|
it "redirects to casting call interviews page" do
|
||||||
|
patch :update, params: { id: casting_call_interview, casting_call_interview: update_params }
|
||||||
|
|
||||||
|
expect(response).to be_redirect
|
||||||
|
expect(response).to redirect_to admin_casting_call_interviews_path
|
||||||
|
end
|
||||||
|
|
||||||
|
it "sets a flash notice" do
|
||||||
|
patch :update, params: { id: casting_call_interview, casting_call_interview: update_params }
|
||||||
|
|
||||||
|
expect(flash.notice).to eq "The casting call interview has been updated"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "updates casting call interview" do
|
||||||
|
patch :update, params: { id: casting_call_interview, casting_call_interview: update_params }
|
||||||
|
|
||||||
|
expect(casting_call_interview.reload.zoom_meeting_url).to eq new_zoom_meeting_url
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#complete" do
|
||||||
|
let(:casting_call_interview) { create(:casting_call_interview) }
|
||||||
|
|
||||||
|
it "sets interviewed_at on casting call interview" do
|
||||||
|
expect(casting_call_interview.interviewed_at).to be_nil
|
||||||
|
|
||||||
|
post :complete, params: { id: casting_call_interview }
|
||||||
|
|
||||||
|
expect(casting_call_interview.reload.interviewed_at).not_to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def casting_call_interview_params
|
||||||
|
casting_call = create(:casting_call)
|
||||||
|
|
||||||
|
attributes_for(:casting_call_interview).except(:interviewed_at).merge(casting_call_id: casting_call.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_params
|
||||||
|
{
|
||||||
|
zoom_meeting_url: new_zoom_meeting_url
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def new_zoom_meeting_url
|
||||||
|
"https://s01web.zoom.us/j/11111?pwd=Ab123Cq34"
|
||||||
|
end
|
||||||
|
|
||||||
|
def invalid_meeting_url_flash_error
|
||||||
|
t 'casting_call_interviews.validation_errors.invalid_meeting_url'
|
||||||
|
end
|
||||||
|
end
|
||||||
43
spec/controllers/casting_call_interviews_controller_spec.rb
Normal file
43
spec/controllers/casting_call_interviews_controller_spec.rb
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
RSpec.describe CastingCallInterviewsController, type: :controller do
|
||||||
|
render_views
|
||||||
|
|
||||||
|
let(:user) { create(:user) }
|
||||||
|
let(:account) { user.primary_account }
|
||||||
|
let(:project) { create(:project, account: user.primary_account) }
|
||||||
|
let(:casting_call) { create(:casting_call, project: project, title: "My Interview") }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#index" do
|
||||||
|
it "returns a successful response" do
|
||||||
|
get :index, params: { project_id: project }
|
||||||
|
|
||||||
|
expect(response).to be_successful
|
||||||
|
end
|
||||||
|
|
||||||
|
it "only shows completed interviews" do
|
||||||
|
create(:casting_call_interview, casting_call: casting_call, interviewed_at: Time.zone.now, performer_name: "John Doe")
|
||||||
|
create(:casting_call_interview, casting_call: casting_call, interviewed_at: nil, performer_name: "Jane Doe")
|
||||||
|
|
||||||
|
get :index, params: { project_id: project }
|
||||||
|
|
||||||
|
expect(response.body).to have_content("John Doe")
|
||||||
|
expect(response.body).not_to have_content("Jane Doe")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#show" do
|
||||||
|
let!(:casting_call_interview) { create(:casting_call_interview, :with_files, casting_call: casting_call, interviewed_at: Time.zone.now, performer_name: "Jane Doe") }
|
||||||
|
|
||||||
|
it "shows files of casting call interview" do
|
||||||
|
get :show, params: { project_id: project, id: casting_call_interview.id }
|
||||||
|
|
||||||
|
expect(response.body).to have_content("Filename")
|
||||||
|
expect(response.body).to have_content("location_photo.png")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
126
spec/controllers/casting_calls_controller_spec.rb
Normal file
126
spec/controllers/casting_calls_controller_spec.rb
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe CastingCallsController, 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
|
||||||
|
create(:casting_call, project: project)
|
||||||
|
|
||||||
|
get :index, params: { project_id: project }
|
||||||
|
|
||||||
|
expect(response.body).to have_link "Create Casting Call"
|
||||||
|
expect(response.body).to have_content "Active"
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when there are many records" do
|
||||||
|
it "paginates the table" do
|
||||||
|
create_list(:casting_call, 20, project: project)
|
||||||
|
|
||||||
|
get :index, params: { project_id: project }
|
||||||
|
|
||||||
|
expect(response.body).to have_link("2", href: project_casting_calls_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
|
||||||
|
expect(assigns(:casting_call)).to be_a_new(CastingCall)
|
||||||
|
expect(response).to render_template(:new)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#create" do
|
||||||
|
it "does create a new record" do
|
||||||
|
expect {
|
||||||
|
post :create, params: { project_id: project.id, casting_call: casting_call_params }
|
||||||
|
}.to change(CastingCall, :count)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "logs an event" do
|
||||||
|
expect {
|
||||||
|
post :create, params: { project_id: project.id, casting_call: casting_call_params }
|
||||||
|
}.to have_enqueued_job(TrackAnalyticsJob).with(user, account, :track_create_casting_call, user_agent: "Rails Testing", user_ip: "0.0.0.0")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "submits data to hubspot form" do
|
||||||
|
expect {
|
||||||
|
post :create, params: { project_id: project.id, casting_call: casting_call_params }
|
||||||
|
}.to have_enqueued_job(SubmitHubspotFormJob)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#update" do
|
||||||
|
let!(:casting_call) { create(:casting_call, project: project, description: "My description" ) }
|
||||||
|
|
||||||
|
it "updates casting call request" do
|
||||||
|
patch :update, params: { project_id: project.id, id: casting_call.id, casting_call: update_params }
|
||||||
|
|
||||||
|
expect(casting_call.reload.description).to eq("This is updated description")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#show" do
|
||||||
|
let!(:casting_call) { create(:casting_call, project: project, description: "Casting Call Request") }
|
||||||
|
|
||||||
|
it "responds successfully" do
|
||||||
|
get :show, params: { project_id: project.id, id: casting_call.id }
|
||||||
|
|
||||||
|
expect(response).to be_successful
|
||||||
|
expect(assigns(:casting_call)).to eq(casting_call)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "renders content" do
|
||||||
|
get :show, params: { project_id: project.id, id: casting_call.id }
|
||||||
|
|
||||||
|
expect(response.body).to have_content "Casting Call Request"
|
||||||
|
expect(response.body).to have_content "Active"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#cancel" do
|
||||||
|
let!(:casting_call) { create(:casting_call, project: project, description: "Casting Call to be Cancelled") }
|
||||||
|
|
||||||
|
it "responds with redirect" do
|
||||||
|
post :cancel, params: { project_id: project.id, id: casting_call.id }
|
||||||
|
|
||||||
|
expect(response).to be_redirect
|
||||||
|
expect(response).to redirect_to(project_casting_calls_path(project))
|
||||||
|
expect(flash.notice).not_to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it "updates the status to 'Cancelled'" do
|
||||||
|
expect {
|
||||||
|
post :cancel, params: { project_id: project.id, id: casting_call.id }
|
||||||
|
}.to change { casting_call.reload.status }.from("Active").to("Cancelled")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def casting_call_params
|
||||||
|
attributes_for(:casting_call).except(:status, :user_email)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_params
|
||||||
|
{ description: "This is updated description" }
|
||||||
|
end
|
||||||
|
end
|
||||||
58
spec/controllers/interview_downloads_controller_spec.rb
Normal file
58
spec/controllers/interview_downloads_controller_spec.rb
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
RSpec.describe InterviewDownloadsController, type: :controller do
|
||||||
|
render_views
|
||||||
|
|
||||||
|
let(:current_user) { create(:user) }
|
||||||
|
let(:project) { create(:project, :discovery_client, account: current_user.primary_account) }
|
||||||
|
let(:casting_call) { create(:casting_call, project: project, title: "My Title") }
|
||||||
|
let(:casting_call_interview) { create(:casting_call_interview, casting_call: casting_call, performer_name: "John Doe") }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in current_user
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#create" do
|
||||||
|
it "enqueues zip file generation job" do
|
||||||
|
expect {
|
||||||
|
post :create, params: { project_id: project.id, casting_call_interview_id: casting_call_interview.id }, format: :js
|
||||||
|
}.to have_enqueued_job(GenerateInterviewFilesZipJob)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "creates a download record with 'not_started' status" do
|
||||||
|
expect {
|
||||||
|
post :create, params: { project_id: project.id, casting_call_interview_id: casting_call_interview.id }, 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("interview_downloads.download.pending", release_type: "Casting Call Interview"))
|
||||||
|
|
||||||
|
post :create, params: { project_id: project.id, casting_call_interview_id: casting_call_interview.id }, format: :js
|
||||||
|
|
||||||
|
expect(ProjectsChannel).to have_received(:broadcast_download_generation_update).with(be_kind_of(Download), I18n.t("interview_downloads.download.pending", release_type: "Casting Call Interview"))
|
||||||
|
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 Casting Call Interview files 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, casting_call_interview_id: casting_call_interview.id }, format: :js
|
||||||
|
|
||||||
|
expect(ProjectsChannel).to have_received(:broadcast_download_generation_update).with(be_kind_of(Download), broadcast_message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Public::CastingCallInterviewsController, type: :controller do
|
||||||
|
render_views
|
||||||
|
|
||||||
|
describe "#show" do
|
||||||
|
let(:casting_call_interview) { create(:casting_call_interview) }
|
||||||
|
|
||||||
|
it "responds successfully" do
|
||||||
|
get :show, params: { token: casting_call_interview.token }
|
||||||
|
|
||||||
|
expect(response).to be_successful
|
||||||
|
expect(assigns(:casting_call_interview)).to eq(casting_call_interview)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "shows casting call interview details" do
|
||||||
|
get :show, params: { token: casting_call_interview.token }
|
||||||
|
|
||||||
|
expect(response.body).to have_content(casting_call_interview.performer_name)
|
||||||
|
expect(response.body).to have_content(casting_call_interview.interview_date)
|
||||||
|
expect(response.body).to have_link("Start Interview")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#update" do
|
||||||
|
let(:casting_call_interview) { create(:casting_call_interview) }
|
||||||
|
|
||||||
|
it "responds successfully" do
|
||||||
|
patch :update, params: { token: casting_call_interview.token, casting_call_interview: casting_call_interview_params }
|
||||||
|
|
||||||
|
expect(response).to redirect_to casting_call_interview_url(token: casting_call_interview.token)
|
||||||
|
expect(flash.notice).to be_present
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def casting_call_interview_params
|
||||||
|
path = Rails.root.join("spec", "fixtures", "files", "contract.pdf")
|
||||||
|
file = Rack::Test::UploadedFile.new(path, "application/pdf")
|
||||||
|
|
||||||
|
{ files: [file]}
|
||||||
|
end
|
||||||
|
end
|
||||||
28
spec/controllers/public/casting_calls_controller_spec.rb
Normal file
28
spec/controllers/public/casting_calls_controller_spec.rb
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Public::CastingCallsController, type: :controller do
|
||||||
|
render_views
|
||||||
|
|
||||||
|
describe "#show" do
|
||||||
|
let(:casting_call) { create(:casting_call) }
|
||||||
|
|
||||||
|
it "responds successfully" do
|
||||||
|
get :show, params: { token: casting_call.token }
|
||||||
|
|
||||||
|
expect(response).to be_successful
|
||||||
|
expect(assigns(:casting_call)).to eq(casting_call)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "shows casting call details" do
|
||||||
|
get :show, params: { token: casting_call.token }
|
||||||
|
|
||||||
|
expect(response.body).to have_content(casting_call.title)
|
||||||
|
expect(response.body).to have_content(casting_call.description)
|
||||||
|
expect(response.body).to have_content(casting_call.project_description)
|
||||||
|
expect(response.body).to have_content(casting_call.interview_instructions)
|
||||||
|
expect(response.body).to have_content(casting_call.interview_requirements)
|
||||||
|
expect(response.body).to have_content(casting_call.questions)
|
||||||
|
expect(response.body).to have_link("Schedule an Audition")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -71,7 +71,7 @@ RSpec.describe TaskRequestsController, type: :controller do
|
|||||||
it "submits data to hubspot form" do
|
it "submits data to hubspot form" do
|
||||||
expect {
|
expect {
|
||||||
post :create, params: { project_id: project.id, task_request: task_request_params }
|
post :create, params: { project_id: project.id, task_request: task_request_params }
|
||||||
}.to have_enqueued_job(SubmitHubspotTaskRequestFormJob)
|
}.to have_enqueued_job(SubmitHubspotFormJob)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
13
spec/factories/casting_call_interviews.rb
Normal file
13
spec/factories/casting_call_interviews.rb
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
FactoryBot.define do
|
||||||
|
factory :casting_call_interview do
|
||||||
|
association :casting_call
|
||||||
|
performer_name 'John Doe'
|
||||||
|
zoom_meeting_url 'https://us04web.zoom.us/j/1111111111?pwd=aDZCS1dzZ2lWdDZJcHBhVnNIclB4QT03'
|
||||||
|
interview_date { 10.days.from_now }
|
||||||
|
interviewed_at { nil }
|
||||||
|
|
||||||
|
trait :with_files do
|
||||||
|
files { [Rack::Test::UploadedFile.new('spec/fixtures/files/location_photo.png', 'image/png')] }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
15
spec/factories/casting_calls.rb
Normal file
15
spec/factories/casting_calls.rb
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
FactoryBot.define do
|
||||||
|
factory :casting_call do
|
||||||
|
association :project
|
||||||
|
user_email 'test@email.com'
|
||||||
|
description "Casting call description"
|
||||||
|
project_description "Casting call project description"
|
||||||
|
interview_instructions "Interview instructions"
|
||||||
|
interview_requirements "Interview requirements"
|
||||||
|
questions "Questions"
|
||||||
|
|
||||||
|
trait :cancelled do
|
||||||
|
cancelled_at { Time.zone.now }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
71
spec/features/admin_managing_casting_call_interviews_spec.rb
Normal file
71
spec/features/admin_managing_casting_call_interviews_spec.rb
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
feature "Admin managing casting call interviews" do
|
||||||
|
let(:current_user) { create(:user, admin: true, email: "user@test.com") }
|
||||||
|
let(:project) { create(:project, account: current_user.primary_account, name: "Test Project") }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in current_user
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "admin cannot create casting call interview with invalid zoom url", js: true do
|
||||||
|
visit admin_casting_call_interviews_path
|
||||||
|
cc = create(:casting_call, title: "SpecialCastingCall")
|
||||||
|
|
||||||
|
click_link create_casting_call_interview_button
|
||||||
|
expect(page).to have_content new_casting_call_interview_heading
|
||||||
|
|
||||||
|
fill_in performer_name_field, with: "TestName"
|
||||||
|
select cc.title, from: casting_call_field
|
||||||
|
fill_in zoom_meeting_url_field, with: "malformed url"
|
||||||
|
|
||||||
|
expect do
|
||||||
|
click_on submit_casting_call_interview_form
|
||||||
|
end.to change(CastingCallInterview, :count).by(0)
|
||||||
|
expect(page).to have_content zoom_meeting_url_invalid_error
|
||||||
|
|
||||||
|
fill_in zoom_meeting_url_field, with: "https://similar.google.com/j/24324324?pwd=334kni3j4"
|
||||||
|
|
||||||
|
expect do
|
||||||
|
click_on submit_casting_call_interview_form
|
||||||
|
end.to change(CastingCallInterview, :count).by(0)
|
||||||
|
expect(page).to have_content zoom_meeting_url_invalid_error
|
||||||
|
|
||||||
|
fill_in zoom_meeting_url_field, with: "https://s01.zoom.us/j/343434?pwd=dawidj34ijij"
|
||||||
|
|
||||||
|
expect do
|
||||||
|
click_on submit_casting_call_interview_form
|
||||||
|
end.to change(CastingCallInterview, :count).by(1)
|
||||||
|
expect(page).to have_content create_casting_call_interview_button
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def create_casting_call_interview_button
|
||||||
|
t 'admin.casting_call_interviews.index.actions.new'
|
||||||
|
end
|
||||||
|
|
||||||
|
def new_casting_call_interview_heading
|
||||||
|
t 'admin.casting_call_interviews.new.heading'
|
||||||
|
end
|
||||||
|
|
||||||
|
def submit_casting_call_interview_form
|
||||||
|
t 'helpers.submit.casting_call_interview.create'
|
||||||
|
end
|
||||||
|
|
||||||
|
def zoom_meeting_url_invalid_error
|
||||||
|
t 'casting_call_interviews.validation_errors.invalid_meeting_url'
|
||||||
|
end
|
||||||
|
|
||||||
|
def performer_name_field
|
||||||
|
'casting_call_interview[performer_name]'
|
||||||
|
end
|
||||||
|
|
||||||
|
def zoom_meeting_url_field
|
||||||
|
'casting_call_interview[zoom_meeting_url]'
|
||||||
|
end
|
||||||
|
|
||||||
|
def casting_call_field
|
||||||
|
'casting_call_interview[casting_call_id]'
|
||||||
|
end
|
||||||
|
end
|
||||||
114
spec/features/user_managing_casiting_calls_spec.rb
Normal file
114
spec/features/user_managing_casiting_calls_spec.rb
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
feature "User managing casting calls" do
|
||||||
|
let(:current_user) { create(:user) }
|
||||||
|
let(:project) { create(:project, account: current_user.primary_account) }
|
||||||
|
|
||||||
|
before :each do
|
||||||
|
sign_in current_user
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "casting calls table is visible" do
|
||||||
|
visit project_casting_calls_path(project)
|
||||||
|
|
||||||
|
expect(page).to have_content "Created On"
|
||||||
|
expect(page).to have_content "Title"
|
||||||
|
expect(page).to have_content "Status"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "sees list of casting calls" do
|
||||||
|
visit project_casting_calls_path(project)
|
||||||
|
|
||||||
|
expect(page).to have_content no_casting_calls_label
|
||||||
|
|
||||||
|
casting_call = create(:casting_call, project: project)
|
||||||
|
|
||||||
|
visit project_casting_calls_path(project)
|
||||||
|
|
||||||
|
expect(page).not_to have_content no_casting_calls_label
|
||||||
|
|
||||||
|
expect(page).to have_content casting_call.created_at.try(:strftime, '%D')
|
||||||
|
expect(page).to have_content casting_call.title
|
||||||
|
expect(page).to have_content casting_call.status
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "can create casting call requests" do
|
||||||
|
visit project_casting_calls_path(project)
|
||||||
|
|
||||||
|
expect(page).to have_content no_casting_calls_label
|
||||||
|
click_on add_new_casting_call_label
|
||||||
|
|
||||||
|
fill_in title_field, with: "Title"
|
||||||
|
fill_in description_field, with: "Description"
|
||||||
|
fill_in project_description_field, with: "Project Description"
|
||||||
|
fill_in interview_instructions_field, with: "Interview instructions"
|
||||||
|
fill_in interview_requirements_field, with: "Interview requirements"
|
||||||
|
fill_in questions_field, with: "Questions"
|
||||||
|
|
||||||
|
click_on "Create Casting call"
|
||||||
|
|
||||||
|
expect(page).to have_content("Your casting call request was successfully submitted. Thank you. A chat window will pop up on the lower right in a few seconds.")
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "can update casting call requests" do
|
||||||
|
create(:casting_call, title: "Title", project: project)
|
||||||
|
visit project_casting_calls_path(project)
|
||||||
|
|
||||||
|
click_on manage_button
|
||||||
|
click_on "Edit"
|
||||||
|
|
||||||
|
fill_in title_field, with: "New Title"
|
||||||
|
|
||||||
|
click_on "Update Casting call"
|
||||||
|
|
||||||
|
expect(page).to have_content("The casting call request has been updated")
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "can cancel a casting call request" do
|
||||||
|
create(:casting_call, title: "Title", project: project)
|
||||||
|
visit project_casting_calls_path(project)
|
||||||
|
|
||||||
|
click_on manage_button
|
||||||
|
click_on "Cancel"
|
||||||
|
|
||||||
|
expect(page).to have_content("The casting call request has been cancelled")
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def no_casting_calls_label
|
||||||
|
"Casting calls will appear here"
|
||||||
|
end
|
||||||
|
|
||||||
|
def manage_button
|
||||||
|
t "casting_calls.casting_call.actions.manage"
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_new_casting_call_label
|
||||||
|
t "casting_calls.index.actions.new"
|
||||||
|
end
|
||||||
|
|
||||||
|
def title_field
|
||||||
|
t "casting_calls.form.labels.title"
|
||||||
|
end
|
||||||
|
|
||||||
|
def description_field
|
||||||
|
t "casting_calls.form.labels.description"
|
||||||
|
end
|
||||||
|
|
||||||
|
def project_description_field
|
||||||
|
t "casting_calls.form.labels.project_description"
|
||||||
|
end
|
||||||
|
|
||||||
|
def interview_instructions_field
|
||||||
|
t "casting_calls.form.labels.interview_instructions"
|
||||||
|
end
|
||||||
|
|
||||||
|
def interview_requirements_field
|
||||||
|
t "casting_calls.form.labels.interview_requirements"
|
||||||
|
end
|
||||||
|
|
||||||
|
def questions_field
|
||||||
|
t "casting_calls.form.labels.questions"
|
||||||
|
end
|
||||||
|
end
|
||||||
60
spec/jobs/generate_interview_files_zip_job_spec.rb
Normal file
60
spec/jobs/generate_interview_files_zip_job_spec.rb
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
describe GenerateInterviewFilesZipJob do
|
||||||
|
let(:project) { create(:project) }
|
||||||
|
let(:download) { create(:download, project: project, release_type: "CastingCallInterview", name: "my-title_john-doe") }
|
||||||
|
let(:casting_call) { create(:casting_call, project: project, title: "My Title") }
|
||||||
|
let(:casting_call_interview) { create(:casting_call_interview, casting_call: casting_call, performer_name: "John Doe") }
|
||||||
|
|
||||||
|
before do
|
||||||
|
dir = Rails.root.join("spec", "fixtures", "files")
|
||||||
|
files = ["contract.pdf", "AppearanceRelease.pdf"]
|
||||||
|
# Attachments in the test environment do not persist to cloud storage
|
||||||
|
# Therefore we want to stub calls to `open` with a cloud storage URL
|
||||||
|
allow_any_instance_of(InterviewFilesCollectionService).to receive(:open).and_return(StringIO.new("file data"))
|
||||||
|
allow_any_instance_of(InterviewFilesCollectionService).to receive(:build).and_yield(dir, files)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe ".perform_later" do
|
||||||
|
it "enqueues a background job for generating zip file" do
|
||||||
|
expect {
|
||||||
|
GenerateInterviewFilesZipJob.perform_later(project, download, casting_call_interview)
|
||||||
|
}.to have_enqueued_job
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe ".perform_now" do
|
||||||
|
it "updates a download record and creates attachment for it" do
|
||||||
|
GenerateInterviewFilesZipJob.perform_now(project, download, casting_call_interview)
|
||||||
|
|
||||||
|
expect(download.project).to eq project
|
||||||
|
expect(download.release_type).to eq "CastingCallInterview"
|
||||||
|
expect(download.name).to eq "my-title_john-doe"
|
||||||
|
expect(download.status).to eq "success"
|
||||||
|
expect(download.file).to be_attached
|
||||||
|
end
|
||||||
|
|
||||||
|
context "When there are errors" do
|
||||||
|
let(:error) { StandardError.new("Casting Call Interview files not found.") }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(ProjectsChannel).to receive(:broadcast_download_generation_update).with(download, I18n.t("interview_downloads.download.failure"))
|
||||||
|
allow_any_instance_of(InterviewFilesCollectionService).to receive(:build).and_raise(StandardError, "Casting Call Interview files not found.")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "updates status to 'failure' and sends user a notification" do
|
||||||
|
GenerateInterviewFilesZipJob.perform_now(project, download, casting_call_interview)
|
||||||
|
|
||||||
|
expect(download.status).to eq "failure"
|
||||||
|
expect(ProjectsChannel).to have_received(:broadcast_download_generation_update).with(download, I18n.t("interview_downloads.download.failure"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
# Delete the file created in fixture.
|
||||||
|
# Or the tests will fail on next run due to already existing files in existing zip.
|
||||||
|
path = Rails.root.join("spec", "fixtures", "files")
|
||||||
|
File.delete("#{path}/my-title_john-doe.zip") if File.exists? "#{path}/my-title_john-doe.zip"
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -11,7 +11,7 @@ RSpec.describe SubmitHubspotFormJob, type: :job do
|
|||||||
allow(Hubspot::Form).to receive(:new).and_return(form)
|
allow(Hubspot::Form).to receive(:new).and_return(form)
|
||||||
allow(form).to receive(:submit).and_return(true)
|
allow(form).to receive(:submit).and_return(true)
|
||||||
|
|
||||||
SubmitHubspotFormJob.perform_now("John", "Doe", "email@test.com", "My Account")
|
SubmitHubspotFormJob.perform_now(first_name: "John", last_name: "Doe", email: "email@test.com", company: "My Account", form_guid: ENV["HUBSPOT_FORM_GUID"])
|
||||||
|
|
||||||
expect(Hubspot::Form).to have_received(:new).with("guid" => "hubspot_form_guid")
|
expect(Hubspot::Form).to have_received(:new).with("guid" => "hubspot_form_guid")
|
||||||
expect(form).to have_received(:submit).with(
|
expect(form).to have_received(:submit).with(
|
||||||
@@ -27,7 +27,7 @@ RSpec.describe SubmitHubspotFormJob, type: :job do
|
|||||||
allow(Hubspot::Form).to receive(:new).and_return(form)
|
allow(Hubspot::Form).to receive(:new).and_return(form)
|
||||||
allow(form).to receive(:submit).and_return(true)
|
allow(form).to receive(:submit).and_return(true)
|
||||||
|
|
||||||
SubmitHubspotFormJob.perform_now("John", "Doe", "email@test.com", "My Account", additional_param_one: "Foo", additional_param_two: "Bar")
|
SubmitHubspotFormJob.perform_now(first_name: "John", last_name: "Doe", email: "email@test.com", company: "My Account", form_guid: ENV["HUBSPOT_FORM_GUID"], additional_param_one: "Foo", additional_param_two: "Bar")
|
||||||
|
|
||||||
expect(form).to have_received(:submit).with(
|
expect(form).to have_received(:submit).with(
|
||||||
first_name: "John",
|
first_name: "John",
|
||||||
@@ -35,7 +35,7 @@ RSpec.describe SubmitHubspotFormJob, type: :job do
|
|||||||
email: "email@test.com",
|
email: "email@test.com",
|
||||||
company: "My Account",
|
company: "My Account",
|
||||||
additional_param_one: "Foo",
|
additional_param_one: "Foo",
|
||||||
additional_param_two: "Bar",
|
additional_param_two: "Bar"
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ RSpec.describe SubmitHubspotFormJob, type: :job do
|
|||||||
allow(Hubspot::Form).to receive(:new).and_return(form)
|
allow(Hubspot::Form).to receive(:new).and_return(form)
|
||||||
allow(form).to receive(:submit)
|
allow(form).to receive(:submit)
|
||||||
|
|
||||||
SubmitHubspotFormJob.perform_now("John", "Doe", "email@test.com", "My Account")
|
SubmitHubspotFormJob.perform_now(first_name: "John", last_name: "Doe", email: "email@test.com", company: "My Account", form_guid: ENV["HUBSPOT_FORM_GUID"])
|
||||||
|
|
||||||
expect(form).not_to have_received(:submit)
|
expect(form).not_to have_received(:submit)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
require 'rails_helper'
|
|
||||||
|
|
||||||
RSpec.describe SubmitHubspotTaskRequestFormJob, type: :job do
|
|
||||||
describe '#perform_now' do
|
|
||||||
before do
|
|
||||||
ENV["HUBSPOT_TASK_REQUEST_FORM_GUID"] = "hubspot_task_request_form_guid"
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'submits to the Hubspot API with the right params' do
|
|
||||||
form = double(:form)
|
|
||||||
allow(Hubspot::Form).to receive(:new).and_return(form)
|
|
||||||
allow(form).to receive(:submit).and_return(true)
|
|
||||||
|
|
||||||
SubmitHubspotTaskRequestFormJob.perform_now("email@test.com", "https://example.com/admin/task_requests/1")
|
|
||||||
|
|
||||||
expect(Hubspot::Form).to have_received(:new).with("guid" => "hubspot_task_request_form_guid")
|
|
||||||
expect(form).to have_received(:submit).with(
|
|
||||||
email: "email@test.com",
|
|
||||||
taskme_url: "https://example.com/admin/task_requests/1"
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when HUBSPOT_TASK_REQUEST_FORM_GUID is not available' do
|
|
||||||
it 'does not submit to the API' do
|
|
||||||
ENV["HUBSPOT_TASK_REQUEST_FORM_GUID"] = nil
|
|
||||||
form = double(:form)
|
|
||||||
allow(Hubspot::Form).to receive(:new).and_return(form)
|
|
||||||
allow(form).to receive(:submit)
|
|
||||||
|
|
||||||
SubmitHubspotTaskRequestFormJob.perform_now("email@test.com", "https://example.com/admin/task_requests/1")
|
|
||||||
|
|
||||||
expect(form).not_to have_received(:submit)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -135,7 +135,9 @@ RSpec.describe Account do
|
|||||||
MedicalRelease,
|
MedicalRelease,
|
||||||
MiscRelease,
|
MiscRelease,
|
||||||
MatchingRequest,
|
MatchingRequest,
|
||||||
ActionMailbox::InboundEmail # This is Rails model, we are not using it and it is NOT added to the Account#storage_total calculation
|
ActionMailbox::InboundEmail, # This is Rails model, we are not using it and it is NOT added to the Account#storage_total calculation
|
||||||
|
CastingCall,
|
||||||
|
CastingCallInterview
|
||||||
]
|
]
|
||||||
Rails.application.eager_load!
|
Rails.application.eager_load!
|
||||||
ActiveRecord::Base.descendants.each do |model|
|
ActiveRecord::Base.descendants.each do |model|
|
||||||
|
|||||||
13
spec/models/casting_call_interview_spec.rb
Normal file
13
spec/models/casting_call_interview_spec.rb
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe CastingCallInterview, type: :model do
|
||||||
|
subject { build(:casting_call_interview) }
|
||||||
|
describe "associations" do
|
||||||
|
it { is_expected.to belong_to(:casting_call) }
|
||||||
|
it { is_expected.to have_secure_token(:token) }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "validations" do
|
||||||
|
it { is_expected.to validate_presence_of(:performer_name) }
|
||||||
|
end
|
||||||
|
end
|
||||||
11
spec/models/casting_call_spec.rb
Normal file
11
spec/models/casting_call_spec.rb
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe CastingCall, type: :model do
|
||||||
|
describe "associations" do
|
||||||
|
it { is_expected.to belong_to(:project) }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "validations" do
|
||||||
|
it { is_expected.to have_secure_token(:token) }
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -19,6 +19,7 @@ RSpec.describe Project, type: :model do
|
|||||||
it { is_expected.to have_many(:broadcasts).dependent(:destroy) }
|
it { is_expected.to have_many(:broadcasts).dependent(:destroy) }
|
||||||
it { is_expected.to have_many(:downloads).dependent(:destroy) }
|
it { is_expected.to have_many(:downloads).dependent(:destroy) }
|
||||||
it { is_expected.to have_many(:zoom_meetings).dependent(:destroy) }
|
it { is_expected.to have_many(:zoom_meetings).dependent(:destroy) }
|
||||||
|
it { is_expected.to have_many(:casting_calls).dependent(:destroy) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "nested attributes" do
|
describe "nested attributes" do
|
||||||
|
|||||||
91
spec/policies/casting_call_policy_spec.rb
Normal file
91
spec/policies/casting_call_policy_spec.rb
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
describe CastingCallPolicy do
|
||||||
|
subject { described_class }
|
||||||
|
|
||||||
|
let(:user_context) { build(:user_context, user: user, account: user.primary_account) }
|
||||||
|
|
||||||
|
context "for an associate" do
|
||||||
|
let(:user) { create(:user, :associate, admin: false) }
|
||||||
|
|
||||||
|
permissions :index? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :create? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :show? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :destroy? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :update? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :cancel? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "for a project manager" do
|
||||||
|
let(:user) { create(:user, :manager, admin: false) }
|
||||||
|
|
||||||
|
permissions :index? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :create? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :show? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :destroy? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :update? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :cancel? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "for account managers" do
|
||||||
|
let(:user) { create(:user, :account_manager, admin: false) }
|
||||||
|
|
||||||
|
permissions :index? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :create? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :show? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :destroy? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :update? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :cancel? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user