Compare commits

..

3 Commits

Author SHA1 Message Date
Bilal
624922cc5c add splash screen to the casting calls 2020-07-28 12:01:51 +02:00
Senad Uka
4f1ebb27d0 Upstream sync 2020-07-27 10:18:49 +00:00
Senad Uka
95e9a70c4b Upstream cast me sync 2020-07-22 13:37:34 +00:00
24 changed files with 506 additions and 120 deletions

View File

@@ -40,7 +40,16 @@ class Admin::CastingSubmissionsController < Admin::ApplicationController
end end
def casting_submission_params def casting_submission_params
params.require(:casting_submission).permit(:casting_call_id, :performer_name, :interview_date, :zoom_meeting_url) params.require(:casting_submission).permit(
:casting_call_id, :performer_name, :interview_date,
:zoom_meeting_url, :interview_recording, :time_elapsed_1,
:time_elapsed_2, :time_elapsed_3, :time_elapsed_4, :time_elapsed_5,
:time_elapsed_6, :time_elapsed_7, :time_elapsed_8, :time_elapsed_9,
:time_elapsed_10, :time_elapsed_11, :time_elapsed_12, :time_elapsed_13,
:time_elapsed_14, :time_elapsed_15, :note_1 , :note_2 , :note_3 , :note_4,
:note_5, :note_6, :note_7, :note_8, :note_9, :note_10, :note_11, :note_12, :note_13,
:note_14, :note_15
)
end end
def casting_submissions def casting_submissions

View File

@@ -4,6 +4,7 @@ class CastingCallsController < ApplicationController
before_action :set_project before_action :set_project
before_action :build_casting_call, only: [:new, :create] before_action :build_casting_call, only: [:new, :create]
before_action :set_casting_call, only: [:show, :edit, :update, :cancel] before_action :set_casting_call, only: [:show, :edit, :update, :cancel]
before_action :show_splash_screen, only: :index
def index def index
@casting_calls = casting_calls.order_by_recent.paginate(page: params[:page]) @casting_calls = casting_calls.order_by_recent.paginate(page: params[:page])
@@ -17,8 +18,7 @@ class CastingCallsController < ApplicationController
if @casting_call.save if @casting_call.save
log_create_analytics log_create_analytics
castme_url = url_for([@project, @casting_call]) redirect_to [@project, :casting_calls], notice: t(".notice")
SubmitHubspotFormJob.perform_later(email: @casting_call.user_email, castme_url: castme_url, form_guid: ENV["HUBSPOT_CASTING_CALL_REQUEST_FORM_GUID"])
else else
render :new render :new
end end
@@ -46,6 +46,10 @@ class CastingCallsController < ApplicationController
private private
def show_splash_screen
render :splash if casting_calls.count.zero?
end
def casting_call_params def casting_call_params
params.require(:casting_call).permit(:title, :description, :project_description, :interview_instructions, :interview_requirements, :questions) params.require(:casting_call).permit(:title, :description, :project_description, :interview_instructions, :interview_requirements, :questions)
end end

View File

@@ -9,7 +9,11 @@ class CastingSubmissionsController < ApplicationController
end end
def show def show
@files = @casting_submission.files.paginate(page: params[:page]) @casting_call = @casting_submission.casting_call
@files = @casting_submission.files.order("created_at DESC").paginate(page: params[:files_page])
@markers = @casting_submission.markers
render layout: 'application'
end end
private private

View File

@@ -1,38 +1,25 @@
class CastingSubmission < ApplicationRecord class CastingSubmission < ApplicationRecord
belongs_to :casting_call belongs_to :casting_call
has_many_attached :files has_many_attached :files
has_one_attached :interview_recording
NUMBER_OF_MARKER_FIELDS = 15
has_secure_token has_secure_token
validates :performer_name, presence: true validates :performer_name, presence: true
validate :zoom_meeting_url_validation
scope :completed, -> { where.not(interviewed_at: nil) } 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 def zip_file_name
"#{self.casting_call.title.parameterize}_#{self.performer_name.parameterize}_#{Time.now.strftime('%Y-%m-%d_%H-%M-%S')}" "#{self.casting_call.title.parameterize}_#{self.performer_name.parameterize}_#{Time.now.strftime('%Y-%m-%d_%H-%M-%S')}"
end end
def zoom_meeting_url_validation def markers
# valid url format : (1..NUMBER_OF_MARKER_FIELDS).map do |n|
# https://us01web.zoom.us/j/12345?pwd=Ab103odw3ok343ko if public_send("time_elapsed_#{n}").present?
valid_url_regex = %r{^https\://[a-z0-9]+\.zoom.us/j/[0-9]+\?pwd\=.+} OpenStruct.new(id: n, time_elapsed: public_send("time_elapsed_#{n}"), note: public_send("note_#{n}") )
return true if zoom_meeting_url.match valid_url_regex
errors.add(:base, invalid_meeting_url_message)
end end
end.compact
private
def invalid_meeting_url_message
I18n.t('casting_submissions.validation_errors.invalid_meeting_url')
end end
end end

View File

@@ -6,6 +6,28 @@
<%= form.text_field :interview_date, class: "datepicker-control" %> <%= form.text_field :interview_date, class: "datepicker-control" %>
<%= form.text_field :zoom_meeting_url %> <%= form.text_field :zoom_meeting_url %>
<% unless casting_submission.new_record? %>
<%= form.file_field :interview_recording, accept: "video/mp4", data: { direct_upload_url: rails_direct_uploads_url, aws_bucket: ENV['AWS_BUCKET'], aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'], signer_url: multipart_signatures_url } %>
<% if casting_submission.interview_recording.attached? %>
<p>
<%= link_to casting_submission.interview_recording do %>
<%= fa_icon "file-text-o" %> <%= casting_submission.interview_recording.filename %>
<% end %>
<span class="text-muted"><%= fa_icon "long-arrow-left" %> <em>Current interview recording</em></span>
</p>
<% end %>
<hr>
<%= card_field_set_tag t(".casting_submission_markers.heading") do %>
<% (1..CastingSubmission::NUMBER_OF_MARKER_FIELDS).each do |n| %>
<div class="form-row">
<%= form.number_field "time_elapsed_#{n}", wrapper_class: "col-md-6", label: "Elapsed Time #{n} (in seconds)" %>
<%= form.text_area "note_#{n}", wrapper_class: "col-md-6", label: "Note #{n}" %>
</div>
<% end %>
<% end %>
<% end %>
<div class="row align-items-center text-center mt-4"> <div class="row align-items-center text-center mt-4">
<%= link_to t("shared.cancel"), [:admin, :casting_submissions], class: "col-3 text-reset" %> <%= link_to t("shared.cancel"), [:admin, :casting_submissions], class: "col-3 text-reset" %>
<div class="col-9"> <div class="col-9">

View File

@@ -9,7 +9,7 @@
<%= form.text_field :title %> <%= form.text_field :title %>
<%= form.text_area :description %> <%= form.text_area :description %>
<%= form.text_area :project_description %> <%= form.text_area :project_description %>
<%= field_set_tag "Chatbot" do %> <%= field_set_tag t(".headings.chatbot") do %>
<%= form.text_area :interview_instructions, rows: 6 %> <%= form.text_area :interview_instructions, rows: 6 %>
<%= form.text_area :questions, rows: 8 %> <%= form.text_area :questions, rows: 8 %>
<%= form.text_area :interview_requirements, rows: 6 %> <%= form.text_area :interview_requirements, rows: 6 %>

View File

@@ -1,2 +0,0 @@
<%= render "shared/initiate_hubspot_chat" %>
<p class="alert alert-success p-3 lead text-center"><%= t '.success_message' %></p>

View File

@@ -0,0 +1,58 @@
<div class="d-flex flex-row">
<div class="d-flex flex-column">
<%= product_wordmark :cast_me, prefix: t('.headings.welcome'), class: "h2" %>
<p class="text-muted"><%= t '.headings.subtitle' %>
</div>
<%= link_to t(".actions.book_demo"), 'https://meetings.hubspot.com/bray2', class: "btn btn-primary border align-self-center h-50 ml-auto mr-2 pb-2", target: '_blank' %>
<% if policy(CastingCall).new? %>
<%= link_to t(".actions.create_casting_call"), [:new, @project, :casting_call], class: "btn btn-success border align-self-center h-50 pb-2" %>
<% end %>
</div>
<hr>
<div class="pt-2">
<div class="row">
<div class="col">
<div class="card-body p-0">
<div class="embed-responsive embed-responsive-16by9">
<div class="embed-responsive-item">
<table class="w-100 h-100 bg-secondary">
<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 class="col">
<div class="row">
<div class="col">
<h3><%= t '.headings.how_it_works' %></h3>
<ol>
<li><%= t '.list_items.enter_information' %></li>
<li><%= t '.list_items.enter_questions' %></li>
<li><%= t '.list_items.copy_and_paste_submission_link' %></li>
<li><%= t '.list_items.wait_for_the_submission_video' %></li>
</ol>
</div>
</div>
<div class="row">
<div class="col">
<h3><%= t '.headings.benefits' %></h3>
<ul class="fa-ul ml-5">
<%= content_tag(:li, fa_icon("check li", text: t('.list_items.fewer_team_members_needed'))) %>
<%= content_tag(:li, fa_icon("check li", text: t('.list_items.fewer_resources_needed'))) %>
<%= content_tag(:li, fa_icon("check li", text: t('.list_items.more_time_spent_with_quality_candidates'))) %>
</ul>
</div>
</div>
</div>
</div>
</div>

View File

@@ -1,6 +1,12 @@
<tr> <li class="my-2" id="<%= dom_id(file) %>">
<td><%= file.filename %></td> <% if file.variable? %>
<td class="text-right"> <%= link_to image_tag(file.variant(resize_and_pad: [300, 300, background: "#F7F8F9"]), class: "bg-light img-thumbnail img-fluid"), file, target: "_blank" %>
<%= link_to fa_icon("download"), file, target: "_blank" %> <% else %>
</td> <div class="border rounded bg-light text-muted d-flex justify-content-center align-items-center fix-h-and-w">
</tr> <%= link_to file, target: "_blank" do %>
<%= fa_icon("file", style: "font-size: 2rem") %>
<div class="mt-2"><%= file.filename %></div>
<% end %>
</div>
<% end %>
</li>

View File

@@ -0,0 +1,14 @@
<div class="overflow-auto mh-30">
<ul class="list-unstyled d-flex flex-column align-items-center text-center" id="casting_submission_file_list_<%= casting_submission.id %>">
<% if files.present? %>
<%= render partial: "casting_submissions/file", collection: files %>
<% else %>
<li class="my-3">
Files will appear here.
</li>
<% end %>
</ul>
<div class="d-flex mt-2 justify-content-center" id="casting_submission_files_pagination_<%= casting_submission.id %>">
<%= will_paginate(files, param_name: 'files_page', params: { active_files_tab: casting_submission.id }) if files.present? %>
</div>
</div>

View File

@@ -0,0 +1,15 @@
<% if casting_submission.interview_recording.present? %>
<div id="casting_submission_video" class="embed-responsive-item"></div>
<% else %>
<div id="casting_submission_video" class="embed-responsive-item">
<table class="w-100 h-100 bg-secondary">
<tbody>
<tr>
<td class="text-center align-middle text-white">
Video player will appear here when the interview recording is available.
</td>
</tr>
</tbody>
</table>
</div>
<% end %>

View File

@@ -1,25 +1,92 @@
<div class="col-md-12"> <% content_for :header do %>
<h2 class="h6 mt-3">Files:</h2> <header class="container-fluid py-3 border-bottom sticky-top bg-light">
<div class="pt-2 mx-n3"> <div class="row align-items-center justify-content-center">
<table class="table table-striped tr-px-4 align-all-middle"> <div class="col-4 text-center">
<thead class="thead-light"> <%= product_wordmark(:cast_me, class: 'navbar-brand') %>
<tr> </div>
<th>Filename</th> </div>
<th></th> </header>
</tr> <% end %>
</thead>
<tbody id="task_requests"> <div class="row">
<% if @files.any? %> <div class="col-lg-8 col-md-12 mb-3">
<%= render partial: "file", collection: @files %> <div class="card shadow-sm">
<% else %> <div class="card-header">
<tr> <div class="d-flex justify-content-start flex-column">
<td colspan="12" class="py-4 text-center text-muted"><%= t(".empty") %></td> <h1 class="h2 mb-1"><%= @casting_submission.performer_name %></h1>
</tr> <h1 class="h6 mb-1"><%= @casting_call.title %></h1>
</div>
</div>
<div class="card-body p-0">
<div class="embed-responsive embed-responsive-16by9">
<%= render partial: 'casting_submissions/video', locals: { casting_submission: @casting_submission } %>
<% if @casting_submission.interview_recording.present? %>
<%= javascript_tag nonce: true do %>
var markerData = <%= raw @markers.to_json %>;
var player = new Clappr.Player({
parentId: '#casting_submission_video',
source: "<%= rails_blob_url(@casting_submission.interview_recording, host: AppHost.new.domain_with_port) %>",
plugins: {
core: [ClapprMarkersPlugin]
},
markersPlugin: {},
width: '100%',
height: '100%',
mute: true,
autoPlay: true,
hlsMinimumDvrSize: 1
});
markerData.forEach(function(marker, index) {
var markers = player.getPlugin("markers-plugin");
var marker = new ClapprMarkersPlugin.StandardMarker(Number(marker.table.time_elapsed), marker.table.note)
markers.addMarker(marker);
});
<% end %>
<% end %> <% end %>
</tbody> </div>
</table> </div>
<div class="mt-4" id="task_requests_pagiantion"> </div>
<%= will_paginate @files %> </div>
<div class="col-lg-4 col-md-12 mb-3">
<div class="card shadow-sm mb-3">
<div class="card-header">
<ul class="nav nav-tabs card-header-tabs">
<li class="nav-item">
<%= link_to "Home", "#home", class: class_string("nav-link", "active" => !params[:active_tab].present?), data: { toggle: "tab" } %>
</li>
<li class="nav-item">
<%= link_to "Files", "#files", class: class_string("nav-link", "active" => params[:active_tab] == "files"), data: { toggle: "tab" } %>
</li>
</ul>
</div>
<div class="card-body p-3">
<div class="tab-content">
<div class="<%= class_string("tab-pane fade show", "active" => !params[:active_tab].present?) %>" id="home">
<div class="row">
<div class="col-md-12">
<dl>
<%= description_list_pair_for @casting_call, :title, append: ":" %>
<%= description_list_pair_for @casting_call, :status, append: ":" %>
<%= description_list_pair_for @casting_call, :created_at, append: ":" %>
<%= description_list_pair_for @casting_call, :description, append: ":" %>
<%= description_list_pair_for @casting_call, :project_description, 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>
</div>
<div class="<%= class_string("tab-pane fade show", "active" => params[:active_tab] == 'files') %>" id="files">
<div class="tab-pane fade show active" id="files_casting_submission_<%= @casting_submission.id %>">
<%= render partial: 'casting_submissions/files_section', locals: { casting_submission: @casting_submission, files: @files } %>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -45,7 +45,7 @@
</div> </div>
</div> </div>
<div class="row align-items-center justify-content-center mt-3"> <div class="row align-items-center justify-content-center mt-3">
<%= link_to "Start Interview", @casting_submission.join_zoom_meeting_url, target: "_blank", class: "btn btn-primary" %> <%= link_to "Start Interview", @casting_submission.zoom_meeting_url, target: "_blank", class: "btn btn-primary" %>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -105,6 +105,9 @@ en:
notice: The casting submission has been completed notice: The casting submission has been completed
create: create:
notice: The casting submission has been created notice: The casting submission has been created
form:
casting_submission_markers:
heading: Markers
index: index:
actions: actions:
new: Create Casting Submission new: Create Casting Submission
@@ -247,13 +250,6 @@ en:
bulk_taggings: bulk_taggings:
new_bulk_tag_modal: new_bulk_tag_modal:
submit: Add submit: Add
casting_submissions:
index:
empty: Casting Submission results will appear here.
show:
empty: Casting Submission files and recorded meeetings will appear here.
validation_errors:
invalid_meeting_url: Zoom Meeting URL is invalid
casting_calls: casting_calls:
cancel: cancel:
notice: The casting call request has been cancelled successfully notice: The casting call request has been cancelled successfully
@@ -261,11 +257,12 @@ en:
actions: actions:
manage: Manage manage: Manage
create: create:
notice: The casting call request has been created notice: The casting call request has been created successfully.
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: edit:
heading: Edit Casting Call heading: Edit Casting Call
form: form:
headings:
chatbot: Chatbot Instructions
info_message: After submitting this casting call request, you'll be connected via chat with a ME Suite representative. info_message: After submitting this casting call request, you'll be connected via chat with a ME Suite representative.
index: index:
actions: actions:
@@ -277,6 +274,23 @@ en:
casting_call_title: Casting Title casting_call_title: Casting Title
new: new:
heading: New Casting Call heading: New Casting Call
splash:
actions:
book_demo: Schedule a Demo
create_casting_call: Create Casting Call
headings:
benefits: Benefits
how_it_works: How It Works
subtitle: The media industry's first automated casting bot
welcome: Welcome to
list_items:
copy_and_paste_submission_link: Copy and paste the submission link wherever you want
enter_information: Enter information about the role and project
enter_questions: Enter the questions you want the Chatbot to ask
fewer_resources_needed: Fewer resources needed for first round of casting search
fewer_team_members_needed: Fewer team members needed to cast large projects
more_time_spent_with_quality_candidates: More time spent with quality casting candidates
wait_for_the_submission_video: Wait for the casting bot to deliver you casting submission videos
update: update:
notice: The casting call request has been updated notice: The casting call request has been updated
casting_submission_downloads: casting_submission_downloads:

View File

@@ -76,9 +76,26 @@ 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_submissions: casting_calls:
validation_errors: index:
invalid_meeting_url: Zoom Meeting URL is invalid (ES) empty: Casting calls will appear here (ES)
splash:
actions:
book_demo: Schedule a Demo (ES)
create_casting_call: Create Casting Call (ES)
headings:
benefits: Benefits (ES)
how_it_works: How It Works (ES)
subtitle: The media industry's first automated casting bot (ES)
welcome: Welcome to (ES)
list_items:
copy_and_paste_submission_link: Copy and paste the submission link wherever you want (ES)
enter_information: Enter information about the role and project (ES)
enter_questions: Enter the questions you want the Chatbot to ask (ES)
fewer_resources_needed: Fewer resources needed for first round of casting search (ES)
fewer_team_members_needed: Fewer team members needed to cast large projects (ES)
more_time_spent_with_quality_candidates: More time spent with quality casting candidates (ES)
wait_for_the_submission_video: Wait for the casting bot to deliver you casting submission videos (ES)
contract_templates: contract_templates:
blank_contracts: blank_contracts:
create: create:

View File

@@ -0,0 +1,35 @@
class AddMarkersToCastingSubmissions < ActiveRecord::Migration[6.0]
def change
add_column :casting_submissions, :time_elapsed_1, :integer
add_column :casting_submissions, :time_elapsed_2, :integer
add_column :casting_submissions, :time_elapsed_3, :integer
add_column :casting_submissions, :time_elapsed_4, :integer
add_column :casting_submissions, :time_elapsed_5, :integer
add_column :casting_submissions, :time_elapsed_6, :integer
add_column :casting_submissions, :time_elapsed_7, :integer
add_column :casting_submissions, :time_elapsed_8, :integer
add_column :casting_submissions, :time_elapsed_9, :integer
add_column :casting_submissions, :time_elapsed_10, :integer
add_column :casting_submissions, :time_elapsed_11, :integer
add_column :casting_submissions, :time_elapsed_12, :integer
add_column :casting_submissions, :time_elapsed_13, :integer
add_column :casting_submissions, :time_elapsed_14, :integer
add_column :casting_submissions, :time_elapsed_15, :integer
add_column :casting_submissions, :note_1, :text
add_column :casting_submissions, :note_2, :text
add_column :casting_submissions, :note_3, :text
add_column :casting_submissions, :note_4, :text
add_column :casting_submissions, :note_5, :text
add_column :casting_submissions, :note_6, :text
add_column :casting_submissions, :note_7, :text
add_column :casting_submissions, :note_8, :text
add_column :casting_submissions, :note_9, :text
add_column :casting_submissions, :note_10, :text
add_column :casting_submissions, :note_11, :text
add_column :casting_submissions, :note_12, :text
add_column :casting_submissions, :note_13, :text
add_column :casting_submissions, :note_14, :text
add_column :casting_submissions, :note_15, :text
end
end

View File

@@ -608,7 +608,37 @@ CREATE TABLE public.casting_submissions (
created_at timestamp(6) without time zone NOT NULL, created_at timestamp(6) without time zone NOT NULL,
updated_at timestamp(6) without time zone NOT NULL, updated_at timestamp(6) without time zone NOT NULL,
token character varying, token character varying,
interviewed_at timestamp without time zone interviewed_at timestamp without time zone,
time_elapsed_1 integer,
time_elapsed_2 integer,
time_elapsed_3 integer,
time_elapsed_4 integer,
time_elapsed_5 integer,
time_elapsed_6 integer,
time_elapsed_7 integer,
time_elapsed_8 integer,
time_elapsed_9 integer,
time_elapsed_10 integer,
time_elapsed_11 integer,
time_elapsed_12 integer,
time_elapsed_13 integer,
time_elapsed_14 integer,
time_elapsed_15 integer,
note_1 text,
note_2 text,
note_3 text,
note_4 text,
note_5 text,
note_6 text,
note_7 text,
note_8 text,
note_9 text,
note_10 text,
note_11 text,
note_12 text,
note_13 text,
note_14 text,
note_15 text
); );
@@ -4050,6 +4080,7 @@ INSERT INTO "schema_migrations" (version) VALUES
('20200706193123'), ('20200706193123'),
('20200706230803'), ('20200706230803'),
('20200707070522'), ('20200707070522'),
('20200714175331'); ('20200714175331'),
('20200722193459');

View File

@@ -37,16 +37,6 @@ RSpec.describe Admin::CastingSubmissionsController, type: :controller do
post :create, params: { casting_submission: casting_submission_params } post :create, params: { casting_submission: casting_submission_params }
}.to change(CastingSubmission, :count) }.to change(CastingSubmission, :count)
end end
it "does not create new record if zoom meeting url is not valid" do
expect {
post :create, params: {
casting_submission: casting_submission_params
.except(:zoom_meeting_url)
.merge(zoom_meeting_url: "malformed_url")
}
}.to change(CastingSubmission, :count).by(0)
end
end end
describe "#edit" do describe "#edit" do

