Compare commits

...

7 Commits

Author SHA1 Message Date
Bilal
0bda6c3480 rebase 2020-09-01 23:07:50 +03:00
Bilal
98afad4174 remove 2020-09-01 23:07:50 +03:00
Bilal
3471e21429 improve download releases button 2020-09-01 23:07:50 +03:00
Senad Uka
f611382e9e Upstream sync 2020-09-01 17:15:16 +02:00
Senad Uka
95a14ab2f6 Upstream sync 2020-08-31 18:19:00 +02:00
Senad Uka
896cec2259 Upstream sync 2020-08-25 05:24:49 +02:00
Senad Uka
a493076f9b Upstream sync 2020-08-24 15:52:23 +02:00
87 changed files with 1096 additions and 1451 deletions

View File

@@ -24,6 +24,8 @@ $(document).on "turbolinks:load", ->
stream_selected = $("#broadcast_video").data('videoType') == 'stream'; stream_selected = $("#broadcast_video").data('videoType') == 'stream';
if data.streamer_status == 'recording' && data.status == 'active' && stream_selected if data.streamer_status == 'recording' && data.status == 'active' && stream_selected
$("#broadcast_video").html data.video_content $("#broadcast_video").html data.video_content
$("#live_take").html data.live_take_content
new (Clappr.Player)( new (Clappr.Player)(
<%= "baseUrl: 'http://cdn.clappr.io/latest'," if Rails.env.test? %> <%= "baseUrl: 'http://cdn.clappr.io/latest'," if Rails.env.test? %>
parentId: '#broadcast_video' parentId: '#broadcast_video'
@@ -35,6 +37,7 @@ $(document).on "turbolinks:load", ->
hlsMinimumDvrSize: 1) hlsMinimumDvrSize: 1)
if data.streamer_status == "idle" && data.status == "idle" if data.streamer_status == "idle" && data.status == "idle"
$("#broadcast_video").html data.video_content $("#broadcast_video").html data.video_content
$("#live_take").html data.live_take_content
showBroadcastRecordings: (data) -> showBroadcastRecordings: (data) ->
$(".flash-message").html data.flash_content $(".flash-message").html data.flash_content

View File

@@ -0,0 +1,20 @@
$(document).on("click", "#download_releases", function(event) {
event.preventDefault();
const releasable_ids = JSON.parse($("#selected_releases_form").attr('data-releasable-ids'));
const total_entries = $('#total_entries').val();
const input_ids = $('<input>').attr({ type: 'hidden', name: 'release_ids', value: JSON.stringify(releasable_ids) });
const search_query = $('<input>').attr({ type: 'hidden', name: 'search_query', value: $("form input[type='search']").val() });
const type_filter = $('<input>').attr({ type: 'hidden', name: 'type_filter', value: $('#type_filter_value').val() });
const download_count = releasable_ids.length > 0 ? releasable_ids.length : total_entries;
$(this).parent().append(input_ids);
$(this).parent().append(search_query);
$(this).parent().append(type_filter);
if (confirm(`${download_count} release(s) will be downloaded. Is this correct?`)){
Rails.fire($(this).parent()[0], 'submit');
}
});

View File

@@ -0,0 +1,4 @@
$(document).on("click", "#director_mode_switch", function() {
// JQuery click event trigger was not working.
document.getElementById("director_mode_link").click();
});

View File

@@ -412,6 +412,16 @@ a[data-behavior=seekable-timecode] {
background-color: rgba($black, 0.05); background-color: rgba($black, 0.05);
} }
// Black background
.bg-black {
background-color: $black;
}
// White background
.bg-white {
background-color: $white;
}
// Custom width // Custom width
.w-65 { .w-65 {
width: 65% !important; width: 65% !important;
@@ -422,8 +432,32 @@ a[data-behavior=seekable-timecode] {
max-height: 30rem; max-height: 30rem;
} }
// Max-width 75%
.max-w-75 {
max-width: 75%;
}
// Fix height and width // Fix height and width
.fix-h-and-w { .fix-h-and-w {
width: 308px; width: 308px;
height:308px; height:308px;
} }
// Dropdown shown state overrride
.override-dropdown-show-state {
color: $white !important;
background-color: $black !important;
border-color: transparent !important;
}
// Override custom switch color
.override-custom-control-label::before {
background-color: #000000;
}
// Override nav tab design
.override-nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active {
background: transparent;
border-color: transparent;
border-bottom: 3px solid #ff0000;
}

View File

@@ -11,6 +11,7 @@ class BroadcastsChannel < ApplicationCable::Channel
def self.broadcast_stream_updates(broadcast) def self.broadcast_stream_updates(broadcast)
status_content = ApplicationController.render partial: "broadcasts/broadcast_status", locals: { broadcast: broadcast } status_content = ApplicationController.render partial: "broadcasts/broadcast_status", locals: { broadcast: broadcast }
video_content = ApplicationController.render partial: "broadcasts/video", locals: { broadcast: broadcast } video_content = ApplicationController.render partial: "broadcasts/video", locals: { broadcast: broadcast }
live_take = ApplicationController.render partial: "broadcasts/live_take", locals: { broadcast: broadcast }
broadcast_to broadcast, { broadcast_to broadcast, {
event: :broadcast_stream_update, event: :broadcast_stream_update,
@@ -18,6 +19,7 @@ class BroadcastsChannel < ApplicationCable::Channel
playback_url: broadcast.stream_playback_url, playback_url: broadcast.stream_playback_url,
full_live_stream_playback_url: broadcast.full_live_stream_playback_url, full_live_stream_playback_url: broadcast.full_live_stream_playback_url,
video_content: video_content, video_content: video_content,
live_take_content: live_take,
status_content: status_content, status_content: status_content,
streamer_status: broadcast.streamer_status streamer_status: broadcast.streamer_status
} }

View File

@@ -4,6 +4,7 @@ require './lib/knock_monkeypatch'
class Api::UserTokenController < Knock::AuthTokenController class Api::UserTokenController < Knock::AuthTokenController
include Oath::ControllerHelpers include Oath::ControllerHelpers
include RememberMe::Controller
skip_before_action :verify_authenticity_token skip_before_action :verify_authenticity_token
before_action :sign_in_user before_action :sign_in_user

View File

@@ -6,9 +6,12 @@ class ApprovalsController < ApplicationController
def create def create
@releasable.approve_by(current_user) @releasable.approve_by(current_user)
@releasable.approved_by_user_signature.attach(approved_by_user_signature_params) if signature_data.present?
if @releasable.save if @releasable.save(context: :approval)
redirect_to [@project, "#{@releasable_param.name.pluralize}"], notice: t('.release_approved', release_type: @releasable.model_name.human) redirect_to [@project, "#{@releasable_param.name.pluralize}"], notice: t('.release_approved', release_type: @releasable.model_name.human)
else
render :new
end end
end end
@@ -25,4 +28,21 @@ class ApprovalsController < ApplicationController
def set_project def set_project
@project = @releasable.project @project = @releasable.project
end end
def releasable_params
params.require(releasable_param.name).permit(approved_by_user_signature: :data)
end
def signature_data
releasable_params.dig(:approved_by_user_signature, :data)
end
def approved_by_user_signature_params
{
data: signature_data,
filename: "approved_by_user_signature.png",
content_type: "image/png",
identify: false,
}
end
end end

View File

@@ -0,0 +1,34 @@
class BroadcastRecordingStarringsController < ApplicationController
layout "project"
before_action :set_project
before_action :set_broadcast
before_action :set_recording
def create
@recording.toggle_star
set_recordings
end
private
def broadcast_recording_params
params.require(:broadcast_recording).permit(:name, :description)
end
def set_project
@project = policy_scope(Project).find(params[:project_id])
end
def set_broadcast
@broadcast = authorize policy_scope(@project.broadcasts).find(params[:broadcast_id])
end
def set_recording
@recording = authorize policy_scope(@broadcast.broadcast_recordings).find(params[:broadcast_recording_id])
end
def set_recordings
@recordings = @broadcast.broadcast_recordings.visible.order_by_recent.paginate(page: params[:page])
end
end

View File

@@ -5,13 +5,25 @@ class BroadcastRecordingsController < ApplicationController
before_action :set_broadcast before_action :set_broadcast
before_action :set_recording before_action :set_recording
def edit
end
def update
@recording.update(broadcast_recording_params)
set_recordings
end
def destroy def destroy
@recording.update(hidden: true) @recording.update(hidden: true)
@recordings = @broadcast.broadcast_recordings.visible.order_by_recent.paginate(page: params[:page]) set_recordings
end end
private private
def broadcast_recording_params
params.require(:broadcast_recording).permit(:name, :description)
end
def set_project def set_project
@project = policy_scope(Project).find(params[:project_id]) @project = policy_scope(Project).find(params[:project_id])
end end
@@ -23,4 +35,8 @@ class BroadcastRecordingsController < ApplicationController
def set_recording def set_recording
@recording = authorize policy_scope(@broadcast.broadcast_recordings).find(params[:id]) @recording = authorize policy_scope(@broadcast.broadcast_recordings).find(params[:id])
end end
def set_recordings
@recordings = @broadcast.broadcast_recordings.visible.order_by_recent.paginate(page: params[:page])
end
end end

View File

@@ -32,6 +32,7 @@ class BroadcastsController < ApplicationController
@conference_url = conference_url_for(@broadcast) @conference_url = conference_url_for(@broadcast)
@recordings = @broadcast.broadcast_recordings.visible.order_by_recent.paginate(page: params[:page]) @recordings = @broadcast.broadcast_recordings.visible.order_by_recent.paginate(page: params[:page])
@files = @broadcast.files.order("created_at DESC").paginate(page: params[:files_page]) @files = @broadcast.files.order("created_at DESC").paginate(page: params[:files_page])
render layout: 'application' render layout: 'application'
end end
@@ -113,7 +114,7 @@ class BroadcastsController < ApplicationController
end end
def conference_url_for(broadcast) def conference_url_for(broadcast)
broadcast.video_conference_url_override || url_for([broadcast.project, broadcast, :zoom_meeting]) broadcast.video_conference_url_override.presence || url_for([broadcast.project, broadcast, :zoom_meeting])
end end
def log_create_analytics def log_create_analytics

View File

@@ -7,28 +7,41 @@ class ContractDownloadsController < ApplicationController
def create def create
authorize policy_scope(Download).create authorize policy_scope(Download).create
fetch_releases
download = @project.downloads.create!(release_type: release_type)
download = @project.downloads.create!(release_type: params[:release_type])
other_downloads_in_progress = @project.downloads.unfinished_desc_order.offset(1) other_downloads_in_progress = @project.downloads.unfinished_desc_order.offset(1)
if other_downloads_in_progress.any? if other_downloads_in_progress.any?
in_progress_downloads_details = render_to_string "_other_pending_downloads", locals: { downloads: other_downloads_in_progress, release_type: params[:release_type] }, :layout => false in_progress_downloads_details = render_to_string "_other_pending_downloads", locals: { downloads: other_downloads_in_progress, release_type: release_type }, :layout => false
ProjectsChannel.broadcast_download_generation_update(download, in_progress_downloads_details) ProjectsChannel.broadcast_download_generation_update(download, in_progress_downloads_details)
else else
ProjectsChannel.broadcast_download_generation_update(download, I18n.t("contract_downloads.download.pending", release_type: params[:release_type].titleize)) ProjectsChannel.broadcast_download_generation_update(download, I18n.t("contract_downloads.download.pending", release_type: release_type.titleize))
end end
GenerateContractsZipJob.perform_later(@project, download, params[:release_type], @releases.ids) GenerateContractsZipJob.perform_later(@project, download, release_type, release_ids, search_query, type_filter)
end end
private private
def fetch_releases def release_type
@releases = policy_scope(@project.public_send(releases)) params[:release_type]
end end
def releases def search_query
params[:release_type].constantize.model_name.plural params[:search_query]
end
def type_filter
params[:type_filter]
end
def release_ids
JSON.parse(params[:release_ids])
rescue StandardError
[]
end
def release_name(release_type)
release_type.constantize.model_name.plural
end end
end end

View File

@@ -106,7 +106,7 @@ class MaterialReleasesController < ApplicationController
:term_id, :term_text, :term_id, :term_text,
:restriction_id, :restriction_text, :restriction_id, :restriction_text,
:description, :description,
:contract, { photos: [] } :contract, files: []
) )
end end

View File

@@ -44,7 +44,7 @@ class Public::BroadcastsController < Public::BaseController
end end
def conference_url_for(broadcast) def conference_url_for(broadcast)
broadcast.video_conference_url_override || broadcast_zoom_meeting_url(broadcast.token) broadcast.video_conference_url_override.presence || broadcast_zoom_meeting_url(broadcast.token)
end end
class MultiViewBroadcast class MultiViewBroadcast

View File

@@ -92,7 +92,7 @@ class Public::MaterialReleasesController < Public::BaseController
params.require(:material_release).permit(person_params, guardian_params, second_guardian_params, :minor, params.require(:material_release).permit(person_params, guardian_params, second_guardian_params, :minor,
:name, :address_street1, :address_street2, :address_city, :address_state, :address_zip, :address_country, :name, :address_street1, :address_street2, :address_city, :address_state, :address_zip, :address_country,
:signature_base64, :signature_base64,
:locale, :contract_template, :description, photos: [] :locale, :contract_template, :description, files: []
) )
end end

View File

@@ -17,6 +17,7 @@ module TagsHelper
disable_with: disabled_content, disable_with: disabled_content,
}, },
form: { form: {
id: "selected_releases_form",
data: { data: {
releasable_ids: [], releasable_ids: [],
}, },

View File

@@ -7,13 +7,14 @@ class GenerateContractsZipJob < ApplicationJob
@project = job.arguments.first @project = job.arguments.first
@download = job.arguments.second @download = job.arguments.second
@release_type = job.arguments.third @release_type = job.arguments.third
@folder_name = "#{@project.name.parameterize}_#{get_release_name(@release_type).gsub('_', '-')}" @release_ids = job.arguments.fourth
@search_query = job.arguments.fifth
@type_filter = job.arguments[5]
@folder_name = "#{@project.name.parameterize}_#{release_name.gsub('_', '-')}"
@download.update!(name: @folder_name, status: :pending) @download.update!(name: @folder_name, status: :pending)
end end
def perform(project, download, release_type, release_ids) def perform(project, download, release_type, release_ids, search_query, type_filter)
releases = project.public_send(get_release_name(release_type)).where(id: release_ids)
::ReleaseContractCollectionService.new(releases, @folder_name).build do |dir, files| ::ReleaseContractCollectionService.new(releases, @folder_name).build do |dir, files|
zipfile_name = "#{dir}/#{@folder_name}.zip" zipfile_name = "#{dir}/#{@folder_name}.zip"
Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile| Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
@@ -31,7 +32,7 @@ class GenerateContractsZipJob < ApplicationJob
end end
rescue StandardError => e rescue StandardError => e
Rails.logger.error("Failed to generate download for project (##{project.id}) with release type #{release_type}\n" + e.message) Rails.logger.error("Failed to generate download for project (##{project.id}) with release type #{release_type}\n" + e.message)
@download.failure! @download.failure!
ProjectsChannel.broadcast_download_generation_update(@download, I18n.t("contract_downloads.download.failure")) ProjectsChannel.broadcast_download_generation_update(@download, I18n.t("contract_downloads.download.failure"))
end end
@@ -61,7 +62,32 @@ class GenerateContractsZipJob < ApplicationJob
end end
end end
def get_release_name(release_type) def release_name
release_type.constantize.model_name.plural @release_type.constantize.model_name.plural
end
def all_releases
@project.public_send(release_name)
end
def releases
if @release_ids.any?
return all_releases.where(id: @release_ids)
end
results = all_releases
if all_releases.respond_to?(:complete, :incomplete)
results = case @type_filter
when 'complete'
all_releases.complete
when 'incomplete'
all_releases.incomplete
else
all_releases
end
end
results = results.search(@search_query) if @search_query.present?
results
end end
end end

View File

@@ -15,7 +15,8 @@ class AcquiredMediaRelease < ApplicationRecord
include SecondGuardianPhotoable include SecondGuardianPhotoable
include GuardianName include GuardianName
include SecondGuardianName include SecondGuardianName
include FilesFilterable
class << self class << self
def custom_csv_exportable_headers def custom_csv_exportable_headers
%i[name files_count owner_info] %i[name files_count owner_info]
@@ -106,16 +107,4 @@ class AcquiredMediaRelease < ApplicationRecord
def files_count def files_count
files.any? ? files.size : I18n.t('acquired_media_releases.acquired_media_release.no_media') files.any? ? files.size : I18n.t('acquired_media_releases.acquired_media_release.no_media')
end end
def image_files
files_blobs.where("content_type ILIKE ?", "%image%")
end
def video_files
files_blobs.where("content_type ILIKE ?", "%video%")
end
def other_files
files_blobs.where("NOT content_type ILIKE ANY (array[?])", ["%image%", "%video%"])
end
end end

View File

@@ -7,8 +7,10 @@ class BroadcastRecording < ApplicationRecord
scope :visible, -> { where(hidden: false) } scope :visible, -> { where(hidden: false) }
before_save :set_title_and_description
def download_url def download_url
"https://stream.mux.com/#{asset_playback_uid}/#{file_name}?download=#{download_file_name}" "https://stream.mux.com/#{asset_playback_uid}/#{file_name}?download=#{name}"
end end
def playback_url def playback_url
@@ -16,6 +18,21 @@ class BroadcastRecording < ApplicationRecord
end end
def download_file_name def download_file_name
"#{broadcast_name}_Date_#{created_at.in_time_zone(broadcast.shoot_location_time_zone).strftime("%Y-%m-%d")}_Time_#{created_at.in_time_zone(broadcast.shoot_location_time_zone).strftime("%T")}".parameterize "#{broadcast_name}_Date_#{Time.now.in_time_zone(broadcast.shoot_location_time_zone).strftime("%Y-%m-%d")}_Time_#{Time.now.in_time_zone(broadcast.shoot_location_time_zone).strftime("%T")}".parameterize
end
def toggle_star
toggle! :starred
end
def thumbnail_url(width = 300)
"https://image.mux.com/#{asset_playback_uid}/thumbnail.jpg?width=#{width}"
end
private
def set_title_and_description
self.name ||= download_file_name
self.description ||= "No description provided for this recording."
end end
end end

View File

@@ -1,15 +1,24 @@
module Approvable module Approvable
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do
include ActiveStorageSupport::SupportForBase64
has_one_base64_attached :approved_by_user_signature
# Requires signature when saving in the approval context
with_options on: :approval do
validates :approved_by_user_signature, attached: true
end
def approve_by(user) def approve_by(user)
return unless approved_at.nil? return unless approved_at.nil?
self.approved_by_user_name = user.full_name self.approved_by_user_name = user.full_name
self.approved_by_user_email = user.email self.approved_by_user_email = user.email
self.approved_at = Time.zone.now self.approved_at = BigMediaTime.time_zone_now
end end
def approved? def approved?
self.approved_at.present? self.approved_at.present?
end end

View File

@@ -0,0 +1,17 @@
module FilesFilterable
extend ActiveSupport::Concern
included do
def image_files
files_blobs.where("content_type ILIKE ?", "%image%")
end
def video_files
files_blobs.where("content_type ILIKE ?", "%video%")
end
def other_files
files_blobs.where("NOT content_type ILIKE ANY (array[?])", ["%image%", "%video%"])
end
end
end

View File

@@ -3,7 +3,7 @@ class MaterialRelease < ApplicationRecord
include Contractable include Contractable
include Exploitable include Exploitable
include Notable include Notable
include Photoable include Photoable # This association needs to be removed after changing the API. Removing it right now will cause failure in API specs.
include Releasable include Releasable
include Searchable include Searchable
include Signable include Signable
@@ -16,11 +16,11 @@ class MaterialRelease < ApplicationRecord
include SecondGuardianPhotoable include SecondGuardianPhotoable
include GuardianName include GuardianName
include SecondGuardianName include SecondGuardianName
include FilesFilterable
class << self class << self
def custom_csv_exportable_headers def custom_csv_exportable_headers
%i[name owner_info] %i[name owner_info files_count]
end end
end end
@@ -56,6 +56,8 @@ class MaterialRelease < ApplicationRecord
%w[guardian_2_address_zip zip], %w[guardian_2_address_zip zip],
%w[guardian_2_address_country country] %w[guardian_2_address_country country]
] ]
has_many_attached :files
# We don't care for the argument but method WILL receive option name # We don't care for the argument but method WILL receive option name
# when called from inside with_option block, hence * argument # when called from inside with_option block, hence * argument
@@ -92,4 +94,8 @@ class MaterialRelease < ApplicationRecord
def uses_edl? def uses_edl?
true true
end end
def files_count
files.any? ? files.size : I18n.t('material_releases.material_release.no_media')
end
end end

View File

@@ -1,9 +1,21 @@
class BroadcastRecordingPolicy < ApplicationPolicy class BroadcastRecordingPolicy < ApplicationPolicy
def create?
true
end
def destroy? def destroy?
if user.nil? || user.user.nil? if user.nil? || user.user.nil?
return false return false
end end
user.manager? || user.account_manager? user.manager? || user.account_manager?
end end
def edit?
destroy?
end
def update?
edit?
end
end end

View File

@@ -19,12 +19,16 @@ class MaterialReleasePolicy < ReleasePolicy
user.manager? || user.account_manager? user.manager? || user.account_manager?
end end
def edit_photos? def edit_files?
true true
end end
def update_files?
edit_files?
end
def update_photos? def update_photos?
edit_photos? edit_files?
end end
def tag_multiple? def tag_multiple?

View File

@@ -24,7 +24,7 @@ class ReleaseContractCollectionService
end end
files = Dir.entries("#{dir}/").select { |f| !File.directory? f } files = Dir.entries("#{dir}/").select { |f| !File.directory? f }
raise StandardError.new "Contracts or Contract Templates not found." unless files.any? # raise StandardError.new "Contracts or Contract Templates not found." unless files.any?
yield(dir, files) yield(dir, files)
} }
end end

View File

@@ -1,5 +1,6 @@
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<input id="total_entries" type=hidden value=<%= @appearance_releases.total_entries %> />
<div id="upload-progress-container" class="mb-1"></div> <div id="upload-progress-container" class="mb-1"></div>
<div class="d-md-flex d-sm-flex flex-sm-column flex-md-row flex-md-wrap mb-2"> <div class="d-md-flex d-sm-flex flex-sm-column flex-md-row flex-md-wrap mb-2">
<% if policy(AppearanceRelease).new? %> <% if policy(AppearanceRelease).new? %>
@@ -16,7 +17,7 @@
<% end %> <% end %>
<% if @appearance_releases.any? && policy(AppearanceRelease).download_multiple? %> <% if @appearance_releases.any? && policy(AppearanceRelease).download_multiple? %>
<%= link_to "Download All", [@project, :contract_downloads, release_type: @appearance_releases.name], method: :post, remote: true, class: "btn btn-light border mr-2 mb-2", data: { disable_with: "Please wait..." } %> <%= button_to "Download", [@project, :contract_downloads, release_type: @appearance_releases.name], id: "download_releases", method: :post, remote: true, class: "btn btn-light border mr-2 mb-2", data: { disable_with: "Please wait..." } %>
<% end %> <% end %>
</div> </div>
</div> </div>

View File

@@ -3,3 +3,5 @@ $("form input[type='search']").val("<%= params[:query] %>");
$("#type_filter_actions").html("<%= j render 'type_filter_actions' %>"); $("#type_filter_actions").html("<%= j render 'type_filter_actions' %>");
$("#appearance_releases_pagination").html("<%= j will_paginate(@appearance_releases) %>"); $("#appearance_releases_pagination").html("<%= j will_paginate(@appearance_releases) %>");
$('#type_filter_value').val("<%= params[:type_filter] %>"); $('#type_filter_value').val("<%= params[:type_filter] %>");
$("#selected_releases_form").attr('data-releasable-ids', JSON.stringify([]));
$("#total_entries").val(<%= @appearance_releases.total_entries %>);

View File

@@ -1,9 +1,13 @@
<div class="card shadow-sm"> <div class="card shadow-sm">
<%= card_header text: t(".heading", release_type: @releasable_param.name.titleize), close_action_path: [@project, "#{@releasable_param.name.pluralize}"] %> <%= card_header text: t(".heading", release_type: @releasable_param.name.titleize), close_action_path: [@project, "#{@releasable_param.name.pluralize}"] %>
<div class="card-body"> <div class="card-body">
<embed class="embeded-contract-preview" type="application/pdf" src="<%= url_for [@releasable, :contracts, format: "pdf"] %>" width="90%" height="1200" /> <embed class="embeded-contract-preview mb-3" type="application/pdf" src="<%= url_for [@releasable, :contracts, format: "pdf"] %>" width="90%" height="1200" />
<%= errors_summary_for @releasable %>
<%= bootstrap_form_with model: @releasable, method: :post, url: public_send("#{@releasable_param.name}_approvals_path", @releasable), local: true do |form| %> <%= bootstrap_form_with model: @releasable, method: :post, url: public_send("#{@releasable_param.name}_approvals_path", @releasable), local: true do |form| %>
<%= card_field_set_tag 'Signature' do %>
<%= render "shared/signature_fields", form: form, signature_field: 'approved_by_user_signature[data]' %>
<% 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"), [@releasable.project, "#{@releasable_param.name.pluralize}"], class: "col-3 text-reset" %> <%= link_to t("shared.cancel"), [@releasable.project, "#{@releasable_param.name.pluralize}"], class: "col-3 text-reset" %>
<div class="col-9"> <div class="col-9">
@@ -12,4 +16,4 @@
</div> </div>
<% end %> <% end %>
</div> </div>
</div> </div>

View File

@@ -0,0 +1 @@
$("#broadcast_recordings").html("<%= j render(partial: 'broadcasts/broadcast_recordings', locals: { recordings: @recordings, broadcast: @broadcast }) %>");

View File

@@ -0,0 +1,24 @@
<%= content_tag :div, class: "modal modal-right", id: "edit_broadcast_recording_modal", aria: { labelledby: "modalLabel", hidden: true }, role: "dialog", tabindex: -1 do %>
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalLabel">Edit Broadcast Recording</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<%= bootstrap_form_with model: [broadcast.project, broadcast, recording], layout: :horizontal, label_col: "col-3", control_col: "col-9" do |form| %>
<div class="modal-body">
<div id="broadcast_recording_fields">
<%= form.text_field :name %>
<%= form.text_area :description %>
</div>
</div>
<div class="modal-footer">
<%= form.button "Close", class: "btn btn-secondary", data: { dismiss: "modal" } %>
<%= form.submit "Update Broadcast Recording", class: "btn btn-primary", data: { disable_with: t("shared.disable_with") } %>
</div>
<% end %>
</div>
</div>
<% end %>

View File

@@ -0,0 +1,11 @@
$('[data-id="<%= dom_id(@recording) %>"]').remove();
<% if @recordings.empty? %>
$("#broadcast_recordings_nav").append('<p class="dropdown-item text-muted">Recordings will appear here</p>')
<% end %>
$("#broadcast_recordings").html("<%= j render(partial: 'broadcasts/broadcast_recordings', locals: { recordings: @recordings, broadcast: @broadcast }) %>");
// Close and remove the modal
$("#edit_broadcast_recording_modal").on("hidden.bs.modal", function (e) {
$("#edit_broadcast_recording_modal").remove();
});
$("#edit_broadcast_recording_modal").modal("hide");

View File

@@ -1,6 +1 @@
var dom_id = "<%= dom_id(@recording) %>" <%= render("broadcast_recordings/refresh_recordings_list") %>
$('[data-id="' + dom_id + '"]').remove();
<% if @recordings.empty? %>
$("#broadcast_recordings_nav").append('<p class="dropdown-item text-muted">Recordings will appear here</p>')
<% end %>
$("#broadcast_recordings").html("<%= j render(partial: 'broadcasts/broadcast_recordings', locals: { recordings: @recordings, broadcast: @broadcast }) %>");

View File

@@ -0,0 +1,6 @@
<% # Remove the modal if it already exists %>
$("#edit_broadcast_recording_modal").remove();
<% # Create and show the modal %>
$("body").append("<%= j render(partial: 'edit_broadcast_recording_modal', locals: { project: @project, broadcast: @broadcast, recording: @recording }) %>");
$("#edit_broadcast_recording_modal").modal("toggle");

View File

@@ -0,0 +1 @@
<%= render("broadcast_recordings/refresh_recordings_list") %>

View File

@@ -1,3 +1 @@
<%= link_to broadcast_recording.download_file_name, "javascript:void(0);", class: "dropdown-item", data: { behavior: "play_recording", playback_url: broadcast_recording.playback_url, id: dom_id(broadcast_recording) } %> <%= link_to broadcast_recording.name, "javascript:void(0);", class: "dropdown-item", data: { behavior: "play_recording", playback_url: broadcast_recording.playback_url, id: dom_id(broadcast_recording) } %>

View File

@@ -1,18 +1,29 @@
<% if recordings.present? %> <% if recordings.present? %>
<p>Click below to download the recordings of the live stream.</p> <div class="list-group">
<ul class="mt-2">
<% recordings.each do |recording| %> <% recordings.each do |recording| %>
<li> <div class="list-group-item list-group-item-action">
<%= link_to(recording.download_file_name, recording.download_url, target: "_blank") %> <div class="d-flex align-items-start">
<% if (controller.class.module_parent.to_s != "Public" && policy(BroadcastRecording).destroy?) %> <% if (controller.class.module_parent.to_s != "Public" && policy(BroadcastRecording).update?) %>
<%= link_to "Hide", [broadcast.project, broadcast, recording], class: "btn-sm btn-primary ml-1 text-decoration-none", remote: true, method: :delete, data: { confirm: t('.confirm_hide') } %> <%= link_to fa_icon("#{recording.starred ? 'star' : 'star-o'} fw"), [broadcast.project, broadcast, recording, :broadcast_recording_starrings], method: :post, class: "text-warning mr-3", remote: true %>
<% end %> <% end %>
</li> <%= image_tag(recording.thumbnail_url, class: 'img-thumbnail img-fluid max-w-75') %>
<div class="ml-auto">
<% if (controller.class.module_parent.to_s != "Public" && policy(BroadcastRecording).edit?) %>
<%= link_to fa_icon('edit'), [:edit, broadcast.project, broadcast, recording], remote: true %>
<% end %>
<%= link_to(fa_icon('download'), recording.download_url, target: "_blank") %>
</div>
</div>
<div class="d-flex flex-column align-items-start justify-content-start p-4">
<h5><%= recording.name %></h5>
<p><%= recording.description %></p>
</div>
</div>
<% end %> <% end %>
</ul> </div>
<div id="recordings_pagination" class="row mt-5 justify-content-center"> <div id="recordings_pagination" class="row mt-5 justify-content-center">
<%= will_paginate(recordings, params: {controller: "broadcasts", action: "show", project_id: broadcast.project_id, id: broadcast.id, page: params[:page], active_tab: 'recordings'}) %> <%= will_paginate(recordings, params: {controller: "broadcasts", action: "show", project_id: broadcast.project_id, id: broadcast.id, page: params[:page], active_tab: 'recordings'}) %>
</div> </div>
<% else %> <% else %>
<p>Recording of the live stream will appear here.</p> <p class="mt-4">Recording of the live stream will appear here.</p>
<% end %> <% end %>

View File

@@ -1,21 +1,13 @@
<% if broadcast.streamer_connected? || (broadcast.streamer_recording? && !broadcast.active?) %> <% if broadcast.streamer_connected? || (broadcast.streamer_recording? && !broadcast.active?) %>
<div class="alert alert-info text-center text-md-left"> <p class="mb-1">Live stream has connected successfully and will be available soon.</p>
<%= fa_icon "info-circle" %> <div class="badge badge-pill badge-success mb-2 text-uppercase">Connected</div>
<strong>Live stream has connected successfully and will be available soon.</strong>
</div>
<% elsif broadcast.streamer_recording? && broadcast.active? %> <% elsif broadcast.streamer_recording? && broadcast.active? %>
<div class="alert alert-success text-center text-md-left"> <p class="mb-1">Live stream has begun, click play to watch it.</p>
<%= fa_icon "success" %> <div class="badge badge-pill badge-danger mb-2 text-uppercase">Live</div>
<strong>Live stream has begun, click play to watch it.</strong>
</div>
<% elsif broadcast.streamer_disconnected? %> <% elsif broadcast.streamer_disconnected? %>
<div class="alert alert-warning text-center text-md-left"> <p class="mb-1">Live stream got disconnected.</p>
<%= fa_icon "warning" %> <div class="badge badge-pill badge-warning mb-2 text-uppercase">Disconnected</div>
<strong>Live stream got disconnected.</strong>
</div>
<% elsif (broadcast.idle? && broadcast.streamer_idle?) || (broadcast.created? && broadcast.streamer_idle?) %> <% elsif (broadcast.idle? && broadcast.streamer_idle?) || (broadcast.created? && broadcast.streamer_idle?) %>
<div class="alert alert-info text-center text-md-left"> <p class="mb-1">Live stream is waiting to begin.</p>
<%= fa_icon "info-circle" %> <div class="badge badge-pill badge-primary mb-2 text-uppercase">Idle</div>
<strong>Live stream is waiting to begin.</strong> <% end %>
</div>
<% end %>

View File

@@ -0,0 +1,12 @@
<div class="list-group">
<div class="list-group-item list-group-item-action flex-column align-items-start">
<div class="d-flex w-100 justify-content-between mb-1">
<h5 class="mb-1"><%= broadcast.name %></h5>
<small>Created - <%= time_ago_in_words(broadcast.created_at) + " ago" %></small>
</div>
<div id="broadcast_updates">
<%= render partial: 'broadcasts/broadcast_status', locals: { broadcast: broadcast } %>
</div>
</div>
</div>
<hr/>

View File

@@ -9,7 +9,7 @@
<table class="w-100 h-100 bg-secondary"> <table class="w-100 h-100 bg-secondary">
<tbody> <tbody>
<tr> <tr>
<td class="text-center align-middle text-white"> <td class="text-center align-middle text-white bg-black">
Video player will appear here when the stream becomes available. Video player will appear here when the stream becomes available.
</td> </td>
</tr> </tr>

View File

