Compare commits

..

13 Commits

Author SHA1 Message Date
Bilal
3ffa883462 fix MR comments 2020-07-13 14:04:14 +02:00
Bilal
e0cf5ba875 add spec 2020-07-09 23:25:21 +02:00
Bilal
ebc13242de add spec 2020-07-09 23:12:37 +02:00
Bilal
8538613a83 sort translations 2020-07-09 20:59:29 +02:00
Bilal
fcb6e093c3 sort translations 2020-07-09 20:56:51 +02:00
Bilal
33bcb6600a TMP commit 2020-07-09 20:56:17 +02:00
Bilal
d585d3cad3 TMP commit 2020-07-09 20:52:41 +02:00
Bilal
578403bb5c TMP commit 2020-07-09 20:43:05 +02:00
Bilal
2020761649 TMP commit 2020-07-09 20:34:37 +02:00
Bilal
bb8e5c9b73 TMP commit 2020-07-09 20:17:48 +02:00
Bilal
5ed930108d TMP commit 2020-07-09 20:11:57 +02:00
Bilal
a1abd70ae9 TMP commit 2020-07-09 20:06:05 +02:00
Bilal
3918484a84 TMP commit 2020-07-09 19:54:48 +02:00
25 changed files with 22 additions and 461 deletions

View File

@@ -1,33 +0,0 @@
# frozen_string_literal: true
class ContractTemplates::DuplicatesController < ApplicationController
before_action :set_contract_template
def create
authorize(ContractTemplate)
new_contract_template = @contract_template.dup
new_contract_template.name = I18n.t('contract_templates.duplicate.name_prefix', template_name: @contract_template.name)
# Duplicate rich text fields
new_contract_template.body = @contract_template.body
new_contract_template.guardian_clause = @contract_template.guardian_clause
new_contract_template.signature_legal_text = @contract_template.signature_legal_text
if new_contract_template.save
redirect_to [:edit, new_contract_template]
else
redirect_to [@contract_template.project, :contract_templates], alert: t('.error')
end
end
private
def contract_templates
policy_scope(ContractTemplate)
end
def set_contract_template
@contract_template = contract_templates.find(params[:contract_template_id])
end
end

View File

@@ -5,9 +5,8 @@ class ContractTemplatesController < ApplicationController
layout 'project'
before_action :set_project, except: [:destroy, :edit, :update]
before_action :set_contract_template, only: [:destroy, :edit, :update]
before_action :set_project_from_contract_template, only: [:edit, :update]
before_action :set_project, except: [:destroy]
before_action :set_contract_template, only: [:destroy]
before_action :show_splash_screen, only: :index
def index
@@ -33,20 +32,6 @@ class ContractTemplatesController < ApplicationController
end
end
def edit
@release_type = @contract_template.release_type
end
def update
@contract_template.attributes = contract_template_params
if @contract_template.save
redirect_to [@project, :contract_templates], notice: t('.notice')
else
render :edit
end
end
def destroy
@contract_template.archive
redirect_to [@contract_template.project, :contract_templates], alert: t('.archived_notice')
@@ -54,10 +39,6 @@ class ContractTemplatesController < ApplicationController
private
def set_project_from_contract_template
@project = @contract_template.project
end
def show_splash_screen
render :splash if contract_templates.non_archived.count.zero?
end
@@ -85,7 +66,7 @@ class ContractTemplatesController < ApplicationController
:signature_legal_text, :fee,
:applicable_medium_id, :applicable_medium_text,
:territory_id, :territory_text,
:term_id, :term_text, :accessibility,
:term_id, :term_text,
:restriction_id, :restriction_text,
:question_1_text, :question_2_text,
:question_3_text, :question_4_text,

View File

@@ -28,9 +28,8 @@ class StreamNotificationsController < ApplicationController
asset_uid = notification.dig(:object, :id)
playback_uid = notification.dig(:data, :playback_ids, 0, :id)
file_name = notification.dig(:data, :static_renditions, :files, -1, :name)
duration = notification.dig(:data, :duration)
recording = @broadcast.broadcast_recordings.create!(asset_uid: asset_uid, asset_playback_uid: playback_uid, file_name: file_name, duration: duration)
recording = @broadcast.broadcast_recordings.create!(asset_uid: asset_uid, asset_playback_uid: playback_uid, file_name: file_name)
recordings = @broadcast.broadcast_recordings.order_by_recent.paginate(page: params[:page])
link = helpers.link_to(recording.broadcast_name.titleize, recording.download_url, target: "_blank")

