Compare commits
6 Commits
microsoft-
...
change-api
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09f4e4d454 | ||
|
|
9a1f49f0dc | ||
|
|
f611382e9e | ||
|
|
95a14ab2f6 | ||
|
|
896cec2259 | ||
|
|
a493076f9b |
@@ -32,10 +32,3 @@ CUSTOM_API_TOKEN=
|
||||
# Required for simulcasting to Millicast for director mode
|
||||
MILLICAST_API_SECRET=
|
||||
MILLICAST_ACCOUNT_ID=
|
||||
|
||||
# Required for Microsoft Azure AD Auth
|
||||
AZURE_CLIENT_ID = Client App ID
|
||||
AZURE_CLIENT_SECRET = Client App Secret
|
||||
AZURE_TENANT_ID = Client App Tenant ID
|
||||
AZURE_REDIRECT_URI = where microsoft will redirect after login, eg. http://localhost:3000/auth/azure_ad/callback
|
||||
AZURE_SCOPES = Scopes required for Application, eg. 'openid email profile User.Read offline_access OnlineMeetings.ReadWrite'
|
||||
5
Gemfile
5
Gemfile
@@ -139,11 +139,6 @@ gem 'rack-cors'
|
||||
# Ruby wrappers for the HubSpot REST API
|
||||
gem "hubspot-ruby"
|
||||
|
||||
# OAuth
|
||||
gem 'omniauth-oauth2', '~> 1.6'
|
||||
# OmniAuth CSRF protection
|
||||
gem 'omniauth-rails_csrf_protection', '~> 0.1.2'
|
||||
|
||||
group :development, :test, :review do
|
||||
# Call "byebug" anywhere in the code to stop execution and get a debugger console
|
||||
gem "byebug", "~> 11.0.1", platforms: [:mri, :mingw, :x64_mingw]
|
||||
|
||||
19
Gemfile.lock
19
Gemfile.lock
@@ -220,7 +220,6 @@ GEM
|
||||
activesupport (>= 4.2.0)
|
||||
hashdiff (1.0.1)
|
||||
hashery (2.1.2)
|
||||
hashie (4.1.0)
|
||||
hexapdf (0.9.3)
|
||||
cmdparse (~> 3.0, >= 3.0.3)
|
||||
geom2d (~> 0.2)
|
||||
@@ -298,7 +297,6 @@ GEM
|
||||
money (~> 6.13.2)
|
||||
railties (>= 3.0)
|
||||
msgpack (1.3.1)
|
||||
multi_json (1.15.0)
|
||||
multi_xml (0.6.0)
|
||||
multipart-post (2.1.1)
|
||||
nio4r (2.5.2)
|
||||
@@ -310,21 +308,6 @@ GEM
|
||||
warden
|
||||
oath-generators (1.0.1)
|
||||
oath (>= 0.0.12)
|
||||
oauth2 (1.4.4)
|
||||
faraday (>= 0.8, < 2.0)
|
||||
jwt (>= 1.0, < 3.0)
|
||||
multi_json (~> 1.3)
|
||||
multi_xml (~> 0.5)
|
||||
rack (>= 1.2, < 3)
|
||||
omniauth (1.9.1)
|
||||
hashie (>= 3.4.6)
|
||||
rack (>= 1.6.2, < 3)
|
||||
omniauth-oauth2 (1.6.0)
|
||||
oauth2 (~> 1.1)
|
||||
omniauth (~> 1.9)
|
||||
omniauth-rails_csrf_protection (0.1.2)
|
||||
actionpack (>= 4.2)
|
||||
omniauth (>= 1.3.1)
|
||||
parallel (1.19.1)
|
||||
parity (3.2.0)
|
||||
parser (2.6.5.0)
|
||||
@@ -569,8 +552,6 @@ DEPENDENCIES
|
||||
mux_ruby!
|
||||
oath (~> 1.1.0)
|
||||
oath-generators (~> 1.0.1)
|
||||
omniauth-oauth2 (~> 1.6)
|
||||
omniauth-rails_csrf_protection (~> 0.1.2)
|
||||
parity (~> 3.2.0)
|
||||
pdf-reader (~> 2.1.0)
|
||||
pdfkit (~> 0.8.2)
|
||||
|
||||
@@ -24,6 +24,8 @@ $(document).on "turbolinks:load", ->
|
||||
stream_selected = $("#broadcast_video").data('videoType') == 'stream';
|
||||
if data.streamer_status == 'recording' && data.status == 'active' && stream_selected
|
||||
$("#broadcast_video").html data.video_content
|
||||
$("#live_take").html data.live_take_content
|
||||
|
||||
new (Clappr.Player)(
|
||||
<%= "baseUrl: 'http://cdn.clappr.io/latest'," if Rails.env.test? %>
|
||||
parentId: '#broadcast_video'
|
||||
@@ -35,6 +37,7 @@ $(document).on "turbolinks:load", ->
|
||||
hlsMinimumDvrSize: 1)
|
||||
if data.streamer_status == "idle" && data.status == "idle"
|
||||
$("#broadcast_video").html data.video_content
|
||||
$("#live_take").html data.live_take_content
|
||||
|
||||
showBroadcastRecordings: (data) ->
|
||||
$(".flash-message").html data.flash_content
|
||||
|
||||
4
app/assets/javascripts/switch_director_mode.js
Normal file
4
app/assets/javascripts/switch_director_mode.js
Normal 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();
|
||||
});
|
||||
@@ -412,6 +412,16 @@ a[data-behavior=seekable-timecode] {
|
||||
background-color: rgba($black, 0.05);
|
||||
}
|
||||
|
||||
// Black background
|
||||
.bg-black {
|
||||
background-color: $black;
|
||||
}
|
||||
|
||||
// White background
|
||||
.bg-white {
|
||||
background-color: $white;
|
||||
}
|
||||
|
||||
// Custom width
|
||||
.w-65 {
|
||||
width: 65% !important;
|
||||
@@ -422,8 +432,32 @@ a[data-behavior=seekable-timecode] {
|
||||
max-height: 30rem;
|
||||
}
|
||||
|
||||
// Max-width 75%
|
||||
.max-w-75 {
|
||||
max-width: 75%;
|
||||
}
|
||||
|
||||
// Fix height and width
|
||||
.fix-h-and-w {
|
||||
width: 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;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ class BroadcastsChannel < ApplicationCable::Channel
|
||||
def self.broadcast_stream_updates(broadcast)
|
||||
status_content = ApplicationController.render partial: "broadcasts/broadcast_status", 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, {
|
||||
event: :broadcast_stream_update,
|
||||
@@ -18,6 +19,7 @@ class BroadcastsChannel < ApplicationCable::Channel
|
||||
playback_url: broadcast.stream_playback_url,
|
||||
full_live_stream_playback_url: broadcast.full_live_stream_playback_url,
|
||||
video_content: video_content,
|
||||
live_take_content: live_take,
|
||||
status_content: status_content,
|
||||
streamer_status: broadcast.streamer_status
|
||||
}
|
||||
|
||||
@@ -45,13 +45,14 @@ class Api::ReleasesController < Api::ApiController
|
||||
if model_name == "acquired_media_release"
|
||||
mapping = {
|
||||
"#{model_name.camelize}": SerializableAcquiredMediaRelease,
|
||||
FileInfo: SerializableFileInfo
|
||||
FileInfo: SerializableFileInfo,
|
||||
"ActiveStorage::Attachment".to_sym => ActiveStorage::SerializableAttachment,
|
||||
}
|
||||
|
||||
render jsonapi: release,
|
||||
status: status,
|
||||
class: mapping,
|
||||
include: [:file_infos]
|
||||
include: [:files, :file_infos]
|
||||
else
|
||||
mapping = {
|
||||
"#{model_name.camelize}": show_serializable,
|
||||
|
||||
@@ -4,6 +4,7 @@ require './lib/knock_monkeypatch'
|
||||
|
||||
class Api::UserTokenController < Knock::AuthTokenController
|
||||
include Oath::ControllerHelpers
|
||||
include RememberMe::Controller
|
||||
|
||||
skip_before_action :verify_authenticity_token
|
||||
before_action :sign_in_user
|
||||
|
||||
@@ -6,9 +6,12 @@ class ApprovalsController < ApplicationController
|
||||
|
||||
def create
|
||||
@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)
|
||||
else
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
@@ -25,4 +28,21 @@ class ApprovalsController < ApplicationController
|
||||
def set_project
|
||||
@project = @releasable.project
|
||||
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
|
||||
|
||||
34
app/controllers/broadcast_recording_starrings_controller.rb
Normal file
34
app/controllers/broadcast_recording_starrings_controller.rb
Normal 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
|
||||
@@ -5,13 +5,25 @@ class BroadcastRecordingsController < ApplicationController
|
||||
before_action :set_broadcast
|
||||
before_action :set_recording
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@recording.update(broadcast_recording_params)
|
||||
set_recordings
|
||||
end
|
||||
|
||||
def destroy
|
||||
@recording.update(hidden: true)
|
||||
@recordings = @broadcast.broadcast_recordings.visible.order_by_recent.paginate(page: params[:page])
|
||||
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
|
||||
@@ -23,4 +35,8 @@ class BroadcastRecordingsController < ApplicationController
|
||||
def set_recording
|
||||
@recording = authorize policy_scope(@broadcast.broadcast_recordings).find(params[:id])
|
||||
end
|
||||
|
||||
def set_recordings
|
||||
@recordings = @broadcast.broadcast_recordings.visible.order_by_recent.paginate(page: params[:page])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -32,6 +32,7 @@ class BroadcastsController < ApplicationController
|
||||
@conference_url = conference_url_for(@broadcast)
|
||||
@recordings = @broadcast.broadcast_recordings.visible.order_by_recent.paginate(page: params[:page])
|
||||
@files = @broadcast.files.order("created_at DESC").paginate(page: params[:files_page])
|
||||
|
||||
render layout: 'application'
|
||||
end
|
||||
|
||||
@@ -75,7 +76,7 @@ class BroadcastsController < ApplicationController
|
||||
end
|
||||
|
||||
def broadcast_params
|
||||
params.require(:broadcast).permit(:name, :shoot_location_time_zone, :conference_option, files: [])
|
||||
params.require(:broadcast).permit(:name, :shoot_location_time_zone, files: [])
|
||||
end
|
||||
|
||||
def set_project
|
||||
@@ -113,7 +114,7 @@ class BroadcastsController < ApplicationController
|
||||
end
|
||||
|
||||
def conference_url_for(broadcast)
|
||||
broadcast.video_conference_url_override || url_for([broadcast.project, broadcast, :conference_meeting])
|
||||
broadcast.video_conference_url_override.presence || url_for([broadcast.project, broadcast, :zoom_meeting])
|
||||
end
|
||||
|
||||
def log_create_analytics
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
class CallbacksController < ApplicationController
|
||||
skip_before_action :require_login
|
||||
skip_after_action :verify_authorized, except: :index
|
||||
skip_after_action :verify_policy_scoped, only: :index
|
||||
skip_before_action :verify_authenticity_token
|
||||
|
||||
def create
|
||||
uid = request.env['omniauth.auth'][:uid]
|
||||
token_data = request.env['omniauth.auth'][:credentials]
|
||||
|
||||
current_user&.tap do |user|
|
||||
user.microsoft_user_id = uid
|
||||
user.microsoft_access_token = token_data.token
|
||||
user.microsoft_refresh_token = token_data.refresh_token
|
||||
user.microsoft_token_expires_at = token_data.expires_at # Expiration time is returned in seconds
|
||||
user.save
|
||||
end
|
||||
|
||||
redirect_to profile_path
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,45 +0,0 @@
|
||||
class ConferenceMeetingsController < ApplicationController
|
||||
require 'microsoft_graph'
|
||||
|
||||
def show
|
||||
authorize broadcast = Broadcast.find(params[:broadcast_id])
|
||||
case broadcast.conference_option
|
||||
when 'zoom'
|
||||
redirect_to broadcast.zoom_meeting_url
|
||||
when 'ms_teams'
|
||||
if broadcast.conference_join_url.nil?
|
||||
begin
|
||||
graph_api = MicrosoftGraph.new(
|
||||
current_user,
|
||||
ENV['AZURE_CLIENT_ID'],
|
||||
ENV['AZURE_CLIENT_SECRET'],
|
||||
ENV['AZURE_TENANT_ID'],
|
||||
ENV['AZURE_SCOPES']
|
||||
)
|
||||
|
||||
subject = "#{broadcast.name} Online Meeting"
|
||||
teams_meeting = graph_api.create_teams_meeting(subject)
|
||||
join_url = teams_meeting['joinUrl']
|
||||
|
||||
if join_url.present?
|
||||
broadcast.conference_join_url = join_url
|
||||
broadcast.save
|
||||
else
|
||||
raise StandardError, 'Failed to read teams meeting join URL'
|
||||
end
|
||||
rescue ActionController::InvalidAuthenticityToken => e
|
||||
Rails.logger.error(e.message)
|
||||
redirect_to project_broadcast_url(broadcast.project, broadcast), alert: t('.alerts.not_authenticated')
|
||||
return
|
||||
rescue StandardError => e
|
||||
Rails.logger.error(e.message)
|
||||
redirect_to project_broadcast_url(broadcast.project, broadcast), alert: t('.alerts.failed_to_join')
|
||||
return
|
||||
end
|
||||
end
|
||||
redirect_to broadcast.conference_join_url
|
||||
else
|
||||
redirect_to project_broadcast_url(broadcast.project, broadcast), alert: t('.alerts.unknown_conference_option')
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -106,7 +106,7 @@ class MaterialReleasesController < ApplicationController
|
||||
:term_id, :term_text,
|
||||
:restriction_id, :restriction_text,
|
||||
:description,
|
||||
:contract, { photos: [] }
|
||||
:contract, files: []
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ class Public::BroadcastsController < Public::BaseController
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
class MultiViewBroadcast
|
||||
|
||||
@@ -92,7 +92,7 @@ class Public::MaterialReleasesController < Public::BaseController
|
||||
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,
|
||||
:signature_base64,
|
||||
:locale, :contract_template, :description, photos: []
|
||||
:locale, :contract_template, :description, files: []
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
6
app/controllers/zoom_meetings_controller.rb
Normal file
6
app/controllers/zoom_meetings_controller.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
class ZoomMeetingsController < ApplicationController
|
||||
def show
|
||||
authorize broadcast = Broadcast.find(params[:broadcast_id])
|
||||
redirect_to broadcast.zoom_meeting_url
|
||||
end
|
||||
end
|
||||
@@ -1,17 +0,0 @@
|
||||
module BroadcastConferencesHelper
|
||||
def options_for_conference_select
|
||||
[
|
||||
['Zoom', 'zoom'],
|
||||
['MS Teams', 'ms_teams']
|
||||
]
|
||||
end
|
||||
|
||||
def conference_option_name_from_key(key)
|
||||
option = options_for_conference_select.find { |option| option[1] == key }
|
||||
if option.present?
|
||||
option.first
|
||||
else
|
||||
'Unknown conference option'
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -15,7 +15,8 @@ class AcquiredMediaRelease < ApplicationRecord
|
||||
include SecondGuardianPhotoable
|
||||
include GuardianName
|
||||
include SecondGuardianName
|
||||
|
||||
include FilesFilterable
|
||||
|
||||
class << self
|
||||
def custom_csv_exportable_headers
|
||||
%i[name files_count owner_info]
|
||||
@@ -106,16 +107,4 @@ class AcquiredMediaRelease < ApplicationRecord
|
||||
def files_count
|
||||
files.any? ? files.size : I18n.t('acquired_media_releases.acquired_media_release.no_media')
|
||||
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
|
||||
|
||||
@@ -7,8 +7,10 @@ class BroadcastRecording < ApplicationRecord
|
||||
|
||||
scope :visible, -> { where(hidden: false) }
|
||||
|
||||
before_save :set_title_and_description
|
||||
|
||||
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
|
||||
|
||||
def playback_url
|
||||
@@ -16,6 +18,21 @@ class BroadcastRecording < ApplicationRecord
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
@@ -1,15 +1,24 @@
|
||||
module Approvable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
|
||||
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)
|
||||
return unless approved_at.nil?
|
||||
|
||||
|
||||
self.approved_by_user_name = user.full_name
|
||||
self.approved_by_user_email = user.email
|
||||
self.approved_at = Time.zone.now
|
||||
self.approved_at = BigMediaTime.time_zone_now
|
||||
end
|
||||
|
||||
|
||||
def approved?
|
||||
self.approved_at.present?
|
||||
end
|
||||
|
||||
17
app/models/concerns/files_filterable.rb
Normal file
17
app/models/concerns/files_filterable.rb
Normal 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
|
||||
@@ -3,7 +3,7 @@ class MaterialRelease < ApplicationRecord
|
||||
include Contractable
|
||||
include Exploitable
|
||||
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 Searchable
|
||||
include Signable
|
||||
@@ -16,11 +16,11 @@ class MaterialRelease < ApplicationRecord
|
||||
include SecondGuardianPhotoable
|
||||
include GuardianName
|
||||
include SecondGuardianName
|
||||
|
||||
include FilesFilterable
|
||||
|
||||
class << self
|
||||
def custom_csv_exportable_headers
|
||||
%i[name owner_info]
|
||||
%i[name owner_info files_count]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -56,6 +56,8 @@ class MaterialRelease < ApplicationRecord
|
||||
%w[guardian_2_address_zip zip],
|
||||
%w[guardian_2_address_country country]
|
||||
]
|
||||
|
||||
has_many_attached :files
|
||||
|
||||
# We don't care for the argument but method WILL receive option name
|
||||
# when called from inside with_option block, hence * argument
|
||||
@@ -92,4 +94,8 @@ class MaterialRelease < ApplicationRecord
|
||||
def uses_edl?
|
||||
true
|
||||
end
|
||||
|
||||
def files_count
|
||||
files.any? ? files.size : I18n.t('material_releases.material_release.no_media')
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
class BroadcastRecordingPolicy < ApplicationPolicy
|
||||
def create?
|
||||
true
|
||||
end
|
||||
|
||||
def destroy?
|
||||
if user.nil? || user.user.nil?
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
user.manager? || user.account_manager?
|
||||
end
|
||||
|
||||
def edit?
|
||||
destroy?
|
||||
end
|
||||
|
||||
def update?
|
||||
edit?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -19,12 +19,16 @@ class MaterialReleasePolicy < ReleasePolicy
|
||||
user.manager? || user.account_manager?
|
||||
end
|
||||
|
||||
def edit_photos?
|
||||
def edit_files?
|
||||
true
|
||||
end
|
||||
|
||||
def update_files?
|
||||
edit_files?
|
||||
end
|
||||
|
||||
def update_photos?
|
||||
edit_photos?
|
||||
edit_files?
|
||||
end
|
||||
|
||||
def tag_multiple?
|
||||
|
||||
@@ -7,7 +7,7 @@ class SerializableAcquiredMediaRelease < JSONAPI::Serializable::Resource
|
||||
:person_title, :person_company, :created_at, :updated_at, :collection_uid, :territory_old, :term_old,
|
||||
:applicable_medium_id, :applicable_medium_text, :territory_id, :territory_text, :term_id, :term_text,
|
||||
:restriction_id, :restriction_text, :categories, :description, :tag_list
|
||||
|
||||
|
||||
has_many :file_infos do
|
||||
data do
|
||||
@object.file_infos
|
||||
@@ -17,4 +17,14 @@ class SerializableAcquiredMediaRelease < JSONAPI::Serializable::Resource
|
||||
{ count: @object.file_infos.size }
|
||||
end
|
||||
end
|
||||
|
||||
has_many :files do
|
||||
data do
|
||||
@object.files
|
||||
end
|
||||
|
||||
meta do
|
||||
{ count: @object.files.size }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
<div class="card shadow-sm">
|
||||
<%= card_header text: t(".heading", release_type: @releasable_param.name.titleize), close_action_path: [@project, "#{@releasable_param.name.pluralize}"] %>
|
||||
<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| %>
|
||||
<%= 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">
|
||||
<%= link_to t("shared.cancel"), [@releasable.project, "#{@releasable_param.name.pluralize}"], class: "col-3 text-reset" %>
|
||||
<div class="col-9">
|
||||
@@ -12,4 +16,4 @@
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
1
app/views/broadcast_recording_starrings/create.js.erb
Normal file
1
app/views/broadcast_recording_starrings/create.js.erb
Normal file
@@ -0,0 +1 @@
|
||||
$("#broadcast_recordings").html("<%= j render(partial: 'broadcasts/broadcast_recordings', locals: { recordings: @recordings, broadcast: @broadcast }) %>");
|
||||
@@ -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">×</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 %>
|
||||
@@ -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");
|
||||
@@ -1,6 +1 @@
|
||||
var dom_id = "<%= dom_id(@recording) %>"
|
||||
$('[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 }) %>");
|
||||
<%= render("broadcast_recordings/refresh_recordings_list") %>
|
||||
6
app/views/broadcast_recordings/edit.js.erb
Normal file
6
app/views/broadcast_recordings/edit.js.erb
Normal 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");
|
||||
1
app/views/broadcast_recordings/update.js.erb
Normal file
1
app/views/broadcast_recordings/update.js.erb
Normal file
@@ -0,0 +1 @@
|
||||
<%= render("broadcast_recordings/refresh_recordings_list") %>
|
||||
@@ -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) } %>
|
||||
|
||||
@@ -1,18 +1,29 @@
|
||||
<% if recordings.present? %>
|
||||
<p>Click below to download the recordings of the live stream.</p>
|
||||
<ul class="mt-2">
|
||||
<div class="list-group">
|
||||
<% recordings.each do |recording| %>
|
||||
<li>
|
||||
<%= link_to(recording.download_file_name, recording.download_url, target: "_blank") %>
|
||||
<% if (controller.class.module_parent.to_s != "Public" && policy(BroadcastRecording).destroy?) %>
|
||||
<%= 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') } %>
|
||||
<% end %>
|
||||
</li>
|
||||
<div class="list-group-item list-group-item-action">
|
||||
<div class="d-flex align-items-start">
|
||||
<% if (controller.class.module_parent.to_s != "Public" && policy(BroadcastRecording).update?) %>
|
||||
<%= 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 %>
|
||||
<%= 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 %>
|
||||
</ul>
|
||||
</div>
|
||||
<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'}) %>
|
||||
</div>
|
||||
<% 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 %>
|
||||
|
||||
@@ -1,21 +1,13 @@
|
||||
<% if broadcast.streamer_connected? || (broadcast.streamer_recording? && !broadcast.active?) %>
|
||||
<div class="alert alert-info text-center text-md-left">
|
||||
<%= fa_icon "info-circle" %>
|
||||
<strong>Live stream has connected successfully and will be available soon.</strong>
|
||||
</div>
|
||||
<p class="mb-1">Live stream has connected successfully and will be available soon.</p>
|
||||
<div class="badge badge-pill badge-success mb-2 text-uppercase">Connected</div>
|
||||
<% elsif broadcast.streamer_recording? && broadcast.active? %>
|
||||
<div class="alert alert-success text-center text-md-left">
|
||||
<%= fa_icon "success" %>
|
||||
<strong>Live stream has begun, click play to watch it.</strong>
|
||||
</div>
|
||||
<p class="mb-1">Live stream has begun, click play to watch it.</p>
|
||||
<div class="badge badge-pill badge-danger mb-2 text-uppercase">Live</div>
|
||||
<% elsif broadcast.streamer_disconnected? %>
|
||||
<div class="alert alert-warning text-center text-md-left">
|
||||
<%= fa_icon "warning" %>
|
||||
<strong>Live stream got disconnected.</strong>
|
||||
</div>
|
||||
<p class="mb-1">Live stream got disconnected.</p>
|
||||
<div class="badge badge-pill badge-warning mb-2 text-uppercase">Disconnected</div>
|
||||
<% elsif (broadcast.idle? && broadcast.streamer_idle?) || (broadcast.created? && broadcast.streamer_idle?) %>
|
||||
<div class="alert alert-info text-center text-md-left">
|
||||
<%= fa_icon "info-circle" %>
|
||||
<strong>Live stream is waiting to begin.</strong>
|
||||
</div>
|
||||
<% end %>
|
||||
<p class="mb-1">Live stream is waiting to begin.</p>
|
||||
<div class="badge badge-pill badge-primary mb-2 text-uppercase">Idle</div>
|
||||
<% end %>
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
<%= bootstrap_form_with model: model, local: true do |form| %>
|
||||
<%= form.text_field :name %>
|
||||
<%= form.select :conference_option, options_for_conference_select, { label: t('.labels.conference_option') }, class: "form-control custom-select" %>
|
||||
<%= form.time_zone_select(:shoot_location_time_zone, nil, label: "Time zone of shoot location") %>
|
||||
|
||||
<div class="row align-items-center text-center mt-4">
|
||||
|
||||
12
app/views/broadcasts/_live_take.html.erb
Normal file
12
app/views/broadcasts/_live_take.html.erb
Normal 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/>
|
||||
@@ -9,7 +9,7 @@
|
||||
<table class="w-100 h-100 bg-secondary">
|
||||
<tbody>
|
||||
<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.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -14,159 +14,135 @@
|
||||
<% end %>
|
||||
|
||||
<% content_for :header do %>
|
||||
<header class="container-fluid py-3 border-bottom sticky-top bg-light">
|
||||
<div class="row align-items-center justify-content-center">
|
||||
<div class="col-4 text-center">
|
||||
<%= product_wordmark(:direct_me, class: 'navbar-brand') %>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<header></header>
|
||||
<% end %>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-8 col-md-12 mb-3">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<h1 class="h3 m-0"><%= @broadcast.name %></h1>
|
||||
<div class="dropdown">
|
||||
<%= link_to "Switch View", "#", class: "btn btn-light border dropdown-toggle", role: "button", id: "dropdownMenuLink", data: { toggle: "dropdown" }, aria: { haspopup: "true", expanded: "false" } %>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
|
||||
<h5 class="dropdown-header">Live Streams</h5>
|
||||
<%= link_to fa_icon("check", text: @broadcast.name.titleize), "#", data: { behavior: "play_stream"}, class: "dropdown-item active" %>
|
||||
<% @multi_view_broadcasts.each do |broadcast| %>
|
||||
<% 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) %>
|
||||
<div class="row no-gutters m-n3">
|
||||
<div class="col-lg-8 col-md-12 bg-black">
|
||||
<div class="d-flex justify-content-start align-items-center flex-row p-3 mb-5 bg-dark">
|
||||
<%= product_wordmark(:direct_me, class: 'navbar-brand text-white') %>
|
||||
<div class="ml-4 dropdown">
|
||||
<%= 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 %>
|
||||
<i class="fa fa-video-camera text-primary" aria-hidden="true"></i><span class="ml-2" id="selected_stream"><%= @broadcast.name %></span>
|
||||
<% end %>
|
||||
<div class="dropdown-menu bg-black" aria-labelledby="dropdownMenuLink">
|
||||
<h5 class="dropdown-header">Live Streams</h5>
|
||||
<%= link_to fa_icon("check", text: @broadcast.name.titleize), "#", data: { behavior: "play_stream"}, class: "dropdown-item active" %>
|
||||
<% @multi_view_broadcasts.each do |broadcast| %>
|
||||
<% if 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 %>
|
||||
<% 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 %>
|
||||
</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 class="col-lg-4 col-md-12 mb-3">
|
||||
<div class="card shadow-sm mb-3">
|
||||
<div class="card-header">
|
||||
<ul class="nav nav-tabs card-header-tabs">
|
||||
<li class="nav-item">
|
||||
<%= link_to "Home", "#home", class: class_string("nav-link", "active" => !params[:active_tab].present?), data: { toggle: "tab" } %>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<%= link_to "Previous Sessions", "#recordings", class: class_string("nav-link", "active" => params[:active_tab] == "recordings"), data: { toggle: "tab" } %>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card-body p-3">
|
||||
<div class="tab-content">
|
||||
<div class="<%= class_string("tab-pane fade show", "active" => !params[:active_tab].present?) %>" id="home">
|
||||
<div 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 #{conference_option_name_from_key(@broadcast.conference_option)} 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 class="col-lg-4 col-md-12 bg-white p-3 min-vh-100 overflow-auto">
|
||||
<% unless controller.class.module_parent.to_s == "Public" %>
|
||||
<% if @multi_view_broadcasts.present? %>
|
||||
<% tokens = @multi_view_broadcasts.map(&:token) %>
|
||||
<div class="btn-group">
|
||||
<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>
|
||||
<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>
|
||||
<% 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>
|
||||
|
||||
<!-- files section -->
|
||||
<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">
|
||||
<div class="<%= class_string("tab-pane fade show", "active" => params[:active_tab] == "files") %>" id="files">
|
||||
<% if @multi_view_broadcasts.present? %>
|
||||
<ul class="nav nav-tabs">
|
||||
<% @multi_view_broadcasts.each_with_index do |mvb, index| %>
|
||||
<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" } %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="card-body p-3">
|
||||
<div class="tab-content">
|
||||
<% if @multi_view_broadcasts.present? %>
|
||||
<div class="tab-content pt-4">
|
||||
<% @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 %>">
|
||||
<%= render partial: 'broadcasts/files_section', locals: { broadcast: mvb, files: mvb.files } %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<div class="tab-pane fade show active" id="files_broadcast_<%= @broadcast.id %>">
|
||||
<%= render partial: 'broadcasts/files_section', locals: { broadcast: @broadcast, files: @files } %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% else %>
|
||||
<%= render partial: 'broadcasts/files_section', locals: { broadcast: @broadcast, files: @files } %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,4 +10,10 @@
|
||||
<%= 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.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 %>
|
||||
|
||||
@@ -16,11 +16,10 @@
|
||||
<%= contract_template.guardian_clause %>
|
||||
<% end %>
|
||||
|
||||
<%# if releasable.model_name.in? %w(MedicalRelease MiscRelease AppearanceRelease) %>
|
||||
<% if releasable.respond_to?(:question_1_answer) %>
|
||||
<div class="page">
|
||||
<%= render "contracts/questionnaire", releasable: releasable, contract_template: contract_template, preview: preview %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="page">
|
||||
@@ -47,14 +46,13 @@
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
|
||||
<% if releasable.respond_to?(:approved?) && releasable.approved? %>
|
||||
<% if releasable.try(:approved?) %>
|
||||
<div class="page">
|
||||
<%= render "contracts/for_office_use_only", releasable: releasable, preview: preview %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if releasable.class == AcquiredMediaRelease %>
|
||||
<% if releasable.respond_to?(:image_files) %>
|
||||
<div class="page">
|
||||
<%= render "contracts/files", release: releasable, preview: preview %>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="<%= I18n.locale %>">
|
||||
<head>
|
||||
<title>MESuite.ai App</title>
|
||||
<title>ME Suite</title>
|
||||
<%= csrf_meta_tags %>
|
||||
<%= csp_meta_tag %>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="<%= I18n.locale %>">
|
||||
<head>
|
||||
<title>MESuite.ai App</title>
|
||||
<title>ME Suite</title>
|
||||
<%= csrf_meta_tags %>
|
||||
<%= csp_meta_tag %>
|
||||
|
||||
|
||||
@@ -57,8 +57,8 @@
|
||||
|
||||
<hr>
|
||||
|
||||
<%= field_set_tag content_tag(:span, t(".photos.heading"), class: "h6 text-muted text-uppercase") do %>
|
||||
<%= render "shared/photos_dropzone_fields", form: form, release: material_release %>
|
||||
<%= field_set_tag content_tag(:span, t(".files.heading"), class: "h6 text-muted text-uppercase") do %>
|
||||
<%= render "shared/releasable_files_dropzone", form: form, releasable: material_release %>
|
||||
|
||||
<div class="<%= class_string("collapse" => !material_release.minor?) %>" data-ujs-target="guardian-fields">
|
||||
<br>
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
<% end %>
|
||||
</td>
|
||||
<td>
|
||||
<% if material_release.photo.attached? %>
|
||||
<%= image_tag medium_variant(material_release.photo), class: "img-fluid" %>
|
||||
<% if material_release.files.any? %>
|
||||
<%= material_release.files.size %>
|
||||
<% else %>
|
||||
<%= fa_icon("warning", text: t(".no_photos"), class: "text-danger") %>
|
||||
<%= fa_icon("warning", text: t(".no_media"), class: "text-danger") %>
|
||||
<% end %>
|
||||
</td>
|
||||
<td>
|
||||
@@ -41,8 +41,8 @@
|
||||
<% 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 %>
|
||||
<% end %>
|
||||
<% if policy(material_release).edit_photos? %>
|
||||
<%= link_to fa_icon("picture-o fw", text: "Photos"), [:edit, material_release, :photos], class: "dropdown-item" %>
|
||||
<% if policy(material_release).edit_files? %>
|
||||
<%= link_to fa_icon("file-o fw", text: "Add Media"), [:edit, material_release, :files], class: "dropdown-item" %>
|
||||
<% end %>
|
||||
<% 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" %>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<tr>
|
||||
<th data-behavior="all-selectable"><%= check_box_tag "material_release_ids[]", false, false %></th>
|
||||
<th><%= t '.table_headers.approved'%></th>
|
||||
<th></th>
|
||||
<th><%= t(".table_headers.files_count") %></th>
|
||||
<th><%= MaterialRelease.human_attribute_name(:name) %></th>
|
||||
<th><%= t(".table_headers.owner_info") %>
|
||||
<th><%= t(".table_headers.notes") %></th>
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
<%= @user.role_for(Current.account).to_s.titleize %>
|
||||
<% end %>
|
||||
</p>
|
||||
<%= link_to 'Auth to Microsoft', '/auth/azure_ad', method: :post, class: "btn btn-primary" %>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
|
||||
@@ -45,8 +45,8 @@
|
||||
<%= render "shared/address_fields", form: form, subject: "person", required: true %>
|
||||
<% end %>
|
||||
|
||||
<%= card_field_set_tag t(".photo.heading") do %>
|
||||
<%= render "shared/photos_dropzone_fields", form: form, release: @material_release %>
|
||||
<%= card_field_set_tag t(".files.heading") do %>
|
||||
<%= render "shared/releasable_files_dropzone", form: form, releasable: @material_release %>
|
||||
<% end %>
|
||||
|
||||
<hr>
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
require 'azure_ad'
|
||||
|
||||
Rails.application.config.middleware.use OmniAuth::Builder do
|
||||
provider :azure_ad,
|
||||
client_id: ENV['AZURE_CLIENT_ID'],
|
||||
client_secret: ENV['AZURE_CLIENT_SECRET'],
|
||||
redirect_uri: ENV['AZURE_REDIRECT_URI'],
|
||||
client_options: {
|
||||
token_url: "#{ENV['AZURE_TENANT_ID']}/oauth2/v2.0/token",
|
||||
authorize_url: "#{ENV['AZURE_TENANT_ID']}/oauth2/v2.0/authorize"
|
||||
},
|
||||
scope: ENV['AZURE_SCOPES']
|
||||
end
|
||||
1
config/initializers/session_cookie.rb
Normal file
1
config/initializers/session_cookie.rb
Normal file
@@ -0,0 +1 @@
|
||||
Rails.application.config.session_store :cookie_store, key: '_easy_release_session', expire_after: 1.month
|
||||
@@ -224,6 +224,9 @@ en:
|
||||
manage: Manage
|
||||
empty_bookmarks:
|
||||
empty: Notes will appear here
|
||||
broadcast_recordings:
|
||||
edit:
|
||||
heading: Edit Broadcast Recording
|
||||
broadcasts:
|
||||
broadcast:
|
||||
actions:
|
||||
@@ -275,9 +278,6 @@ en:
|
||||
stream_multiple_cameras: Stream multiple cameras at one time
|
||||
update:
|
||||
reset_notice: The Share URL has been reset, and the previous URL will no longer work. Please click "Copy URL" and share it again with those who you want to have access to this live stream
|
||||
form:
|
||||
labels:
|
||||
conference_option: Conference Option
|
||||
bulk_taggings:
|
||||
new_bulk_tag_modal:
|
||||
submit: Add
|
||||
@@ -904,6 +904,8 @@ en:
|
||||
form:
|
||||
contract_and_rights:
|
||||
heading: 3 of 4 Contract & Exploitable Rights
|
||||
files:
|
||||
heading: Files
|
||||
guardian_2_info:
|
||||
heading: Second Guardian Information (if company requires)
|
||||
guardian_info:
|
||||
@@ -911,7 +913,7 @@ en:
|
||||
material_details:
|
||||
heading: 1 of 3 Material Details
|
||||
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:
|
||||
heading: Second Guardian Photo
|
||||
guardian_photo:
|
||||
@@ -926,6 +928,7 @@ en:
|
||||
empty: Material Releases will appear here
|
||||
table_headers:
|
||||
approved: Approved
|
||||
files_count: No. of Files
|
||||
name: Name
|
||||
notes: Notes
|
||||
owner_info: Owner Info
|
||||
@@ -937,6 +940,7 @@ en:
|
||||
review: Review
|
||||
messages:
|
||||
approved_tooltip: Approved by %{user} on %{timestamp}
|
||||
no_media: No Media
|
||||
no_photos: Needs Photo
|
||||
new:
|
||||
heading: Import Material Release (Products / Logos)
|
||||
@@ -1255,6 +1259,8 @@ en:
|
||||
cancel: Cancel
|
||||
contact_info:
|
||||
heading: Licensor/Owner Contact Information
|
||||
files:
|
||||
heading: Files
|
||||
guardian_2_info:
|
||||
heading: Second Guardian Information (if company requires)
|
||||
guardian_2_photo:
|
||||
@@ -1645,9 +1651,3 @@ en:
|
||||
edit: Edit
|
||||
report: Report
|
||||
generating: Generating...
|
||||
conference_meetings:
|
||||
show:
|
||||
alerts:
|
||||
not_authenticated: You are not authenticated via Microsoft, please authenticate and try again
|
||||
failed_to_join: Failed to join conference
|
||||
unknown_conference_option: Unknown conference option
|
||||
|
||||
@@ -131,9 +131,6 @@ es:
|
||||
stream_multiple_cameras: Stream multiple cameras at one time
|
||||
update:
|
||||
reset_notice: The Share URL has been reset, and the previous URL will no longer work. Please click "Copy URL" and share it again with those who you want to have access to this live stream
|
||||
form:
|
||||
labels:
|
||||
conference_option: Conference Option (ES)
|
||||
contract_templates:
|
||||
blank_contracts:
|
||||
create:
|
||||
@@ -708,9 +705,3 @@ es:
|
||||
production_elements_logs: Production Elements Logs, and more (ES)
|
||||
reduces_labor_cost: Reduces labor costs (ES)
|
||||
simplifies_cue_sheets: Simplifies Music Cue Sheets, Graphic Cue Sheets (ES)
|
||||
conference_meetings:
|
||||
show:
|
||||
alerts:
|
||||
not_authenticated: You are not authenticated via Microsoft, please authenticate and try again (ES)
|
||||
failed_to_join: Failed to join conference (ES)
|
||||
unknown_conference_option: Unknown conference option (ES)
|
||||
|
||||
@@ -4,8 +4,6 @@ require 'sidekiq/web'
|
||||
Rails.application.routes.draw do
|
||||
AVAILABLE_LOCALES_REGEX = /#{I18n.available_locales.join("|")}/.freeze
|
||||
|
||||
get 'auth/azure_ad/callback', to: 'callbacks#create'
|
||||
|
||||
concern :confirmable do
|
||||
resources :video_release_confirmations, only: [:new, :create, :destroy]
|
||||
end
|
||||
@@ -57,7 +55,7 @@ Rails.application.routes.draw do
|
||||
resources :appearance_releases, except: [:show], concerns: [:contractable, :notable]
|
||||
resources :appearance_release_imports, only: [:create]
|
||||
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 :talent_releases, except: [:show], concerns: [:contractable, :notable, :photoable]
|
||||
resources :medical_releases, except: [:show], concerns: [:contractable, :notable, :photoable]
|
||||
@@ -102,8 +100,10 @@ Rails.application.routes.draw do
|
||||
member do
|
||||
delete :destroy_file
|
||||
end
|
||||
resource :conference_meeting, only: [:show]
|
||||
resources :broadcast_recordings, only: :destroy
|
||||
resource :zoom_meeting, only: [:show]
|
||||
resources :broadcast_recordings, only: [:destroy, :edit, :update] do
|
||||
resources :broadcast_recording_starrings, only: :create
|
||||
end
|
||||
end
|
||||
resources :directories, except: [:index] do
|
||||
member do
|
||||
|
||||
@@ -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
|
||||
@@ -1,8 +0,0 @@
|
||||
class AddMicrosoftInfoToUsers < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
add_column :users, :microsoft_user_id, :string
|
||||
add_column :users, :microsoft_access_token, :string
|
||||
add_column :users, :microsoft_refresh_token, :string
|
||||
add_column :users, :microsoft_token_expires_at, :integer
|
||||
end
|
||||
end
|
||||
@@ -1,6 +0,0 @@
|
||||
class AddConferenceDetailsToBroadcasts < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
add_column :broadcasts, :conference_option, :string
|
||||
add_column :broadcasts, :conference_join_url, :string
|
||||
end
|
||||
end
|
||||
@@ -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
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddStarToBroadcastRecordings < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
add_column :broadcast_recordings, :starred, :boolean, default: false
|
||||
end
|
||||
end
|
||||
@@ -541,7 +541,10 @@ CREATE TABLE public.broadcast_recordings (
|
||||
created_at timestamp(6) without time zone NOT NULL,
|
||||
updated_at timestamp(6) without time zone NOT NULL,
|
||||
duration double precision,
|
||||
hidden boolean DEFAULT false
|
||||
hidden boolean DEFAULT false,
|
||||
starred boolean DEFAULT false,
|
||||
name character varying,
|
||||
description text
|
||||
);
|
||||
|
||||
|
||||
@@ -586,9 +589,7 @@ CREATE TABLE public.broadcasts (
|
||||
stream_key_override character varying,
|
||||
director_mode_video_embed text,
|
||||
simulcast_uid character varying,
|
||||
video_conference_url_override character varying,
|
||||
conference_option character varying,
|
||||
conference_join_url character varying
|
||||
video_conference_url_override character varying
|
||||
);
|
||||
|
||||
|
||||
@@ -1491,7 +1492,6 @@ CREATE TABLE public.settings (
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.settings_id_seq
|
||||
AS integer
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
@@ -1527,7 +1527,6 @@ CREATE TABLE public.taggings (
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.taggings_id_seq
|
||||
AS integer
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
@@ -1558,7 +1557,6 @@ CREATE TABLE public.tags (
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.tags_id_seq
|
||||
AS integer
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
@@ -1806,11 +1804,7 @@ CREATE TABLE public.users (
|
||||
remember_created_at timestamp without time zone,
|
||||
first_name character varying,
|
||||
last_name character varying,
|
||||
time_zone character varying DEFAULT 'UTC'::character varying NOT NULL,
|
||||
microsoft_user_id character varying,
|
||||
microsoft_access_token character varying,
|
||||
microsoft_refresh_token character varying,
|
||||
microsoft_token_expires_at integer
|
||||
time_zone character varying DEFAULT 'UTC'::character varying NOT NULL
|
||||
);
|
||||
|
||||
|
||||
@@ -4032,7 +4026,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||
('20200811102720'),
|
||||
('20200812060406'),
|
||||
('20200819070738'),
|
||||
('20200820081251'),
|
||||
('20200820081524');
|
||||
('20200820082501'),
|
||||
('20200824171649');
|
||||
|
||||
|
||||
|
||||
124
lib/azure_ad.rb
124
lib/azure_ad.rb
@@ -1,124 +0,0 @@
|
||||
require 'omniauth-oauth2'
|
||||
|
||||
# This file is from omniauth-microsoft_graph lib (not installed)
|
||||
# It is modified to make auth work
|
||||
|
||||
module OmniAuth
|
||||
module Strategies
|
||||
class AzureAd < OmniAuth::Strategies::OAuth2
|
||||
BASE_SCOPE_URL = 'https://graph.microsoft.com/'
|
||||
BASE_SCOPES = %w[offline_access openid email profile].freeze
|
||||
DEFAULT_SCOPE = 'offline_access openid email profile User.Read'.freeze
|
||||
|
||||
option :name, :azure_ad
|
||||
|
||||
option :client_options,
|
||||
site: 'https://login.microsoftonline.com/'
|
||||
|
||||
option :authorize_options, %i[state callback_url scope response_mode]
|
||||
|
||||
option :token_params, {}
|
||||
|
||||
option :scope, DEFAULT_SCOPE
|
||||
option :authorized_client_ids, []
|
||||
|
||||
uid { raw_info["id"] }
|
||||
|
||||
info do
|
||||
{
|
||||
# 'email' => raw_info["mail"],
|
||||
# 'first_name' => raw_info["givenName"],
|
||||
# 'last_name' => raw_info["surname"],
|
||||
# 'name' => [raw_info["givenName"], raw_info["surname"]].join(' '),
|
||||
# 'nickname' => raw_info["displayName"],
|
||||
}
|
||||
end
|
||||
|
||||
extra do
|
||||
{
|
||||
# 'raw_info' => raw_info,
|
||||
# 'params' => access_token.params,
|
||||
# 'aud' => options.client_id
|
||||
}
|
||||
end
|
||||
|
||||
def authorize_params
|
||||
super.tap do |params|
|
||||
options[:authorize_options].each do |k|
|
||||
params[k] = request.params[k.to_s] unless [nil, ''].include?(request.params[k.to_s])
|
||||
end
|
||||
|
||||
params[:scope] = get_scope(params)
|
||||
|
||||
session['omniauth.state'] = params[:state] if params[:state]
|
||||
end
|
||||
end
|
||||
|
||||
def raw_info
|
||||
@raw_info ||= access_token.get('https://graph.microsoft.com/v1.0/me').parsed
|
||||
end
|
||||
|
||||
def callback_url
|
||||
options[:callback_url] || full_host + script_name + callback_path
|
||||
end
|
||||
|
||||
def custom_build_access_token
|
||||
token_response = get_access_token(request)
|
||||
session[:microsoft_graph_api_token] = token_response.token
|
||||
token_response
|
||||
end
|
||||
|
||||
alias build_access_token custom_build_access_token
|
||||
|
||||
private
|
||||
|
||||
def get_access_token(request)
|
||||
verifier = request.params['code']
|
||||
redirect_uri = request.params['redirect_uri'] || request.params['callback_url']
|
||||
if verifier && request.xhr?
|
||||
client_get_token(verifier, redirect_uri || '/auth/azure_ad/callback')
|
||||
elsif verifier
|
||||
client_get_token(verifier, redirect_uri || callback_url)
|
||||
elsif verify_token(request.params['access_token'])
|
||||
::OAuth2::AccessToken.from_hash(client, request.params.dup)
|
||||
elsif request.content_type =~ /json/i
|
||||
begin
|
||||
body = JSON.parse(request.body.read)
|
||||
request.body.rewind # rewind request body for downstream middlewares
|
||||
verifier = body && body['code']
|
||||
client_get_token(verifier, '/auth/azure_ad/callback') if verifier
|
||||
rescue JSON::ParserError => e
|
||||
warn "[omniauth google-oauth2] JSON parse error=#{e}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def client_get_token(verifier, redirect_uri)
|
||||
client.auth_code.get_token(verifier, get_token_options(redirect_uri), get_token_params)
|
||||
end
|
||||
|
||||
def get_token_params
|
||||
deep_symbolize(options.auth_token_params || {})
|
||||
end
|
||||
|
||||
def get_token_options(redirect_uri = '')
|
||||
{ redirect_uri: redirect_uri }.merge(token_params.to_hash(symbolize_keys: true))
|
||||
end
|
||||
|
||||
def get_scope(params)
|
||||
raw_scope = params[:scope] || DEFAULT_SCOPE
|
||||
scope_list = raw_scope.split(' ').map { |item| item.split(',') }.flatten
|
||||
scope_list.map! { |s| s =~ %r{^https?://} || BASE_SCOPES.include?(s) ? s : "#{BASE_SCOPE_URL}#{s}" }
|
||||
scope_list.join(' ')
|
||||
end
|
||||
|
||||
def verify_token(access_token)
|
||||
return false unless access_token
|
||||
# access_token.get('https://graph.microsoft.com/v1.0/me').parsed
|
||||
raw_response = client.request(:get, 'https://graph.microsoft.com/v1.0/me',
|
||||
params: { access_token: access_token }).parsed
|
||||
(raw_response['aud'] == options.client_id) || options.authorized_client_ids.include?(raw_response['aud'])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,107 +0,0 @@
|
||||
require 'httparty'
|
||||
|
||||
class MicrosoftGraph
|
||||
BASE_URL = 'https://graph.microsoft.com/v1.0'.freeze
|
||||
|
||||
def initialize(current_user, client_id, client_secret, tenant_id, scopes)
|
||||
@current_user = current_user
|
||||
@uid = current_user.microsoft_user_id
|
||||
@token = current_user.microsoft_access_token
|
||||
@refresh_token = current_user.microsoft_refresh_token
|
||||
@token_expires_at = current_user.microsoft_token_expires_at
|
||||
|
||||
@client_id = client_id
|
||||
@client_secret = client_secret
|
||||
@tenant_id = tenant_id
|
||||
@scopes = scopes
|
||||
end
|
||||
|
||||
def create_teams_meeting(subject)
|
||||
if @refresh_token.nil? || @token_expires_at.nil?
|
||||
raise ActionController::InvalidAuthenticityToken, 'Missing refresh token / token expiration'
|
||||
return
|
||||
end
|
||||
|
||||
# Obtain new token if token is expired or will expire in less than 5 minutes
|
||||
if 5.minutes.from_now.to_i > @token_expires_at.seconds
|
||||
refresh_access_token
|
||||
end
|
||||
|
||||
if @token.nil?
|
||||
raise ActionController::InvalidAuthenticityToken, 'Missing access token'
|
||||
return
|
||||
end
|
||||
|
||||
response = HTTParty.post(
|
||||
"#{BASE_URL}/me/onlineMeetings",
|
||||
body: {
|
||||
subject: subject,
|
||||
participants: {
|
||||
organizer: {
|
||||
identity: {
|
||||
user: {
|
||||
id: @uid
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.to_json,
|
||||
headers: {
|
||||
Authorization: "Bearer #{@token}",
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
)
|
||||
|
||||
raise StandardError, 'Authenticated user does not have a permission to create Teams Online Meeting' if response.code == 403
|
||||
|
||||
if response.code != 201
|
||||
Rails.logger.error('[Microsoft Graph Error]')
|
||||
Rails.logger.error(response.inspect)
|
||||
raise StandardError, "Failed to create teams meeting [#{response.code}]"
|
||||
else
|
||||
JSON.parse(response.body)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def refresh_token_url
|
||||
"https://login.microsoftonline.com/#{@tenant_id}/oauth2/v2.0/token"
|
||||
end
|
||||
|
||||
def refresh_access_token
|
||||
response = HTTParty.post(refresh_token_url,
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
body: {
|
||||
client_id: @client_id,
|
||||
client_secret: @client_secret,
|
||||
refresh_token: @refresh_token,
|
||||
grant_type: 'refresh_token',
|
||||
scope: @scopes
|
||||
})
|
||||
|
||||
if response.code != 200
|
||||
Rails.logger.error '[Microsoft Graph Error] Failed to obtain new access token using refresh token'
|
||||
Rails.logger.error(response.inspect)
|
||||
raise StandardError, 'Failed to obtain new access token'
|
||||
end
|
||||
|
||||
parsed_response = JSON.parse(response.body)
|
||||
|
||||
new_access_token = parsed_response['access_token']
|
||||
new_refresh_token = parsed_response['refresh_token']
|
||||
token_expires_in = parsed_response['expires_in'] # For how long access token is valid (in seconds)
|
||||
token_new_expiration_time = Time.now.to_i + token_expires_in
|
||||
|
||||
@current_user.microsoft_access_token = new_access_token
|
||||
@current_user.microsoft_refresh_token = new_refresh_token
|
||||
@current_user.microsoft_token_expires_at = token_new_expiration_time
|
||||
@current_user.save!
|
||||
|
||||
@token = new_access_token
|
||||
@refresh_token = new_refresh_token
|
||||
@token_expires_at = token_new_expiration_time
|
||||
end
|
||||
end
|
||||
@@ -17,6 +17,7 @@ RSpec.describe BroadcastsChannel, type: :channel do
|
||||
it "broadcasts to the channel" do
|
||||
status_content = ApplicationController.render partial: "broadcasts/broadcast_status", 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 {
|
||||
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,
|
||||
status_content: status_content,
|
||||
video_content: video_content,
|
||||
live_take_content: live_take,
|
||||
streamer_status: broadcast.streamer_status
|
||||
})
|
||||
end
|
||||
|
||||
@@ -30,6 +30,16 @@ RSpec.describe Api::AcquiredMediaReleasesController, type: :controller do
|
||||
|
||||
expect(response).to be_successful
|
||||
end
|
||||
|
||||
it 'contains files attachment data' do
|
||||
tested_release = create(:acquired_media_release, name: 'ct1', project_id: project.id)
|
||||
|
||||
sign_in_to_api(current_user)
|
||||
get :show, params: { id: tested_release.id }
|
||||
|
||||
expect(response.body).to match /file_infos/
|
||||
expect(response.body).to match /files/
|
||||
end
|
||||
end
|
||||
|
||||
describe '#create' do
|
||||
|
||||
@@ -27,10 +27,17 @@ RSpec.describe ApprovalsController, type: :controller do
|
||||
|
||||
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(MedicalRelease.last.approved?).to eq true
|
||||
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
|
||||
|
||||
@@ -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
|
||||
@@ -9,9 +9,10 @@ RSpec.describe BroadcastRecordingsController, type: :controller do
|
||||
|
||||
before do
|
||||
sign_in user
|
||||
stub_mux_live_stream
|
||||
end
|
||||
|
||||
describe "#destroy" do
|
||||
describe "#edit" do
|
||||
let(:broadcast) { create(:broadcast, project: project, name: "New Broadcast") }
|
||||
let(:recording) { create(:broadcast_recording, broadcast: broadcast) }
|
||||
|
||||
@@ -19,6 +20,55 @@ RSpec.describe BroadcastRecordingsController, type: :controller do
|
||||
stub_mux_live_stream
|
||||
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
|
||||
expect(recording.hidden).to be false
|
||||
|
||||
|
||||
@@ -150,31 +150,16 @@ RSpec.describe BroadcastsController, type: :controller do
|
||||
expect(assigns(:broadcast)).to eq(broadcast)
|
||||
end
|
||||
|
||||
it "renders readonly share url" do
|
||||
get :show, params: { project_id: project.id, id: broadcast.id }
|
||||
|
||||
expect(response.body).to have_button "Copy URL"
|
||||
expect(response.body).to have_xpath "//input[@readonly][@value='#{broadcast_url(broadcast.token)}']"
|
||||
end
|
||||
|
||||
it "displays zoom meeting button for zoom conference option" do
|
||||
it "displays zoom meeting button" do
|
||||
get :show, params: { project_id: project.id, id: broadcast.id }
|
||||
|
||||
expect(response.body).to have_link("Video Conference", href: project_broadcast_conference_meeting_url(project, broadcast))
|
||||
end
|
||||
|
||||
it "displays microsoft teams meeting button for MS Teams conference option" do
|
||||
ms_teams_broadcast = create(:broadcast, :ms_teams_conference, project: project )
|
||||
get :show, params: { project_id: project.id, id: ms_teams_broadcast.id }
|
||||
|
||||
expect(response.body).to have_content 'MS Teams'
|
||||
expect(response.body).to have_link 'Video Conference', href: project_broadcast_conference_meeting_url(project, ms_teams_broadcast)
|
||||
expect(response.body).to have_link("Video Conference", href: project_broadcast_zoom_meeting_url(project, broadcast))
|
||||
end
|
||||
|
||||
it "assigns required variables" do
|
||||
get :show, params: { project_id: project.id, id: broadcast.id }
|
||||
|
||||
expect(assigns(:conference_url)).to eq project_broadcast_conference_meeting_url(project, broadcast)
|
||||
expect(assigns(:conference_url)).to eq project_broadcast_zoom_meeting_url(project, broadcast)
|
||||
expect(assigns(:broadcast)).to eq broadcast
|
||||
end
|
||||
|
||||
@@ -182,7 +167,7 @@ RSpec.describe BroadcastsController, type: :controller do
|
||||
it "renders the view dropdown with just the current broadcast" do
|
||||
get :show, params: { project_id: project, id: broadcast }
|
||||
|
||||
expect(response.body).to have_content "Switch View"
|
||||
expect(response.body).to have_content broadcast.name
|
||||
expect(response.body).to have_selector(".dropdown-menu .dropdown-item.active", text: "Another Broadcast")
|
||||
end
|
||||
end
|
||||
@@ -193,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] }
|
||||
|
||||
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 a.dropdown-item", text: "Some Other Broadcast")
|
||||
end
|
||||
end
|
||||
|
||||
context "when there are no recordings for the current broadcast" do
|
||||
it "renders the view dropdown with a message" do
|
||||
get :show, params: { project_id: project, id: broadcast }
|
||||
|
||||
expect(response.body).to have_content "Switch View"
|
||||
expect(response.body).to have_selector(".dropdown-menu .dropdown-item", text: "Recordings will appear here")
|
||||
end
|
||||
end
|
||||
|
||||
context "when there are recordings available" do
|
||||
it "renders the view dropdown with the recordings" do
|
||||
recording = create(:broadcast_recording, broadcast: broadcast)
|
||||
|
||||
get :show, params: { project_id: project, id: broadcast }
|
||||
|
||||
expect(response.body).to have_content "Switch View"
|
||||
expect(response.body).to have_selector(".dropdown-menu a.dropdown-item", text: recording.download_file_name)
|
||||
end
|
||||
end
|
||||
|
||||
context "when virtual director video embed is available" do
|
||||
let(:broadcast) { create(:broadcast, project: project, name: "Another Broadcast",
|
||||
director_mode_video_embed: "<iframe>video player</iframe>") }
|
||||
@@ -226,9 +191,8 @@ RSpec.describe BroadcastsController, type: :controller do
|
||||
it "renders the view dropdown with a director mode enable option" 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 h5.dropdown-header", text: "Director Mode")
|
||||
expect(response.body).to have_selector(".dropdown-menu a.dropdown-item", text: "Enable Director Mode")
|
||||
expect(response.body).to have_content broadcast.name
|
||||
expect(response.body).to have_selector(".custom-control-label", text: "Director Mode")
|
||||
end
|
||||
|
||||
context "when director mode is enabled" do
|
||||
@@ -241,9 +205,8 @@ RSpec.describe BroadcastsController, type: :controller do
|
||||
it "renders the view dropdown with a director mode disable option" do
|
||||
get :show, params: { project_id: project, id: broadcast, director_mode: true }
|
||||
|
||||
expect(response.body).to have_content "Switch View"
|
||||
expect(response.body).to have_selector(".dropdown-menu h5.dropdown-header", text: "Director Mode")
|
||||
expect(response.body).to have_selector(".dropdown-menu a.dropdown-item", text: "Disable Director Mode")
|
||||
expect(response.body).to have_content broadcast.name
|
||||
expect(response.body).to have_selector(".custom-control-label", text: "Director Mode")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ConferenceMeetingsController, type: :controller do
|
||||
let(:user) { create(:user) }
|
||||
let(:account) { user.primary_account }
|
||||
let(:project) { create(:project, account: user.primary_account) }
|
||||
let(:broadcast) { create(:broadcast, name: "Broadcast", project: project) }
|
||||
let(:ms_teams_broadcast) { create(:broadcast, :ms_teams_conference, project: project) }
|
||||
let(:unknown_option_broadcast) { create(:broadcast, project: project, conference_option: 'google') }
|
||||
|
||||
let(:meeting_start_url) { "http://meeting_start_url" }
|
||||
let(:meeting_hash) { HashWithIndifferentAccess.new(start_url: meeting_start_url) }
|
||||
let(:user_create_response) { {"id" => "new_host_id"} }
|
||||
let(:roles_assign_response) { {"ids" => ["new_host_id"]} }
|
||||
let(:roles_list_response) { {"roles" => [{"name" => "directme-host"}]} }
|
||||
|
||||
|
||||
before :each do
|
||||
allow_any_instance_of(ZoomGateway).to receive(:find_meeting).and_return(meeting_hash)
|
||||
allow_any_instance_of(ZoomGateway).to receive(:create_meeting).and_return("meeting_id")
|
||||
allow_any_instance_of(ZoomGateway).to receive(:create_host).and_return("host_id")
|
||||
stub_mux_live_stream
|
||||
end
|
||||
|
||||
describe "#show" do
|
||||
before { sign_in user }
|
||||
|
||||
it "redirects to meeting start url with Zoom conference option" do
|
||||
get :show, params: { project_id: project.id, broadcast_id: broadcast.id }
|
||||
expect(response).to redirect_to(meeting_start_url)
|
||||
end
|
||||
|
||||
it "redirects to the broadcast show page with alert if user is not authenticated via microsoft and tries to create MS Teams meeting" do
|
||||
get :show, params: { project_id: project.id, broadcast_id: ms_teams_broadcast.id }
|
||||
expect(response).to redirect_to project_broadcast_path(project, ms_teams_broadcast)
|
||||
expect(flash.alert).to eq not_authenticated_alert
|
||||
end
|
||||
|
||||
it "redirects to the broadcast show page with alert if user is authenticated via microsoft and tries to create MS Teams meeting but Graph API fails to create meeting" do
|
||||
allow_any_instance_of(MicrosoftGraph).to receive(:create_teams_meeting).and_return(nil)
|
||||
get :show, params: { project_id: project.id, broadcast_id: ms_teams_broadcast.id }
|
||||
expect(response).to redirect_to project_broadcast_path(project, ms_teams_broadcast)
|
||||
expect(flash.alert).to eq failed_to_join_alert
|
||||
end
|
||||
|
||||
it "redirects to the broadcast show page with alert if conference option is not reckognized" do
|
||||
get :show, params: { project_id: project.id, broadcast_id: unknown_option_broadcast.id }
|
||||
expect(response).to redirect_to project_broadcast_path(project, unknown_option_broadcast)
|
||||
expect(flash.alert).to eq unknown_conference_option_alert
|
||||
end
|
||||
|
||||
it "redirects to meeting start url with MS Teams conference option" do
|
||||
new_ms_teams_meeting = JSON.parse({ joinUrl: meeting_start_url }.to_json)
|
||||
|
||||
allow_any_instance_of(MicrosoftGraph).to receive(:create_teams_meeting).and_return(new_ms_teams_meeting)
|
||||
|
||||
get :show, params: { project_id: project.id, broadcast_id: ms_teams_broadcast.id }
|
||||
expect(response).to redirect_to(meeting_start_url)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def not_authenticated_alert
|
||||
t 'conference_meetings.show.alerts.not_authenticated'
|
||||
end
|
||||
|
||||
def failed_to_join_alert
|
||||
t 'conference_meetings.show.alerts.failed_to_join'
|
||||
end
|
||||
|
||||
def unknown_conference_option_alert
|
||||
t 'conference_meetings.show.alerts.unknown_conference_option'
|
||||
end
|
||||
end
|
||||
@@ -68,13 +68,7 @@ RSpec.describe PhotosController, type: :controller do
|
||||
|
||||
it_behaves_like "a photoable releases controller"
|
||||
end
|
||||
|
||||
context "for material releases" do
|
||||
subject { create(:material_release, project: project) }
|
||||
|
||||
it_behaves_like "a photoable releases controller"
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def release_params
|
||||
|
||||
@@ -45,7 +45,7 @@ RSpec.describe Public::BroadcastsController, type: :controller do
|
||||
it "renders the view dropdown with just the current broadcast" do
|
||||
get :show, params: { token: broadcast.token }
|
||||
|
||||
expect(response.body).to have_content "Switch View"
|
||||
expect(response.body).to have_content broadcast.name
|
||||
expect(response.body).to have_selector(".dropdown-menu .dropdown-item.active", text: "Broadcast")
|
||||
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] }
|
||||
|
||||
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 a.dropdown-item", text: "Some Other Broadcast")
|
||||
end
|
||||
@@ -66,8 +66,7 @@ RSpec.describe Public::BroadcastsController, type: :controller do
|
||||
it "renders the view dropdown with a message" do
|
||||
get :show, params: { token: broadcast.token }
|
||||
|
||||
expect(response.body).to have_content "Switch View"
|
||||
expect(response.body).to have_selector(".dropdown-menu .dropdown-item", text: "Recordings will appear here")
|
||||
expect(response.body).to have_content broadcast.name
|
||||
end
|
||||
end
|
||||
|
||||
@@ -77,8 +76,7 @@ RSpec.describe Public::BroadcastsController, type: :controller do
|
||||
|
||||
get :show, params: { token: broadcast.token }
|
||||
|
||||
expect(response.body).to have_content "Switch View"
|
||||
expect(response.body).to have_selector(".dropdown-menu a.dropdown-item", text: recording.download_file_name)
|
||||
expect(response.body).to have_content broadcast.name
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -10,10 +10,10 @@ describe Public::MaterialReleasesController do
|
||||
it "allows photos param" do
|
||||
contract_template = create(:contract_template, project: project)
|
||||
|
||||
post :create, params: { account_id: user.primary_account.to_param, project_id: project, contract_template_id: contract_template, 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(MaterialRelease.last.photos.attached?).to eq true
|
||||
expect(MaterialRelease.last.files.attached?).to eq true
|
||||
end
|
||||
|
||||
it "displays validation errors" do
|
||||
@@ -63,8 +63,8 @@ describe Public::MaterialReleasesController do
|
||||
attributes_for(:material_release, :native).except(:signature).merge(signature_param)
|
||||
end
|
||||
|
||||
def material_release_params_with_photos
|
||||
attributes_for(:material_release, :native, :with_photo).except(:signature).merge(signature_param)
|
||||
def material_release_params_with_files
|
||||
attributes_for(:material_release, :native, :with_file).except(:signature).merge(signature_param)
|
||||
end
|
||||
|
||||
|
||||
|
||||
30
spec/controllers/zoom_meetings_controller_spec.rb
Normal file
30
spec/controllers/zoom_meetings_controller_spec.rb
Normal file
@@ -0,0 +1,30 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ZoomMeetingsController, type: :controller do
|
||||
let(:user) { create(:user) }
|
||||
let(:account) { user.primary_account }
|
||||
let(:project) { create(:project, account: user.primary_account) }
|
||||
let(:broadcast) { create(:broadcast, name: "Broadcast", project: project) }
|
||||
|
||||
let(:meeting_start_url) { "http://meeting_start_url" }
|
||||
let(:meeting_hash) { HashWithIndifferentAccess.new(start_url: meeting_start_url) }
|
||||
let(:user_create_response) { {"id" => "new_host_id"} }
|
||||
let(:roles_assign_response) { {"ids" => ["new_host_id"]} }
|
||||
let(:roles_list_response) { {"roles" => [{"name" => "directme-host"}]} }
|
||||
|
||||
before :each do
|
||||
allow_any_instance_of(ZoomGateway).to receive(:find_meeting).and_return(meeting_hash)
|
||||
allow_any_instance_of(ZoomGateway).to receive(:create_meeting).and_return("meeting_id")
|
||||
allow_any_instance_of(ZoomGateway).to receive(:create_host).and_return("host_id")
|
||||
stub_mux_live_stream
|
||||
end
|
||||
|
||||
describe "#show" do
|
||||
before { sign_in user }
|
||||
|
||||
it "redirects to meeting start url" do
|
||||
get :show, params: { project_id: project.id, broadcast_id: broadcast.id }
|
||||
expect(response).to redirect_to(meeting_start_url)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -5,5 +5,9 @@ FactoryBot.define do
|
||||
asset_uid "asset_uid"
|
||||
asset_playback_uid "asset_playback_uid"
|
||||
hidden { false }
|
||||
|
||||
trait :with_random_asset_uid do
|
||||
sequence(:asset_uid, 'a')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,16 +2,11 @@ FactoryBot.define do
|
||||
factory :broadcast do
|
||||
association :project
|
||||
name "My Live Stream"
|
||||
conference_option "zoom"
|
||||
|
||||
transient do
|
||||
skip_create_callback false
|
||||
end
|
||||
|
||||
trait :ms_teams_conference do
|
||||
conference_option "ms_teams"
|
||||
end
|
||||
|
||||
trait :with_stream do
|
||||
stream_uid "mux_stream"
|
||||
stream_key "mux_key"
|
||||
|
||||
@@ -42,6 +42,12 @@ FactoryBot.define do
|
||||
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
|
||||
contract do
|
||||
|
||||
191
spec/features/user_approving_releasables_spec.rb
Normal file
191
spec/features/user_approving_releasables_spec.rb
Normal 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
|
||||
@@ -444,104 +444,9 @@ feature "User managing acquired_media releases" do
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
context "when the user is associate" do
|
||||
@@ -703,42 +608,6 @@ feature "User managing acquired_media releases" do
|
||||
'Some signature legal language'
|
||||
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
|
||||
'acquired_media_release_minor'
|
||||
end
|
||||
|
||||
@@ -687,103 +687,9 @@ feature 'User managing appearance releases' 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(: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
|
||||
|
||||
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
|
||||
|
||||
context 'when the user is associate' do
|
||||
@@ -801,15 +707,6 @@ feature 'User managing appearance releases' do
|
||||
click_on manage_button
|
||||
expect(page).not_to have_link('Download', exact: true)
|
||||
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
|
||||
|
||||
private
|
||||
@@ -1039,42 +936,6 @@ feature 'User managing appearance releases' do
|
||||
'Some signature legal language'
|
||||
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
|
||||
t 'public.amendments.new.amendment.heading'
|
||||
end
|
||||
|
||||
@@ -25,7 +25,6 @@ feature 'User managing broadcasts' do
|
||||
|
||||
by 'filling out the form' do
|
||||
fill_in broadcast_name_field, with: 'My Broadcast'
|
||||
select_conference_option('Zoom')
|
||||
select_time_zone("New Delhi")
|
||||
end
|
||||
|
||||
@@ -57,14 +56,32 @@ feature 'User managing broadcasts' do
|
||||
visit project_broadcast_path(project, broadcast)
|
||||
|
||||
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
|
||||
expect(page).to have_content('contract.pdf')
|
||||
click_on "Files"
|
||||
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
|
||||
|
||||
click_on 'Previous Sessions'
|
||||
expect(page).to have_content(recording.download_file_name)
|
||||
scenario 'loads full broadcast asset url if available' do
|
||||
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
|
||||
|
||||
scenario 'Clicking Reset URL regenerates broadcast token' do
|
||||
@@ -74,93 +91,19 @@ feature 'User managing broadcasts' do
|
||||
visit project_broadcast_path(project, broadcast)
|
||||
|
||||
expect(page).to have_content reset_url
|
||||
expect(page).to have_xpath "//input[@readonly][@value='#{broadcast_url(old_token)}']"
|
||||
|
||||
click_link reset_url
|
||||
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
|
||||
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
|
||||
broadcast = create(:broadcast, :with_stream, :with_files, project: project)
|
||||
|
||||
visit project_broadcast_path(project, broadcast)
|
||||
|
||||
expect(page).to have_content('Live stream is waiting to begin.')
|
||||
click_on "Files"
|
||||
expect(page).to have_content add_file_button
|
||||
|
||||
click_on add_file_button
|
||||
@@ -170,7 +113,7 @@ feature 'User managing broadcasts' do
|
||||
broadcast = create(:broadcast, :with_stream, :with_files, project: project)
|
||||
|
||||
visit project_broadcast_path(project, broadcast)
|
||||
|
||||
click_on "Files"
|
||||
expect(page).to have_content delete_file_button, count: 3
|
||||
|
||||
accept_alert do
|
||||
@@ -190,9 +133,11 @@ feature 'User managing broadcasts' do
|
||||
|
||||
new_window = window_opened_by { click_link 'Multi-View' }
|
||||
within_window new_window do
|
||||
expect(page).to have_content switch_view_dropdown
|
||||
|
||||
click_on switch_view_dropdown
|
||||
click_on "Files"
|
||||
expect(page).to have_content broadcast_one.name
|
||||
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 2')
|
||||
|
||||
@@ -206,24 +151,6 @@ feature 'User managing broadcasts' do
|
||||
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
|
||||
let(:current_user) { create(:user, :associate) }
|
||||
|
||||
@@ -241,17 +168,6 @@ feature 'User managing broadcasts' do
|
||||
|
||||
expect(page).to have_content delete_file_button, count: 0
|
||||
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
|
||||
|
||||
context 'When the user is account manager' do
|
||||
@@ -268,7 +184,7 @@ feature 'User managing broadcasts' do
|
||||
broadcast = create(:broadcast, :with_stream, :with_files, project: project)
|
||||
|
||||
visit project_broadcast_path(project, broadcast)
|
||||
|
||||
click_on "Files"
|
||||
expect(page).to have_content delete_file_button, count: 3
|
||||
|
||||
accept_alert do
|
||||
@@ -278,26 +194,7 @@ feature 'User managing broadcasts' do
|
||||
expect(page).to have_content delete_file_button, count: 2
|
||||
expect(Broadcast.find(broadcast.id).files.count).to eq 2
|
||||
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
|
||||
|
||||
private
|
||||
@@ -321,10 +218,6 @@ feature 'User managing broadcasts' do
|
||||
all('input[type="checkbox"]')[1].click
|
||||
end
|
||||
|
||||
def switch_view_dropdown
|
||||
'Switch View'
|
||||
end
|
||||
|
||||
def schedule_demo
|
||||
t 'broadcasts.splash.actions.book_demo'
|
||||
end
|
||||
@@ -353,10 +246,5 @@ feature 'User managing broadcasts' do
|
||||
t 'broadcasts.file.actions.delete_file'
|
||||
end
|
||||
|
||||
def select_conference_option(value)
|
||||
if value.present?
|
||||
select value, from: "broadcast[conference_option]"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -383,104 +383,9 @@ feature "User managing location releases" do
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
context "when the user is associate" do
|
||||
@@ -498,15 +403,6 @@ feature "User managing location releases" do
|
||||
click_on manage_button
|
||||
expect(page).not_to have_link("Download", exact: true)
|
||||
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
|
||||
|
||||
private
|
||||
@@ -650,42 +546,6 @@ feature "User managing location releases" do
|
||||
'Some signature legal language'
|
||||
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
|
||||
t 'public.amendments.new.amendment.heading'
|
||||
end
|
||||
|
||||
@@ -37,7 +37,7 @@ feature "User managing material releases" do
|
||||
click_button submit_release_button
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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"
|
||||
expect(page).to have_link("Download")
|
||||
@@ -364,19 +364,19 @@ feature "User managing material releases" do
|
||||
|
||||
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 "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")
|
||||
|
||||
drop_file Rails.root.join(file_fixture("material_photo.png")), type: :dropzone
|
||||
click_on "Save Changes"
|
||||
|
||||
expect(page).to have_content("The release has been updated")
|
||||
expect(page).to have_photo("material_photo.png", visible: :all)
|
||||
expect(page).to have_content("Files added successfully to the release")
|
||||
expect(page).to have_content("1")
|
||||
end
|
||||
|
||||
scenario "viewing the contract PDF" do
|
||||
@@ -421,104 +421,9 @@ feature "User managing material releases" do
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
context "when the user is associate" do
|
||||
@@ -536,15 +441,6 @@ feature "User managing material releases" do
|
||||
click_on "Manage"
|
||||
expect(page).not_to have_link("Download", exact: true)
|
||||
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
|
||||
|
||||
private
|
||||
@@ -693,42 +589,6 @@ feature "User managing material releases" do
|
||||
'Some signature legal language'
|
||||
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
|
||||
'material_release_minor'
|
||||
end
|
||||
|
||||
@@ -215,15 +215,6 @@ feature "User managing medical releases" do
|
||||
expect(page).to have_link("Download", exact: true, count: 2)
|
||||
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
|
||||
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')
|
||||
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
|
||||
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,
|
||||
@@ -343,15 +276,6 @@ feature "User managing medical releases" do
|
||||
expect(page).to have_link("Download", exact: true, count: 0)
|
||||
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
|
||||
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)
|
||||
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
|
||||
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
|
||||
'Some signature legal language'
|
||||
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
|
||||
|
||||
@@ -79,83 +79,6 @@ feature "User managing misc releases" do
|
||||
expect(content_type).to eq('application/pdf')
|
||||
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
|
||||
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)
|
||||
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
|
||||
|
||||
private
|
||||
@@ -300,40 +215,4 @@ feature "User managing misc releases" do
|
||||
def view_release_pdf_link_for(release)
|
||||
['Download', href: misc_release_contracts_path(release, format: 'pdf')]
|
||||
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
|
||||
|
||||
@@ -92,39 +92,9 @@ feature "User managing music releases" do
|
||||
before do
|
||||
sign_in current_user
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
context "when the user is associate" do
|
||||
@@ -133,24 +103,15 @@ feature "User managing music releases" do
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
|
||||
scenario "should not show download" do
|
||||
collection1 = create(:music_release, name: "EDM Music", project: project)
|
||||
|
||||
|
||||
visit project_music_releases_path(project)
|
||||
|
||||
|
||||
click_on "Manage"
|
||||
expect(page).not_to have_link("Download", exact: true)
|
||||
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
|
||||
|
||||
private
|
||||
@@ -216,16 +177,4 @@ feature "User managing music releases" do
|
||||
select "Other", from: "Restriction"
|
||||
fill_in "Describe other restrictions", with: "Test"
|
||||
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
|
||||
|
||||
@@ -374,104 +374,9 @@ feature "User managing talent releases" do
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
context "when the user is associate" do
|
||||
@@ -489,15 +394,6 @@ feature "User managing talent releases" do
|
||||
click_on "Manage"
|
||||
expect(page).not_to have_link("Download", exact: true)
|
||||
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
|
||||
|
||||
private
|
||||
@@ -679,40 +575,4 @@ feature "User managing talent releases" do
|
||||
def dummy_signature_legal_text
|
||||
'Some signature legal language'
|
||||
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
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe AcquiredMediaRelease do
|
||||
it_behaves_like 'an approvable'
|
||||
it_behaves_like "a contractable"
|
||||
it_behaves_like "an exploitable"
|
||||
it_behaves_like "a notable"
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe AppearanceRelease do
|
||||
it_behaves_like 'an approvable'
|
||||
it_behaves_like 'a contractable'
|
||||
it_behaves_like 'an exploitable'
|
||||
it_behaves_like 'a notable'
|
||||
|
||||
@@ -6,7 +6,8 @@ RSpec.describe BroadcastRecording, type: :model do
|
||||
end
|
||||
|
||||
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) }
|
||||
end
|
||||
|
||||
@@ -24,16 +25,20 @@ RSpec.describe BroadcastRecording, type: :model do
|
||||
let(:broadcast_recording) { create(:broadcast_recording, broadcast: broadcast) }
|
||||
|
||||
it "should have a download url" do
|
||||
download_file_name = broadcast_recording.send(:download_file_name)
|
||||
expect(broadcast_recording.download_url).to eq("https://stream.mux.com/asset_playback_uid/high.mp4?download=#{download_file_name}")
|
||||
name = broadcast_recording.name
|
||||
expect(broadcast_recording.download_url).to eq("https://stream.mux.com/asset_playback_uid/high.mp4?download=#{name}")
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
broadcast = create(:broadcast, skip_create_callback: true, name: "My Broadcast")
|
||||
recording = create(:broadcast_recording, broadcast: broadcast, created_at: DateTime.new(2020, 05, 14, 15, 30, 00))
|
||||
file_name = recording.download_file_name
|
||||
recording = create(:broadcast_recording, broadcast: broadcast)
|
||||
file_name = recording.name
|
||||
|
||||
expect(file_name).to eq "my-broadcast_date_2020-05-14_time_15-30-00"
|
||||
end
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe LocationRelease do
|
||||
it_behaves_like 'an approvable'
|
||||
it_behaves_like "a contractable"
|
||||
it_behaves_like "an exploitable"
|
||||
it_behaves_like "a notable"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe MaterialRelease do
|
||||
it_behaves_like 'an approvable'
|
||||
it_behaves_like "a contractable"
|
||||
it_behaves_like "an exploitable"
|
||||
it_behaves_like "a notable"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe MedicalRelease do
|
||||
it_behaves_like 'an approvable'
|
||||
it_behaves_like "a contractable"
|
||||
it_behaves_like "a notable"
|
||||
it_behaves_like "a photoable"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe MiscRelease, type: :model do
|
||||
it_behaves_like 'an approvable'
|
||||
it_behaves_like "a contractable"
|
||||
it_behaves_like "a notable"
|
||||
it_behaves_like "a photoable"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe MusicRelease do
|
||||
it_behaves_like 'an approvable'
|
||||
it_behaves_like "a contractable"
|
||||
it_behaves_like "an exploitable"
|
||||
it_behaves_like "a notable"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe TalentRelease do
|
||||
it_behaves_like 'an approvable'
|
||||
it_behaves_like "a contractable"
|
||||
it_behaves_like "an exploitable"
|
||||
it_behaves_like "a notable"
|
||||
|
||||
@@ -24,7 +24,11 @@ describe MaterialReleasePolicy do
|
||||
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) }
|
||||
end
|
||||
|
||||
|
||||
47
spec/support/shared_examples_for_an_approvable.rb
Normal file
47
spec/support/shared_examples_for_an_approvable.rb
Normal 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
|
||||
@@ -2,7 +2,7 @@ module SignatureHelper
|
||||
def draw_signature(file, signature_field_id)
|
||||
data_uri = ActionController::Base.helpers.escape_javascript(Base64Image.from_image(file).data_uri)
|
||||
page.execute_script <<-JS
|
||||
$("##{signature_field_id}").val("#{data_uri}")
|
||||
document.getElementById("#{signature_field_id}").value = "#{data_uri}";
|
||||
JS
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user