@@ -14,159 +14,135 @@
<% end %> <% end %>
<% content_for :header do %> <% content_for :header do %>
<header class="container-fluid py-3 border-bottom sticky-top bg-light"> <header></header>
<div class="row align-items-center justify-content-center">
<div class="col-4 text-center">
<%= product_wordmark(:direct_me, class: 'navbar-brand') %>
</div>
</div>
</header>
<% end %> <% end %>
<div class="row"> <div class="row no-gutters m-n3">
<div class="col-lg-8 col-md-12 mb-3"> <div class="col-lg-8 col-md-12 bg-black">
<div class="card shadow-sm"> <div class="d-flex justify-content-start align-items-center flex-row p-3 mb-5 bg-dark">
<div class="card-header"> <%= product_wordmark(:direct_me, class: 'navbar-brand text-white') %>
<div class="d-flex justify-content-between align-items-center"> <div class="ml-4 dropdown">
<h1 class="h3 m-0"><%= @broadcast.name %></h1> <%= link_to "#", class: "btn btn-light dropdown-toggle text-white bg-black border-0 override-dropdown-show-state", role: "button", id: "dropdownMenuLink", data: { toggle: "dropdown" }, aria: { haspopup: "true", expanded: "false" } do %>
<div class="dropdown"> <i class="fa fa-video-camera text-primary" aria-hidden="true"></i><span class="ml-2" id="selected_stream"><%= @broadcast.name %></span>
<%= link_to "Switch View", "#", class: "btn btn-light border dropdown-toggle", role: "button", id: "dropdownMenuLink", data: { toggle: "dropdown" }, aria: { haspopup: "true", expanded: "false" } %> <% end %>
<div class="dropdown-menu" aria-labelledby="dropdownMenuLink"> <div class="dropdown-menu bg-black" aria-labelledby="dropdownMenuLink">
<h5 class="dropdown-header">Live Streams</h5> <h5 class="dropdown-header">Live Streams</h5>
<%= link_to fa_icon("check", text: @broadcast.name.titleize), "#", data: { behavior: "play_stream"}, class: "dropdown-item active" %> <%= link_to fa_icon("check", text: @broadcast.name.titleize), "#", data: { behavior: "play_stream"}, class: "dropdown-item active" %>
<% @multi_view_broadcasts.each do |broadcast| %> <% @multi_view_broadcasts.each do |broadcast| %>
<% if broadcast.id != @broadcast.id %> <% if broadcast.id != @broadcast.id %>
<%= link_to broadcast.name.titleize, broadcast.url, data: { behavior: "play_stream"}, class: class_string("dropdown-item", "active" => @broadcast.id == broadcast.id) %> <% if params[:director_mode] %>
<% if controller.class.module_parent.to_s == "Public" %>
<%= link_to broadcast.name.titleize, url_for(params.permit!.merge(director_mode: true, token: broadcast.token)), data: { behavior: "play_stream"}, class: class_string("dropdown-item", "active" => @broadcast.id == broadcast.id) %>
<% else %>
<%= link_to broadcast.name.titleize, url_for(params.permit!.merge(director_mode: true, id: broadcast.id)), data: { behavior: "play_stream"}, class: class_string("dropdown-item", "active" => @broadcast.id == broadcast.id) %>
<% end %>
<% else %>
<% if controller.class.module_parent.to_s == "Public" %>
<%= link_to broadcast.name.titleize, url_for(params.permit!.merge(token: broadcast.token).except(:director_mode)), data: { behavior: "play_stream"}, class: class_string("dropdown-item", "active" => @broadcast.id == broadcast.id) %>
<% else %>
<%= link_to broadcast.name.titleize, url_for(params.permit!.merge(id: broadcast.id).except(:director_mode)), data: { behavior: "play_stream"}, class: class_string("dropdown-item", "active" => @broadcast.id == broadcast.id) %>
<% end %> <% end %>
<% end %> <% end %>
<% if @broadcast.director_mode_video_embed.present? %>
<h5 class="dropdown-header">Director Mode</h5>
<% unless params[:director_mode] %>
<%= link_to "Enable Director Mode", url_for(params.permit!.merge(director_mode: true)), class: "dropdown-item" %>
<% else %>
<%= link_to "Disable Director Mode", url_for(params.permit!.except(:director_mode)), class: "dropdown-item" %>
<% end %>
<% end %>
<h5 class="dropdown-header">Previous Sessions</h5>
<div id="broadcast_recordings_nav">
<% if @recordings.any? %>
<%= render partial: "broadcasts/broadcast_recording_nav", collection: @recordings, as: :broadcast_recording %>
<% else %>
<p class="dropdown-item text-muted">Recordings will appear here</p>
<% end %>
</div>
</div>
</div>
</div>
</div>
<div class="card-body p-0">
<div class="embed-responsive embed-responsive-16by9">
<%= render partial: 'broadcasts/video', locals: { broadcast: @broadcast } %>
<% if @broadcast.streamer_recording? && @broadcast.active? %>
<%= javascript_tag nonce: true do %>
new Clappr.Player({
parentId: '#broadcast_video',
source: "<%= @broadcast.stream_playback_url %>",
width: '100%',
height: '100%',
mute: true,
autoPlay: true,
hlsMinimumDvrSize: 1
});
<% end %> <% end %>
<% end %> <% end %>
</div> </div>
</div> </div>
<% if @broadcast.director_mode_video_embed.present? %>
<% if params[:director_mode] %>
<div class="custom-control custom-switch ml-auto">
<input type="checkbox" name="director_mode" value="true" class="custom-control-input" id="director_mode_switch" checked="checked" />
<label class="custom-control-label text-white override-custom-control-label" for="director_mode_switch">Director Mode</label>
</div>
<%= link_to "Disable Director Mode", url_for(params.permit!.except(:director_mode)), class: "d-none", id: "director_mode_link" %>
<% else %>
<div class="custom-control custom-switch ml-auto">
<input type="checkbox" name="director_mode" value="true" class="custom-control-input" id="director_mode_switch" />
<label class="custom-control-label text-white override-custom-control-label" for="director_mode_switch">Director Mode</label>
</div>
<%= link_to "Enable Director Mode", url_for(params.permit!.merge(director_mode: true)), class: "d-none", id: "director_mode_link" %>
<% end %>
<% end %>
</div>
<div class="embed-responsive embed-responsive-16by9" id="video_content">
<%= render partial: 'broadcasts/video', locals: { broadcast: @broadcast } %>
<% if @broadcast.streamer_recording? && @broadcast.active? %>
<%= javascript_tag nonce: true do %>
new Clappr.Player({
parentId: '#broadcast_video',
source: "<%= @broadcast.full_live_stream_playback_url %>",
width: '100%',
height: '100%',
mute: true,
autoPlay: true,
hlsMinimumDvrSize: 1
});
<% end %>
<% end %>
</div> </div>
</div> </div>
<div class="col-lg-4 col-md-12 mb-3"> <div class="col-lg-4 col-md-12 bg-white p-3 min-vh-100 overflow-auto">
<div class="card shadow-sm mb-3"> <% unless controller.class.module_parent.to_s == "Public" %>
<div class="card-header"> <% if @multi_view_broadcasts.present? %>
<ul class="nav nav-tabs card-header-tabs"> <% tokens = @multi_view_broadcasts.map(&:token) %>
<li class="nav-item"> <div class="btn-group">
<%= link_to "Home", "#home", class: class_string("nav-link", "active" => !params[:active_tab].present?), data: { toggle: "tab" } %> <button type="button" class="btn btn-primary" id="broadcast_share_url" data-behavior="clipboard" href="<%= broadcast_url(@broadcast.token, multi_view_tokens: tokens) %>">Share URL</button>
</li> <button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<li class="nav-item"> <span class="sr-only">Toggle Dropdown</span>
<%= link_to "Previous Sessions", "#recordings", class: class_string("nav-link", "active" => params[:active_tab] == "recordings"), data: { toggle: "tab" } %> </button>
</li> <div class="dropdown-menu">
</ul> <%= link_to t('.actions.reset_url'), [@project, @broadcast], method: :patch, class: "dropdown-item" %>
</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 id="broadcast_updates">
<%= render partial: 'broadcasts/broadcast_status', locals: { broadcast: @broadcast } %>
</div>
<% unless controller.class.module_parent.to_s == "Public" %>
<hr>
<div class="form-group">
<label for="broadcast_share_url">To share the stream, copy the URL below. Anyone with the link can view the stream.</label>
<div class="input-group">
<% if @multi_view_broadcasts.present? %>
<% tokens = @multi_view_broadcasts.map(&:token) %>
<input type="text" class="form-control" value="<%= broadcast_url(@broadcast.token, multi_view_tokens: tokens) %>" readonly>
<div class="input-group-append">
<button type="button" id="broadcast_share_url" class="btn btn-success" data-behavior="clipboard" href="<%= broadcast_url(@broadcast.token, multi_view_tokens: tokens) %>">
<i class="fa fa-clipboard"></i>
Copy URL
</button>
<%= link_to t('.actions.reset_url'), [@project, @broadcast], method: :patch, class: "btn btn-danger" %>
</div>
<% else %>
<input type="text" class="form-control" value="<%= broadcast_url(@broadcast.token) %>" readonly>
<div class="input-group-append">
<button type="button" id="broadcast_share_url" class="btn btn-success" data-behavior="clipboard" href="<%= broadcast_url(@broadcast.token) %>">
<i class="fa fa-clipboard"></i>
Copy URL
</button>
<%= link_to t('.actions.reset_url'), [@project, @broadcast], method: :patch, class: "btn btn-danger" %>
</div>
<% end %>
</div>
</div>
<hr>
<% end %>
<p class="card-text">If you want to join the ZOOM meeting dedicated to this broadcast, follow the link below.</p>
<%= link_to 'Video Conference', @conference_url, class: 'btn btn-primary btn-block', target: '_blank' %>
</div>
<div class="<%= class_string("tab-pane fade show", "active" => params[:active_tab] == 'recordings') %>" id="recordings">
<div id="broadcast_recordings">
<%= render partial: 'broadcasts/broadcast_recordings', locals: { recordings: @recordings, broadcast: @broadcast } %>
</div>
</div> </div>
</div> </div>
<% else %>
<div class="btn-group">
<button type="button" class="btn btn-primary" id="broadcast_share_url" data-behavior="clipboard" href="<%= broadcast_url(@broadcast.token) %>">Share URL</button>
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="sr-only">Toggle Dropdown</span>
</button>
<div class="dropdown-menu">
<%= link_to t('.actions.reset_url'), [@project, @broadcast], method: :patch, class: "dropdown-item" %>
</div>
</div>
<% end %>
<% end %>
<%= link_to 'Video Conference', @conference_url, class: 'btn btn-primary', target: '_blank' %>
<hr/>
<ul class="nav nav-tabs override-nav-tabs mb-3">
<li class="nav-item">
<%= link_to "Takes", "#recordings", 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 class="tab-content">
<div class="<%= class_string("tab-pane fade show", "active" => !params[:active_tab].present?) %>" id="recordings">
<div id="live_take">
<%= render partial: 'broadcasts/live_take', locals: { broadcast: @broadcast } %>
</div>
<div id="broadcast_recordings">
<%= render partial: 'broadcasts/broadcast_recordings', locals: { recordings: @recordings, broadcast: @broadcast } %>
</div>
</div> </div>
</div> <div class="<%= class_string("tab-pane fade show", "active" => params[:active_tab] == "files") %>" id="files">
<% if @multi_view_broadcasts.present? %>
<!-- files section --> <ul class="nav nav-tabs">
<div id="files" class="card shadow-sm mb-3">
<div class="card-header">
<h2 class="h5">Files</h2>
<% if @multi_view_broadcasts %>
<ul class="nav nav-tabs card-header-tabs">
<% @multi_view_broadcasts.each_with_index do |mvb, index| %> <% @multi_view_broadcasts.each_with_index do |mvb, index| %>
<li class="nav-item"> <li class="nav-item">
<%= link_to mvb.name, "#files_broadcast_#{mvb.token}", class: class_string("nav-link", "active" => (params[:active_files_tab] == mvb.token || (params[:active_files_tab].nil? && index == 0))), data: { toggle: "tab" } %> <%= link_to mvb.name, "#files_broadcast_#{mvb.token}", class: class_string("nav-link", "active" => (params[:active_files_tab] == mvb.token || (params[:active_files_tab].nil? && index == 0))), data: { toggle: "tab" } %>
</li> </li>
<% end %> <% end %>
</ul> </ul>
<% end %> <div class="tab-content pt-4">
</div>
<div class="card-body p-3">
<div class="tab-content">
<% if @multi_view_broadcasts.present? %>
<% @multi_view_broadcasts.each_with_index do |mvb, index| %> <% @multi_view_broadcasts.each_with_index do |mvb, index| %>
<div class="<%= class_string("tab-pane fade show", "active" => (params[:active_files_tab] == mvb.token || (params[:active_files_tab].nil? && index == 0))) %>" id="files_broadcast_<%= mvb.token %>"> <div class="<%= class_string("tab-pane fade show", "active" => (params[:active_files_tab] == mvb.token || (params[:active_files_tab].nil? && index == 0))) %>" id="files_broadcast_<%= mvb.token %>">
<%= render partial: 'broadcasts/files_section', locals: { broadcast: mvb, files: mvb.files } %> <%= render partial: 'broadcasts/files_section', locals: { broadcast: mvb, files: mvb.files } %>
</div> </div>
<% end %> <% end %>
<% else %> </div>
<div class="tab-pane fade show active" id="files_broadcast_<%= @broadcast.id %>"> <% else %>
<%= render partial: 'broadcasts/files_section', locals: { broadcast: @broadcast, files: @files } %> <%= render partial: 'broadcasts/files_section', locals: { broadcast: @broadcast, files: @files } %>
</div> <% end %>
<% end %>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -10,4 +10,10 @@
<%= description_list_pair t('.description_labels.issued_to'), releasable.name %> <%= description_list_pair t('.description_labels.issued_to'), releasable.name %>
<%= description_list_pair t('.description_labels.issued_by'), releasable.approved_by_user_name %> <%= description_list_pair t('.description_labels.issued_by'), releasable.approved_by_user_name %>
<%= description_list_pair t('.description_labels.date_issued'), releasable.approved_at %> <%= description_list_pair t('.description_labels.date_issued'), releasable.approved_at %>
</dl> </dl>
<% if preview %>
<%= image_tag dummy_signature %>
<% elsif releasable.approved_by_user_signature.attached? %>
<%= image_tag releasable.approved_by_user_signature.variant(auto_orient: true, resize: "200x200") %>
<% end %>

View File

@@ -16,11 +16,10 @@
<%= contract_template.guardian_clause %> <%= contract_template.guardian_clause %>
<% end %> <% end %>
<%# if releasable.model_name.in? %w(MedicalRelease MiscRelease AppearanceRelease) %>
<% if releasable.respond_to?(:question_1_answer) %> <% if releasable.respond_to?(:question_1_answer) %>
<div class="page"> <div class="page">
<%= render "contracts/questionnaire", releasable: releasable, contract_template: contract_template, preview: preview %> <%= render "contracts/questionnaire", releasable: releasable, contract_template: contract_template, preview: preview %>
</div> </div>
<% end %> <% end %>
<div class="page"> <div class="page">
@@ -47,14 +46,13 @@
<% end %> <% end %>
<% end %> <% end %>
<% if releasable.try(:approved?) %>
<% if releasable.respond_to?(:approved?) && releasable.approved? %>
<div class="page"> <div class="page">
<%= render "contracts/for_office_use_only", releasable: releasable, preview: preview %> <%= render "contracts/for_office_use_only", releasable: releasable, preview: preview %>
</div> </div>
<% end %> <% end %>
<% if releasable.class == AcquiredMediaRelease %> <% if releasable.respond_to?(:image_files) %>
<div class="page"> <div class="page">
<%= render "contracts/files", release: releasable, preview: preview %> <%= render "contracts/files", release: releasable, preview: preview %>
</div> </div>

View File

@@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="<%= I18n.locale %>"> <html lang="<%= I18n.locale %>">
<head> <head>
<title>MESuite.ai App</title> <title>ME Suite</title>
<%= csrf_meta_tags %> <%= csrf_meta_tags %>
<%= csp_meta_tag %> <%= csp_meta_tag %>

View File

@@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="<%= I18n.locale %>"> <html lang="<%= I18n.locale %>">
<head> <head>
<title>MESuite.ai App</title> <title>ME Suite</title>
<%= csrf_meta_tags %> <%= csrf_meta_tags %>
<%= csp_meta_tag %> <%= csp_meta_tag %>

View File

@@ -57,8 +57,8 @@
<hr> <hr>
<%= field_set_tag content_tag(:span, t(".photos.heading"), class: "h6 text-muted text-uppercase") do %> <%= field_set_tag content_tag(:span, t(".files.heading"), class: "h6 text-muted text-uppercase") do %>
<%= render "shared/photos_dropzone_fields", form: form, release: material_release %> <%= render "shared/releasable_files_dropzone", form: form, releasable: material_release %>
<div class="<%= class_string("collapse" => !material_release.minor?) %>" data-ujs-target="guardian-fields"> <div class="<%= class_string("collapse" => !material_release.minor?) %>" data-ujs-target="guardian-fields">
<br> <br>

View File

@@ -9,10 +9,10 @@
<% end %> <% end %>
</td> </td>
<td> <td>
<% if material_release.photo.attached? %> <% if material_release.files.any? %>
<%= image_tag medium_variant(material_release.photo), class: "img-fluid" %> <%= material_release.files.size %>
<% else %> <% else %>
<%= fa_icon("warning", text: t(".no_photos"), class: "text-danger") %> <%= fa_icon("warning", text: t(".no_media"), class: "text-danger") %>
<% end %> <% end %>
</td> </td>
<td> <td>
@@ -41,8 +41,8 @@
<% if policy(material_release.tags).new? %> <% if policy(material_release.tags).new? %>
<%= link_to fa_icon("tags fw", text: "Tags"), [:new, material_release, :acts_as_taggable_on_tag], class: "dropdown-item", remote: true %> <%= link_to fa_icon("tags fw", text: "Tags"), [:new, material_release, :acts_as_taggable_on_tag], class: "dropdown-item", remote: true %>
<% end %> <% end %>
<% if policy(material_release).edit_photos? %> <% if policy(material_release).edit_files? %>
<%= link_to fa_icon("picture-o fw", text: "Photos"), [:edit, material_release, :photos], class: "dropdown-item" %> <%= link_to fa_icon("file-o fw", text: "Add Media"), [:edit, material_release, :files], class: "dropdown-item" %>
<% end %> <% end %>
<% if policy(Contract).show? && (material_release.contract.attached? || material_release.contract_template.present?) %> <% if policy(Contract).show? && (material_release.contract.attached? || material_release.contract_template.present?) %>
<%= link_to fa_icon("download fw", text: "Download"), [material_release, :contracts, format: "pdf"], class: "dropdown-item", target: "_blank" %> <%= link_to fa_icon("download fw", text: "Download"), [material_release, :contracts, format: "pdf"], class: "dropdown-item", target: "_blank" %>

