mirror of
https://github.com/openSUSE/osem.git
synced 2026-08-13 19:54:02 +00:00
Implement track request acceptance
Allow track submitter to request specific dates Redirect to Tracks#edit if a track doesn't have a room or start/end date before accepting it Don't allow the submitter or the track organizers to edit the request after it has been accepted or confirmed Restrict track selection in proposals and move track selection from Proposals form to events helper Mark cfp_active of the tracks table as not null and fill in true if nil
This commit is contained in:
parent
2f9eb04219
commit
d9faffc96a
27 changed files with 909 additions and 62 deletions
|
|
@ -181,6 +181,7 @@ linters:
|
|||
- "app/views/tracks/index.html.haml"
|
||||
- "app/views/tracks/show.html.haml"
|
||||
- "app/views/conferences/_call_for_tracks.html.haml"
|
||||
- "app/views/admin/tracks/_change_state_dropdown.html.haml"
|
||||
|
||||
# Offense count: 223
|
||||
InstanceVariables:
|
||||
|
|
@ -245,6 +246,7 @@ linters:
|
|||
- "app/views/tracks/_form.html.haml"
|
||||
- "app/views/admin/cfps/_tracks_cfp.html.haml"
|
||||
- "app/views/conferences/_call_for_tracks.html.haml"
|
||||
- "app/views/admin/tracks/_change_state_dropdown.html.haml"
|
||||
|
||||
# Offense count: 32
|
||||
IdNames:
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ module Admin
|
|||
def create
|
||||
@track = @program.tracks.new(track_params)
|
||||
@track.state = 'confirmed'
|
||||
@track.cfp_active = true
|
||||
if @track.save
|
||||
redirect_to admin_conference_program_tracks_path(conference_id: @conference.short_title),
|
||||
notice: 'Track successfully created.'
|
||||
|
|
@ -60,10 +61,55 @@ module Admin
|
|||
end
|
||||
end
|
||||
|
||||
def restart
|
||||
update_state(:restart, "Review for #{@track.name} started!")
|
||||
end
|
||||
|
||||
def to_accept
|
||||
update_state(:to_accept, "Track #{@track.name} marked as a possible acceptance!")
|
||||
end
|
||||
|
||||
def accept
|
||||
if @track.room && @track.start_date && @track.end_date
|
||||
update_state(:accept, "Track #{@track.name} accepted!")
|
||||
else
|
||||
flash[:alert] = 'Please make sure that the track has a room and start/end dates before accepting it'
|
||||
redirect_to edit_admin_conference_program_track_path(@conference.short_title, @track)
|
||||
end
|
||||
end
|
||||
|
||||
def confirm
|
||||
update_state(:confirm, "Track #{@track.name} confirmed!")
|
||||
end
|
||||
|
||||
def to_reject
|
||||
update_state(:to_reject, "Track #{@track.name} marked as a possible rejection!")
|
||||
end
|
||||
|
||||
def reject
|
||||
update_state(:reject, "Track #{@track.name} rejected!")
|
||||
end
|
||||
|
||||
def cancel
|
||||
update_state(:cancel, "Track #{@track.name} canceled!")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def track_params
|
||||
params.require(:track).permit(:name, :description, :color, :short_name, :cfp_active, :start_date, :end_date, :room_id)
|
||||
end
|
||||
|
||||
def update_state(transition, notice)
|
||||
errors = @track.update_state(transition)
|
||||
|
||||
if errors.blank?
|
||||
flash[:notice] = notice
|
||||
else
|
||||
flash[:error] = errors
|
||||
end
|
||||
|
||||
redirect_back_or_to(admin_conference_program_tracks_path(conference_id: @conference.short_title))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ class TracksController < ApplicationController
|
|||
load_and_authorize_resource through: :program, find_by: :short_name
|
||||
|
||||
def index
|
||||
@tracks = current_user.tracks.where(program: @program)
|
||||
@tracks = @tracks.where(submitter: current_user)
|
||||
end
|
||||
|
||||
def show; end
|
||||
|
|
@ -38,9 +38,33 @@ class TracksController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def restart
|
||||
update_state(:restart, "Track #{@track.name} re-submitted.")
|
||||
end
|
||||
|
||||
def confirm
|
||||
update_state(:confirm, "Track #{@track.name} confirmed.")
|
||||
end
|
||||
|
||||
def withdraw
|
||||
update_state(:withdraw, "Track #{@track.name} withdrawn.")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def track_params
|
||||
params.require(:track).permit(:name, :description, :color, :short_name)
|
||||
params.require(:track).permit(:name, :description, :color, :short_name, :start_date, :end_date)
|
||||
end
|
||||
|
||||
def update_state(transition, notice)
|
||||
errors = @track.update_state(transition)
|
||||
|
||||
if errors.blank?
|
||||
flash[:notice] = notice
|
||||
else
|
||||
flash[:error] = errors
|
||||
end
|
||||
|
||||
redirect_back_or_to(conference_program_tracks_path(conference_id: @conference.short_title))
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ module ApplicationHelper
|
|||
end
|
||||
|
||||
def tracks(conference)
|
||||
all = conference.program.tracks.map { |t| t.name if !t.self_organized? || t.confirmed? && t.cfp_active }.compact
|
||||
all = conference.program.tracks.where(state: 'confirmed', cfp_active: true).pluck(:name)
|
||||
first = all[0...-1]
|
||||
last = all[-1]
|
||||
ts = ''
|
||||
|
|
|
|||
|
|
@ -39,4 +39,12 @@ module EventsHelper
|
|||
content_tag :span, 'REPLACEMENT', class: (['label', 'label-info'] + label_classes)
|
||||
end
|
||||
end
|
||||
|
||||
def track_selector_input(form)
|
||||
if @program.tracks.any?
|
||||
form.input :track_id, as: :select,
|
||||
collection: @program.tracks.where(state: 'confirmed', cfp_active: true).pluck(:name, :id),
|
||||
include_blank: true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -100,8 +100,10 @@ class Ability
|
|||
track.new_record? && track.program.cfps.for_tracks.try(:open?)
|
||||
end
|
||||
|
||||
can [:index, :show, :edit, :update], Track do |track|
|
||||
user == track.submitter
|
||||
can [:index, :show, :restart, :confirm, :withdraw], Track, submitter_id: user.id
|
||||
|
||||
can [:edit, :update], Track do |track|
|
||||
user == track.submitter && !(track.accepted? || track.confirmed?)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -275,6 +275,10 @@ class AdminAbility
|
|||
|
||||
can :manage, Track, id: track_ids_for_track_organizer
|
||||
|
||||
cannot [:edit, :update], Track do |track|
|
||||
track.self_organized_and_accepted_or_confirmed?
|
||||
end
|
||||
|
||||
# Show Roles in the admin sidebar and allow authorization of the index action
|
||||
can [:index, :show], Role do |role|
|
||||
role.resource_type == 'Conference' || role.resource_type == 'Track'
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ class Event < ActiveRecord::Base
|
|||
validates :max_attendees, numericality: { only_integer: true, greater_than_or_equal_to: 1, allow_nil: true }
|
||||
|
||||
validate :max_attendees_no_more_than_room_size
|
||||
validate :acceptable_track
|
||||
|
||||
scope :confirmed, -> { where(state: 'confirmed') }
|
||||
scope :canceled, -> { where(state: 'canceled') }
|
||||
|
|
@ -303,4 +304,11 @@ class Event < ActiveRecord::Base
|
|||
def conference_id
|
||||
program.conference_id
|
||||
end
|
||||
|
||||
##
|
||||
# Allow only confirmed tracks that belong to the same program and are included in the cfp
|
||||
def acceptable_track
|
||||
return unless track && track.program && program
|
||||
errors.add(:track, 'is invalid') unless track.confirmed? && track.cfp_active && track.program == program
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,13 +22,13 @@ class Track < ActiveRecord::Base
|
|||
}
|
||||
validates :state,
|
||||
presence: true,
|
||||
inclusion: { in: %w(new to_accept accepted confirmed to_reject rejected canceled withdrawn) },
|
||||
if: :self_organized?
|
||||
validates :cfp_active, inclusion: { in: [true, false] }, if: :self_organized?
|
||||
inclusion: { in: %w(new to_accept accepted confirmed to_reject rejected canceled withdrawn) }
|
||||
validates :cfp_active, inclusion: { in: [true, false] }
|
||||
validates :start_date, presence: true, if: :self_organized_and_accepted_or_confirmed?
|
||||
validates :end_date, presence: true, if: :self_organized_and_accepted_or_confirmed?
|
||||
validates :room, presence: true, if: :self_organized_and_accepted_or_confirmed?
|
||||
validate :valid_dates, if: :self_organized_and_accepted_or_confirmed?
|
||||
validate :valid_dates
|
||||
validate :valid_room, if: :self_organized_and_accepted_or_confirmed?
|
||||
|
||||
before_validation :capitalize_color
|
||||
|
||||
|
|
@ -45,7 +45,7 @@ class Track < ActiveRecord::Base
|
|||
event :restart do
|
||||
transitions to: :new, from: [:rejected, :withdrawn, :canceled]
|
||||
end
|
||||
event :readiness_to_accept do
|
||||
event :to_accept do
|
||||
transitions to: :to_accept, from: [:new]
|
||||
end
|
||||
event :accept do
|
||||
|
|
@ -54,7 +54,7 @@ class Track < ActiveRecord::Base
|
|||
event :confirm do
|
||||
transitions to: :confirmed, from: [:accepted], on_transition: :assign_role_to_submitter
|
||||
end
|
||||
event :readiness_to_reject do
|
||||
event :to_reject do
|
||||
transitions to: :to_reject, from: [:new]
|
||||
end
|
||||
event :reject do
|
||||
|
|
@ -107,6 +107,7 @@ class Track < ActiveRecord::Base
|
|||
|
||||
events.each do |event|
|
||||
event.track = nil
|
||||
event.save!
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -137,6 +138,19 @@ class Track < ActiveRecord::Base
|
|||
self_organized? && (accepted? || confirmed?)
|
||||
end
|
||||
|
||||
def update_state(transition)
|
||||
error = ''
|
||||
|
||||
begin
|
||||
send(transition)
|
||||
rescue Transitions::InvalidTransition => e
|
||||
error += "State update failed. #{e.message} "
|
||||
end
|
||||
|
||||
error += errors.full_messages.join(', ') unless save
|
||||
error
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def generate_guid
|
||||
|
|
@ -162,26 +176,32 @@ class Track < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def valid_dates
|
||||
return unless start_date && end_date
|
||||
|
||||
if program && program.conference && program.conference.start_date && (start_date < program.conference.start_date)
|
||||
errors.add(:start_date, "can't be before the conference start date (#{program.conference.end_date})")
|
||||
if start_date && program && program.conference && program.conference.start_date && (start_date < program.conference.start_date)
|
||||
errors.add(:start_date, "can't be before the conference start date (#{program.conference.start_date})")
|
||||
end
|
||||
|
||||
if program && program.conference && program.conference.start_date && (end_date < program.conference.start_date)
|
||||
errors.add(:end_date, "can't be before the conference start date (#{program.conference.end_date})")
|
||||
if end_date && program && program.conference && program.conference.start_date && (end_date < program.conference.start_date)
|
||||
errors.add(:end_date, "can't be before the conference start date (#{program.conference.start_date})")
|
||||
end
|
||||
|
||||
if program && program.conference && program.conference.end_date && (start_date > program.conference.end_date)
|
||||
if start_date && program && program.conference && program.conference.end_date && (start_date > program.conference.end_date)
|
||||
errors.add(:start_date, "can't be after the conference end date (#{program.conference.end_date})")
|
||||
end
|
||||
|
||||
if program && program.conference && program.conference.end_date && (end_date > program.conference.end_date)
|
||||
if end_date && program && program.conference && program.conference.end_date && (end_date > program.conference.end_date)
|
||||
errors.add(:end_date, "can't be after the conference end date (#{program.conference.end_date})")
|
||||
end
|
||||
|
||||
if start_date > end_date
|
||||
errors.add(:start_date, 'can\'t be after the end_date')
|
||||
if start_date && end_date && (start_date > end_date)
|
||||
errors.add(:start_date, 'can\'t be after the end date')
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Verify that the room is a room of the conference
|
||||
def valid_room
|
||||
if room && room.venue && room.venue.conference && program && program.conference && (program.conference != room.venue.conference)
|
||||
errors.add(:room, "must be a room of #{program.conference.venue.name}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
34
app/views/admin/tracks/_change_state_dropdown.html.haml
Normal file
34
app/views/admin/tracks/_change_state_dropdown.html.haml
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
- if track.transition_possible? :restart
|
||||
%li= link_to 'Start review',
|
||||
restart_admin_conference_program_track_path(@conference.short_title, track),
|
||||
method: :patch, id: "restart_track_#{track.id}"
|
||||
|
||||
- if track.transition_possible? :to_accept
|
||||
%li= link_to 'Mark as possible acceptance',
|
||||
to_accept_admin_conference_program_track_path(@conference.short_title, track),
|
||||
method: :patch, id: "to_accept_track_#{track.id}"
|
||||
|
||||
- if track.transition_possible? :accept
|
||||
%li= link_to 'Accept track request',
|
||||
accept_admin_conference_program_track_path(@conference.short_title, track),
|
||||
method: :patch, id: "accept_track_#{track.id}"
|
||||
|
||||
- if track.transition_possible? :confirm
|
||||
%li= link_to 'Confirm track',
|
||||
confirm_admin_conference_program_track_path(@conference.short_title, track),
|
||||
method: :patch, id: "confirm_track_#{track.id}"
|
||||
|
||||
- if track.transition_possible? :to_reject
|
||||
%li= link_to 'Mark as possible rejection',
|
||||
to_reject_admin_conference_program_track_path(@conference.short_title, track),
|
||||
method: :patch, id: "to_reject_track_#{track.id}"
|
||||
|
||||
- if track.transition_possible? :reject
|
||||
%li= link_to 'Reject track request',
|
||||
reject_admin_conference_program_track_path(@conference.short_title, track),
|
||||
method: :patch, confirm: 'Are you sure?', id: "reject_track_#{track.id}"
|
||||
|
||||
- if track.transition_possible? :cancel
|
||||
%li= link_to 'Cancel track request',
|
||||
cancel_admin_conference_program_track_path(@conference.short_title, track),
|
||||
method: :patch, id: "cancel_track_#{track.id}"
|
||||
|
|
@ -19,6 +19,5 @@
|
|||
- else
|
||||
Please add a venue with rooms, if you want to select a room for the track.
|
||||
= f.input :description, input_html: {rows: 2, data: { provide: 'markdown-editable' } }, hint: markdown_hint
|
||||
- if @track.self_organized?
|
||||
= f.input :cfp_active, label: 'Allow event submitters to select this track for their proposal'
|
||||
= f.input :cfp_active, label: 'Allow event submitters to select this track for their proposal'
|
||||
= f.action :submit, as: :button, button_html: { class: 'btn btn-primary' }
|
||||
|
|
|
|||
|
|
@ -40,21 +40,24 @@
|
|||
= track.color
|
||||
%td
|
||||
- if track.self_organized?
|
||||
= track.state
|
||||
.btn-group
|
||||
%button{ type: 'button', class: 'btn btn-link dropdown-toggle', 'data-toggle' => 'dropdown' }
|
||||
= track.state.humanize
|
||||
%span.caret
|
||||
%ul.dropdown-menu{ role: 'menu' }
|
||||
= render 'change_state_dropdown', track: track
|
||||
- else
|
||||
= track.state.humanize
|
||||
%td
|
||||
- if track.self_organized?
|
||||
= check_box_tag "#{@conference.short_title}_#{track.short_name}", track.id, track.cfp_active,
|
||||
class: 'switch-checkbox', method: :patch,
|
||||
url: toggle_cfp_inclusion_admin_conference_program_track_path(@conference.short_title, id: track.short_name)+"?included=",
|
||||
data: { size: 'small',
|
||||
on_color: 'success',
|
||||
off_color: 'warning',
|
||||
on_text: 'Yes',
|
||||
off_text: 'No' }
|
||||
- else
|
||||
%i.fa.fa-check
|
||||
= check_box_tag "#{@conference.short_title}_#{track.short_name}", track.id, track.cfp_active,
|
||||
class: 'switch-checkbox', method: :patch,
|
||||
url: toggle_cfp_inclusion_admin_conference_program_track_path(@conference.short_title, id: track.short_name)+"?included=",
|
||||
data: { size: 'small',
|
||||
on_color: 'success',
|
||||
off_color: 'warning',
|
||||
on_text: 'Yes',
|
||||
off_text: 'No' }
|
||||
|
||||
%td
|
||||
- if track.room
|
||||
= link_to track.room.name, admin_conference_venue_room_path(@conference.short_title, track.room.id)
|
||||
|
|
@ -72,8 +75,9 @@
|
|||
N/A
|
||||
%td
|
||||
.btn-group{role: "group"}
|
||||
= link_to 'Edit', edit_admin_conference_program_track_path(@conference.short_title, track),
|
||||
method: :get, class: 'btn btn-primary'
|
||||
- if can? :edit, track
|
||||
= link_to 'Edit', edit_admin_conference_program_track_path(@conference.short_title, track),
|
||||
method: :get, class: 'btn btn-primary'
|
||||
- if can? :destroy, track
|
||||
= link_to 'Delete', admin_conference_program_track_path(@conference.short_title, track),
|
||||
method: :delete, class: 'btn btn-danger',
|
||||
|
|
|
|||
|
|
@ -6,10 +6,7 @@
|
|||
|
||||
= speaker_selector_input f
|
||||
|
||||
- if @program.tracks.any?
|
||||
= f.input :track_id, as: :select,
|
||||
collection: @program.tracks.map {|track| ["#{track.name}", track.id] },
|
||||
include_blank: true
|
||||
= track_selector_input f
|
||||
|
||||
= f.input :event_type_id, as: :select,
|
||||
collection: @conference.program.event_types.map {|type| ["#{type.title} - #{show_time(type.length)}", type.id,
|
||||
|
|
|
|||
|
|
@ -9,9 +9,11 @@
|
|||
Track
|
||||
.row
|
||||
.col-md-12
|
||||
= semantic_form_for(@track, url: (@track.new_record? ? conference_program_tracks_path : conference_program_track_path(@conference.short_title, @track))) do |f|
|
||||
= semantic_form_for(@track, url: (@track.new_record? ? conference_program_tracks_path(@conference.short_title) : conference_program_track_path(@conference.short_title, @track))) do |f|
|
||||
= f.input :name
|
||||
= f.input :short_name, hint: "A short and unique handle for the track, using only letters, numbers, underscores, and dashes. This will be used to identify the track in URLs etc. Example: 'my_awesome_track'", input_html: { required: 'required', pattern: '[a-zA-Z0-9_-]+', title: 'Only letters, numbers, underscores, and dashes.' }
|
||||
= f.input :color, input_html: {size: 6, type: 'color'}, required: true
|
||||
= f.input :start_date, as: :string, input_html: { id: 'registration-period-start-datepicker', start_date: @conference.start_date, end_date: @conference.end_date, readonly: 'readonly' }
|
||||
= f.input :end_date, as: :string, input_html: { id: 'registration-period-end-datepicker', readonly: 'readonly' }
|
||||
= f.input :description, input_html: {rows: 2, data: { provide: 'markdown-editable' } }, required: true, hint: markdown_hint
|
||||
= f.action :submit, as: :button, button_html: { class: 'btn btn-primary' }
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
%th Description
|
||||
%th Color
|
||||
%th State
|
||||
%th Start Date
|
||||
%th End Date
|
||||
%th Actions
|
||||
%tbody
|
||||
- @tracks.each do |track|
|
||||
|
|
@ -34,10 +36,31 @@
|
|||
%td
|
||||
= track.state.humanize
|
||||
%td
|
||||
= link_to 'Edit', edit_conference_program_track_path(@conference.short_title, track),
|
||||
method: :get, class: 'btn btn-primary'
|
||||
- if track.start_date
|
||||
= track.start_date.strftime('%A, %B %-d. %Y')
|
||||
- else
|
||||
N/A
|
||||
%td
|
||||
- if track.end_date
|
||||
= track.end_date.strftime('%A, %B %-d. %Y')
|
||||
- else
|
||||
N/A
|
||||
%td
|
||||
- if track.transition_possible? :confirm
|
||||
= link_to 'Confirm', confirm_conference_program_track_path(@conference.short_title, track),
|
||||
method: :patch, class: 'btn btn-mini btn-success', id: "confirm_track_#{track.id}"
|
||||
- if track.transition_possible? :withdraw
|
||||
= link_to 'Withdraw', withdraw_conference_program_track_path(@conference.short_title, track),
|
||||
method: :patch, data: { confirm: 'Are you sure you want to withdraw this track request?' },
|
||||
class: 'btn btn-mini btn-warning', id: "withdraw_track_request_#{track.id}"
|
||||
- if track.transition_possible? :restart
|
||||
= link_to 'Re-Submit', restart_conference_program_track_path(@conference.short_title, track),
|
||||
method: :patch, class: 'btn btn-mini btn-success', id: "resubmit_track_request_#{track.id}"
|
||||
- if can? :edit, track
|
||||
= link_to 'Edit', edit_conference_program_track_path(@conference.short_title, track),
|
||||
method: :get, class: 'btn btn-primary'
|
||||
|
||||
.row
|
||||
.col-md-12
|
||||
- if can? :create, @track
|
||||
- if can? :new, @program.tracks.new
|
||||
= link_to "New Track request", new_conference_program_track_path(@conference.short_title), class: 'btn btn-success pull-right'
|
||||
|
|
|
|||
|
|
@ -17,10 +17,25 @@
|
|||
State:
|
||||
%dd
|
||||
= @track.state.humanize
|
||||
%dt
|
||||
Start date:
|
||||
%dd
|
||||
- if @track.start_date
|
||||
= @track.start_date.strftime('%A, %B %-d. %Y')
|
||||
- else
|
||||
N/A
|
||||
%dt
|
||||
End date:
|
||||
%dd
|
||||
- if @track.end_date
|
||||
= @track.end_date.strftime('%A, %B %-d. %Y')
|
||||
- else
|
||||
N/A
|
||||
%dt
|
||||
Description
|
||||
%dd
|
||||
= @track.description
|
||||
.row
|
||||
.col-md-12.text-right
|
||||
= link_to 'Edit Track request', edit_conference_program_track_path(@conference.short_title, @track), class: 'btn btn-primary'
|
||||
- if can? :edit, @track
|
||||
= link_to 'Edit Track request', edit_conference_program_track_path(@conference.short_title, @track), class: 'btn btn-primary'
|
||||
|
|
|
|||
|
|
@ -69,6 +69,13 @@ Osem::Application.routes.draw do
|
|||
resources :tracks do
|
||||
member do
|
||||
patch :toggle_cfp_inclusion
|
||||
patch :restart
|
||||
patch :to_accept
|
||||
patch :accept
|
||||
patch :confirm
|
||||
patch :to_reject
|
||||
patch :reject
|
||||
patch :cancel
|
||||
end
|
||||
end
|
||||
resources :event_types
|
||||
|
|
@ -149,7 +156,13 @@ Osem::Application.routes.draw do
|
|||
patch '/restart' => 'proposals#restart'
|
||||
end
|
||||
end
|
||||
resources :tracks, except: :destroy
|
||||
resources :tracks, except: :destroy do
|
||||
member do
|
||||
patch :restart
|
||||
patch :confirm
|
||||
patch :withdraw
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: change conference_registrations to singular resource
|
||||
|
|
|
|||
14
db/migrate/20170720134353_make_track_cfp_active_not_null.rb
Normal file
14
db/migrate/20170720134353_make_track_cfp_active_not_null.rb
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
class MakeTrackCfpActiveNotNull < ActiveRecord::Migration
|
||||
class TmpTrack < ActiveRecord::Base
|
||||
self.table_name = 'tracks'
|
||||
end
|
||||
|
||||
def change
|
||||
TmpTrack.where(cfp_active: nil).each do |track|
|
||||
track.cfp_active = true
|
||||
track.save!
|
||||
end
|
||||
|
||||
change_column_null :tracks, :cfp_active, false
|
||||
end
|
||||
end
|
||||
|
|
@ -520,7 +520,7 @@ ActiveRecord::Schema.define(version: 20170807092805) do
|
|||
t.integer "program_id"
|
||||
t.string "short_name", null: false
|
||||
t.string "state", default: "new", null: false
|
||||
t.boolean "cfp_active"
|
||||
t.boolean "cfp_active", null: false
|
||||
t.integer "submitter_id"
|
||||
t.integer "room_id"
|
||||
t.date "start_date"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ describe Admin::TracksController do
|
|||
|
||||
let(:conference) { create(:conference) }
|
||||
let!(:track) { create(:track, program: conference.program, color: '#800080') }
|
||||
let!(:self_organized_track) { create(:track, :self_organized, program: conference.program) }
|
||||
let!(:self_organized_track) { create(:track, :self_organized, program: conference.program, name: 'My awesome track') }
|
||||
|
||||
before :each do
|
||||
sign_in(admin)
|
||||
|
|
@ -83,6 +83,7 @@ describe Admin::TracksController do
|
|||
|
||||
it 'the new tracks has the correct attributes' do
|
||||
expect(assigns(:track).state).to eq 'confirmed'
|
||||
expect(assigns(:track).cfp_active).to eq true
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -257,4 +258,204 @@ describe Admin::TracksController do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PATCH #restart' do
|
||||
before :each do
|
||||
self_organized_track.state = 'canceled'
|
||||
self_organized_track.save!
|
||||
patch :restart, conference_id: conference.short_title, id: self_organized_track.short_name
|
||||
self_organized_track.reload
|
||||
end
|
||||
|
||||
it 'assigns the correct track' do
|
||||
expect(assigns(:track)).to eq self_organized_track
|
||||
end
|
||||
|
||||
it 'shows message in flash notice' do
|
||||
expect(flash[:notice]).to eq 'Review for My awesome track started!'
|
||||
end
|
||||
|
||||
it 'changes the track\'s state to new' do
|
||||
expect(self_organized_track.state).to eq 'new'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PATCH #to_accept' do
|
||||
before :each do
|
||||
patch :to_accept, conference_id: conference.short_title, id: self_organized_track.short_name
|
||||
self_organized_track.reload
|
||||
end
|
||||
|
||||
it 'assigns the correct track' do
|
||||
expect(assigns(:track)).to eq self_organized_track
|
||||
end
|
||||
|
||||
it 'shows message in flash notice' do
|
||||
expect(flash[:notice]).to eq 'Track My awesome track marked as a possible acceptance!'
|
||||
end
|
||||
|
||||
it 'changes the track\'s state to to_accept' do
|
||||
expect(self_organized_track.state).to eq 'to_accept'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PATCH #accept' do
|
||||
shared_examples 'fails to accept' do |start_date, end_date, room|
|
||||
before :each do
|
||||
self_organized_track.start_date = start_date ? Date.today : nil
|
||||
self_organized_track.end_date = end_date ? Date.today : nil
|
||||
if room
|
||||
conference.venue = create(:venue)
|
||||
self_organized_track.room = create(:room, venue: conference.venue)
|
||||
else
|
||||
self_organized_track.room = nil
|
||||
end
|
||||
self_organized_track.save!
|
||||
|
||||
patch :accept, conference_id: conference.short_title, id: self_organized_track.short_name
|
||||
self_organized_track.reload
|
||||
end
|
||||
|
||||
it 'redirects to Tracks#edit' do
|
||||
expect(response).to redirect_to edit_admin_conference_program_track_path(conference.short_title, self_organized_track)
|
||||
end
|
||||
|
||||
it 'shows message in flash alert' do
|
||||
expect(flash[:alert]).to eq 'Please make sure that the track has a room and start/end dates before accepting it'
|
||||
end
|
||||
end
|
||||
|
||||
context 'has start_date, end_date and room' do
|
||||
before :each do
|
||||
self_organized_track.start_date = Date.today
|
||||
self_organized_track.end_date = Date.today
|
||||
conference.venue = create(:venue)
|
||||
self_organized_track.room = create(:room, venue: conference.venue)
|
||||
self_organized_track.save!
|
||||
|
||||
patch :accept, conference_id: conference.short_title, id: self_organized_track.short_name
|
||||
self_organized_track.reload
|
||||
end
|
||||
|
||||
it 'assigns the correct track' do
|
||||
expect(assigns(:track)).to eq self_organized_track
|
||||
end
|
||||
|
||||
it 'shows message in flash notice' do
|
||||
expect(flash[:notice]).to eq 'Track My awesome track accepted!'
|
||||
end
|
||||
|
||||
it 'changes the track\'s state to accepted' do
|
||||
expect(self_organized_track.state).to eq 'accepted'
|
||||
end
|
||||
end
|
||||
|
||||
context 'has start_date and end_date' do
|
||||
it_behaves_like 'fails to accept', true, true, false
|
||||
end
|
||||
|
||||
context 'has start_date and room' do
|
||||
it_behaves_like 'fails to accept', true, false, true
|
||||
end
|
||||
|
||||
context 'has start_date' do
|
||||
it_behaves_like 'fails to accept', true, false, false
|
||||
end
|
||||
|
||||
context 'has end_date and room' do
|
||||
it_behaves_like 'fails to accept', false, true, true
|
||||
end
|
||||
|
||||
context 'has end_date' do
|
||||
it_behaves_like 'fails to accept', false, true, false
|
||||
end
|
||||
|
||||
context 'has room' do
|
||||
it_behaves_like 'fails to accept', false, false, true
|
||||
end
|
||||
|
||||
context 'has non of start_date, end_date, room' do
|
||||
it_behaves_like 'fails to accept', false, false, false
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PATCH #confirm' do
|
||||
before :each do
|
||||
self_organized_track.state = 'accepted'
|
||||
self_organized_track.save!
|
||||
patch :confirm, conference_id: conference.short_title, id: self_organized_track.short_name
|
||||
self_organized_track.reload
|
||||
end
|
||||
|
||||
it 'assigns the correct track' do
|
||||
expect(assigns(:track)).to eq self_organized_track
|
||||
end
|
||||
|
||||
it 'shows message in flash notice' do
|
||||
expect(flash[:notice]).to eq 'Track My awesome track confirmed!'
|
||||
end
|
||||
|
||||
it 'changes the track\'s state to confirmed' do
|
||||
expect(self_organized_track.state).to eq 'confirmed'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PATCH #to_reject' do
|
||||
before :each do
|
||||
patch :to_reject, conference_id: conference.short_title, id: self_organized_track.short_name
|
||||
self_organized_track.reload
|
||||
end
|
||||
|
||||
it 'assigns the correct track' do
|
||||
expect(assigns(:track)).to eq self_organized_track
|
||||
end
|
||||
|
||||
it 'shows message in flash notice' do
|
||||
expect(flash[:notice]).to eq 'Track My awesome track marked as a possible rejection!'
|
||||
end
|
||||
|
||||
it 'changes the track\'s state to to_reject' do
|
||||
expect(self_organized_track.state).to eq 'to_reject'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PATCH #reject' do
|
||||
before :each do
|
||||
patch :reject, conference_id: conference.short_title, id: self_organized_track.short_name
|
||||
self_organized_track.reload
|
||||
end
|
||||
|
||||
it 'assigns the correct track' do
|
||||
expect(assigns(:track)).to eq self_organized_track
|
||||
end
|
||||
|
||||
it 'shows message in flash notice' do
|
||||
expect(flash[:notice]).to eq 'Track My awesome track rejected!'
|
||||
end
|
||||
|
||||
it 'changes the track\'s state to rejected' do
|
||||
expect(self_organized_track.state).to eq 'rejected'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PATCH #cancel' do
|
||||
before :each do
|
||||
self_organized_track.state = 'confirmed'
|
||||
self_organized_track.save!
|
||||
patch :cancel, conference_id: conference.short_title, id: self_organized_track.short_name
|
||||
self_organized_track.reload
|
||||
end
|
||||
|
||||
it 'assigns the correct track' do
|
||||
expect(assigns(:track)).to eq self_organized_track
|
||||
end
|
||||
|
||||
it 'shows message in flash notice' do
|
||||
expect(flash[:notice]).to eq 'Track My awesome track canceled!'
|
||||
end
|
||||
|
||||
it 'changes the track\'s state to canceled' do
|
||||
expect(self_organized_track.state).to eq 'canceled'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe TracksController do
|
||||
# A regular user should be used when the track requests have been enabled
|
||||
let(:user) { create(:admin) }
|
||||
|
||||
let(:conference) { create(:conference) }
|
||||
let!(:regular_track) { create(:track, program: conference.program) }
|
||||
let!(:self_organized_track) { create(:track, :self_organized, program: conference.program, submitter: user, color: '#800080') }
|
||||
let!(:self_organized_track) { create(:track, :self_organized, program: conference.program, submitter: user, name: 'My awesome track', color: '#800080') }
|
||||
|
||||
before :each do
|
||||
sign_in(user)
|
||||
|
|
@ -176,4 +175,67 @@ describe TracksController do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PATCH #restart' do
|
||||
before :each do
|
||||
self_organized_track.state = 'withdrawn'
|
||||
self_organized_track.save!
|
||||
patch :restart, conference_id: conference.short_title, id: self_organized_track.short_name
|
||||
self_organized_track.reload
|
||||
end
|
||||
|
||||
it 'assigns the correct track' do
|
||||
expect(assigns(:track)).to eq self_organized_track
|
||||
end
|
||||
|
||||
it 'shows message in flash notice' do
|
||||
expect(flash[:notice]).to eq 'Track My awesome track re-submitted.'
|
||||
end
|
||||
|
||||
it 'changes the track\'s state to new' do
|
||||
expect(self_organized_track.state).to eq 'new'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PATCH #confirm' do
|
||||
before :each do
|
||||
self_organized_track.state = 'accepted'
|
||||
self_organized_track.save!
|
||||
patch :confirm, conference_id: conference.short_title, id: self_organized_track.short_name
|
||||
self_organized_track.reload
|
||||
end
|
||||
|
||||
it 'assigns the correct track' do
|
||||
expect(assigns(:track)).to eq self_organized_track
|
||||
end
|
||||
|
||||
it 'shows message in flash notice' do
|
||||
expect(flash[:notice]).to eq 'Track My awesome track confirmed.'
|
||||
end
|
||||
|
||||
it 'changes the track\'s state to confirmed' do
|
||||
expect(self_organized_track.state).to eq 'confirmed'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PATCH #withdraw' do
|
||||
before :each do
|
||||
self_organized_track.state = 'confirmed'
|
||||
self_organized_track.save!
|
||||
patch :withdraw, conference_id: conference.short_title, id: self_organized_track.short_name
|
||||
self_organized_track.reload
|
||||
end
|
||||
|
||||
it 'assigns the correct track' do
|
||||
expect(assigns(:track)).to eq self_organized_track
|
||||
end
|
||||
|
||||
it 'shows message in flash notice' do
|
||||
expect(flash[:notice]).to eq 'Track My awesome track withdrawn.'
|
||||
end
|
||||
|
||||
it 'changes the track\'s state to withdrawn' do
|
||||
expect(self_organized_track.state).to eq 'withdrawn'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,12 +5,16 @@ FactoryGirl.define do
|
|||
color { Faker::Color.hex_color }
|
||||
short_name { SecureRandom.urlsafe_base64(5) }
|
||||
state 'confirmed'
|
||||
cfp_active true
|
||||
program
|
||||
|
||||
trait :self_organized do
|
||||
association :submitter, factory: :user
|
||||
state 'new'
|
||||
cfp_active false
|
||||
start_date { Date.today }
|
||||
end_date { Date.today }
|
||||
room
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ describe 'User' do
|
|||
|
||||
let(:program_with_cfp) { create(:program, :with_cfp) }
|
||||
let(:program_without_cfp) { create(:program) }
|
||||
let(:program_with_call_for_tracks) { create(:cfp, cfp_type: 'tracks').program }
|
||||
let(:conference_with_open_registration) { create(:conference) }
|
||||
let!(:open_registration_period) { create(:registration_period, conference: conference_with_open_registration, start_date: Date.current - 6.days) }
|
||||
let(:conference_with_closed_registration) { create(:conference) }
|
||||
|
|
@ -82,6 +83,10 @@ describe 'User' do
|
|||
|
||||
let(:user_event_with_cfp) { create(:event, users: [user], program: program_with_cfp) }
|
||||
let(:user_commercial) { create(:commercial, commercialable: user_event_with_cfp) }
|
||||
let(:user_self_organized_track) { create(:track, :self_organized, submitter: user) }
|
||||
let(:accepted_user_self_organized_track) { create(:track, :self_organized, submitter: user, state: 'accepted') }
|
||||
let(:confirmed_user_self_organized_track) { create(:track, :self_organized, submitter: user, state: 'confirmed') }
|
||||
let(:other_self_organized_track) { create(:track, :self_organized) }
|
||||
|
||||
it{ should be_able_to(:manage, user) }
|
||||
|
||||
|
|
@ -114,6 +119,31 @@ describe 'User' do
|
|||
it{ should be_able_to(:create, user_event_with_cfp.commercials.new) }
|
||||
it{ should be_able_to(:manage, user_commercial) }
|
||||
it{ should_not be_able_to(:manage, commercial_event_unconfirmed) }
|
||||
|
||||
it{ should be_able_to(:new, Track.new(program: program_with_call_for_tracks)) }
|
||||
it{ should be_able_to(:create, Track.new(program: program_with_call_for_tracks)) }
|
||||
it{ should_not be_able_to(:new, Track.new(program: program_without_cfp)) }
|
||||
it{ should_not be_able_to(:create, Track.new(program: program_without_cfp)) }
|
||||
|
||||
it{ should be_able_to(:index, user_self_organized_track) }
|
||||
it{ should be_able_to(:show, user_self_organized_track) }
|
||||
it{ should be_able_to(:restart, user_self_organized_track) }
|
||||
it{ should be_able_to(:confirm, user_self_organized_track) }
|
||||
it{ should be_able_to(:withdraw, user_self_organized_track) }
|
||||
it{ should_not be_able_to(:index, other_self_organized_track) }
|
||||
it{ should_not be_able_to(:show, other_self_organized_track) }
|
||||
it{ should_not be_able_to(:restart, other_self_organized_track) }
|
||||
it{ should_not be_able_to(:confirm, other_self_organized_track) }
|
||||
it{ should_not be_able_to(:withdraw, other_self_organized_track) }
|
||||
|
||||
it{ should be_able_to(:edit, user_self_organized_track) }
|
||||
it{ should be_able_to(:update, user_self_organized_track) }
|
||||
it{ should_not be_able_to(:edit, accepted_user_self_organized_track) }
|
||||
it{ should_not be_able_to(:update, accepted_user_self_organized_track) }
|
||||
it{ should_not be_able_to(:edit, confirmed_user_self_organized_track) }
|
||||
it{ should_not be_able_to(:update, confirmed_user_self_organized_track) }
|
||||
it{ should_not be_able_to(:edit, other_self_organized_track) }
|
||||
it{ should_not be_able_to(:update, other_self_organized_track) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ describe 'User with admin role' do
|
|||
let!(:my_event_schedule) { create(:event_schedule, schedule: my_schedule) }
|
||||
let!(:other_event_schedule) { create(:event_schedule, schedule: other_schedule) }
|
||||
|
||||
let!(:my_self_organized_track) { create(:track, :self_organized, program: my_conference.program) }
|
||||
let!(:my_self_organized_track) { create(:track, :self_organized, program: my_conference.program, state: 'confirmed') }
|
||||
|
||||
context 'user #is_admin?' do
|
||||
let(:venue) { my_conference.venue }
|
||||
|
|
@ -505,6 +505,8 @@ describe 'User with admin role' do
|
|||
it{ should be_able_to(:show, my_conference.program) }
|
||||
it{ should be_able_to(:update, new_track) }
|
||||
it{ should be_able_to(:manage, my_self_organized_track) }
|
||||
it{ should_not be_able_to(:edit, my_self_organized_track) }
|
||||
it{ should_not be_able_to(:update, my_self_organized_track) }
|
||||
|
||||
it_behaves_like 'user with any role'
|
||||
it_behaves_like 'user with non-organizer role', 'track_organizer'
|
||||
|
|
|
|||
|
|
@ -606,8 +606,8 @@ describe Conference do
|
|||
describe 'tracks_distribution' do
|
||||
before do
|
||||
subject.email_settings = create(:email_settings)
|
||||
@track_one = create(:track, name: 'Track One', color: '#000000')
|
||||
@track_two = create(:track, name: 'Track Two', color: '#ffffff')
|
||||
@track_one = create(:track, name: 'Track One', color: '#000000', program: subject.program)
|
||||
@track_two = create(:track, name: 'Track Two', color: '#ffffff', program: subject.program)
|
||||
end
|
||||
|
||||
describe '#tracks_distribution' do
|
||||
|
|
|
|||
|
|
@ -96,6 +96,40 @@ describe Event do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#acceptable_track' do
|
||||
context 'is valid' do
|
||||
it 'when the track belong to the same program, is confirmed and is included in the cfp' do
|
||||
track = create(:track, state: 'confirmed', cfp_active: true, program: conference.program)
|
||||
event = build(:event, program: conference.program, track: track)
|
||||
expect(event.valid?).to eq true
|
||||
end
|
||||
end
|
||||
|
||||
context 'is invalid' do
|
||||
it 'when the track doesn\'t have the same program' do
|
||||
track = create(:track, state: 'confirmed', cfp_active: true)
|
||||
event = build(:event, program: conference.program, track: track)
|
||||
expect(event.valid?).to eq false
|
||||
expect(event.errors[:track]).to eq ['is invalid']
|
||||
end
|
||||
|
||||
it 'when the track is unconfirmed' do
|
||||
track = create(:track, cfp_active: true, program: conference.program)
|
||||
allow(track).to receive(:confirmed?).and_return(false)
|
||||
event = build(:event, program: conference.program, track: track)
|
||||
expect(event.valid?).to eq false
|
||||
expect(event.errors[:track]).to eq ['is invalid']
|
||||
end
|
||||
|
||||
it 'when the track isn\'t included in the cfp' do
|
||||
track = create(:track, state: 'confirmed', cfp_active: false, program: conference.program)
|
||||
event = build(:event, program: conference.program, track: track)
|
||||
expect(event.valid?).to eq false
|
||||
expect(event.errors[:track]).to eq ['is invalid']
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#comments_count' do
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ describe Track do
|
|||
describe 'association' do
|
||||
it { is_expected.to belong_to(:program) }
|
||||
it { is_expected.to belong_to(:submitter).class_name('User') }
|
||||
it { is_expected.to belong_to(:room) }
|
||||
it { is_expected.to have_many(:events) }
|
||||
end
|
||||
|
||||
|
|
@ -23,23 +24,99 @@ describe Track do
|
|||
it { is_expected.to allow_value('My_track_name').for(:short_name) }
|
||||
it { is_expected.to_not allow_value('My track name').for(:short_name) }
|
||||
it { is_expected.to validate_uniqueness_of(:short_name).scoped_to(:program_id) }
|
||||
it { is_expected.to validate_presence_of(:state) }
|
||||
it { is_expected.to validate_inclusion_of(:state).in_array(%w[new to_accept accepted confirmed to_reject rejected canceled withdrawn]) }
|
||||
it { is_expected.to validate_inclusion_of(:cfp_active).in_array([true, false]) }
|
||||
|
||||
context 'when self-organized' do
|
||||
context 'when self_organized_and_accepted_or_confirmed? returns true' do
|
||||
before :each do
|
||||
allow(subject).to receive(:self_organized?).and_return(true)
|
||||
allow(subject).to receive(:self_organized_and_accepted_or_confirmed?).and_return(true)
|
||||
end
|
||||
|
||||
it { is_expected.to validate_presence_of(:state) }
|
||||
it { is_expected.to validate_inclusion_of(:cfp_active).in_array([true, false]) }
|
||||
it { is_expected.to validate_presence_of(:start_date) }
|
||||
it { is_expected.to validate_presence_of(:end_date) }
|
||||
it { is_expected.to validate_presence_of(:room) }
|
||||
end
|
||||
|
||||
context 'when regular' do
|
||||
context 'when self_organized_and_accepted_or_confirmed? returns false' do
|
||||
before :each do
|
||||
allow(subject).to receive(:self_organized?).and_return(false)
|
||||
allow(subject).to receive(:self_organized_and_accepted_or_confirmed?).and_return(false)
|
||||
end
|
||||
|
||||
it { is_expected.to_not validate_presence_of(:state) }
|
||||
it { is_expected.to_not validate_inclusion_of(:cfp_active) }
|
||||
it { is_expected.to_not validate_presence_of(:start_date) }
|
||||
it { is_expected.to_not validate_presence_of(:end_date) }
|
||||
it { is_expected.to_not validate_presence_of(:room) }
|
||||
end
|
||||
|
||||
describe '#valid_dates' do
|
||||
before :each do
|
||||
@conference = create(:conference, start_date: 1.day.ago, end_date: 2.days.from_now)
|
||||
end
|
||||
|
||||
context 'is valid' do
|
||||
it 'when the track\'s start date is before it\'s end date and between the conference start/end dates' do
|
||||
track = build(:track, start_date: Date.today, end_date: Date.tomorrow, program: @conference.program)
|
||||
expect(track.valid?).to eq true
|
||||
end
|
||||
end
|
||||
|
||||
context 'is invalid' do
|
||||
it 'when the track\'s start date is before the conference\'s start date' do
|
||||
track = build(:track, start_date: 2.days.ago, end_date: Date.tomorrow, program: @conference.program)
|
||||
expect(track.valid?).to eq false
|
||||
expect(track.errors[:start_date]).to eq ["can't be before the conference start date (#{1.day.ago.to_date})"]
|
||||
end
|
||||
|
||||
it 'when the track\'s end date is before the conference\'s start date' do
|
||||
track = build(:track, start_date: 3.days.ago, end_date: 2.days.ago, program: @conference.program)
|
||||
expect(track.valid?).to eq false
|
||||
expect(track.errors[:end_date]).to eq ["can't be before the conference start date (#{1.day.ago.to_date})"]
|
||||
end
|
||||
|
||||
it 'when the track\'s start date is after the conference\'s end date' do
|
||||
track = build(:track, start_date: 3.days.from_now, end_date: 4.days.from_now, program: @conference.program)
|
||||
expect(track.valid?).to eq false
|
||||
expect(track.errors[:start_date]).to eq ["can't be after the conference end date (#{2.days.from_now.to_date})"]
|
||||
end
|
||||
|
||||
it 'when the track\'s end date is after the conference\'s end date' do
|
||||
track = build(:track, start_date: Date.today, end_date: 3.days.from_now, program: @conference.program)
|
||||
expect(track.valid?).to eq false
|
||||
expect(track.errors[:end_date]).to eq ["can't be after the conference end date (#{2.days.from_now.to_date})"]
|
||||
end
|
||||
|
||||
it 'when the track\'s start date is after it\'s end date' do
|
||||
track = build(:track, start_date: 1.day.from_now, end_date: 1.day.ago)
|
||||
expect(track.valid?).to eq false
|
||||
expect(track.errors[:start_date]).to eq ['can\'t be after the end date']
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#valid_room' do
|
||||
before :each do
|
||||
@conference = create(:conference)
|
||||
@conference.venue = create(:venue, name: 'The venue')
|
||||
end
|
||||
|
||||
context 'is valid' do
|
||||
it 'when the track\'s room belongs to the venue of the conference' do
|
||||
room = create(:room, venue: @conference.venue)
|
||||
track = build(:track, :self_organized, state: 'accepted', program: @conference.program, room: room)
|
||||
expect(track.valid?).to eq true
|
||||
end
|
||||
end
|
||||
|
||||
context 'is invalid' do
|
||||
it 'when the track\'s room doesn\'t belong to the venue of the track\'s conference' do
|
||||
other_conference = create(:conference)
|
||||
other_conference.venue = create(:venue)
|
||||
room = create(:room, venue: other_conference.venue)
|
||||
track = build(:track, :self_organized, state: 'accepted', program: @conference.program, room: room)
|
||||
expect(track.valid?).to eq false
|
||||
expect(track.errors[:room]).to eq ['must be a room of The venue']
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -54,4 +131,226 @@ describe Track do
|
|||
expect(track.self_organized?).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
describe '#transition_possible?' do
|
||||
shared_examples 'transition_possible?' do |state, transition, expected|
|
||||
it "returns #{expected} for #{transition} event, when the track's state is #{state}}" do
|
||||
my_self_organized_track = create(:track, :self_organized, state: state)
|
||||
expect(my_self_organized_track.transition_possible?(transition.to_sym)).to eq expected
|
||||
end
|
||||
end
|
||||
|
||||
states = [:new, :to_accept, :accepted, :confirmed, :to_reject, :rejected, :canceled, :withdrawn]
|
||||
transitions = [:restart, :to_accept, :accept, :confirm, :to_reject, :reject, :cancel, :withdraw]
|
||||
|
||||
states_transitions = { new: { restart: false, to_accept: true, accept: true, confirm: false, to_reject: true, reject: true, cancel: false, withdraw: true },
|
||||
to_accept: { restart: false, to_accept: false, accept: true, confirm: false, to_reject: false, reject: false, cancel: true, withdraw: true },
|
||||
accepted: { restart: false, to_accept: false, accept: false, confirm: true, to_reject: false, reject: false, cancel: true, withdraw: true },
|
||||
confirmed: { restart: false, to_accept: false, accept: false, confirm: false, to_reject: false, reject: false, cancel: true, withdraw: true },
|
||||
to_reject: { restart: false, to_accept: false, accept: false, confirm: false, to_reject: false, reject: true, cancel: true, withdraw: true },
|
||||
rejected: { restart: true, to_accept: false, accept: false, confirm: false, to_reject: false, reject: false, cancel: false, withdraw: false },
|
||||
canceled: { restart: true, to_accept: false, accept: false, confirm: false, to_reject: false, reject: false, cancel: false, withdraw: false },
|
||||
withdrawn: { restart: true, to_accept: false, accept: false, confirm: false, to_reject: false, reject: false, cancel: false, withdraw: false } }
|
||||
|
||||
states.each do |state|
|
||||
transitions.each do |transition|
|
||||
it_behaves_like 'transition_possible?', state, transition, states_transitions[state.to_sym][transition.to_sym]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#assign_role_to_submitter' do
|
||||
before :each do
|
||||
Role.where(name: 'track_organizer', resource: self_organized_track).first_or_create
|
||||
@submitter = self_organized_track.submitter
|
||||
end
|
||||
|
||||
it 'gives the role of the track organizer to the submitter of the track' do
|
||||
expect(@submitter.has_role?(:track_organizer, self_organized_track)).to eq false
|
||||
self_organized_track.assign_role_to_submitter
|
||||
expect(@submitter.has_role?(:track_organizer, self_organized_track)).to eq true
|
||||
end
|
||||
|
||||
it 'is executed when the track is confirmed' do
|
||||
self_organized_track.state = 'accepted'
|
||||
self_organized_track.save!
|
||||
expect(@submitter.has_role?(:track_organizer, self_organized_track)).to eq false
|
||||
self_organized_track.confirm
|
||||
expect(@submitter.has_role?(:track_organizer, self_organized_track)).to eq true
|
||||
end
|
||||
end
|
||||
|
||||
describe '#revoke_role_and_cleanup' do
|
||||
before :each do
|
||||
Role.where(name: 'track_organizer', resource: self_organized_track).first_or_create
|
||||
@a_track_organizer = create(:user)
|
||||
self_organized_track.state = 'confirmed'
|
||||
self_organized_track.cfp_active = true
|
||||
self_organized_track.save!
|
||||
@a_track_organizer.add_role 'track_organizer', self_organized_track
|
||||
@an_event_of_the_track = create(:event, program: self_organized_track.program, track: self_organized_track)
|
||||
end
|
||||
|
||||
it 'revokes the role of the track organizer' do
|
||||
expect(@a_track_organizer.has_role?(:track_organizer, self_organized_track)).to eq true
|
||||
self_organized_track.revoke_role_and_cleanup
|
||||
expect(@a_track_organizer.has_role?(:track_organizer, self_organized_track)).to eq false
|
||||
end
|
||||
|
||||
it 'removes the track from the events that have it set' do
|
||||
expect(@an_event_of_the_track.track).to eq self_organized_track
|
||||
self_organized_track.revoke_role_and_cleanup
|
||||
@an_event_of_the_track.reload
|
||||
expect(@an_event_of_the_track.track).to eq nil
|
||||
end
|
||||
|
||||
it 'is executed when the track is canceled' do
|
||||
self_organized_track.state = 'confirmed'
|
||||
self_organized_track.save!
|
||||
self_organized_track.cancel
|
||||
expect(@a_track_organizer.has_role?(:track_organizer, self_organized_track)).to eq false
|
||||
@an_event_of_the_track.reload
|
||||
expect(@an_event_of_the_track.track).to eq nil
|
||||
end
|
||||
|
||||
it 'is executed when the track is withdrawn' do
|
||||
self_organized_track.withdraw
|
||||
expect(@a_track_organizer.has_role?(:track_organizer, self_organized_track)).to eq false
|
||||
@an_event_of_the_track.reload
|
||||
expect(@an_event_of_the_track.track).to eq nil
|
||||
end
|
||||
end
|
||||
|
||||
describe '#accepted?' do
|
||||
context 'returns true' do
|
||||
it 'when the state is "accepted"' do
|
||||
self_organized_track.state = 'accepted'
|
||||
self_organized_track.save!
|
||||
expect(self_organized_track.accepted?).to eq true
|
||||
end
|
||||
end
|
||||
|
||||
context 'returns false' do
|
||||
%w[new to_accept confirmed to_reject rejected canceled withdrawn].each do |state|
|
||||
it "when the state is \"#{state}\"" do
|
||||
self_organized_track.state = state
|
||||
self_organized_track.save!
|
||||
expect(self_organized_track.accepted?).to eq false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#confirmed?' do
|
||||
context 'returns true' do
|
||||
it 'when the state is "confirmed"' do
|
||||
self_organized_track.state = 'confirmed'
|
||||
self_organized_track.save!
|
||||
expect(self_organized_track.confirmed?).to eq true
|
||||
end
|
||||
end
|
||||
|
||||
context 'returns false' do
|
||||
%w[new to_accept accepted to_reject rejected canceled withdrawn].each do |state|
|
||||
it "when the state is \"#{state}\"" do
|
||||
self_organized_track.state = state
|
||||
self_organized_track.save!
|
||||
expect(self_organized_track.confirmed?).to eq false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# accepted? and confirmed? are mutually exclusive (they can't be both true)
|
||||
describe '#self_organized_and_accepted_or_confirmed?' do
|
||||
context 'returns true' do
|
||||
context 'when self_organized? returns true' do
|
||||
before :each do
|
||||
allow(track).to receive(:self_organized?).and_return(true)
|
||||
end
|
||||
|
||||
context 'accepted? returns true and confirmed? returns false' do
|
||||
before :each do
|
||||
allow(track).to receive(:accepted?).and_return(true)
|
||||
allow(track).to receive(:confirmed?).and_return(false)
|
||||
end
|
||||
|
||||
it { expect(track.self_organized_and_accepted_or_confirmed?).to eq true }
|
||||
end
|
||||
|
||||
context 'accepted? returns false and confirmed? returns true' do
|
||||
before :each do
|
||||
allow(track).to receive(:accepted?).and_return(false)
|
||||
allow(track).to receive(:confirmed?).and_return(true)
|
||||
end
|
||||
|
||||
it { expect(track.self_organized_and_accepted_or_confirmed?).to eq true }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'returns false' do
|
||||
context 'when self_organized? returns true' do
|
||||
before :each do
|
||||
allow(track).to receive(:self_organized?).and_return(true)
|
||||
end
|
||||
|
||||
context 'accepted? returns false and confirmed? returns false' do
|
||||
before :each do
|
||||
allow(track).to receive(:accepted?).and_return(false)
|
||||
allow(track).to receive(:confirmed?).and_return(false)
|
||||
end
|
||||
|
||||
it { expect(track.self_organized_and_accepted_or_confirmed?).to eq false }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when self_organized? returns false' do
|
||||
before :each do
|
||||
allow(track).to receive(:self_organized?).and_return(false)
|
||||
end
|
||||
|
||||
context 'accepted? returns false and confirmed? returns false' do
|
||||
before :each do
|
||||
allow(track).to receive(:accepted?).and_return(false)
|
||||
allow(track).to receive(:confirmed?).and_return(false)
|
||||
end
|
||||
|
||||
it { expect(track.self_organized_and_accepted_or_confirmed?).to eq false }
|
||||
end
|
||||
|
||||
context 'accepted? returns true and confirmed? returns false' do
|
||||
before :each do
|
||||
allow(track).to receive(:accepted?).and_return(true)
|
||||
allow(track).to receive(:confirmed?).and_return(false)
|
||||
end
|
||||
|
||||
it { expect(track.self_organized_and_accepted_or_confirmed?).to eq false }
|
||||
end
|
||||
|
||||
context 'accepted? returns false and confirmed? returns true' do
|
||||
before :each do
|
||||
allow(track).to receive(:accepted?).and_return(false)
|
||||
allow(track).to receive(:confirmed?).and_return(true)
|
||||
end
|
||||
|
||||
it { expect(track.self_organized_and_accepted_or_confirmed?).to eq false }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#create_organizer_role' do
|
||||
it 'creates the role of the track organizer' do
|
||||
expect(Role.find_by(name: 'track_organizer', resource: self_organized_track)).to eq nil
|
||||
self_organized_track.send(:create_organizer_role)
|
||||
expect(Role.find_by(name: 'track_organizer', resource: self_organized_track).description).to eq 'For the organizers of the Track'
|
||||
end
|
||||
|
||||
it 'is executed when the track is accepted' do
|
||||
expect(Role.find_by(name: 'track_organizer', resource: self_organized_track)).to eq nil
|
||||
self_organized_track.accept
|
||||
expect(Role.find_by(name: 'track_organizer', resource: self_organized_track).description).to eq 'For the organizers of the Track'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue