Compare commits

...

8 Commits

Author SHA1 Message Date
Bilal
5147806483 add specs and use i18n 2020-08-19 15:47:01 +03:00
Bilal
f5628c47df allow selecting conference option 2020-08-19 13:05:16 +03:00
Bilal
27fade2d09 remove obsolete require 2020-08-18 20:46:38 +03:00
Bilal
be5261037e Complete teams meeting creation and token refresh 2020-08-18 20:43:33 +03:00
Bilal
f25a72004e create graph api client to handle requests 2020-08-12 16:36:47 +02:00
Bilal
3352217a03 update azure_ad strategy 2020-08-12 14:44:22 +02:00
Bilal
0cc3b2bd62 Get code and token from Azure AD and store it to the DB 2020-08-12 13:52:22 +02:00
Senad Uka
eb7f8f1a43 Initial teams commit 2020-08-06 16:57:39 +00:00
88 changed files with 640 additions and 1658 deletions

View File

@@ -7,6 +7,8 @@ AWS_SECRET_ACCESS_KEY=
AWS_REGION= AWS_REGION=
BRAYNIAC_AI_API_ENDPOINT=https://z99cprg2eg.execute-api.us-east-1.amazonaws.com/dev/v0.0.1 BRAYNIAC_AI_API_ENDPOINT=https://z99cprg2eg.execute-api.us-east-1.amazonaws.com/dev/v0.0.1
SOURCE_AUDIO_API_ENDPOINT=https://bigmedia.sourceaudio.com/api
SOURCE_AUDIO_TOKEN=
# Optional # Optional
REDIS_URL= REDIS_URL=
@@ -14,6 +16,7 @@ REDIS_URL=
# Required for Zoom.us integration # Required for Zoom.us integration
ZOOM_API_KEY= ZOOM_API_KEY=
ZOOM_API_SECRET= ZOOM_API_SECRET=
ZOOM_ACCOUNT_NUMBER=
ZOOM_PRO_USERS_LIMIT= # defaults to 3 ZOOM_PRO_USERS_LIMIT= # defaults to 3
ZOOM_USER_TYPE= # 'pro' / 'basic' ZOOM_USER_TYPE= # 'pro' / 'basic'
ZOOM_ENABLE_RECORDINGS= # true / false (default: false) ZOOM_ENABLE_RECORDINGS= # true / false (default: false)
@@ -26,6 +29,10 @@ MUX_TOKEN_SECRET=
MUX_BROADCAST_SERVER_URL=rtmp://global-live.mux.com:5222/app MUX_BROADCAST_SERVER_URL=rtmp://global-live.mux.com:5222/app
MUX_TEST_MODE_DISABLED= MUX_TEST_MODE_DISABLED=
# Required for creating user through API
CUSTOM_API_TOKEN=
# 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'

View File

@@ -139,6 +139,15 @@ gem 'rack-cors'
# Ruby wrappers for the HubSpot REST API # Ruby wrappers for the HubSpot REST API
gem "hubspot-ruby" gem "hubspot-ruby"
# OAuth
gem 'omniauth-oauth2', '~> 1.6'
# OmniAuth CSRF protection
gem 'omniauth-rails_csrf_protection', '~> 0.1.2'
# authenticate via Microsoft
# gem 'omniauth-microsoft_graph', git: 'https://github.com/m4c3/omniauth-microsoft_graph'
# gem 'omniauth-microsoft_graph'
group :development, :test, :review do group :development, :test, :review do
# Call "byebug" anywhere in the code to stop execution and get a debugger console # Call "byebug" anywhere in the code to stop execution and get a debugger console
gem "byebug", "~> 11.0.1", platforms: [:mri, :mingw, :x64_mingw] gem "byebug", "~> 11.0.1", platforms: [:mri, :mingw, :x64_mingw]

View File

@@ -220,6 +220,7 @@ GEM
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
hashdiff (1.0.1) hashdiff (1.0.1)
hashery (2.1.2) hashery (2.1.2)
hashie (4.1.0)
hexapdf (0.9.3) hexapdf (0.9.3)
cmdparse (~> 3.0, >= 3.0.3) cmdparse (~> 3.0, >= 3.0.3)
geom2d (~> 0.2) geom2d (~> 0.2)
@@ -297,6 +298,7 @@ GEM
money (~> 6.13.2) money (~> 6.13.2)
railties (>= 3.0) railties (>= 3.0)
msgpack (1.3.1) msgpack (1.3.1)
multi_json (1.15.0)
multi_xml (0.6.0) multi_xml (0.6.0)
multipart-post (2.1.1) multipart-post (2.1.1)
nio4r (2.5.2) nio4r (2.5.2)
@@ -308,6 +310,21 @@ GEM
warden warden
oath-generators (1.0.1) oath-generators (1.0.1)
oath (>= 0.0.12) 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) parallel (1.19.1)
parity (3.2.0) parity (3.2.0)
parser (2.6.5.0) parser (2.6.5.0)
@@ -552,6 +569,8 @@ DEPENDENCIES
mux_ruby! mux_ruby!
oath (~> 1.1.0) oath (~> 1.1.0)
oath-generators (~> 1.0.1) oath-generators (~> 1.0.1)
omniauth-oauth2 (~> 1.6)
omniauth-rails_csrf_protection (~> 0.1.2)
parity (~> 3.2.0) parity (~> 3.2.0)
pdf-reader (~> 2.1.0) pdf-reader (~> 2.1.0)
pdfkit (~> 0.8.2) pdfkit (~> 0.8.2)

View File

@@ -1,9 +0,0 @@
$(document).on("turbolinks:load", function() {
$("#upload_directory_files").on('click', function(e){
const newFilesCount = $('input[name = "directory[files][]"][type = "hidden"]').length;
if (newFilesCount === 0){
e.preventDefault();
}
});
});

View File

@@ -20,7 +20,6 @@ class Admin::AccountsController < Admin::ApplicationController
def show def show
@videos = filtered_account_videos.order(created_at: :desc, project_id: :desc).paginate(page: params[:page]) @videos = filtered_account_videos.order(created_at: :desc, project_id: :desc).paginate(page: params[:page])
@broadcasts = account_broadcasts.order(created_at: :desc, project_id: :desc).paginate(page: params[:page])
end end
def edit def edit
@@ -71,8 +70,4 @@ class Admin::AccountsController < Admin::ApplicationController
@account.videos @account.videos
end end
end end
def account_broadcasts
@account.broadcasts
end
end end

View File

@@ -1,24 +0,0 @@
class Admin::BroadcastsController < Admin::ApplicationController
before_action :set_broadcast, only: [:edit, :update]
def edit
end
def update
if @broadcast.update(broadcast_update_params)
redirect_to [:admin, @broadcast.project.account], notice: t(".notice")
else
render :edit
end
end
private
def set_broadcast
@broadcast = authorize policy_scope(Broadcast).find(params[:id])
end
def broadcast_update_params
params.require(:broadcast).permit(:stream_url_override, :stream_key_override, :director_mode_video_embed)
end
end

View File

@@ -1,12 +1,5 @@
# frozen_string_literal: true
require './lib/knock_monkeypatch'
class Api::UserTokenController < Knock::AuthTokenController class Api::UserTokenController < Knock::AuthTokenController
include Oath::ControllerHelpers
skip_before_action :verify_authenticity_token skip_before_action :verify_authenticity_token
before_action :sign_in_user
rescue_from Exception, :with => :return_error rescue_from Exception, :with => :return_error
@@ -17,7 +10,7 @@ class Api::UserTokenController < Knock::AuthTokenController
logger.error "==Handled=======" logger.error "==Handled======="
logger.error exception.message logger.error exception.message
logger.error exception.backtrace.join("\n") logger.error exception.backtrace.join("\n")
logger.error "==Handled=======" logger.error "==Handled======="
case exception case exception
when ActiveRecord::RecordNotFound when ActiveRecord::RecordNotFound
@status = 404 @status = 404
@@ -34,18 +27,12 @@ class Api::UserTokenController < Knock::AuthTokenController
end end
# for some reason render json_errors is not working # for some reason render json_errors is not working
# simulating JSON API support # simulating JSON API support
render json: { render json: {
errors: [{ errors: [{
status: @status.to_s, status: @status.to_s,
title: @message title: @message
}] }]
} }
end end
private
def sign_in_user
sign_in(entity)
end
end end

View File

@@ -1,33 +0,0 @@
# frozen_string_literal: true
class Api::UsersController < Api::ApiController
skip_before_action :authenticate_user
before_action :verify_custom_token, only: :create
def create
if user_params[:email].nil? || user_params[:password].nil?
raise ActionController::ParameterMissing.new 'Missing email or password'
end
user = Oath::Services::SignUp.new(user_params).perform
render json: user.slice(:email, :created_at, :first_name, :last_name)
end
private
def user_params
params.require(:user).permit(%i[
email
password
first_name
last_name
])
end
def verify_custom_token
if token.blank? || token != ENV['CUSTOM_API_TOKEN']
unauthorized_entity(:user)
end
end
end

View File

@@ -1,26 +0,0 @@
class BroadcastRecordingsController < ApplicationController
layout "project"
before_action :set_project
before_action :set_broadcast
before_action :set_recording
def destroy
@recording.update(hidden: true)
@recordings = @broadcast.broadcast_recordings.visible.order_by_recent.paginate(page: params[:page])
end
private
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[:id])
end
end

View File

@@ -26,8 +26,8 @@ class BroadcastsController < ApplicationController
end end
def show def show
@conference_url = url_for [@broadcast.project, @broadcast, :zoom_meeting] @conference_url = url_for [@broadcast.project, @broadcast, :conference_meeting]
@recordings = @broadcast.broadcast_recordings.visible.order_by_recent.paginate(page: params[:page]) @recordings = @broadcast.broadcast_recordings.order_by_recent.paginate(page: params[:page])
@files = @broadcast.files.order("created_at DESC").paginate(page: params[:files_page]) @files = @broadcast.files.order("created_at DESC").paginate(page: params[:files_page])
render layout: 'application' render layout: 'application'
end end
@@ -72,7 +72,7 @@ class BroadcastsController < ApplicationController
end end
def broadcast_params def broadcast_params
params.require(:broadcast).permit(:name, :shoot_location_time_zone, files: []) params.require(:broadcast).permit(:name, :shoot_location_time_zone, :conference_option, files: [])
end end
def set_project def set_project

View File

@@ -0,0 +1,22 @@
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

View File

@@ -0,0 +1,45 @@
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

View File

@@ -50,58 +50,11 @@ class MaterialReleasesController < ApplicationController
private private
def person_params
%i[
person_first_name
person_last_name
person_phone
person_company
person_email
person_title
person_address_street1
person_address_street2
person_address_city
person_address_state
person_address_zip
person_address_country
]
end
def guardian_params
%i[
guardian_first_name
guardian_last_name
guardian_phone
guardian_email
guardian_photo
guardian_address_street1
guardian_address_street2
guardian_address_city
guardian_address_state
guardian_address_zip
guardian_address_country
]
end
def second_guardian_params
%i[
guardian_2_first_name
guardian_2_last_name
guardian_2_phone
guardian_2_email
guardian_2_photo
guardian_2_address_street1
guardian_2_address_street2
guardian_2_address_city
guardian_2_address_state
guardian_2_address_zip
guardian_2_address_country
]
end
def material_release_params def material_release_params
params.require(:material_release).permit(person_params, guardian_params, second_guardian_params, :minor, params.require(:material_release).permit(
:name, :address_street1, :address_street2, :address_city, :address_state, :address_zip, :address_country, :name, :address_street1, :address_street2, :address_city, :address_state, :address_zip, :address_country,
:person_first_name, :person_last_name, :person_title, :person_company, :person_phone, :person_email,
:person_address_street1, :person_address_street2, :person_address_city, :person_address_state, :person_address_zip, :person_address_country,
:applicable_medium_id, :applicable_medium_text, :applicable_medium_id, :applicable_medium_text,
:territory_id, :territory_text, :territory_id, :territory_text,
:term_id, :term_text, :term_id, :term_text,

View File

@@ -5,7 +5,7 @@ class Public::BroadcastsController < Public::BaseController
def show def show
@conference_url = broadcast_zoom_meeting_url(@broadcast.token) @conference_url = broadcast_zoom_meeting_url(@broadcast.token)
@multi_view_broadcasts = multi_view_broadcasts @multi_view_broadcasts = multi_view_broadcasts
@recordings = @broadcast.broadcast_recordings.visible.order_by_recent.paginate(page: params[:page]) @recordings = @broadcast.broadcast_recordings.order_by_recent.paginate(page: params[:page])
@files = @broadcast.files.order("created_at DESC").paginate(page: params[:files_page]) @files = @broadcast.files.order("created_at DESC").paginate(page: params[:files_page])
render 'broadcasts/show' render 'broadcasts/show'

View File

@@ -39,59 +39,11 @@ class Public::MaterialReleasesController < Public::BaseController
authorize material_releases.build(params) authorize material_releases.build(params)
end end
def person_params
%i[
person_first_name
person_last_name
person_phone
person_email
person_title
person_company
person_address_street1
person_address_street2
person_address_city
person_address_state
person_address_zip
person_address_country
]
end
def guardian_params
%i[
guardian_first_name
guardian_last_name
guardian_phone
guardian_email
guardian_photo
guardian_address_street1
guardian_address_street2
guardian_address_city
guardian_address_state
guardian_address_zip
guardian_address_country
]
end
def second_guardian_params
%i[
guardian_2_first_name
guardian_2_last_name
guardian_2_phone
guardian_2_email
guardian_2_photo
guardian_2_address_street1
guardian_2_address_street2
guardian_2_address_city
guardian_2_address_state
guardian_2_address_zip
guardian_2_address_country
]
end
def material_release_params def material_release_params
params.require(:material_release).permit(person_params, guardian_params, second_guardian_params, :minor, params.require(:material_release).permit(
:name, :address_street1, :address_street2, :address_city, :address_state, :address_zip, :address_country, :name, :address_street1, :address_street2, :address_city, :address_state, :address_zip, :address_country,
:person_first_name, :person_last_name, :person_title, :person_company, :person_phone, :person_email,
:person_address_street1, :person_address_street2, :person_address_city, :person_address_state, :person_address_zip, :person_address_country,
:signature_base64, :signature_base64,
:locale, :contract_template, :description, photos: [] :locale, :contract_template, :description, photos: []
) )

View File

@@ -35,7 +35,7 @@ class StreamNotificationsController < ApplicationController
duration = notification.dig(:data, :duration) duration = notification.dig(:data, :duration)
recording = @broadcast.broadcast_recordings.create!(asset_uid: asset_uid, asset_playback_uid: playback_uid, file_name: file_name, duration: duration) recording = @broadcast.broadcast_recordings.create!(asset_uid: asset_uid, asset_playback_uid: playback_uid, file_name: file_name, duration: duration)
recordings = @broadcast.broadcast_recordings.visible.order_by_recent.paginate(page: params[:page]) recordings = @broadcast.broadcast_recordings.order_by_recent.paginate(page: params[:page])
link = helpers.link_to(recording.broadcast_name.titleize, recording.download_url, target: "_blank") link = helpers.link_to(recording.broadcast_name.titleize, recording.download_url, target: "_blank")
message = "Your recent live stream has been recorded and is available for download here: #{link}" message = "Your recent live stream has been recorded and is available for download here: #{link}"

View File

@@ -0,0 +1,17 @@
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

View File

@@ -5,7 +5,6 @@ class Account < ApplicationRecord
has_many :users, through: :account_auths has_many :users, through: :account_auths
has_many :projects, dependent: :destroy has_many :projects, dependent: :destroy
has_many :videos, through: :projects has_many :videos, through: :projects
has_many :broadcasts, through: :projects
has_many :contract_templates, through: :projects has_many :contract_templates, through: :projects
validates :name, presence: true validates :name, presence: true
@@ -64,19 +63,6 @@ class Account < ApplicationRecord
])).sum(:byte_size).to_f ])).sum(:byte_size).to_f
end end
def total_number_of_releases
[
MiscRelease.where(project: projects).size,
AppearanceRelease.where(project: projects).size,
TalentRelease.where(project: projects).size,
MaterialRelease.where(project: projects).size,
MedicalRelease.where(project: projects).size,
LocationRelease.where(project: projects).size,
AcquiredMediaRelease.where(project: projects).size,
MusicRelease.where(project: projects).size
].sum
end
def to_param def to_param
slug slug
end end
@@ -98,7 +84,7 @@ class Account < ApplicationRecord
end end
def taskme_enabled? def taskme_enabled?
plan_uid.to_s == "me_suite" || plan_uid.to_s == "taskme" ENV["TASKME_ENABLED"] && (plan_uid.to_s == "me_suite" || plan_uid.to_s == "taskme")
end end
def plan_name def plan_name

View File

@@ -15,7 +15,7 @@ class AppHost
end end
def domain_with_port def domain_with_port
[domain, port].compact.join(":") [domain, port].reject(&:blank?).compact.join(":")
end end
def protocol def protocol

View File

@@ -35,11 +35,7 @@ class Broadcast < ApplicationRecord
end end
def stream_server_url def stream_server_url
stream_url_override.presence || ENV["MUX_BROADCAST_SERVER_URL"] ENV['MUX_BROADCAST_SERVER_URL']
end
def stream_server_key
stream_key_override.presence || stream_key
end end
def zoom_meeting_url def zoom_meeting_url

View File

@@ -5,8 +5,6 @@ class BroadcastRecording < ApplicationRecord
validates :asset_uid, uniqueness: true validates :asset_uid, uniqueness: true
scope :visible, -> { where(hidden: false) }
def download_url def download_url
"https://stream.mux.com/#{asset_playback_uid}/#{file_name}?download=#{download_file_name}" "https://stream.mux.com/#{asset_playback_uid}/#{file_name}?download=#{download_file_name}"
end end

View File

@@ -12,11 +12,6 @@ class MaterialRelease < ApplicationRecord
include PersonName include PersonName
include CsvExportable include CsvExportable
include Approvable include Approvable
include GuardianPhotoable
include SecondGuardianPhotoable
include GuardianName
include SecondGuardianName
class << self class << self
def custom_csv_exportable_headers def custom_csv_exportable_headers
@@ -35,39 +30,6 @@ class MaterialRelease < ApplicationRecord
%w(person_address_country country) %w(person_address_country country)
] ]
composed_of :guardian_address,
class_name: 'Address',
mapping: [
%w[guardian_address_street1 street1],
%w[guardian_address_street2 street2],
%w[guardian_address_city city],
%w[guardian_address_state state],
%w[guardian_address_zip zip],
%w[guardian_address_country country]
]
composed_of :guardian_2_address,
class_name: 'Address',
mapping: [
%w[guardian_2_address_street1 street1],
%w[guardian_2_address_street2 street2],
%w[guardian_2_address_city city],
%w[guardian_2_address_state state],
%w[guardian_2_address_zip zip],
%w[guardian_2_address_country country]
]
# We don't care for the argument but method WILL receive option name
# when called from inside with_option block, hence * argument
def self.face_photo_acceptable_content_types(*)
['image/png', 'image/jpeg']
end
def self.acceptable_import_file_extensions
['.png', '.jpeg', '.jpg', '.pdf']
end
validates :name, presence: true validates :name, presence: true
validates :person_email, email: true, allow_blank: true validates :person_email, email: true, allow_blank: true
@@ -85,8 +47,8 @@ class MaterialRelease < ApplicationRecord
@contact_person ||= Contact.new(person_name, person_address, person_email, person_phone) @contact_person ||= Contact.new(person_name, person_address, person_email, person_phone)
end end
def second_guardian_present? def minor?
guardian_2_first_name.present? false
end end
def uses_edl? def uses_edl?

View File

@@ -1,9 +0,0 @@
class BroadcastRecordingPolicy < ApplicationPolicy
def destroy?
if user.nil? || user.user.nil?
return false
end
user.manager? || user.account_manager?
end
end

View File

@@ -1,4 +1,4 @@
<%= bootstrap_form_with model: account, url: account_path, html: { autocorrect: :off, autocapitalize: :none, autocomplete: :off, spellcheck: false }, layout: :inline, remote: true do |form| %> <%= bootstrap_form_with model: account, url: account_path, html: { autocorrect: :off, autocapitalize: :none, autocomplete: :off, spellcheck: false }, layout: :inline, remote: true do |form| %>
<%= form.file_field :logo, hide_label: true, accept: "image/*", placeholder: "Upload Logo", direct_upload: true, wrapper_class: "mr-1", required: true %> <%= form.file_field :logo, hide_label: true, accept: "image/*", placeholder: "Upload Logo", direct_upload: true, wrapper_class: "mr-1" %>
<%= form.button(fa_icon("upload", text: t(".submit")), class: "btn btn-md btn-primary", data: { disable_with: t("shared.disable_with") }) %> <%= form.button(fa_icon("upload", text: t(".submit")), class: "btn btn-md btn-primary", data: { disable_with: t("shared.disable_with") }) %>
<% end %> <% end %>

View File

@@ -18,9 +18,6 @@
<%= fa_icon("warning", text: t(".no_media"), class: "text-danger") %> <%= fa_icon("warning", text: t(".no_media"), class: "text-danger") %>
<% end %> <% end %>
</td> </td>
<td>
<%= contact_info_for(acquired_media_release.contact_person) %>
</td>
<td> <td>
<%= notes_preview acquired_media_release.notes.order_by_recent %> <%= notes_preview acquired_media_release.notes.order_by_recent %>
</td> </td>

View File

@@ -29,7 +29,6 @@
<th><%= t '.table_headers.approved'%></th> <th><%= t '.table_headers.approved'%></th>
<th><%= AcquiredMediaRelease.human_attribute_name(:name) %></th> <th><%= AcquiredMediaRelease.human_attribute_name(:name) %></th>
<th><%= t(".table_headers.file_infos_count") %></th> <th><%= t(".table_headers.file_infos_count") %></th>
<th><%= t(".table_headers.owner_info") %></th>
<th><%= t(".table_headers.notes") %></th> <th><%= t(".table_headers.notes") %></th>
<th><%= t(".table_headers.tags") %></th> <th><%= t(".table_headers.tags") %></th>
<th><%= t(".table_headers.signed_at") %></th> <th><%= t(".table_headers.signed_at") %></th>

View File

@@ -1,13 +0,0 @@
<tr>
<td><%= broadcast.project.name %></td>
<td><%= broadcast.name %></td>
<td class="text-right">
<div class="btn-group">
<%= button_tag "Manage", class: "btn btn-light btn-sm dropdown-toggle border", data: { toggle: "dropdown", boundary: "window" }, aria: { haspopup: true, expanded: false } %>
<div class="dropdown-menu dropdown-menu-right">
<%= link_to "View on Mux", "#{ENV['MUX_LIVE_STREAM_DASHBOARD_URL']}/#{broadcast.stream_uid}", class: "dropdown-item", target: "_blank" %>
<%= link_to "Edit", [:edit, :admin, broadcast, locale: I18n.locale], class: "dropdown-item" %>
</div>
</div>
</td>
</tr>

View File

@@ -9,8 +9,6 @@
<dd class="col-sm-10"><%= @account.users.size %></dd> <dd class="col-sm-10"><%= @account.users.size %></dd>
<dt class="col-sm-2">Created at</dt> <dt class="col-sm-2">Created at</dt>
<dd class="col-sm-10"><%= time_ago_in_words(@account.created_at) %> ago</dd> <dd class="col-sm-10"><%= time_ago_in_words(@account.created_at) %> ago</dd>
<dt class="col-sm-2"># of Releases</dt>
<dd class="col-sm-10"><%= @account.total_number_of_releases %></dd>
</dl> </dl>
<% end %> <% end %>
@@ -36,25 +34,5 @@
<%= will_paginate @videos %> <%= will_paginate @videos %>
</div> </div>
<% end %> <% end %>
<hr>
<%= card_field_set_tag "Broadcasts" do %>
<div class="table-responsive-sm">
<table class="table table-striped tr-px-4 align-all-middle">
<thead class="thead-light">
<tr>
<th>Project</th>
<th>Name</th>
<th></th>
</tr>
</thead>
<tbody id="broadcasts">
<%= render partial: "admin/accounts/broadcast", collection: @broadcasts %>
</tbody>
</table>
</div>
<div id="broadcasts_pagination">
<%= will_paginate @broadcasts %>
</div>
<% end %>
</div> </div>
</div> </div>

View File

@@ -1,14 +0,0 @@
<%= errors_summary_for broadcast %>
<%= bootstrap_form_with model: model, local: true do |form| %>
<%= form.text_field :stream_url_override %>
<%= form.text_field :stream_key_override %>
<%= form.text_area :director_mode_video_embed %>
<div class="row align-items-center text-center mt-4">
<%= link_to t("shared.cancel"), [:admin, broadcast.project.account], class: "col-3 text-reset" %>
<div class="col-9">
<%= form.submit class: class_string("btn btn-block", ["btn-success", "btn-primary"] => broadcast.new_record?), data: { disable_with: t("shared.disable_with") } %>
</div>
</div>
<% end %>

View File

@@ -1,6 +0,0 @@
<div class="card shadow-sm">
<%= card_header text: t(".heading"), close_action_path: [:admin, @broadcast.project.account] %>
<div class="card-body">
<%= render "form", model: [:admin, @broadcast], broadcast: @broadcast %>
</div>
</div>

View File

@@ -1,6 +0,0 @@
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 }) %>");

View File

@@ -16,8 +16,8 @@
<div class="btn-group"> <div class="btn-group">
<%= button_tag t(".actions.manage"), class: "btn btn-light btn-sm dropdown-toggle border", data: { toggle: "dropdown", boundary: "window" }, aria: { haspopup: true, expanded: false } %> <%= button_tag t(".actions.manage"), class: "btn btn-light btn-sm dropdown-toggle border", data: { toggle: "dropdown", boundary: "window" }, aria: { haspopup: true, expanded: false } %>
<div class="dropdown-menu dropdown-menu-right"> <div class="dropdown-menu dropdown-menu-right">
<%= link_to fa_icon("link fw", text: "Copy Stream URL"), broadcast.stream_server_url, class: "dropdown-item", data: { behavior: "clipboard" } %> <%= link_to fa_icon("link fw", text: "Copy Stream URL"), ENV['MUX_BROADCAST_SERVER_URL'], class: "dropdown-item", data: { behavior: "clipboard" } %>
<%= link_to fa_icon("key fw", text: "Copy Stream Key"), broadcast.stream_server_key, class: "dropdown-item", data: { behavior: "clipboard" } %> <%= link_to fa_icon("key fw", text: "Copy Stream Key"), broadcast.stream_key, class: "dropdown-item", data: { behavior: "clipboard" } %>
<% if policy(broadcast).show? %> <% if policy(broadcast).show? %>
<%= link_to fa_icon("file-video-o fw", text: "View"), [broadcast.project, broadcast], class: "dropdown-item", target: '_blank' %> <%= link_to fa_icon("file-video-o fw", text: "View"), [broadcast.project, broadcast], class: "dropdown-item", target: '_blank' %>
<% end %> <% end %>

View File

@@ -1,3 +1,2 @@
<%= 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.download_file_name, "javascript:void(0);", class: "dropdown-item", data: { behavior: "play_recording", playback_url: broadcast_recording.playback_url } %>

View File

@@ -2,12 +2,7 @@
<p>Click below to download the recordings of the live stream.</p> <p>Click below to download the recordings of the live stream.</p>
<ul class="mt-2"> <ul class="mt-2">
<% recordings.each do |recording| %> <% recordings.each do |recording| %>
<li> <li><%= link_to(recording.download_file_name, recording.download_url, target: "_blank") %></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>
<% end %> <% end %>
</ul> </ul>
<div id="recordings_pagination" class="row mt-5 justify-content-center"> <div id="recordings_pagination" class="row mt-5 justify-content-center">