View File

@@ -27,7 +27,7 @@
<tr> <tr>
<th data-behavior="all-selectable"><%= check_box_tag "material_release_ids[]", false, false %></th> <th data-behavior="all-selectable"><%= check_box_tag "material_release_ids[]", false, false %></th>
<th><%= t '.table_headers.approved'%></th> <th><%= t '.table_headers.approved'%></th>
<th></th> <th><%= t(".table_headers.files_count") %></th>
<th><%= MaterialRelease.human_attribute_name(:name) %></th> <th><%= MaterialRelease.human_attribute_name(:name) %></th>
<th><%= t(".table_headers.owner_info") %> <th><%= t(".table_headers.owner_info") %>
<th><%= t(".table_headers.notes") %></th> <th><%= t(".table_headers.notes") %></th>

View File

@@ -45,8 +45,8 @@
<%= render "shared/address_fields", form: form, subject: "person", required: true %> <%= render "shared/address_fields", form: form, subject: "person", required: true %>
<% end %> <% end %>
<%= card_field_set_tag t(".photo.heading") do %> <%= card_field_set_tag t(".files.heading") do %>
<%= render "shared/photos_dropzone_fields", form: form, release: @material_release %> <%= render "shared/releasable_files_dropzone", form: form, releasable: @material_release %>
<% end %> <% end %>
<hr> <hr>

View File

@@ -0,0 +1 @@
Rails.application.config.session_store :cookie_store, key: '_easy_release_session', expire_after: 1.month

View File

@@ -224,6 +224,9 @@ en:
manage: Manage manage: Manage
empty_bookmarks: empty_bookmarks:
empty: Notes will appear here empty: Notes will appear here
broadcast_recordings:
edit:
heading: Edit Broadcast Recording
broadcasts: broadcasts:
broadcast: broadcast:
actions: actions:
@@ -901,6 +904,8 @@ en:
form: form:
contract_and_rights: contract_and_rights:
heading: 3 of 4 Contract & Exploitable Rights heading: 3 of 4 Contract & Exploitable Rights
files:
heading: Files
guardian_2_info: guardian_2_info:
heading: Second Guardian Information (if company requires) heading: Second Guardian Information (if company requires)
guardian_info: guardian_info:
@@ -908,7 +913,7 @@ en:
material_details: material_details:
heading: 1 of 3 Material Details heading: 1 of 3 Material Details
photos: photos:
dropzone_label: Tap to take a photo of Licensed Material (optional) dropzone_label: "To Add Files to the release:<br>Drag & Drop Files<br>or<br>Click or Tap here to browse files"
guardian_2_photo: guardian_2_photo:
heading: Second Guardian Photo heading: Second Guardian Photo
guardian_photo: guardian_photo:
@@ -923,6 +928,7 @@ en:
empty: Material Releases will appear here empty: Material Releases will appear here
table_headers: table_headers:
approved: Approved approved: Approved
files_count: No. of Files
name: Name name: Name
notes: Notes notes: Notes
owner_info: Owner Info owner_info: Owner Info
@@ -934,6 +940,7 @@ en:
review: Review review: Review
messages: messages:
approved_tooltip: Approved by %{user} on %{timestamp} approved_tooltip: Approved by %{user} on %{timestamp}
no_media: No Media
no_photos: Needs Photo no_photos: Needs Photo
new: new:
heading: Import Material Release (Products / Logos) heading: Import Material Release (Products / Logos)
@@ -1252,6 +1259,8 @@ en:
cancel: Cancel cancel: Cancel
contact_info: contact_info:
heading: Licensor/Owner Contact Information heading: Licensor/Owner Contact Information
files:
heading: Files
guardian_2_info: guardian_2_info:
heading: Second Guardian Information (if company requires) heading: Second Guardian Information (if company requires)
guardian_2_photo: guardian_2_photo:

View File

@@ -55,7 +55,7 @@ Rails.application.routes.draw do
resources :appearance_releases, except: [:show], concerns: [:contractable, :notable] resources :appearance_releases, except: [:show], concerns: [:contractable, :notable]
resources :appearance_release_imports, only: [:create] resources :appearance_release_imports, only: [:create]
resources :location_releases, except: [:show], concerns: [:contractable, :notable, :photoable] resources :location_releases, except: [:show], concerns: [:contractable, :notable, :photoable]
resources :material_releases, except: [:show], concerns: [:contractable, :notable, :photoable] resources :material_releases, except: [:show], concerns: [:contractable, :notable, :file_uploadable]
resources :music_releases, except: [:show], concerns: [:contractable, :notable] resources :music_releases, except: [:show], concerns: [:contractable, :notable]
resources :talent_releases, except: [:show], concerns: [:contractable, :notable, :photoable] resources :talent_releases, except: [:show], concerns: [:contractable, :notable, :photoable]
resources :medical_releases, except: [:show], concerns: [:contractable, :notable, :photoable] resources :medical_releases, except: [:show], concerns: [:contractable, :notable, :photoable]
@@ -101,7 +101,9 @@ Rails.application.routes.draw do
delete :destroy_file delete :destroy_file
end end
resource :zoom_meeting, only: [:show] resource :zoom_meeting, only: [:show]
resources :broadcast_recordings, only: :destroy resources :broadcast_recordings, only: [:destroy, :edit, :update] do
resources :broadcast_recording_starrings, only: :create
end
end end
resources :directories, except: [:index] do resources :directories, except: [:index] do
member do member do

View File

@@ -0,0 +1,9 @@
class MigrateMaterialPhotosToFiles < ActiveRecord::DataMigration
def up
photos = ActiveStorage::Attachment.where(name: "photos", record_type: "MaterialRelease")
photos.each do |photo|
photo.update(name: "files")
end
end
end

View File

@@ -0,0 +1,6 @@
class AddNameAndDescriptionToBroadcastRecordings < ActiveRecord::Migration[6.0]
def change
add_column :broadcast_recordings, :name, :string
add_column :broadcast_recordings, :description, :text
end
end

View File

@@ -0,0 +1,5 @@
class AddStarToBroadcastRecordings < ActiveRecord::Migration[6.0]
def change
add_column :broadcast_recordings, :starred, :boolean, default: false
end
end

View File

