implements adding the proposal by admin users

This commit is contained in:
Eugene Dubinin 2017-01-19 17:05:25 +02:00
parent 2a0e1b5dea
commit b86c03f898
8 changed files with 287 additions and 4 deletions

View file

@ -4,8 +4,9 @@ module Admin
load_and_authorize_resource :program, through: :conference, singleton: true load_and_authorize_resource :program, through: :conference, singleton: true
load_and_authorize_resource :event, through: :program load_and_authorize_resource :event, through: :program
load_and_authorize_resource :events_registration, only: :toggle_attendance load_and_authorize_resource :events_registration, only: :toggle_attendance
load_and_authorize_resource :user, only: :new
before_action :get_event, except: [:index, :create, :reports] before_action :get_event, except: [:index, :create, :new, :reports]
# FIXME: The timezome should only be applied on output, otherwise # FIXME: The timezome should only be applied on output, otherwise
# you get lost in timezone conversions... # you get lost in timezone conversions...
@ -92,7 +93,34 @@ module Admin
end end
end end
def create; end def create
@url = admin_conference_program_events_path(@conference.short_title, @event)
@users = User.all
@languages = @program.languages_list
@event.validate_owners = true
# make event confirmed initially since there is not much sens to go over the approval procedure for admin-added proposals
@event.state = :confirmed
if @event.valid?
@event.event_users.new(user_id: @event.submitter_id,
event_role: 'submitter')
@event.event_users.new(user_id: @event.speaker_id,
event_role: 'speaker')
end
if @event.save
ahoy.track 'Event submission', title: 'New submission'
redirect_to admin_conference_program_events_path(@conference.short_title), notice: 'Event was successfully submitted.'
else
flash[:error] = "Could not create event: #{@event.errors.full_messages.join(', ')}"
render action: 'new'
end
end
def new
@url = admin_conference_program_events_path(@conference.short_title, @event)
@languages = @program.languages_list
@users = User.all.order(:name)
end
def accept def accept
send_mail = @event.program.conference.email_settings.send_on_accepted send_mail = @event.program.conference.email_settings.send_on_accepted
@ -168,7 +196,7 @@ module Admin
# Set also in proposals controller # Set also in proposals controller
:title, :subtitle, :event_type_id, :abstract, :description, :require_registration, :difficulty_level_id, :title, :subtitle, :event_type_id, :abstract, :description, :require_registration, :difficulty_level_id,
# Set only in admin/events controller # Set only in admin/events controller
:track_id, :state, :language, :is_highlight, :max_attendees, :track_id, :state, :language, :is_highlight, :max_attendees, :speaker_id, :submitter_id,
# Not used anymore? # Not used anymore?
:proposal_additional_speakers, :user, :users_attributes) :proposal_additional_speakers, :user, :users_attributes)
end end

View file

@ -1,4 +1,8 @@
class Event < ActiveRecord::Base class Event < ActiveRecord::Base
attr_accessor :submitter_id
attr_accessor :speaker_id
attr_accessor :validate_owners
include ActiveRecord::Transitions include ActiveRecord::Transitions
has_paper_trail on: [:create, :update], ignore: [:updated_at, :guid, :week], meta: { conference_id: :conference_id } has_paper_trail on: [:create, :update], ignore: [:updated_at, :guid, :week], meta: { conference_id: :conference_id }
@ -37,6 +41,8 @@ class Event < ActiveRecord::Base
validate :max_attendees_no_more_than_room_size validate :max_attendees_no_more_than_room_size
validate :submitter_and_speaker_present
scope :confirmed, -> { where(state: 'confirmed') } scope :confirmed, -> { where(state: 'confirmed') }
scope :canceled, -> { where(state: 'canceled') } scope :canceled, -> { where(state: 'canceled') }
scope :withdrawn, -> { where(state: 'withdrawn') } scope :withdrawn, -> { where(state: 'withdrawn') }
@ -294,4 +300,18 @@ class Event < ActiveRecord::Base
def conference_id def conference_id
program.conference_id program.conference_id
end end
def submitter_and_speaker_present
if validate_owners
errors.add(:speaker_id, "can't be blank!") unless self.speaker_id.present?
if self.speaker_id.present?
errors.add(:speaker_id, "user should exist!") unless User.where(id: self.speaker_id).take
end
errors.add(:submitter_id, "can't be blank!") unless self.submitter_id.present?
if self.submitter_id.present?
errors.add(:submitter_id, "user should exist!") unless User.where(id: self.submitter_id).take
end
end
end
end end

