Compare commits
2 Commits
prevent-AP
...
microsoft-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d29f14953 | ||
|
|
4b5238435a |
@@ -32,3 +32,10 @@ CUSTOM_API_TOKEN=
|
||||
# Required for simulcasting to Millicast for director mode
|
||||
MILLICAST_API_SECRET=
|
||||
MILLICAST_ACCOUNT_ID=
|
||||
|
||||
# Required for Microsoft Azure AD Auth
|
||||
AZURE_CLIENT_ID = Client App ID
|
||||
AZURE_CLIENT_SECRET = Client App Secret
|
||||
AZURE_TENANT_ID = Client App Tenant ID
|
||||
AZURE_REDIRECT_URI = where microsoft will redirect after login, eg. http://localhost:3000/auth/azure_ad/callback
|
||||
AZURE_SCOPES = Scopes required for Application, eg. 'openid email profile User.Read offline_access OnlineMeetings.ReadWrite'
|
||||
5
Gemfile
5
Gemfile
@@ -139,6 +139,11 @@ gem 'rack-cors'
|
||||
# Ruby wrappers for the HubSpot REST API
|
||||
gem "hubspot-ruby"
|
||||
|
||||
# OAuth
|
||||
gem 'omniauth-oauth2', '~> 1.6'
|
||||
# OmniAuth CSRF protection
|
||||
gem 'omniauth-rails_csrf_protection', '~> 0.1.2'
|
||||
|
||||
group :development, :test, :review do
|
||||
# Call "byebug" anywhere in the code to stop execution and get a debugger console
|
||||
gem "byebug", "~> 11.0.1", platforms: [:mri, :mingw, :x64_mingw]
|
||||
|
||||
19
Gemfile.lock
19
Gemfile.lock
@@ -220,6 +220,7 @@ GEM
|
||||
activesupport (>= 4.2.0)
|
||||
hashdiff (1.0.1)
|
||||
hashery (2.1.2)
|
||||
hashie (4.1.0)
|
||||
hexapdf (0.9.3)
|
||||
cmdparse (~> 3.0, >= 3.0.3)
|
||||
geom2d (~> 0.2)
|
||||
@@ -297,6 +298,7 @@ GEM
|
||||
money (~> 6.13.2)
|
||||
railties (>= 3.0)
|
||||
msgpack (1.3.1)
|
||||
multi_json (1.15.0)
|
||||
multi_xml (0.6.0)
|
||||
multipart-post (2.1.1)
|
||||
nio4r (2.5.2)
|
||||
@@ -308,6 +310,21 @@ GEM
|
||||
warden
|
||||
oath-generators (1.0.1)
|
||||
oath (>= 0.0.12)
|
||||
oauth2 (1.4.4)
|
||||
faraday (>= 0.8, < 2.0)
|
||||
jwt (>= 1.0, < 3.0)
|
||||
multi_json (~> 1.3)
|
||||
multi_xml (~> 0.5)
|
||||
rack (>= 1.2, < 3)
|
||||
omniauth (1.9.1)
|
||||
hashie (>= 3.4.6)
|
||||
rack (>= 1.6.2, < 3)
|
||||
omniauth-oauth2 (1.6.0)
|
||||
oauth2 (~> 1.1)
|
||||
omniauth (~> 1.9)
|
||||
omniauth-rails_csrf_protection (0.1.2)
|
||||
actionpack (>= 4.2)
|
||||
omniauth (>= 1.3.1)
|
||||
parallel (1.19.1)
|
||||
parity (3.2.0)
|
||||
parser (2.6.5.0)
|
||||
@@ -552,6 +569,8 @@ DEPENDENCIES
|
||||
mux_ruby!
|
||||
oath (~> 1.1.0)
|
||||
oath-generators (~> 1.0.1)
|
||||
omniauth-oauth2 (~> 1.6)
|
||||
omniauth-rails_csrf_protection (~> 0.1.2)
|
||||
parity (~> 3.2.0)
|
||||
pdf-reader (~> 2.1.0)
|
||||
pdfkit (~> 0.8.2)
|
||||
|
||||
@@ -4,7 +4,6 @@ require './lib/knock_monkeypatch'
|
||||
|
||||
class Api::UserTokenController < Knock::AuthTokenController
|
||||
include Oath::ControllerHelpers
|
||||
include RememberMe::Controller
|
||||
|
||||
skip_before_action :verify_authenticity_token
|
||||
before_action :sign_in_user
|
||||
|
||||
@@ -6,12 +6,9 @@ class ApprovalsController < ApplicationController
|
||||
|
||||
def create
|
||||
@releasable.approve_by(current_user)
|
||||
@releasable.approved_by_user_signature.attach(approved_by_user_signature_params) if signature_data.present?
|
||||
|
||||
if @releasable.save(context: :approval)
|
||||
if @releasable.save
|
||||
redirect_to [@project, "#{@releasable_param.name.pluralize}"], notice: t('.release_approved', release_type: @releasable.model_name.human)
|
||||
else
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
@@ -28,21 +25,4 @@ class ApprovalsController < ApplicationController
|
||||
def set_project
|
||||
@project = @releasable.project
|
||||
end
|
||||
|
||||
def releasable_params
|
||||
params.require(releasable_param.name).permit(approved_by_user_signature: :data)
|
||||
end
|
||||
|
||||
def signature_data
|
||||
releasable_params.dig(:approved_by_user_signature, :data)
|
||||
end
|
||||
|
||||
def approved_by_user_signature_params
|
||||
{
|
||||
data: signature_data,
|
||||
filename: "approved_by_user_signature.png",
|
||||
content_type: "image/png",
|
||||
identify: false,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -75,7 +75,7 @@ class BroadcastsController < ApplicationController
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
def set_project
|
||||
@@ -113,7 +113,7 @@ class BroadcastsController < ApplicationController
|
||||
end
|
||||
|
||||
def conference_url_for(broadcast)
|
||||
broadcast.video_conference_url_override || url_for([broadcast.project, broadcast, :zoom_meeting])
|
||||
broadcast.video_conference_url_override || url_for([broadcast.project, broadcast, :conference_meeting])
|
||||
end
|
||||
|
||||
def log_create_analytics
|
||||
|
||||
22
app/controllers/callbacks_controller.rb
Normal file
22
app/controllers/callbacks_controller.rb
Normal 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
|
||||
45
app/controllers/conference_meetings_controller.rb
Normal file
45
app/controllers/conference_meetings_controller.rb
Normal 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
|
||||
@@ -1,6 +0,0 @@
|
||||
class ZoomMeetingsController < ApplicationController
|
||||
def show
|
||||
authorize broadcast = Broadcast.find(params[:broadcast_id])
|
||||
redirect_to broadcast.zoom_meeting_url
|
||||
end
|
||||
end
|
||||
17
app/helpers/broadcast_conferences_helper.rb
Normal file
17
app/helpers/broadcast_conferences_helper.rb
Normal 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
|
||||
@@ -1,24 +1,15 @@
|
||||
module Approvable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
|
||||
included do
|
||||
include ActiveStorageSupport::SupportForBase64
|
||||
|
||||
has_one_base64_attached :approved_by_user_signature
|
||||
|
||||
# Requires signature when saving in the approval context
|
||||
with_options on: :approval do
|
||||
validates :approved_by_user_signature, attached: true
|
||||
end
|
||||
|
||||
def approve_by(user)
|
||||
return unless approved_at.nil?
|
||||
|
||||
|
||||
self.approved_by_user_name = user.full_name
|
||||
self.approved_by_user_email = user.email
|
||||
self.approved_at = BigMediaTime.time_zone_now
|
||||
self.approved_at = Time.zone.now
|
||||
end
|
||||
|
||||
|
||||
def approved?
|
||||
self.approved_at.present?
|
||||
end
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
<div class="card shadow-sm">
|
||||
<%= card_header text: t(".heading", release_type: @releasable_param.name.titleize), close_action_path: [@project, "#{@releasable_param.name.pluralize}"] %>
|
||||
<div class="card-body">
|
||||
<embed class="embeded-contract-preview mb-3" type="application/pdf" src="<%= url_for [@releasable, :contracts, format: "pdf"] %>" width="90%" height="1200" />
|
||||
<embed class="embeded-contract-preview" type="application/pdf" src="<%= url_for [@releasable, :contracts, format: "pdf"] %>" width="90%" height="1200" />
|
||||
|
||||
<%= errors_summary_for @releasable %>
|
||||
<%= bootstrap_form_with model: @releasable, method: :post, url: public_send("#{@releasable_param.name}_approvals_path", @releasable), local: true do |form| %>
|
||||
<%= card_field_set_tag 'Signature' do %>
|
||||
<%= render "shared/signature_fields", form: form, signature_field: 'approved_by_user_signature[data]' %>
|
||||
<% end %>
|
||||
<div class="row align-items-center text-center mt-4">
|
||||
<%= link_to t("shared.cancel"), [@releasable.project, "#{@releasable_param.name.pluralize}"], class: "col-3 text-reset" %>
|
||||
<div class="col-9">
|
||||
@@ -16,4 +12,4 @@
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
<%= bootstrap_form_with model: model, local: true do |form| %>
|
||||
<%= form.text_field :name %>
|
||||
<%= form.select :conference_option, options_for_conference_select, { label: t('.labels.conference_option') }, class: "form-control custom-select" %>
|
||||
<%= form.time_zone_select(:shoot_location_time_zone, nil, label: "Time zone of shoot location") %>
|
||||
|
||||
<div class="row align-items-center text-center mt-4">
|
||||
|
||||
@@ -127,8 +127,8 @@
|
||||
</div>
|
||||
<hr>
|
||||
<% end %>
|
||||
<p class="card-text">If you want to join the ZOOM meeting dedicated to this broadcast, follow the link below.</p>
|
||||
<%= link_to 'Video Conference', @conference_url, class: 'btn btn-primary btn-block', target: '_blank' %>
|
||||
<p class="card-text"><%= "If you want to join the #{conference_option_name_from_key(@broadcast.conference_option)} meeting dedicated to this broadcast, follow the link below." %></p>
|
||||
<%= link_to 'Video Conference', @conference_url, class: "btn btn-primary btn-block", target: '_blank' %>
|
||||
</div>
|
||||
<div class="<%= class_string("tab-pane fade show", "active" => params[:active_tab] == 'recordings') %>" id="recordings">
|
||||
<div id="broadcast_recordings">
|
||||
|
||||
@@ -10,10 +10,4 @@
|
||||
<%= description_list_pair t('.description_labels.issued_to'), releasable.name %>
|
||||
<%= description_list_pair t('.description_labels.issued_by'), releasable.approved_by_user_name %>
|
||||
<%= description_list_pair t('.description_labels.date_issued'), releasable.approved_at %>
|
||||
</dl>
|
||||
|
||||
<% if preview %>
|
||||
<%= image_tag dummy_signature %>
|
||||
<% elsif releasable.approved_by_user_signature.attached? %>
|
||||
<%= image_tag releasable.approved_by_user_signature.variant(auto_orient: true, resize: "200x200") %>
|
||||
<% end %>
|
||||
</dl>
|
||||
@@ -16,10 +16,11 @@
|
||||
<%= contract_template.guardian_clause %>
|
||||
<% end %>
|
||||
|
||||
<%# if releasable.model_name.in? %w(MedicalRelease MiscRelease AppearanceRelease) %>
|
||||
<% if releasable.respond_to?(:question_1_answer) %>
|
||||
<div class="page">
|
||||
<%= render "contracts/questionnaire", releasable: releasable, contract_template: contract_template, preview: preview %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="page">
|
||||
@@ -46,7 +47,8 @@
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% if releasable.try(:approved?) %>
|
||||
|
||||
<% if releasable.respond_to?(:approved?) && releasable.approved? %>
|
||||
<div class="page">
|
||||
<%= render "contracts/for_office_use_only", releasable: releasable, preview: preview %>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="<%= I18n.locale %>">
|
||||
<head>
|
||||
<title>ME Suite</title>
|
||||
<title>MESuite.ai App</title>
|
||||
<%= csrf_meta_tags %>
|
||||
<%= csp_meta_tag %>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="<%= I18n.locale %>">
|
||||
<head>
|
||||
<title>ME Suite</title>
|
||||
<title>MESuite.ai App</title>
|
||||
<%= csrf_meta_tags %>
|
||||
<%= csp_meta_tag %>
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
<%= @user.role_for(Current.account).to_s.titleize %>
|
||||
<% end %>
|
||||
</p>
|
||||
<%= link_to 'Auth to Microsoft', '/auth/azure_ad', method: :post, class: "btn btn-primary" %>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
|
||||
13
config/initializers/omniauth.rb
Normal file
13
config/initializers/omniauth.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
require 'azure_ad'
|
||||
|
||||
Rails.application.config.middleware.use OmniAuth::Builder do
|
||||
provider :azure_ad,
|
||||
client_id: ENV['AZURE_CLIENT_ID'],
|
||||
client_secret: ENV['AZURE_CLIENT_SECRET'],
|
||||
redirect_uri: ENV['AZURE_REDIRECT_URI'],
|
||||
client_options: {
|
||||
token_url: "#{ENV['AZURE_TENANT_ID']}/oauth2/v2.0/token",
|
||||
authorize_url: "#{ENV['AZURE_TENANT_ID']}/oauth2/v2.0/authorize"
|
||||
},
|
||||
scope: ENV['AZURE_SCOPES']
|
||||
end
|
||||
@@ -1 +0,0 @@
|
||||
Rails.application.config.session_store :cookie_store, key: '_easy_release_session', expire_after: 1.month
|
||||
@@ -275,6 +275,9 @@ en:
|
||||
stream_multiple_cameras: Stream multiple cameras at one time
|
||||
update:
|
||||
reset_notice: The Share URL has been reset, and the previous URL will no longer work. Please click "Copy URL" and share it again with those who you want to have access to this live stream
|
||||
form:
|
||||
labels:
|
||||
conference_option: Conference Option
|
||||
bulk_taggings:
|
||||
new_bulk_tag_modal:
|
||||
submit: Add
|
||||
@@ -1642,3 +1645,9 @@ en:
|
||||
edit: Edit
|
||||
report: Report
|
||||
generating: Generating...
|
||||
conference_meetings:
|
||||
show:
|
||||
alerts:
|
||||
not_authenticated: You are not authenticated via Microsoft, please authenticate and try again
|
||||
failed_to_join: Failed to join conference
|
||||
unknown_conference_option: Unknown conference option
|
||||
|
||||
@@ -131,6 +131,9 @@ es:
|
||||
stream_multiple_cameras: Stream multiple cameras at one time
|
||||
update:
|
||||
reset_notice: The Share URL has been reset, and the previous URL will no longer work. Please click "Copy URL" and share it again with those who you want to have access to this live stream
|
||||
form:
|
||||
labels:
|
||||
conference_option: Conference Option (ES)
|
||||
contract_templates:
|
||||
blank_contracts:
|
||||
create:
|
||||
@@ -705,3 +708,9 @@ es:
|
||||
production_elements_logs: Production Elements Logs, and more (ES)
|
||||
reduces_labor_cost: Reduces labor costs (ES)
|
||||
simplifies_cue_sheets: Simplifies Music Cue Sheets, Graphic Cue Sheets (ES)
|
||||
conference_meetings:
|
||||
show:
|
||||
alerts:
|
||||
not_authenticated: You are not authenticated via Microsoft, please authenticate and try again (ES)
|
||||
failed_to_join: Failed to join conference (ES)
|
||||
unknown_conference_option: Unknown conference option (ES)
|
||||
|
||||
@@ -4,6 +4,8 @@ require 'sidekiq/web'
|
||||
Rails.application.routes.draw do
|
||||
AVAILABLE_LOCALES_REGEX = /#{I18n.available_locales.join("|")}/.freeze
|
||||
|
||||
get 'auth/azure_ad/callback', to: 'callbacks#create'
|
||||
|
||||
concern :confirmable do
|
||||
resources :video_release_confirmations, only: [:new, :create, :destroy]
|
||||
end
|
||||
@@ -100,7 +102,7 @@ Rails.application.routes.draw do
|
||||
member do
|
||||
delete :destroy_file
|
||||
end
|
||||
resource :zoom_meeting, only: [:show]
|
||||
resource :conference_meeting, only: [:show]
|
||||
resources :broadcast_recordings, only: :destroy
|
||||
end
|
||||
resources :directories, except: [:index] do
|
||||
|
||||
8
db/migrate/20200820081251_add_microsoft_info_to_users.rb
Normal file
8
db/migrate/20200820081251_add_microsoft_info_to_users.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
class AddMicrosoftInfoToUsers < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
add_column :users, :microsoft_user_id, :string
|
||||
add_column :users, :microsoft_access_token, :string
|
||||
add_column :users, :microsoft_refresh_token, :string
|
||||
add_column :users, :microsoft_token_expires_at, :integer
|
||||
end
|
||||
end
|
||||
@@ -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
|
||||
@@ -586,7 +586,9 @@ CREATE TABLE public.broadcasts (
|
||||
stream_key_override character varying,
|
||||
director_mode_video_embed text,
|
||||
simulcast_uid character varying,
|
||||
video_conference_url_override character varying
|
||||
video_conference_url_override character varying,
|
||||
conference_option character varying,
|
||||
conference_join_url character varying
|
||||
);
|
||||
|
||||
|
||||
@@ -1804,7 +1806,11 @@ CREATE TABLE public.users (
|
||||
remember_created_at timestamp without time zone,
|
||||
first_name character varying,
|
||||
last_name character varying,
|
||||
time_zone character varying DEFAULT 'UTC'::character varying NOT NULL
|
||||
time_zone character varying DEFAULT 'UTC'::character varying NOT NULL,
|
||||
microsoft_user_id character varying,
|
||||
microsoft_access_token character varying,
|
||||
microsoft_refresh_token character varying,
|
||||
microsoft_token_expires_at integer
|
||||
);
|
||||
|
||||
|
||||
@@ -4025,6 +4031,8 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||
('20200807190607'),
|
||||
('20200811102720'),
|
||||
('20200812060406'),
|
||||
('20200819070738');
|
||||
('20200819070738'),
|
||||
('20200820081251'),
|
||||
('20200820081524');
|
||||
|
||||
|
||||
|
||||
124
lib/azure_ad.rb
Normal file
124
lib/azure_ad.rb
Normal 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
|
||||
107
lib/microsoft_graph.rb
Normal file
107
lib/microsoft_graph.rb
Normal 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
|
||||
@@ -27,17 +27,10 @@ RSpec.describe ApprovalsController, type: :controller do
|
||||
|
||||
expect(MedicalRelease.last.approved?).to eq false
|
||||
|
||||
post :create, params: { medical_release_id: medical_release, medical_release: approvable_params }
|
||||
post :create, params: { medical_release_id: medical_release }
|
||||
|
||||
expect(response).to redirect_to [project, :medical_releases]
|
||||
expect(MedicalRelease.last.approved?).to eq true
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def approvable_params
|
||||
signature_base64 ||= Base64Image.from_image(file_fixture('signature.png')).data_uri
|
||||
{ approved_by_user_signature: { data: signature_base64 } }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -157,16 +157,24 @@ RSpec.describe BroadcastsController, type: :controller do
|
||||
expect(response.body).to have_xpath "//input[@readonly][@value='#{broadcast_url(broadcast.token)}']"
|
||||
end
|
||||
|
||||
it "displays zoom meeting button" do
|
||||
it "displays zoom meeting button for zoom conference option" do
|
||||
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_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
|
||||
|
||||
it "assigns required variables" do
|
||||
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
|
||||
end
|
||||
|
||||
|
||||
75
spec/controllers/conference_meetings_controller_spec.rb
Normal file
75
spec/controllers/conference_meetings_controller_spec.rb
Normal file
@@ -0,0 +1,75 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ConferenceMeetingsController, type: :controller do
|
||||
let(:user) { create(:user) }
|
||||
let(:account) { user.primary_account }
|
||||
let(:project) { create(:project, account: user.primary_account) }
|
||||
let(:broadcast) { create(:broadcast, name: "Broadcast", project: project) }
|
||||
let(:ms_teams_broadcast) { create(:broadcast, :ms_teams_conference, project: project) }
|
||||
let(:unknown_option_broadcast) { create(:broadcast, project: project, conference_option: 'google') }
|
||||
|
||||
let(:meeting_start_url) { "http://meeting_start_url" }
|
||||
let(:meeting_hash) { HashWithIndifferentAccess.new(start_url: meeting_start_url) }
|
||||
let(:user_create_response) { {"id" => "new_host_id"} }
|
||||
let(:roles_assign_response) { {"ids" => ["new_host_id"]} }
|
||||
let(:roles_list_response) { {"roles" => [{"name" => "directme-host"}]} }
|
||||
|
||||
|
||||
before :each do
|
||||
allow_any_instance_of(ZoomGateway).to receive(:find_meeting).and_return(meeting_hash)
|
||||
allow_any_instance_of(ZoomGateway).to receive(:create_meeting).and_return("meeting_id")
|
||||
allow_any_instance_of(ZoomGateway).to receive(:create_host).and_return("host_id")
|
||||
stub_mux_live_stream
|
||||
end
|
||||
|
||||
describe "#show" do
|
||||
before { sign_in user }
|
||||
|
||||
it "redirects to meeting start url with Zoom conference option" do
|
||||
get :show, params: { project_id: project.id, broadcast_id: broadcast.id }
|
||||
expect(response).to redirect_to(meeting_start_url)
|
||||
end
|
||||
|
||||
it "redirects to the broadcast show page with alert if user is not authenticated via microsoft and tries to create MS Teams meeting" do
|
||||
get :show, params: { project_id: project.id, broadcast_id: ms_teams_broadcast.id }
|
||||
expect(response).to redirect_to project_broadcast_path(project, ms_teams_broadcast)
|
||||
expect(flash.alert).to eq not_authenticated_alert
|
||||
end
|
||||
|
||||
it "redirects to the broadcast show page with alert if user is authenticated via microsoft and tries to create MS Teams meeting but Graph API fails to create meeting" do
|
||||
allow_any_instance_of(MicrosoftGraph).to receive(:create_teams_meeting).and_return(nil)
|
||||
get :show, params: { project_id: project.id, broadcast_id: ms_teams_broadcast.id }
|
||||
expect(response).to redirect_to project_broadcast_path(project, ms_teams_broadcast)
|
||||
expect(flash.alert).to eq failed_to_join_alert
|
||||
end
|
||||
|
||||
it "redirects to the broadcast show page with alert if conference option is not reckognized" do
|
||||
get :show, params: { project_id: project.id, broadcast_id: unknown_option_broadcast.id }
|
||||
expect(response).to redirect_to project_broadcast_path(project, unknown_option_broadcast)
|
||||
expect(flash.alert).to eq unknown_conference_option_alert
|
||||
end
|
||||
|
||||
it "redirects to meeting start url with MS Teams conference option" do
|
||||
new_ms_teams_meeting = JSON.parse({ joinUrl: meeting_start_url }.to_json)
|
||||
|
||||
allow_any_instance_of(MicrosoftGraph).to receive(:create_teams_meeting).and_return(new_ms_teams_meeting)
|
||||
|
||||
get :show, params: { project_id: project.id, broadcast_id: ms_teams_broadcast.id }
|
||||
expect(response).to redirect_to(meeting_start_url)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def not_authenticated_alert
|
||||
t 'conference_meetings.show.alerts.not_authenticated'
|
||||
end
|
||||
|
||||
def failed_to_join_alert
|
||||
t 'conference_meetings.show.alerts.failed_to_join'
|
||||
end
|
||||
|
||||
def unknown_conference_option_alert
|
||||
t 'conference_meetings.show.alerts.unknown_conference_option'
|
||||
end
|
||||
end
|
||||
@@ -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")
|
||||
stub_mux_live_stream
|
||||
end
|
||||
|
||||
describe "#show" do
|
||||
before { sign_in user }
|
||||
|
||||
it "redirects to meeting start url" do
|
||||
get :show, params: { project_id: project.id, broadcast_id: broadcast.id }
|
||||
expect(response).to redirect_to(meeting_start_url)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2,11 +2,16 @@ FactoryBot.define do
|
||||
factory :broadcast do
|
||||
association :project
|
||||
name "My Live Stream"
|
||||
conference_option "zoom"
|
||||
|
||||
transient do
|
||||
skip_create_callback false
|
||||
end
|
||||
|
||||
trait :ms_teams_conference do
|
||||
conference_option "ms_teams"
|
||||
end
|
||||
|
||||
trait :with_stream do
|
||||
stream_uid "mux_stream"
|
||||
stream_key "mux_key"
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
require 'rails_helper'
|
||||
|
||||
feature 'User approving releasables' do
|
||||
shared_examples 'an approvable UI' do
|
||||
let(:current_user) { create(:user, :associate) }
|
||||
let(:project) { create(:project, members: current_user, account: current_user.primary_account) }
|
||||
|
||||
before :each do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
shared_examples 'not authorized to review' do
|
||||
it 'does not show the review action' do
|
||||
visit polymorphic_path [project, subject.model_name.plural]
|
||||
click_on manage_button
|
||||
|
||||
expect(page).not_to have_link(review_action, exact: true)
|
||||
end
|
||||
end
|
||||
|
||||
scenario 'approval status is indicating by a checkmark' do
|
||||
approved_releasable = create("#{subject.model_name.singular}", approved_at: 1.day.ago, project: project)
|
||||
|
||||
visit polymorphic_path [project, subject.model_name.plural]
|
||||
|
||||
expect(page).not_to be_approved(subject)
|
||||
expect(page).not_to be_approved(approved_releasable)
|
||||
end
|
||||
|
||||
context 'as an account manager' do
|
||||
let(:current_user) { create(:user, :account_manager) }
|
||||
|
||||
scenario 'approving a release', js: true do
|
||||
visit polymorphic_path [project, subject.model_name.plural]
|
||||
|
||||
click_on manage_button
|
||||
click_link review_action
|
||||
|
||||
expect(page).to have_content review_page_heading(subject.model_name)
|
||||
expect(page).to have_content approve_button
|
||||
expect(page).to have_content signature_field
|
||||
|
||||
click_on approve_button
|
||||
|
||||
expect(page).not_to have_content approved_notice(subject.model_name)
|
||||
expect(page).to have_content 'is not attached'
|
||||
|
||||
by 'adding signature' do
|
||||
draw_signature file_fixture('signature.png'), signature_data_field(subject.model_name)
|
||||
click_on approve_button
|
||||
|
||||
expect(page).to have_content approved_notice(subject.model_name)
|
||||
end
|
||||
end
|
||||
|
||||
scenario 'viewing the contract PDF for an unapproved release' do
|
||||
visit polymorphic_path [project, subject.model_name.plural]
|
||||
click_on 'Manage'
|
||||
click_link 'Download'
|
||||
|
||||
expect(content_type).to eq('application/pdf')
|
||||
expect(content_disposition).to include('inline')
|
||||
expect(pdf_body).not_to have_content for_office_use_only
|
||||
end
|
||||
|
||||
scenario 'viewing the contract PDF of an approved release' do
|
||||
approver = create(:user, email: 'big.doe@test.com', first_name: 'Big', last_name: 'Joe')
|
||||
subject.approve_by(approver)
|
||||
subject.save!
|
||||
|
||||
visit polymorphic_path([subject, :contracts], format: 'pdf')
|
||||
|
||||
expect(content_type).to eq('application/pdf')
|
||||
expect(content_disposition).to include('inline')
|
||||
expect(pdf_body).to have_content for_office_use_only.upcase
|
||||
expect(pdf_body).to have_content producer_label
|
||||
expect(pdf_body).to have_content production_label
|
||||
expect(pdf_body).to have_content issued_to_label
|
||||
expect(pdf_body).to have_content issued_by_label
|
||||
expect(pdf_body).to have_content date_issued
|
||||
expect(pdf_body).to have_content 'Big Joe'
|
||||
end
|
||||
end
|
||||
|
||||
context 'as a manager' do
|
||||
let(:current_user) { create(:user, :manager) }
|
||||
|
||||
include_examples 'not authorized to review'
|
||||
end
|
||||
|
||||
context 'as an associate' do
|
||||
let(:current_user) { create(:user, :associate) }
|
||||
|
||||
include_examples 'not authorized to review'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def approve_button
|
||||
t 'approvals.new.actions.approve'
|
||||
end
|
||||
|
||||
def approved_notice(model_name)
|
||||
t('approvals.create.release_approved', release_type: model_name.human)
|
||||
end
|
||||
|
||||
def be_approved(releasable)
|
||||
releasable_dom_id = "##{releasable.model_name.singular}_#{releasable.id}"
|
||||
have_css("#{releasable_dom_id }i.fa.fa-check-circle.fa-2x", count: 1)
|
||||
end
|
||||
|
||||
def manage_button
|
||||
'Manage'
|
||||
end
|
||||
|
||||
def review_action
|
||||
'Review'
|
||||
end
|
||||
|
||||
def review_page_heading(model_name)
|
||||
t 'approvals.new.heading', release_type: model_name.human.titleize
|
||||
end
|
||||
|
||||
def signature_field
|
||||
'SIGNATURE'
|
||||
end
|
||||
|
||||
def signature_data_field(model_name)
|
||||
"#{model_name.singular}_approved_by_user_signature[data]"
|
||||
end
|
||||
|
||||
def for_office_use_only
|
||||
t('contracts.for_office_use_only.heading').upcase
|
||||
end
|
||||
|
||||
def producer_label
|
||||
t 'contracts.for_office_use_only.description_labels.producer'
|
||||
end
|
||||
|
||||
def production_label
|
||||
t 'contracts.for_office_use_only.description_labels.production'
|
||||
end
|
||||
|
||||
def issued_to_label
|
||||
t 'contracts.for_office_use_only.description_labels.issued_to'
|
||||
end
|
||||
|
||||
def issued_by_label
|
||||
t 'contracts.for_office_use_only.description_labels.issued_by'
|
||||
end
|
||||
|
||||
def date_issued
|
||||
t 'contracts.for_office_use_only.description_labels.date_issued'
|
||||
end
|
||||
end
|
||||
|
||||
context 'for an appearance release' do
|
||||
subject { create(:appearance_release_with_contract_template, :native, project: project) }
|
||||
it_behaves_like 'an approvable UI'
|
||||
end
|
||||
|
||||
context 'for a talent release' do
|
||||
subject { create(:talent_release_with_contract_template, :native, project: project) }
|
||||
it_behaves_like 'an approvable UI'
|
||||
end
|
||||
|
||||
context 'for a location release' do
|
||||
subject { create(:location_release_with_contract_template, :native, project: project) }
|
||||
it_behaves_like 'an approvable UI'
|
||||
end
|
||||
|
||||
context 'for a material release' do
|
||||
subject { create(:material_release_with_contract_template, :native, project: project) }
|
||||
it_behaves_like 'an approvable UI'
|
||||
end
|
||||
|
||||
context 'for a acquired media release' do
|
||||
subject { create(:acquired_media_release_with_contract_template, :native, project: project) }
|
||||
it_behaves_like 'an approvable UI'
|
||||
end
|
||||
|
||||
context 'for a medical release' do
|
||||
subject { create(:medical_release_with_contract_template, :native, project: project) }
|
||||
it_behaves_like 'an approvable UI'
|
||||
end
|
||||
|
||||
context 'for a misc release' do
|
||||
subject { create(:misc_release_with_contract_template, :native, project: project) }
|
||||
it_behaves_like 'an approvable UI'
|
||||
end
|
||||
end
|
||||
@@ -444,9 +444,104 @@ feature "User managing acquired_media releases" do
|
||||
end
|
||||
|
||||
context "when the user is account manager" do
|
||||
let(:current_user) { create(:user, :account_manager) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
scenario "Review action in Manage menu is visible" do
|
||||
create(:acquired_media_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_acquired_media_releases_path(project)
|
||||
|
||||
expect(page).to have_link(review_action, exact: true)
|
||||
end
|
||||
|
||||
scenario "Reviewing release" do
|
||||
create(:acquired_media_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_acquired_media_releases_path(project)
|
||||
|
||||
click_link review_action
|
||||
|
||||
expect(page).to have_content review_page_heading
|
||||
expect(page).to have_content approve_button
|
||||
end
|
||||
|
||||
scenario "Approved releases have checkmark and non-approved releases don't have checkmarks" do
|
||||
create(:acquired_media_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_acquired_media_releases_path(project)
|
||||
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 0)
|
||||
|
||||
create(:acquired_media_release_with_contract_template, :native, project: project, approved_by_user_email: "some@email.com", approved_at: DateTime.now)
|
||||
visit project_acquired_media_releases_path(project)
|
||||
|
||||
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 1)
|
||||
end
|
||||
|
||||
scenario 'When viewing the contract PDF of approved release there is page for office use only' do
|
||||
acquired_media_release = create(:acquired_media_release_with_contract_template,
|
||||
:native,
|
||||
project: project,
|
||||
person_first_name: 'Jane',
|
||||
person_last_name: 'Doe',
|
||||
approved_by_user_name: "Big Joe",
|
||||
approved_by_user_email: "some@email.com",
|
||||
approved_at: DateTime.now)
|
||||
|
||||
sign_in(current_user)
|
||||
visit project_acquired_media_releases_path(project)
|
||||
click_link *view_release_pdf_link_for(acquired_media_release)
|
||||
|
||||
expect(content_type).to eq('application/pdf')
|
||||
expect(content_disposition).to include('inline')
|
||||
expect(pdf_body).to have_content for_office_use_only.upcase
|
||||
expect(pdf_body).to have_content producer_label
|
||||
expect(pdf_body).to have_content production_label
|
||||
expect(pdf_body).to have_content issued_to_label
|
||||
expect(pdf_body).to have_content issued_by_label
|
||||
expect(pdf_body).to have_content date_issued
|
||||
expect(pdf_body).to have_content 'Big Joe'
|
||||
end
|
||||
|
||||
scenario 'When viewing the contract PDF of not approved release there is no page for office use only' do
|
||||
acquired_media_release = create(:acquired_media_release_with_contract_template,
|
||||
:native,
|
||||
project: project,
|
||||
person_first_name: 'Jane',
|
||||
person_last_name: 'Doe')
|
||||
|
||||
sign_in(current_user)
|
||||
visit project_acquired_media_releases_path(project)
|
||||
click_link *view_release_pdf_link_for(acquired_media_release)
|
||||
|
||||
expect(content_type).to eq('application/pdf')
|
||||
expect(content_disposition).to include('inline')
|
||||
expect(pdf_body).not_to have_content for_office_use_only.upcase
|
||||
expect(pdf_body).not_to have_content producer_label
|
||||
expect(pdf_body).not_to have_content production_label
|
||||
expect(pdf_body).not_to have_content issued_to_label
|
||||
expect(pdf_body).not_to have_content issued_by_label
|
||||
expect(pdf_body).not_to have_content date_issued
|
||||
expect(pdf_body).not_to have_content 'Big Joe'
|
||||
end
|
||||
end
|
||||
|
||||
context "when the user is project manager" do
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
scenario "Review action in Manage menu is not visible" do
|
||||
create(:acquired_media_release_with_contract_template, project: project)
|
||||
|
||||
visit project_acquired_media_releases_path(project)
|
||||
click_on "Manage"
|
||||
|
||||
expect(page).not_to have_link(review_action, exact: true)
|
||||
end
|
||||
end
|
||||
|
||||
context "when the user is associate" do
|
||||
@@ -608,6 +703,42 @@ feature "User managing acquired_media releases" do
|
||||
'Some signature legal language'
|
||||
end
|
||||
|
||||
def review_action
|
||||
t 'acquired_media_releases.acquired_media_release.actions.review'
|
||||
end
|
||||
|
||||
def review_page_heading
|
||||
t 'approvals.new.heading', release_type: "Acquired Media Release"
|
||||
end
|
||||
|
||||
def approve_button
|
||||
t 'approvals.new.actions.approve'
|
||||
end
|
||||
|
||||
def for_office_use_only
|
||||
t 'contracts.for_office_use_only.heading'
|
||||
end
|
||||
|
||||
def producer_label
|
||||
t 'contracts.for_office_use_only.description_labels.producer'
|
||||
end
|
||||
|
||||
def production_label
|
||||
t 'contracts.for_office_use_only.description_labels.production'
|
||||
end
|
||||
|
||||
def issued_to_label
|
||||
t 'contracts.for_office_use_only.description_labels.issued_to'
|
||||
end
|
||||
|
||||
def issued_by_label
|
||||
t 'contracts.for_office_use_only.description_labels.issued_by'
|
||||
end
|
||||
|
||||
def date_issued
|
||||
t 'contracts.for_office_use_only.description_labels.date_issued'
|
||||
end
|
||||
|
||||
def person_is_minor_checkbox
|
||||
'acquired_media_release_minor'
|
||||
end
|
||||
|
||||
@@ -687,9 +687,103 @@ feature 'User managing appearance releases' do
|
||||
|
||||
context "when the user is account manager" do
|
||||
let(:current_user) { create(:user, :account_manager) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
scenario "Review action in Manage menu is visible" do
|
||||
create(:appearance_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_appearance_releases_path(project)
|
||||
|
||||
expect(page).to have_link(review_action, exact: true)
|
||||
end
|
||||
|
||||
scenario "Reviewing release" do
|
||||
create(:appearance_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_appearance_releases_path(project)
|
||||
|
||||
click_link review_action
|
||||
|
||||
expect(page).to have_content review_page_heading
|
||||
expect(page).to have_content approve_button
|
||||
end
|
||||
|
||||
scenario "Approved releases have checkmark and non-approved releases don't have checkmarks" do
|
||||
create(:appearance_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_appearance_releases_path(project)
|
||||
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 0)
|
||||
|
||||
create(:appearance_release_with_contract_template, :native, project: project, approved_by_user_email: "some@email.com", approved_at: DateTime.now)
|
||||
visit project_appearance_releases_path(project)
|
||||
|
||||
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 1)
|
||||
end
|
||||
|
||||
scenario 'When viewing the contract PDF of approved release there is page for office use only' do
|
||||
appearance_release = create(:appearance_release_with_contract_template,
|
||||
:native,
|
||||
project: project,
|
||||
person_first_name: 'Jane',
|
||||
person_last_name: 'Doe',
|
||||
approved_by_user_name: "Big Joe",
|
||||
approved_by_user_email: "some@email.com",
|
||||
approved_at: DateTime.now)
|
||||
|
||||
sign_in(current_user)
|
||||
visit project_appearance_releases_path(project)
|
||||
click_link *view_release_pdf_link_for(appearance_release)
|
||||
|
||||
expect(content_type).to eq('application/pdf')
|
||||
expect(content_disposition).to include('inline')
|
||||
expect(pdf_body).to have_content for_office_use_only.upcase
|
||||
expect(pdf_body).to have_content producer_label
|
||||
expect(pdf_body).to have_content production_label
|
||||
expect(pdf_body).to have_content issued_to_label
|
||||
expect(pdf_body).to have_content issued_by_label
|
||||
expect(pdf_body).to have_content date_issued
|
||||
expect(pdf_body).to have_content 'Big Joe'
|
||||
end
|
||||
|
||||
scenario 'When viewing the contract PDF of not approved release there is no page for office use only' do
|
||||
appearance_release = create(:appearance_release_with_contract_template,
|
||||
:native,
|
||||
project: project,
|
||||
person_first_name: 'Jane',
|
||||
person_last_name: 'Doe')
|
||||
|
||||
sign_in(current_user)
|
||||
visit project_appearance_releases_path(project)
|
||||
click_link *view_release_pdf_link_for(appearance_release)
|
||||
|
||||
expect(content_type).to eq('application/pdf')
|
||||
expect(content_disposition).to include('inline')
|
||||
expect(pdf_body).not_to have_content for_office_use_only.upcase
|
||||
expect(pdf_body).not_to have_content producer_label
|
||||
expect(pdf_body).not_to have_content production_label
|
||||
expect(pdf_body).not_to have_content issued_to_label
|
||||
expect(pdf_body).not_to have_content issued_by_label
|
||||
expect(pdf_body).not_to have_content date_issued
|
||||
expect(pdf_body).not_to have_content 'Big Joe'
|
||||
end
|
||||
end
|
||||
|
||||
context "when the user is project manager" do
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
scenario "Review action in Manage menu is not visible" do
|
||||
create(:appearance_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_appearance_releases_path(project)
|
||||
click_on manage_button
|
||||
|
||||
expect(page).not_to have_link(review_action, exact: true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user is associate' do
|
||||
@@ -707,6 +801,15 @@ feature 'User managing appearance releases' do
|
||||
click_on manage_button
|
||||
expect(page).not_to have_link('Download', exact: true)
|
||||
end
|
||||
|
||||
scenario "Review action in Manage menu is not visible" do
|
||||
create(:appearance_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_appearance_releases_path(project)
|
||||
click_on manage_button
|
||||
|
||||
expect(page).not_to have_link(review_action, exact: true)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
@@ -936,6 +1039,42 @@ feature 'User managing appearance releases' do
|
||||
'Some signature legal language'
|
||||
end
|
||||
|
||||
def review_action
|
||||
t 'appearance_releases.appearance_release.actions.review'
|
||||
end
|
||||
|
||||
def review_page_heading
|
||||
t 'approvals.new.heading', release_type: "Appearance Release"
|
||||
end
|
||||
|
||||
def approve_button
|
||||
t 'approvals.new.actions.approve'
|
||||
end
|
||||
|
||||
def for_office_use_only
|
||||
t 'contracts.for_office_use_only.heading'
|
||||
end
|
||||
|
||||
def producer_label
|
||||
t 'contracts.for_office_use_only.description_labels.producer'
|
||||
end
|
||||
|
||||
def production_label
|
||||
t 'contracts.for_office_use_only.description_labels.production'
|
||||
end
|
||||
|
||||
def issued_to_label
|
||||
t 'contracts.for_office_use_only.description_labels.issued_to'
|
||||
end
|
||||
|
||||
def issued_by_label
|
||||
t 'contracts.for_office_use_only.description_labels.issued_by'
|
||||
end
|
||||
|
||||
def date_issued
|
||||
t 'contracts.for_office_use_only.description_labels.date_issued'
|
||||
end
|
||||
|
||||
def amendments_heading
|
||||
t 'public.amendments.new.amendment.heading'
|
||||
end
|
||||
|
||||
@@ -25,6 +25,7 @@ feature 'User managing broadcasts' do
|
||||
|
||||
by 'filling out the form' do
|
||||
fill_in broadcast_name_field, with: 'My Broadcast'
|
||||
select_conference_option('Zoom')
|
||||
select_time_zone("New Delhi")
|
||||
end
|
||||
|
||||
@@ -352,5 +353,10 @@ feature 'User managing broadcasts' do
|
||||
t 'broadcasts.file.actions.delete_file'
|
||||
end
|
||||
|
||||
def select_conference_option(value)
|
||||
if value.present?
|
||||
select value, from: "broadcast[conference_option]"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -383,9 +383,104 @@ feature "User managing location releases" do
|
||||
end
|
||||
|
||||
context "when the user is account manager" do
|
||||
let(:current_user) { create(:user, :account_manager) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
scenario "Review action in Manage menu is visible" do
|
||||
create(:location_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_location_releases_path(project)
|
||||
|
||||
expect(page).to have_link(review_action, exact: true)
|
||||
end
|
||||
|
||||
scenario "Reviewing release" do
|
||||
create(:location_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_location_releases_path(project)
|
||||
|
||||
click_link review_action
|
||||
|
||||
expect(page).to have_content review_page_heading
|
||||
expect(page).to have_content approve_button
|
||||
end
|
||||
|
||||
scenario "Approved releases have checkmark and non-approved releases don't have checkmarks" do
|
||||
create(:location_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_location_releases_path(project)
|
||||
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 0)
|
||||
|
||||
create(:location_release_with_contract_template, :native, project: project, approved_by_user_email: "some@email.com", approved_at: DateTime.now)
|
||||
visit project_location_releases_path(project)
|
||||
|
||||
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 1)
|
||||
end
|
||||
|
||||
scenario 'When viewing the contract PDF of approved release there is page for office use only' do
|
||||
location_release = create(:location_release_with_contract_template,
|
||||
:native,
|
||||
project: project,
|
||||
person_first_name: 'Jane',
|
||||
person_last_name: 'Doe',
|
||||
approved_by_user_name: "Big Joe",
|
||||
approved_by_user_email: "some@email.com",
|
||||
approved_at: DateTime.now)
|
||||
|
||||
sign_in(current_user)
|
||||
visit project_location_releases_path(project)
|
||||
click_link *view_release_pdf_link_for(location_release)
|
||||
|
||||
expect(content_type).to eq('application/pdf')
|
||||
expect(content_disposition).to include('inline')
|
||||
expect(pdf_body).to have_content for_office_use_only.upcase
|
||||
expect(pdf_body).to have_content producer_label
|
||||
expect(pdf_body).to have_content production_label
|
||||
expect(pdf_body).to have_content issued_to_label
|
||||
expect(pdf_body).to have_content issued_by_label
|
||||
expect(pdf_body).to have_content date_issued
|
||||
expect(pdf_body).to have_content 'Big Joe'
|
||||
end
|
||||
|
||||
scenario 'When viewing the contract PDF of not approved release there is no page for office use only' do
|
||||
location_release = create(:location_release_with_contract_template,
|
||||
:native,
|
||||
project: project,
|
||||
person_first_name: 'Jane',
|
||||
person_last_name: 'Doe')
|
||||
|
||||
sign_in(current_user)
|
||||
visit project_location_releases_path(project)
|
||||
click_link *view_release_pdf_link_for(location_release)
|
||||
|
||||
expect(content_type).to eq('application/pdf')
|
||||
expect(content_disposition).to include('inline')
|
||||
expect(pdf_body).not_to have_content for_office_use_only.upcase
|
||||
expect(pdf_body).not_to have_content producer_label
|
||||
expect(pdf_body).not_to have_content production_label
|
||||
expect(pdf_body).not_to have_content issued_to_label
|
||||
expect(pdf_body).not_to have_content issued_by_label
|
||||
expect(pdf_body).not_to have_content date_issued
|
||||
expect(pdf_body).not_to have_content 'Big Joe'
|
||||
end
|
||||
end
|
||||
|
||||
context "when the user is project manager" do
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
scenario "Review action in Manage menu is not visible" do
|
||||
create(:location_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_location_releases_path(project)
|
||||
click_on manage_button
|
||||
|
||||
expect(page).not_to have_link(review_action, exact: true)
|
||||
end
|
||||
end
|
||||
|
||||
context "when the user is associate" do
|
||||
@@ -403,6 +498,15 @@ feature "User managing location releases" do
|
||||
click_on manage_button
|
||||
expect(page).not_to have_link("Download", exact: true)
|
||||
end
|
||||
|
||||
scenario "Review action in Manage menu is not visible" do
|
||||
create(:location_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_location_releases_path(project)
|
||||
click_on manage_button
|
||||
|
||||
expect(page).not_to have_link(review_action, exact: true)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
@@ -546,6 +650,42 @@ feature "User managing location releases" do
|
||||
'Some signature legal language'
|
||||
end
|
||||
|
||||
def review_action
|
||||
t 'location_releases.location_release.actions.review'
|
||||
end
|
||||
|
||||
def review_page_heading
|
||||
t 'approvals.new.heading', release_type: "Location Release"
|
||||
end
|
||||
|
||||
def approve_button
|
||||
t 'approvals.new.actions.approve'
|
||||
end
|
||||
|
||||
def for_office_use_only
|
||||
t 'contracts.for_office_use_only.heading'
|
||||
end
|
||||
|
||||
def producer_label
|
||||
t 'contracts.for_office_use_only.description_labels.producer'
|
||||
end
|
||||
|
||||
def production_label
|
||||
t 'contracts.for_office_use_only.description_labels.production'
|
||||
end
|
||||
|
||||
def issued_to_label
|
||||
t 'contracts.for_office_use_only.description_labels.issued_to'
|
||||
end
|
||||
|
||||
def issued_by_label
|
||||
t 'contracts.for_office_use_only.description_labels.issued_by'
|
||||
end
|
||||
|
||||
def date_issued
|
||||
t 'contracts.for_office_use_only.description_labels.date_issued'
|
||||
end
|
||||
|
||||
def amendments_heading
|
||||
t 'public.amendments.new.amendment.heading'
|
||||
end
|
||||
|
||||
@@ -421,9 +421,104 @@ feature "User managing material releases" do
|
||||
end
|
||||
|
||||
context "when the user is account manager" do
|
||||
let(:current_user) { create(:user, :account_manager) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
scenario "Review action in Manage menu is visible" do
|
||||
create(:material_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_material_releases_path(project)
|
||||
|
||||
expect(page).to have_link(review_action, exact: true)
|
||||
end
|
||||
|
||||
scenario "Reviewing release" do
|
||||
create(:material_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_material_releases_path(project)
|
||||
|
||||
click_link review_action
|
||||
|
||||
expect(page).to have_content review_page_heading
|
||||
expect(page).to have_content approve_button
|
||||
end
|
||||
|
||||
scenario "Approved releases have checkmark and non-approved releases don't have checkmarks" do
|
||||
create(:material_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_material_releases_path(project)
|
||||
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 0)
|
||||
|
||||
create(:material_release_with_contract_template, :native, project: project, approved_by_user_email: "some@email.com", approved_at: DateTime.now)
|
||||
visit project_material_releases_path(project)
|
||||
|
||||
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 1)
|
||||
end
|
||||
|
||||
scenario 'When viewing the contract PDF of approved release there is page for office use only' do
|
||||
material_release = create(:material_release_with_contract_template,
|
||||
:native,
|
||||
project: project,
|
||||
person_first_name: 'Jane',
|
||||
person_last_name: 'Doe',
|
||||
approved_by_user_name: "Big Joe",
|
||||
approved_by_user_email: "some@email.com",
|
||||
approved_at: DateTime.now)
|
||||
|
||||
sign_in(current_user)
|
||||
visit project_material_releases_path(project)
|
||||
click_link *view_release_pdf_link_for(material_release)
|
||||
|
||||
expect(content_type).to eq('application/pdf')
|
||||
expect(content_disposition).to include('inline')
|
||||
expect(pdf_body).to have_content for_office_use_only.upcase
|
||||
expect(pdf_body).to have_content producer_label
|
||||
expect(pdf_body).to have_content production_label
|
||||
expect(pdf_body).to have_content issued_to_label
|
||||
expect(pdf_body).to have_content issued_by_label
|
||||
expect(pdf_body).to have_content date_issued
|
||||
expect(pdf_body).to have_content 'Big Joe'
|
||||
end
|
||||
|
||||
scenario 'When viewing the contract PDF of not approved release there is no page for office use only' do
|
||||
material_release = create(:material_release_with_contract_template,
|
||||
:native,
|
||||
project: project,
|
||||
person_first_name: 'Jane',
|
||||
person_last_name: 'Doe')
|
||||
|
||||
sign_in(current_user)
|
||||
visit project_material_releases_path(project)
|
||||
click_link *view_release_pdf_link_for(material_release)
|
||||
|
||||
expect(content_type).to eq('application/pdf')
|
||||
expect(content_disposition).to include('inline')
|
||||
expect(pdf_body).not_to have_content for_office_use_only.upcase
|
||||
expect(pdf_body).not_to have_content producer_label
|
||||
expect(pdf_body).not_to have_content production_label
|
||||
expect(pdf_body).not_to have_content issued_to_label
|
||||
expect(pdf_body).not_to have_content issued_by_label
|
||||
expect(pdf_body).not_to have_content date_issued
|
||||
expect(pdf_body).not_to have_content 'Big Joe'
|
||||
end
|
||||
end
|
||||
|
||||
context "when the user is project manager" do
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
scenario "Review action in Manage menu is not visible" do
|
||||
create(:material_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_material_releases_path(project)
|
||||
click_on "Manage"
|
||||
|
||||
expect(page).not_to have_link(review_action, exact: true)
|
||||
end
|
||||
end
|
||||
|
||||
context "when the user is associate" do
|
||||
@@ -441,6 +536,15 @@ feature "User managing material releases" do
|
||||
click_on "Manage"
|
||||
expect(page).not_to have_link("Download", exact: true)
|
||||
end
|
||||
|
||||
scenario "Review action in Manage menu is not visible" do
|
||||
create(:material_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_material_releases_path(project)
|
||||
click_on "Manage"
|
||||
|
||||
expect(page).not_to have_link(review_action, exact: true)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
@@ -589,6 +693,42 @@ feature "User managing material releases" do
|
||||
'Some signature legal language'
|
||||
end
|
||||
|
||||
def review_action
|
||||
t 'material_releases.material_release.actions.review'
|
||||
end
|
||||
|
||||
def review_page_heading
|
||||
t 'approvals.new.heading', release_type: "Material Release"
|
||||
end
|
||||
|
||||
def approve_button
|
||||
t 'approvals.new.actions.approve'
|
||||
end
|
||||
|
||||
def for_office_use_only
|
||||
t 'contracts.for_office_use_only.heading'
|
||||
end
|
||||
|
||||
def producer_label
|
||||
t 'contracts.for_office_use_only.description_labels.producer'
|
||||
end
|
||||
|
||||
def production_label
|
||||
t 'contracts.for_office_use_only.description_labels.production'
|
||||
end
|
||||
|
||||
def issued_to_label
|
||||
t 'contracts.for_office_use_only.description_labels.issued_to'
|
||||
end
|
||||
|
||||
def issued_by_label
|
||||
t 'contracts.for_office_use_only.description_labels.issued_by'
|
||||
end
|
||||
|
||||
def date_issued
|
||||
t 'contracts.for_office_use_only.description_labels.date_issued'
|
||||
end
|
||||
|
||||
def person_is_minor_checkbox
|
||||
'material_release_minor'
|
||||
end
|
||||
|
||||
@@ -215,6 +215,15 @@ feature "User managing medical releases" do
|
||||
expect(page).to have_link("Download", exact: true, count: 2)
|
||||
end
|
||||
|
||||
scenario "Review action in Manage menu is visible" do
|
||||
create(:medical_release_with_contract_template, :native, project: project)
|
||||
create(:medical_release_with_contract_template, :non_native, project: project)
|
||||
|
||||
visit project_medical_releases_path(project)
|
||||
|
||||
expect(page).to have_link(review_action, exact: true)
|
||||
end
|
||||
|
||||
scenario "Downloading PDF of native medical release is possible" do
|
||||
native_release = create(:medical_release_with_contract_template, :native, project: project)
|
||||
|
||||
@@ -224,6 +233,64 @@ feature "User managing medical releases" do
|
||||
expect(content_type).to eq('application/pdf')
|
||||
end
|
||||
|
||||
scenario "Reviewing release" do
|
||||
create(:medical_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_medical_releases_path(project)
|
||||
|
||||
click_link review_action
|
||||
|
||||
expect(page).to have_content review_page_heading
|
||||
expect(page).to have_content approve_button
|
||||
end
|
||||
|
||||
scenario 'When viewing the contract PDF of approved release there is page for office use only' do
|
||||
medical_release = create(:medical_release_with_contract_template,
|
||||
:native,
|
||||
project: project,
|
||||
person_first_name: 'Jane',
|
||||
person_last_name: 'Doe',
|
||||
approved_by_user_name: "Big Joe",
|
||||
approved_by_user_email: "some@email.com",
|
||||
approved_at: DateTime.now)
|
||||
|
||||
sign_in(current_user)
|
||||
visit project_medical_releases_path(project)
|
||||
click_link *view_release_pdf_link_for(medical_release)
|
||||
|
||||
expect(content_type).to eq('application/pdf')
|
||||
expect(content_disposition).to include('inline')
|
||||
expect(pdf_body).to have_content for_office_use_only.upcase
|
||||
expect(pdf_body).to have_content producer_label
|
||||
expect(pdf_body).to have_content production_label
|
||||
expect(pdf_body).to have_content issued_to_label
|
||||
expect(pdf_body).to have_content issued_by_label
|
||||
expect(pdf_body).to have_content date_issued
|
||||
expect(pdf_body).to have_content 'Big Joe'
|
||||
end
|
||||
|
||||
scenario 'When viewing the contract PDF of not approved release there is no page for office use only' do
|
||||
medical_release = create(:medical_release_with_contract_template,
|
||||
:native,
|
||||
project: project,
|
||||
person_first_name: 'Jane',
|
||||
person_last_name: 'Doe')
|
||||
|
||||
sign_in(current_user)
|
||||
visit project_medical_releases_path(project)
|
||||
click_link *view_release_pdf_link_for(medical_release)
|
||||
|
||||
expect(content_type).to eq('application/pdf')
|
||||
expect(content_disposition).to include('inline')
|
||||
expect(pdf_body).not_to have_content for_office_use_only.upcase
|
||||
expect(pdf_body).not_to have_content producer_label
|
||||
expect(pdf_body).not_to have_content production_label
|
||||
expect(pdf_body).not_to have_content issued_to_label
|
||||
expect(pdf_body).not_to have_content issued_by_label
|
||||
expect(pdf_body).not_to have_content date_issued
|
||||
expect(pdf_body).not_to have_content 'Big Joe'
|
||||
end
|
||||
|
||||
scenario 'viewing contract PDF with medical questionnaire' do
|
||||
contract_template = create(:medical_release_contract_template, project: project, questionnaire_legal_text: "Questionnaire legal text", question_1_text: "Question 1 text")
|
||||
medical_release = create(:medical_release,
|
||||
@@ -276,6 +343,15 @@ feature "User managing medical releases" do
|
||||
expect(page).to have_link("Download", exact: true, count: 0)
|
||||
end
|
||||
|
||||
scenario "Review action in Manage menu is not visible" do
|
||||
create(:medical_release_with_contract_template, :native, project: project)
|
||||
create(:medical_release_with_contract_template, :non_native, project: project)
|
||||
|
||||
visit project_medical_releases_path(project)
|
||||
|
||||
expect(page).not_to have_link(review_action, exact: true)
|
||||
end
|
||||
|
||||
scenario "Downloading PDF of native medical release is not possible" do
|
||||
native_release = create(:medical_release_with_contract_template, :native, project: project)
|
||||
|
||||
@@ -320,6 +396,15 @@ feature "User managing medical releases" do
|
||||
expect(page).to have_link("Download", exact: true, count: 0)
|
||||
end
|
||||
|
||||
scenario "Review action in Manage menu is not visible" do
|
||||
create(:medical_release_with_contract_template, :native, project: project)
|
||||
create(:medical_release_with_contract_template, :non_native, project: project)
|
||||
|
||||
visit project_medical_releases_path(project)
|
||||
|
||||
expect(page).not_to have_link(review_action, exact: true)
|
||||
end
|
||||
|
||||
scenario "Downloading PDF of native medical release is not possible" do
|
||||
native_release = create(:medical_release_with_contract_template, :native, project: project)
|
||||
|
||||
@@ -499,4 +584,40 @@ feature "User managing medical releases" do
|
||||
def dummy_signature_legal_text
|
||||
'Some signature legal language'
|
||||
end
|
||||
|
||||
def review_action
|
||||
t 'medical_releases.medical_release.actions.review'
|
||||
end
|
||||
|
||||
def review_page_heading
|
||||
t 'approvals.new.heading', release_type: "Medical Release"
|
||||
end
|
||||
|
||||
def approve_button
|
||||
t 'approvals.new.actions.approve'
|
||||
end
|
||||
|
||||
def for_office_use_only
|
||||
t 'contracts.for_office_use_only.heading'
|
||||
end
|
||||
|
||||
def producer_label
|
||||
t 'contracts.for_office_use_only.description_labels.producer'
|
||||
end
|
||||
|
||||
def production_label
|
||||
t 'contracts.for_office_use_only.description_labels.production'
|
||||
end
|
||||
|
||||
def issued_to_label
|
||||
t 'contracts.for_office_use_only.description_labels.issued_to'
|
||||
end
|
||||
|
||||
def issued_by_label
|
||||
t 'contracts.for_office_use_only.description_labels.issued_by'
|
||||
end
|
||||
|
||||
def date_issued
|
||||
t 'contracts.for_office_use_only.description_labels.date_issued'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -79,6 +79,83 @@ feature "User managing misc releases" do
|
||||
expect(content_type).to eq('application/pdf')
|
||||
end
|
||||
|
||||
scenario "Review action in Manage menu is visible" do
|
||||
create(:misc_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_misc_releases_path(project)
|
||||
|
||||
expect(page).to have_link(review_action, exact: true)
|
||||
end
|
||||
|
||||
scenario "Reviewing release" do
|
||||
create(:misc_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_misc_releases_path(project)
|
||||
|
||||
click_link review_action
|
||||
|
||||
expect(page).to have_content review_page_heading
|
||||
expect(page).to have_content approve_button
|
||||
end
|
||||
|
||||
scenario "Approved releases have checkmark and non-approved releases don't have checkmarks" do
|
||||
create(:misc_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_misc_releases_path(project)
|
||||
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 0)
|
||||
|
||||
create(:misc_release_with_contract_template, :native, project: project, approved_by_user_email: "some@email.com", approved_at: DateTime.now)
|
||||
visit project_misc_releases_path(project)
|
||||
|
||||
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 1)
|
||||
end
|
||||
|
||||
scenario 'When viewing the contract PDF of approved release there is page for office use only' do
|
||||
misc_release = create(:misc_release_with_contract_template,
|
||||
:native,
|
||||
project: project,
|
||||
person_first_name: 'Jane',
|
||||
person_last_name: 'Doe',
|
||||
approved_by_user_name: "Big Joe",
|
||||
approved_by_user_email: "some@email.com",
|
||||
approved_at: DateTime.now)
|
||||
|
||||
sign_in(current_user)
|
||||
visit project_misc_releases_path(project)
|
||||
click_link *view_release_pdf_link_for(misc_release)
|
||||
|
||||
expect(content_type).to eq('application/pdf')
|
||||
expect(content_disposition).to include('inline')
|
||||
expect(pdf_body).to have_content for_office_use_only.upcase
|
||||
expect(pdf_body).to have_content producer_label
|
||||
expect(pdf_body).to have_content production_label
|
||||
expect(pdf_body).to have_content issued_to_label
|
||||
expect(pdf_body).to have_content issued_by_label
|
||||
expect(pdf_body).to have_content date_issued
|
||||
expect(pdf_body).to have_content 'Big Joe'
|
||||
end
|
||||
|
||||
scenario 'When viewing the contract PDF of not approved release there is no page for office use only' do
|
||||
misc_release = create(:misc_release_with_contract_template,
|
||||
:native,
|
||||
project: project,
|
||||
person_first_name: 'Jane',
|
||||
person_last_name: 'Doe')
|
||||
|
||||
sign_in(current_user)
|
||||
visit project_misc_releases_path(project)
|
||||
click_link *view_release_pdf_link_for(misc_release)
|
||||
|
||||
expect(content_type).to eq('application/pdf')
|
||||
expect(content_disposition).to include('inline')
|
||||
expect(pdf_body).not_to have_content for_office_use_only.upcase
|
||||
expect(pdf_body).not_to have_content producer_label
|
||||
expect(pdf_body).not_to have_content production_label
|
||||
expect(pdf_body).not_to have_content issued_to_label
|
||||
expect(pdf_body).not_to have_content issued_by_label
|
||||
expect(pdf_body).not_to have_content date_issued
|
||||
expect(pdf_body).not_to have_content 'Big Joe'
|
||||
end
|
||||
|
||||
scenario 'viewing the contract PDF' do
|
||||
misc_release = create(:misc_release,
|
||||
@@ -141,6 +218,14 @@ feature "User managing misc releases" do
|
||||
|
||||
expect(page).to have_link("Download", exact: true, count: 0)
|
||||
end
|
||||
|
||||
scenario "Review action in Manage menu is not visible" do
|
||||
create(:misc_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_misc_releases_path(project)
|
||||
|
||||
expect(page).not_to have_link(review_action, exact: true)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
@@ -215,4 +300,40 @@ feature "User managing misc releases" do
|
||||
def view_release_pdf_link_for(release)
|
||||
['Download', href: misc_release_contracts_path(release, format: 'pdf')]
|
||||
end
|
||||
|
||||
def review_action
|
||||
t 'misc_releases.misc_release.actions.review'
|
||||
end
|
||||
|
||||
def review_page_heading
|
||||
t 'approvals.new.heading', release_type: "Misc Release"
|
||||
end
|
||||
|
||||
def approve_button
|
||||
t 'approvals.new.actions.approve'
|
||||
end
|
||||
|
||||
def for_office_use_only
|
||||
t 'contracts.for_office_use_only.heading'
|
||||
end
|
||||
|
||||
def producer_label
|
||||
t 'contracts.for_office_use_only.description_labels.producer'
|
||||
end
|
||||
|
||||
def production_label
|
||||
t 'contracts.for_office_use_only.description_labels.production'
|
||||
end
|
||||
|
||||
def issued_to_label
|
||||
t 'contracts.for_office_use_only.description_labels.issued_to'
|
||||
end
|
||||
|
||||
def issued_by_label
|
||||
t 'contracts.for_office_use_only.description_labels.issued_by'
|
||||
end
|
||||
|
||||
def date_issued
|
||||
t 'contracts.for_office_use_only.description_labels.date_issued'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -92,9 +92,39 @@ feature "User managing music releases" do
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
scenario "Review action in Manage menu is visible" do
|
||||
create(:music_release_with_contract_template, project: project)
|
||||
|
||||
visit project_music_releases_path(project)
|
||||
click_on "Manage"
|
||||
|
||||
expect(page).to have_link(review_action, exact: true)
|
||||
end
|
||||
|
||||
scenario "Reviewing release" do
|
||||
create(:music_release_with_contract_template, project: project)
|
||||
|
||||
visit project_music_releases_path(project)
|
||||
click_on "Manage"
|
||||
|
||||
click_link review_action
|
||||
|
||||
expect(page).to have_content review_page_heading
|
||||
expect(page).to have_content approve_button
|
||||
end
|
||||
end
|
||||
|
||||
context "when the user is project manager" do
|
||||
scenario "Review action in Manage menu is not visible" do
|
||||
create(:music_release_with_contract_template, project: project)
|
||||
|
||||
sign_in current_user
|
||||
visit project_music_releases_path(project)
|
||||
click_on "Manage"
|
||||
|
||||
expect(page).not_to have_link(review_action, exact: true)
|
||||
end
|
||||
end
|
||||
|
||||
context "when the user is associate" do
|
||||
@@ -103,15 +133,24 @@ feature "User managing music releases" do
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
|
||||
scenario "should not show download" do
|
||||
collection1 = create(:music_release, name: "EDM Music", project: project)
|
||||
|
||||
|
||||
visit project_music_releases_path(project)
|
||||
|
||||
|
||||
click_on "Manage"
|
||||
expect(page).not_to have_link("Download", exact: true)
|
||||
end
|
||||
|
||||
scenario "Review action in Manage menu is not visible" do
|
||||
create(:music_release_with_contract_template, project: project)
|
||||
|
||||
visit project_music_releases_path(project)
|
||||
click_on "Manage"
|
||||
|
||||
expect(page).not_to have_link(review_action, exact: true)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
@@ -177,4 +216,16 @@ feature "User managing music releases" do
|
||||
select "Other", from: "Restriction"
|
||||
fill_in "Describe other restrictions", with: "Test"
|
||||
end
|
||||
|
||||
def review_action
|
||||
t 'music_releases.music_release.actions.review'
|
||||
end
|
||||
|
||||
def review_page_heading
|
||||
t 'approvals.new.heading', release_type: "Music Release"
|
||||
end
|
||||
|
||||
def approve_button
|
||||
t 'approvals.new.actions.approve'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -374,9 +374,104 @@ feature "User managing talent releases" do
|
||||
end
|
||||
|
||||
context "when the user is account manager" do
|
||||
let(:current_user) { create(:user, :account_manager) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
scenario "Review action in Manage menu is visible" do
|
||||
create(:talent_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_talent_releases_path(project)
|
||||
|
||||
expect(page).to have_link(review_action, exact: true)
|
||||
end
|
||||
|
||||
scenario "Reviewing release" do
|
||||
create(:talent_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_talent_releases_path(project)
|
||||
|
||||
click_link review_action
|
||||
|
||||
expect(page).to have_content review_page_heading
|
||||
expect(page).to have_content approve_button
|
||||
end
|
||||
|
||||
scenario "Approved releases have checkmark and non-approved releases don't have checkmarks" do
|
||||
create(:talent_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_talent_releases_path(project)
|
||||
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 0)
|
||||
|
||||
create(:talent_release_with_contract_template, :native, project: project, approved_by_user_email: "some@email.com", approved_at: DateTime.now)
|
||||
visit project_talent_releases_path(project)
|
||||
|
||||
expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 1)
|
||||
end
|
||||
|
||||
scenario 'When viewing the contract PDF of approved release there is page for office use only' do
|
||||
talent_release = create(:talent_release_with_contract_template,
|
||||
:native,
|
||||
project: project,
|
||||
person_first_name: 'Jane',
|
||||
person_last_name: 'Doe',
|
||||
approved_by_user_name: "Big Joe",
|
||||
approved_by_user_email: "some@email.com",
|
||||
approved_at: DateTime.now)
|
||||
|
||||
sign_in(current_user)
|
||||
visit project_talent_releases_path(project)
|
||||
click_link *view_release_pdf_link_for(talent_release)
|
||||
|
||||
expect(content_type).to eq('application/pdf')
|
||||
expect(content_disposition).to include('inline')
|
||||
expect(pdf_body).to have_content for_office_use_only.upcase
|
||||
expect(pdf_body).to have_content producer_label
|
||||
expect(pdf_body).to have_content production_label
|
||||
expect(pdf_body).to have_content issued_to_label
|
||||
expect(pdf_body).to have_content issued_by_label
|
||||
expect(pdf_body).to have_content date_issued
|
||||
expect(pdf_body).to have_content 'Big Joe'
|
||||
end
|
||||
|
||||
scenario 'When viewing the contract PDF of not approved release there is no page for office use only' do
|
||||
talent_release = create(:talent_release_with_contract_template,
|
||||
:native,
|
||||
project: project,
|
||||
person_first_name: 'Jane',
|
||||
person_last_name: 'Doe')
|
||||
|
||||
sign_in(current_user)
|
||||
visit project_talent_releases_path(project)
|
||||
click_link *view_release_pdf_link_for(talent_release)
|
||||
|
||||
expect(content_type).to eq('application/pdf')
|
||||
expect(content_disposition).to include('inline')
|
||||
expect(pdf_body).not_to have_content for_office_use_only.upcase
|
||||
expect(pdf_body).not_to have_content producer_label
|
||||
expect(pdf_body).not_to have_content production_label
|
||||
expect(pdf_body).not_to have_content issued_to_label
|
||||
expect(pdf_body).not_to have_content issued_by_label
|
||||
expect(pdf_body).not_to have_content date_issued
|
||||
expect(pdf_body).not_to have_content 'Big Joe'
|
||||
end
|
||||
end
|
||||
|
||||
context "when the user is project manager" do
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
scenario "Review action in Manage menu is not visible" do
|
||||
create(:talent_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_talent_releases_path(project)
|
||||
click_on "Manage"
|
||||
|
||||
expect(page).not_to have_link(review_action, exact: true)
|
||||
end
|
||||
end
|
||||
|
||||
context "when the user is associate" do
|
||||
@@ -394,6 +489,15 @@ feature "User managing talent releases" do
|
||||
click_on "Manage"
|
||||
expect(page).not_to have_link("Download", exact: true)
|
||||
end
|
||||
|
||||
scenario "Review action in Manage menu is not visible" do
|
||||
create(:talent_release_with_contract_template, :native, project: project)
|
||||
|
||||
visit project_talent_releases_path(project)
|
||||
click_on "Manage"
|
||||
|
||||
expect(page).not_to have_link(review_action, exact: true)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
@@ -575,4 +679,40 @@ feature "User managing talent releases" do
|
||||
def dummy_signature_legal_text
|
||||
'Some signature legal language'
|
||||
end
|
||||
|
||||
def review_action
|
||||
t 'talent_releases.talent_release.actions.review'
|
||||
end
|
||||
|
||||
def review_page_heading
|
||||
t 'approvals.new.heading', release_type: "Talent Release"
|
||||
end
|
||||
|
||||
def approve_button
|
||||
t 'approvals.new.actions.approve'
|
||||
end
|
||||
|
||||
def for_office_use_only
|
||||
t 'contracts.for_office_use_only.heading'
|
||||
end
|
||||
|
||||
def producer_label
|
||||
t 'contracts.for_office_use_only.description_labels.producer'
|
||||
end
|
||||
|
||||
def production_label
|
||||
t 'contracts.for_office_use_only.description_labels.production'
|
||||
end
|
||||
|
||||
def issued_to_label
|
||||
t 'contracts.for_office_use_only.description_labels.issued_to'
|
||||
end
|
||||
|
||||
def issued_by_label
|
||||
t 'contracts.for_office_use_only.description_labels.issued_by'
|
||||
end
|
||||
|
||||
def date_issued
|
||||
t 'contracts.for_office_use_only.description_labels.date_issued'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe AcquiredMediaRelease do
|
||||
it_behaves_like 'an approvable'
|
||||
it_behaves_like "a contractable"
|
||||
it_behaves_like "an exploitable"
|
||||
it_behaves_like "a notable"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe AppearanceRelease do
|
||||
it_behaves_like 'an approvable'
|
||||
it_behaves_like 'a contractable'
|
||||
it_behaves_like 'an exploitable'
|
||||
it_behaves_like 'a notable'
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe LocationRelease do
|
||||
it_behaves_like 'an approvable'
|
||||
it_behaves_like "a contractable"
|
||||
it_behaves_like "an exploitable"
|
||||
it_behaves_like "a notable"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe MaterialRelease do
|
||||
it_behaves_like 'an approvable'
|
||||
it_behaves_like "a contractable"
|
||||
it_behaves_like "an exploitable"
|
||||
it_behaves_like "a notable"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe MedicalRelease do
|
||||
it_behaves_like 'an approvable'
|
||||
it_behaves_like "a contractable"
|
||||
it_behaves_like "a notable"
|
||||
it_behaves_like "a photoable"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe MiscRelease, type: :model do
|
||||
it_behaves_like 'an approvable'
|
||||
it_behaves_like "a contractable"
|
||||
it_behaves_like "a notable"
|
||||
it_behaves_like "a photoable"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe MusicRelease do
|
||||
it_behaves_like 'an approvable'
|
||||
it_behaves_like "a contractable"
|
||||
it_behaves_like "an exploitable"
|
||||
it_behaves_like "a notable"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe TalentRelease do
|
||||
it_behaves_like 'an approvable'
|
||||
it_behaves_like "a contractable"
|
||||
it_behaves_like "an exploitable"
|
||||
it_behaves_like "a notable"
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
shared_examples_for "an approvable" do
|
||||
it { is_expected.to respond_to(:approved_by_user_signature) }
|
||||
|
||||
describe "#approve_by" do
|
||||
before do
|
||||
allow(BigMediaTime).to receive(:time_zone_now).and_return(1.week.ago)
|
||||
end
|
||||
|
||||
it "stores info about the approving user" do
|
||||
user = double(full_name: "Jane Doe", email: "jane.doe@test.com")
|
||||
|
||||
subject.approve_by(user)
|
||||
|
||||
expect(subject.approved_by_user_name).to eq "Jane Doe"
|
||||
expect(subject.approved_by_user_email).to eq "jane.doe@test.com"
|
||||
expect(subject.approved_at).to eq BigMediaTime.time_zone_now
|
||||
end
|
||||
|
||||
context "when approval has already been given" do
|
||||
it "does not change the existing info" do
|
||||
user1 = double(full_name: "Jane Doe", email: "jane.doe@test.com")
|
||||
subject.approve_by(user1)
|
||||
|
||||
expect(subject.approved_by_user_name).to eq "Jane Doe"
|
||||
expect(subject.approved_by_user_email).to eq "jane.doe@test.com"
|
||||
expect(subject.approved_at).to eq BigMediaTime.time_zone_now
|
||||
|
||||
user2 = double(full_name: "John Doe", email: "john.doe@test.com")
|
||||
subject.approve_by(user2)
|
||||
|
||||
expect(subject.approved_by_user_name).to eq "Jane Doe"
|
||||
expect(subject.approved_by_user_email).to eq "jane.doe@test.com"
|
||||
expect(subject.approved_at).to eq BigMediaTime.time_zone_now
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#approved?" do
|
||||
it "indicates whether or not it has been approved" do
|
||||
subject.approved_at = nil
|
||||
expect(subject).not_to be_approved
|
||||
|
||||
subject.approved_at = 1.week.ago
|
||||
expect(subject).to be_approved
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2,7 +2,7 @@ module SignatureHelper
|
||||
def draw_signature(file, signature_field_id)
|
||||
data_uri = ActionController::Base.helpers.escape_javascript(Base64Image.from_image(file).data_uri)
|
||||
page.execute_script <<-JS
|
||||
document.getElementById("#{signature_field_id}").value = "#{data_uri}";
|
||||
$("##{signature_field_id}").val("#{data_uri}")
|
||||
JS
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user