@@ -9,20 +9,6 @@ SET xmloption = content;
SET client_min_messages = warning; SET client_min_messages = warning;
SET row_security = off; SET row_security = off;
--
-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: -
--
CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
--
-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: -
--
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
-- --
-- Name: fuzzystrmatch; Type: EXTENSION; Schema: -; Owner: - -- Name: fuzzystrmatch; Type: EXTENSION; Schema: -; Owner: -
-- --
@@ -555,7 +541,10 @@ CREATE TABLE public.broadcast_recordings (
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,
duration double precision, duration double precision,
hidden boolean DEFAULT false hidden boolean DEFAULT false,
name character varying,
description text,
starred boolean DEFAULT false
); );
@@ -1503,6 +1492,7 @@ CREATE TABLE public.settings (
-- --
CREATE SEQUENCE public.settings_id_seq CREATE SEQUENCE public.settings_id_seq
AS integer
START WITH 1 START WITH 1
INCREMENT BY 1 INCREMENT BY 1
NO MINVALUE NO MINVALUE
@@ -1538,6 +1528,7 @@ CREATE TABLE public.taggings (
-- --
CREATE SEQUENCE public.taggings_id_seq CREATE SEQUENCE public.taggings_id_seq
AS integer
START WITH 1 START WITH 1
INCREMENT BY 1 INCREMENT BY 1
NO MINVALUE NO MINVALUE
@@ -1568,6 +1559,7 @@ CREATE TABLE public.tags (
-- --
CREATE SEQUENCE public.tags_id_seq CREATE SEQUENCE public.tags_id_seq
AS integer
START WITH 1 START WITH 1
INCREMENT BY 1 INCREMENT BY 1
NO MINVALUE NO MINVALUE
@@ -4036,6 +4028,8 @@ INSERT INTO "schema_migrations" (version) VALUES
('20200807190607'), ('20200807190607'),
('20200811102720'), ('20200811102720'),
('20200812060406'), ('20200812060406'),
('20200819070738'); ('20200819070738'),
('20200820082501'),
('20200824171649');

View File

@@ -17,6 +17,7 @@ RSpec.describe BroadcastsChannel, type: :channel do
it "broadcasts to the channel" do it "broadcasts to the channel" do
status_content = ApplicationController.render partial: "broadcasts/broadcast_status", locals: { broadcast: broadcast } status_content = ApplicationController.render partial: "broadcasts/broadcast_status", locals: { broadcast: broadcast }
video_content = ApplicationController.render partial: "broadcasts/video", locals: { broadcast: broadcast } video_content = ApplicationController.render partial: "broadcasts/video", locals: { broadcast: broadcast }
live_take = ApplicationController.render partial: "broadcasts/live_take", locals: { broadcast: broadcast }
expect { expect {
BroadcastsChannel.broadcast_stream_updates(broadcast) BroadcastsChannel.broadcast_stream_updates(broadcast)
@@ -27,6 +28,7 @@ RSpec.describe BroadcastsChannel, type: :channel do
full_live_stream_playback_url: broadcast.full_live_stream_playback_url, full_live_stream_playback_url: broadcast.full_live_stream_playback_url,
status_content: status_content, status_content: status_content,
video_content: video_content, video_content: video_content,
live_take_content: live_take,
streamer_status: broadcast.streamer_status streamer_status: broadcast.streamer_status
}) })
end end

View File

@@ -27,10 +27,17 @@ RSpec.describe ApprovalsController, type: :controller do
expect(MedicalRelease.last.approved?).to eq false expect(MedicalRelease.last.approved?).to eq false
post :create, params: { medical_release_id: medical_release } post :create, params: { medical_release_id: medical_release, medical_release: approvable_params }
expect(response).to redirect_to [project, :medical_releases] expect(response).to redirect_to [project, :medical_releases]
expect(MedicalRelease.last.approved?).to eq true expect(MedicalRelease.last.approved?).to eq true
end end
end end
private
def approvable_params
signature_base64 ||= Base64Image.from_image(file_fixture('signature.png')).data_uri
{ approved_by_user_signature: { data: signature_base64 } }
end
end end

View File

@@ -0,0 +1,48 @@
require 'rails_helper'
RSpec.describe BroadcastRecordingStarringsController, 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
stub_mux_live_stream
end
describe "#create" do
let(:broadcast) { create(:broadcast, project: project, name: "New Broadcast") }
let(:recordings) { create_list(:broadcast_recording, 5, :with_random_asset_uid, broadcast: broadcast) }
let(:starred_recordings) { create_list(:broadcast_recording, 5, :with_random_asset_uid, broadcast: broadcast, starred: true) }
it "sets star property to true when recording is starred" do
recordings.each do |recording|
expect(recording.starred).to be_falsey
end
post :create, params: { project_id: project, broadcast_id: broadcast, broadcast_recording_id: recordings.first.id }, xhr: true
expect(recordings.first.reload.starred).to eq true
recordings[1..5].each do |recording|
expect(recording.reload.starred).to be_falsey
end
end
it "sets star property to false when recording is unstarred" do
starred_recordings.each do |recording|
expect(recording.starred).to be_truthy
end
post :create, params: { project_id: project, broadcast_id: broadcast, broadcast_recording_id: starred_recordings.first.id }, xhr: true
expect(starred_recordings.first.reload.starred).to eq false
starred_recordings[1..5].each do |recording|
expect(recording.reload.starred).to eq true
end
end
end
end

View File

@@ -9,9 +9,10 @@ RSpec.describe BroadcastRecordingsController, type: :controller do
before do before do
sign_in user sign_in user
stub_mux_live_stream
end end
describe "#destroy" do describe "#edit" do
let(:broadcast) { create(:broadcast, project: project, name: "New Broadcast") } let(:broadcast) { create(:broadcast, project: project, name: "New Broadcast") }
let(:recording) { create(:broadcast_recording, broadcast: broadcast) } let(:recording) { create(:broadcast_recording, broadcast: broadcast) }
@@ -19,6 +20,55 @@ RSpec.describe BroadcastRecordingsController, type: :controller do
stub_mux_live_stream stub_mux_live_stream
end end
it "assigns project, broadcast, broadcast recording" do
get :edit, params: { project_id: project, broadcast_id: broadcast, id: recording }, xhr: true
expect(assigns(:project)).to have_attributes({
id: project.id,
name: project.name,
account_id: project.account_id
})
expect(assigns(:broadcast)).to have_attributes({
id: broadcast.id,
name: broadcast.name,
project_id: project.id
})
expect(assigns(:recording)).to have_attributes({
id: recording.id,
broadcast_id: broadcast.id,
file_name: "high.mp4"
})
end
end
describe "#update" do
let(:broadcast) { create(:broadcast, project: project, name: "New Broadcast") }
let(:recording) { create(:broadcast_recording, broadcast: broadcast) }
let(:recordings) { create_list(:broadcast_recording, 5, :with_random_asset_uid, broadcast: broadcast) }
let(:starred_recordings) { create_list(:broadcast_recording, 5, :with_random_asset_uid, broadcast: broadcast, starred: true) }
before do
stub_mux_live_stream
end
it "updates the recording's name and description" do
expect(recording.name).to eq(recording.download_file_name)
expect(recording.description).to eq("No description provided for this recording.")
patch :update, params: { project_id: project, broadcast_id: broadcast, id: recording, broadcast_recording: { name: "Just for fun", description: "I had fun while making this stream." } }, xhr: true
recording.reload
expect(recording.name).to eq("Just for fun")
expect(recording.description).to eq("I had fun while making this stream.")
end
end
describe "#destroy" do
let(:broadcast) { create(:broadcast, project: project, name: "New Broadcast") }
let(:recording) { create(:broadcast_recording, broadcast: broadcast) }
it "hides the broadcast recording" do it "hides the broadcast recording" do
expect(recording.hidden).to be false expect(recording.hidden).to be false

View File

@@ -150,13 +150,6 @@ RSpec.describe BroadcastsController, type: :controller do
expect(assigns(:broadcast)).to eq(broadcast) expect(assigns(:broadcast)).to eq(broadcast)
end end
it "renders readonly share url" do
get :show, params: { project_id: project.id, id: broadcast.id }
expect(response.body).to have_button "Copy URL"
expect(response.body).to have_xpath "//input[@readonly][@value='#{broadcast_url(broadcast.token)}']"
end
it "displays zoom meeting button" do it "displays zoom meeting button" do
get :show, params: { project_id: project.id, id: broadcast.id } get :show, params: { project_id: project.id, id: broadcast.id }
@@ -174,7 +167,7 @@ RSpec.describe BroadcastsController, type: :controller do
it "renders the view dropdown with just the current broadcast" do it "renders the view dropdown with just the current broadcast" do
get :show, params: { project_id: project, id: broadcast } get :show, params: { project_id: project, id: broadcast }
expect(response.body).to have_content "Switch View" expect(response.body).to have_content broadcast.name
expect(response.body).to have_selector(".dropdown-menu .dropdown-item.active", text: "Another Broadcast") expect(response.body).to have_selector(".dropdown-menu .dropdown-item.active", text: "Another Broadcast")
end end
end end
@@ -185,32 +178,12 @@ RSpec.describe BroadcastsController, type: :controller do
get :show, params: { project_id: project, id: broadcast, multi_view_ids: [broadcast.id, other_broadcast.id] } get :show, params: { project_id: project, id: broadcast, multi_view_ids: [broadcast.id, other_broadcast.id] }
expect(response.body).to have_content "Switch View" expect(response.body).to have_content broadcast.name
expect(response.body).to have_selector(".dropdown-menu .dropdown-item.active", text: "Another Broadcast") expect(response.body).to have_selector(".dropdown-menu .dropdown-item.active", text: "Another Broadcast")
expect(response.body).to have_selector(".dropdown-menu a.dropdown-item", text: "Some Other Broadcast") expect(response.body).to have_selector(".dropdown-menu a.dropdown-item", text: "Some Other Broadcast")
end end
end end
context "when there are no recordings for the current broadcast" do
it "renders the view dropdown with a message" do
get :show, params: { project_id: project, id: broadcast }
expect(response.body).to have_content "Switch View"
expect(response.body).to have_selector(".dropdown-menu .dropdown-item", text: "Recordings will appear here")
end
end
context "when there are recordings available" do
it "renders the view dropdown with the recordings" do
recording = create(:broadcast_recording, broadcast: broadcast)
get :show, params: { project_id: project, id: broadcast }
expect(response.body).to have_content "Switch View"
expect(response.body).to have_selector(".dropdown-menu a.dropdown-item", text: recording.download_file_name)
end
end
context "when virtual director video embed is available" do context "when virtual director video embed is available" do
let(:broadcast) { create(:broadcast, project: project, name: "Another Broadcast", let(:broadcast) { create(:broadcast, project: project, name: "Another Broadcast",
director_mode_video_embed: "<iframe>video player</iframe>") } director_mode_video_embed: "<iframe>video player</iframe>") }
@@ -218,9 +191,8 @@ RSpec.describe BroadcastsController, type: :controller do
it "renders the view dropdown with a director mode enable option" do it "renders the view dropdown with a director mode enable option" do
get :show, params: { project_id: project, id: broadcast } get :show, params: { project_id: project, id: broadcast }
expect(response.body).to have_content "Switch View" expect(response.body).to have_content broadcast.name
expect(response.body).to have_selector(".dropdown-menu h5.dropdown-header", text: "Director Mode") expect(response.body).to have_selector(".custom-control-label", text: "Director Mode")
expect(response.body).to have_selector(".dropdown-menu a.dropdown-item", text: "Enable Director Mode")
end end
context "when director mode is enabled" do context "when director mode is enabled" do
@@ -233,9 +205,8 @@ RSpec.describe BroadcastsController, type: :controller do
it "renders the view dropdown with a director mode disable option" do it "renders the view dropdown with a director mode disable option" do
get :show, params: { project_id: project, id: broadcast, director_mode: true } get :show, params: { project_id: project, id: broadcast, director_mode: true }
expect(response.body).to have_content "Switch View" expect(response.body).to have_content broadcast.name
expect(response.body).to have_selector(".dropdown-menu h5.dropdown-header", text: "Director Mode") expect(response.body).to have_selector(".custom-control-label", text: "Director Mode")
expect(response.body).to have_selector(".dropdown-menu a.dropdown-item", text: "Disable Director Mode")
end end
end end
end end

View File

@@ -68,13 +68,7 @@ RSpec.describe PhotosController, type: :controller do
it_behaves_like "a photoable releases controller" it_behaves_like "a photoable releases controller"
end end
context "for material releases" do
subject { create(:material_release, project: project) }
it_behaves_like "a photoable releases controller"
end
private private
def release_params def release_params

View File

@@ -45,7 +45,7 @@ RSpec.describe Public::BroadcastsController, type: :controller do
it "renders the view dropdown with just the current broadcast" do it "renders the view dropdown with just the current broadcast" do
get :show, params: { token: broadcast.token } get :show, params: { token: broadcast.token }
expect(response.body).to have_content "Switch View" expect(response.body).to have_content broadcast.name
expect(response.body).to have_selector(".dropdown-menu .dropdown-item.active", text: "Broadcast") expect(response.body).to have_selector(".dropdown-menu .dropdown-item.active", text: "Broadcast")
end end
end end
@@ -56,7 +56,7 @@ RSpec.describe Public::BroadcastsController, type: :controller do
get :show, params: { token: broadcast.token, multi_view_tokens: [broadcast.token, other_broadcast.token] } get :show, params: { token: broadcast.token, multi_view_tokens: [broadcast.token, other_broadcast.token] }
expect(response.body).to have_content "Switch View" expect(response.body).to have_content broadcast.name
expect(response.body).to have_selector(".dropdown-menu .dropdown-item.active", text: "Broadcast") expect(response.body).to have_selector(".dropdown-menu .dropdown-item.active", text: "Broadcast")
expect(response.body).to have_selector(".dropdown-menu a.dropdown-item", text: "Some Other Broadcast") expect(response.body).to have_selector(".dropdown-menu a.dropdown-item", text: "Some Other Broadcast")
end end
@@ -66,8 +66,7 @@ RSpec.describe Public::BroadcastsController, type: :controller do
it "renders the view dropdown with a message" do it "renders the view dropdown with a message" do
get :show, params: { token: broadcast.token } get :show, params: { token: broadcast.token }
expect(response.body).to have_content "Switch View" expect(response.body).to have_content broadcast.name
expect(response.body).to have_selector(".dropdown-menu .dropdown-item", text: "Recordings will appear here")
end end
end end
@@ -77,8 +76,7 @@ RSpec.describe Public::BroadcastsController, type: :controller do
get :show, params: { token: broadcast.token } get :show, params: { token: broadcast.token }
expect(response.body).to have_content "Switch View" expect(response.body).to have_content broadcast.name
expect(response.body).to have_selector(".dropdown-menu a.dropdown-item", text: recording.download_file_name)
end end
end end

View File

@@ -10,10 +10,10 @@ describe Public::MaterialReleasesController do
it "allows photos param" do it "allows photos param" do
contract_template = create(:contract_template, project: project) contract_template = create(:contract_template, project: project)
post :create, params: { account_id: user.primary_account.to_param, project_id: project, contract_template_id: contract_template, material_release: material_release_params_with_photos } post :create, params: { account_id: user.primary_account.to_param, project_id: project, contract_template_id: contract_template, material_release: material_release_params_with_files }
expect(response).to be_successful expect(response).to be_successful
expect(MaterialRelease.last.photos.attached?).to eq true expect(MaterialRelease.last.files.attached?).to eq true
end end
it "displays validation errors" do it "displays validation errors" do
@@ -63,8 +63,8 @@ describe Public::MaterialReleasesController do
attributes_for(:material_release, :native).except(:signature).merge(signature_param) attributes_for(:material_release, :native).except(:signature).merge(signature_param)
end end
def material_release_params_with_photos def material_release_params_with_files
attributes_for(:material_release, :native, :with_photo).except(:signature).merge(signature_param) attributes_for(:material_release, :native, :with_file).except(:signature).merge(signature_param)
end end

View File

@@ -5,5 +5,9 @@ FactoryBot.define do
asset_uid "asset_uid" asset_uid "asset_uid"
asset_playback_uid "asset_playback_uid" asset_playback_uid "asset_playback_uid"
hidden { false } hidden { false }
trait :with_random_asset_uid do
sequence(:asset_uid, 'a')
end
end end
end end

View File

@@ -42,6 +42,12 @@ FactoryBot.define do
end end
end end
trait :with_file do
files do
path = Rails.root.join("spec", "fixtures", "files", "material_photo.png")
[Rack::Test::UploadedFile.new(path, "image/png")]
end
end
trait :non_native do trait :non_native do
contract do contract do

View File

@@ -0,0 +1,191 @@
require 'rails_helper'
feature 'User approving releasables' do
shared_examples 'an approvable UI' do
let(:current_user) { create(:user, :associate) }
let(:project) { create(:project, members: current_user, account: current_user.primary_account) }
before :each do
sign_in current_user
end
shared_examples 'not authorized to review' do
it 'does not show the review action' do
visit polymorphic_path [project, subject.model_name.plural]
click_on manage_button
expect(page).not_to have_link(review_action, exact: true)
end
end
scenario 'approval status is indicating by a checkmark' do
approved_releasable = create("#{subject.model_name.singular}", approved_at: 1.day.ago, project: project)
visit polymorphic_path [project, subject.model_name.plural]
expect(page).not_to be_approved(subject)
expect(page).not_to be_approved(approved_releasable)
end
context 'as an account manager' do
let(:current_user) { create(:user, :account_manager) }
scenario 'approving a release', js: true do
visit polymorphic_path [project, subject.model_name.plural]
click_on manage_button
click_link review_action
expect(page).to have_content review_page_heading(subject.model_name)
expect(page).to have_content approve_button
expect(page).to have_content signature_field
click_on approve_button
expect(page).not_to have_content approved_notice(subject.model_name)
expect(page).to have_content 'is not attached'
by 'adding signature' do
draw_signature file_fixture('signature.png'), signature_data_field(subject.model_name)
click_on approve_button
expect(page).to have_content approved_notice(subject.model_name)
end
end
scenario 'viewing the contract PDF for an unapproved release' do
visit polymorphic_path [project, subject.model_name.plural]
click_on 'Manage'
click_link 'Download'
expect(content_type).to eq('application/pdf')
expect(content_disposition).to include('inline')
expect(pdf_body).not_to have_content for_office_use_only
end
scenario 'viewing the contract PDF of an approved release' do
approver = create(:user, email: 'big.doe@test.com', first_name: 'Big', last_name: 'Joe')
subject.approve_by(approver)
subject.save!
visit polymorphic_path([subject, :contracts], format: 'pdf')
expect(content_type).to eq('application/pdf')
expect(content_disposition).to include('inline')
expect(pdf_body).to have_content for_office_use_only.upcase
expect(pdf_body).to have_content producer_label
expect(pdf_body).to have_content production_label
expect(pdf_body).to have_content issued_to_label
expect(pdf_body).to have_content issued_by_label
expect(pdf_body).to have_content date_issued
expect(pdf_body).to have_content 'Big Joe'
end
end
context 'as a manager' do
let(:current_user) { create(:user, :manager) }
include_examples 'not authorized to review'
end
context 'as an associate' do
let(:current_user) { create(:user, :associate) }
include_examples 'not authorized to review'
end
private
def approve_button
t 'approvals.new.actions.approve'
end
def approved_notice(model_name)
t('approvals.create.release_approved', release_type: model_name.human)
end
def be_approved(releasable)
releasable_dom_id = "##{releasable.model_name.singular}_#{releasable.id}"
have_css("#{releasable_dom_id }i.fa.fa-check-circle.fa-2x", count: 1)
end
def manage_button
'Manage'
end
def review_action
'Review'
end
def review_page_heading(model_name)
t 'approvals.new.heading', release_type: model_name.human.titleize
end
def signature_field
'SIGNATURE'
end
def signature_data_field(model_name)
"#{model_name.singular}_approved_by_user_signature[data]"
end
def for_office_use_only
t('contracts.for_office_use_only.heading').upcase
end
def producer_label
t 'contracts.for_office_use_only.description_labels.producer'
end
def production_label
t 'contracts.for_office_use_only.description_labels.production'
end
def issued_to_label
t 'contracts.for_office_use_only.description_labels.issued_to'
end
def issued_by_label
t 'contracts.for_office_use_only.description_labels.issued_by'
end
def date_issued
t 'contracts.for_office_use_only.description_labels.date_issued'
end
end
context 'for an appearance release' do
subject { create(:appearance_release_with_contract_template, :native, project: project) }
it_behaves_like 'an approvable UI'
end
context 'for a talent release' do
subject { create(:talent_release_with_contract_template, :native, project: project) }
it_behaves_like 'an approvable UI'
end
context 'for a location release' do
subject { create(:location_release_with_contract_template, :native, project: project) }
it_behaves_like 'an approvable UI'
end
context 'for a material release' do
subject { create(:material_release_with_contract_template, :native, project: project) }
it_behaves_like 'an approvable UI'
end
context 'for a acquired media release' do
subject { create(:acquired_media_release_with_contract_template, :native, project: project) }
it_behaves_like 'an approvable UI'
end
context 'for a medical release' do
subject { create(:medical_release_with_contract_template, :native, project: project) }
it_behaves_like 'an approvable UI'
end
context 'for a misc release' do
subject { create(:misc_release_with_contract_template, :native, project: project) }
it_behaves_like 'an approvable UI'
end
end

View File

@@ -444,104 +444,9 @@ feature "User managing acquired_media releases" do
end end
context "when the user is account manager" do context "when the user is account manager" do
let(:current_user) { create(:user, :account_manager) }
before do
sign_in current_user
end
scenario "Review action in Manage menu is visible" do
create(:acquired_media_release_with_contract_template, :native, project: project)
visit project_acquired_media_releases_path(project)
expect(page).to have_link(review_action, exact: true)
end
scenario "Reviewing release" do
create(:acquired_media_release_with_contract_template, :native, project: project)
visit project_acquired_media_releases_path(project)
click_link review_action
expect(page).to have_content review_page_heading
expect(page).to have_content approve_button
end
scenario "Approved releases have checkmark and non-approved releases don't have checkmarks" do
create(:acquired_media_release_with_contract_template, :native, project: project)
visit project_acquired_media_releases_path(project)
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 0)
create(:acquired_media_release_with_contract_template, :native, project: project, approved_by_user_email: "some@email.com", approved_at: DateTime.now)
visit project_acquired_media_releases_path(project)
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 1)
end
scenario 'When viewing the contract PDF of approved release there is page for office use only' do
acquired_media_release = create(:acquired_media_release_with_contract_template,
:native,
project: project,
person_first_name: 'Jane',
person_last_name: 'Doe',
approved_by_user_name: "Big Joe",
approved_by_user_email: "some@email.com",
approved_at: DateTime.now)
sign_in(current_user)
visit project_acquired_media_releases_path(project)
click_link *view_release_pdf_link_for(acquired_media_release)
expect(content_type).to eq('application/pdf')
expect(content_disposition).to include('inline')
expect(pdf_body).to have_content for_office_use_only.upcase
expect(pdf_body).to have_content producer_label
expect(pdf_body).to have_content production_label
expect(pdf_body).to have_content issued_to_label
expect(pdf_body).to have_content issued_by_label
expect(pdf_body).to have_content date_issued
expect(pdf_body).to have_content 'Big Joe'
end
scenario 'When viewing the contract PDF of not approved release there is no page for office use only' do
acquired_media_release = create(:acquired_media_release_with_contract_template,
:native,
project: project,
person_first_name: 'Jane',
person_last_name: 'Doe')
sign_in(current_user)
visit project_acquired_media_releases_path(project)
click_link *view_release_pdf_link_for(acquired_media_release)
expect(content_type).to eq('application/pdf')
expect(content_disposition).to include('inline')
expect(pdf_body).not_to have_content for_office_use_only.upcase
expect(pdf_body).not_to have_content producer_label
expect(pdf_body).not_to have_content production_label
expect(pdf_body).not_to have_content issued_to_label
expect(pdf_body).not_to have_content issued_by_label
expect(pdf_body).not_to have_content date_issued
expect(pdf_body).not_to have_content 'Big Joe'
end
end end
context "when the user is project manager" do context "when the user is project manager" do
before do
sign_in current_user
end
scenario "Review action in Manage menu is not visible" do
create(:acquired_media_release_with_contract_template, project: project)
visit project_acquired_media_releases_path(project)
click_on "Manage"
expect(page).not_to have_link(review_action, exact: true)
end
end end
context "when the user is associate" do context "when the user is associate" do
@@ -703,42 +608,6 @@ feature "User managing acquired_media releases" do
'Some signature legal language' 'Some signature legal language'
end end
def review_action
t 'acquired_media_releases.acquired_media_release.actions.review'
end
def review_page_heading
t 'approvals.new.heading', release_type: "Acquired Media Release"
end
def approve_button
t 'approvals.new.actions.approve'
end
def for_office_use_only
t 'contracts.for_office_use_only.heading'
end
def producer_label
t 'contracts.for_office_use_only.description_labels.producer'
end
def production_label
t 'contracts.for_office_use_only.description_labels.production'
end
def issued_to_label
t 'contracts.for_office_use_only.description_labels.issued_to'
end
def issued_by_label
t 'contracts.for_office_use_only.description_labels.issued_by'
end
def date_issued
t 'contracts.for_office_use_only.description_labels.date_issued'
end
def person_is_minor_checkbox def person_is_minor_checkbox
'acquired_media_release_minor' 'acquired_media_release_minor'
end end

View File

@@ -687,103 +687,9 @@ feature 'User managing appearance releases' do
context "when the user is account manager" do context "when the user is account manager" do
let(:current_user) { create(:user, :account_manager) } let(:current_user) { create(:user, :account_manager) }
before do
sign_in current_user
end
scenario "Review action in Manage menu is visible" do
create(:appearance_release_with_contract_template, :native, project: project)
visit project_appearance_releases_path(project)
expect(page).to have_link(review_action, exact: true)
end
scenario "Reviewing release" do
create(:appearance_release_with_contract_template, :native, project: project)
visit project_appearance_releases_path(project)
click_link review_action
expect(page).to have_content review_page_heading
expect(page).to have_content approve_button
end
scenario "Approved releases have checkmark and non-approved releases don't have checkmarks" do
create(:appearance_release_with_contract_template, :native, project: project)
visit project_appearance_releases_path(project)
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 0)
create(:appearance_release_with_contract_template, :native, project: project, approved_by_user_email: "some@email.com", approved_at: DateTime.now)
visit project_appearance_releases_path(project)
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 1)
end
scenario 'When viewing the contract PDF of approved release there is page for office use only' do
appearance_release = create(:appearance_release_with_contract_template,
:native,
project: project,
person_first_name: 'Jane',
person_last_name: 'Doe',
approved_by_user_name: "Big Joe",
approved_by_user_email: "some@email.com",
approved_at: DateTime.now)
sign_in(current_user)
visit project_appearance_releases_path(project)
click_link *view_release_pdf_link_for(appearance_release)
expect(content_type).to eq('application/pdf')
expect(content_disposition).to include('inline')
expect(pdf_body).to have_content for_office_use_only.upcase
expect(pdf_body).to have_content producer_label
expect(pdf_body).to have_content production_label
expect(pdf_body).to have_content issued_to_label
expect(pdf_body).to have_content issued_by_label
expect(pdf_body).to have_content date_issued
expect(pdf_body).to have_content 'Big Joe'
end
scenario 'When viewing the contract PDF of not approved release there is no page for office use only' do
appearance_release = create(:appearance_release_with_contract_template,
:native,
project: project,
person_first_name: 'Jane',
person_last_name: 'Doe')
sign_in(current_user)
visit project_appearance_releases_path(project)
click_link *view_release_pdf_link_for(appearance_release)
expect(content_type).to eq('application/pdf')
expect(content_disposition).to include('inline')
expect(pdf_body).not_to have_content for_office_use_only.upcase
expect(pdf_body).not_to have_content producer_label
expect(pdf_body).not_to have_content production_label
expect(pdf_body).not_to have_content issued_to_label
expect(pdf_body).not_to have_content issued_by_label
expect(pdf_body).not_to have_content date_issued
expect(pdf_body).not_to have_content 'Big Joe'
end
end end
context "when the user is project manager" do context "when the user is project manager" do
before do
sign_in current_user
end
scenario "Review action in Manage menu is not visible" do
create(:appearance_release_with_contract_template, :native, project: project)
visit project_appearance_releases_path(project)
click_on manage_button
expect(page).not_to have_link(review_action, exact: true)
end
end end
context 'when the user is associate' do context 'when the user is associate' do
@@ -801,15 +707,6 @@ feature 'User managing appearance releases' do
click_on manage_button click_on manage_button
expect(page).not_to have_link('Download', exact: true) expect(page).not_to have_link('Download', exact: true)
end end
scenario "Review action in Manage menu is not visible" do
create(:appearance_release_with_contract_template, :native, project: project)
visit project_appearance_releases_path(project)
click_on manage_button
expect(page).not_to have_link(review_action, exact: true)
end
end end
private private
@@ -1039,42 +936,6 @@ feature 'User managing appearance releases' do
'Some signature legal language' 'Some signature legal language'
end end
def review_action
t 'appearance_releases.appearance_release.actions.review'
end
def review_page_heading
t 'approvals.new.heading', release_type: "Appearance Release"
end
def approve_button
t 'approvals.new.actions.approve'
end
def for_office_use_only
t 'contracts.for_office_use_only.heading'
end
def producer_label
t 'contracts.for_office_use_only.description_labels.producer'
end
def production_label
t 'contracts.for_office_use_only.description_labels.production'
end
def issued_to_label
t 'contracts.for_office_use_only.description_labels.issued_to'
end
def issued_by_label
t 'contracts.for_office_use_only.description_labels.issued_by'
end
def date_issued
t 'contracts.for_office_use_only.description_labels.date_issued'
end
def amendments_heading def amendments_heading
t 'public.amendments.new.amendment.heading' t 'public.amendments.new.amendment.heading'
end end