View File

@@ -43,8 +43,6 @@ class ContractTemplate < ApplicationRecord
scope :non_archived, -> { where(archived_at: nil) }
scope :order_by_name, -> { order(:name) }
enum accessibility: [:public_template, :private_template]
def fee?
!fee.zero?
end
@@ -68,14 +66,4 @@ class ContractTemplate < ApplicationRecord
def has_questionnaire?
(1..NUMBER_OF_CUSTOM_FIELDS).any? { |n| public_send("question_#{n}_text").presence }
end
def editable?
releases.size.zero?
end
def attributes
result = super()
result[:signature_legal_text] = signature_legal_text.as_json
result
end
end

View File

@@ -3,10 +3,8 @@ class ContractTemplatePolicy < ApplicationPolicy
def resolve
if user.account_manager?
scope.left_outer_joins(:project).where(projects: {account: user.account})
elsif user.manager?
scope.left_outer_joins(project: :project_memberships).where(project_memberships: { user_id: user.id })
else
scope.public_template.left_outer_joins(project: :project_memberships).where(project_memberships: { user_id: user.id })
scope.left_outer_joins(project: :project_memberships).where(project_memberships: { user_id: user.id })
end
end
end
@@ -23,18 +21,6 @@ class ContractTemplatePolicy < ApplicationPolicy
create?
end
def edit?
record.editable? && create?
end
def update?
edit?
end
def duplicate?
create?
end
def import?
if user.account_manager?
record.project.account = user.account

View File

@@ -19,12 +19,6 @@
<div class="btn-group">
<%= button_tag t(".actions.manage"), class: "btn btn-light btn-sm dropdown-toggle border", data: { toggle: "dropdown", boundary: "window" }, aria: { haspopup: true, expanded: false } %>
<div class="dropdown-menu dropdown-menu-right">
<% if policy(contract_template).edit? %>
<%= link_to fa_icon("pencil fw", text: t(".actions.edit")), [:edit, contract_template], class: "dropdown-item" %>
<% end %>
<% if policy(ContractTemplate).duplicate? %>
<%= link_to fa_icon("clone fw", text: t(".actions.duplicate")), contract_template_duplicates_path(contract_template), method: :post, class: "dropdown-item" %>
<% end %>
<% if policy(QrCode).show? %>
<%= link_to fa_icon("qrcode", text: t(".actions.qr_code")), [contract_template, :qr_codes], class: "dropdown-item", target: :_blank %>
<% end %>

View File

@@ -1,13 +1,9 @@
<%= bootstrap_form_with model: model, local: true do |form| %>
<%= bootstrap_form_with model: [project, contract_template], local: true do |form| %>
<%= field_set_tag content_tag(:span, t(".release_info.heading"), class: "h6 text-muted text-uppercase") do %>
<div class="form-row">
<%= 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" %>
</div>
<div class="form-row mb-3">
<%= form.radio_button :accessibility, :public_template, label: "Public", wrapper_class: "mr-3" %>
<%= form.radio_button :accessibility, :private_template, label: "Private" %>
</div>
<div class="form-row" id="fee_field">
<%= form.number_field :fee, min:"0", max:"99999999", step: "0.01", prepend: "$", wrapper_class: "col-sm-6" %>
</div>

View File

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

View File

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

View File