View file

@ -0,0 +1,77 @@
.row
.col-md-12
.page-header
%h1
New Event
.row
.col-md-12
= semantic_form_for(@event, url: @url) do |f|
= f.inputs name: 'Event Information' do
= f.input :title, as: :string, required: true
= f.input :subtitle, as: :string
= f.input :submitter_id, as: :select,
collection: @users.map {|user| ["#{user.name}", user.id,]},
include_blank: '(Please select)', label: 'Submitter', input_html: { class: 'select-help-toggle' }
= f.input :speaker_id, as: :select,
collection: @users.map {|user| ["#{user.name}", user.id,]},
include_blank: '(Please select)', label: 'Speaker', input_html: { class: 'select-help-toggle' }
- if @program.tracks.any?
= f.input :track_id, as: :select,
collection: @program.tracks.map {|track| ["#{track.name}", track.id] },
include_blank: true
= 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 }]},
include_blank: false, label: 'Type', input_html: { class: 'select-help-toggle' }
- if @program.languages.present?
= f.input :language, as: :select,
collection: @languages,
include_blank: false, label: 'Language', input_html: { class: 'select-help-toggle' }
- @conference.program.event_types.each do |event_type|
%span{ class: 'help-block select-help-text event_event_type_id collapse', id: "#{event_type.id}-help" }
= event_type.description
= f.input :difficulty_level, as: :select, collection: @conference.program.difficulty_levels, input_html: { class: 'select-help-toggle' },
include_blank: '(Please select)' if @conference.program.difficulty_levels.any?
- @conference.program.difficulty_levels.each do |difficulty_level|
%span{ class: 'help-block select-help-text collapse event_difficulty_level_id', id: "#{difficulty_level.id}-help" }
= difficulty_level.description
= f.input :abstract, required: true, input_html: { rows: 5, data: { provide: 'markdown-editable' } },
hint: markdown_hint(link_to('Tips to improve your presentations.', 'http://blog.hubspot.com/blog/tabid/6307/bid/5975/10-Rules-to-Instantly-Improve-Your-Presentations.aspx'))
%p
You have used
%span#abstract-count #{@event.abstract_word_count}
words. Abstracts must be between
%span#abstract-minimum-word-count
0
and
%span#abstract-maximum-word-count
250
words.
= f.inputs 'Enable pre-registration' do
= f.input :require_registration, label: 'Require participants to register to your event'
- message = @event.room ? "Value must be between 1 and #{@event.room.size}" : 'Check room capacity after scheduling.'
= f.input :max_attendees, hint: 'The maximum number of participants. ' + message
= f.input :is_highlight
%p.text-right
= link_to '#description', 'data-toggle' => 'collapse' do
Do you require something special?
.collapse#description
= f.input :description, input_html: { rows: 5 }, label: 'Requirements', placeholder: 'Eg. Whiteboard, printer, or something like that.'
%p.text-right
= f.submit 'Create Event', class: 'btn btn-success'

View file

@ -4,7 +4,10 @@
%h1 %h1
Events Events
= "(#{@events.length})" if @events.any? = "(#{@events.length})" if @events.any?
.btn-group.pull-right
.pull-right
- if can? :create, Event
=link_to 'Add Event', new_admin_conference_program_event_path(@conference.short_title), :class => 'button btn btn-default btn-info'
- if can? :read, Event - if can? :read, Event
.btn-group .btn-group
%button.btn.btn-default.dropdown-toggle{"data-toggle" => "dropdown", :type => "button", :class => 'btn btn-success'} %button.btn.btn-default.dropdown-toggle{"data-toggle" => "dropdown", :type => "button", :class => 'btn btn-success'}

View file