View File

@@ -56,14 +56,32 @@ feature 'User managing broadcasts' do
visit project_broadcast_path(project, broadcast) visit project_broadcast_path(project, broadcast)
expect(page).to have_content('Live stream is waiting to begin.') expect(page).to have_content('Live stream is waiting to begin.')
expect(page).to have_content('Copy URL') expect(page).to have_content('Share URL')
within '#files' do click_on "Files"
expect(page).to have_content('contract.pdf') expect(page).to have_content('contract.pdf')
click_on 'Takes'
expect(page).to have_content(recording.name)
end
context 'visit show page of active broadcast' do
scenario 'loads full live stream playback url if available' do
broadcast = create(:broadcast, :with_stream, :with_files, project: project, streamer_status: :recording, status: :active)
visit project_broadcast_path(project, broadcast)
expect(page.body).not_to match broadcast.stream_playback_url
expect(page.body).to match broadcast.full_live_stream_playback_url
end end
click_on 'Previous Sessions' scenario 'loads full broadcast asset url if available' do
expect(page).to have_content(recording.download_file_name) broadcast = create(:broadcast, :with_stream, :with_files, project: project, streamer_status: :recording, status: :active, full_live_stream_playback_uid: '')
visit project_broadcast_path(project, broadcast)
expect(page.body).to match broadcast.stream_playback_url
end
end end
scenario 'Clicking Reset URL regenerates broadcast token' do scenario 'Clicking Reset URL regenerates broadcast token' do
@@ -73,93 +91,19 @@ feature 'User managing broadcasts' do
visit project_broadcast_path(project, broadcast) visit project_broadcast_path(project, broadcast)
expect(page).to have_content reset_url expect(page).to have_content reset_url
expect(page).to have_xpath "//input[@readonly][@value='#{broadcast_url(old_token)}']"
click_link reset_url click_link reset_url
expect(Broadcast.last.token).not_to eq old_token expect(Broadcast.last.token).not_to eq old_token
expect(page).to have_xpath "//input[@readonly][@value='#{broadcast_url(Broadcast.last.token)}']"
expect(page).to have_content token_reset_notice expect(page).to have_content token_reset_notice
end end
scenario 'Player will not reload if stream is reactivated while user is watching previous recording', js: true do
broadcast = create(:broadcast, :with_stream, :with_files, project: project)
recording = create(:broadcast_recording, broadcast: broadcast)
visit project_broadcast_path(project, broadcast)
expect(page).to have_content stream_idle_message
broadcast.streamer_status = :recording
broadcast.status = :active
BroadcastsChannel.broadcast_stream_updates(broadcast)
expect(page).to have_content stream_begun_message
expect(page).to have_selector('div#broadcast_video', count: 2)
broadcast.streamer_status = :idle
broadcast.status = :idle
BroadcastsChannel.broadcast_stream_updates(broadcast)
click_on switch_view_dropdown
click_on recording.download_file_name
expect(page).to have_content stream_idle_message
expect(page).to have_selector('div#broadcast_video', count: 1)
broadcast.streamer_status = :recording
broadcast.status = :active
BroadcastsChannel.broadcast_stream_updates(broadcast)
expect(page).to have_content stream_begun_message
expect(page).to have_selector('div#broadcast_video', count: 1)
end
scenario 'user can go back and forth between live session and previous sessions', js: true do
broadcast = create(:broadcast, :with_stream, :with_files, project: project)
recording = create(:broadcast_recording, broadcast: broadcast)
visit project_broadcast_path(project, broadcast)
expect(page).to have_content broadcast.name.titleize, count: 1
expect(page).to have_content recording.download_file_name, count: 0
click_on switch_view_dropdown
expect(page).to have_content broadcast.name.titleize, count: 2
expect(page).to have_content recording.download_file_name, count: 1
live_stream_nav_item = page.find('.dropdown-item', text: broadcast.name.titleize)
recording_nav_item = page.find('.dropdown-item', text: recording.download_file_name)
expect(live_stream_nav_item[:class].include?('active')).to eq true
expect(recording_nav_item[:class].include?('active')).to eq false
click_on recording.download_file_name
expect(page).to have_content broadcast.name.titleize, count: 1
expect(page).to have_content recording.download_file_name, count: 0
expect(live_stream_nav_item[:class].include?('active')).to eq false
expect(recording_nav_item[:class].include?('active')).to eq true
click_on switch_view_dropdown
click_on broadcast.name.titleize
expect(page).to have_content broadcast.name.titleize, count: 1
expect(page).to have_content recording.download_file_name, count: 0
# Page is reloaded, we need to get dropdown items again
live_stream_nav_item = page.find('.dropdown-item', text: broadcast.name.titleize, visible: :all)
recording_nav_item = page.find('.dropdown-item', text: recording.download_file_name, visible: :all)
expect(live_stream_nav_item[:class].include?('active')).to eq true
expect(recording_nav_item[:class].include?('active')).to eq false
end
scenario 'form will not submit if user clicks Add files without selected files', js: true do scenario 'form will not submit if user clicks Add files without selected files', js: true do
broadcast = create(:broadcast, :with_stream, :with_files, project: project) broadcast = create(:broadcast, :with_stream, :with_files, project: project)
visit project_broadcast_path(project, broadcast) visit project_broadcast_path(project, broadcast)
expect(page).to have_content('Live stream is waiting to begin.') expect(page).to have_content('Live stream is waiting to begin.')
click_on "Files"
expect(page).to have_content add_file_button expect(page).to have_content add_file_button
click_on add_file_button click_on add_file_button
@@ -169,7 +113,7 @@ feature 'User managing broadcasts' do
broadcast = create(:broadcast, :with_stream, :with_files, project: project) broadcast = create(:broadcast, :with_stream, :with_files, project: project)
visit project_broadcast_path(project, broadcast) visit project_broadcast_path(project, broadcast)
click_on "Files"
expect(page).to have_content delete_file_button, count: 3 expect(page).to have_content delete_file_button, count: 3
accept_alert do accept_alert do
@@ -189,9 +133,11 @@ feature 'User managing broadcasts' do
new_window = window_opened_by { click_link 'Multi-View' } new_window = window_opened_by { click_link 'Multi-View' }
within_window new_window do within_window new_window do
expect(page).to have_content switch_view_dropdown click_on "Files"
expect(page).to have_content broadcast_one.name
click_on switch_view_dropdown expect(page).to have_content broadcast_two.name
click_on broadcast_one.name
expect(page).to have_link('Broadcast 1') expect(page).to have_link('Broadcast 1')
expect(page).to have_link('Broadcast 2') expect(page).to have_link('Broadcast 2')
@@ -205,24 +151,6 @@ feature 'User managing broadcasts' do
end end
end end
scenario 'project manager can hide broadcast recordings', js: true do
broadcast = create(:broadcast, :with_stream, :with_files, project: project)
recording = create(:broadcast_recording, broadcast: broadcast, asset_uid: "another_asset_uid")
visit project_broadcast_path(project, broadcast)
click_on 'Previous Sessions'
expect(page).to have_content(recording.download_file_name)
expect(page).to have_content('Hide')
accept_alert do
click_link "Hide"
end
expect(page).not_to have_content(recording.download_file_name)
expect(page).to have_content("Recording of the live stream will appear here")
end
context 'When the user is associate' do context 'When the user is associate' do
let(:current_user) { create(:user, :associate) } let(:current_user) { create(:user, :associate) }
@@ -240,17 +168,6 @@ feature 'User managing broadcasts' do
expect(page).to have_content delete_file_button, count: 0 expect(page).to have_content delete_file_button, count: 0
end end
scenario 'associate does not see hide button in front of recording' do
broadcast = create(:broadcast, :with_stream, :with_files, project: project)
recording = create(:broadcast_recording, broadcast: broadcast, asset_uid: "another_asset_uid")
visit project_broadcast_path(project, broadcast)
click_on 'Previous Sessions'
expect(page).to have_content(recording.download_file_name)
expect(page).not_to have_content('Hide')
end
end end
context 'When the user is account manager' do context 'When the user is account manager' do
@@ -267,7 +184,7 @@ feature 'User managing broadcasts' do
broadcast = create(:broadcast, :with_stream, :with_files, project: project) broadcast = create(:broadcast, :with_stream, :with_files, project: project)
visit project_broadcast_path(project, broadcast) visit project_broadcast_path(project, broadcast)
click_on "Files"
expect(page).to have_content delete_file_button, count: 3 expect(page).to have_content delete_file_button, count: 3
accept_alert do accept_alert do
@@ -277,26 +194,7 @@ feature 'User managing broadcasts' do
expect(page).to have_content delete_file_button, count: 2 expect(page).to have_content delete_file_button, count: 2
expect(Broadcast.find(broadcast.id).files.count).to eq 2 expect(Broadcast.find(broadcast.id).files.count).to eq 2
end end
scenario 'account manager can hide broadcast recordings', js: true do
broadcast = create(:broadcast, :with_stream, :with_files, project: project)
recording = create(:broadcast_recording, broadcast: broadcast, asset_uid: "another_asset_uid")
visit project_broadcast_path(project, broadcast)
click_on 'Previous Sessions'
expect(page).to have_content(recording.download_file_name)
expect(page).to have_content('Hide')
accept_alert do
click_link "Hide"
end
expect(page).not_to have_content(recording.download_file_name)
expect(page).to have_content("Recording of the live stream will appear here")
end
end end
end end
private private
@@ -320,10 +218,6 @@ feature 'User managing broadcasts' do
all('input[type="checkbox"]')[1].click all('input[type="checkbox"]')[1].click
end end
def switch_view_dropdown
'Switch View'
end
def schedule_demo def schedule_demo
t 'broadcasts.splash.actions.book_demo' t 'broadcasts.splash.actions.book_demo'
end end

View File

@@ -383,104 +383,9 @@ feature "User managing location releases" do
end end
context "when the user is account manager" do context "when the user is account manager" do
let(:current_user) { create(:user, :account_manager) }
before do
sign_in current_user
end
scenario "Review action in Manage menu is visible" do
create(:location_release_with_contract_template, :native, project: project)
visit project_location_releases_path(project)
expect(page).to have_link(review_action, exact: true)
end
scenario "Reviewing release" do
create(:location_release_with_contract_template, :native, project: project)
visit project_location_releases_path(project)
click_link review_action
expect(page).to have_content review_page_heading
expect(page).to have_content approve_button
end
scenario "Approved releases have checkmark and non-approved releases don't have checkmarks" do
create(:location_release_with_contract_template, :native, project: project)
visit project_location_releases_path(project)
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 0)
create(:location_release_with_contract_template, :native, project: project, approved_by_user_email: "some@email.com", approved_at: DateTime.now)
visit project_location_releases_path(project)
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 1)
end
scenario 'When viewing the contract PDF of approved release there is page for office use only' do
location_release = create(:location_release_with_contract_template,
:native,
project: project,
person_first_name: 'Jane',
person_last_name: 'Doe',
approved_by_user_name: "Big Joe",
approved_by_user_email: "some@email.com",
approved_at: DateTime.now)
sign_in(current_user)
visit project_location_releases_path(project)
click_link *view_release_pdf_link_for(location_release)
expect(content_type).to eq('application/pdf')
expect(content_disposition).to include('inline')
expect(pdf_body).to have_content for_office_use_only.upcase
expect(pdf_body).to have_content producer_label
expect(pdf_body).to have_content production_label
expect(pdf_body).to have_content issued_to_label
expect(pdf_body).to have_content issued_by_label
expect(pdf_body).to have_content date_issued
expect(pdf_body).to have_content 'Big Joe'
end
scenario 'When viewing the contract PDF of not approved release there is no page for office use only' do
location_release = create(:location_release_with_contract_template,
:native,
project: project,
person_first_name: 'Jane',
person_last_name: 'Doe')
sign_in(current_user)
visit project_location_releases_path(project)
click_link *view_release_pdf_link_for(location_release)
expect(content_type).to eq('application/pdf')
expect(content_disposition).to include('inline')
expect(pdf_body).not_to have_content for_office_use_only.upcase
expect(pdf_body).not_to have_content producer_label
expect(pdf_body).not_to have_content production_label
expect(pdf_body).not_to have_content issued_to_label
expect(pdf_body).not_to have_content issued_by_label
expect(pdf_body).not_to have_content date_issued
expect(pdf_body).not_to have_content 'Big Joe'
end
end end
context "when the user is project manager" do context "when the user is project manager" do
before do
sign_in current_user
end
scenario "Review action in Manage menu is not visible" do
create(:location_release_with_contract_template, :native, project: project)
visit project_location_releases_path(project)
click_on manage_button
expect(page).not_to have_link(review_action, exact: true)
end
end end
context "when the user is associate" do context "when the user is associate" do
@@ -498,15 +403,6 @@ feature "User managing location releases" do
click_on manage_button click_on manage_button
expect(page).not_to have_link("Download", exact: true) expect(page).not_to have_link("Download", exact: true)
end end
scenario "Review action in Manage menu is not visible" do
create(:location_release_with_contract_template, :native, project: project)
visit project_location_releases_path(project)
click_on manage_button
expect(page).not_to have_link(review_action, exact: true)
end
end end
private private
@@ -650,42 +546,6 @@ feature "User managing location releases" do
'Some signature legal language' 'Some signature legal language'
end end
def review_action
t 'location_releases.location_release.actions.review'
end
def review_page_heading
t 'approvals.new.heading', release_type: "Location Release"
end
def approve_button
t 'approvals.new.actions.approve'
end
def for_office_use_only
t 'contracts.for_office_use_only.heading'
end
def producer_label
t 'contracts.for_office_use_only.description_labels.producer'
end
def production_label
t 'contracts.for_office_use_only.description_labels.production'
end
def issued_to_label
t 'contracts.for_office_use_only.description_labels.issued_to'
end
def issued_by_label
t 'contracts.for_office_use_only.description_labels.issued_by'
end
def date_issued
t 'contracts.for_office_use_only.description_labels.date_issued'
end
def amendments_heading def amendments_heading
t 'public.amendments.new.amendment.heading' t 'public.amendments.new.amendment.heading'
end end

View File