View File

@@ -2,6 +2,7 @@
<%= bootstrap_form_with model: model, local: true do |form| %> <%= bootstrap_form_with model: model, local: true do |form| %>
<%= form.text_field :name %> <%= 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") %> <%= 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"> <div class="row align-items-center text-center mt-4">

View File

@@ -1,8 +1,4 @@
<% if broadcast.director_mode_video_embed.present? && params[:director_mode].present? %> <% if broadcast.streamer_recording? && broadcast.active? %>
<div class="embed-responsive-item" data-video-type="stream">
<%= raw broadcast.director_mode_video_embed %>
</div>
<% elsif broadcast.streamer_recording? && broadcast.active? %>
<div id="broadcast_video" class="embed-responsive-item" data-video-type="stream"></div> <div id="broadcast_video" class="embed-responsive-item" data-video-type="stream"></div>
<% else %> <% else %>
<div id="broadcast_video" class="embed-responsive-item" data-video-type="stream"> <div id="broadcast_video" class="embed-responsive-item" data-video-type="stream">
@@ -16,4 +12,4 @@
</tbody> </tbody>
</table> </table>
</div> </div>
<% end %> <% end %>

View File

@@ -39,15 +39,6 @@
<%= link_to broadcast.name.titleize, broadcast.url, data: { behavior: "play_stream"}, class: class_string("dropdown-item", "active" => @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) %>
<% end %> <% end %>
<% end %> <% end %>
<% if @broadcast.director_mode_video_embed.present? %>
<h5 class="dropdown-header">Director Mode</h5>
<% unless params[:director_mode] %>
<%= link_to "Enable Director Mode", url_for(params.permit!.merge(director_mode: true)), class: "dropdown-item" %>
<% else %>
<%= link_to "Disable Director Mode", url_for(params.permit!.except(:director_mode)), class: "dropdown-item" %>
<% end %>
<% end %>
<h5 class="dropdown-header">Previous Sessions</h5> <h5 class="dropdown-header">Previous Sessions</h5>
<div id="broadcast_recordings_nav"> <div id="broadcast_recordings_nav">
<% if @recordings.any? %> <% if @recordings.any? %>
@@ -127,8 +118,8 @@
</div> </div>
<hr> <hr>
<% end %> <% end %>
<p class="card-text">If you want to join the ZOOM meeting dedicated to this broadcast, follow the link below.</p> <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' %> <%= link_to 'Video Conference', @conference_url, class: "btn btn-primary btn-block", target: '_blank' %>
</div> </div>
<div class="<%= class_string("tab-pane fade show", "active" => params[:active_tab] == 'recordings') %>" id="recordings"> <div class="<%= class_string("tab-pane fade show", "active" => params[:active_tab] == 'recordings') %>" id="recordings">
<div id="broadcast_recordings"> <div id="broadcast_recordings">

View File

@@ -2,7 +2,7 @@
<%= field_set_tag content_tag(:span, t(".release_info.heading"), class: "h6 text-muted text-uppercase") do %> <%= field_set_tag content_tag(:span, t(".release_info.heading"), class: "h6 text-muted text-uppercase") do %>
<div class="form-row"> <div class="form-row">
<%= form.text_field :name, wrapper_class: "col-sm-6" %> <%= form.text_field :name, wrapper_class: "col-sm-6" %>
<%= form.select :release_type, options_for_release_type_select(project, @release_type), { wrapper_class: "col-sm-6" }, data: { toggle: "collapse-select", target_show_values_mapping: { "#guardian_clause": %w(acquired_media appearance talent material misc medical), "#fee_field": %w(appearance talent location material acquired_media), "#exploitable_rights_fields": %w(appearance talent location material acquired_media), "#custom_fields": %w(medical misc), "#amendment_clause": %w(location) } }, class: "form-control custom-select" %> <%= form.select :release_type, options_for_release_type_select(project, @release_type), { wrapper_class: "col-sm-6" }, data: { toggle: "collapse-select", target_show_values_mapping: { "#guardian_clause": %w(acquired_media appearance talent misc medical), "#fee_field": %w(appearance talent location material acquired_media), "#exploitable_rights_fields": %w(appearance talent location material acquired_media), "#custom_fields": %w(medical misc), "#amendment_clause": %w(location) } }, class: "form-control custom-select" %>
</div> </div>
<div class="form-row mb-3"> <div class="form-row mb-3">
<%= form.radio_button :accessibility, :public_template, label: "Public", wrapper_class: "mr-3" %> <%= form.radio_button :accessibility, :public_template, label: "Public", wrapper_class: "mr-3" %>

View File

@@ -3,6 +3,6 @@
<%= render "shared/files_dropzone_fields", form: form, directory: directory %> <%= render "shared/files_dropzone_fields", form: form, directory: directory %>
<% end %> <% end %>
<div class="pt-3"> <div class="pt-3">
<%= form.submit t(".submit"), id: "upload_directory_files", class: "btn btn-block btn-success", data: { disable_with: t("shared.disable_with") } %> <%= form.submit t(".submit"), class: "btn btn-block btn-success", data: { disable_with: t("shared.disable_with") } %>
</div> </div>
<% end %> <% end %>

View File

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

View File

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

View File

@@ -16,10 +16,10 @@
<% end %> <% end %>
</td> </td>
<td> <td>
<%= contact_info(name: location_release.name, address: location_release.address) %> <%= location_release.name %>
</td> </td>
<td> <td>
<%= contact_info_for(location_release.contact_person) %> <%= contact_info address: location_release.address %>
</td> </td>
<td> <td>
<%= notes_preview location_release.notes.order_by_recent %> <%= notes_preview location_release.notes.order_by_recent %>

View File

@@ -28,12 +28,12 @@
<th data-behavior="all-selectable"><%= check_box_tag "location_release_ids[]", false, false %></th> <th data-behavior="all-selectable"><%= check_box_tag "location_release_ids[]", false, false %></th>
<th><%= t '.table_headers.approved'%></th> <th><%= t '.table_headers.approved'%></th>
<th></th> <th></th>
<th><%= t(".table_headers.location_info") %></th> <th><%= t(".table_headers.name") %></th>
<th><%= t(".table_headers.owner_info") %> <th><%= t(".table_headers.address") %>
<th><%= t(".table_headers.notes") %></th> <th><%= t(".table_headers.notes") %></th>
<th><%= t(".table_headers.tags") %></th> <th><%= t(".table_headers.tags") %></th>
<th><%= t(".table_headers.signed_at") %></th> <th><%= t(".table_headers.signed_at") %></th>
<th><%= t(".table_headers.amendment_signed") %></th> <th></th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>

View File

@@ -12,9 +12,6 @@
<hr> <hr>
<%= field_set_tag content_tag(:span, t(".signer_details.heading"), class: "h6 text-muted text-uppercase") do %> <%= field_set_tag content_tag(:span, t(".signer_details.heading"), class: "h6 text-muted text-uppercase") do %>
<%= form.form_group :minor do %>
<%= form.check_box :minor, label: t("helpers.label.material_release.minor"), data: { target: "[data-ujs-target=guardian-fields]", toggle: "collapse" } %>
<% end %>
<div class="form-row"> <div class="form-row">
<%= form.text_field :person_first_name, wrapper_class: "col-sm-6" %> <%= form.text_field :person_first_name, wrapper_class: "col-sm-6" %>
<%= form.text_field :person_last_name, wrapper_class: "col-sm-6" %> <%= form.text_field :person_last_name, wrapper_class: "col-sm-6" %>
@@ -24,28 +21,6 @@
<%= form.text_field :person_title, wrapper_class: "col-sm-6" %> <%= form.text_field :person_title, wrapper_class: "col-sm-6" %>
</div> </div>
<%= render "shared/address_fields", form: form, subject: "person" %> <%= render "shared/address_fields", form: form, subject: "person" %>
<div class="<%= class_string("collapse" => !material_release.minor?) %>" data-ujs-target="guardian-fields">
<%= card_field_set_tag t(".guardian_info.heading") do %>
<div class="form-row">
<%= form.text_field :guardian_first_name, required: material_release.minor?, wrapper_class: "col-sm-3" %>
<%= form.text_field :guardian_last_name, required: material_release.minor?, wrapper_class: "col-sm-3" %>
<%= form.phone_field :guardian_phone, wrapper_class: "col-sm-6" %>
<%= form.text_field :guardian_email, wrapper_class: "col-sm-6" %>
</div>
<%= render "shared/address_fields", form: form, subject: "guardian" %>
<% end %>
<%= card_field_set_tag t(".guardian_2_info.heading") do %>
<div class="form-row">
<%= form.text_field :guardian_2_first_name, wrapper_class: "col-sm-3" %>
<%= form.text_field :guardian_2_last_name, wrapper_class: "col-sm-3" %>
<%= form.phone_field :guardian_2_phone, wrapper_class: "col-sm-6" %>
<%= form.text_field :guardian_2_email, wrapper_class: "col-sm-6" %>
</div>
<%= render "shared/address_fields", form: form, subject: "guardian_2" %>
<% end %>
</div>
<% end %> <% end %>
<hr> <hr>
@@ -59,44 +34,6 @@
<%= field_set_tag content_tag(:span, t(".photos.heading"), class: "h6 text-muted text-uppercase") do %> <%= 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 %> <%= render "shared/photos_dropzone_fields", form: form, release: material_release %>
<div class="<%= class_string("collapse" => !material_release.minor?) %>" data-ujs-target="guardian-fields">
<br>
<div class="text-left">
<p><%= t(".photos.guardian_photo.heading") %></p>
<div id="guardian-photo-preview" class="d-inline-block mb-2" data-behavior="guardian-photo-preview" data-file-input="[data-ujs-target=guardian-photo-input]">
<div class="align-items-center d-flex photo-preview img-thumbnail justify-content-center">
<span>No photo yet</span>
</div>
</div>
<% if material_release.guardian_photo.attached? %>
<%= javascript_tag nonce: true do %>
App.PhotoPreview.set("#guardian-photo-preview", "<%= url_for(material_release.guardian_photo.variant(auto_orient: true, resize: '200x200')) %>");
<% end %>
<% end %>
<div class="d-inline-block">
<%= form.hidden_field :guardian_photo, value: form.object.guardian_photo.signed_id if material_release.guardian_photo.attached?%>
<%= form.file_field :guardian_photo, hide_label: true, data: { ujs_target: "guardian-photo-input" }, help: "PNG or JPG only", accept: material_release.class.face_photo_acceptable_content_types.join(",") %>
</div>
<p><%= t(".photos.guardian_2_photo.heading") %></p>
<div id="guardian-2-photo-preview" class="d-inline-block mb-2" data-behavior="guardian-photo-preview" data-file-input="[data-ujs-target=guardian-2-photo-input]">
<div class="align-items-center d-flex photo-preview img-thumbnail justify-content-center">
<span>No photo yet</span>
</div>
</div>
<% if material_release.guardian_2_photo.attached? %>
<%= javascript_tag nonce: true do %>
App.PhotoPreview.set("#guardian-2-photo-preview", "<%= url_for(material_release.guardian_2_photo.variant(auto_orient: true, resize: '200x200')) %>");
<% end %>
<% end %>
<div class="d-inline-block">
<%= form.hidden_field :guardian_2_photo, value: form.object.guardian_2_photo.signed_id if material_release.guardian_2_photo.attached?%>
<%= form.file_field :guardian_2_photo, hide_label: true, data: { ujs_target: "guardian-2-photo-input" }, help: "PNG or JPG only", accept: material_release.class.face_photo_acceptable_content_types.join(",") %>
</div>
</div>
<hr>
</div>
<% end %> <% end %>
<div class="row align-items-center text-center mt-4"> <div class="row align-items-center text-center mt-4">

View File

@@ -18,9 +18,6 @@
<td> <td>
<%= material_release.name %> <%= material_release.name %>
</td> </td>
<td>
<%= contact_info_for(material_release.contact_person) %>
</td>
<td> <td>
<%= notes_preview material_release.notes.order_by_recent %> <%= notes_preview material_release.notes.order_by_recent %>
</td> </td>

View File

@@ -29,10 +29,10 @@
<th><%= t '.table_headers.approved'%></th> <th><%= t '.table_headers.approved'%></th>
<th></th> <th></th>
<th><%= MaterialRelease.human_attribute_name(:name) %></th> <th><%= MaterialRelease.human_attribute_name(:name) %></th>
<th><%= t(".table_headers.owner_info") %>
<th><%= t(".table_headers.notes") %></th> <th><%= t(".table_headers.notes") %></th>
<th><%= t(".table_headers.tags") %></th> <th><%= t(".table_headers.tags") %></th>
<th><%= t(".table_headers.signed_at") %></th> <th><%= t(".table_headers.signed_at") %></th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>

View File

@@ -17,6 +17,7 @@
<%= @user.role_for(Current.account).to_s.titleize %> <%= @user.role_for(Current.account).to_s.titleize %>
<% end %> <% end %>
</p> </p>
<%= link_to 'Auth to Microsoft', '/auth/azure_ad', method: :post, class: "btn btn-primary" %>
</div> </div>
<div class="mt-3"> <div class="mt-3">

View File

@@ -8,10 +8,6 @@
<div class="card-body"> <div class="card-body">
<%= errors_summary_for @release %> <%= errors_summary_for @release %>
<%= bootstrap_form_with model: @release, method: :post, url: public_send("account_project_contract_template_#{@contract_template.release_type}_release_amendments_path"), local: true do |form| %> <%= bootstrap_form_with model: @release, method: :post, url: public_send("account_project_contract_template_#{@contract_template.release_type}_release_amendments_path"), local: true do |form| %>
<%= card_field_set_tag t('.signed_contract_preview') do %>
<embed class="embeded-contract-preview" type="application/pdf" src="<%= url_for([@release, :contracts, format: "pdf"]) %>" width="80%" height="1200" />
<% end %>
<%= card_field_set_tag t(".amendment.heading") do %> <%= card_field_set_tag t(".amendment.heading") do %>
<p><%= @contract_template.amendment_clause %></p> <p><%= @contract_template.amendment_clause %></p>
<% end %> <% end %>