View File

@@ -18,7 +18,7 @@ RSpec.describe CastingCallsController, type: :controller do
expect(response).to be_successful expect(response).to be_successful
end end
it "renders content" do it "renders content if there are existing broadcasts" do
create(:casting_call, project: project) create(:casting_call, project: project)
get :index, params: { project_id: project } get :index, params: { project_id: project }
@@ -36,6 +36,18 @@ RSpec.describe CastingCallsController, type: :controller do
expect(response.body).to have_link("2", href: project_casting_calls_path(project, page: 2)) expect(response.body).to have_link("2", href: project_casting_calls_path(project, page: 2))
end end
end end
context "when there are no records" do
it "renders splash screen" do
CastingCall.destroy_all
get :index, params: { project_id: project }
expect(response.body).not_to have_content no_casting_calls_message
expect(response.body).to have_link create_casting_call
expect(response.body).to have_link schedule_demo
end
end
end end
describe "#new" do describe "#new" do
@@ -60,12 +72,6 @@ RSpec.describe CastingCallsController, type: :controller do
post :create, params: { project_id: project.id, casting_call: casting_call_params } 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") }.to have_enqueued_job(TrackAnalyticsJob).with(user, account, :track_create_casting_call, user_agent: "Rails Testing", user_ip: "0.0.0.0")
end 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 end
describe "#update" do describe "#update" do
@@ -123,4 +129,16 @@ RSpec.describe CastingCallsController, type: :controller do
def update_params def update_params
{ description: "This is updated description" } { description: "This is updated description" }
end end
def no_casting_calls_message
t 'casting_calls.index.empty'
end
def create_casting_call
t 'casting_calls.splash.actions.create_casting_call'
end
def schedule_demo
t 'casting_calls.splash.actions.book_demo'
end
end end