@@ -37,7 +37,7 @@ feature "User managing material releases" do
click_button submit_release_button click_button submit_release_button
expect(page).to have_content success_submit_message expect(page).to have_content success_submit_message
expect(MaterialRelease.last.photos.attached?).to eq true expect(MaterialRelease.last.files.attached?).to eq true
end end
scenario "creating a release for a minor - guardian fields are required when minor checkbox is checked", js: true do scenario "creating a release for a minor - guardian fields are required when minor checkbox is checked", js: true do
@@ -225,7 +225,7 @@ feature "User managing material releases" do
click_button create_release_button click_button create_release_button
expect(page).to have_content(create_release_notice) expect(page).to have_content(create_release_notice)
expect(page).to have_photo("material_photo.png", visible: :all) expect(page).to have_content("1")
click_on "Manage" click_on "Manage"
expect(page).to have_link("Download") expect(page).to have_link("Download")
@@ -364,19 +364,19 @@ feature "User managing material releases" do
visit project_material_releases_path(project) visit project_material_releases_path(project)
expect(page).to have_content("Needs Photo") expect(page).to have_content("No Media")
click_on "Manage" click_on "Manage"
click_on "Photos" click_on "Add Media"
expect(page).to have_content("Add Photos") expect(page).to have_content("Add Files")
expect(page).to have_content("Apple MacBook Air") expect(page).to have_content("Apple MacBook Air")
drop_file Rails.root.join(file_fixture("material_photo.png")), type: :dropzone drop_file Rails.root.join(file_fixture("material_photo.png")), type: :dropzone
click_on "Save Changes" click_on "Save Changes"
expect(page).to have_content("The release has been updated") expect(page).to have_content("Files added successfully to the release")
expect(page).to have_photo("material_photo.png", visible: :all) expect(page).to have_content("1")
end end
scenario "viewing the contract PDF" do scenario "viewing the contract PDF" do
@@ -421,104 +421,9 @@ feature "User managing material releases" do
end end
context "when the user is account manager" do context "when the user is account manager" do
let(:current_user) { create(:user, :account_manager) }
before do
sign_in current_user
end
scenario "Review action in Manage menu is visible" do
create(:material_release_with_contract_template, :native, project: project)
visit project_material_releases_path(project)
expect(page).to have_link(review_action, exact: true)
end
scenario "Reviewing release" do
create(:material_release_with_contract_template, :native, project: project)
visit project_material_releases_path(project)
click_link review_action
expect(page).to have_content review_page_heading
expect(page).to have_content approve_button
end
scenario "Approved releases have checkmark and non-approved releases don't have checkmarks" do
create(:material_release_with_contract_template, :native, project: project)
visit project_material_releases_path(project)
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 0)
create(:material_release_with_contract_template, :native, project: project, approved_by_user_email: "some@email.com", approved_at: DateTime.now)
visit project_material_releases_path(project)
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 1)
end
scenario 'When viewing the contract PDF of approved release there is page for office use only' do
material_release = create(:material_release_with_contract_template,
:native,
project: project,
person_first_name: 'Jane',
person_last_name: 'Doe',
approved_by_user_name: "Big Joe",
approved_by_user_email: "some@email.com",
approved_at: DateTime.now)
sign_in(current_user)
visit project_material_releases_path(project)
click_link *view_release_pdf_link_for(material_release)
expect(content_type).to eq('application/pdf')
expect(content_disposition).to include('inline')
expect(pdf_body).to have_content for_office_use_only.upcase
expect(pdf_body).to have_content producer_label
expect(pdf_body).to have_content production_label
expect(pdf_body).to have_content issued_to_label
expect(pdf_body).to have_content issued_by_label
expect(pdf_body).to have_content date_issued
expect(pdf_body).to have_content 'Big Joe'
end
scenario 'When viewing the contract PDF of not approved release there is no page for office use only' do
material_release = create(:material_release_with_contract_template,
:native,
project: project,
person_first_name: 'Jane',
person_last_name: 'Doe')
sign_in(current_user)
visit project_material_releases_path(project)
click_link *view_release_pdf_link_for(material_release)
expect(content_type).to eq('application/pdf')
expect(content_disposition).to include('inline')
expect(pdf_body).not_to have_content for_office_use_only.upcase
expect(pdf_body).not_to have_content producer_label
expect(pdf_body).not_to have_content production_label
expect(pdf_body).not_to have_content issued_to_label
expect(pdf_body).not_to have_content issued_by_label
expect(pdf_body).not_to have_content date_issued
expect(pdf_body).not_to have_content 'Big Joe'
end
end end
context "when the user is project manager" do context "when the user is project manager" do
before do
sign_in current_user
end
scenario "Review action in Manage menu is not visible" do
create(:material_release_with_contract_template, :native, project: project)
visit project_material_releases_path(project)
click_on "Manage"
expect(page).not_to have_link(review_action, exact: true)
end
end end
context "when the user is associate" do context "when the user is associate" do
@@ -536,15 +441,6 @@ feature "User managing material releases" do
click_on "Manage" click_on "Manage"
expect(page).not_to have_link("Download", exact: true) expect(page).not_to have_link("Download", exact: true)
end end
scenario "Review action in Manage menu is not visible" do
create(:material_release_with_contract_template, :native, project: project)
visit project_material_releases_path(project)
click_on "Manage"
expect(page).not_to have_link(review_action, exact: true)
end
end end
private private
@@ -693,42 +589,6 @@ feature "User managing material releases" do
'Some signature legal language' 'Some signature legal language'
end end
def review_action
t 'material_releases.material_release.actions.review'
end
def review_page_heading
t 'approvals.new.heading', release_type: "Material Release"
end
def approve_button
t 'approvals.new.actions.approve'
end
def for_office_use_only
t 'contracts.for_office_use_only.heading'
end
def producer_label
t 'contracts.for_office_use_only.description_labels.producer'
end
def production_label
t 'contracts.for_office_use_only.description_labels.production'
end
def issued_to_label
t 'contracts.for_office_use_only.description_labels.issued_to'
end
def issued_by_label
t 'contracts.for_office_use_only.description_labels.issued_by'
end
def date_issued
t 'contracts.for_office_use_only.description_labels.date_issued'
end
def person_is_minor_checkbox def person_is_minor_checkbox
'material_release_minor' 'material_release_minor'
end end

View File

@@ -215,15 +215,6 @@ feature "User managing medical releases" do
expect(page).to have_link("Download", exact: true, count: 2) expect(page).to have_link("Download", exact: true, count: 2)
end end
scenario "Review action in Manage menu is visible" do
create(:medical_release_with_contract_template, :native, project: project)
create(:medical_release_with_contract_template, :non_native, project: project)
visit project_medical_releases_path(project)
expect(page).to have_link(review_action, exact: true)
end
scenario "Downloading PDF of native medical release is possible" do scenario "Downloading PDF of native medical release is possible" do
native_release = create(:medical_release_with_contract_template, :native, project: project) native_release = create(:medical_release_with_contract_template, :native, project: project)
@@ -233,64 +224,6 @@ feature "User managing medical releases" do
expect(content_type).to eq('application/pdf') expect(content_type).to eq('application/pdf')
end end
scenario "Reviewing release" do
create(:medical_release_with_contract_template, :native, project: project)
visit project_medical_releases_path(project)
click_link review_action
expect(page).to have_content review_page_heading
expect(page).to have_content approve_button
end
scenario 'When viewing the contract PDF of approved release there is page for office use only' do
medical_release = create(:medical_release_with_contract_template,
:native,
project: project,
person_first_name: 'Jane',
person_last_name: 'Doe',
approved_by_user_name: "Big Joe",
approved_by_user_email: "some@email.com",
approved_at: DateTime.now)
sign_in(current_user)
visit project_medical_releases_path(project)
click_link *view_release_pdf_link_for(medical_release)
expect(content_type).to eq('application/pdf')
expect(content_disposition).to include('inline')
expect(pdf_body).to have_content for_office_use_only.upcase
expect(pdf_body).to have_content producer_label
expect(pdf_body).to have_content production_label
expect(pdf_body).to have_content issued_to_label
expect(pdf_body).to have_content issued_by_label
expect(pdf_body).to have_content date_issued
expect(pdf_body).to have_content 'Big Joe'
end
scenario 'When viewing the contract PDF of not approved release there is no page for office use only' do
medical_release = create(:medical_release_with_contract_template,
:native,
project: project,
person_first_name: 'Jane',
person_last_name: 'Doe')
sign_in(current_user)
visit project_medical_releases_path(project)
click_link *view_release_pdf_link_for(medical_release)
expect(content_type).to eq('application/pdf')
expect(content_disposition).to include('inline')
expect(pdf_body).not_to have_content for_office_use_only.upcase
expect(pdf_body).not_to have_content producer_label
expect(pdf_body).not_to have_content production_label
expect(pdf_body).not_to have_content issued_to_label
expect(pdf_body).not_to have_content issued_by_label
expect(pdf_body).not_to have_content date_issued
expect(pdf_body).not_to have_content 'Big Joe'
end
scenario 'viewing contract PDF with medical questionnaire' do scenario 'viewing contract PDF with medical questionnaire' do
contract_template = create(:medical_release_contract_template, project: project, questionnaire_legal_text: "Questionnaire legal text", question_1_text: "Question 1 text") contract_template = create(:medical_release_contract_template, project: project, questionnaire_legal_text: "Questionnaire legal text", question_1_text: "Question 1 text")
medical_release = create(:medical_release, medical_release = create(:medical_release,
@@ -343,15 +276,6 @@ feature "User managing medical releases" do
expect(page).to have_link("Download", exact: true, count: 0) expect(page).to have_link("Download", exact: true, count: 0)
end end
scenario "Review action in Manage menu is not visible" do
create(:medical_release_with_contract_template, :native, project: project)
create(:medical_release_with_contract_template, :non_native, project: project)
visit project_medical_releases_path(project)
expect(page).not_to have_link(review_action, exact: true)
end
scenario "Downloading PDF of native medical release is not possible" do scenario "Downloading PDF of native medical release is not possible" do
native_release = create(:medical_release_with_contract_template, :native, project: project) native_release = create(:medical_release_with_contract_template, :native, project: project)
@@ -396,15 +320,6 @@ feature "User managing medical releases" do
expect(page).to have_link("Download", exact: true, count: 0) expect(page).to have_link("Download", exact: true, count: 0)
end end
scenario "Review action in Manage menu is not visible" do
create(:medical_release_with_contract_template, :native, project: project)
create(:medical_release_with_contract_template, :non_native, project: project)
visit project_medical_releases_path(project)
expect(page).not_to have_link(review_action, exact: true)
end
scenario "Downloading PDF of native medical release is not possible" do scenario "Downloading PDF of native medical release is not possible" do
native_release = create(:medical_release_with_contract_template, :native, project: project) native_release = create(:medical_release_with_contract_template, :native, project: project)
@@ -584,40 +499,4 @@ feature "User managing medical releases" do
def dummy_signature_legal_text def dummy_signature_legal_text
'Some signature legal language' 'Some signature legal language'
end end
def review_action
t 'medical_releases.medical_release.actions.review'
end
def review_page_heading
t 'approvals.new.heading', release_type: "Medical Release"
end
def approve_button
t 'approvals.new.actions.approve'
end
def for_office_use_only
t 'contracts.for_office_use_only.heading'
end
def producer_label
t 'contracts.for_office_use_only.description_labels.producer'
end
def production_label
t 'contracts.for_office_use_only.description_labels.production'
end
def issued_to_label
t 'contracts.for_office_use_only.description_labels.issued_to'
end
def issued_by_label
t 'contracts.for_office_use_only.description_labels.issued_by'
end
def date_issued
t 'contracts.for_office_use_only.description_labels.date_issued'
end
end end

View File

@@ -79,83 +79,6 @@ feature "User managing misc releases" do
expect(content_type).to eq('application/pdf') expect(content_type).to eq('application/pdf')
end end
scenario "Review action in Manage menu is visible" do
create(:misc_release_with_contract_template, :native, project: project)
visit project_misc_releases_path(project)
expect(page).to have_link(review_action, exact: true)
end
scenario "Reviewing release" do
create(:misc_release_with_contract_template, :native, project: project)
visit project_misc_releases_path(project)
click_link review_action
expect(page).to have_content review_page_heading
expect(page).to have_content approve_button
end
scenario "Approved releases have checkmark and non-approved releases don't have checkmarks" do
create(:misc_release_with_contract_template, :native, project: project)
visit project_misc_releases_path(project)
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 0)
create(:misc_release_with_contract_template, :native, project: project, approved_by_user_email: "some@email.com", approved_at: DateTime.now)
visit project_misc_releases_path(project)
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 1)
end
scenario 'When viewing the contract PDF of approved release there is page for office use only' do
misc_release = create(:misc_release_with_contract_template,
:native,
project: project,
person_first_name: 'Jane',
person_last_name: 'Doe',
approved_by_user_name: "Big Joe",
approved_by_user_email: "some@email.com",
approved_at: DateTime.now)
sign_in(current_user)
visit project_misc_releases_path(project)
click_link *view_release_pdf_link_for(misc_release)
expect(content_type).to eq('application/pdf')
expect(content_disposition).to include('inline')
expect(pdf_body).to have_content for_office_use_only.upcase
expect(pdf_body).to have_content producer_label
expect(pdf_body).to have_content production_label
expect(pdf_body).to have_content issued_to_label
expect(pdf_body).to have_content issued_by_label
expect(pdf_body).to have_content date_issued
expect(pdf_body).to have_content 'Big Joe'
end
scenario 'When viewing the contract PDF of not approved release there is no page for office use only' do
misc_release = create(:misc_release_with_contract_template,
:native,
project: project,
person_first_name: 'Jane',
person_last_name: 'Doe')
sign_in(current_user)
visit project_misc_releases_path(project)
click_link *view_release_pdf_link_for(misc_release)
expect(content_type).to eq('application/pdf')
expect(content_disposition).to include('inline')
expect(pdf_body).not_to have_content for_office_use_only.upcase
expect(pdf_body).not_to have_content producer_label
expect(pdf_body).not_to have_content production_label
expect(pdf_body).not_to have_content issued_to_label
expect(pdf_body).not_to have_content issued_by_label
expect(pdf_body).not_to have_content date_issued
expect(pdf_body).not_to have_content 'Big Joe'
end
scenario 'viewing the contract PDF' do scenario 'viewing the contract PDF' do
misc_release = create(:misc_release, misc_release = create(:misc_release,
@@ -218,14 +141,6 @@ feature "User managing misc releases" do
expect(page).to have_link("Download", exact: true, count: 0) expect(page).to have_link("Download", exact: true, count: 0)
end end
scenario "Review action in Manage menu is not visible" do
create(:misc_release_with_contract_template, :native, project: project)
visit project_misc_releases_path(project)
expect(page).not_to have_link(review_action, exact: true)
end
end end
private private
@@ -300,40 +215,4 @@ feature "User managing misc releases" do
def view_release_pdf_link_for(release) def view_release_pdf_link_for(release)
['Download', href: misc_release_contracts_path(release, format: 'pdf')] ['Download', href: misc_release_contracts_path(release, format: 'pdf')]
end end
def review_action
t 'misc_releases.misc_release.actions.review'
end
def review_page_heading
t 'approvals.new.heading', release_type: "Misc Release"
end
def approve_button
t 'approvals.new.actions.approve'
end
def for_office_use_only
t 'contracts.for_office_use_only.heading'
end
def producer_label
t 'contracts.for_office_use_only.description_labels.producer'
end
def production_label
t 'contracts.for_office_use_only.description_labels.production'
end
def issued_to_label
t 'contracts.for_office_use_only.description_labels.issued_to'
end
def issued_by_label
t 'contracts.for_office_use_only.description_labels.issued_by'
end
def date_issued
t 'contracts.for_office_use_only.description_labels.date_issued'
end
end end

View File

@@ -92,39 +92,9 @@ feature "User managing music releases" do
before do before do
sign_in current_user sign_in current_user
end end
scenario "Review action in Manage menu is visible" do
create(:music_release_with_contract_template, project: project)
visit project_music_releases_path(project)
click_on "Manage"
expect(page).to have_link(review_action, exact: true)
end
scenario "Reviewing release" do
create(:music_release_with_contract_template, project: project)
visit project_music_releases_path(project)
click_on "Manage"
click_link review_action
expect(page).to have_content review_page_heading
expect(page).to have_content approve_button
end
end end
context "when the user is project manager" do context "when the user is project manager" do
scenario "Review action in Manage menu is not visible" do
create(:music_release_with_contract_template, project: project)
sign_in current_user
visit project_music_releases_path(project)
click_on "Manage"
expect(page).not_to have_link(review_action, exact: true)
end
end end
context "when the user is associate" do context "when the user is associate" do
@@ -133,24 +103,15 @@ feature "User managing music releases" do
before do before do
sign_in current_user sign_in current_user
end end
scenario "should not show download" do scenario "should not show download" do
collection1 = create(:music_release, name: "EDM Music", project: project) collection1 = create(:music_release, name: "EDM Music", project: project)
visit project_music_releases_path(project) visit project_music_releases_path(project)
click_on "Manage" click_on "Manage"
expect(page).not_to have_link("Download", exact: true) expect(page).not_to have_link("Download", exact: true)
end end
scenario "Review action in Manage menu is not visible" do
create(:music_release_with_contract_template, project: project)
visit project_music_releases_path(project)
click_on "Manage"
expect(page).not_to have_link(review_action, exact: true)
end
end end
private private
@@ -216,16 +177,4 @@ feature "User managing music releases" do
select "Other", from: "Restriction" select "Other", from: "Restriction"
fill_in "Describe other restrictions", with: "Test" fill_in "Describe other restrictions", with: "Test"
end end
def review_action
t 'music_releases.music_release.actions.review'
end
def review_page_heading
t 'approvals.new.heading', release_type: "Music Release"
end
def approve_button
t 'approvals.new.actions.approve'
end
end end

View File

@@ -374,104 +374,9 @@ feature "User managing talent releases" do
end end
context "when the user is account manager" do context "when the user is account manager" do
let(:current_user) { create(:user, :account_manager) }
before do
sign_in current_user
end
scenario "Review action in Manage menu is visible" do
create(:talent_release_with_contract_template, :native, project: project)
visit project_talent_releases_path(project)
expect(page).to have_link(review_action, exact: true)
end
scenario "Reviewing release" do
create(:talent_release_with_contract_template, :native, project: project)
visit project_talent_releases_path(project)
click_link review_action
expect(page).to have_content review_page_heading
expect(page).to have_content approve_button
end
scenario "Approved releases have checkmark and non-approved releases don't have checkmarks" do
create(:talent_release_with_contract_template, :native, project: project)
visit project_talent_releases_path(project)
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 0)
create(:talent_release_with_contract_template, :native, project: project, approved_by_user_email: "some@email.com", approved_at: DateTime.now)
visit project_talent_releases_path(project)
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 1)
end
scenario 'When viewing the contract PDF of approved release there is page for office use only' do
talent_release = create(:talent_release_with_contract_template,
:native,
project: project,
person_first_name: 'Jane',
person_last_name: 'Doe',
approved_by_user_name: "Big Joe",
approved_by_user_email: "some@email.com",
approved_at: DateTime.now)
sign_in(current_user)
visit project_talent_releases_path(project)
click_link *view_release_pdf_link_for(talent_release)
expect(content_type).to eq('application/pdf')
expect(content_disposition).to include('inline')
expect(pdf_body).to have_content for_office_use_only.upcase
expect(pdf_body).to have_content producer_label
expect(pdf_body).to have_content production_label
expect(pdf_body).to have_content issued_to_label
expect(pdf_body).to have_content issued_by_label
expect(pdf_body).to have_content date_issued
expect(pdf_body).to have_content 'Big Joe'
end
scenario 'When viewing the contract PDF of not approved release there is no page for office use only' do
talent_release = create(:talent_release_with_contract_template,
:native,
project: project,
person_first_name: 'Jane',
person_last_name: 'Doe')
sign_in(current_user)
visit project_talent_releases_path(project)
click_link *view_release_pdf_link_for(talent_release)
expect(content_type).to eq('application/pdf')
expect(content_disposition).to include('inline')
expect(pdf_body).not_to have_content for_office_use_only.upcase
expect(pdf_body).not_to have_content producer_label
expect(pdf_body).not_to have_content production_label
expect(pdf_body).not_to have_content issued_to_label
expect(pdf_body).not_to have_content issued_by_label
expect(pdf_body).not_to have_content date_issued
expect(pdf_body).not_to have_content 'Big Joe'
end
end end
context "when the user is project manager" do context "when the user is project manager" do
before do
sign_in current_user
end
scenario "Review action in Manage menu is not visible" do
create(:talent_release_with_contract_template, :native, project: project)
visit project_talent_releases_path(project)
click_on "Manage"
expect(page).not_to have_link(review_action, exact: true)
end
end end
context "when the user is associate" do context "when the user is associate" do
@@ -489,15 +394,6 @@ feature "User managing talent releases" do
click_on "Manage" click_on "Manage"
expect(page).not_to have_link("Download", exact: true) expect(page).not_to have_link("Download", exact: true)
end end
scenario "Review action in Manage menu is not visible" do
create(:talent_release_with_contract_template, :native, project: project)
visit project_talent_releases_path(project)
click_on "Manage"
expect(page).not_to have_link(review_action, exact: true)
end
end end
private private
@@ -679,40 +575,4 @@ feature "User managing talent releases" do
def dummy_signature_legal_text def dummy_signature_legal_text
'Some signature legal language' 'Some signature legal language'
end end
def review_action
t 'talent_releases.talent_release.actions.review'
end
def review_page_heading
t 'approvals.new.heading', release_type: "Talent Release"
end
def approve_button
t 'approvals.new.actions.approve'
end
def for_office_use_only
t 'contracts.for_office_use_only.heading'
end
def producer_label
t 'contracts.for_office_use_only.description_labels.producer'
end
def production_label
t 'contracts.for_office_use_only.description_labels.production'
end
def issued_to_label
t 'contracts.for_office_use_only.description_labels.issued_to'
end
def issued_by_label
t 'contracts.for_office_use_only.description_labels.issued_by'
end
def date_issued
t 'contracts.for_office_use_only.description_labels.date_issued'
end
end end