@@ -250,8 +250,6 @@ en:
contract_template:
actions:
copy_url: Copy Release URL
duplicate: Duplicate
edit: Edit
manage: Manage
qr_code: QR Code
sign: Sign
@@ -261,13 +259,6 @@ en:
destroy:
archived_failure: Failed to archive the release template
archived_notice: The release template has been archived
duplicate:
name_prefix: Copy of %{template_name}
duplicates:
create:
error: Failed to duplicate release template
edit:
heading: Edit Contract Template
form:
custom_fields:
heading: Questionnaire
@@ -306,8 +297,6 @@ en:
manage_large_audience: Easily manage large audiences with the crowd control feature
print_QR_code: Print out release QR codes
releases_automatically_organized: Releases are automatically organized as theyre submitted
update:
notice: The release template has been updated
contracts:
for_office_use_only:
description_labels:
@@ -700,7 +689,6 @@ en:
update: Save Changes
contract_template:
create: Create Release Template
update: Save Changes
directory:
create: Create Folder
new_file: Upload Files

View File

@@ -103,17 +103,6 @@ es:
blank_contracts:
create:
number_of_copies_invalid_notice: Please enter valid number greater than 0 (ES)
contract_template:
actions:
duplicate: Duplicate (ES)
edit: Edit (ES)
duplicate:
name_prefix: Copy of %{template_name} (ES)
duplicates:
create:
error: Failed to duplicate release template (ES)
edit:
heading: Edit Contract Template (ES)
form:
custom_fields:
heading: Medical Questionnaire (ES)
@@ -140,8 +129,6 @@ es:
manage_large_audience: Easily manage large audiences with the crowd control feature (ES)
print_QR_code: Print out release QR codes (ES)
releases_automatically_organized: Releases are automatically organized as theyre submitted (ES)
update:
notice: The release template has been updated (ES)
contracts:
for_office_use_only:
description_labels:
@@ -317,8 +304,6 @@ es:
broadcast:
create: Create Live Stream (ES)
update: Save Changes (ES)
contract_template:
update: Save changes (ES)
create: 'Crear %{model}'
medical_release:
update: Approve (ES)

View File

@@ -56,10 +56,9 @@ Rails.application.routes.draw do
resources :talent_releases, except: [:show], concerns: [:contractable, :notable, :photoable]
resources :medical_releases, except: [:show], concerns: [:contractable, :notable, :photoable]
resources :misc_releases, except: [:show], concerns: [:contractable, :notable, :photoable]
resources :contract_templates, only: [:index, :new, :create, :edit, :update, :destroy] do
resources :contract_templates, only: [:index, :new, :create, :destroy] do
resource :qr_codes, only: [:show], controller: "contract_templates/qr_codes"
resource :blank_contracts, only: [:show, :new, :create], controller: "contract_templates/blank_contracts"
resource :duplicates, only: [:create], controller: "contract_templates/duplicates"
end
resource :release_template_imports, only: [:new, :create]
resources :project_memberships, only: [:index, :create, :destroy]

View File

@@ -1,18 +0,0 @@
class AddDurationToBroadcastRecordings < ActiveRecord::DataMigration
def up
recordings = BroadcastRecording.where(duration: nil)
client = MuxRuby::AssetsApi.new
recordings.each do |recording|
begin
response = client.get_asset(recording.asset_uid)
duration = response.data.duration
recording.update(duration: duration)
rescue MuxRuby::ApiError => e
Rails.logger.error("Failed to update duration for broadcast recording with id #{recording.id}\n" + e.message)
end
sleep(1)
end
end
end

View File

@@ -1,5 +0,0 @@
class AddAccessibilityToContractTemplates < ActiveRecord::Migration[6.0]
def change
add_column :contract_templates, :accessibility, :integer, default: 0
end
end

View File

@@ -1,5 +0,0 @@
class AddDurationToBroadcastRecordings < ActiveRecord::Migration[6.0]
def change
add_column :broadcast_recordings, :duration, :float
end
end

View File

@@ -494,8 +494,7 @@ CREATE TABLE public.broadcast_recordings (
asset_playback_uid character varying NOT NULL,
file_name character varying NOT NULL,
created_at timestamp(6) without time zone NOT NULL,
updated_at timestamp(6) without time zone NOT NULL,
duration double precision
updated_at timestamp(6) without time zone NOT NULL
);
@@ -630,8 +629,7 @@ CREATE TABLE public.contract_templates (
question_12_text text,
question_13_text text,
question_14_text text,
question_15_text text,
accessibility integer DEFAULT 0
question_15_text text
);
@@ -3908,8 +3906,6 @@ INSERT INTO "schema_migrations" (version) VALUES
('20200622180507'),
('20200625144713'),
('20200702152130'),
('20200707155717'),
('20200709120630'),
('20200712181139');
('20200707155717');