View File

@@ -13,17 +13,6 @@
<hr> <hr>
<% unless @contract_template.guardian_clause.blank? %>
<%= form.form_group :minor do %>
<%= form.check_box :minor, label: t("helpers.label.appearance_release.minor"), data: { behavior: "update-required-status", target: "[data-ujs-target=guardian-fields]", toggle: "collapse" } %>
<% end %>
<%= card_field_set_tag t(".guardian_clause.heading") do %>
<p><%= @contract_template.guardian_clause %></p>
<% end %>
<hr>
<% end %>
<%= card_field_set_tag t(".release_info.heading") do %> <%= card_field_set_tag t(".release_info.heading") do %>
<div class="form-row"> <div class="form-row">
<%= form.text_field :name, required: true, wrapper_class: "col-12" %> <%= form.text_field :name, required: true, wrapper_class: "col-12" %>
@@ -51,91 +40,6 @@
<hr> <hr>
<% unless @contract_template.guardian_clause.blank? %>
<div class="<%= class_string("collapse" => !@material_release.minor?) %>" data-ujs-target="guardian-fields">
<%= card_field_set_tag t(".guardian_info.heading") do %>
<div class="form-row">
<%= form.text_field :guardian_first_name, required: @material_release.minor?, wrapper_class: "col-sm-3", data: { required_tag: "guardian" } %>
<%= form.text_field :guardian_last_name, required: @material_release.minor?, wrapper_class: "col-sm-3", data: { required_tag: "guardian" } %>
<%= form.phone_field :guardian_phone, required: @material_release.minor?, wrapper_class: "col-sm-6", data: { required_tag: "guardian" } %>
<%= form.text_field :guardian_email, required: @material_release.minor?, wrapper_class: "col-sm-6", data: { required_tag: "guardian" } %>
</div>
<%= render "shared/address_fields", form: form, subject: "guardian", required: @material_release.minor?, data: { required_tag: "guardian" } %>
<% end %>
<hr>
<%= card_field_set_tag t(".guardian_photo.heading") do %>
<div class="alert alert-warning font-weight-bold"><%= t ".guardian_photo.instructions" %></div>
<div class="text-center">
<div class="d-inline-block mb-2" data-behavior="guardian-photo-preview" data-file-input="[data-ujs-target=guardian-photo-input]">
<div class="align-items-center d-flex photo-preview img-thumbnail justify-content-center">
<span><%= t ".photo.no_photo" %></span>
</div>
</div>
<div class="d-inline-block text-left">
<% if @material_release.guardian_photo.attached? %>
<%= javascript_tag nonce: true do %>
App.PhotoPreview.set("[data-behavior=guardian-photo-preview]", "<%= url_for(@material_release.guardian_photo.variant(auto_orient: true, resize: '200x200')) %>");
<% end %>
<% end %>
<div class="hidden-file-input">
<%= form.hidden_field :guardian_photo, value: form.object.guardian_photo.signed_id if @material_release.guardian_photo.attached? %>
<%= form.file_field :guardian_photo, required: @material_release.minor?, hide_label: true, data: { ujs_target: "guardian-photo-input" }, accept: @material_release.class.face_photo_acceptable_content_types.join(","), direct_upload: true %>
</div>
<%= button_tag t(".photo.take_photo"), type: "button", class: "btn btn-lg btn-primary take-photo-button", data: { behavior: "trigger-click", target: "[data-ujs-target=guardian-photo-input]" } %>
</div>
<p class="p-2 font-weight-bold">
<small class="text-muted"><%= t ".photo.warning" %></small>
</p>
</div>
<% end %>
<hr>
<%= card_field_set_tag t(".guardian_2_info.heading") do %>
<div class="form-row">
<%= form.text_field :guardian_2_first_name, wrapper_class: "col-sm-3" %>
<%= form.text_field :guardian_2_last_name, wrapper_class: "col-sm-3" %>
<%= form.phone_field :guardian_2_phone, wrapper_class: "col-sm-6" %>
<%= form.text_field :guardian_2_email, wrapper_class: "col-sm-6" %>
</div>
<%= render "shared/address_fields", form: form, subject: "guardian_2" %>
<% end %>
<hr>
<%= card_field_set_tag t(".guardian_2_photo.heading") do %>
<div class="alert alert-warning font-weight-bold"><%= t ".guardian_2_photo.instructions" %></div>
<div class="text-center">
<div class="d-inline-block mb-2" data-behavior="guardian-photo-preview" data-file-input="[data-ujs-target=guardian-2-photo-input]">
<div class="align-items-center d-flex photo-preview img-thumbnail justify-content-center">
<span><%= t ".photo.no_photo" %></span>
</div>
</div>
<div class="d-inline-block text-left">
<% if @material_release.guardian_2_photo.attached? %>
<%= javascript_tag nonce: true do %>
App.PhotoPreview.set("[data-behavior=guardian-photo-preview]", "<%= url_for(@material_release.guardian_2_photo.variant(auto_orient: true, resize: '200x200')) %>");
<% end %>
<% end %>
<div class="hidden-file-input">
<%= form.hidden_field :guardian_2_photo, value: form.object.guardian_2_photo.signed_id if @material_release.guardian_2_photo.attached? %>
<%= form.file_field :guardian_2_photo, hide_label: true, data: { ujs_target: "guardian-2-photo-input" }, accept: @material_release.class.face_photo_acceptable_content_types.join(","), direct_upload: true %>
</div>
<%= button_tag t(".photo.take_photo"), type: "button", class: "btn btn-lg btn-primary take-photo-button", data: { behavior: "trigger-click", target: "[data-ujs-target=guardian-2-photo-input]" } %>
</div>
<p class="p-2 font-weight-bold">
<small class="text-muted"><%= t ".photo.warning" %></small>
</p>
</div>
<% end %>
<hr>
</div>
<% end %>
<%= card_field_set_tag t(".signature.heading") do %> <%= card_field_set_tag t(".signature.heading") do %>
<%= render "shared/signature_fields", form: form, instruction: 'For Owner or Authorized Signatory', signature_legal_text: @contract_template.signature_legal_text %> <%= render "shared/signature_fields", form: form, instruction: 'For Owner or Authorized Signatory', signature_legal_text: @contract_template.signature_legal_text %>
<% end %> <% end %>

View File

@@ -18,7 +18,15 @@
<div class="card-body p-0"> <div class="card-body p-0">
<div class="embed-responsive embed-responsive-16by9"> <div class="embed-responsive embed-responsive-16by9">
<div class="embed-responsive-item"> <div class="embed-responsive-item">
<div style="padding:56.25% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/444718363" style="position:absolute;top:0;left:0;width:100%;height:100%;" frameborder="0" allow="autoplay; fullscreen" allowfullscreen></iframe></div><script src="https://player.vimeo.com/api/player.js"></script> <table class="w-100 h-100 bg-secondary">
<tbody>
<tr>
<td class="text-center align-middle text-white">
Video tutorial will be available soon
</td>
</tr>
</tbody>
</table>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -0,0 +1,17 @@
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
# Rails.application.config.middleware.use OmniAuth::Builder do
# provider :microsoft_graph, ENV['AZURE_CLIENT_ID'], ENV['AZURE_CLIENT_SECRET'], scope: 'openid email profile User.Read'
# end

View File

@@ -67,7 +67,6 @@ en:
notes: Notes notes: Notes
signed_at: Date Signed signed_at: Date Signed
tags: Tags tags: Tags
owner_info: Owner Info
new: new:
heading: Import Acquired Media Release heading: Import Acquired Media Release
update: update:
@@ -112,11 +111,6 @@ en:
application: application:
header: header:
sign_out: Sign Out sign_out: Sign Out
broadcasts:
edit:
heading: Edit Broadcast
update:
notice: The broadcast has been updated
task_requests: task_requests:
index: index:
empty: Task requests will appear here empty: Task requests will appear here
@@ -224,8 +218,6 @@ en:
broadcast: broadcast:
actions: actions:
manage: Manage manage: Manage
broadcast_recordings:
confirm_hide: Are you sure you want to hide this recording from everyone?
create: create:
notice: A live stream has been created notice: A live stream has been created
destroy: destroy:
@@ -270,6 +262,9 @@ en:
stream_multiple_cameras: Stream multiple cameras at one time stream_multiple_cameras: Stream multiple cameras at one time
update: 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 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: bulk_taggings:
new_bulk_tag_modal: new_bulk_tag_modal:
submit: Add submit: Add
@@ -519,8 +514,6 @@ en:
person_last_name: Last name person_last_name: Last name
person_name: Name person_name: Name
person_phone: Phone number person_phone: Phone number
contract_template:
amendment_clause: Additional Contract Clause
location_release: location_release:
address_city: City address_city: City
address_country: Country address_country: Country
@@ -541,27 +534,6 @@ en:
person_last_name: Owner last name person_last_name: Owner last name
material_release: material_release:
description: Description of licensed material description: Description of licensed material
guardian_2_address_city: Guardian 2 city
guardian_2_address_country: Guardian 2 country
guardian_2_address_state: Guardian 2 state
guardian_2_address_street1: Guardian 2 address
guardian_2_address_street2: Guardian 2 address (Line 2)
guardian_2_address_zip: Guardian 2 zip code
guardian_2_email: Guardian 2 email
guardian_2_first_name: Guardian 2 first name
guardian_2_last_name: Guardian 2 last name
guardian_2_phone: Guardian 2 phone
guardian_address_city: Guardian city
guardian_address_country: Guardian country
guardian_address_state: Guardian state
guardian_address_street1: Guardian address
guardian_address_street2: Guardian address (Line 2)
guardian_address_zip: Guardian zip code
guardian_email: Guardian email
guardian_first_name: Guardian first name
guardian_last_name: Guardian last name
guardian_phone: Guardian phone
minor: Is the person a minor?
name: Name of licensed material name: Name of licensed material
person_address: Address person_address: Address
person_address_city: City person_address_city: City
@@ -852,18 +824,16 @@ en:
empty: Location Releases will appear here empty: Location Releases will appear here
table_headers: table_headers:
address: Address address: Address
amendment_signed: Additional Clause
approved: Approved approved: Approved
location_info: Location Info name: Location Name
notes: Notes notes: Notes
owner_info: Owner Info
signed_at: Date Signed signed_at: Date Signed
tags: Tags tags: Tags
location_release: location_release:
actions: actions:
manage: Manage manage: Manage
review: Review review: Review
sign_amendment: Sign Additional Clause sign_amendment: Sign Amendment
messages: messages:
amendment_not_signed_tooltip: Amendment not yet signed amendment_not_signed_tooltip: Amendment not yet signed
amendment_signed_tooltip: Amendment Signed amendment_signed_tooltip: Amendment Signed
@@ -883,18 +853,10 @@ en:
form: form:
contract_and_rights: contract_and_rights:
heading: 3 of 4 Contract & Exploitable Rights heading: 3 of 4 Contract & Exploitable Rights
guardian_2_info:
heading: Second Guardian Information (if company requires)
guardian_info:
heading: Guardian Information
material_details: material_details:
heading: 1 of 3 Material Details heading: 1 of 3 Material Details
photos: photos:
dropzone_label: Tap to take a photo of Licensed Material (optional) dropzone_label: Tap to take a photo of Licensed Material (optional)
guardian_2_photo:
heading: Second Guardian Photo
guardian_photo:
heading: Guardian Photo
heading: 4 of 4 Photos heading: 4 of 4 Photos
signer_details: signer_details:
heading: 2 of 4 Licensor/Owner Details heading: 2 of 4 Licensor/Owner Details
@@ -907,7 +869,6 @@ en:
approved: Approved approved: Approved
name: Name name: Name
notes: Notes notes: Notes
owner_info: Owner Info
signed_at: Date Signed signed_at: Date Signed
tags: Tags tags: Tags
material_release: material_release:
@@ -1146,11 +1107,10 @@ en:
amendment_signed_message: Release amendment signed successfully! Thank you amendment_signed_message: Release amendment signed successfully! Thank you
new: new:
amendment: amendment:
heading: Additional Clause heading: Amendment
copy_url: Copy sign amendment URL copy_url: Copy sign amendment URL
signature: signature:
heading: Signature heading: Signature
signed_contract_preview: Signed Contract Preview
appearance_releases: appearance_releases:
create: create:
notice: Your release has been signed. Thank you! notice: Your release has been signed. Thank you!
@@ -1224,27 +1184,10 @@ en:
cancel: Cancel cancel: Cancel
contact_info: contact_info:
heading: Licensor/Owner Contact Information heading: Licensor/Owner Contact Information
guardian_2_info:
heading: Second Guardian Information (if company requires)
guardian_2_photo:
heading: Second Guardian Photo
instructions: >
Lastly, it's time for second guardian to take a selfie photo! Please remove your hat and sunglasses (regular eyewear is ok), make sure that you are the only person in the photo, look straight into the camera, and say Cheese!
guardian_clause:
heading: Guardian Clause
guardian_info:
heading: Guardian Information
guardian_photo:
heading: Guardian Photo
instructions: >
Lastly, it's time for guardian to take a selfie photo! Please remove your hat and sunglasses (regular eyewear is ok), make sure that you are the only person in the photo, look straight into the camera, and say Cheese!
legal: legal:
heading: Legal heading: Legal
photo: photo:
heading: Photos heading: Photos
no_photo: No photo yet
take_photo: Take Photo
warning: If your photo appears sideways, it will be autocorrected when you submit your release.
release_info: release_info:
heading: Release Information heading: Release Information
signature: signature:
@@ -1614,3 +1557,9 @@ en:
edit: Edit edit: Edit
report: Report report: Report
generating: Generating... 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

