diff --git a/app/assets/javascripts/osem.js b/app/assets/javascripts/osem.js index dcab692c..0839f13b 100644 --- a/app/assets/javascripts/osem.js +++ b/app/assets/javascripts/osem.js @@ -149,15 +149,21 @@ function word_count(text, divId, maxcount) { /* Wait for the DOM to be ready before attaching events to the elements */ $( document ).ready(function() { - /* Set the minimum and maximum proposal abstract word length */ + /* Set the minimum and maximum proposal abstract and submission text word length */ $("#event_event_type_id").change(function () { var $selected = $("#event_event_type_id option:selected") var max = $selected.data("max-words"); var min = $selected.data("min-words"); $("#abstract-maximum-word-count").text(max); + $("#submission-maximum-word-count").text(max); $("#abstract-minimum-word-count").text(min); + $("#submission-minimum-word-count").text(min); word_count($('#event_abstract').get(0), 'abstract-count', max); + word_count($('#event_submission_text').get(0), 'submission-count', max); + + // Set the placeholder text for the abstract + $('#event_submission_text').attr("placeholder", $selected.data("help")); }) .trigger('change'); @@ -167,6 +173,13 @@ $( document ).ready(function() { var max = $selected.data("max-words"); word_count(this, 'abstract-count', max); } ); + + /* Count the submission text length */ + $("#event_submission_text").bind('change keyup paste input', function() { + var $selected = $("event_event_type_id option:selected") + var max = $selected.data("max-words"); + word_count(this, 'submission-count', max); + }); }); /* Commodity function for modal windows */ diff --git a/app/controllers/admin/events_controller.rb b/app/controllers/admin/events_controller.rb index b24882f3..f5e68165 100644 --- a/app/controllers/admin/events_controller.rb +++ b/app/controllers/admin/events_controller.rb @@ -175,7 +175,7 @@ module Admin def event_params params.require(:event).permit( # Set also in proposals controller - :title, :subtitle, :event_type_id, :abstract, :description, :require_registration, :difficulty_level_id, + :title, :subtitle, :event_type_id, :abstract, :submission_text, :description, :require_registration, :difficulty_level_id, # Set only in admin/events controller :track_id, :state, :language, :is_highlight, :max_attendees, # Not used anymore? diff --git a/app/controllers/proposals_controller.rb b/app/controllers/proposals_controller.rb index adfdbea0..bf1b3adc 100644 --- a/app/controllers/proposals_controller.rb +++ b/app/controllers/proposals_controller.rb @@ -170,7 +170,7 @@ class ProposalsController < ApplicationController def event_params params.require(:event).permit(:event_type_id, :track_id, :difficulty_level_id, - :title, :subtitle, :abstract, :description, + :title, :subtitle, :abstract, :submission_text, :description, :require_registration, :max_attendees, :language, speaker_ids: [], volunteer_ids: [] ) diff --git a/app/models/event.rb b/app/models/event.rb index 0370926b..ba04ba20 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -18,6 +18,7 @@ # require_registration :boolean # start_time :datetime # state :string default("new"), not null +# submission_text :text # subtitle :string # title :string not null # week :integer @@ -73,6 +74,7 @@ class Event < ApplicationRecord before_create :generate_guid validate :abstract_limit + validate :submission_limit validate :before_end_of_conference, on: :create validates :title, presence: true validates :abstract, presence: true @@ -217,6 +219,10 @@ class Event < ApplicationRecord abstract.to_s.split.size end + def submission_word_count + submission_text.to_s.split.size + end + def self.get_state_color(state) COLORS[state.to_sym] || '#00FFFF' # azure end @@ -341,16 +347,28 @@ class Event < ApplicationRecord errors.add(:max_attendees, "cannot be more than the room's capacity (#{room.size})") if max_attendees && (max_attendees > room.size) end - def abstract_limit - # If we don't have an event type, there is no need to count anything - return unless event_type && abstract + def word_limit(field) + # If we don't have an event type or the requested field, don't count + return unless event_type && respond_to?(field) && self[field] - len = abstract.split.size + len = self[field].split.size + # TODO: Use different limits for different text fields + # Uncomment the two lines below this when the separate word limits are implemented. + # max_words = event_type["maximum_#{field}_length"] + # min_words = event_type["minimum_#{field}_length"] max_words = event_type.maximum_abstract_length min_words = event_type.minimum_abstract_length - errors.add(:abstract, "cannot have less than #{min_words} words") if len < min_words - errors.add(:abstract, "cannot have more than #{max_words} words") if len > max_words + errors.add(field.to_sym, "cannot have less than #{min_words} words") if len < min_words + errors.add(field.to_sym, "cannot have more than #{max_words} words") if len > max_words + end + + def abstract_limit + word_limit(:abstract) + end + + def submission_limit + word_limit(:submission_text) end # TODO: create a module to be mixed into model to perform same operation diff --git a/app/serializers/event_serializer.rb b/app/serializers/event_serializer.rb index 4e81ef3b..8c30b1a1 100644 --- a/app/serializers/event_serializer.rb +++ b/app/serializers/event_serializer.rb @@ -18,6 +18,7 @@ # require_registration :boolean # start_time :datetime # state :string default("new"), not null +# submission_text :text # subtitle :string # title :string not null # week :integer diff --git a/app/views/admin/events/_proposal.html.haml b/app/views/admin/events/_proposal.html.haml index 1c2254d3..05d48bb7 100644 --- a/app/views/admin/events/_proposal.html.haml +++ b/app/views/admin/events/_proposal.html.haml @@ -113,6 +113,10 @@ %td %b Abstract %td= markdown(@event.abstract) + %tr + %td + %b Submission Description + %td= markdown(@event.submission_text) %tr %td %b Requirements diff --git a/app/views/proposals/_proposal_form.html.haml b/app/views/proposals/_proposal_form.html.haml index f385bdeb..5b4e7079 100644 --- a/app/views/proposals/_proposal_form.html.haml +++ b/app/views/proposals/_proposal_form.html.haml @@ -13,7 +13,7 @@ = f.input :event_type_id, as: :select, collection: @conference.program.event_types.map {|type| ["#{type.title} - #{show_time(type.length)}", type.id, - data: { min_words: type.minimum_abstract_length, max_words: type.maximum_abstract_length }]}, + data: { min_words: type.minimum_abstract_length, max_words: type.maximum_abstract_length, help: type.description }]}, include_blank: false, label: 'Type', input_html: { class: 'select-help-toggle' } - if @program.languages.present? @@ -46,6 +46,22 @@ 250 words. + %br + + = f.input :submission_text, input_html: { rows: 5, data: { provide: 'markdown' }, placeholder: '' }, + hint: markdown_hint('Only conference organizers will read this.') + + %p + You have used + %span#submission-count #{@event.submission_word_count} + words. Submission descriptions must be between + %span#submission-minimum-word-count + 0 + and + %span#submission-maximum-word-count + 250 + words. + - if current_user.is_admin? or @program.cfp.enable_registrations? = f.inputs 'Enable pre-registration' do = f.input :require_registration, label: 'Require participants to register to your event' diff --git a/app/views/proposals/new.html.haml b/app/views/proposals/new.html.haml index b7fc22f5..bdd16e11 100644 --- a/app/views/proposals/new.html.haml +++ b/app/views/proposals/new.html.haml @@ -61,6 +61,22 @@ 250 words. + = f.input :submission_text, input_html: { rows: 5, data: { provide: 'markdown' } }, + hint: markdown_hint + + %p + You have used + %span#submission-count #{@event.submission_word_count} + words. Submission descriptions must be between + %span#submission-minimum-word-count + 0 + and + %span#submission-maximum-word-count + 250 + words. + + + - if @program.cfp.enable_registrations? = f.input :require_registration, label: 'Require participants to register to your event' diff --git a/db/migrate/20210215213515_add_submission_text_to_events.rb b/db/migrate/20210215213515_add_submission_text_to_events.rb new file mode 100644 index 00000000..cf935e18 --- /dev/null +++ b/db/migrate/20210215213515_add_submission_text_to_events.rb @@ -0,0 +1,5 @@ +class AddSubmissionTextToEvents < ActiveRecord::Migration[5.2] + def change + add_column :events, :submission_text, :text + end +end diff --git a/db/schema.rb b/db/schema.rb index e8ac08e8..dee892f6 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,10 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_07_16_181602) do - - # These are extensions that must be enabled in order to support this database - enable_extension "plpgsql" +ActiveRecord::Schema.define(version: 2021_02_15_213515) do create_table "answers", force: :cascade do |t| t.string "title" @@ -257,6 +254,7 @@ ActiveRecord::Schema.define(version: 2020_07_16_181602) do t.integer "program_id" t.integer "max_attendees" t.integer "comments_count", default: 0, null: false + t.text "submission_text" end create_table "events_registrations", force: :cascade do |t| diff --git a/spec/factories/events.rb b/spec/factories/events.rb index 18d40a3b..c8360449 100644 --- a/spec/factories/events.rb +++ b/spec/factories/events.rb @@ -18,6 +18,7 @@ # require_registration :boolean # start_time :datetime # state :string default("new"), not null +# submission_text :text # subtitle :string # title :string not null # week :integer diff --git a/spec/features/base_controller_spec.rb b/spec/features/base_controller_spec.rb index 57d5be94..6bfd0622 100644 --- a/spec/features/base_controller_spec.rb +++ b/spec/features/base_controller_spec.rb @@ -13,6 +13,10 @@ feature 'BaseController' do describe 'GET #verify_user_admin' do context 'when user is a guest' do + before(:each) do + sign_out + end + it 'redirects to sign in page' do visit admin_conferences_path expect(current_path).to eq new_user_session_path diff --git a/spec/features/proposals_spec.rb b/spec/features/proposals_spec.rb index 6839f8dd..15c23fcb 100644 --- a/spec/features/proposals_spec.rb +++ b/spec/features/proposals_spec.rb @@ -97,6 +97,7 @@ feature Event do fill_in 'event_title', with: 'Example Proposal' select('Example Event Type', from: 'event[event_type_id]') fill_in 'event_abstract', with: 'Lorem ipsum abstract' + fill_in 'event_submission_text', with: 'Lorem ipsum submission' click_button 'Submit Proposal' page.find('#flash') @@ -138,6 +139,9 @@ feature Event do fill_in 'event_abstract', with: 'Lorem ipsum abstract' expect(page).to have_text('You have used 3 words') + fill_in 'event_submission_text', with: 'Lorem ipsum submission_text' + expect(page).to have_text('Submission description') + click_link 'Do you require something special?' fill_in 'event_description', with: 'Lorem ipsum description' diff --git a/spec/helpers/events_helper_spec.rb b/spec/helpers/events_helper_spec.rb index c1cf5344..35866d6b 100644 --- a/spec/helpers/events_helper_spec.rb +++ b/spec/helpers/events_helper_spec.rb @@ -5,6 +5,7 @@ require 'spec_helper' describe EventsHelper, type: :helper do let(:conference) { create(:conference) } let(:event) { create(:event_full, program: conference.program) } + let(:event_schedule) { create(:event_schedule) } let(:my_vote) { 3 } let(:max_rating) { 5 } let(:fraction) { my_vote.to_s + '/' + max_rating.to_s } @@ -28,6 +29,27 @@ describe EventsHelper, type: :helper do end end + describe '#canceled_replacement_event_label' do + describe 'returns nothing' do + it "when the event isn't cancelled and is not a replacement" do + event.state = 'confirmed' + expect(canceled_replacement_event_label(event, nil, 'text-class')).to eq nil + end + + it 'when the event is canceled' do + event.state = 'canceled' + expect(canceled_replacement_event_label(event, nil, 'test-class')).to eq 'CANCELED' + end + + it 'when the event is a replacement but is not canceled' do + event.state = 'confirmed' + allow(event_schedule).to receive(:replacement?) { true } + expect(canceled_replacement_event_label(event, event_schedule, 'tent-class')).to eq 'REPLACEMENT' + end + + end + end + describe '#rating_tooltip' do let(:vote_count) { pluralize(event.voters.length, 'vote') } diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index c2dca815..14e0b044 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -18,6 +18,7 @@ # require_registration :boolean # start_time :datetime # state :string default("new"), not null +# submission_text :text # subtitle :string # title :string not null # week :integer @@ -109,6 +110,35 @@ describe Event do end end + describe '#submission_limit' do + before :each do + event.event_type.maximum_abstract_length = 3 + event.event_type.minimum_abstract_length = 2 + end + + context 'is invalid' do + it 'when submission text is too long' do + event.submission_text = 'four too many words' + expect(event.valid?).to eq false + expect(event.errors[:submission_text]).to eq ['cannot have more than 3 words'] + end + + it 'when submission text is too short' do + event.submission_text = 'word' + expect(event.valid?).to eq false + expect(event.errors[:submission_text]).to eq ['cannot have less than 2 words'] + end + end + + context 'is valid' do + it 'when submission text is within limts' do + event.abstract = 'the magic three' + expect(event.valid?).to eq true + expect(event.errors.size).to eq 0 + end + end + end + describe '#before_end_of_conference' do context 'is invalid' do it 'when event is created after the conference end_date, and returns an error message' do diff --git a/spec/serializers/event_serializer_spec.rb b/spec/serializers/event_serializer_spec.rb index b365a310..506134cf 100644 --- a/spec/serializers/event_serializer_spec.rb +++ b/spec/serializers/event_serializer_spec.rb @@ -18,6 +18,7 @@ # require_registration :boolean # start_time :datetime # state :string default("new"), not null +# submission_text :text # subtitle :string # title :string not null # week :integer