View File

@@ -36,8 +36,9 @@ RSpec.describe CastingSubmissionsController, type: :controller do
it "shows files of casting submission" do it "shows files of casting submission" do
get :show, params: { project_id: project, id: casting_submission.id } get :show, params: { project_id: project, id: casting_submission.id }
expect(response.body).to have_content("Filename") expect(response.body).to have_content(casting_submission.performer_name)
expect(response.body).to have_content("location_photo.png") expect(response.body).to have_content(casting_submission.casting_call.title)
expect(response.body).to have_content(casting_submission.casting_call.project_description)
end end
end end
end end

View File

@@ -2,6 +2,7 @@ FactoryBot.define do
factory :casting_call do factory :casting_call do
association :project association :project
user_email 'test@email.com' user_email 'test@email.com'
title 'Casting Call Title'
description "Casting call description" description "Casting call description"
project_description "Casting call project description" project_description "Casting call project description"
interview_instructions "Interview instructions" interview_instructions "Interview instructions"

View File

@@ -9,5 +9,9 @@ FactoryBot.define do
trait :with_files do trait :with_files do
files { [Rack::Test::UploadedFile.new('spec/fixtures/files/location_photo.png', 'image/png')] } files { [Rack::Test::UploadedFile.new('spec/fixtures/files/location_photo.png', 'image/png')] }
end end
trait :with_interview_recording do
interview_recording { Rack::Test::UploadedFile.new('spec/fixtures/files/video_file.mp4', 'video/mp4') }
end
end end
end end

