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:
AEtherC0r3 2017-07-14 15:57:34 +03:00 committed by Stella Rouzi
parent 2f9eb04219
commit d9faffc96a
27 changed files with 909 additions and 62 deletions

View file

@ -181,6 +181,7 @@ linters:
- "app/views/tracks/index.html.haml" - "app/views/tracks/index.html.haml"
- "app/views/tracks/show.html.haml" - "app/views/tracks/show.html.haml"
- "app/views/conferences/_call_for_tracks.html.haml" - "app/views/conferences/_call_for_tracks.html.haml"
- "app/views/admin/tracks/_change_state_dropdown.html.haml"
# Offense count: 223 # Offense count: 223
InstanceVariables: InstanceVariables:
@ -245,6 +246,7 @@ linters:
- "app/views/tracks/_form.html.haml" - "app/views/tracks/_form.html.haml"
- "app/views/admin/cfps/_tracks_cfp.html.haml" - "app/views/admin/cfps/_tracks_cfp.html.haml"
- "app/views/conferences/_call_for_tracks.html.haml" - "app/views/conferences/_call_for_tracks.html.haml"
- "app/views/admin/tracks/_change_state_dropdown.html.haml"
# Offense count: 32 # Offense count: 32
IdNames: IdNames:

View file

@ -20,6 +20,7 @@ module Admin
def create def create
@track = @program.tracks.new(track_params) @track = @program.tracks.new(track_params)
@track.state = 'confirmed' @track.state = 'confirmed'
@track.cfp_active = true
if @track.save if @track.save
redirect_to admin_conference_program_tracks_path(conference_id: @conference.short_title), redirect_to admin_conference_program_tracks_path(conference_id: @conference.short_title),
notice: 'Track successfully created.' notice: 'Track successfully created.'
@ -60,10 +61,55 @@ module Admin
end end
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 private
def track_params def track_params
params.require(:track).permit(:name, :description, :color, :short_name, :cfp_active, :start_date, :end_date, :room_id) params.require(:track).permit(:name, :description, :color, :short_name, :cfp_active, :start_date, :end_date, :room_id)
end 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
end end

View file

@ -4,7 +4,7 @@ class TracksController < ApplicationController
load_and_authorize_resource through: :program, find_by: :short_name load_and_authorize_resource through: :program, find_by: :short_name
def index def index
@tracks = current_user.tracks.where(program: @program) @tracks = @tracks.where(submitter: current_user)
end end
def show; end def show; end
@ -38,9 +38,33 @@ class TracksController < ApplicationController
end end
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 private
def track_params 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
end end

View file

@ -56,7 +56,7 @@ module ApplicationHelper
end end
def tracks(conference) 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] first = all[0...-1]
last = all[-1] last = all[-1]
ts = '' ts = ''

View file

@ -39,4 +39,12 @@ module EventsHelper
content_tag :span, 'REPLACEMENT', class: (['label', 'label-info'] + label_classes) content_tag :span, 'REPLACEMENT', class: (['label', 'label-info'] + label_classes)
end end
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 end

View file

@ -100,8 +100,10 @@ class Ability
track.new_record? && track.program.cfps.for_tracks.try(:open?) track.new_record? && track.program.cfps.for_tracks.try(:open?)
end end
can [:index, :show, :edit, :update], Track do |track| can [:index, :show, :restart, :confirm, :withdraw], Track, submitter_id: user.id
user == track.submitter
can [:edit, :update], Track do |track|
user == track.submitter && !(track.accepted? || track.confirmed?)
end end
end end

View file

@ -275,6 +275,10 @@ class AdminAbility
can :manage, Track, id: track_ids_for_track_organizer 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 # Show Roles in the admin sidebar and allow authorization of the index action
can [:index, :show], Role do |role| can [:index, :show], Role do |role|
role.resource_type == 'Conference' || role.resource_type == 'Track' role.resource_type == 'Conference' || role.resource_type == 'Track'

View file

@ -45,6 +45,7 @@ class Event < ActiveRecord::Base
validates :max_attendees, numericality: { only_integer: true, greater_than_or_equal_to: 1, allow_nil: true } 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 :max_attendees_no_more_than_room_size
validate :acceptable_track
scope :confirmed, -> { where(state: 'confirmed') } scope :confirmed, -> { where(state: 'confirmed') }
scope :canceled, -> { where(state: 'canceled') } scope :canceled, -> { where(state: 'canceled') }
@ -303,4 +304,11 @@ class Event < ActiveRecord::Base
def conference_id def conference_id
program.conference_id program.conference_id
end 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 end