View File

@@ -21,7 +21,6 @@ es:
notes: Notes (ES) notes: Notes (ES)
signed_at: Date Signed (ES) signed_at: Date Signed (ES)
tags: Tags (ES) tags: Tags (ES)
owner_info: Owner Info (ES)
activerecord: activerecord:
attributes: attributes:
appearance_release: appearance_release:
@@ -121,6 +120,9 @@ es:
stream_multiple_cameras: Stream multiple cameras at one time stream_multiple_cameras: Stream multiple cameras at one time
update: 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 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: contract_templates:
blank_contracts: blank_contracts:
create: create:
@@ -286,31 +288,6 @@ es:
person_email: Dirección de correo electrónico person_email: Dirección de correo electrónico
person_name: Nómbre person_name: Nómbre
person_phone: Número de teléfono person_phone: Número de teléfono
contract_template:
amendment_clause: Additional Contract Clause (ES)
material_release:
guardian_2_address_city: Guardian 2 city (ES)
guardian_2_address_country: Guardian 2 country (ES)
guardian_2_address_state: Guardian 2 state (ES)
guardian_2_address_street1: Guardian 2 address (ES)
guardian_2_address_street2: Guardian 2 address (Line 2) (ES)
guardian_2_address_zip: Guardian 2 zip code (ES)
guardian_2_email: Guardian 2 email (ES)
guardian_2_first_name: Guardian 2 first name (ES)
guardian_2_last_name: Guardian 2 last name (ES)
guardian_2_phone: Guardian 2 phone (ES)
guardian_address_city: Guardian city (ES)
guardian_address_country: Guardian country (ES)
guardian_address_state: Guardian state (ES)
guardian_address_street1: Dirección del tutor legal
guardian_address_street2: Dirección del tutor legal (Línea 2)
guardian_address_zip: Guardian zip code (ES)
guardian_email: Guardian email (ES)
guardian_first_name: Guardian first name (ES)
guardian_last_name: Guardian last name (ES)
guardian_name: Nómbre del tutor legal
guardian_phone: Número de teléfono del tutor legal
minor: El firmante es un menor
medical_release: medical_release:
guardian_2_address_city: Guardian 2 city (ES) guardian_2_address_city: Guardian 2 city (ES)
guardian_2_address_country: Guardian 2 country (ES) guardian_2_address_country: Guardian 2 country (ES)
@@ -399,8 +376,6 @@ es:
contract_template: contract_template:
update: Save changes (ES) update: Save changes (ES)
create: 'Crear %{model}' create: 'Crear %{model}'
material_release:
create: Import Release (ES)
medical_release: medical_release:
update: Approve (ES) update: Approve (ES)
update: 'Actualizar %{model}' update: 'Actualizar %{model}'
@@ -411,35 +386,23 @@ es:
index: index:
table_headers: table_headers:
address: Address (ES) address: Address (ES)
amendment_signed: Additional Clause (ES)
notes: Notes (ES) notes: Notes (ES)
signed_at: Date Signed (ES) signed_at: Date Signed (ES)
tags: Tags (ES) tags: Tags (ES)
location_release: location_release:
actions: actions:
sign_amendment: Sign Additional Clause (ES) sign_amendment: Sign Amendment (ES)
messages: messages:
amendment_not_signed_tooltip: Amendment not yet signed (ES) amendment_not_signed_tooltip: Amendment not yet signed (ES)
amendment_signed_tooltip: Amendment Signed (ES) amendment_signed_tooltip: Amendment Signed (ES)
material_releases: material_releases:
create:
notice: The acquired media release has been created (ES)
form: form:
guardian_2_info:
heading: Guardian Information (if company requires) [ES]
guardian_info:
heading: Guardian Information (ES)
photos: photos:
dropzone_label: Tap to take a photo of Licensed Material (optional) (ES) dropzone_label: Tap to take a photo of Licensed Material (optional) (ES)
guardian_2_photo:
heading: Second Guardian Photo
guardian_photo:
heading: Guardian Photo
index: index:
table_headers: table_headers:
name: Name (ES) name: Name (ES)
notes: Notes (ES) notes: Notes (ES)
owner_info: Owner Info
signed_at: Date Signed (ES) signed_at: Date Signed (ES)
tags: Tags (ES) tags: Tags (ES)
medical_releases: medical_releases:
@@ -504,11 +467,10 @@ es:
amendment_signed_message: Release amendment signed successfully! Thank you (ES) amendment_signed_message: Release amendment signed successfully! Thank you (ES)
new: new:
amendment: amendment:
heading: Additional Clause (ES) heading: Amendment
copy_url: Copy sign amendment URL (ES) copy_url: Copy sign amendment URL (ES)
signature: signature:
heading: Signature (ES) heading: Signature (ES)
signed_contract_preview: Signed Contract Preview (ES)
appearance_releases: appearance_releases:
create: create:
notice: La autorización está firmada. ¡Gracias! notice: La autorización está firmada. ¡Gracias!
@@ -548,25 +510,8 @@ es:
heading: Photos (ES) heading: Photos (ES)
material_releases: material_releases:
new: new:
guardian_2_info:
heading: Second Guardian Information (if company requires) [ES]
guardian_2_photo:
heading: Second Guardian Photo (ES)
instructions: >
(ES) Lastly, it's time for second guardian to take a selfie photo! Please remove your hat and sunglasses (regular eyewear is ok), make sure that you are the only person in the photo, look straight into the camera, and say Cheese! (ES)
guardian_clause:
heading: Guardian Clause (ES)
guardian_info:
heading: Guardian Information (ES)
guardian_photo:
heading: Guardian Photo (ES)
instructions: >
(ES) Lastly, it's time for guardian to take a selfie photo! Please remove your hat and sunglasses (regular eyewear is ok), make sure that you are the only person in the photo, look straight into the camera, and say Cheese! (ES)
photo: photo:
heading: Photos (ES) heading: Photos (ES)
no_photo: No photo yet (ES)
take_photo: Take Photo (ES)
warning: If your photo appears sideways, it will be autocorrected when you submit your release. (ES)
medical_releases: medical_releases:
new: new:
guardian_2_info: guardian_2_info:
@@ -688,3 +633,11 @@ es:
production_elements_logs: Production Elements Logs, and more (ES) production_elements_logs: Production Elements Logs, and more (ES)
reduces_labor_cost: Reduces labor costs (ES) reduces_labor_cost: Reduces labor costs (ES)
simplifies_cue_sheets: Simplifies Music Cue Sheets, Graphic Cue Sheets (ES) simplifies_cue_sheets: Simplifies Music Cue Sheets, Graphic Cue Sheets (ES)
conference_meetings:
show:
alert:
not_authenticated: ""
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)

View File

@@ -4,6 +4,8 @@ require 'sidekiq/web'
Rails.application.routes.draw do Rails.application.routes.draw do
AVAILABLE_LOCALES_REGEX = /#{I18n.available_locales.join("|")}/.freeze AVAILABLE_LOCALES_REGEX = /#{I18n.available_locales.join("|")}/.freeze
get 'auth/azure_ad/callback', to: 'callbacks#create'
concern :confirmable do concern :confirmable do
resources :video_release_confirmations, only: [:new, :create, :destroy] resources :video_release_confirmations, only: [:new, :create, :destroy]
end end
@@ -35,7 +37,6 @@ Rails.application.routes.draw do
resource :masquerade, only: :create resource :masquerade, only: :create
end end
resources :task_requests, only: [:index, :edit, :update, :show] resources :task_requests, only: [:index, :edit, :update, :show]
resources :broadcasts, only: [:edit, :update]
root to: "accounts#index", as: :signed_in_root root to: "accounts#index", as: :signed_in_root
end end
@@ -100,8 +101,7 @@ Rails.application.routes.draw do
member do member do
delete :destroy_file delete :destroy_file
end end
resource :zoom_meeting, only: [:show] resource :conference_meeting, only: [:show]
resources :broadcast_recordings, only: :destroy
end end
resources :directories, except: [:index] do resources :directories, except: [:index] do
member do member do
@@ -160,7 +160,6 @@ Rails.application.routes.draw do
scope 'v1' do scope 'v1' do
get 'sync' => 'sync#index' get 'sync' => 'sync#index'
post 'user_token' => 'user_token#create' post 'user_token' => 'user_token#create'
post 'users' => 'users#create'
resource :profiles, only: [:show] resource :profiles, only: [:show]
resources :projects, only: [:index] do resources :projects, only: [:index] do
resources :broadcasts, only: [:index, :show, :update] resources :broadcasts, only: [:index, :show, :update]

View File

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

View File

@@ -1,25 +0,0 @@
class AddGuardiansFieldsToMaterialReleases < ActiveRecord::Migration[6.0]
def change
add_column :material_releases, :minor, :boolean, default: false
add_column :material_releases, :guardian_first_name, :string
add_column :material_releases, :guardian_last_name, :string
add_column :material_releases, :guardian_email, :string
add_column :material_releases, :guardian_phone, :string
add_column :material_releases, :guardian_address_street1, :string
add_column :material_releases, :guardian_address_street2, :string
add_column :material_releases, :guardian_address_city, :string
add_column :material_releases, :guardian_address_state, :string
add_column :material_releases, :guardian_address_zip, :string
add_column :material_releases, :guardian_address_country, :string
add_column :material_releases, :guardian_2_first_name, :string
add_column :material_releases, :guardian_2_last_name, :string
add_column :material_releases, :guardian_2_email, :string
add_column :material_releases, :guardian_2_phone, :string
add_column :material_releases, :guardian_2_address_street1, :string
add_column :material_releases, :guardian_2_address_street2, :string
add_column :material_releases, :guardian_2_address_city, :string
add_column :material_releases, :guardian_2_address_state, :string
add_column :material_releases, :guardian_2_address_zip, :string
add_column :material_releases, :guardian_2_address_country, :string
end
end

View File

@@ -1,7 +0,0 @@
class AddStreamAndKeyOverrideToBroadcasts < ActiveRecord::Migration[6.0]
def change
add_column :broadcasts, :stream_url_override, :string
add_column :broadcasts, :stream_key_override, :string
add_column :broadcasts, :youtube_uid, :string
end
end

View File

@@ -1,5 +0,0 @@
class RemoveYoutubeUidFromBroadcasts < ActiveRecord::Migration[6.0]
def change
remove_column :broadcasts, :youtube_uid, :string
end
end

View File

@@ -1,5 +0,0 @@
class AddDirectorModeVideoEmbedToBroadcasts < ActiveRecord::Migration[6.0]
def change
add_column :broadcasts, :director_mode_video_embed, :text
end
end

View File

@@ -0,0 +1,7 @@
class AddMicrosoftTokensToUsers < ActiveRecord::Migration[6.0]
def change
add_column :users, :microsoft_access_token, :string
add_column :users, :microsoft_refresh_token, :string
add_column :users, :microsoft_token_expires_at, :integer
end
end

View File

@@ -0,0 +1,5 @@
class AddMicrosoftUserIdToUsers < ActiveRecord::Migration[6.0]
def change
add_column :users, :microsoft_user_id, :string
end
end

View File

@@ -0,0 +1,6 @@
class AddConferenceDetailsToBroadcasts < ActiveRecord::Migration[6.0]
def change
add_column :broadcasts, :conference_option, :string
add_column :broadcasts, :conference_join_url, :string
end
end

View File