View File

@@ -8,35 +8,57 @@ feature "Admin managing casting submissions" do
sign_in current_user sign_in current_user
end end
scenario "admin cannot create casting submission with invalid zoom url", js: true do scenario "when creating new casting call interview - interview recording field is not visible" do
visit admin_casting_submissions_path visit admin_casting_submissions_path
cc = create(:casting_call, title: "SpecialCastingCall")
click_link create_casting_submission_button click_on create_casting_submission_button
expect(page).to have_content new_casting_submission_heading expect(page).to have_content new_casting_submission_heading
expect(page).not_to have_field interview_recording_field
end
fill_in performer_name_field, with: "TestName" scenario "admin can upload interview recording video when editing casting call interview" do
select cc.title, from: casting_call_field cc = create(:casting_call)
fill_in zoom_meeting_url_field, with: "malformed url" cci = create(:casting_submission, casting_call: cc)
expect do expect(CastingSubmission.last.interview_recording).not_to be_attached
click_on submit_casting_submission_form
end.to change(CastingSubmission, :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" visit edit_admin_casting_submission_path(cci)
expect do expect(page).to have_content edit_casting_submission_heading
click_on submit_casting_submission_form expect(page).to have_field interview_recording_field
end.to change(CastingSubmission, :count).by(0) expect(page).not_to have_content current_interview_recording_label
expect(page).to have_content zoom_meeting_url_invalid_error attach_file interview_recording_field, Rails.root.join(file_fixture('video_file.mp4'))
click_on update_casting_submission_button
expect(page).to have_content casting_submission_updated_message
expect(CastingSubmission.last.interview_recording).to be_attached
end
fill_in zoom_meeting_url_field, with: "https://s01.zoom.us/j/343434?pwd=dawidj34ijij" scenario "when editing casting call interview with already uploaded interview video, interview recording file name link is shown below file field" do
cc = create(:casting_call)
cci = create(:casting_submission, :with_interview_recording, casting_call: cc)
expect do expect(CastingSubmission.last.interview_recording).to be_attached
click_on submit_casting_submission_form
end.to change(CastingSubmission, :count).by(1) visit edit_admin_casting_submission_path(cci)
expect(page).to have_content create_casting_submission_button
expect(page).to have_content edit_casting_submission_heading
expect(page).to have_content current_interview_recording_label
expect(page).to have_link CastingSubmission.last.interview_recording.attachment.blob.filename.to_s
end
scenario "when admin opens view page for casting submission, it does not fail if zoom meeting URL is invalid" do
cc = create(:casting_call)
cci = create(:casting_submission, casting_call: cc, zoom_meeting_url: "anything")
visit admin_casting_submissions_path
click_on manage_button
click_link view_link
expect(page).to have_content casting_submission_details_header
expect(page).to have_content interview_files_label
expect(page).to have_content cci.performer_name
end end
private private
@@ -49,6 +71,14 @@ feature "Admin managing casting submissions" do
t 'admin.casting_submissions.new.heading' t 'admin.casting_submissions.new.heading'
end end
def edit_casting_submission_heading
'Edit Casting Submission'
end
def update_casting_submission_button
'Update Casting submission'
end
def submit_casting_submission_form def submit_casting_submission_form
t 'helpers.submit.casting_submission.create' t 'helpers.submit.casting_submission.create'
end end
@@ -68,4 +98,32 @@ feature "Admin managing casting submissions" do
def casting_call_field def casting_call_field
'casting_submission[casting_call_id]' 'casting_submission[casting_call_id]'
end end
def casting_submission_updated_message
t 'admin.casting_submissions.update.notice'
end
def interview_recording_field
'casting_submission[interview_recording]'
end
def current_interview_recording_label
'Current interview recording'
end
def manage_button
'Manage'
end
def view_link
'View'
end
def casting_submission_details_header
'Casting submission details'
end
def interview_files_label
'INTERVIEW FILES:'
end
end end

View File

@@ -1,14 +1,15 @@
require "rails_helper" require "rails_helper"
feature "User managing casting calls" do feature "User managing casting calls" do
let(:current_user) { create(:user) } let(:current_user) { create(:user, :manager) }
let(:project) { create(:project, account: current_user.primary_account) } let(:project) { create(:project, members: current_user, account: current_user.primary_account) }
before :each do before :each do
sign_in current_user sign_in current_user
end end
scenario "casting calls table is visible" do scenario "casting calls table is visible if there are existing casting calls" do
create(:casting_call, project: project)
visit project_casting_calls_path(project) visit project_casting_calls_path(project)
expect(page).to have_content "Created On" expect(page).to have_content "Created On"
@@ -16,11 +17,14 @@ feature "User managing casting calls" do
expect(page).to have_content "Status" expect(page).to have_content "Status"
end end
scenario "sees list of casting calls" do scenario "splash page is shown if there are no existing records" do
visit project_casting_calls_path(project) visit project_casting_calls_path(project)
expect(page).to have_content no_casting_calls_label expect(page).to have_content schedule_demo
expect(page).to have_content create_casting_call
end
scenario "sees list of casting calls" do
casting_call = create(:casting_call, project: project) casting_call = create(:casting_call, project: project)
visit project_casting_calls_path(project) visit project_casting_calls_path(project)
@@ -35,7 +39,6 @@ feature "User managing casting calls" do
scenario "can create casting call requests" do scenario "can create casting call requests" do
visit project_casting_calls_path(project) visit project_casting_calls_path(project)
expect(page).to have_content no_casting_calls_label
click_on add_new_casting_call_label click_on add_new_casting_call_label
fill_in title_field, with: "Casting Title" fill_in title_field, with: "Casting Title"
@@ -47,7 +50,7 @@ feature "User managing casting calls" do
click_on "Create Casting call" 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.") expect(page).to have_content("The casting call request has been created successfully.")
end end
scenario "can update casting call requests" do scenario "can update casting call requests" do
@@ -92,6 +95,28 @@ feature "User managing casting calls" do
expect(page).to have_content cc.questions expect(page).to have_content cc.questions
end end
context 'When the user is associate' do
let(:current_user) { create(:user, :associate) }
it 'does show button to create new casting call' do
visit project_casting_calls_path(project)
expect(page).to have_content schedule_demo
expect(page).to have_content create_casting_call
end
end
context 'When the user is account manager' do
let(:current_user) { create(:user, :account_manager) }
it 'does show button to create new casting call' do
visit project_casting_calls_path(project)
expect(page).to have_content schedule_demo
expect(page).to have_content create_casting_call
end
end
context "when signed out" do context "when signed out" do
scenario "user opens public accessible casting call URL" do scenario "user opens public accessible casting call URL" do
cc = create(:casting_call, title: "Dummy title", project: project) cc = create(:casting_call, title: "Dummy title", project: project)
@@ -114,7 +139,7 @@ feature "User managing casting calls" do
private private
def no_casting_calls_label def no_casting_calls_label
"Casting calls will appear here" t 'casting_calls.index.empty'
end end
def manage_button def manage_button
@@ -152,4 +177,12 @@ feature "User managing casting calls" do
def questions_field def questions_field
t "helpers.label.casting_call.questions" t "helpers.label.casting_call.questions"
end end
def create_casting_call
t 'casting_calls.splash.actions.create_casting_call'
end
def schedule_demo
t 'casting_calls.splash.actions.book_demo'
end
end end