View File

@@ -30,21 +30,6 @@ RSpec.describe Api::ContractTemplatesController, type: :controller do
expect(response).to be_successful
end
it 'returns electronic signature legal text when present' do
ct = create(:contract_template, name: 'ct1', project_id: project.id)
ct.signature_legal_text = "some electronic signature legal text"
ct.save
sign_in_to_api(current_user)
get :show, params: { id: ct.id }
expect(response).to be_successful
expect(response.body).to include("signature_legal_text")
expect(response.body).to include(ct.signature_legal_text.body.as_json)
end
end
private

View File

@@ -127,15 +127,8 @@ RSpec.describe Api::SyncController, type: :controller do
get :index
medical_releases = attributes_for_type('medical_releases')
expect(medical_releases.first).to include('id')
end
it 'contains signature legal text for contract templates' do
create_default_data_with_signature_legal_text
get :index
contract_templates = attributes_for_type('contract_templates')
expect(contract_templates.first).to include('signature_legal_text')
expect(contract_templates.first['signature_legal_text']).to eq ContractTemplate.first.signature_legal_text.as_json
expect(medical_releases.first).to include('id')
end
end
@@ -156,13 +149,6 @@ RSpec.describe Api::SyncController, type: :controller do
create(:appearance_release, :minor_with_guardian_photo, project: project)
end
def create_default_data_with_signature_legal_text
create_default_data
ct = create(:contract_template, name: "with signature legal text", project: Project.first)
ct.signature_legal_text = "legal text example"
ct.save
end
def response_body_json
JSON.parse(response.body)
end

View File

@@ -1,30 +0,0 @@
# frozen_string_literal: true
require 'rails_helper'
describe ContractTemplates::DuplicatesController do
let(:account) { build(:account) }
let(:current_user) { create(:user, :manager, primary_account: account) }
let(:project) { create(:project, members: [current_user], account: account) }
before do
sign_in(current_user)
end
describe '#create' do
it "responds with redirect to the edit page for newly created duplicate" do
contract_template = create(:contract_template, project: project)
expect do
post :create, params: { contract_template_id: contract_template }
end.to change(ContractTemplate, :count).by(1)
new_ct = ContractTemplate.last
expect(new_ct.name).to eq t('contract_templates.duplicate.name_prefix', template_name: contract_template.name)
expect(new_ct.release_type).to eq contract_template.release_type
expect(response).to redirect_to [:edit, new_ct]
end
end
end

View File

@@ -118,57 +118,6 @@ describe ContractTemplatesController do
end
end
describe '#edit' do
let(:contract_template) do
create(:contract_template,
name: 'My Contract Template', fee: 50, release_type: 'appearance',
project: project)
end
it 'responds ok' do
get :edit, params: { project_id: project, id: contract_template }
expect(response).to be_successful
end
context 'when current user is an associate' do
let(:current_user) { create(:user, :associate) }
it 'raises exception' do
expect do
get :edit, params: { project_id: project, id: contract_template }
end.to raise_error(Pundit::NotAuthorizedError)
end
end
end
describe '#update' do
let(:contract_template) do
create(:contract_template,
name: 'My Contract Template', fee: 50, release_type: 'appearance',
project: project)
end
it 'redirects' do
patch :update, params: { project_id: project, id: contract_template, contract_template: contract_template_params }
expect(response).to redirect_to(project_contract_templates_path(project))
end
context 'when current user is an associate' do
let(:current_user) { create(:user, :associate) }
it 'raises exception' do
expect do
patch :update, params: { project_id: project, id: contract_template, contract_template: contract_template_params }
end.to raise_error(Pundit::NotAuthorizedError)
end
end
end
describe '#destroy' do
let!(:contract_template) { create(:contract_template, project: project) }

View File

@@ -7,7 +7,6 @@ FactoryBot.define do
body "This is a test contract template."
guardian_clause "Is the signer a minor?"
fee "$0.00"
accessibility "public_template"
trait :archived do
archived_at Time.zone.now

