diff --git a/app/views/contract_templates/_form.html.erb b/app/views/contract_templates/_form.html.erb
index 09a0203..15d37ff 100644
--- a/app/views/contract_templates/_form.html.erb
+++ b/app/views/contract_templates/_form.html.erb
@@ -2,7 +2,7 @@
<%= field_set_tag content_tag(:span, t(".release_info.heading"), class: "h6 text-muted text-uppercase") do %>
<%= 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(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) } }, 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(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" %>
<%= form.radio_button :accessibility, :public_template, label: "Public", wrapper_class: "mr-3" %>
@@ -29,6 +29,11 @@
<%= form.rich_text_area :guardian_clause %>
<% end %>
+
+ <%= form.form_group do %>
+ <%= form.rich_text_area :amendment_clause %>
+ <% end %>
+
<%= form.form_group do %>
<%= form.rich_text_area :signature_legal_text %>
diff --git a/app/views/contract_templates/splash.html.erb b/app/views/contract_templates/splash.html.erb
index 26f22f9..d79944e 100644
--- a/app/views/contract_templates/splash.html.erb
+++ b/app/views/contract_templates/splash.html.erb
@@ -6,7 +6,8 @@
<%= link_to t(".actions.book_demo"), 'https://meetings.hubspot.com/bray2', class: "btn btn-primary border align-self-center h-50 ml-auto mr-2 pb-2", target: '_blank' %>
<% if policy(ContractTemplate).new? %>
- <%= link_to t(".actions.create_template"), [:new, @project, :contract_template], class: "btn btn-success border align-self-center h-50 pb-2" %>
+ <%= link_to t(".actions.create_template"), [:new, @project, :contract_template], class: "btn btn-success border align-self-center h-50 mr-2 pb-2" %>
+ <%= link_to t(".actions.import_template"), [:new, @project, :release_template_imports], class: "btn btn-light border align-self-center h-50 pb-2" %>
<% end %>
@@ -47,4 +48,4 @@
-
\ No newline at end of file
+
diff --git a/app/views/contracts/_amendment_page.html.erb b/app/views/contracts/_amendment_page.html.erb
new file mode 100644
index 0000000..427dc9a
--- /dev/null
+++ b/app/views/contracts/_amendment_page.html.erb
@@ -0,0 +1,19 @@
+<% if preview %>
+ PREVIEW ONLY
+<% end %>
+
+<%= t '.heading' %>
+
+
+ <%= description_list_pair "#{t('.description_labels.amendment_clause')}:", releasable.contract_template.amendment_clause %>
+ <%= description_list_pair "#{t('.description_labels.amendment_signer_name')}:", releasable.amendment_signer_name %>
+
+ - <%= t('.description_labels.amendment_signature') %>:
+ -
+ <% if preview %>
+ <%= image_tag dummy_signature %>
+ <% elsif releasable.amendment_signature.attached? %>
+ <%= image_tag releasable.amendment_signature.variant(auto_orient: true, resize: "200x200") %>
+ <% end %>
+
+
\ No newline at end of file
diff --git a/app/views/contracts/_signature_page.html.erb b/app/views/contracts/_signature_page.html.erb
index 1f6265b..90727d7 100644
--- a/app/views/contracts/_signature_page.html.erb
+++ b/app/views/contracts/_signature_page.html.erb
@@ -18,10 +18,14 @@
<% end %>
<% end %>
- <%= description_list_pair_for releasable, :name, append: ":" %>
- <%= description_list_pair "Contact Address:", releasable.contact_person.address %>
- <%= description_list_pair "Contact Phone:", releasable.contact_person.phone %>
- <%= description_list_pair "Contact Email:", releasable.contact_person.email %>
+ <%= description_list_pair t(".labels.#{releasable.model_name.param_key}.name", default: "Name"), releasable.name, append: ":" %>
+ <% if releasable.model_name == "LocationRelease" %>
+ <%= description_list_pair "Location Address:", releasable.address %>
+ <%= description_list_pair "Owner Name", releasable.person_name, append: ":" %>
+ <% end %>
+ <%= description_list_pair t(".labels.#{releasable.model_name.param_key}.contact_person_address", default: "Contact Address"), releasable.contact_person.address, append: ":" %>
+ <%= description_list_pair t(".labels.#{releasable.model_name.param_key}.contact_person_phone", default: "Contact Phone"), releasable.contact_person.phone, append: ":" %>
+ <%= description_list_pair t(".labels.#{releasable.model_name.param_key}.contact_person_email", default: "Contact Email"), releasable.contact_person.email, append: ":" %>
<% if releasable.model_name == "AppearanceRelease" %>
<%= description_list_pair "Person Date of Birth:", releasable&.person_date_of_birth&.strftime("%D") %>
<% end %>
diff --git a/app/views/contracts/pdf.html.erb b/app/views/contracts/pdf.html.erb
index dd01e5f..edeab19 100644
--- a/app/views/contracts/pdf.html.erb
+++ b/app/views/contracts/pdf.html.erb
@@ -26,6 +26,12 @@
<%= render "contracts/signature_page", releasable: releasable, contract_template: contract_template, preview: preview %>
+<% if releasable.respond_to?(:amendment_signed?) && releasable.amendment_signed? %>
+
+ <%= render "contracts/amendment_page", releasable: releasable, preview: preview %>
+
+<%end %>
+
<% if releasable.respond_to?(:approved?) && releasable.approved? %>
<%= render "contracts/for_office_use_only", releasable: releasable, preview: preview %>
diff --git a/app/views/location_releases/_location_release.html.erb b/app/views/location_releases/_location_release.html.erb
index e5b9c76..a829689 100644
--- a/app/views/location_releases/_location_release.html.erb
+++ b/app/views/location_releases/_location_release.html.erb
@@ -30,6 +30,17 @@
<%= location_release.signed_on %>
|
+
+ <% if location_release.amendment_signed? %>
+
+ <% elsif location_release.amendment_signable? %>
+
+ <% end %>
+ |
@@ -44,6 +55,9 @@
<% if policy(location_release).edit_photos? %>
<%= link_to fa_icon("picture-o fw", text: "Photos"), [:edit, location_release, :photos], class: "dropdown-item" %>
<% end %>
+ <% if policy(location_release).sign_amendment? && location_release.amendment_signable? && !location_release.amendment_signed? %>
+ <%= link_to fa_icon("file-text fw", text: t('.actions.sign_amendment')), [:new, location_release.project.account, location_release.project, location_release.contract_template, location_release, :amendment], class: "dropdown-item", target: "_blank" %>
+ <% end %>
<% if policy(Contract).show? && (location_release.contract.attached? || location_release.contract_template.present?) %>
<%= link_to fa_icon("download fw", text: "Download"), [location_release, :contracts, format: "pdf"], class: "dropdown-item", target: "_blank" %>
<% end %>
diff --git a/app/views/location_releases/index.html.erb b/app/views/location_releases/index.html.erb
index 96ec918..f319ea8 100644
--- a/app/views/location_releases/index.html.erb
+++ b/app/views/location_releases/index.html.erb
@@ -28,12 +28,12 @@
| <%= check_box_tag "location_release_ids[]", false, false %> |
<%= t '.table_headers.approved'%> |
|
- <%= LocationRelease.human_attribute_name(:name) %> |
+ <%= t(".table_headers.name") %> |
<%= t(".table_headers.address") %>
| <%= t(".table_headers.notes") %> |
<%= t(".table_headers.tags") %> |
- <%= t(".table_headers.signed_at") %> |
-
+ <%= t(".table_headers.signed_at") %> |
+ |
|
diff --git a/app/views/public/amendments/create.html.erb b/app/views/public/amendments/create.html.erb
new file mode 100644
index 0000000..cdc2055
--- /dev/null
+++ b/app/views/public/amendments/create.html.erb
@@ -0,0 +1,3 @@
+<% message = local_assigns[:already_signed] ? t('.amendment_already_signed_message') : t('.amendment_signed_message') %>
+<% alert_type = local_assigns[:already_signed] ? "alert-warning" : "alert-success" %>
+<%= message %>
diff --git a/app/views/public/amendments/new.html.erb b/app/views/public/amendments/new.html.erb
new file mode 100644
index 0000000..24b31c3
--- /dev/null
+++ b/app/views/public/amendments/new.html.erb
@@ -0,0 +1,30 @@
+
+
+
+
+
+ <%= 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| %>
+ <%= card_field_set_tag t(".amendment.heading") do %>
+
<%= @contract_template.amendment_clause %>
+ <% end %>
+
+
+
+
+ <%= form.text_field :amendment_signer_name, required: true, wrapper_class: "col-sm-6" %>
+
+
+ <%= card_field_set_tag t(".signature.heading") do %>
+ <%= render "shared/signature_fields", signature_field: :amendment_signature_base64, form: form %>
+ <% end %>
+
+
+ <%= form.button t("shared.submit_release_long"), class: "btn btn-block btn-lg btn-success", data: { disable_with: t("shared.disable_with") } %>
+
+ <% end %>
+
+
diff --git a/app/views/shared/_signature_fields.html.erb b/app/views/shared/_signature_fields.html.erb
index eb1fc6e..ec2b3dc 100644
--- a/app/views/shared/_signature_fields.html.erb
+++ b/app/views/shared/_signature_fields.html.erb
@@ -1,3 +1,4 @@
+<% signature_field = local_assigns[:signature_field] ? local_assigns[:signature_field] : :signature_base64 %>
<% if local_assigns[:instruction] %>
@@ -6,7 +7,7 @@
<% end %>
-<%= form.hidden_field :signature_base64, data: { ujs_target: "signature-input" } %>
+<%= form.hidden_field signature_field, data: { ujs_target: "signature-input" } %>
<%= button_tag class: "btn btn-sm btn-danger", data: { behavior: "clear-digital-signature" } do %>
<%= fa_icon "refresh" %> <%= t "shared.clear" %>
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 0031f0f..7363cdd 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -214,6 +214,10 @@ en:
destroy:
alert: A live stream has been deleted
api_error: Something went wrong, please try again later after some time
+ file:
+ actions:
+ delete_file: Delete
+ confirm_delete: Are you sure?
index:
actions:
new: Create New Live Stream
@@ -307,6 +311,7 @@ en:
actions:
book_demo: Schedule a Demo
create_template: Create New Release Template
+ import_template: Import Template
headings:
benefits: Benefits
how_it_works: How It Works
@@ -323,6 +328,12 @@ en:
update:
notice: The release template has been updated
contracts:
+ amendment_page:
+ description_labels:
+ amendment_clause: Amendment Clause
+ amendment_signature: Amendment Signature
+ amendment_signer_name: Amendment Signer Name
+ heading: Amendment
for_office_use_only:
description_labels:
date_issued: Date Issued
@@ -347,6 +358,12 @@ en:
signature_page:
heading: Signature Page
instructions: "By signing this signature page, as of the date listed below, I hereby agree, acknowledge and accept the terms and conditions listed in this %{releasable_name}."
+ labels:
+ location_release:
+ contact_person_address: Owner Address
+ contact_person_email: Owner Email
+ contact_person_phone: Owner Phone
+ name: Location Name
directories:
destroy:
alert: The folder has been deleted
@@ -405,6 +422,7 @@ en:
helpers:
help:
contract_template:
+ amendment_clause: Leave blank if not required for this contract
fee: Leave at $0.00 for no-fee
guardian_clause: Leave blank if not required for this contract
signature_legal_text: Leave blank if not required for this contract
@@ -772,7 +790,7 @@ en:
table_headers:
address: Address
approved: Approved
- name: Name
+ name: Location Name
notes: Notes
signed_at: Date Signed
tags: Tags
@@ -780,7 +798,10 @@ en:
actions:
manage: Manage
review: Review
+ sign_amendment: Sign Amendment
messages:
+ amendment_not_signed_tooltip: Amendment not yet signed
+ amendment_signed_tooltip: Amendment Signed
approved_tooltip: Approved by %{user} on %{timestamp}
no_photos: Needs Photo
new:
@@ -1027,6 +1048,16 @@ en:
heading: Licensor/Owner Contact Information
signature:
heading: Signature
+ amendments:
+ create:
+ amendment_already_signed_message: Release amendment is already signed!
+ amendment_signed_message: Release amendment signed successfully! Thank you
+ new:
+ amendment:
+ heading: Amendment
+ copy_url: Copy sign amendment URL
+ signature:
+ heading: Signature
appearance_releases:
create:
notice: Your release has been signed. Thank you!
diff --git a/config/locales/es.yml b/config/locales/es.yml
index 00d454a..a4a4688 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -81,6 +81,10 @@ es:
do_not_copy_warning: "Do not copy (ES)"
serial_number_label: "Serial Number (ES)"
broadcasts:
+ file:
+ actions:
+ delete_file: Delete
+ confirm_delete: Are you sure? (ES)
show:
actions:
reset_url: Reset URL (ES)
@@ -148,6 +152,12 @@ es:
update:
notice: The release template has been updated (ES)
contracts:
+ amendment_page:
+ description_labels:
+ amendment_clause: Amendment Clause (ES)
+ amendment_signature: Amendment Signature (ES)
+ amendment_signer_name: Amendment Signer Name (ES)
+ heading: Amendment (ES)
for_office_use_only:
description_labels:
date_issued: Date Issued (ES)
@@ -207,6 +217,7 @@ es:
helpers:
help:
contract_template:
+ amendment_clause: Leave blank if not required for this contract (ES)
fee: Leave at $0.00 for no-fee (ES)
guardian_clause: Leave blank if not required for this contract (ES)
signature_legal_text: Leave blank if not required for this contract (ES)
@@ -338,6 +349,12 @@ es:
notes: Notes (ES)
signed_at: Date Signed (ES)
tags: Tags (ES)
+ location_release:
+ actions:
+ sign_amendment: Sign Amendment (ES)
+ messages:
+ amendment_not_signed_tooltip: Amendment not yet signed (ES)
+ amendment_signed_tooltip: Amendment Signed (ES)
material_releases:
form:
photos:
@@ -384,6 +401,16 @@ es:
signed_at: Date Signed (ES)
tags: Tags (ES)
public:
+ amendments:
+ create:
+ amendment_already_signed_message: Release amendment is already signed! (ES)
+ amendment_signed_message: Release amendment signed successfully! Thank you (ES)
+ new:
+ amendment:
+ heading: Amendment
+ copy_url: Copy sign amendment URL (ES)
+ signature:
+ heading: Signature (ES)
appearance_releases:
create:
notice: La autorización está firmada. ¡Gracias!
diff --git a/config/routes.rb b/config/routes.rb
index 6f2e9a9..4f0c3ff 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -96,6 +96,9 @@ Rails.application.routes.draw do
end
resources :projects, only: [] do
resources :broadcasts, except: [:edit] do
+ member do
+ delete :destroy_file
+ end
resource :zoom_meeting, only: [:show]
end
resources :directories, except: [:index] do
@@ -128,7 +131,9 @@ Rails.application.routes.draw do
resources :talent_releases, only: [:new, :create]
resources :appearance_releases, only: [:new, :create]
resources :acquired_media_releases, only: [:new, :create]
- resources :location_releases, only: [:new, :create]
+ resources :location_releases, only: [:new, :create] do
+ resources :amendments, only: [:new, :create]
+ end
resources :material_releases, only: [:new, :create]
resources :medical_releases, only: [:new, :create]
resources :misc_releases, only: [:new, :create]
diff --git a/db/migrate/20200721140821_add_amendment_signer_details_to_location_releases.rb b/db/migrate/20200721140821_add_amendment_signer_details_to_location_releases.rb
new file mode 100644
index 0000000..3c1e448
--- /dev/null
+++ b/db/migrate/20200721140821_add_amendment_signer_details_to_location_releases.rb
@@ -0,0 +1,5 @@
+class AddAmendmentSignerDetailsToLocationReleases < ActiveRecord::Migration[6.0]
+ def change
+ add_column :location_releases, :amendment_signer_name, :string
+ end
+end
diff --git a/db/structure.sql b/db/structure.sql
index a10feff..76a20f1 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -888,7 +888,8 @@ CREATE TABLE public.location_releases (
filming_hours text,
approved_by_user_name text,
approved_by_user_email text,
- approved_at timestamp without time zone
+ approved_at timestamp without time zone,
+ amendment_signer_name character varying
);
@@ -3942,6 +3943,7 @@ INSERT INTO "schema_migrations" (version) VALUES
('20200716103525'),
('20200716105723'),
('20200720051634'),
-('20200720131309');
+('20200720131309'),
+('20200721140821');
diff --git a/spec/controllers/api/broadcasts_controller_spec.rb b/spec/controllers/api/broadcasts_controller_spec.rb
index ee5e3af..5927bca 100644
--- a/spec/controllers/api/broadcasts_controller_spec.rb
+++ b/spec/controllers/api/broadcasts_controller_spec.rb
@@ -106,7 +106,7 @@ RSpec.describe Api::BroadcastsController, type: :controller do
included = JSON.parse(response.body).dig('included')
expect(relationships.keys).to include('files')
- expect(included.size).to eq 1
+ expect(included.size).to eq 3
expect(included.first.dig("id")).to eq broadcast.files.first.id.to_s
expect(included.first.dig("type")).to eq 'active_storage_attachment'
end
diff --git a/spec/controllers/contract_templates_controller_spec.rb b/spec/controllers/contract_templates_controller_spec.rb
index 6069598..b2a1af1 100644
--- a/spec/controllers/contract_templates_controller_spec.rb
+++ b/spec/controllers/contract_templates_controller_spec.rb
@@ -43,8 +43,21 @@ describe ContractTemplatesController do
get :index, params: { project_id: project }
expect(response.body).to have_link "Create New Release Template"
+ expect(response.body).to have_link "Import Template"
expect(response.body).to have_link schedule_demo
end
+
+ context 'when current user is an associate' do
+ let(:current_user) { create(:user, :associate) }
+
+ it 'does not show the new contract template button' do
+ get :index, params: { project_id: project }
+
+ expect(response.body).not_to have_link "Create New Release Template"
+ expect(response.body).not_to have_link "Import Template"
+ expect(response.body).to have_link schedule_demo
+ end
+ end
end
context 'when current user is an associate' do
diff --git a/spec/controllers/public/amendments_controller_spec.rb b/spec/controllers/public/amendments_controller_spec.rb
new file mode 100644
index 0000000..277212e
--- /dev/null
+++ b/spec/controllers/public/amendments_controller_spec.rb
@@ -0,0 +1,112 @@
+require 'rails_helper'
+
+RSpec.describe Public::AmendmentsController, type: :controller do
+ let(:user) { create(:user) }
+ let(:account) { user.primary_account }
+ let(:project) { create(:project, account: account) }
+ let(:contract_template) { create(:location_release_contract_template, :with_amendment_clause, project: project) }
+ let(:location_release) { create(:location_release, contract_template: contract_template, project: project) }
+
+ render_views
+
+ describe "#new" do
+ it "shows amendment signing form for non-signed amendment of a release" do
+ expect(location_release.amendment_signed?).to be_falsey
+
+ get :new, params: {
+ account_id: account,
+ project_id: project,
+ contract_template_id: location_release.contract_template,
+ location_release_id: location_release
+ }
+
+ expect(response).to be_successful
+
+ body = CGI.unescape_html(response.body)
+ expect(body).not_to match already_signed_message
+ end
+
+ it "shows already signed message for signed amendment of a release" do
+ signed_release = create(:location_release, :amendment_signed, contract_template: contract_template, project: project)
+
+ expect(signed_release.amendment_signed?).to be_truthy
+
+ get :new, params: {
+ account_id: account,
+ project_id: project,
+ contract_template_id: location_release.contract_template,
+ location_release_id: signed_release
+ }
+
+ expect(response).to be_successful
+
+ body = CGI.unescape_html(response.body)
+ expect(body).to match already_signed_message
+ end
+ end
+
+ describe "#create" do
+ it "signs amendment" do
+ expect(location_release.amendment_signed?).to be_falsey
+
+ post :create, params: {
+ account_id: account,
+ project_id: project,
+ contract_template_id: location_release.contract_template,
+ location_release_id: location_release,
+ location_release: {
+ amendment_signer_name: "Signer Name",
+ amendment_signature_base64: signature_base64
+ }
+ }
+
+ expect(response).to be_successful
+
+ body = CGI.unescape_html(response.body)
+ expect(body).not_to match already_signed_message
+ expect(body).to match signed_successfully_message
+
+ expect(LocationRelease.last.amendment_signed?).to be_truthy
+ expect(LocationRelease.last.amendment_signer_name).to eq "Signer Name"
+ end
+
+ it "shows already signed message for signed amendment of a release" do
+ signed_release = create(:location_release, :amendment_signed, name: "Test Loc", amendment_signer_name: "Big Signer", contract_template: contract_template, project: project)
+
+ expect(signed_release.amendment_signed?).to be_truthy
+
+ post :create, params: {
+ account_id: account,
+ project_id: project,
+ contract_template_id: location_release.contract_template,
+ location_release_id: signed_release,
+ location_release: {
+ amendment_signer_name: "Signer Who",
+ amendment_signature_base64: signature_base64
+ }
+ }
+
+ expect(response).to be_successful
+
+ body = CGI.unescape_html(response.body)
+ expect(body).to match already_signed_message
+
+ expect(signed_release.amendment_signed?).to be_truthy
+ expect(signed_release.amendment_signer_name).to eq "Big Signer"
+ end
+ end
+
+ private
+
+ def already_signed_message
+ t 'public.amendments.create.amendment_already_signed_message'
+ end
+
+ def signed_successfully_message
+ t 'public.amendments.create.amendment_signed_message'
+ end
+
+ def signature_base64
+ @signature_base64 ||= Base64Image.from_image(file_fixture('signature.png')).data_uri
+ end
+end
diff --git a/spec/controllers/public/broadcasts_controller_spec.rb b/spec/controllers/public/broadcasts_controller_spec.rb
index 8850bd7..f42338d 100644
--- a/spec/controllers/public/broadcasts_controller_spec.rb
+++ b/spec/controllers/public/broadcasts_controller_spec.rb
@@ -87,6 +87,7 @@ RSpec.describe Public::BroadcastsController, type: :controller do
let!(:broadcast) { create(:broadcast, :with_stream, skip_create_callback: true, project: project ) }
it "uploads files to broadcast" do
+ allow(BroadcastsChannel).to receive(:broadcast_file_upload_updates)
patch :update, params: { token: broadcast.token, broadcast: file_params }, xhr: true
expect(broadcast.files.count).to eq(1)
diff --git a/spec/factories/broadcasts.rb b/spec/factories/broadcasts.rb
index 3b022c2..4148242 100644
--- a/spec/factories/broadcasts.rb
+++ b/spec/factories/broadcasts.rb
@@ -17,7 +17,13 @@ FactoryBot.define do
end
trait :with_files do
- files { [Rack::Test::UploadedFile.new('spec/fixtures/files/contract.pdf', 'application/pdf')] }
+ files do
+ [
+ Rack::Test::UploadedFile.new('spec/fixtures/files/contract.pdf', 'application/pdf'),
+ Rack::Test::UploadedFile.new('spec/fixtures/files/audio.mp3', 'audio/mpeg'),
+ Rack::Test::UploadedFile.new('spec/fixtures/files/video_file.mp4', 'video/mp4')
+ ]
+ end
end
after(:build) do |broadcast, evaluator|
diff --git a/spec/factories/contract_templates.rb b/spec/factories/contract_templates.rb
index 22583c4..8935cd5 100644
--- a/spec/factories/contract_templates.rb
+++ b/spec/factories/contract_templates.rb
@@ -13,6 +13,10 @@ FactoryBot.define do
archived_at Time.zone.now
end
+ trait :with_amendment_clause do
+ amendment_clause "Amendment Legal Language"
+ end
+
factory :appearance_release_contract_template do
release_type "appearance"
end
diff --git a/spec/factories/location_releases.rb b/spec/factories/location_releases.rb
index 727ea50..8ceb6ae 100644
--- a/spec/factories/location_releases.rb
+++ b/spec/factories/location_releases.rb
@@ -22,6 +22,14 @@ FactoryBot.define do
end
end
+ trait :amendment_signed do
+ amendment_signature do
+ path = Rails.root.join("spec", "fixtures", "files", "signature.png")
+ Rack::Test::UploadedFile.new(path, "image/png")
+ end
+ amendment_signer_name "Amendment Signer"
+ end
+
trait :non_native do
contract do
path = Rails.root.join("spec", "fixtures", "files", "contract.pdf")
diff --git a/spec/features/user_manages_contract_templates_spec.rb b/spec/features/user_manages_contract_templates_spec.rb
index 6985b3c..48ba336 100644
--- a/spec/features/user_manages_contract_templates_spec.rb
+++ b/spec/features/user_manages_contract_templates_spec.rb
@@ -11,11 +11,12 @@ RSpec.feature 'User manages contract templates', type: :feature do
sign_in(current_user)
end
- scenario 'splash page is shown if tehre are no contract templates' do
+ scenario 'splash page is shown if there are no contract templates' do
visit project_contract_templates_path(project)
expect(page).to have_content schedule_demo
expect(page).to have_content create_release_template
+ expect(page).to have_content import_release_template
end
scenario 'creating a new release template' do
@@ -30,7 +31,7 @@ RSpec.feature 'User manages contract templates', type: :feature do
fill_in 'Describe other territory', with: 'North America only'
select 'In perpetuity', from: 'Term'
select 'None', from: 'Restriction'
- click_on 'Create Release Template'
+ click_on create_release_template_button
expect(page).to have_content(create_contract_template_success_message)
end
@@ -48,18 +49,30 @@ RSpec.feature 'User manages contract templates', type: :feature do
fill_in_trix signature_legal_text_field, with: 'LL'
expect do
- click_on 'Create Release Template'
+ click_on create_release_template_button
end.to change(ContractTemplate, :count).by(1)
end
end
+ scenario 'location release template has a amendment clause field' do
+ visit new_project_contract_template_path(project)
+
+ fill_in 'Name', with: 'My Release Template'
+ select 'Location Release', from: 'Release type'
+ fill_hidden amendment_clause_field, with: 'Amendment clause text'
+ click_on create_release_template_button
+
+ expect(page).to have_content(create_contract_template_success_message)
+ expect(ContractTemplate.last.amendment_clause.body.to_s).to match /Amendment clause text/
+ end
+
scenario 'medical release template has a guardian clause field' do
visit new_project_contract_template_path(project)
fill_in 'Name', with: 'My Release Template'
select 'Medical Release', from: 'Release type'
fill_hidden guardian_clause_field, with: 'Guardian clause text'
- click_on 'Create Release Template'
+ click_on create_release_template_button
expect(page).to have_content(create_contract_template_success_message)
expect(ContractTemplate.last.guardian_clause.body.to_s).to match /Guardian clause text/
@@ -78,7 +91,7 @@ RSpec.feature 'User manages contract templates', type: :feature do
fill_in_trix 'contract_template_guardian_clause', with: 'Guardian clause text'
fill_in question_field(1), with: 'How much experience do you have in the industry?'
- click_on 'Create Release Template'
+ click_on create_release_template_button
expect(page).to have_content(create_contract_template_success_message)
end
@@ -185,13 +198,13 @@ RSpec.feature 'User manages contract templates', type: :feature do
scenario 'Should not allow negative fees' do
fill_in 'Fee', with: '-200'
- click_on 'Create Release Template'
+ click_on create_release_template_button
expect(page).not_to have_content(create_contract_template_success_message)
end
scenario 'Should not allow fees with more than 9 digits' do
fill_in 'Fee', with: '9999999999'
- click_on 'Create Release Template'
+ click_on create_release_template_button
expect(page).not_to have_content(create_contract_template_success_message)
end
end
@@ -366,6 +379,7 @@ RSpec.feature 'User manages contract templates', type: :feature do
expect(page).to have_content schedule_demo
expect(page).not_to have_content create_release_template
+ expect(page).not_to have_content import_release_template
end
it 'does not show edit button' do
@@ -397,11 +411,12 @@ RSpec.feature 'User manages contract templates', type: :feature do
expect(page).to have_content('Delete')
end
- it 'does not show create release button on splash page' do
+ it 'shows create release button on splash page' do
visit project_contract_templates_path(project)
expect(page).to have_content schedule_demo
expect(page).to have_content create_release_template
+ expect(page).to have_content import_release_template
end
it 'shows edit button when contract template is not signed' do
@@ -465,6 +480,10 @@ RSpec.feature 'User manages contract templates', type: :feature do
'contract_template_guardian_clause_trix_input_contract_template'
end
+ def amendment_clause_field
+ 'contract_template_amendment_clause_trix_input_contract_template'
+ end
+
def signature_legal_text_field
'contract_template_signature_legal_text'
end
@@ -489,6 +508,10 @@ RSpec.feature 'User manages contract templates', type: :feature do
t 'contract_templates.splash.actions.create_template'
end
+ def import_release_template
+ t 'contract_templates.splash.actions.import_template'
+ end
+
def signature_legal_text_trix_field
'Signature legal text'
end
@@ -516,4 +539,8 @@ RSpec.feature 'User manages contract templates', type: :feature do
def duplicate_release_name(template_name = '')
t 'contract_templates.duplicate.name_prefix', template_name: template_name
end
+
+ def create_release_template_button
+ 'Create Release Template'
+ end
end
diff --git a/spec/features/user_managing_broadcasts_spec.rb b/spec/features/user_managing_broadcasts_spec.rb
index b20cabc..b4acf4e 100644
--- a/spec/features/user_managing_broadcasts_spec.rb
+++ b/spec/features/user_managing_broadcasts_spec.rb
@@ -93,7 +93,7 @@ feature 'User managing broadcasts' do
BroadcastsChannel.broadcast_stream_updates(broadcast)
expect(page).to have_content stream_begun_message
- expect(page).to have_selector('div#broadcast_video', count: 1)
+ expect(page).to have_selector('div#broadcast_video', count: 2)
broadcast.streamer_status = :idle
broadcast.status = :idle
@@ -164,6 +164,21 @@ feature 'User managing broadcasts' do
click_on add_file_button
end
+ scenario 'manager user can click delete button next to the file and delete file', js: true do
+ broadcast = create(:broadcast, :with_stream, :with_files, project: project)
+
+ visit project_broadcast_path(project, broadcast)
+
+ expect(page).to have_content delete_file_button, count: 3
+
+ accept_alert do
+ first('a', text: delete_file_button).click
+ end
+
+ expect(page).to have_content delete_file_button, count: 2
+ expect(Broadcast.find(broadcast.id).files.count).to eq 2
+ end
+
scenario 'visit multi-view broadcast page', js: true do
broadcast_one = create(:broadcast, :with_stream, :with_files, name: 'Broadcast 1', project: project)
broadcast_two = create(:broadcast, :with_stream, :with_files, name: 'Broadcast 2', project: project)
@@ -198,6 +213,14 @@ feature 'User managing broadcasts' do
expect(page).to have_content schedule_demo
expect(page).not_to have_content create_stream
end
+
+ scenario 'associate user does not see delete button next to the file', js: true do
+ broadcast = create(:broadcast, :with_stream, :with_files, project: project)
+
+ visit project_broadcast_path(project, broadcast)
+
+ expect(page).to have_content delete_file_button, count: 0
+ end
end
context 'When the user is account manager' do
@@ -209,6 +232,21 @@ feature 'User managing broadcasts' do
expect(page).to have_content schedule_demo
expect(page).to have_content create_stream
end
+
+ scenario 'account manager user can click delete button next to the file and delete file', js: true do
+ broadcast = create(:broadcast, :with_stream, :with_files, project: project)
+
+ visit project_broadcast_path(project, broadcast)
+
+ expect(page).to have_content delete_file_button, count: 3
+
+ accept_alert do
+ first('a', text: delete_file_button).click
+ end
+
+ expect(page).to have_content delete_file_button, count: 2
+ expect(Broadcast.find(broadcast.id).files.count).to eq 2
+ end
end
end
@@ -262,5 +300,9 @@ feature 'User managing broadcasts' do
'Live stream is waiting to begin'
end
+ def delete_file_button
+ t 'broadcasts.file.actions.delete_file'
+ end
+
end
diff --git a/spec/features/user_managing_location_releases_spec.rb b/spec/features/user_managing_location_releases_spec.rb
index 4f67d88..db3e53a 100644
--- a/spec/features/user_managing_location_releases_spec.rb
+++ b/spec/features/user_managing_location_releases_spec.rb
@@ -78,6 +78,47 @@ feature "User managing location releases" do
expect(page).to have_content dummy_signature_legal_text
end
+
+ scenario "signing amendment for a not-signed amendment release", js: true do
+ contract_template = create(:location_release_contract_template, :with_amendment_clause, project: project)
+ release = create(:location_release, contract_template: contract_template, project: project)
+
+ expect(release.amendment_signed?).to be_falsey
+
+ visit new_account_project_contract_template_location_release_amendment_path(project.account, project, contract_template, release)
+
+ expect(page).to have_content amendments_heading
+
+ fill_in amendment_signer_name_field, with: 'Big Signer'
+ draw_signature file_fixture("signature.png"), amendment_signature_field
+
+ click_button sign_amendment_button
+
+ expect(page).to have_content signed_successfully_message
+ expect(LocationRelease.find(release.id).amendment_signed?).to be_truthy
+ end
+
+ scenario "opening signing amendment page for a signed amendment release shows already signed message", js: true do
+ contract_template = create(:location_release_contract_template, :with_amendment_clause, project: project)
+ release = create(:location_release, :amendment_signed, contract_template: contract_template, project: project)
+
+ expect(release.amendment_signed?).to be_truthy
+
+ visit new_account_project_contract_template_location_release_amendment_path(project.account, project, contract_template, release)
+
+ expect(page).not_to have_content amendments_heading
+ expect(page).not_to have_content signed_successfully_message
+ expect(page).to have_content already_signed_message
+ end
+
+ scenario "amendment signing form has copy URL button" do
+ contract_template = create(:location_release_contract_template, :with_amendment_clause, project: project)
+ release = create(:location_release, contract_template: contract_template, project: project)
+
+ visit new_account_project_contract_template_location_release_amendment_path(project.account, project, contract_template, release)
+
+ expect(page).to have_content copy_url_button
+ end
end
context "when signed in" do
@@ -108,9 +149,9 @@ feature "User managing location releases" do
fill_in filming_hours_field, with: "04:00 - 22:00"
click_button create_release_button
expect(page).to have_content(create_release_notice)
- expect(page).to have_photo("location_photo.png")
+ expect(page).to have_photo("location_photo.png", visible: :all)
- click_on "Manage"
+ click_on manage_button
expect(page).to have_link("Download")
end
end
@@ -119,7 +160,7 @@ feature "User managing location releases" do
location_release = create(:location_release_with_photo, :non_native, project: project)
visit project_location_releases_path(project)
- click_on "Manage"
+ click_on manage_button
click_link *update_location_release_link(location_release)
within ".dropzone" do
@@ -139,7 +180,7 @@ feature "User managing location releases" do
location_release = create(:location_release, project: project)
visit project_location_releases_path(project)
- click_on "Manage"
+ click_on manage_button
accept_alert do
click_link *destroy_location_release_link(location_release)
@@ -172,7 +213,7 @@ feature "User managing location releases" do
expect(page).to have_content("Needs Photo")
- click_on "Manage"
+ click_on manage_button
click_on "Photos"
expect(page).to have_content("Add Photos")
@@ -182,11 +223,85 @@ feature "User managing location releases" do
click_on "Save Changes"
expect(page).to have_content("The release has been updated")
- expect(page).to have_photo("location_photo.png")
+ expect(page).to have_photo("location_photo.png", visible: :all)
+ end
+
+ scenario "signing amendment for a not-signed amendment release", js: true do
+ contract_template = create(:location_release_contract_template, :with_amendment_clause, project: project)
+ release = create(:location_release, name: "Test Loc", contract_template: contract_template, project: project)
+
+ expect(release.amendment_signed?).to be_falsey
+
+ visit project_location_releases_path(project)
+
+ expect(page).to have_content "Test Loc"
+
+ click_on manage_button
+
+ expect(page).to have_link sign_amendment_link
+
+ new_window = window_opened_by { click_link sign_amendment_link }
+ within_window new_window do
+ expect(page).to have_content amendments_heading
+
+ fill_in amendment_signer_name_field, with: 'Big Signer'
+ draw_signature file_fixture("signature.png"), amendment_signature_field
+
+ click_button sign_amendment_button
+
+ expect(page).to have_content signed_successfully_message
+ expect(LocationRelease.find(release.id).amendment_signed?).to be_truthy
+ end
+ end
+
+ scenario "signed amendment release does not have sign amendment option in manage dropdown", js: true do
+ contract_template = create(:location_release_contract_template, :with_amendment_clause, project: project)
+ release = create(:location_release, :amendment_signed, name: "Test Loc", contract_template: contract_template, project: project)
+
+ expect(release.amendment_signed?).to be_truthy
+
+ visit project_location_releases_path(project)
+
+ expect(page).to have_content "Test Loc"
+
+ click_on manage_button
+
+ expect(page).not_to have_link sign_amendment_link
+ end
+
+ scenario "signed amendment release have checked box in location releases index table", js: true do
+ contract_template = create(:location_release_contract_template, :with_amendment_clause, project: project)
+ not_signed_release = create(:location_release, name: "Not Yet Loc", contract_template: contract_template, project: project)
+ expect(not_signed_release.amendment_signed?).to be_falsey
+
+ visit project_location_releases_path(project)
+
+ expect(page).to have_content "Not Yet Loc"
+ expect(page).to have_css('i.fa.fa-square-o', count: 1)
+ expect(page).to have_css('i.fa.fa-check-square', count: 0)
+
+ signed_release = create(:location_release, :amendment_signed, name: "Signed A Loc", contract_template: contract_template, project: project)
+ expect(signed_release.amendment_signed?).to be_truthy
+
+ visit project_location_releases_path(project)
+
+ expect(page).to have_content "Signed A Loc"
+
+ expect(page).to have_css('i.fa.fa-square-o', count: 1)
+ expect(page).to have_css('i.fa.fa-check-square-o', count: 1)
+ end
+
+ scenario "amendment signing form has copy URL button when user is signed in", js: true do
+ contract_template = create(:location_release_contract_template, :with_amendment_clause, project: project)
+ release = create(:location_release, contract_template: contract_template, project: project)
+
+ visit new_account_project_contract_template_location_release_amendment_path(project.account, project, contract_template, release)
+
+ expect(page).to have_content copy_url_button
end
end
- scenario "viewing the contract PDF" do
+ scenario "viewing the contract PDF when amendment is not yet signed" do
location_release = create(:location_release_with_contract_template_and_photo,
:native,
project: project,
@@ -198,16 +313,13 @@ feature "User managing location releases" do
content: "Note 1",
user: build(:user, email: "jane.doe@test.com"),
email: "jane.doe@test.com",
- created_at: DateTime.new(2020, 2, 21, 12, 0, 0),
- ),
+ created_at: DateTime.new(2020, 2, 21, 12, 0, 0),),
build(:note,
content: "Note 2",
user: build(:user, email: "john.doe@test.com"),
email: "john.doe@test.com",
- created_at: DateTime.new(2020, 2, 20, 11, 0, 0),
- ),
- ]
- )
+ created_at: DateTime.new(2020, 2, 20, 11, 0, 0),),
+ ])
sign_in(current_user)
visit project_location_releases_path(project)
@@ -216,6 +328,8 @@ feature "User managing location releases" do
expect(content_type).to eq("application/pdf")
expect(content_disposition).to include("inline")
expect(pdf_filename).to include("benny-s-burritos")
+
+ expect(pdf_body).not_to have_content amendment_page_heading
expect(pdf_body).to have_content("Benny's Burritos")
expect(pdf_body).to have_content("NOTES")
expect(pdf_body).to have_content("Note 1")
@@ -232,6 +346,34 @@ feature "User managing location releases" do
expect(pdf_body).to have_content("06:00 - 20:00")
end
+ scenario "viewing the contract PDF when amendment is signed" do
+ contract_template = create(:location_release_contract_template, :with_amendment_clause, project: project)
+ location_release = create(:location_release,
+ :amendment_signed,
+ :native,
+ contract_template: contract_template,
+ project: project,
+ name: "Test Loc")
+
+ 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_filename).to include("test-loc")
+
+ expect(pdf_body).to have_content("Test Loc")
+
+ expect(pdf_body).to have_content amendment_page_heading
+ expect(pdf_body).to have_content amendment_clause_label
+ expect(pdf_body).to have_content amendment_signer_name_label
+ expect(pdf_body).to have_content amendment_signature_label
+
+ expect(pdf_body).to have_content contract_template.amendment_clause.to_plain_text
+ expect(pdf_body).to have_content location_release.amendment_signer_name
+ end
+
context "when the user is account manager" do
let(:current_user) { create(:user, :account_manager) }
@@ -327,7 +469,7 @@ feature "User managing location releases" do
create(:location_release_with_contract_template, :native, project: project)
visit project_location_releases_path(project)
- click_on "Manage"
+ click_on manage_button
expect(page).not_to have_link(review_action, exact: true)
end
@@ -345,7 +487,7 @@ feature "User managing location releases" do
visit project_location_releases_path(project)
- click_on "Manage"
+ click_on manage_button
expect(page).not_to have_link("Download", exact: true)
end
@@ -353,7 +495,7 @@ feature "User managing location releases" do
create(:location_release_with_contract_template, :native, project: project)
visit project_location_releases_path(project)
- click_on "Manage"
+ click_on manage_button
expect(page).not_to have_link(review_action, exact: true)
end
@@ -437,8 +579,8 @@ feature "User managing location releases" do
"location_release[filming_hours]"
end
- def have_photo(filename, attr: "src")
- have_selector("img[#{attr}*='#{filename}']")
+ def have_photo(filename, attr: "src", visible: true)
+ have_selector("img[#{attr}*='#{filename}']", visible: visible)
end
def import_location_release_link(project)
@@ -535,4 +677,56 @@ feature "User managing location releases" do
def date_issued
t 'contracts.for_office_use_only.description_labels.date_issued'
end
+
+ def amendments_heading
+ t 'public.amendments.new.amendment.heading'
+ end
+
+ def amendment_signer_name_field
+ 'location_release[amendment_signer_name]'
+ end
+
+ def amendment_signature_field
+ 'location_release_amendment_signature_base64'
+ end
+
+ def sign_amendment_button
+ t 'shared.submit_release_long'
+ end
+
+ def already_signed_message
+ t 'public.amendments.create.amendment_already_signed_message'
+ end
+
+ def signed_successfully_message
+ t 'public.amendments.create.amendment_signed_message'
+ end
+
+ def manage_button
+ t 'location_releases.location_release.actions.manage'
+ end
+
+ def sign_amendment_link
+ t 'location_releases.location_release.actions.sign_amendment'
+ end
+
+ def copy_url_button
+ t 'public.amendments.new.copy_url'
+ end
+
+ def amendment_page_heading
+ t 'contracts.amendment_page.heading'
+ end
+
+ def amendment_signer_name_label
+ t 'contracts.amendment_page.description_labels.amendment_signer_name'
+ end
+
+ def amendment_clause_label
+ t 'contracts.amendment_page.description_labels.amendment_clause'
+ end
+
+ def amendment_signature_label
+ t 'contracts.amendment_page.description_labels.amendment_signature'
+ end
end