View file

@ -22,13 +22,13 @@ class Track < ActiveRecord::Base
} }
validates :state, validates :state,
presence: true, presence: true,
inclusion: { in: %w(new to_accept accepted confirmed to_reject rejected canceled withdrawn) }, inclusion: { in: %w(new to_accept accepted confirmed to_reject rejected canceled withdrawn) }
if: :self_organized? validates :cfp_active, inclusion: { in: [true, false] }
validates :cfp_active, inclusion: { in: [true, false] }, if: :self_organized?
validates :start_date, presence: true, if: :self_organized_and_accepted_or_confirmed? 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 :end_date, presence: true, if: :self_organized_and_accepted_or_confirmed?
validates :room, 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 before_validation :capitalize_color
@ -45,7 +45,7 @@ class Track < ActiveRecord::Base
event :restart do event :restart do
transitions to: :new, from: [:rejected, :withdrawn, :canceled] transitions to: :new, from: [:rejected, :withdrawn, :canceled]
end end
event :readiness_to_accept do event :to_accept do
transitions to: :to_accept, from: [:new] transitions to: :to_accept, from: [:new]
end end
event :accept do event :accept do
@ -54,7 +54,7 @@ class Track < ActiveRecord::Base
event :confirm do event :confirm do
transitions to: :confirmed, from: [:accepted], on_transition: :assign_role_to_submitter transitions to: :confirmed, from: [:accepted], on_transition: :assign_role_to_submitter
end end
event :readiness_to_reject do event :to_reject do
transitions to: :to_reject, from: [:new] transitions to: :to_reject, from: [:new]
end end
event :reject do event :reject do
@ -107,6 +107,7 @@ class Track < ActiveRecord::Base
events.each do |event| events.each do |event|
event.track = nil event.track = nil
event.save!
end end
end end
@ -137,6 +138,19 @@ class Track < ActiveRecord::Base
self_organized? && (accepted? || confirmed?) self_organized? && (accepted? || confirmed?)
end 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 private
def generate_guid def generate_guid
@ -162,26 +176,32 @@ class Track < ActiveRecord::Base
end end
def valid_dates def valid_dates
return unless start_date && 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})")
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})")
end end
if program && program.conference && program.conference.start_date && (end_date < program.conference.start_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.end_date})") errors.add(:end_date, "can't be before the conference start date (#{program.conference.start_date})")
end 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})") errors.add(:start_date, "can't be after the conference end date (#{program.conference.end_date})")
end 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})") errors.add(:end_date, "can't be after the conference end date (#{program.conference.end_date})")
end end
if start_date > end_date if start_date && end_date && (start_date > end_date)
errors.add(:start_date, 'can\'t be after the 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 end
end end

View 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}"

View file

@ -19,6 +19,5 @@
- else - else
Please add a venue with rooms, if you want to select a room for the track. 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 = 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' } = f.action :submit, as: :button, button_html: { class: 'btn btn-primary' }

View file

@ -40,11 +40,15 @@
= track.color = track.color
%td %td
- if track.self_organized? - 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 - else
= track.state.humanize = track.state.humanize
%td %td
- if track.self_organized?
= check_box_tag "#{@conference.short_title}_#{track.short_name}", track.id, track.cfp_active, = check_box_tag "#{@conference.short_title}_#{track.short_name}", track.id, track.cfp_active,
class: 'switch-checkbox', method: :patch, class: 'switch-checkbox', method: :patch,
url: toggle_cfp_inclusion_admin_conference_program_track_path(@conference.short_title, id: track.short_name)+"?included=", url: toggle_cfp_inclusion_admin_conference_program_track_path(@conference.short_title, id: track.short_name)+"?included=",
@ -53,8 +57,7 @@
off_color: 'warning', off_color: 'warning',
on_text: 'Yes', on_text: 'Yes',
off_text: 'No' } off_text: 'No' }
- else
%i.fa.fa-check
%td %td
- if track.room - if track.room
= link_to track.room.name, admin_conference_venue_room_path(@conference.short_title, track.room.id) = link_to track.room.name, admin_conference_venue_room_path(@conference.short_title, track.room.id)
@ -72,6 +75,7 @@
N/A N/A
%td %td
.btn-group{role: "group"} .btn-group{role: "group"}
- if can? :edit, track
= link_to 'Edit', edit_admin_conference_program_track_path(@conference.short_title, track), = link_to 'Edit', edit_admin_conference_program_track_path(@conference.short_title, track),
method: :get, class: 'btn btn-primary' method: :get, class: 'btn btn-primary'
- if can? :destroy, track - if can? :destroy, track

