diff --git a/app/assets/javascripts/photo_preview.js b/app/assets/javascripts/photo_preview.js index 3f0cbb8..741db37 100644 --- a/app/assets/javascripts/photo_preview.js +++ b/app/assets/javascripts/photo_preview.js @@ -51,10 +51,8 @@ $(document).on("turbolinks:load", function() { $("[data-behavior=guardian-photo-preview]").each(function(index, element) { App.PhotoPreview.init(element); }); - $("[data-behavior=take-person-photo]").click(function(e) { - $("[data-ujs-target=person-photo-input]").trigger("click"); - }); - $("[data-behavior=take-guardian-photo]").click(function(e) { - $("[data-ujs-target=guardian-photo-input]").trigger("click"); + $("[data-behavior=trigger-click]").click(function(e) { + const target = $(this).data("target"); + $(target).trigger("click"); }); }); diff --git a/app/controllers/concerns/misc_release_context.rb b/app/controllers/concerns/misc_release_context.rb new file mode 100644 index 0000000..75c8b6a --- /dev/null +++ b/app/controllers/concerns/misc_release_context.rb @@ -0,0 +1,13 @@ +module MiscReleaseContext + extend ActiveSupport::Concern + + def misc_releases + policy_scope(MiscRelease) + end + + def set_misc_release + misc_release_id = params[:misc_release_id] || params[:id] + + @misc_release = authorize misc_releases.find(misc_release_id) + end +end diff --git a/app/controllers/misc_releases_controller.rb b/app/controllers/misc_releases_controller.rb new file mode 100644 index 0000000..1541725 --- /dev/null +++ b/app/controllers/misc_releases_controller.rb @@ -0,0 +1,40 @@ +class MiscReleasesController < ApplicationController + include ProjectContext, MiscReleaseContext + + before_action :set_project, only: [:index] + before_action :set_misc_release, only: [:destroy] + + include ProjectLayout + + def index + @misc_releases = filtered_misc_releases.order_by_recent.paginate(page: params[:page]) + end + + def destroy + @project = @misc_release.project + + if @misc_release.destroy + redirect_to [@project, :misc_releases], alert: t(".alert") + end + end + + private + + def misc_releases + if @project + policy_scope(@project.misc_releases) + else + policy_scope(MiscRelease) + end + end + + def filtered_misc_releases + results = misc_releases + + if params[:query].present? + results = results.search(params[:query]) + end + + results + end +end diff --git a/app/controllers/public/appearance_releases_controller.rb b/app/controllers/public/appearance_releases_controller.rb index 419fcd1..17d5464 100644 --- a/app/controllers/public/appearance_releases_controller.rb +++ b/app/controllers/public/appearance_releases_controller.rb @@ -71,8 +71,25 @@ class Public::AppearanceReleasesController < Public::BaseController ] end + def second_guardian_params + %i[ + guardian_2_first_name + guardian_2_last_name + guardian_2_phone + guardian_2_email + guardian_2_photo + guardian_2_address_street1 + guardian_2_address_street2 + guardian_2_address_city + guardian_2_address_state + guardian_2_address_zip + guardian_2_address_country + ] + end + def appearance_release_params params.require(:appearance_release).permit(person_params, guardian_params, + second_guardian_params, :minor, :signature_base64, :person_date_of_birth, :locale, :contract_template) diff --git a/app/controllers/public/misc_releases_controller.rb b/app/controllers/public/misc_releases_controller.rb new file mode 100644 index 0000000..61e4933 --- /dev/null +++ b/app/controllers/public/misc_releases_controller.rb @@ -0,0 +1,99 @@ +class Public::MiscReleasesController < Public::BaseController + before_action :set_account, :set_project, :set_contract_template + + def new + @misc_release = build_misc_release + end + + def create + @misc_release = build_misc_release(misc_release_params_with_locale_and_contract_template) + + if @misc_release.save(context: :native) + if @misc_release.contract_template.present? + AttachContractToReleasableJob.perform_later(@misc_release) + end + log_create_analytics + else + render :new + end + end + + private + + def set_project + @project = @account.projects.find(params[:project_id]) + end + + def set_account + @account = Account.find_by(slug: params[:account_id]) + end + + def set_contract_template + @contract_template = @project.contract_templates.find(params[:contract_template_id]) + end + + def misc_releases + policy_scope(@project.misc_releases) + end + + def build_misc_release(params = {}) + authorize misc_releases.build(params) + end + + def misc_release_params + params + .require(:misc_release) + .permit( + person_params, + guardian_params, + :signature_base64, + :locale, + :contract_template, + photos: [], + ) + end + + def person_params + [ + :person_first_name, + :person_last_name, + :person_phone, + :person_email, + :person_address_street1, + :person_address_street2, + :person_address_city, + :person_address_state, + :person_address_zip, + :person_address_country, + ] + end + + def guardian_params + [ + :guardian_first_name, + :guardian_last_name, + :guardian_phone, + :guardian_email, + :minor, + :guardian_address_street1, + :guardian_address_street2, + :guardian_address_city, + :guardian_address_state, + :guardian_address_zip, + :guardian_address_country, + :guardian_photo + ] + end + + def misc_release_params_with_locale + misc_release_params.merge(locale: I18n.locale) + end + + def misc_release_params_with_locale_and_contract_template + misc_release_params_with_locale.merge(contract_template: @contract_template) + end + + def log_create_analytics + TrackAnalyticsJob.perform_later(nil, nil, :track_create_native_release, release_type: MiscRelease.to_s, account: @account, user_agent: request.user_agent, user_ip: request.remote_ip) + end +end diff --git a/app/models/appearance_release.rb b/app/models/appearance_release.rb index 078eefd..9a750a7 100644 --- a/app/models/appearance_release.rb +++ b/app/models/appearance_release.rb @@ -12,7 +12,9 @@ class AppearanceRelease < ApplicationRecord include Taggable include PersonName include GuardianPhotoable + include SecondGuardianPhotoable include GuardianName + include SecondGuardianName has_one_attached :person_photo @@ -38,6 +40,17 @@ class AppearanceRelease < ApplicationRecord %w[guardian_address_country country] ] + composed_of :guardian_2_address, + class_name: 'Address', + mapping: [ + %w[guardian_2_address_street1 street1], + %w[guardian_2_address_street2 street2], + %w[guardian_2_address_city city], + %w[guardian_2_address_state state], + %w[guardian_2_address_zip zip], + %w[guardian_2_address_country country] + ] + # These validations apply to all releases validates :person_email, email: true, allow_blank: true @@ -132,6 +145,10 @@ class AppearanceRelease < ApplicationRecord true end + def second_guardian_present? + self.guardian_2_first_name.present? + end + def contract_file_name "#{project.name.parameterize}_#{contract_template.release_type}_#{(signed_at || created_at).strftime('%Y.%m.%d')}_#{release_number}_#{filename_suffix.parameterize}" end diff --git a/app/models/concerns/second_guardian_name.rb b/app/models/concerns/second_guardian_name.rb new file mode 100644 index 0000000..8e4e04d --- /dev/null +++ b/app/models/concerns/second_guardian_name.rb @@ -0,0 +1,20 @@ +module SecondGuardianName + extend ActiveSupport::Concern + + included do + def guardian_2_name + "#{guardian_2_first_name} #{guardian_2_last_name}".titleize + end + + def guardian_2_name=(value) + if value.include?(' ') + split = value.split(" ", 2) + self.guardian_2_first_name = split.first + self.guardian_2_last_name = split.last + else + self.guardian_2_first_name = value + self.guardian_2_last_name = "(Not Given)" + end + end + end +end diff --git a/app/models/concerns/second_guardian_photoable.rb b/app/models/concerns/second_guardian_photoable.rb new file mode 100644 index 0000000..5e21240 --- /dev/null +++ b/app/models/concerns/second_guardian_photoable.rb @@ -0,0 +1,9 @@ +module SecondGuardianPhotoable + extend ActiveSupport::Concern + + included do + has_one_attached :guardian_2_photo + + validates :guardian_2_photo, content_type: ["image/png", "image/jpeg"] + end +end diff --git a/app/models/misc_release.rb b/app/models/misc_release.rb index 61ee820..54887d3 100644 --- a/app/models/misc_release.rb +++ b/app/models/misc_release.rb @@ -8,6 +8,7 @@ class MiscRelease < ApplicationRecord include Syncable include PersonName include GuardianName + include GuardianPhotoable composed_of :person_address, class_name: "Address", diff --git a/app/models/releasable_param.rb b/app/models/releasable_param.rb index a3010be..4c2b7c9 100644 --- a/app/models/releasable_param.rb +++ b/app/models/releasable_param.rb @@ -1,5 +1,5 @@ class ReleasableParam - TYPES = %w(talent appearance location material acquired_media music medical) + TYPES = %w(talent appearance location material acquired_media music medical misc) def initialize(params) @params = params diff --git a/app/policies/misc_release_policy.rb b/app/policies/misc_release_policy.rb new file mode 100644 index 0000000..99b40e3 --- /dev/null +++ b/app/policies/misc_release_policy.rb @@ -0,0 +1,41 @@ +class MiscReleasePolicy < ReleasePolicy + def create? + true + end + + def show? + true + end + + def update? + !record.native? + end + + def destroy? + true + end + + def edit_photos? + true + end + + def index? + true + end + + def update_photos? + edit_photos? + end + + def tag_multiple? + true + end + + def download_single? + true + end + + def download_multiple? + download_single? + end +end diff --git a/app/views/contracts/_photos.html.erb b/app/views/contracts/_photos.html.erb index 6f429f7..242881c 100644 --- a/app/views/contracts/_photos.html.erb +++ b/app/views/contracts/_photos.html.erb @@ -5,6 +5,9 @@ <% if release.respond_to? :guardian_photo %> <% @total_photos_count += release.guardian_photo.attached? ? 1 : 0 %> <% end %> +<% if release.respond_to? :guardian_2_photo %> + <% @total_photos_count += release.guardian_2_photo.attached? ? 1 : 0 %> +<% end %>
<%= t '.heading', count: @total_photos_count %>
<%= t '.guardian_2_photo_heading' %>
+Second guardian Information
+ + <% # Second guardian information %> +| <%= check_box_tag "misc_release_ids[]", false, false %> | ++ | <%= MiscRelease.human_attribute_name(:person_name) %> | +<%= MiscRelease.human_attribute_name(:contact_info) %> | +<%= t(".table_headers.notes") %> | +<%= t(".table_headers.tags") %> | +<%= t(".table_headers.signed_at") %> | ++ | ||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| <%= t(".empty") %> | +|||||||||||
<%= fa_icon "arrow-up", text: t(".photo.camera_instructions_html") %>
@@ -75,8 +75,6 @@
<%= form.text_field :guardian_first_name, required: @appearance_release.minor?, wrapper_class: "col-sm-3" %>
<%= form.text_field :guardian_last_name, required: @appearance_release.minor?, wrapper_class: "col-sm-3" %>
<%= form.phone_field :guardian_phone, required: @appearance_release.minor?, wrapper_class: "col-sm-6" %>
-
-
+ <%= fa_icon "arrow-up", text: t(".photo.camera_instructions_html") %>
+ <%= t ".photo.warning" %>
+
<%= fa_icon "arrow-up", text: t(".photo.camera_instructions_html") %>
diff --git a/app/views/public/misc_releases/create.html.erb b/app/views/public/misc_releases/create.html.erb
new file mode 100644
index 0000000..6eda1cb
--- /dev/null
+++ b/app/views/public/misc_releases/create.html.erb
@@ -0,0 +1 @@
+
Your release was successfully submitted. Thank you.
\ No newline at end of file diff --git a/app/views/public/misc_releases/new.html.erb b/app/views/public/misc_releases/new.html.erb new file mode 100644 index 0000000..35672ce --- /dev/null +++ b/app/views/public/misc_releases/new.html.erb @@ -0,0 +1,97 @@ +<%= @contract_template.body %>
+ <% end %> + +<%= @contract_template.guardian_clause %>
+ <% end %> +
+ <%= fa_icon "arrow-up", text: t(".guardian_photo.camera_instructions_html") %>
+ <%= t ".guardian_photo.warning" %>
+
<%= fa_icon "arrow-up", text: t(".guardian_photo.camera_instructions_html") %>
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 65c27ab..13104a0 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -60,6 +60,10 @@ en:
activerecord:
attributes:
appearance_release:
+ guardian_2_address: Guardian 2 address
+ guardian_2_email: Guardian 2 email
+ guardian_2_name: Guardian 2 name
+ guardian_2_phone: Guardian 2 phone
person_address: Address
person_email: Email
person_name: Name
@@ -237,6 +241,7 @@ en:
heading: New Release Template
contracts:
photos:
+ guardian_2_photo_heading: Second guardian photo
guardian_photo_heading: Guardian photo
heading:
one: Photo
@@ -328,6 +333,16 @@ en:
person_phone: Phone number
person_title: Title
appearance_release:
+ guardian_2_address_city: Guardian 2 city
+ guardian_2_address_country: Guardian 2 country
+ guardian_2_address_state: Guardian 2 state
+ guardian_2_address_street1: Guardian 2 address
+ guardian_2_address_street2: Guardian 2 address (Line 2)
+ guardian_2_address_zip: Guardian 2 zip code
+ guardian_2_email: Guardian 2 email
+ guardian_2_first_name: Guardian 2 first name
+ guardian_2_last_name: Guardian 2 last name
+ guardian_2_phone: Guardian 2 phone
guardian_address_city: Guardian city
guardian_address_country: Guardian country
guardian_address_state: Guardian state
@@ -645,6 +660,20 @@ en:
medical_release:
actions:
manage: Manage
+ misc_releases:
+ destroy:
+ alert: The misc release has been deleted
+ index:
+ actions:
+ search: Search
+ empty: Misc Releases will appear here
+ table_headers:
+ notes: Notes
+ signed_at: Date Signed
+ tags: Tags
+ misc_release:
+ actions:
+ manage: Manage
music_releases:
create:
notice: The music release has been created
@@ -802,6 +831,12 @@ en:
notice: Your release has been signed. Thank you!
new:
cancel: Cancel
+ guardian_2_info:
+ heading: Second Guardian Information (if company requires)
+ guardian_2_photo:
+ heading: Second Guardian Photo
+ instructions: >
+ Lastly, it's time for second guardian to take a selfie photo! Please remove your hat and sunglasses (regular eyewear is ok), make sure that you are the only person in the photo, look straight into the camera, and say Cheese!
guardian_clause:
heading: Guardian Clause
guardian_info:
@@ -880,6 +915,34 @@ en:
heading: Questionnaire
signature:
heading: Signature
+ misc_releases:
+ create:
+ notice: Your release has been signed. Thank you!
+ new:
+ cancel: Cancel
+ guardian_clause:
+ heading: Guardian Clause
+ guardian_info:
+ heading: Guardian Information
+ guardian_photo:
+ camera_instructions_html: Click Take Photo to Turn ON Camera
+ heading: Guardian Photo
+ instructions: >
+ Lastly, it's time for guardian to take a selfie photo! Please remove your hat and sunglasses (regular eyewear is ok), make sure that you are the only person in the photo, look straight into the camera, and say Cheese!
+ no_photo: No photo yet
+ take_photo: Take Photo
+ warning: If your photo appears sideways, it will be autocorrected when you submit your release.
+ instructions_html: >
+ Below is the misc release form. After scrolling down and reading the misc release form, please enter your personal information, take a photo, and press the "Submit Release" button.
+ legal:
+ heading: Legal
+ personal_info:
+ heading: Personal Information
+ instructions: Now, enter your personal information.
+ photo:
+ heading: Photos
+ signature:
+ heading: Signature
talent_releases:
create:
notice: Your release has been signed. Thank you!
diff --git a/config/locales/es.yml b/config/locales/es.yml
index 82258a2..6ce2858 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -66,6 +66,7 @@ es:
heading: Release Info (ES)
contracts:
photos:
+ guardian_2_photo_heading: Second guardian photo (ES)
guardian_photo_heading: Guardian photo (ES)
heading:
one: Photo (ES)
@@ -115,6 +116,16 @@ es:
helpers:
label:
appearance_release:
+ guardian_2_address_city: Second guardian city (ES)
+ guardian_2_address_country: Second guardian country (ES)
+ guardian_2_address_state: Second guardian state (ES)
+ guardian_2_address_street1: Second guardian address (ES)
+ guardian_2_address_street2: Second guardian address (Line 2) (ES)
+ guardian_2_address_zip: Second guardian zip code (ES)
+ guardian_2_email: Second guardian email (ES)
+ guardian_2_first_name: Second guardian first name (ES)
+ guardian_2_last_name: Second guardian last name (ES)
+ guardian_2_phone: Second guardian phone (ES)
guardian_address_city: Guardian city (ES)
guardian_address_country: Guardian country (ES)
guardian_address_state: Guardian state (ES)
@@ -167,6 +178,12 @@ es:
notice: La autorización está firmada. ¡Gracias!
new:
cancel: Cancelar
+ guardian_2_info:
+ heading: Second Guardian Information (ES)
+ guardian_2_photo:
+ heading: Second Guardian Photo (ES)
+ instructions: >
+ (ES) Lastly, it's time for second guardian to take a selfie photo! Please remove your hat and sunglasses (regular eyewear is ok), make sure that you are the only person in the photo, look straight into the camera, and say Cheese! (ES)
guardian_clause:
heading: Guardian Clause (ES)
guardian_photo:
diff --git a/db/data_migrations/20200623111803_change_existing_zoom_user_settings.rb b/db/data_migrations/20200623111803_change_existing_zoom_user_settings.rb
new file mode 100644
index 0000000..adbacee
--- /dev/null
+++ b/db/data_migrations/20200623111803_change_existing_zoom_user_settings.rb
@@ -0,0 +1,9 @@
+class ChangeExistingZoomUserSettings < ActiveRecord::DataMigration
+ def up
+ gateway = ZoomGateway.new
+
+ ZoomUser.find_each do |zu|
+ gateway.update_user_settings zu.api_id
+ end
+ end
+end
diff --git a/db/migrate/20200619134853_add_second_guardian_fields_to_appearance_releases.rb b/db/migrate/20200619134853_add_second_guardian_fields_to_appearance_releases.rb
new file mode 100644
index 0000000..a067b44
--- /dev/null
+++ b/db/migrate/20200619134853_add_second_guardian_fields_to_appearance_releases.rb
@@ -0,0 +1,14 @@
+class AddSecondGuardianFieldsToAppearanceReleases < ActiveRecord::Migration[6.0]
+ def change
+ add_column :appearance_releases, :guardian_2_first_name, :string
+ add_column :appearance_releases, :guardian_2_last_name, :string
+ add_column :appearance_releases, :guardian_2_email, :string
+ add_column :appearance_releases, :guardian_2_phone, :string
+ add_column :appearance_releases, :guardian_2_address_street1, :string
+ add_column :appearance_releases, :guardian_2_address_street2, :string
+ add_column :appearance_releases, :guardian_2_address_city, :string
+ add_column :appearance_releases, :guardian_2_address_state, :string
+ add_column :appearance_releases, :guardian_2_address_zip, :string
+ add_column :appearance_releases, :guardian_2_address_country, :string
+ end
+end
diff --git a/db/structure.sql b/db/structure.sql
index 3ad5cad..051cc35 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -9,20 +9,6 @@ SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;
---
--- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: -
---
-
-CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
-
-
---
--- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: -
---
-
-COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
-
-
--
-- Name: fuzzystrmatch; Type: EXTENSION; Schema: -; Owner: -
--
@@ -342,7 +328,17 @@ CREATE TABLE public.appearance_releases (
guardian_address_city character varying,
guardian_address_state character varying,
guardian_address_zip character varying,
- guardian_address_country character varying
+ guardian_address_country character varying,
+ guardian_2_first_name character varying,
+ guardian_2_last_name character varying,
+ guardian_2_email character varying,
+ guardian_2_phone character varying,
+ guardian_2_address_street1 character varying,
+ guardian_2_address_street2 character varying,
+ guardian_2_address_city character varying,
+ guardian_2_address_state character varying,
+ guardian_2_address_zip character varying,
+ guardian_2_address_country character varying
);
@@ -3793,6 +3789,7 @@ INSERT INTO "schema_migrations" (version) VALUES
('20200615133602'),
('20200616124214'),
('20200619081446'),
-('20200619085823');
+('20200619085823'),
+('20200619134853');
diff --git a/lib/zoom_gateway.rb b/lib/zoom_gateway.rb
index 764c2f9..60e8798 100644
--- a/lib/zoom_gateway.rb
+++ b/lib/zoom_gateway.rb
@@ -1,3 +1,7 @@
+# frozen_string_literal: true
+
+require './lib/zoom_wrapper_monkeypatch'
+
class ZoomGateway
class AuthenticationError < StandardError; end
class MeetingExpired < StandardError; end
@@ -65,6 +69,23 @@ class ZoomGateway
parse_zoom_error(e)
end
+ # Update user with custom settings
+ def update_user_settings(user_id)
+ custom_defaults = {
+ id: user_id,
+ in_meeting: {
+ auto_saving_chat: true,
+ co_host: true,
+ non_verbal_feedback: true,
+ breakout_room: true,
+ group_hd: true,
+ far_end_camera_control: true,
+ allow_live_streaming: true
+ }
+ }
+ @client.user_settings_update custom_defaults
+ end
+
def create_host(host_email)
# Find role
host_role = @client.roles_list["roles"].try(:select) { |r| r["name"] == self.class.HOST_ROLE }.try(:first)
@@ -82,6 +103,8 @@ class ZoomGateway
type: self.class.USER_TYPE
})
+ update_user_settings(host_user["id"])
+
# Assign role to user
@client.roles_assign role_id: host_role["id"], members: [{id: host_user["id"]}]
diff --git a/lib/zoom_wrapper_monkeypatch.rb b/lib/zoom_wrapper_monkeypatch.rb
new file mode 100644
index 0000000..bb9e0dc
--- /dev/null
+++ b/lib/zoom_wrapper_monkeypatch.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Zoom
+ module Actions
+ module User
+ def user_settings_update(*args)
+ params = Zoom::Params.new(Utils.extract_options!(args))
+ permitted_in_meeting_params = %i[
+ auto_saving_chat
+ co_host
+ non_verbal_feedback
+ breakout_room
+ group_hd
+ far_end_camera_control
+ allow_live_streaming
+ ]
+ permitted_params = { in_meeting: permitted_in_meeting_params }
+ params.require(:id).permit permitted_params
+ request_body = params.except(:id).to_json
+ resp = self.class.patch("/users/#{params[:id]}/settings", body: request_body, headers: request_headers)
+ Utils.parse_response resp
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/spec/controllers/misc_releases_controller_spec.rb b/spec/controllers/misc_releases_controller_spec.rb
new file mode 100644
index 0000000..43f8957
--- /dev/null
+++ b/spec/controllers/misc_releases_controller_spec.rb
@@ -0,0 +1,116 @@
+require "rails_helper"
+
+RSpec.describe MiscReleasesController, type: :controller do
+ render_views
+
+ let(:user) { create(:user) }
+ let(:account) { user.primary_account }
+ let(:project) { create(:project, account: user.primary_account) }
+
+ before do
+ sign_in user
+ end
+
+ describe "#index" do
+ it "responds successfully" do
+ get :index, params: { project_id: project }
+
+ expect(response).to be_successful
+ end
+
+ it "renders content" do
+ release = create(:misc_release, project: project,
+ person_first_name: "My",
+ person_last_name: "Release",
+ person_phone: "5551234567",
+ person_email: "jane.doe@test.com")
+ create(:note, notable: release, content: "Some notes here")
+
+ get :index, params: { project_id: project }
+
+ expect(response.body).to have_content "My Release"
+ expect(response.body).to have_content "P: 5551234567"
+ expect(response.body).to have_content "jane.doe@test.com"
+ expect(response.body).to have_content "Some notes here"
+ expect(response.body).to have_content "Manage"
+ end
+
+ context "when there are no misc releases" do
+ it "renders an empty message" do
+ get :index, params: { project_id: project }
+
+ expect(response.body).to have_content("Misc Releases will appear here")
+ end
+ end
+
+ context "when there are many records" do
+ it "paginates the table" do
+ create_list(:misc_release, 20, project: project)
+
+ get :index, params: { project_id: project }
+
+ expect(response.body).to have_link("2", href: project_misc_releases_path(project, page: 2))
+ end
+ end
+
+ context "for xhr request" do
+ it "filters the releases by a query param" do
+ misc_releases = [
+ create(:misc_release, person_name: "Adam Sandler", project: project),
+ create(:misc_release, person_name: "Zoe Perry", project: project),
+ ]
+
+ get :index, params: { project_id: project, query: "Zoe" }, xhr: true
+
+ expect(response.body).not_to have_content("Adam Sandler")
+ expect(response.body).to have_content("Zoe Perry")
+ end
+ end
+ end
+
+ describe "#destroy" do
+ let!(:misc_release) { create(:misc_release, project: project) }
+
+ it "responds with redirect" do
+ delete :destroy, params: { project_id: project, id: misc_release }
+
+ expect(response).to be_redirect
+ expect(response).to redirect_to [project, :misc_releases]
+ end
+
+ it "sets the flash" do
+ delete :destroy, params: { project_id: project, id: misc_release }
+
+ expect(flash.alert).not_to be_nil
+ end
+
+ it "destroys the record" do
+ expect {
+ delete :destroy, params: { project_id: project, id: misc_release }
+ }.to change(MiscRelease, :count).by(-1)
+ end
+ end
+
+ private
+
+ def misc_release_params
+ attributes_for(:misc_release).merge(exploitable_rights_params)
+ end
+
+ def minor_misc_release_params
+ attributes_for(:misc_release, :minor_with_guardian_photo).merge(exploitable_rights_params)
+ end
+
+ def exploitable_rights_params
+ {
+ applicable_medium_id: ApplicableMedium.last.id,
+ applicable_medium_text: "applicable_media",
+ territory_id: Territory.last.id,
+ territory_text: "territory",
+ term_id: Term.last.id,
+ term_text: "term",
+ restriction_id: Restriction.last.id,
+ restriction_text: "restrictions",
+ }
+ end
+end
diff --git a/spec/factories/misc_releases.rb b/spec/factories/misc_releases.rb
index 2a6003f..42096e8 100644
--- a/spec/factories/misc_releases.rb
+++ b/spec/factories/misc_releases.rb
@@ -23,6 +23,17 @@ FactoryBot.define do
guardian_phone "123-555-1234"
end
+ trait :minor_with_guardian_photo do
+ minor true
+ guardian_first_name "Jamie"
+ guardian_last_name "Doe"
+ guardian_phone "123-555-1234"
+ guardian_photo do
+ path = Rails.root.join("spec", "fixtures", "files", "pratt.jpg")
+ Rack::Test::UploadedFile.new(path, "image/jpeg")
+ end
+ end
+
factory :misc_release_with_contract_template do
after(:build) do |misc_release, _|
misc_release.contract_template = build(:misc_release_contract_template)
diff --git a/spec/features/user_creates_note_spec.rb b/spec/features/user_creates_note_spec.rb
index 9cfe11c..0aed700 100644
--- a/spec/features/user_creates_note_spec.rb
+++ b/spec/features/user_creates_note_spec.rb
@@ -109,4 +109,10 @@ feature "User creates notes" do
it_behaves_like "a notable collection UI"
end
+
+ context "for misc releases" do
+ subject! { create(:misc_release, project: project, notes: []) }
+
+ it_behaves_like "a notable collection UI"
+ end
end
diff --git a/spec/features/user_creates_tags_spec.rb b/spec/features/user_creates_tags_spec.rb
index b8ca14a..2d02dc6 100644
--- a/spec/features/user_creates_tags_spec.rb
+++ b/spec/features/user_creates_tags_spec.rb
@@ -92,4 +92,10 @@ feature "User creates tags" do
it_behaves_like "a taggable collection UI"
end
+
+ context "for misc releases" do
+ subject! { create(:misc_release, project: project, tags: []) }
+
+ it_behaves_like "a taggable collection UI"
+ end
end
diff --git a/spec/features/user_managing_appearance_releases_spec.rb b/spec/features/user_managing_appearance_releases_spec.rb
index 33e1eb3..06ea050 100644
--- a/spec/features/user_managing_appearance_releases_spec.rb
+++ b/spec/features/user_managing_appearance_releases_spec.rb
@@ -72,6 +72,61 @@ feature 'User managing appearance releases' do
expect(page).to have_content(successful_submission_message)
end
+
+ scenario 'creating a release for a minor with two guardians', js: true do
+ allow(BrayniacAI::Validation).to receive(:create).and_return(double(:validation, valid: true))
+
+ project = create(:project, members: current_user, account: current_user.primary_account)
+ contract_template = create(:contract_template, project: project)
+
+ visit new_account_project_contract_template_appearance_release_path(project.account, project, contract_template)
+
+ expect(page).to have_photo_button
+ expect(page).not_to have_content('SECOND GUARDIAN INFORMATION')
+ expect(page).not_to have_content('SECOND GUARDIAN PHOTO')
+
+ page.check person_is_minor_checkbox
+ expect(page).to have_content('GUARDIAN INFORMATION')
+ expect(page).to have_content('GUARDIAN PHOTO')
+ expect(page).to have_content 'Guardian Email'
+
+ expect(page).to have_content 'SECOND GUARDIAN INFORMATION'
+ expect(page).to have_content 'SECOND GUARDIAN PHOTO'
+ expect(page).to have_content 'Guardian 2 Email'
+ expect(page).to have_content 'Guardian 2 Phone'
+ expect(page).to have_content 'Guardian 2 Address'
+
+ fill_in guardian_first_name_field, with: 'Guardian'
+ fill_in guardian_last_name_field, with: 'Name'
+ fill_in guardian_phone_field, with: '001101'
+ fill_in person_first_name_field, with: 'Jane'
+ fill_in person_last_name_field, with: 'Doe'
+ fill_in_person_address_fields
+ fill_in person_phone_field, with: '555-555-5555'
+ fill_in person_email_field, with: 'jane.doe@test.com'
+ fill_in person_date_of_birth, with: '01/01/1999'
+ attach_file person_photo_field, file_fixture('person_photo.png'), visible: :all
+ attach_file guardian_photo_field, file_fixture('hemsworth.jpeg'), visible: :all
+ draw_signature file_fixture('signature.png'), 'appearance_release_signature_base64'
+
+ fill_in guardian_email_field, with: 'invalid@email'
+ click_button submit_release_button
+ expect(page).to have_content('Guardian email is not an email')
+
+ fill_in guardian_email_field, with: 'valid@email.com'
+ fill_in_guardian_address_fields
+ attach_file guardian_photo_field, file_fixture('hemsworth.jpeg'), visible: :all
+ draw_signature file_fixture('signature.png'), 'appearance_release_signature_base64'
+
+ fill_in guardian_2_first_name_field, with: 'Second'
+ fill_in guardian_2_last_name_field, with: 'Guardian'
+ fill_in guardian_2_phone_field, with: '999'
+
+ click_button submit_release_button
+
+ expect(page).to have_content(successful_submission_message)
+ expect(AppearanceRelease.last.guardian_2_first_name).to eq 'Second'
+ end
end
context 'when signed in' do
@@ -454,6 +509,18 @@ feature 'User managing appearance releases' do
'appearance_release_minor'
end
+ def guardian_2_first_name_field
+ 'Guardian 2 first name'
+ end
+
+ def guardian_2_last_name_field
+ 'Guardian 2 last name'
+ end
+
+ def guardian_2_phone_field
+ 'Guardian 2 phone'
+ end
+
def guardian_first_name_field
'Guardian first name'
end
diff --git a/spec/features/user_managing_misc_releases_spec.rb b/spec/features/user_managing_misc_releases_spec.rb
new file mode 100644
index 0000000..d2ae17e
--- /dev/null
+++ b/spec/features/user_managing_misc_releases_spec.rb
@@ -0,0 +1,55 @@
+require "rails_helper"
+
+feature "User managing misc releases" do
+ let(:current_user) { create(:user) }
+ let(:project) { create(:project, members: current_user, account: current_user.primary_account) }
+
+ context "when signed in as account manager" do
+ before do
+ sign_in current_user
+ end
+
+ scenario "Download All is visible" do
+ create(:misc_release_with_contract_template, :native, project: project)
+
+ visit project_misc_releases_path(project)
+
+ expect(page).to have_content download_all_button
+ end
+
+ scenario "Downloading PDF of native misc release is possible" do
+ native_release = create(:misc_release_with_contract_template, :native, project: project)
+
+ visit project_misc_releases_path(project)
+
+ click_link *view_release_pdf_link_for(native_release)
+ expect(content_type).to eq('application/pdf')
+ end
+ end
+
+ context "when the user is manager(project manager)" do
+ let(:current_user) { create(:user, :manager) }
+
+ before do
+ sign_in current_user
+ end
+
+ scenario "Download 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).to have_link("Download", exact: true, count: 0)
+ end
+ end
+
+ private
+
+ def download_all_button
+ 'Download All'
+ end
+
+ def view_release_pdf_link_for(release)
+ ['Download', href: misc_release_contracts_path(release, format: 'pdf')]
+ end
+end
diff --git a/spec/lib/zoom_gateway_spec.rb b/spec/lib/zoom_gateway_spec.rb
index 0b48a24..dc41514 100644
--- a/spec/lib/zoom_gateway_spec.rb
+++ b/spec/lib/zoom_gateway_spec.rb
@@ -5,6 +5,7 @@ RSpec.describe ZoomGateway do
let(:host_user_hash) { {"email" => "user1@directme", "id" => "host_user_id"} }
let(:roles_members_response) { {"members" => [host_user_hash]} }
let(:user_create_response) { {"id" => "new_host_id"} }
+ let(:user_settings_update_response) { "User settings updated" }
let(:roles_assign_response) { {"ids" => ["new_host_id"]} }
let(:meeting_hash) { {"id" => "meeting_id", "start_url" => "https://start_url", "join_url" => "https://join_url"} }
let(:gateway) { ZoomGateway.new }
@@ -121,7 +122,9 @@ RSpec.describe ZoomGateway do
it "returns new host id" do
allow_any_instance_of(Zoom.new.class).to receive(:user_create).and_return(user_create_response)
allow_any_instance_of(Zoom.new.class).to receive(:roles_assign).and_return(roles_assign_response)
+ allow_any_instance_of(Zoom.new.class).to receive(:user_settings_update).and_return(user_settings_update_response)
+ expect_any_instance_of(Zoom.new.class).to receive(:user_settings_update)
expect(gateway.create_host("host-email@address")).to eq("new_host_id")
end
diff --git a/spec/lib/zoom_wrapper_monkeypatch_spec.rb b/spec/lib/zoom_wrapper_monkeypatch_spec.rb
new file mode 100644
index 0000000..7f653e6
--- /dev/null
+++ b/spec/lib/zoom_wrapper_monkeypatch_spec.rb
@@ -0,0 +1,60 @@
+require 'rails_helper'
+
+RSpec.describe Zoom::Actions::User do
+ let(:wrapper) { Zoom.new }
+
+ describe '.update_user_settings' do
+ it 'raises exception if id param is missing' do
+ params = {
+ in_meeting: {
+ not_allowed_param: 1
+ }
+ }
+
+ expect do
+ wrapper.user_settings_update(params)
+ end.to raise_exception(Zoom::ParameterMissing)
+ end
+
+ it 'raises exception if not allowed param is present' do
+ params = {
+ id: 'dw3-3sd33',
+ in_meeting: {
+ not_allowed_param: 1
+ }
+ }
+
+ expect do
+ wrapper.user_settings_update(params)
+ end.to raise_exception(Zoom::ParameterNotPermitted)
+ end
+
+ it 'sends PATCH request to the Zoom API endpoint' do
+ params = {
+ id: 'zoom-120-id',
+ in_meeting: {
+ auto_saving_chat: true,
+ co_host: true,
+ non_verbal_feedback: true,
+ breakout_room: true,
+ group_hd: true,
+ far_end_camera_control: true,
+ allow_live_streaming: true
+ }
+ }
+
+ allow(Zoom::Utils).to receive(:parse_response).and_return 'Success!'
+
+ path = "/users/#{params[:id]}/settings"
+ body_params = { body: params.except(:id).to_json }
+ allow(wrapper.class)
+ .to receive(:patch)
+ .with(path, hash_including(body_params))
+ .and_return({})
+
+ mock_response = wrapper.user_settings_update params
+ expect(mock_response).to eq 'Success!'
+ end
+ end
+
+end
diff --git a/spec/policies/misc_release_policy_spec.rb b/spec/policies/misc_release_policy_spec.rb
new file mode 100644
index 0000000..3105adb
--- /dev/null
+++ b/spec/policies/misc_release_policy_spec.rb
@@ -0,0 +1,33 @@
+require "rails_helper"
+
+describe MiscReleasePolicy do
+ let(:user_context) { build(:user_context) }
+
+ subject { described_class }
+
+ permissions :create? do
+ it { is_expected.to permit(:create) }
+ end
+
+ permissions :show? do
+ it { is_expected.to permit(:show) }
+ end
+
+ permissions :update? do
+ context "for a native release" do
+ it { is_expected.not_to permit(user_context, build(:misc_release, :native)) }
+ end
+ end
+
+ permissions :destroy? do
+ it { is_expected.to permit(:destroy) }
+ end
+
+ permissions :edit_photos? do
+ it { is_expected.to permit(:edit_photos) }
+ end
+
+ permissions :update_photos? do
+ it { is_expected.to permit(:update_photos) }
+ end
+end