@ -0,0 +1,88 @@
require 'spec_helper'
describe Admin::EventsController do
let!(:admin) { create(:admin) }
let(:conference) { create(:conference) }
let(:event_type) { create :event_type }
let(:event) { create(:event, program: conference.program) }
context 'admin is signed in' do
before { sign_in admin }
describe 'GET #index' do
before { get :index, conference_id: conference.short_title }
it 'renders index template' do
expect(response).to render_template('index')
end
end
describe 'GET #edit' do
before { get :edit, conference_id: conference.short_title, id: event.id }
it 'renders edit template' do
expect(response).to render_template('edit')
end
it 'assigns event variable' do
expect(assigns(:event)).to be_instance_of(Event)
end
end
describe 'GET #new' do
before { get :new, conference_id: conference.short_title }
it 'renders new template' do
expect(response).to render_template('new')
end
it 'assigns event variable' do
expect(assigns(:event)).to be_instance_of(Event)
end
end
describe 'POST #create' do
context 'saves successfuly' do
before do
post :create, event: attributes_for(:event, event_type_id: event_type.id).merge!(submitter_id: admin.id, speaker_id: admin.id), conference_id: conference.short_title
end
it 'redirects to admin events index path' do
expect(response).to redirect_to admin_conference_program_events_path(conference_id: conference.short_title)
end
it 'shows success message in flash notice' do
expect(flash[:notice]).to match('Event was successfully submitted.')
end
it 'creates new event' do
expect(Event.find(event.id)).to be_instance_of(Event)
end
end
context 'save fails' do
before do
allow_any_instance_of(Event).to receive(:save).and_return(false)
post :create, event: attributes_for(:event), conference_id: conference.short_title
end
it 'renders new template' do
expect(response).to render_template('new')
end
it 'shows error in flash message' do
expect(flash[:error]).to match("Could not create event: #{event.errors.full_messages.join(', ')}")
end
it 'does not create new event' do
allow_any_instance_of(Event).to receive(:save).and_return(false)
expect do
post :create, event: attributes_for(:event, event_type_id: event_type.id),
conference_id: conference.short_title,
user: attributes_for(:user)
end.not_to change{ Event.count }
end
end
end
end
end

View file

@ -96,6 +96,43 @@ describe Event do
end end
end end
end end
describe 'submitter_and_speaker_present' do
context 'is invalid with owner validation enabled' do
before :each do
@new_event = build(:event, program: conference.program)
@new_event.validate_owners = true
end
it 'when submitter id is blank' do
expect(@new_event).to be_invalid
expect(@new_event.errors[:submitter_id]).to eq ["can't be blank!"]
end
it 'when speaker id is blank' do
expect(@new_event).to be_invalid
expect(@new_event.errors[:speaker_id]).to eq ["can't be blank!"]
end
it 'when submitter is is provided but the user does not exist' do
@new_event.submitter_id = 'deadbeef'
expect(@new_event).to be_invalid
expect(@new_event.errors[:submitter_id]).to eq ["user should exist!"]
end
it 'when speaker id is provided but the user does not exist' do
@new_event.speaker_id = 'deadbeef'
expect(@new_event).to be_invalid
expect(@new_event.errors[:speaker_id]).to eq ["user should exist!"]
end
end
context 'is valid with owner validation enabled' do
it 'when submitter and speaker ids are not blank and users with these ids exist' do
new_event = build(:event, program: conference.program)
new_user = create(:user)
new_event.submitter_id = new_user.id
new_event.speaker_id = new_user.id
new_event.validate_owners = true
expect(new_event).to be_valid
end
end
end
end end
describe 'scope ' do describe 'scope ' do

View file

@ -38,4 +38,19 @@ describe 'admin/events/index' do
expect(rendered).to have_selector('table tr:nth-of-type(2) td:nth-of-type(2)', text: 'event2') expect(rendered).to have_selector('table tr:nth-of-type(2) td:nth-of-type(2)', text: 'event2')
expect(rendered).to have_selector('table tr:nth-of-type(2) td:nth-of-type(5)', text: 'German') expect(rendered).to have_selector('table tr:nth-of-type(2) td:nth-of-type(5)', text: 'German')
end end
it 'has the Add Event link with a new event path' do
assign(:conference, conference)
assign(:program, conference.program)
program.languages = 'en,de'
assign(:events, [ event1, event2 ])
assign(:event_types, [ create(:event_type, program: conference.program), create(:event_type, program: conference.program) ])
assign(:tracks, [ create(:track, program: conference.program), create(:track, program: conference.program) ])
assign(:difficulty_levels, [ create(:difficulty_level, program: conference.program), create(:difficulty_level, program: conference.program) ])
render
expect(rendered).to have_link('Add Event', href: new_admin_conference_program_event_path(conference.short_title))
end
end end

View file

@ -0,0 +1,15 @@
require 'spec_helper'
describe 'admin/conferences/events/new' do
it 'renders the new event template' do
@conference = create(:conference)
@user = create(:user)
@program = @conference.program
@event = build(:event, program: @conference.program)
@event_type = create(:event_type, program: @program)
@url = admin_conference_program_events_path(@conference.short_title, @event)
@users = User.all
render template: 'admin/events/_form.html.haml'
expect(rendered).to include('New Event')
end
end