View file

@ -6,10 +6,7 @@
= speaker_selector_input f = speaker_selector_input f
- if @program.tracks.any? = track_selector_input f
= 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, = f.input :event_type_id, as: :select,
collection: @conference.program.event_types.map {|type| ["#{type.title} - #{show_time(type.length)}", type.id, collection: @conference.program.event_types.map {|type| ["#{type.title} - #{show_time(type.length)}", type.id,

View file

@ -9,9 +9,11 @@
Track Track
.row .row
.col-md-12 .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 :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 :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 :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.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' } = f.action :submit, as: :button, button_html: { class: 'btn btn-primary' }

View file

@ -16,6 +16,8 @@
%th Description %th Description
%th Color %th Color
%th State %th State
%th Start Date
%th End Date
%th Actions %th Actions
%tbody %tbody
- @tracks.each do |track| - @tracks.each do |track|
@ -34,10 +36,31 @@
%td %td
= track.state.humanize = track.state.humanize
%td %td
- 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), = link_to 'Edit', edit_conference_program_track_path(@conference.short_title, track),
method: :get, class: 'btn btn-primary' method: :get, class: 'btn btn-primary'
.row .row
.col-md-12 .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' = link_to "New Track request", new_conference_program_track_path(@conference.short_title), class: 'btn btn-success pull-right'

View file

@ -17,10 +17,25 @@
State: State:
%dd %dd
= @track.state.humanize = @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 %dt
Description Description
%dd %dd
= @track.description = @track.description
.row .row
.col-md-12.text-right .col-md-12.text-right
- if can? :edit, @track
= link_to 'Edit Track request', edit_conference_program_track_path(@conference.short_title, @track), class: 'btn btn-primary' = link_to 'Edit Track request', edit_conference_program_track_path(@conference.short_title, @track), class: 'btn btn-primary'

View file

@ -69,6 +69,13 @@ Osem::Application.routes.draw do
resources :tracks do resources :tracks do
member do member do
patch :toggle_cfp_inclusion patch :toggle_cfp_inclusion
patch :restart
patch :to_accept
patch :accept
patch :confirm
patch :to_reject
patch :reject
patch :cancel
end end
end end
resources :event_types resources :event_types
@ -149,7 +156,13 @@ Osem::Application.routes.draw do
patch '/restart' => 'proposals#restart' patch '/restart' => 'proposals#restart'
end end
end end
resources :tracks, except: :destroy resources :tracks, except: :destroy do
member do
patch :restart
patch :confirm
patch :withdraw
end
end
end end
# TODO: change conference_registrations to singular resource # TODO: change conference_registrations to singular resource

View 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

View file

@ -520,7 +520,7 @@ ActiveRecord::Schema.define(version: 20170807092805) do
t.integer "program_id" t.integer "program_id"
t.string "short_name", null: false t.string "short_name", null: false
t.string "state", default: "new", 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 "submitter_id"
t.integer "room_id" t.integer "room_id"
t.date "start_date" t.date "start_date"

View file

@ -5,7 +5,7 @@ describe Admin::TracksController do
let(:conference) { create(:conference) } let(:conference) { create(:conference) }
let!(:track) { create(:track, program: conference.program, color: '#800080') } 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 before :each do
sign_in(admin) sign_in(admin)
@ -83,6 +83,7 @@ describe Admin::TracksController do
it 'the new tracks has the correct attributes' do it 'the new tracks has the correct attributes' do
expect(assigns(:track).state).to eq 'confirmed' expect(assigns(:track).state).to eq 'confirmed'
expect(assigns(:track).cfp_active).to eq true
end end
end end
@ -257,4 +258,204 @@ describe Admin::TracksController do
end end
end 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 end

View file

@ -1,12 +1,11 @@
require 'spec_helper' require 'spec_helper'
describe TracksController do describe TracksController do
# A regular user should be used when the track requests have been enabled
let(:user) { create(:admin) } let(:user) { create(:admin) }
let(:conference) { create(:conference) } let(:conference) { create(:conference) }
let!(:regular_track) { create(:track, program: conference.program) } 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 before :each do
sign_in(user) sign_in(user)
@ -176,4 +175,67 @@ describe TracksController do
end end
end 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 end

View file

@ -5,12 +5,16 @@ FactoryGirl.define do
color { Faker::Color.hex_color } color { Faker::Color.hex_color }
short_name { SecureRandom.urlsafe_base64(5) } short_name { SecureRandom.urlsafe_base64(5) }
state 'confirmed' state 'confirmed'
cfp_active true
program program
trait :self_organized do trait :self_organized do
association :submitter, factory: :user association :submitter, factory: :user
state 'new' state 'new'
cfp_active false cfp_active false
start_date { Date.today }
end_date { Date.today }
room
end end
end end
end end

View file

@ -26,6 +26,7 @@ describe 'User' do
let(:program_with_cfp) { create(:program, :with_cfp) } let(:program_with_cfp) { create(:program, :with_cfp) }
let(:program_without_cfp) { create(:program) } 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(: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!(:open_registration_period) { create(:registration_period, conference: conference_with_open_registration, start_date: Date.current - 6.days) }
let(:conference_with_closed_registration) { create(:conference) } 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_event_with_cfp) { create(:event, users: [user], program: program_with_cfp) }
let(:user_commercial) { create(:commercial, commercialable: user_event_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) } 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(:create, user_event_with_cfp.commercials.new) }
it{ should be_able_to(:manage, user_commercial) } it{ should be_able_to(:manage, user_commercial) }
it{ should_not be_able_to(:manage, commercial_event_unconfirmed) } 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 end
end end

View file

@ -44,7 +44,7 @@ describe 'User with admin role' do
let!(:my_event_schedule) { create(:event_schedule, schedule: my_schedule) } let!(:my_event_schedule) { create(:event_schedule, schedule: my_schedule) }
let!(:other_event_schedule) { create(:event_schedule, schedule: other_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 context 'user #is_admin?' do
let(:venue) { my_conference.venue } 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(:show, my_conference.program) }
it{ should be_able_to(:update, new_track) } it{ should be_able_to(:update, new_track) }
it{ should be_able_to(:manage, my_self_organized_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 any role'
it_behaves_like 'user with non-organizer role', 'track_organizer' it_behaves_like 'user with non-organizer role', 'track_organizer'

View file

@ -606,8 +606,8 @@ describe Conference do
describe 'tracks_distribution' do describe 'tracks_distribution' do
before do before do
subject.email_settings = create(:email_settings) subject.email_settings = create(:email_settings)
@track_one = create(:track, name: 'Track One', color: '#000000') @track_one = create(:track, name: 'Track One', color: '#000000', program: subject.program)
@track_two = create(:track, name: 'Track Two', color: '#ffffff') @track_two = create(:track, name: 'Track Two', color: '#ffffff', program: subject.program)
end end
describe '#tracks_distribution' do describe '#tracks_distribution' do

View file

@ -96,6 +96,40 @@ describe Event do
end end
end 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 end
describe '#comments_count' do describe '#comments_count' do

View file

@ -8,6 +8,7 @@ describe Track do
describe 'association' do describe 'association' do
it { is_expected.to belong_to(:program) } it { is_expected.to belong_to(:program) }
it { is_expected.to belong_to(:submitter).class_name('User') } it { is_expected.to belong_to(:submitter).class_name('User') }
it { is_expected.to belong_to(:room) }
it { is_expected.to have_many(:events) } it { is_expected.to have_many(:events) }
end end
@ -23,23 +24,99 @@ describe Track do
it { is_expected.to allow_value('My_track_name').for(:short_name) } 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_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_uniqueness_of(:short_name).scoped_to(:program_id) }
context 'when self-organized' do
before :each do
allow(subject).to receive(:self_organized?).and_return(true)
end
it { is_expected.to validate_presence_of(:state) } 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]) } it { is_expected.to validate_inclusion_of(:cfp_active).in_array([true, false]) }
end
context 'when regular' do context 'when self_organized_and_accepted_or_confirmed? returns true' do
before :each 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(true)
end end
it { is_expected.to_not validate_presence_of(:state) } it { is_expected.to validate_presence_of(:start_date) }
it { is_expected.to_not validate_inclusion_of(:cfp_active) } it { is_expected.to validate_presence_of(:end_date) }
it { is_expected.to validate_presence_of(:room) }
end
context 'when self_organized_and_accepted_or_confirmed? returns false' do
before :each do
allow(subject).to receive(:self_organized_and_accepted_or_confirmed?).and_return(false)
end
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
end end
@ -54,4 +131,226 @@ describe Track do
expect(track.self_organized?).to eq false expect(track.self_organized?).to eq false
end end
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 end