@@ -9,20 +9,6 @@ SET xmloption = content;
SET client_min_messages = warning; SET client_min_messages = warning;
SET row_security = off; SET row_security = off;
--
-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: -
--
CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
--
-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: -
--
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
-- --
-- Name: fuzzystrmatch; Type: EXTENSION; Schema: -; Owner: - -- Name: fuzzystrmatch; Type: EXTENSION; Schema: -; Owner: -
-- --
@@ -536,8 +522,7 @@ CREATE TABLE public.broadcast_recordings (
file_name character varying NOT NULL, file_name character varying NOT NULL,
created_at timestamp(6) without time zone NOT NULL, created_at timestamp(6) without time zone NOT NULL,
updated_at timestamp(6) without time zone NOT NULL, updated_at timestamp(6) without time zone NOT NULL,
duration double precision, duration double precision
hidden boolean DEFAULT false
); );
@@ -578,9 +563,8 @@ CREATE TABLE public.broadcasts (
streamer_status integer DEFAULT 0, streamer_status integer DEFAULT 0,
shoot_location_time_zone character varying DEFAULT 'UTC'::character varying, shoot_location_time_zone character varying DEFAULT 'UTC'::character varying,
full_live_stream_playback_uid character varying, full_live_stream_playback_uid character varying,
stream_url_override character varying, conference_option character varying,
stream_key_override character varying, conference_join_url character varying
director_mode_video_embed text
); );
@@ -1020,28 +1004,7 @@ CREATE TABLE public.material_releases (
person_last_name character varying, person_last_name character varying,
approved_by_user_name text, approved_by_user_name text,
approved_by_user_email text, approved_by_user_email text,
approved_at timestamp without time zone, approved_at timestamp without time zone
minor boolean DEFAULT false,
guardian_first_name character varying,
guardian_last_name character varying,
guardian_email character varying,
guardian_phone character varying,
guardian_address_street1 character varying,
guardian_address_street2 character varying,
guardian_address_city character varying,
guardian_address_state character varying,
guardian_address_zip character varying,
guardian_address_country character varying,
guardian_2_first_name character varying,
guardian_2_last_name character varying,
guardian_2_email character varying,
guardian_2_phone character varying,
guardian_2_address_street1 character varying,
guardian_2_address_street2 character varying,
guardian_2_address_city character varying,
guardian_2_address_state character varying,
guardian_2_address_zip character varying,
guardian_2_address_country character varying
); );
@@ -1479,6 +1442,7 @@ CREATE TABLE public.settings (
-- --
CREATE SEQUENCE public.settings_id_seq CREATE SEQUENCE public.settings_id_seq
AS integer
START WITH 1 START WITH 1
INCREMENT BY 1 INCREMENT BY 1
NO MINVALUE NO MINVALUE
@@ -1514,6 +1478,7 @@ CREATE TABLE public.taggings (
-- --
CREATE SEQUENCE public.taggings_id_seq CREATE SEQUENCE public.taggings_id_seq
AS integer
START WITH 1 START WITH 1
INCREMENT BY 1 INCREMENT BY 1
NO MINVALUE NO MINVALUE
@@ -1544,6 +1509,7 @@ CREATE TABLE public.tags (
-- --
CREATE SEQUENCE public.tags_id_seq CREATE SEQUENCE public.tags_id_seq
AS integer
START WITH 1 START WITH 1
INCREMENT BY 1 INCREMENT BY 1
NO MINVALUE NO MINVALUE
@@ -1791,7 +1757,11 @@ CREATE TABLE public.users (
remember_created_at timestamp without time zone, remember_created_at timestamp without time zone,
first_name character varying, first_name character varying,
last_name character varying, last_name character varying,
time_zone character varying DEFAULT 'UTC'::character varying NOT NULL time_zone character varying DEFAULT 'UTC'::character varying NOT NULL,
microsoft_access_token character varying,
microsoft_refresh_token character varying,
microsoft_token_expires_at integer,
microsoft_user_id character varying
); );
@@ -4002,11 +3972,9 @@ INSERT INTO "schema_migrations" (version) VALUES
('20200720051634'), ('20200720051634'),
('20200720131309'), ('20200720131309'),
('20200721140821'), ('20200721140821'),
('20200724084722'),
('20200725231419'), ('20200725231419'),
('20200727143209'), ('20200810140331'),
('20200730050903'), ('20200812161119'),
('20200803145912'), ('20200817233053');
('20200803150138');

124
lib/azure_ad.rb Normal file
View File

@@ -0,0 +1,124 @@
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

View File

@@ -1,7 +0,0 @@
module Knock
class AuthTokenController < ApplicationController
skip_before_action :authenticate
alias authenticate_with_token authenticate
before_action :authenticate_with_token
end
end

107
lib/microsoft_graph.rb Normal file
View File

@@ -0,0 +1,107 @@
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

View File

@@ -35,7 +35,7 @@ RSpec.describe BroadcastsChannel, type: :channel do
describe '#stream_recording_ready' do describe '#stream_recording_ready' do
it 'broadcasts to the channel with the right data' do it 'broadcasts to the channel with the right data' do
create_list(:broadcast_recording, 1, broadcast: broadcast) create_list(:broadcast_recording, 1, broadcast: broadcast)
recordings = broadcast.broadcast_recordings.visible.paginate(page: 1) recordings = broadcast.broadcast_recordings.paginate(page: 1)
flash_message = OpenStruct.new(notice: 'Hello world', alert: nil) flash_message = OpenStruct.new(notice: 'Hello world', alert: nil)
flash_content = ApplicationController.render partial: 'application/flash', locals: { flash: flash_message } flash_content = ApplicationController.render partial: 'application/flash', locals: { flash: flash_message }
recordings_content = ApplicationController.render partial: 'broadcasts/broadcast_recordings', locals: { recordings: recordings, broadcast: broadcast } recordings_content = ApplicationController.render partial: 'broadcasts/broadcast_recordings', locals: { recordings: recordings, broadcast: broadcast }

View File

@@ -116,16 +116,6 @@ RSpec.describe Admin::AccountsController, type: :controller do
expect(response.body).to have_link("2", href: admin_account_path(current_user.primary_account, page: 2)) expect(response.body).to have_link("2", href: admin_account_path(current_user.primary_account, page: 2))
end end
it "paginates the broadcast list" do
allow(MuxLiveStream).to receive(:new).and_return(double(id: "id", key: "key", playback_id: "playback_id"))
project = create(:project, account: current_user.primary_account)
create_list(:broadcast, 20, project: project )
get :show, params: { id: current_user.primary_account }
expect(response.body).to have_link("2", href: admin_account_path(current_user.primary_account, page: 2))
end
it "filters the videos by a query param" do it "filters the videos by a query param" do
project = create(:project, account: current_user.primary_account) project = create(:project, account: current_user.primary_account)
create(:video, project: project, name: "First video") create(:video, project: project, name: "First video")

View File

@@ -1,77 +0,0 @@
require "rails_helper"
RSpec.describe Admin::BroadcastsController, type: :controller do
render_views
let!(:current_user) { create(:user, :admin) }
before do
sign_in(current_user)
allow(MuxLiveStream).to receive(:new).and_return(double(id: "id", key: "key", playback_id: "playback_id"))
end
describe "#edit" do
let(:broadcast) { create(:broadcast) }
it "returns a successful response" do
get :edit, params: { id: broadcast }
expect(response).to be_successful
end
it "assigns broadcast" do
get :edit, params: { id: broadcast }
expect(assigns(:broadcast)).to eq broadcast
end
end
describe "#update" do
let(:broadcast) { create(:broadcast) }
it "redirects to broadcasts page" do
patch :update, params: { id: broadcast, broadcast: broadcast_update_params }
expect(response).to be_redirect
expect(response).to redirect_to [:admin, broadcast.project.account]
end
it "sets a flash notice" do
patch :update, params: { id: broadcast, broadcast: broadcast_update_params }
expect(flash.notice).to eq "The broadcast has been updated"
end
it "updates the broadcast record" do
patch :update, params: { id: broadcast, broadcast: broadcast_update_params }
expect(assigns(:broadcast)).to have_attributes(
stream_url_override: "https://example.com/streams/abcd",
stream_key_override: "abcdef",
)
end
context "when record cannot be saved" do
before do
allow_any_instance_of(Broadcast).to receive(:update).and_return(false)
end
it "re-displays the form" do
patch :update, params: { id: broadcast, broadcast: broadcast_update_params }
expect(response).to be_successful
expect(flash.notice).to be_nil
end
end
end
private
def broadcast_update_params
{
stream_url_override: "https://example.com/streams/abcd",
stream_key_override: "abcdef",
director_mode_video_embed: "<iframe>Video player</iframe>",
}
end
end

View File

@@ -94,7 +94,7 @@ RSpec.describe Api::SyncController, type: :controller do
expect(appearance_releases.first).to include('guardian_photo') expect(appearance_releases.first).to include('guardian_photo')
expect(talent_releases.first).to include('guardian_photo') expect(talent_releases.first).to include('guardian_photo')
expect(location_releases.first).not_to include('guardian_photo') expect(location_releases.first).not_to include('guardian_photo')
expect(material_releases.first).to include('guardian_photo') expect(material_releases.first).not_to include('guardian_photo')
end end
it 'guardian photo has same format as other photos' do it 'guardian photo has same format as other photos' do

View File

@@ -1,63 +0,0 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Api::UserTokenController, type: :request do
let(:current_user) { create(:user) }
describe '#create' do
it 'returns error if credentials are not corrent and does not set cookie' do
post create_endpoint, params: wrong_auth_params
expect(response).to be_successful
expect(response.body).to match record_not_found
expect(cookie_data).to eq nil
end
it 'sends token and cookie if credentials are correct' do
post create_endpoint, params: correct_auth_params
expect(response).to be_successful
expect(response.body).not_to match record_not_found
expect(response.body).to match token_response
expect(cookie_data).not_to eq nil
end
end
private
def wrong_auth_params
{
auth: {
email: 'wrong_email@api-test.com',
password: 'password'
}
}
end
def correct_auth_params
{
auth: {
email: current_user.email,
password: 'password'
}
}
end
def create_endpoint
'/api/v1/user_token'
end
def record_not_found
/Record not found/
end
def token_response
/jwt/
end
def cookie_data
cookies[:_easy_release_session]
end
end

View File

@@ -1,78 +0,0 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Api::UsersController, type: :controller do
before do
ENV['CUSTOM_API_TOKEN'] = "custom_token"
end
describe '#create' do
context 'Invalid token' do
it 'Returns 401 (Unauthorized) status if token is not valid' do
post :create
expect(response).not_to be_successful
expect(response).to have_http_status(401)
end
end
context 'Valid token' do
before :each do
controller.request.env['HTTP_AUTHORIZATION'] = 'Bearer custom_token'
end
it 'Returns Server error if user param is missing' do
user_count = User.all.count
expect do
post :create
end.to raise_exception ActionController::ParameterMissing
expect(User.all.count).to eq user_count
end
it 'Returns Server Error if email or password is missing' do
user_count = User.all.count
expect do
post :create, params: { user: { email: "a@b.com" } }
end.to raise_exception ActionController::ParameterMissing
expect do
post :create, params: { user: { password: "123" } }
end.to raise_exception ActionController::ParameterMissing
expect(User.all.count).to eq user_count
end
it 'Returns Server Error if body contains not permitted params' do
user_count = User.all.count
expect do
post :create, params: { user: { email: "a@b.com", password: "123", admin: true } }
end.to raise_exception ActionController::UnpermittedParameters
expect(User.all.count).to eq user_count
end
it 'Creates user if body contains correct params' do
expect do
post :create, params: { user: { email: "a@b.com", password: "123" } }
end.to change(User, :count).by(1)
expect(response).to be_successful
end
it 'Nothing changes if existing email is used' do
create(:user, email: "a@b.com")
expect do
post :create, params: { user: { email: "a@b.com", password: "123" } }
end.not_to change(User, :count)
expect(response).to be_successful
end
end
end
end

View File

@@ -1,30 +0,0 @@
require 'rails_helper'
RSpec.describe BroadcastRecordingsController, type: :controller do
render_views
let(:user) { create(:user) }
let(:account) { user.primary_account }
let(:project) { create(:project, account: user.primary_account) }
before do
sign_in user
end
describe "#destroy" do
let(:broadcast) { create(:broadcast, project: project, name: "New Broadcast") }
let(:recording) { create(:broadcast_recording, broadcast: broadcast) }
before do
allow(MuxLiveStream).to receive(:new).and_return(double(id: "id", key: "key", playback_id: "playback_id"))
end
it "hides the broadcast recording" do
expect(recording.hidden).to be false
post :destroy, params: { project_id: project, broadcast_id: broadcast, id: recording }, xhr: true
expect(recording.reload.hidden).to be true
end
end
end

View File

@@ -131,16 +131,25 @@ RSpec.describe BroadcastsController, type: :controller do
expect(response.body).to have_xpath "//input[@readonly][@value='#{broadcast_url(broadcast.token)}']" expect(response.body).to have_xpath "//input[@readonly][@value='#{broadcast_url(broadcast.token)}']"
end end
it "displays zoom meeting button" do it "displays zoom meeting button for zoom conference option" do
get :show, params: { project_id: project.id, id: broadcast.id } get :show, params: { project_id: project.id, id: broadcast.id }
expect(response.body).to have_link("Video Conference", href: project_broadcast_zoom_meeting_url(project, broadcast)) expect(response.body).to have_content 'Zoom'
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)
end end
it "assigns required variables" do it "assigns required variables" do
get :show, params: { project_id: project.id, id: broadcast.id } get :show, params: { project_id: project.id, id: broadcast.id }
expect(assigns(:conference_url)).to eq project_broadcast_zoom_meeting_url(project, broadcast) expect(assigns(:conference_url)).to eq project_broadcast_conference_meeting_url(project, broadcast)
expect(assigns(:broadcast)).to eq broadcast expect(assigns(:broadcast)).to eq broadcast
end end
@@ -184,35 +193,6 @@ RSpec.describe BroadcastsController, type: :controller do
expect(response.body).to have_selector(".dropdown-menu a.dropdown-item", text: recording.download_file_name) expect(response.body).to have_selector(".dropdown-menu a.dropdown-item", text: recording.download_file_name)
end end
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>") }
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")
end
context "when director mode is enabled" do
it "shows the video embed" do
get :show, params: { project_id: project, id: broadcast, director_mode: true }
expect(response.body).to have_selector("iframe", text: "video player")
end
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")
end
end
end
end end
describe "#update" do describe "#update" do

View File

@@ -0,0 +1,76 @@
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")
allow(MuxLiveStream).to receive(:new).and_return OpenStruct.new(id: 'id', key: 'key', playback_id: 'playback_id')
end
describe "#show" do
before { sign_in user }
it "redirects to meeting start url 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

View File

@@ -1,30 +0,0 @@
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")
allow(MuxLiveStream).to receive(:new).and_return OpenStruct.new(id: 'id', key: 'key', playback_id: 'playback_id')
end
describe "#show" do
before { sign_in user }
it "redirects to meeting start url" do
get :show, params: { project_id: project.id, broadcast_id: broadcast.id }
expect(response).to redirect_to(meeting_start_url)
end
end
end

View File

@@ -4,22 +4,6 @@ FactoryBot.define do
name "Test Acquired Media Release" name "Test Acquired Media Release"
trait :with_address do
person_address_street1 "St1"
person_address_street2 "St2"
person_address_city "City"
person_address_state "State"
person_address_zip "123"
person_address_country "US"
end
trait :with_owner_info do
person_first_name "Jane"
person_last_name "Doe"
person_phone "100-555-1001"
person_email "owner@email.com"
end
trait :native do trait :native do
signature do signature do
path = Rails.root.join("spec", "fixtures", "files", "signature.png") path = Rails.root.join("spec", "fixtures", "files", "signature.png")

View File

@@ -3,7 +3,6 @@ FactoryBot.define do
association :broadcast association :broadcast
file_name "high.mp4" file_name "high.mp4"
asset_uid "asset_uid" asset_uid "asset_uid"
asset_playback_uid "asset_playback_uid" asset_playback_uid "asset_playback_uid"
hidden { false }
end end
end end

View File

@@ -2,11 +2,16 @@ FactoryBot.define do
factory :broadcast do factory :broadcast do
association :project association :project
name "My Live Stream" name "My Live Stream"
conference_option "zoom"
transient do transient do
skip_create_callback false skip_create_callback false
end end
trait :ms_teams_conference do
conference_option "ms_teams"
end
trait :with_stream do trait :with_stream do
stream_uid "mux_stream" stream_uid "mux_stream"
stream_key "mux_key" stream_key "mux_key"
@@ -16,17 +21,6 @@ FactoryBot.define do
streamer_status "idle" streamer_status "idle"
end end
trait :with_overriden_stream do
stream_uid "mux_stream"
stream_key "mux_key"
stream_playback_uid "mux_playback_id"
full_live_stream_playback_uid "full_live_stream_playback_uid"
status "created"
streamer_status "idle"
stream_url_override "overriden_stream_url"
stream_key_override "overriden_stream_key"
end
trait :with_files do trait :with_files do
files do files do
[ [

View File

@@ -4,20 +4,10 @@ FactoryBot.define do
name "Test Materials" name "Test Materials"
trait :with_address do
person_address_street1 "St1"
person_address_street2 "St2"
person_address_city "City"
person_address_state "State"
person_address_zip "123"
person_address_country "US"
end
trait :native do trait :native do
person_first_name "Jane" person_first_name "Jane"
person_last_name "Doe" person_last_name "Doe"
person_phone "100-555-1001" person_phone "100-555-1001"
person_email "owner@email.com"
signature do signature do
path = Rails.root.join("spec", "fixtures", "files", "signature.png") path = Rails.root.join("spec", "fixtures", "files", "signature.png")
@@ -25,16 +15,6 @@ FactoryBot.define do
end end
end end
trait :minor do
minor true
guardian_first_name "Guardian1"
guardian_last_name "First"
guardian_2_first_name "Guardian2"
guardian_2_last_name "Second"
guardian_phone "1111"
guardian_2_phone "2222"
end
trait :with_photo do trait :with_photo do
photos do photos do
path = Rails.root.join("spec", "fixtures", "files", "material_photo.png") path = Rails.root.join("spec", "fixtures", "files", "material_photo.png")

View File

@@ -178,7 +178,7 @@ RSpec.feature 'User manages contract templates', type: :feature do
expect(content_disposition).to include('inline') expect(content_disposition).to include('inline')
expect(pdf_body).to have_content('PREVIEW ONLY') expect(pdf_body).to have_content('PREVIEW ONLY')
expect(pdf_body).to have_content('Material Release') expect(pdf_body).to have_content('Material Release')
expect(pdf_body).to have_content('Guardian') expect(pdf_body).not_to have_content('Guardian')
end end
context 'preventing creation of release template with wrong fee value' do context 'preventing creation of release template with wrong fee value' do

View File

@@ -51,13 +51,6 @@ RSpec.feature "User manages project custom folders", type: :feature do
expect(page).to have_content("UPLOAD NEW FILES") expect(page).to have_content("UPLOAD NEW FILES")
expect do
click_button "Upload Files"
end.not_to raise_exception
expect(page).to have_content("UPLOAD NEW FILES")
expect(page).not_to have_content("The folder has been updated")
drop_file Rails.root.join(file_fixture("person_photo.png")), type: :dropzone drop_file Rails.root.join(file_fixture("person_photo.png")), type: :dropzone
click_button "Upload Files" click_button "Upload Files"

View File

@@ -165,24 +165,6 @@ feature "User managing acquired_media releases" do
sign_in current_user sign_in current_user
end end
scenario "index table shows owner info" do
release = create(:acquired_media_release, :with_owner_info, :with_address, project: project)
visit project_acquired_media_releases_path(project)
expect(page).to have_content owner_info_table_header
expect(page).to have_content release.person_first_name
expect(page).to have_content release.person_last_name
expect(page).to have_content release.person_phone
expect(page).to have_content release.person_email
expect(page).to have_content release.person_address_street1
expect(page).to have_content release.person_address_city
expect(page).to have_content release.person_address_state
expect(page).to have_content release.person_address_zip
expect(page).to have_content release.person_address_country
end
scenario "creating a release for an adult", js: true do scenario "creating a release for an adult", js: true do
visit new_project_acquired_media_release_path(project) visit new_project_acquired_media_release_path(project)
@@ -280,63 +262,62 @@ feature "User managing acquired_media releases" do
end end
scenario "creating, updating, destroying a release", js: true do scenario "creating, updating, destroying a release", js: true do
resize_window_to(1_000, 1_000) do release_data = {
release_data = { name: "Test Acquired Media Release",
name: "Test Acquired Media Release", applicable_media: ApplicableMedium.last.label,
applicable_media: ApplicableMedium.last.label, territory: Territory.last.label,
territory: Territory.last.label, term: Term.last.label,
term: Term.last.label, restriction: Restriction.first.label,
restriction: Restriction.first.label, restriction_text: "Not available in China",
restriction_text: "Not available in China", }
}
sign_in current_user sign_in current_user
visit new_project_acquired_media_release_path(project) visit new_project_acquired_media_release_path(project)
by "attaching only a contract" do by "attaching only a contract" do
attach_file contract_field, Rails.root.join(file_fixture("contract.pdf")), visible: false attach_file contract_field, Rails.root.join(file_fixture("contract.pdf")), visible: false
click_button create_release_button click_button create_release_button
expect(page).to have_invalid_field(acquired_media_name_field) expect(page).to have_invalid_field(acquired_media_name_field)
end
by "attaching files" do
drop_file Rails.root.join(file_fixture("video_file.mp4")), type: "file-info-dropzone"
click_button create_release_button
expect(page).to have_invalid_field(acquired_media_name_field)
end
by "filling out the remaining information" do
fill_in_release_fields release_data
click_button create_release_button
expect(page).to have_content(create_release_notice)
expect(page).to have_content("1")
click_on "Manage"
expect(page).to have_link("Download")
end
it_also "updates an existing release" do
click_link "Edit"
within ".dropzone" do
expect(page).to have_filename("video_file.mp4")
end end
by "attaching files" do expect(page).to have_filled_in_data(release_data)
drop_file Rails.root.join(file_fixture("video_file.mp4")), type: "file-info-dropzone"
click_button create_release_button
expect(page).to have_invalid_field(acquired_media_name_field) fill_in_release_fields name: "New name"
end drop_file Rails.root.join(file_fixture("person_photo.png")), type: "file-info-dropzone"
click_button update_release_button
by "filling out the remaining information" do expect(page).to have_content(update_release_notice)
fill_in_release_fields release_data expect(page).to have_content("New name")
click_button create_release_button expect(page).to have_content("2")
end
expect(page).to have_content(create_release_notice) it_also "deletes an existing release" do
expect(page).to have_content("1")
click_on "Manage"
expect(page).to have_link("Download")
end
it_also "updates an existing release" do
click_link "Edit"
within ".dropzone" do
expect(page).to have_filename("video_file.mp4")
end
expect(page).to have_filled_in_data(release_data)
fill_in_release_fields name: "New name"
drop_file Rails.root.join(file_fixture("person_photo.png")), type: "file-info-dropzone"
click_button update_release_button
expect(page).to have_content(update_release_notice)
expect(page).to have_content("New name")
expect(page).to have_content("2")
end
it_also "deletes an existing release" do
click_button "Manage" click_button "Manage"
accept_alert do accept_alert do
click_link "Delete" click_link "Delete"
@@ -344,7 +325,6 @@ feature "User managing acquired_media releases" do
expect(page).not_to have_content("New name") expect(page).not_to have_content("New name")
end end
end
end end
scenario "viewing the contract PDF for an adult" do scenario "viewing the contract PDF for an adult" do
@@ -856,8 +836,4 @@ feature "User managing acquired_media releases" do
def successful_import_message def successful_import_message
t 'acquired_media_releases.create.notice' t 'acquired_media_releases.create.notice'
end end
def owner_info_table_header
t 'acquired_media_releases.index.table_headers.owner_info'
end
end end

View File

@@ -3,7 +3,6 @@
require 'rails_helper' require 'rails_helper'
feature 'User managing broadcasts' do feature 'User managing broadcasts' do
let(:current_user) { create(:user, :manager) } let(:current_user) { create(:user, :manager) }
let(:project) { create(:project, members: current_user, account: current_user.primary_account) } let(:project) { create(:project, members: current_user, account: current_user.primary_account) }
@@ -25,6 +24,7 @@ feature 'User managing broadcasts' do
by 'filling out the form' do by 'filling out the form' do
fill_in broadcast_name_field, with: 'My Broadcast' fill_in broadcast_name_field, with: 'My Broadcast'
select_conference_option('Zoom')
select_time_zone("New Delhi") select_time_zone("New Delhi")
end end
@@ -51,7 +51,7 @@ feature 'User managing broadcasts' do
scenario 'visit show page of broadcast', js: true do scenario 'visit show page of broadcast', js: true do
broadcast = create(:broadcast, :with_stream, :with_files, project: project) broadcast = create(:broadcast, :with_stream, :with_files, project: project)
recording = create(:broadcast_recording, broadcast: broadcast, asset_uid: "asset_uid_1") recording = create(:broadcast_recording, broadcast: broadcast)
visit project_broadcast_path(project, broadcast) visit project_broadcast_path(project, broadcast)
@@ -205,24 +205,6 @@ feature 'User managing broadcasts' do
end end
end end
scenario 'project manager can hide broadcast recordings', js: true do
broadcast = create(:broadcast, :with_stream, :with_files, project: project)
recording = create(:broadcast_recording, broadcast: broadcast, asset_uid: "another_asset_uid")
visit project_broadcast_path(project, broadcast)
click_on 'Previous Sessions'
expect(page).to have_content(recording.download_file_name)
expect(page).to have_content('Hide')
accept_alert do
click_link "Hide"
end
expect(page).not_to have_content(recording.download_file_name)
expect(page).to have_content("Recording of the live stream will appear here")
end
context 'When the user is associate' do context 'When the user is associate' do
let(:current_user) { create(:user, :associate) } let(:current_user) { create(:user, :associate) }
@@ -240,17 +222,6 @@ feature 'User managing broadcasts' do
expect(page).to have_content delete_file_button, count: 0 expect(page).to have_content delete_file_button, count: 0
end end
scenario 'associate does not see hide button in front of recording' do
broadcast = create(:broadcast, :with_stream, :with_files, project: project)
recording = create(:broadcast_recording, broadcast: broadcast, asset_uid: "another_asset_uid")
visit project_broadcast_path(project, broadcast)
click_on 'Previous Sessions'
expect(page).to have_content(recording.download_file_name)
expect(page).not_to have_content('Hide')
end
end end
context 'When the user is account manager' do context 'When the user is account manager' do
@@ -277,24 +248,6 @@ feature 'User managing broadcasts' do
expect(page).to have_content delete_file_button, count: 2 expect(page).to have_content delete_file_button, count: 2
expect(Broadcast.find(broadcast.id).files.count).to eq 2 expect(Broadcast.find(broadcast.id).files.count).to eq 2
end end
scenario 'account manager can hide broadcast recordings', js: true do
broadcast = create(:broadcast, :with_stream, :with_files, project: project)
recording = create(:broadcast_recording, broadcast: broadcast, asset_uid: "another_asset_uid")
visit project_broadcast_path(project, broadcast)
click_on 'Previous Sessions'
expect(page).to have_content(recording.download_file_name)
expect(page).to have_content('Hide')
accept_alert do
click_link "Hide"
end
expect(page).not_to have_content(recording.download_file_name)
expect(page).to have_content("Recording of the live stream will appear here")
end
end end
end end
@@ -315,6 +268,12 @@ feature 'User managing broadcasts' do
end end
end end
def select_conference_option(value)
if value.present?
select value, from: "broadcast[conference_option]"
end
end
def click_checkboxes def click_checkboxes
all('input[type="checkbox"]')[0].click all('input[type="checkbox"]')[0].click
all('input[type="checkbox"]')[1].click all('input[type="checkbox"]')[1].click

View File

@@ -87,7 +87,7 @@ feature "User managing location releases" do
visit new_account_project_contract_template_location_release_amendment_path(project.account, project, contract_template, release) visit new_account_project_contract_template_location_release_amendment_path(project.account, project, contract_template, release)
expect(page).to have_content amendments_heading.upcase expect(page).to have_content amendments_heading
fill_in amendment_signer_name_field, with: 'Big Signer' fill_in amendment_signer_name_field, with: 'Big Signer'
draw_signature file_fixture("signature.png"), amendment_signature_field draw_signature file_fixture("signature.png"), amendment_signature_field
@@ -127,14 +127,6 @@ feature "User managing location releases" do
sign_in current_user sign_in current_user
end end
scenario "listing all releases, table have correct headers", js:true do
ct = create(:contract_template, :with_amendment_clause, project: project)
create(:location_release, :native, project: project, contract_template: ct)
visit project_location_releases_path(project)
table_headers.each { |s| expect(page).to have_content s }
end
scenario "creating a release", js: true do scenario "creating a release", js: true do
visit new_project_location_release_path(project) visit new_project_location_release_path(project)
@@ -250,7 +242,7 @@ feature "User managing location releases" do
new_window = window_opened_by { click_link sign_amendment_link } new_window = window_opened_by { click_link sign_amendment_link }
within_window new_window do within_window new_window do
expect(page).to have_content amendments_heading.upcase expect(page).to have_content amendments_heading
fill_in amendment_signer_name_field, with: 'Big Signer' fill_in amendment_signer_name_field, with: 'Big Signer'
draw_signature file_fixture("signature.png"), amendment_signature_field draw_signature file_fixture("signature.png"), amendment_signature_field
@@ -690,10 +682,6 @@ feature "User managing location releases" do
t 'public.amendments.new.amendment.heading' t 'public.amendments.new.amendment.heading'
end end
def signed_contract_preview
t 'public.amendments.new.signed_contract_preview'
end
def amendment_signer_name_field def amendment_signer_name_field
'location_release[amendment_signer_name]' 'location_release[amendment_signer_name]'
end end
@@ -741,16 +729,4 @@ feature "User managing location releases" do
def amendment_signature_label def amendment_signature_label
t 'contracts.amendment_page.description_labels.amendment_signature' t 'contracts.amendment_page.description_labels.amendment_signature'
end end
def table_headers
[
t('location_releases.index.table_headers.approved'),
t('location_releases.index.table_headers.location_info'),
t('location_releases.index.table_headers.owner_info'),
t('location_releases.index.table_headers.notes'),
t('location_releases.index.table_headers.tags'),
t('location_releases.index.table_headers.signed_at'),
t('location_releases.index.table_headers.amendment_signed')
]
end
end end

View File

@@ -40,93 +40,6 @@ feature "User managing material releases" do
expect(MaterialRelease.last.photos.attached?).to eq true expect(MaterialRelease.last.photos.attached?).to eq true
end end
scenario "creating a release for a minor - guardian fields are required when minor checkbox is checked", js: true do
contract_template = create(:contract_template, project: project)
visit new_account_project_contract_template_material_release_path(project.account, project, contract_template)
all('input[data-required-tag="guardian"]').each do |field|
expect(field['required']).to eq 'false'
expect(field).not_to be_visible
end
page.check person_is_minor_checkbox
all('input[data-required-tag="guardian"]').each do |field|
expect(field['required']).to eq 'true'
expect(field).to be_visible
end
end
scenario 'creating a release for a minor', js: true do
project = create(:project, members: current_user, account: current_user.primary_account)
contract_template = create(:contract_template, project: project)
visit new_account_project_contract_template_material_release_path(project.account, project, contract_template)
expect(page).not_to have_content guardian_information_heading.upcase
expect(page).not_to have_content guardian_photo_heading.upcase
page.check person_is_minor_checkbox
expect(page).to have_content guardian_information_heading.upcase
expect(page).to have_content guardian_photo_heading.upcase
expect(page).to have_content guardian_email_field.titleize
fill_all_fields
fill_in guardian_first_name_field, with: 'Guardian'
fill_in guardian_last_name_field, with: 'Name'
fill_in guardian_phone_field, with: '001101'
fill_in guardian_email_field, with: 'valid@email.com'
attach_file guardian_photo_field, file_fixture('hemsworth.jpeg'), visible: :all
fill_in_guardian_address_fields
draw_signature file_fixture("signature.png"), signature_field
click_button submit_release_button
expect(page).to have_content(successful_submission_message)
end
scenario 'creating a release for a minor with two guardians', js: true do
project = create(:project, members: current_user, account: current_user.primary_account)
contract_template = create(:contract_template, project: project)
visit new_account_project_contract_template_material_release_path(project.account, project, contract_template)
expect(page).not_to have_content guardian_2_information_heading.upcase
expect(page).not_to have_content guardian_2_photo_heading.upcase
page.check person_is_minor_checkbox
expect(page).to have_content guardian_information_heading.upcase
expect(page).to have_content guardian_photo_heading.upcase
expect(page).to have_content guardian_email_field.titleize
expect(page).to have_content guardian_2_information_heading.upcase
expect(page).to have_content guardian_2_photo_heading.upcase
expect(page).to have_content guardian_2_phone_field.titleize
fill_all_fields
fill_in guardian_first_name_field, with: 'Guardian'
fill_in guardian_last_name_field, with: 'Name'
fill_in guardian_phone_field, with: '001101'
fill_in guardian_email_field, with: 'valid@email.com'
attach_file guardian_photo_field, file_fixture('hemsworth.jpeg'), visible: :all
fill_in_guardian_address_fields
draw_signature file_fixture("signature.png"), signature_field
fill_in guardian_2_first_name_field, with: 'Second'
fill_in guardian_2_last_name_field, with: 'Guardian'
fill_in guardian_2_phone_field, with: '999'
click_button submit_release_button
expect(page).to have_content(successful_submission_message)
expect(MaterialRelease.last.guardian_2_first_name).to eq 'Second'
end
scenario "creating release is possible only after filling all fields", js: true do scenario "creating release is possible only after filling all fields", js: true do
contract_template = create(:contract_template, project: project) contract_template = create(:contract_template, project: project)
@@ -185,25 +98,7 @@ feature "User managing material releases" do
sign_in current_user sign_in current_user
end end
scenario "index table shows owner info" do scenario "creating a release", js: true do
release = create(:material_release, :native, :with_address, project: project)
visit project_material_releases_path(project)
expect(page).to have_content owner_info_table_header
expect(page).to have_content release.person_first_name
expect(page).to have_content release.person_last_name
expect(page).to have_content release.person_phone
expect(page).to have_content release.person_email
expect(page).to have_content release.person_address_street1
expect(page).to have_content release.person_address_city
expect(page).to have_content release.person_address_state
expect(page).to have_content release.person_address_zip
expect(page).to have_content release.person_address_country
end
scenario "creating a release for and adult", js: true do
visit new_project_material_release_path(project) visit new_project_material_release_path(project)
by "attaching only a contract" do by "attaching only a contract" do
@@ -225,94 +120,13 @@ feature "User managing material releases" do
click_button create_release_button click_button create_release_button
expect(page).to have_content(create_release_notice) expect(page).to have_content(create_release_notice)
expect(page).to have_photo("material_photo.png", visible: :all) expect(page).to have_photo("material_photo.png")
click_on "Manage" click_on "Manage"
expect(page).to have_link("Download") expect(page).to have_link("Download")
end end
end end
scenario "creating a release for a minor - guardian fields are required when minor checkbox is checked", js: true do
visit new_project_material_release_path(project)
all('input[data-required-tag="guardian"]').each do |field|
expect(field['required']).to eq 'false'
expect(field).not_to be_visible
end
page.check person_is_minor_checkbox
all('input[data-required-tag="guardian"]').each do |field|
expect(field['required']).to eq 'true'
expect(field).to be_visible
end
end
scenario "creating a release for a minor", js: true do
visit new_project_material_release_path(project)
expect(page).not_to have_content guardian_information_heading.upcase
expect(page).not_to have_content guardian_photo_heading
page.check person_is_minor_checkbox
expect(page).to have_content guardian_information_heading.upcase
expect(page).to have_content guardian_photo_heading
expect(page).to have_content guardian_email_field.titleize
fill_in_release_fields name: "Apple Laptop"
attach_file contract_field, Rails.root.join(file_fixture("contract.pdf")), visible: false
fill_in guardian_first_name_field, with: 'Guardian'
fill_in guardian_last_name_field, with: 'Name'
fill_in guardian_phone_field, with: '001101'
fill_in guardian_email_field, with: 'valid@email.com'
attach_file guardian_photo_field, file_fixture('hemsworth.jpeg'), visible: :all
fill_in_guardian_address_fields
click_button import_release_button
expect(page).to have_content successful_import_message
expect(MaterialRelease.last.guardian_first_name).to eq 'Guardian'
end
scenario "creating a release for a minor with two guardians", js: true do
visit new_project_material_release_path(project)
expect(page).not_to have_content guardian_2_information_heading.upcase
expect(page).not_to have_content guardian_2_photo_heading
page.check person_is_minor_checkbox
expect(page).to have_content guardian_information_heading.upcase
expect(page).to have_content guardian_photo_heading
expect(page).to have_content guardian_email_field.titleize
expect(page).to have_content guardian_2_information_heading.upcase
expect(page).to have_content guardian_2_photo_heading
expect(page).to have_content guardian_2_phone_field.titleize
fill_in_release_fields name: "Apple Laptop"
attach_file contract_field, Rails.root.join(file_fixture("contract.pdf")), visible: false
fill_in guardian_first_name_field, with: 'Guardian'
fill_in guardian_last_name_field, with: 'Name'
fill_in guardian_phone_field, with: '001101'
fill_in guardian_email_field, with: 'valid@email.com'
attach_file guardian_photo_field, file_fixture('hemsworth.jpeg'), visible: :all
fill_in_guardian_address_fields
fill_in guardian_2_first_name_field, with: 'Second'
fill_in guardian_2_last_name_field, with: 'Guardian'
fill_in guardian_2_phone_field, with: '999'
click_button import_release_button
expect(page).to have_content successful_import_message
expect(MaterialRelease.last.guardian_first_name).to eq 'Guardian'
expect(MaterialRelease.last.guardian_2_first_name).to eq 'Second'
end
scenario "updating an existing release", js: true do scenario "updating an existing release", js: true do
material_release = create(:material_release, :non_native, project: project) material_release = create(:material_release, :non_native, project: project)
@@ -376,7 +190,7 @@ feature "User managing material releases" do
click_on "Save Changes" click_on "Save Changes"
expect(page).to have_content("The release has been updated") expect(page).to have_content("The release has been updated")
expect(page).to have_photo("material_photo.png", visible: :all) expect(page).to have_photo("material_photo.png")
end end
scenario "viewing the contract PDF" do scenario "viewing the contract PDF" do
@@ -605,8 +419,8 @@ feature "User managing material releases" do
"material_release[person_address_zip]" "material_release[person_address_zip]"
end end
def have_photo(filename, visible: true) def have_photo(filename)
have_selector("img[src*='#{filename}']", visible: visible) have_selector("img[src*='#{filename}']")
end end
def import_material_release_link(project) def import_material_release_link(project)
@@ -728,111 +542,4 @@ feature "User managing material releases" do
def date_issued def date_issued
t 'contracts.for_office_use_only.description_labels.date_issued' t 'contracts.for_office_use_only.description_labels.date_issued'
end end
def person_is_minor_checkbox
'material_release_minor'
end
def guardian_2_first_name_field
t 'helpers.label.material_release.guardian_2_first_name'
end
def guardian_2_last_name_field
t 'helpers.label.material_release.guardian_2_last_name'
end
def guardian_2_phone_field
t 'helpers.label.material_release.guardian_2_phone'
end
def guardian_first_name_field
t 'helpers.label.material_release.guardian_first_name'
end
def guardian_last_name_field
t 'helpers.label.material_release.guardian_last_name'
end
def guardian_phone_field
t 'helpers.label.material_release.guardian_phone'
end
def guardian_email_field
t 'helpers.label.material_release.guardian_email'
end
def guardian_address_street1_field
t('helpers.label.material_release.guardian_address_street1')
end
def guardian_address_city_field
t('helpers.label.material_release.guardian_address_city')
end
def guardian_address_state_field
t('helpers.label.material_release.guardian_address_state')
end
def guardian_address_zip_field
t('helpers.label.material_release.guardian_address_zip')
end
def guardian_photo_field
'material_release[guardian_photo]'
end
def guardian_2_photo_field
'material_release[guardian_2_photo]'
end
def fill_in_guardian_address_fields
fill_in guardian_address_street1_field, with: "124 Test Lane"
fill_in guardian_address_city_field, with: "New York"
fill_in guardian_address_state_field, with: "NY"
fill_in guardian_address_zip_field, with: '1000'
end
def submit_release_button
'I have read and agree to the above'
end
def successful_submission_message
'Your release was successfully submitted. Thank you.'
end
def guardian_information_heading
t 'public.material_releases.new.guardian_info.heading'
end
def guardian_photo_heading
t 'public.material_releases.new.guardian_photo.heading'
end
def guardian_2_information_heading
t 'public.material_releases.new.guardian_2_info.heading'
end
def guardian_2_photo_heading
t 'public.material_releases.new.guardian_2_photo.heading'
end
def contract_field
'material_release[contract]'
end
def import_release_button
t 'helpers.submit.material_release.create'
end
def successful_import_message
t 'material_releases.create.notice'
end
def signature_field
'material_release_signature_base64'
end
def owner_info_table_header
t 'material_releases.index.table_headers.owner_info'
end
end end

View File

@@ -148,18 +148,6 @@ RSpec.describe Account do
end end
end end
describe "#total_number_of_releases" do
it "returns total number of releases" do
account = create(:account)
project = create(:project, account: account)
appearance_release = create(:appearance_release, project: project)
talent_release = create(:talent_release, project: project)
material_release = create(:material_release, project: project)
expect(account.total_number_of_releases).to eq 3
end
end
describe "#me_suite_enabled?" do describe "#me_suite_enabled?" do
it "returns true when plan_uid is me_suite" do it "returns true when plan_uid is me_suite" do
expect(build(:account, plan_uid: "me_suite").me_suite_enabled?).to eq true expect(build(:account, plan_uid: "me_suite").me_suite_enabled?).to eq true

View File

@@ -49,36 +49,6 @@ RSpec.describe Broadcast, type: :model do
expect(broadcast).to have_received(:destroy_mux_live_stream) expect(broadcast).to have_received(:destroy_mux_live_stream)
end end
end end
context "#stream_server_url" do
it "returns mux stream url when overriden stream url is absent" do
ENV["MUX_BROADCAST_SERVER_URL"] = "mux_stream"
broadcast = create(:broadcast, :with_stream, skip_create_callback: true, name: "My Broadcast")
expect(broadcast.stream_server_url).to eq("mux_stream")
end
it "returns overriden stream url when it is present" do
ENV["MUX_BROADCAST_SERVER_URL"] = "mux_stream"
broadcast = create(:broadcast, :with_overriden_stream, skip_create_callback: true, name: "My Broadcast")
expect(broadcast.stream_server_url).to eq("overriden_stream_url")
end
end
context "#stream_server_key" do
it "returns mux stream key when overriden stream key is absent" do
broadcast = create(:broadcast, :with_stream, skip_create_callback: true, name: "My Broadcast")
expect(broadcast.stream_server_key).to eq("mux_key")
end
it "returns overriden stream key when it is present" do
broadcast = create(:broadcast, :with_overriden_stream, skip_create_callback: true, name: "My Broadcast")
expect(broadcast.stream_server_key).to eq("overriden_stream_key")
end
end
end end
describe "#zoom_meeting_url" do describe "#zoom_meeting_url" do