View File

@@ -19,7 +19,7 @@ describe GenerateContractsZipJob do
describe ".perform_later" do describe ".perform_later" do
it "enqueues a background job for generating zip file" do it "enqueues a background job for generating zip file" do
expect { expect {
GenerateContractsZipJob.perform_later(project, download, "AppearanceRelease", project.appearance_releases.ids) GenerateContractsZipJob.perform_later(project, download, "AppearanceRelease", project.appearance_releases.ids, '', '')
}.to have_enqueued_job }.to have_enqueued_job
end end
end end
@@ -28,7 +28,7 @@ describe GenerateContractsZipJob do
shared_examples "generates ZIP containig CSV file with all releases data" do shared_examples "generates ZIP containig CSV file with all releases data" do
it "generates ZIP containing CSV file with all releases data for all release types" do it "generates ZIP containing CSV file with all releases data for all release types" do
lowercase_plural = subject.constantize.model_name.plural lowercase_plural = subject.constantize.model_name.plural
GenerateContractsZipJob.perform_now(project, download, subject, project.public_send(lowercase_plural).ids) GenerateContractsZipJob.perform_now(project, download, subject, project.public_send(lowercase_plural).ids, '', '')
generated_zip = download.file.blob.download generated_zip = download.file.blob.download
csv_file_name = "#{project.name.parameterize}_#{lowercase_plural.gsub('_', '-')}.csv" csv_file_name = "#{project.name.parameterize}_#{lowercase_plural.gsub('_', '-')}.csv"
@@ -50,8 +50,111 @@ describe GenerateContractsZipJob do
end end
end end
shared_examples "generates ZIP containig CSV file with specific releases data" do
it "generates ZIP containing CSV file with all selected releases data for selected releases" do
lowercase_plural = subject.constantize.model_name.plural
all_releases = project.public_send(lowercase_plural)
included_releases = all_releases.where(id: all_releases.ids[0..1])
not_included_releases = all_releases.where.not(id: all_releases.ids[0..1])
GenerateContractsZipJob.perform_now(project, download, subject, included_releases.ids, '', '')
generated_zip = download.file.blob.download
csv_file_name = "#{project.name.parameterize}_#{lowercase_plural.gsub('_', '-')}.csv"
Zip::InputStream.open(StringIO.new(generated_zip)) do |io|
while entry = io.get_next_entry
next unless entry.name == csv_file_name
csv_file = entry.get_input_stream.read
release_class = Object.const_get subject
release_headers = release_class.csv_headers
release_headers.each do |header|
expect(csv_file).to match header
expect(csv_file).not_to match translation_missing
end
included_releases.each do |release|
expect(csv_file).to match release.person_first_name
end
not_included_releases.each do |release|
expect(csv_file).not_to match release.person_first_name
end
end
end
end
it "generates ZIP containing CSV file with all filtered releases data for filtered releases" do
lowercase_plural = subject.constantize.model_name.plural
GenerateContractsZipJob.perform_now(project, download, subject, [], '', 'complete')
complete_releases = project.public_send(lowercase_plural).complete
incomplete_releases = project.public_send(lowercase_plural).incomplete
generated_zip = download.file.blob.download
csv_file_name = "#{project.name.parameterize}_#{lowercase_plural.gsub('_', '-')}.csv"
Zip::InputStream.open(StringIO.new(generated_zip)) do |io|
while entry = io.get_next_entry
next unless entry.name == csv_file_name
csv_file = entry.get_input_stream.read
release_class = Object.const_get subject
release_headers = release_class.csv_headers
release_headers.each do |header|
expect(csv_file).to match header
expect(csv_file).not_to match translation_missing
end
complete_releases.each do |release|
expect(csv_file).to match release.person_first_name
end
incomplete_releases.each do |release|
expect(csv_file).not_to match release.person_first_name
end
end
end
end
it "generates ZIP containing CSV file with all search query matching releases" do
lowercase_plural = subject.constantize.model_name.plural
matched_releases = project.public_send(lowercase_plural).search('Brad')
not_matched_releases = project.public_send(lowercase_plural).where.not(id: matched_releases.ids)
GenerateContractsZipJob.perform_now(project, download, subject, [], 'Brad', '')
generated_zip = download.file.blob.download
csv_file_name = "#{project.name.parameterize}_#{lowercase_plural.gsub('_', '-')}.csv"
Zip::InputStream.open(StringIO.new(generated_zip)) do |io|
while entry = io.get_next_entry
next unless entry.name == csv_file_name
csv_file = entry.get_input_stream.read
release_class = Object.const_get subject
release_headers = release_class.csv_headers
release_headers.each do |header|
expect(csv_file).to match header
expect(csv_file).not_to match translation_missing
end
matched_releases.each do |release|
expect(csv_file).to match release.person_first_name
end
not_matched_releases.each do |release|
expect(csv_file).not_to match release.person_first_name
end
end
end
end
end
it "updates a download record and creates attachment for it" do it "updates a download record and creates attachment for it" do
GenerateContractsZipJob.perform_now(project, download, "AppearanceRelease", project.appearance_releases.ids) GenerateContractsZipJob.perform_now(project, download, "AppearanceRelease", project.appearance_releases.ids, '', '')
expect(download.project).to eq project expect(download.project).to eq project
expect(download.release_type).to eq "AppearanceRelease" expect(download.release_type).to eq "AppearanceRelease"
@@ -69,9 +172,12 @@ describe GenerateContractsZipJob do
context "generates ZIP for appearance releases" do context "generates ZIP for appearance releases" do
let(:release) { create(:appearance_release_with_contract_template, :native, project: project, person_name: "John Doe") } let(:release) { create(:appearance_release_with_contract_template, :native, project: project, person_name: "John Doe") }
let(:incomplete_release) { create(:appearance_release_with_contract_template, project: project, person_name: "Jane Doe") }
let(:complete_release) { create(:appearance_release_with_contract_template, :non_native, project: project, person_name: "Brad Doe") }
subject { 'AppearanceRelease' } subject { 'AppearanceRelease' }
it_behaves_like "generates ZIP containig CSV file with all releases data" it_behaves_like "generates ZIP containig CSV file with all releases data"
it_behaves_like "generates ZIP containig CSV file with specific releases data"
end end
context "generates ZIP for location releases" do context "generates ZIP for location releases" do
@@ -125,7 +231,7 @@ describe GenerateContractsZipJob do
end end
it "updates status to 'failure' and sends user a notification" do it "updates status to 'failure' and sends user a notification" do
GenerateContractsZipJob.perform_now(project, download, "AppearanceRelease", project.appearance_releases.ids) GenerateContractsZipJob.perform_now(project, download, "AppearanceRelease", project.appearance_releases.ids, '', '')
expect(download.status).to eq "failure" expect(download.status).to eq "failure"
expect(ProjectsChannel).to have_received(:broadcast_download_generation_update).with(download, I18n.t("contract_downloads.download.failure")) expect(ProjectsChannel).to have_received(:broadcast_download_generation_update).with(download, I18n.t("contract_downloads.download.failure"))

View File

@@ -1,6 +1,7 @@
require "rails_helper" require "rails_helper"
RSpec.describe AcquiredMediaRelease do RSpec.describe AcquiredMediaRelease do
it_behaves_like 'an approvable'
it_behaves_like "a contractable" it_behaves_like "a contractable"
it_behaves_like "an exploitable" it_behaves_like "an exploitable"
it_behaves_like "a notable" it_behaves_like "a notable"

View File

@@ -3,6 +3,7 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe AppearanceRelease do RSpec.describe AppearanceRelease do
it_behaves_like 'an approvable'
it_behaves_like 'a contractable' it_behaves_like 'a contractable'
it_behaves_like 'an exploitable' it_behaves_like 'an exploitable'
it_behaves_like 'a notable' it_behaves_like 'a notable'

View File

@@ -6,7 +6,8 @@ RSpec.describe BroadcastRecording, type: :model do
end end
describe "validations" do describe "validations" do
subject { described_class.new(asset_uid: "asset_uid", asset_playback_uid: "playback_uid", file_name: "medium.mp4") } let(:broadcast) { create(:broadcast, :with_stream, skip_create_callback: true, name: "My Broadcast") }
subject { described_class.new(asset_uid: "asset_uid", asset_playback_uid: "playback_uid", file_name: "medium.mp4", broadcast: broadcast) }
it { is_expected.to validate_uniqueness_of(:asset_uid) } it { is_expected.to validate_uniqueness_of(:asset_uid) }
end end
@@ -24,16 +25,20 @@ RSpec.describe BroadcastRecording, type: :model do
let(:broadcast_recording) { create(:broadcast_recording, broadcast: broadcast) } let(:broadcast_recording) { create(:broadcast_recording, broadcast: broadcast) }
it "should have a download url" do it "should have a download url" do
download_file_name = broadcast_recording.send(:download_file_name) name = broadcast_recording.name
expect(broadcast_recording.download_url).to eq("https://stream.mux.com/asset_playback_uid/high.mp4?download=#{download_file_name}") expect(broadcast_recording.download_url).to eq("https://stream.mux.com/asset_playback_uid/high.mp4?download=#{name}")
end end
end end
describe "#download_file_name" do describe "#download_file_name" do
before do
allow_any_instance_of(BroadcastRecording).to receive(:download_file_name).and_return("my-broadcast_date_2020-05-14_time_15-30-00")
end
it "includes the name of the live stream and the created datetime" do it "includes the name of the live stream and the created datetime" do
broadcast = create(:broadcast, skip_create_callback: true, name: "My Broadcast") broadcast = create(:broadcast, skip_create_callback: true, name: "My Broadcast")
recording = create(:broadcast_recording, broadcast: broadcast, created_at: DateTime.new(2020, 05, 14, 15, 30, 00)) recording = create(:broadcast_recording, broadcast: broadcast)
file_name = recording.download_file_name file_name = recording.name
expect(file_name).to eq "my-broadcast_date_2020-05-14_time_15-30-00" expect(file_name).to eq "my-broadcast_date_2020-05-14_time_15-30-00"
end end

View File

@@ -1,6 +1,7 @@
require "rails_helper" require "rails_helper"
RSpec.describe LocationRelease do RSpec.describe LocationRelease do
it_behaves_like 'an approvable'
it_behaves_like "a contractable" it_behaves_like "a contractable"
it_behaves_like "an exploitable" it_behaves_like "an exploitable"
it_behaves_like "a notable" it_behaves_like "a notable"

View File

@@ -1,6 +1,7 @@
require "rails_helper" require "rails_helper"
RSpec.describe MaterialRelease do RSpec.describe MaterialRelease do
it_behaves_like 'an approvable'
it_behaves_like "a contractable" it_behaves_like "a contractable"
it_behaves_like "an exploitable" it_behaves_like "an exploitable"
it_behaves_like "a notable" it_behaves_like "a notable"

View File

@@ -1,6 +1,7 @@
require "rails_helper" require "rails_helper"
RSpec.describe MedicalRelease do RSpec.describe MedicalRelease do
it_behaves_like 'an approvable'
it_behaves_like "a contractable" it_behaves_like "a contractable"
it_behaves_like "a notable" it_behaves_like "a notable"
it_behaves_like "a photoable" it_behaves_like "a photoable"

View File

@@ -1,6 +1,7 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe MiscRelease, type: :model do RSpec.describe MiscRelease, type: :model do
it_behaves_like 'an approvable'
it_behaves_like "a contractable" it_behaves_like "a contractable"
it_behaves_like "a notable" it_behaves_like "a notable"
it_behaves_like "a photoable" it_behaves_like "a photoable"

View File

@@ -1,6 +1,7 @@
require "rails_helper" require "rails_helper"
RSpec.describe MusicRelease do RSpec.describe MusicRelease do
it_behaves_like 'an approvable'
it_behaves_like "a contractable" it_behaves_like "a contractable"
it_behaves_like "an exploitable" it_behaves_like "an exploitable"
it_behaves_like "a notable" it_behaves_like "a notable"

View File

@@ -1,6 +1,7 @@
require "rails_helper" require "rails_helper"
RSpec.describe TalentRelease do RSpec.describe TalentRelease do
it_behaves_like 'an approvable'
it_behaves_like "a contractable" it_behaves_like "a contractable"
it_behaves_like "an exploitable" it_behaves_like "an exploitable"
it_behaves_like "a notable" it_behaves_like "a notable"

View File

@@ -24,7 +24,11 @@ describe MaterialReleasePolicy do
end end
end end
permissions :edit_photos? do permissions :edit_files? do
it { is_expected.to permit(:edit_photos) }
end
permissions :update_files? do
it { is_expected.to permit(:edit_photos) } it { is_expected.to permit(:edit_photos) }
end end

View File

@@ -0,0 +1,47 @@
shared_examples_for "an approvable" do
it { is_expected.to respond_to(:approved_by_user_signature) }
describe "#approve_by" do
before do
allow(BigMediaTime).to receive(:time_zone_now).and_return(1.week.ago)
end
it "stores info about the approving user" do
user = double(full_name: "Jane Doe", email: "jane.doe@test.com")
subject.approve_by(user)
expect(subject.approved_by_user_name).to eq "Jane Doe"
expect(subject.approved_by_user_email).to eq "jane.doe@test.com"
expect(subject.approved_at).to eq BigMediaTime.time_zone_now
end
context "when approval has already been given" do
it "does not change the existing info" do
user1 = double(full_name: "Jane Doe", email: "jane.doe@test.com")
subject.approve_by(user1)
expect(subject.approved_by_user_name).to eq "Jane Doe"
expect(subject.approved_by_user_email).to eq "jane.doe@test.com"
expect(subject.approved_at).to eq BigMediaTime.time_zone_now
user2 = double(full_name: "John Doe", email: "john.doe@test.com")
subject.approve_by(user2)
expect(subject.approved_by_user_name).to eq "Jane Doe"
expect(subject.approved_by_user_email).to eq "jane.doe@test.com"
expect(subject.approved_at).to eq BigMediaTime.time_zone_now
end
end
end
describe "#approved?" do
it "indicates whether or not it has been approved" do
subject.approved_at = nil
expect(subject).not_to be_approved
subject.approved_at = 1.week.ago
expect(subject).to be_approved
end
end
end

View File

@@ -2,7 +2,7 @@ module SignatureHelper
def draw_signature(file, signature_field_id) def draw_signature(file, signature_field_id)
data_uri = ActionController::Base.helpers.escape_javascript(Base64Image.from_image(file).data_uri) data_uri = ActionController::Base.helpers.escape_javascript(Base64Image.from_image(file).data_uri)
page.execute_script <<-JS page.execute_script <<-JS
$("##{signature_field_id}").val("#{data_uri}") document.getElementById("#{signature_field_id}").value = "#{data_uri}";
JS JS
end end
end end