View File

@@ -49,18 +49,12 @@ FactoryBot.define do
predefined_client_name "nat_geo"
end
factory :project_with_contract_template_public do
factory :project_with_contract_template do
after(:build) do |project, _|
project.contract_templates << build(:contract_template, project: nil)
end
end
factory :project_with_contract_template_private do
after(:build) do |project, _|
project.contract_templates << build(:contract_template, project: nil, accessibility: "private_template")
end
end
factory :project_with_directories do
after(:build) do |project, _|
project.directories << build(:directory, project: nil, name: "Shared")

View File

@@ -262,93 +262,6 @@ RSpec.feature 'User manages contract templates', type: :feature do
expect(page).to have_content('Active template')
end
scenario 'edit button is visible for not-signed contract template' do
create(:contract_template, project: project)
visit project_contract_templates_path(project)
expect(page).to have_link(edit_button_label, exact: true, count: 1)
end
scenario 'edit button is not visible for signed contract template' do
ct = create(:contract_template, project: project)
create(:appearance_release, contract_template: ct)
visit project_contract_templates_path(project)
expect(page).to have_link(edit_button_label, exact: true, count: 0)
end
scenario 'duplicate button is visible for not signed contract template' do
create(:contract_template, project: project)
visit project_contract_templates_path(project)
expect(page).to have_link(duplicate_button_label, exact: true, count: 1)
end
scenario 'duplicate button is visible for signed contract template' do
ct = create(:contract_template, project: project)
create(:appearance_release, contract_template: ct)
visit project_contract_templates_path(project)
expect(page).to have_link(duplicate_button_label, exact: true, count: 1)
end
scenario 'clicking edit button opens edit page for contract template' do
ct = create(:contract_template, project: project)
visit project_contract_templates_path(project)
expect(page).to have_content ct.name
expect(page).not_to have_content 'Updated CT'
expect(page).not_to have_content 'Medical'
click_link edit_button_label
expect(page).to have_content edit_page_heading
fill_in name_field, with: 'Updated CT'
select 'Medical Release', from: 'Release type'
fill_in_trix body_field, with: 'Updated legal text'
click_on update_contract_template_button_label
expect(page).to have_content 'Updated CT'
expect(page).to have_content 'Medical'
end
scenario 'clicking duplicate button opens edit page for newly created contract template' do
ct = create(:contract_template, project: project)
visit project_contract_templates_path(project)
expect(page).to have_content ct.name
expect(page).not_to have_content 'Modified duplicate'
expect(page).not_to have_content 'Misc'
expect do
click_link duplicate_button_label
end.to change(ContractTemplate, :count).by(1)
expect(page).to have_content edit_page_heading
name_input = find("##{name_field}")
expect(name_input.value).to eq duplicate_release_name(ct.name)
fill_in name_field, with: 'Modified duplicate'
select 'Misc Release', from: 'Release type'
fill_in_trix body_field, with: 'Legal text for duplicate'
click_on update_contract_template_button_label
expect(page).to have_content 'Modified duplicate'
expect(page).to have_content 'Misc'
expect(ct.body.id).not_to eq ContractTemplate.last.body.id
expect(ct.guardian_clause.id).not_to eq ContractTemplate.last.guardian_clause.id
expect(ct.signature_legal_text.id).not_to eq ContractTemplate.last.signature_legal_text.id
end
context 'When the user is associate' do
let(:current_user) { create(:user, :associate) }
@@ -367,22 +280,6 @@ 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
end
it 'does not show edit button' do
create(:contract_template, project: project)
visit project_contract_templates_path(project)
expect(page).to have_link(edit_button_label, exact: true, count: 0)
end
it 'does not show duplicate button' do
create(:contract_template, project: project)
visit project_contract_templates_path(project)
expect(page).to have_link(duplicate_button_label, exact: true, count: 0)
end
end
context 'When the user is account manager' do
@@ -403,40 +300,6 @@ RSpec.feature 'User manages contract templates', type: :feature do
expect(page).to have_content schedule_demo
expect(page).to have_content create_release_template
end
it 'shows edit button when contract template is not signed' do
create(:contract_template, project: project)
visit project_contract_templates_path(project)
expect(page).to have_link(edit_button_label, exact: true, count: 1)
end
it 'does not show edit button when contract template is signed' do
ct = create(:contract_template, project: project)
create(:appearance_release, contract_template: ct)
visit project_contract_templates_path(project)
expect(page).to have_link(edit_button_label, exact: true, count: 0)
end
it 'shows duplicate button when contract template is not signed' do
create(:contract_template, project: project)
visit project_contract_templates_path(project)
expect(page).to have_link(duplicate_button_label, exact: true, count: 1)
end
it 'shows duplicate button when contract template is signed' do
ct = create(:contract_template, project: project)
create(:appearance_release, contract_template: ct)
visit project_contract_templates_path(project)
expect(page).to have_link(duplicate_button_label, exact: true, count: 1)
end
end
private
@@ -492,28 +355,4 @@ RSpec.feature 'User manages contract templates', type: :feature do
def signature_legal_text_trix_field
'Signature legal text'
end
def edit_button_label
t 'contract_templates.contract_template.actions.edit'
end
def duplicate_button_label
t 'contract_templates.contract_template.actions.duplicate'
end
def edit_page_heading
t 'contract_templates.edit.heading'
end
def name_field
'contract_template_name'
end
def update_contract_template_button_label
t 'helpers.submit.contract_template.update'
end
def duplicate_release_name(template_name = '')
t 'contract_templates.duplicate.name_prefix', template_name: template_name
end
end

