From cde81508b4d6ca60914a26c896c1df20c3d763ce Mon Sep 17 00:00:00 2001 From: Bilal Date: Wed, 15 Jul 2020 16:35:18 +0200 Subject: [PATCH] validate zoom meeting url --- .../casting_call_interviews_controller.rb | 13 ++-- app/models/casting_call_interview.rb | 16 +++++ config/locales/en.yml | 4 ++ config/locales/es.yml | 5 ++ db/structure.sql | 14 ---- ...casting_call_interviews_controller_spec.rb | 22 +++++- ...n_managing_casting_call_interviews_spec.rb | 71 +++++++++++++++++++ spec/models/casting_call_interview_spec.rb | 1 + 8 files changed, 122 insertions(+), 24 deletions(-) create mode 100644 spec/features/admin_managing_casting_call_interviews_spec.rb diff --git a/app/controllers/admin/casting_call_interviews_controller.rb b/app/controllers/admin/casting_call_interviews_controller.rb index c9f0a92..9b83b34 100644 --- a/app/controllers/admin/casting_call_interviews_controller.rb +++ b/app/controllers/admin/casting_call_interviews_controller.rb @@ -1,14 +1,11 @@ class Admin::CastingCallInterviewsController < Admin::ApplicationController before_action :set_casting_call_interview, only: [:edit, :update, :show, :complete] before_action :build_casting_call_interview, only: [:new, :create] + before_action :set_accounts, only: %i[new create edit] def index @casting_call_interviews = casting_call_interviews.order_by_recent.paginate(page: params[:page]) end - - def new - @accounts = accounts - end def create @casting_call_interview.attributes = casting_call_interview_params @@ -20,10 +17,6 @@ class Admin::CastingCallInterviewsController < Admin::ApplicationController end end - def edit - @accounts = accounts - end - def update if @casting_call_interview.update(casting_call_interview_params) redirect_to [:admin, :casting_call_interviews], notice: t(".notice") @@ -42,6 +35,10 @@ class Admin::CastingCallInterviewsController < Admin::ApplicationController private + def set_accounts + @accounts = accounts + end + def casting_call_interview_params params.require(:casting_call_interview).permit(:casting_call_id, :performer_name, :interview_date, :zoom_meeting_url) end diff --git a/app/models/casting_call_interview.rb b/app/models/casting_call_interview.rb index 3427ed3..225f681 100644 --- a/app/models/casting_call_interview.rb +++ b/app/models/casting_call_interview.rb @@ -5,6 +5,7 @@ class CastingCallInterview < ApplicationRecord has_secure_token validates :performer_name, presence: true + validate :zoom_meeting_url_validation scope :completed, -> { where.not(interviewed_at: nil) } @@ -19,4 +20,19 @@ class CastingCallInterview < ApplicationRecord def zip_file_name "#{self.casting_call.title.parameterize}_#{self.performer_name.parameterize}_#{Time.now.strftime('%Y-%m-%d_%H-%M-%S')}" end + + def zoom_meeting_url_validation + # valid url format : + # https://us01web.zoom.us/j/12345?pwd=Ab103odw3ok343ko + valid_url_regex = %r{^https\://[a-z0-9]+\.zoom.us/j/[0-9]+\?pwd\=.+} + return true if zoom_meeting_url.match valid_url_regex + + errors.add(:base, invalid_meeting_url_message) + end + + private + + def invalid_meeting_url_message + I18n.t('casting_call_interviews.validation_errors.invalid_meeting_url') + end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 2d8fc99..6a5ece3 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -249,6 +249,8 @@ en: empty: Casting Call Interview results will appear here. show: empty: Interview files and recorded meeetings will appear here. + validation_errors: + invalid_meeting_url: Zoom Meeting URL is invalid casting_calls: cancel: notice: The casting call request has been cancelled successfully @@ -721,6 +723,8 @@ en: broadcast: create: Create Live Stream update: Save Changes + casting_call_interview: + create: Create casting call interview contract_template: create: Create Release Template directory: diff --git a/config/locales/es.yml b/config/locales/es.yml index 636e5f2..f352771 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -76,6 +76,9 @@ es: share_stream: Share live stream link with clients stream_from_mobile_app: Stream from ME Suite Mobile app, or via a professional camera stream_multiple_cameras: Stream multiple cameras at one time + casting_call_interviews: + validation_errors: + invalid_meeting_url: Zoom Meeting URL is invalid (ES) contract_templates: blank_contracts: create: @@ -272,6 +275,8 @@ es: broadcast: create: Create Live Stream (ES) update: Save Changes (ES) + casting_call_interview: + create: Create casting call interview (ES) create: 'Crear %{model}' update: 'Actualizar %{model}' location_releases: diff --git a/db/structure.sql b/db/structure.sql index cb699b9..c858da2 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: - -- diff --git a/spec/controllers/admin/casting_call_interviews_controller_spec.rb b/spec/controllers/admin/casting_call_interviews_controller_spec.rb index d2ff7b2..7a6b3ea 100644 --- a/spec/controllers/admin/casting_call_interviews_controller_spec.rb +++ b/spec/controllers/admin/casting_call_interviews_controller_spec.rb @@ -37,6 +37,16 @@ RSpec.describe Admin::CastingCallInterviewsController, type: :controller do post :create, params: { casting_call_interview: casting_call_interview_params } }.to change(CastingCallInterview, :count) end + + it "does not create new record if zoom meeting url is not valid" do + expect { + post :create, params: { + casting_call_interview: casting_call_interview_params + .except(:zoom_meeting_url) + .merge(zoom_meeting_url: "malformed_url") + } + }.to change(CastingCallInterview, :count).by(0) + end end describe "#edit" do @@ -74,7 +84,7 @@ RSpec.describe Admin::CastingCallInterviewsController, type: :controller do it "updates casting call interview" do patch :update, params: { id: casting_call_interview, casting_call_interview: update_params } - expect(casting_call_interview.reload.zoom_meeting_url).to eq("new_zoom_meeting_url") + expect(casting_call_interview.reload.zoom_meeting_url).to eq new_zoom_meeting_url end end @@ -100,7 +110,15 @@ RSpec.describe Admin::CastingCallInterviewsController, type: :controller do def update_params { - zoom_meeting_url: "new_zoom_meeting_url" + zoom_meeting_url: new_zoom_meeting_url } end + + def new_zoom_meeting_url + "https://s01web.zoom.us/j/11111?pwd=Ab123Cq34" + end + + def invalid_meeting_url_flash_error + t 'casting_call_interviews.validation_errors.invalid_meeting_url' + end end diff --git a/spec/features/admin_managing_casting_call_interviews_spec.rb b/spec/features/admin_managing_casting_call_interviews_spec.rb new file mode 100644 index 0000000..4514543 --- /dev/null +++ b/spec/features/admin_managing_casting_call_interviews_spec.rb @@ -0,0 +1,71 @@ +require "rails_helper" + +feature "Admin managing casting call interviews" do + let(:current_user) { create(:user, admin: true, email: "user@test.com") } + let(:project) { create(:project, account: current_user.primary_account, name: "Test Project") } + + before do + sign_in current_user + end + + scenario "admin cannot create casting call interview with invalid zoom url", js: true do + visit admin_casting_call_interviews_path + cc = create(:casting_call, title: "SpecialCastingCall") + + click_link create_casting_call_interview_button + expect(page).to have_content new_casting_call_interview_heading + + fill_in performer_name_field, with: "TestName" + select cc.title, from: casting_call_field + fill_in zoom_meeting_url_field, with: "malformed url" + + expect do + click_on submit_casting_call_interview_form + end.to change(CastingCallInterview, :count).by(0) + expect(page).to have_content zoom_meeting_url_invalid_error + + fill_in zoom_meeting_url_field, with: "https://similar.google.com/j/24324324?pwd=334kni3j4" + + expect do + click_on submit_casting_call_interview_form + end.to change(CastingCallInterview, :count).by(0) + expect(page).to have_content zoom_meeting_url_invalid_error + + fill_in zoom_meeting_url_field, with: "https://s01.zoom.us/j/343434?pwd=dawidj34ijij" + + expect do + click_on submit_casting_call_interview_form + end.to change(CastingCallInterview, :count).by(1) + expect(page).to have_content create_casting_call_interview_button + end + + private + + def create_casting_call_interview_button + t 'admin.casting_call_interviews.index.actions.new' + end + + def new_casting_call_interview_heading + t 'admin.casting_call_interviews.new.heading' + end + + def submit_casting_call_interview_form + t 'helpers.submit.casting_call_interview.create' + end + + def zoom_meeting_url_invalid_error + t 'casting_call_interviews.validation_errors.invalid_meeting_url' + end + + def performer_name_field + 'casting_call_interview[performer_name]' + end + + def zoom_meeting_url_field + 'casting_call_interview[zoom_meeting_url]' + end + + def casting_call_field + 'casting_call_interview[casting_call_id]' + end +end diff --git a/spec/models/casting_call_interview_spec.rb b/spec/models/casting_call_interview_spec.rb index 8affc14..624792b 100644 --- a/spec/models/casting_call_interview_spec.rb +++ b/spec/models/casting_call_interview_spec.rb @@ -1,6 +1,7 @@ require 'rails_helper' RSpec.describe CastingCallInterview, type: :model do + subject { build(:casting_call_interview) } describe "associations" do it { is_expected.to belong_to(:casting_call) } it { is_expected.to have_secure_token(:token) }