View File

@@ -36,7 +36,7 @@ RSpec.describe Project, type: :model do
describe "#import_contract_templates" do
it "imports contract templates from other projects within the account" do
existing_project = create(:project_with_contract_template_public)
existing_project = create(:project_with_contract_template)
new_project = create(:project, name: "New Project", account: existing_project.account)
expect {

View File

@@ -75,17 +75,14 @@ describe ContractTemplatePolicy do
end
permissions ".scope" do
let!(:member_project_public_template) do
create(:project_with_contract_template_public, name: "Member Project Public Template", members: user, account: account)
end
let!(:member_project_private_template) do
create(:project_with_contract_template_private, name: "Member Project Private Template", members: user, account: account)
let!(:member_project) do
create(:project_with_contract_template, name: "Member Project", members: user, account: account)
end
let!(:non_member_project) do
create(:project_with_contract_template_public, name: "Non-Member Project", account: account)
create(:project_with_contract_template, name: "Non-Member Project", account: account)
end
let!(:outside_project) do
create(:project_with_contract_template_public, name: "Outside Project", account: build(:account))
create(:project_with_contract_template, name: "Outside Project", account: build(:account))
end
let(:account) { build(:account) }
@@ -96,8 +93,7 @@ describe ContractTemplatePolicy do
context "for an account manager" do
let(:user) { create(:user, :account_manager, primary_account: account)}
it { is_expected.to include(member_project_public_template.contract_templates.first) }
it { is_expected.to include(member_project_private_template.contract_templates.first) }
it { is_expected.to include(member_project.contract_templates.first) }
it { is_expected.to include(non_member_project.contract_templates.first) }
it { is_expected.not_to include(outside_project.contract_templates.first) }
end
@@ -105,17 +101,15 @@ describe ContractTemplatePolicy do
context "for manager" do
let(:user) { create(:user, :manager, primary_account: account) }
it { is_expected.to include(member_project_public_template.contract_templates.first) }
it { is_expected.to include(member_project_private_template.contract_templates.first) }
it { is_expected.to include(member_project.contract_templates.first) }
it { is_expected.not_to include(non_member_project.contract_templates.first) }
it { is_expected.not_to include(outside_project.contract_templates.first) }
end
context "for associate" do
let(:user) { create(:user, :associate, primary_account: account) }
it { is_expected.to include(member_project_public_template.contract_templates.first) }
it { is_expected.not_to include(member_project_private_template.contract_templates.first) }
it { is_expected.to include(member_project.contract_templates.first) }
it { is_expected.not_to include(non_member_project.contract_templates.first) }
it { is_expected.not_to include(outside_project.contract_templates.first) }
end