mirror of
https://github.com/openSUSE/osem.git
synced 2026-08-13 19:54:02 +00:00
Implement track requests and add the track organizer role
About track requests: Create migration that adds the fields submitter_id, state, and cfp_active to Tracks Add validations and the self_organized? method to the Track model Create a new TracksController outide of the admin namespace Create the relevant views for index, show, new and edit Modify the admin views for tracks to include extra info for self-organized tracks About track organizers: Create the role when a self-organized track is created Define track organizer abilities Modify the roles views and controller to handle the new role The route for Roles#edit needs to have higher priority than the nested routes for track roles, otherwise, the word edit in the url is matched as a track with short_name edit
This commit is contained in:
parent
98fc1137e1
commit
68fc750e9f
26 changed files with 766 additions and 27 deletions
|
|
@ -172,6 +172,9 @@ linters:
|
|||
- "app/views/users/edit.html.haml"
|
||||
- "app/views/users/show.html.haml"
|
||||
- "app/views/admin/cfps/index.html.haml"
|
||||
- "app/views/tracks/_form.html.haml"
|
||||
- "app/views/tracks/index.html.haml"
|
||||
- "app/views/tracks/show.html.haml"
|
||||
|
||||
# Offense count: 223
|
||||
InstanceVariables:
|
||||
|
|
@ -231,6 +234,7 @@ linters:
|
|||
- "app/views/schedules/_schedule_item.html.haml"
|
||||
- "app/views/schedules/_schedule_tabs.html.haml"
|
||||
- "app/views/admin/cfps/_events_cfp.html.haml"
|
||||
- "app/views/tracks/_form.html.haml"
|
||||
|
||||
# Offense count: 32
|
||||
IdNames:
|
||||
|
|
@ -330,6 +334,8 @@ linters:
|
|||
- "app/views/shared/_object_changes.html.haml"
|
||||
- "app/views/tickets/_ticket.html.haml"
|
||||
- "app/views/tickets/index.html.haml"
|
||||
- "app/views/tracks/index.html.haml"
|
||||
- "app/views/tracks/show.html.haml"
|
||||
|
||||
# Offense count: 23
|
||||
ClassesBeforeIds:
|
||||
|
|
|
|||
|
|
@ -30,3 +30,4 @@ Metrics/BlockLength:
|
|||
Exclude:
|
||||
- 'spec/models/conference_spec.rb'
|
||||
- 'spec/features/ability_spec.rb'
|
||||
- 'spec/models/ability_spec.rb'
|
||||
|
|
|
|||
|
|
@ -94,6 +94,8 @@ Metrics/ModuleLength:
|
|||
# Offense count: 14
|
||||
Metrics/PerceivedComplexity:
|
||||
Max: 15
|
||||
Exclude:
|
||||
- 'app/controllers/admin/roles_controller.rb'
|
||||
|
||||
# Offense count: 11
|
||||
# Cop supports --auto-correct.
|
||||
|
|
@ -850,6 +852,7 @@ Style/SymbolProc:
|
|||
- 'app/controllers/admin/questions_controller.rb'
|
||||
- 'app/helpers/application_helper.rb'
|
||||
- 'app/models/ability.rb'
|
||||
- 'app/models/admin_ability.rb'
|
||||
- 'db/migrate/20140730104658_migrate_roles_for_cancancan.rb'
|
||||
- 'spec/controllers/admin/conferences_controller_spec.rb'
|
||||
- 'spec/support/flash.rb'
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ module Admin
|
|||
end
|
||||
unless (current_user.has_role? :organizer, :any) || (current_user.has_role? :cfp, :any) ||
|
||||
(current_user.has_role? :info_desk, :any) || (current_user.has_role? :organization_admin, :any) ||
|
||||
(current_user.has_role? :volunteers_coordinator, :any) || current_user.is_admin
|
||||
(current_user.has_role? :volunteers_coordinator, :any) ||
|
||||
(current_user.has_role? :track_organizer, :any) || current_user.is_admin
|
||||
raise CanCan::AccessDenied.new('You are not authorized to access this page.')
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,14 +8,26 @@ module Admin
|
|||
|
||||
def index
|
||||
@roles = Role.where(resource: @conference)
|
||||
tracks = @conference.program.tracks.where.not(submitter: nil)
|
||||
@roles += Role.where(resource: tracks)
|
||||
authorize! :index, @role
|
||||
end
|
||||
|
||||
def show
|
||||
@url = if @track
|
||||
toggle_user_track_admin_conference_role_path(@conference.short_title, @role.name, @track.name.tr(' ', '_'))
|
||||
else
|
||||
toggle_user_admin_conference_role_path(@conference.short_title, @role.name)
|
||||
end
|
||||
@users = @role.users
|
||||
end
|
||||
|
||||
def edit
|
||||
@url = if @track
|
||||
track_admin_conference_role_path(@conference.short_title, @role.name, @track.name.tr(' ', '_'))
|
||||
else
|
||||
admin_conference_role_path(@conference.short_title, @role.name)
|
||||
end
|
||||
@users = @role.users
|
||||
end
|
||||
|
||||
|
|
@ -23,7 +35,13 @@ module Admin
|
|||
role_name = @role.name
|
||||
|
||||
if @role.update_attributes(role_params)
|
||||
redirect_to admin_conference_role_path(@conference.short_title, @role.name),
|
||||
url = if @track
|
||||
track_admin_conference_role_path(@conference.short_title, @role.name, @track.name.tr(' ', '_'))
|
||||
else
|
||||
admin_conference_role_path(@conference.short_title, @role.name)
|
||||
end
|
||||
|
||||
redirect_to url,
|
||||
notice: 'Successfully updated role ' + @role.name
|
||||
else
|
||||
@role.name = role_name
|
||||
|
|
@ -36,8 +54,14 @@ module Admin
|
|||
user = User.find_by(email: user_params[:email])
|
||||
state = user_params[:state]
|
||||
|
||||
url = if @track
|
||||
track_admin_conference_role_path(@conference.short_title, @role.name, @track.name.tr(' ', '_'))
|
||||
else
|
||||
admin_conference_role_path(@conference.short_title, @role.name)
|
||||
end
|
||||
|
||||
unless user
|
||||
redirect_to admin_conference_role_path(@conference.short_title, @role.name),
|
||||
redirect_to url,
|
||||
error: 'Could not find user. Please provide a valid email!'
|
||||
return
|
||||
end
|
||||
|
|
@ -49,17 +73,23 @@ module Admin
|
|||
return
|
||||
end
|
||||
|
||||
if @role.resource_type == 'Conference'
|
||||
role_resource = @conference
|
||||
elsif @role.resource_type == 'Track'
|
||||
role_resource = @track
|
||||
end
|
||||
|
||||
# Remove user
|
||||
if state == 'false'
|
||||
if user.remove_role @role.name, @conference
|
||||
if user.remove_role @role.name, role_resource
|
||||
flash[:notice] = "Successfully removed role #{@role.name} from user #{user.email}"
|
||||
else
|
||||
flash[:error] = "Could not remove role #{@role.name} from user #{user.email}"
|
||||
end
|
||||
elsif user.has_role? @role.name, @conference
|
||||
elsif user.has_role? @role.name, role_resource
|
||||
flash[:error] = "User #{user.email} already has the role #{@role.name}"
|
||||
# Add user
|
||||
elsif user.add_role @role.name, @conference
|
||||
elsif user.add_role @role.name, role_resource
|
||||
flash[:notice] = "Successfully added role #{@role.name} to user #{user.email}"
|
||||
else
|
||||
flash[:error] = "Coud not add role #{@role.name} to #{user.email}"
|
||||
|
|
@ -67,7 +97,7 @@ module Admin
|
|||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
format.html { redirect_to admin_conference_role_path(@conference.short_title, @role.name) }
|
||||
format.html { redirect_to url }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -77,8 +107,13 @@ module Admin
|
|||
# Set 'organizer' as default role, when there is no other selection
|
||||
@selection = params[:id] ? params[:id].parameterize.underscore : 'organizer'
|
||||
|
||||
if @selection == 'track_organizer'
|
||||
@track = @conference.program.tracks.find_by(short_name: params[:track_name])
|
||||
@role = Role.find_by(name: @selection, resource: @track)
|
||||
else
|
||||
@role = Role.find_by(name: @selection, resource: @conference)
|
||||
end
|
||||
end
|
||||
|
||||
def role_params
|
||||
params.require(:role).permit(:name, :description, user_ids: [])
|
||||
|
|
|
|||
|
|
@ -50,10 +50,19 @@ module Admin
|
|||
end
|
||||
end
|
||||
|
||||
def toggle_cfp_inclusion
|
||||
@track.cfp_active = !@track.cfp_active
|
||||
if @track.save
|
||||
head :ok
|
||||
else
|
||||
head :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def track_params
|
||||
params.require(:track).permit(:name, :description, :color, :short_name)
|
||||
params.require(:track).permit(:name, :description, :color, :short_name, :cfp_active)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
47
app/controllers/tracks_controller.rb
Normal file
47
app/controllers/tracks_controller.rb
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
class TracksController < ApplicationController
|
||||
load_resource :conference, find_by: :short_title
|
||||
load_resource :program, through: :conference, singleton: true
|
||||
load_and_authorize_resource through: :program, find_by: :short_name
|
||||
|
||||
def index
|
||||
@tracks = current_user.tracks.where(program: @program)
|
||||
end
|
||||
|
||||
def show; end
|
||||
|
||||
def new
|
||||
@track = @program.tracks.new(color: @conference.next_color_for_collection(:tracks))
|
||||
end
|
||||
|
||||
def edit; end
|
||||
|
||||
def create
|
||||
@track = @program.tracks.new(track_params)
|
||||
@track.submitter = current_user
|
||||
@track.state = 'new'
|
||||
@track.cfp_active = false
|
||||
if @track.save
|
||||
redirect_to conference_program_tracks_path(conference_id: @conference.short_title),
|
||||
notice: 'Track request successfully created.'
|
||||
else
|
||||
flash.now[:error] = "Creating Track request failed: #{@track.errors.full_messages.join('. ')}."
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
if @track.update_attributes(track_params)
|
||||
redirect_to admin_conference_program_tracks_path(conference_id: @conference.short_title),
|
||||
notice: 'Track request successfully updated.'
|
||||
else
|
||||
flash.now[:error] = "Track request update failed: #{@track.errors.full_messages.join('. ')}."
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def track_params
|
||||
params.require(:track).permit(:name, :description, :color, :short_name)
|
||||
end
|
||||
end
|
||||
|
|
@ -70,6 +70,11 @@ class AdminAbility
|
|||
cannot :destroy, Venue do |venue|
|
||||
venue.conference.program.events.where.not(room_id: nil).any?
|
||||
end
|
||||
|
||||
# Prevent requests for tracks from being destroyed
|
||||
cannot :destroy, Track do |track|
|
||||
track.self_organized?
|
||||
end
|
||||
end
|
||||
|
||||
# Abilities for signed in users with roles
|
||||
|
|
@ -79,6 +84,7 @@ class AdminAbility
|
|||
signed_in_with_cfp_role(user) if user.has_role? :cfp, :any
|
||||
signed_in_with_info_desk_role(user) if user.has_role? :info_desk, :any
|
||||
signed_in_with_volunteers_coordinator_role(user) if user.has_role? :volunteers_coordinator, :any
|
||||
signed_in_with_track_organizer_role(user) if user.has_role? :track_organizer, :any
|
||||
common_abilities_for_roles(user)
|
||||
end
|
||||
|
||||
|
|
@ -100,6 +106,9 @@ class AdminAbility
|
|||
# ids of all the conferences for which the user has the 'organizer' role and
|
||||
# conferences that belong to organizations for which user is 'organization_admin'
|
||||
conf_ids = conf_ids_for_organization_admin.concat(Conference.with_role(:organizer, user).pluck(:id)).uniq
|
||||
# ids of all the tracks that belong to the programs of the above conferences
|
||||
track_ids = Track.joins(:program).where('programs.conference_id IN (?)', conf_ids).pluck(:id)
|
||||
|
||||
can :manage, Resource, conference_id: conf_ids
|
||||
can [:read, :update, :destroy], Conference, id: conf_ids
|
||||
can :manage, Splashpage, conference_id: conf_ids
|
||||
|
|
@ -140,11 +149,12 @@ class AdminAbility
|
|||
|
||||
# Abilities for Role (Conference resource)
|
||||
can [:index, :show], Role do |role|
|
||||
role.resource_type == 'Conference'
|
||||
role.resource_type == 'Conference' || role.resource_type == 'Track'
|
||||
end
|
||||
|
||||
can [:edit, :update, :toggle_user], Role do |role|
|
||||
role.resource_type == 'Conference' && (conf_ids.include? role.resource_id)
|
||||
role.resource_type == 'Conference' && (conf_ids.include? role.resource_id) ||
|
||||
role.resource_type == 'Track' && (track_ids.include? role.resource_id)
|
||||
end
|
||||
|
||||
can [:index, :revert_object, :revert_attribute], PaperTrail::Version do |version|
|
||||
|
|
@ -178,7 +188,7 @@ class AdminAbility
|
|||
|
||||
# Abilities for Role (Conference resource)
|
||||
can [:index, :show], Role do |role|
|
||||
role.resource_type == 'Conference'
|
||||
role.resource_type == 'Conference' || role.resource_type == 'Track'
|
||||
end
|
||||
# Can add or remove users from role, when user has that same role for the conference
|
||||
# Eg. If you are member of the CfP team, you can add more CfP team members (add users to the role 'CfP')
|
||||
|
|
@ -211,7 +221,7 @@ class AdminAbility
|
|||
|
||||
# Abilities for Role (Conference resource)
|
||||
can [:index, :show], Role do |role|
|
||||
role.resource_type == 'Conference'
|
||||
role.resource_type == 'Conference' || role.resource_type == 'Track'
|
||||
end
|
||||
# Can add or remove users from role, when user has that same role for the conference
|
||||
# Eg. If you are member of the CfP team, you can add more CfP team members (add users to the role 'CfP')
|
||||
|
|
@ -234,7 +244,7 @@ class AdminAbility
|
|||
|
||||
# Abilities for Role (Conference resource)
|
||||
can [:index, :show], Role do |role|
|
||||
role.resource_type == 'Conference'
|
||||
role.resource_type == 'Conference' || role.resource_type == 'Track'
|
||||
end
|
||||
# Can add or remove users from role, when user has that same role for the conference
|
||||
# Eg. If you are member of the CfP team, you can add more CfP team members (add users to the role 'CfP')
|
||||
|
|
@ -243,4 +253,34 @@ class AdminAbility
|
|||
(Conference.with_role(:volunteers_coordinator, user).pluck(:id).include? role.resource_id)
|
||||
end
|
||||
end
|
||||
|
||||
def signed_in_with_track_organizer_role(user)
|
||||
# ids of all the conferences for which the user has the 'track organizer' role
|
||||
conf_ids_for_track_organizer = Track.with_role(:track_organizer, user).joins(:program).pluck(:conference_id)
|
||||
# ids of all the tracks for which the user has the 'track_organizer' role
|
||||
track_ids_for_track_organizer = Track.with_role(:track_organizer, user).pluck(:id)
|
||||
|
||||
can :show, Conference do |conf|
|
||||
conf_ids_for_track_organizer.include?(conf.id)
|
||||
end
|
||||
|
||||
# Show Program in the admin sidebar
|
||||
can :show, Program, conference_id: conf_ids_for_track_organizer
|
||||
|
||||
# Show Tracks in the admin sidebar
|
||||
can :update, Track do |track|
|
||||
track.new_record? && conf_ids_for_track_organizer.include?(track.program.conference_id)
|
||||
end
|
||||
|
||||
can :manage, Track, id: track_ids_for_track_organizer
|
||||
|
||||
# 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'
|
||||
end
|
||||
|
||||
can :toggle_user, Role do |role|
|
||||
role.resource_type == 'Track' && track_ids_for_track_organizer.include?(role.resource_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
class Track < ActiveRecord::Base
|
||||
include RevisionCount
|
||||
|
||||
resourcify :roles, dependent: :delete_all
|
||||
|
||||
belongs_to :program
|
||||
belongs_to :submitter, class_name: 'User'
|
||||
has_many :events, dependent: :nullify
|
||||
|
||||
has_paper_trail only: [:name, :description, :color], meta: { conference_id: :conference_id }
|
||||
|
|
@ -14,13 +18,27 @@ class Track < ActiveRecord::Base
|
|||
uniqueness: {
|
||||
scope: :program
|
||||
}
|
||||
validates :state, presence: true, if: :self_organized?
|
||||
validates :cfp_active, inclusion: { in: [true, false] }, if: :self_organized?
|
||||
|
||||
before_validation :capitalize_color
|
||||
|
||||
after_create :create_organizer_role, if: :self_organized?
|
||||
|
||||
def conference
|
||||
program.conference
|
||||
end
|
||||
|
||||
##
|
||||
# Checks if the track is self-organized
|
||||
# ====Returns
|
||||
# * +true+ -> If the track has a submitter
|
||||
# * +false+ -> if the track doesn't have a submitter
|
||||
def self_organized?
|
||||
return true if submitter
|
||||
false
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def generate_guid
|
||||
|
|
@ -38,4 +56,10 @@ class Track < ActiveRecord::Base
|
|||
def conference_id
|
||||
program.conference_id
|
||||
end
|
||||
|
||||
##
|
||||
# Creates the role of the track organizer
|
||||
def create_organizer_role
|
||||
Role.where(name: 'track_organizer', resource: self).first_or_create(description: 'For the organizers of the Track')
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ class User < ActiveRecord::Base
|
|||
has_many :votes, dependent: :destroy
|
||||
has_many :voted_events, through: :votes, source: :events
|
||||
has_many :subscriptions, dependent: :destroy
|
||||
has_many :tracks, foreign_key: 'submitter_id'
|
||||
accepts_nested_attributes_for :roles
|
||||
|
||||
scope :admin, -> { where(is_admin: true) }
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
.text-muted
|
||||
= @role.description
|
||||
|
||||
= semantic_form_for @role, url: admin_conference_role_path(@conference.short_title, @role.name) do |f|
|
||||
= semantic_form_for @role, url: @url do |f|
|
||||
.row
|
||||
.col-md-5
|
||||
= f.input :description
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
- if ( can? :toggle_user, @role )
|
||||
%td.text-right
|
||||
= hidden_field_tag "role[user_ids][]", nil
|
||||
= check_box_tag @conference.short_title, @role.id, (@role.user_ids.include? user.id), method: :post, url: "/admin/conferences/#{@conference.short_title}/roles/#{@role.name}/toggle_user?user[email]=#{user.email}&user[state]=", class: 'switch-checkbox', data: { size: 'small', off_color: 'warning', on_text: 'Yes', off_text: 'No' }
|
||||
= check_box_tag @conference.short_title, @role.id, (@role.user_ids.include? user.id), method: :post, url: "#{@url}?user[email]=#{user.email}&user[state]=", class: 'switch-checkbox', data: { size: 'small', off_color: 'warning', on_text: 'Yes', off_text: 'No' }
|
||||
%td= user.id
|
||||
%td= user.name
|
||||
%td= user.email
|
||||
|
|
|
|||
|
|
@ -19,13 +19,23 @@
|
|||
%tr
|
||||
%td= role.id
|
||||
%td= role.name.titleize
|
||||
%td= role.description
|
||||
%td
|
||||
= role.description
|
||||
- if role.resource_type == 'Track'
|
||||
- track = Track.find(role.resource_id)
|
||||
= link_to track.name, admin_conference_program_track_path(@conference.short_title, track)
|
||||
%td
|
||||
= role.users.pluck(:name).first(5).join ', '
|
||||
- if role.users.count > 5
|
||||
= link_to '...', admin_conference_role_path(@conference.short_title, role.name)
|
||||
%td
|
||||
.btn-group
|
||||
- if role.resource_type == 'Track'
|
||||
- track_name = Track.find(role.resource_id).short_name
|
||||
= link_to 'Users', track_admin_conference_role_path(@conference.short_title, role.name, track_name), class: 'btn btn-success'
|
||||
- if can? :edit, role
|
||||
= link_to 'Edit', track_edit_admin_conference_role_path(@conference.short_title, role.name, track_name), class: 'btn btn-primary'
|
||||
- else
|
||||
= link_to 'Users', admin_conference_role_path(@conference.short_title, role.name), class: 'btn btn-success'
|
||||
- if can? :edit, role
|
||||
= link_to 'Edit', edit_admin_conference_role_path(@conference.short_title, role.name), class: 'btn btn-primary'
|
||||
|
|
|
|||
|
|
@ -6,14 +6,20 @@
|
|||
Role
|
||||
= @role.name.titleize
|
||||
- if can? :edit, @role
|
||||
- if @track
|
||||
= link_to 'Edit', track_edit_admin_conference_role_path(@conference.short_title, @role.name, @track.short_name), class: 'btn btn-primary pull-right'
|
||||
- else
|
||||
= link_to 'Edit', edit_admin_conference_role_path(@conference.short_title, @role.name), class: 'btn btn-primary pull-right'
|
||||
.text-muted
|
||||
= @role.description
|
||||
- if @track
|
||||
= link_to @track.name, admin_conference_program_track_path(@conference.short_title, @track)
|
||||
|
||||
|
||||
.row.col-md-3
|
||||
- if ( can? :toggle_user, @role ) && !@role.new_record?
|
||||
|
||||
= semantic_form_for :user, url: toggle_user_admin_conference_role_path(@conference.short_title, @role.name), method: :post do |u|
|
||||
= semantic_form_for :user, url: @url, method: :post do |u|
|
||||
|
||||
= u.label 'Add user by email: '
|
||||
.input-group
|
||||
|
|
|
|||
|
|
@ -13,4 +13,6 @@
|
|||
= 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 :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.action :submit, as: :button, button_html: { class: 'btn btn-primary' }
|
||||
|
|
|
|||
|
|
@ -11,7 +11,10 @@
|
|||
%th Name
|
||||
%th Short name
|
||||
%th Description
|
||||
%th Submitter
|
||||
%th Color
|
||||
%th State
|
||||
%th Included in the Cfp
|
||||
%th Actions
|
||||
%tbody
|
||||
- @tracks.each do |track|
|
||||
|
|
@ -24,9 +27,31 @@
|
|||
%td
|
||||
%p
|
||||
= truncate(track.description)
|
||||
%td
|
||||
- if track.self_organized?
|
||||
= link_to track.submitter.name, admin_user_path(track.submitter)
|
||||
- else
|
||||
N/A
|
||||
%td
|
||||
%span.label{style: "background-color: #{track.color}; color: #{ contrast_color(track.color) }"}
|
||||
= track.color
|
||||
%td
|
||||
- if track.self_organized?
|
||||
= track.state
|
||||
- else
|
||||
N/A
|
||||
%td
|
||||
- if track.self_organized?
|
||||
= check_box_tag "#{@conference.short_title}_#{track.id}", track.id, track.cfp_active,
|
||||
class: 'switch-checkbox', method: :patch,
|
||||
url: toggle_cfp_inclusion_admin_conference_program_track_path(@conference.short_title, id: track.id)+"?included=",
|
||||
data: { size: 'small',
|
||||
on_color: 'success',
|
||||
off_color: 'warning',
|
||||
on_text: 'Yes',
|
||||
off_text: 'No' }
|
||||
- else
|
||||
%i.fa.fa-check
|
||||
%td
|
||||
.btn-group{role: "group"}
|
||||
= link_to 'Edit', edit_admin_conference_program_track_path(@conference.short_title, track.short_name),
|
||||
|
|
|
|||
17
app/views/tracks/_form.html.haml
Normal file
17
app/views/tracks/_form.html.haml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
.container
|
||||
.row
|
||||
.col-md-12
|
||||
.page-header
|
||||
%h1
|
||||
- if @track.new_record?
|
||||
New
|
||||
= @track.name
|
||||
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.short_name))) 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 :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' }
|
||||
43
app/views/tracks/index.html.haml
Normal file
43
app/views/tracks/index.html.haml
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
.container
|
||||
.row
|
||||
.col-md-12.page-header
|
||||
%h1
|
||||
Track requests for
|
||||
%span.notranslate
|
||||
= @conference.title
|
||||
|
||||
- if @tracks.any?
|
||||
.row
|
||||
.col-md-12
|
||||
%table.table.table-hover#tracks
|
||||
%thead
|
||||
%th Name
|
||||
%th Short name
|
||||
%th Description
|
||||
%th Color
|
||||
%th State
|
||||
%th Actions
|
||||
%tbody
|
||||
- @tracks.each do |track|
|
||||
%tr
|
||||
%td
|
||||
= link_to(conference_program_track_path(@conference.short_title, track.short_name)) do
|
||||
= track.name
|
||||
%td
|
||||
= track.short_name
|
||||
%td
|
||||
%p
|
||||
= truncate(track.description)
|
||||
%td
|
||||
%span.label{style: "background-color: #{track.color}; color: #{ contrast_color(track.color) }"}
|
||||
= track.color
|
||||
%td
|
||||
= track.state
|
||||
%td
|
||||
= link_to 'Edit', edit_conference_program_track_path(@conference.short_title, track.short_name),
|
||||
method: :get, class: 'btn btn-primary'
|
||||
|
||||
.row
|
||||
.col-md-12
|
||||
- if can? :create, @track
|
||||
= link_to "New Track request", new_conference_program_track_path(@conference.short_title), class: 'btn btn-success pull-right'
|
||||
26
app/views/tracks/show.html.haml
Normal file
26
app/views/tracks/show.html.haml
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
.container
|
||||
.row
|
||||
.col-md-12
|
||||
.page-header
|
||||
%h1
|
||||
= @track.name
|
||||
Track
|
||||
.row
|
||||
.col-md-8
|
||||
%dl.dl-horizontal
|
||||
%dt
|
||||
Color:
|
||||
%dd
|
||||
%span.label{style: "background-color: #{@track.color}; color: #{ contrast_color(@track.color) }"}
|
||||
= @track.color
|
||||
%dt
|
||||
State:
|
||||
%dd
|
||||
= @track.state
|
||||
%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.short_name), class: 'btn btn-primary'
|
||||
|
|
@ -54,7 +54,11 @@ Osem::Application.routes.draw do
|
|||
resource :registration_period
|
||||
resource :program do
|
||||
resources :cfps
|
||||
resources :tracks
|
||||
resources :tracks do
|
||||
member do
|
||||
patch :toggle_cfp_inclusion
|
||||
end
|
||||
end
|
||||
resources :event_types
|
||||
resources :difficulty_levels
|
||||
resources :events do
|
||||
|
|
@ -82,9 +86,15 @@ Osem::Application.routes.draw do
|
|||
resources :campaigns, except: [:show]
|
||||
resources :emails, only: [:show, :update, :index]
|
||||
resources :physical_ticket, only: [:index]
|
||||
resources :roles, except: [ :new, :create ] do
|
||||
resources :roles, only: [:edit]
|
||||
resources :roles, except: [ :new, :create, :edit ] do
|
||||
member do
|
||||
post :toggle_user
|
||||
get ':track_name' => 'roles#show', as: 'track'
|
||||
get ':track_name/edit' => 'roles#edit', as: 'track_edit'
|
||||
patch ':track_name' => 'roles#update'
|
||||
put ':track_name' => 'roles#update'
|
||||
post ':track_name/toggle_user' => 'roles#toggle_user', as: 'toggle_user_track'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -120,6 +130,7 @@ Osem::Application.routes.draw do
|
|||
patch '/restart' => 'proposals#restart'
|
||||
end
|
||||
end
|
||||
resources :tracks, except: :destroy
|
||||
end
|
||||
|
||||
# TODO: change conference_registrations to singular resource
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
class AddStateCfpActiveAndSubmitterReferenceToTracks < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :tracks, :state, :string
|
||||
add_column :tracks, :cfp_active, :boolean
|
||||
add_column :tracks, :submitter_id, :integer
|
||||
add_index :tracks, :submitter_id
|
||||
end
|
||||
end
|
||||
|
|
@ -491,8 +491,13 @@ ActiveRecord::Schema.define(version: 20170711102511) do
|
|||
t.datetime "updated_at"
|
||||
t.integer "program_id"
|
||||
t.string "short_name", null: false
|
||||
t.string "state"
|
||||
t.boolean "cfp_active"
|
||||
t.integer "submitter_id"
|
||||
end
|
||||
|
||||
add_index "tracks", ["submitter_id"], name: "index_tracks_on_submitter_id"
|
||||
|
||||
create_table "users", force: :cascade do |t|
|
||||
t.string "email", default: "", null: false
|
||||
t.string "encrypted_password", default: "", null: false
|
||||
|
|
|
|||
|
|
@ -5,5 +5,11 @@ FactoryGirl.define do
|
|||
color { Faker::Color.hex_color }
|
||||
short_name { SecureRandom.urlsafe_base64(5) }
|
||||
program
|
||||
|
||||
trait :self_organized do
|
||||
association :submitter, factory: :user
|
||||
state 'new'
|
||||
cfp_active false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
244
spec/features/track_organizer_ability_spec.rb
Normal file
244
spec/features/track_organizer_ability_spec.rb
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
require 'spec_helper'
|
||||
|
||||
feature 'Has correct abilities' do
|
||||
|
||||
let(:organization) { create(:organization) }
|
||||
let(:conference) { create(:full_conference, organization: organization) }
|
||||
let(:self_organized_track) { create(:track, :self_organized, program: conference.program) }
|
||||
let(:role_track_organizer) { Role.find_by(name: 'track_organizer', resource: self_organized_track) }
|
||||
let(:user_track_organizer) { create(:user, role_ids: [role_track_organizer.id]) }
|
||||
|
||||
context 'when user is info desk' do
|
||||
before do
|
||||
sign_in user_track_organizer
|
||||
end
|
||||
|
||||
scenario 'for organization and conference attributes' do
|
||||
visit admin_conference_path(conference.short_title)
|
||||
expect(current_path).to eq(admin_conference_path(conference.short_title))
|
||||
|
||||
expect(page).to have_selector('li.nav-header.nav-header-bigger a', text: 'Dashboard')
|
||||
expect(page).to_not have_link('Basics', href: "/admin/conferences/#{conference.short_title}/edit")
|
||||
expect(page).to have_text('Basics')
|
||||
expect(page).to_not have_link('Contact', href: "/admin/conferences/#{conference.short_title}/contact/edit")
|
||||
expect(page).to have_link('Commercials', href: "/admin/conferences/#{conference.short_title}/commercials")
|
||||
expect(page).to_not have_link('Splashpage', href: "/admin/conferences/#{conference.short_title}/splashpage")
|
||||
expect(page).to_not have_link('Venue', href: "/admin/conferences/#{conference.short_title}/venue")
|
||||
expect(page).to_not have_link('Rooms', href: "/admin/conferences/#{conference.short_title}/venue/rooms")
|
||||
expect(page).to_not have_link('Lodgings', href: "/admin/conferences/#{conference.short_title}/lodgings")
|
||||
expect(page).to have_link('Program', href: "/admin/conferences/#{conference.short_title}/program")
|
||||
expect(page).to_not have_link('Call for Papers', href: "/admin/conferences/#{conference.short_title}/program/cfps")
|
||||
expect(page).to_not have_link('Events', href: "/admin/conferences/#{conference.short_title}/program/events")
|
||||
expect(page).to have_link('Tracks', href: "/admin/conferences/#{conference.short_title}/program/tracks")
|
||||
expect(page).to_not have_link('Event Types', href: "/admin/conferences/#{conference.short_title}/program/event_types")
|
||||
expect(page).to_not have_link('Difficulty Levels', href: "/admin/conferences/#{conference.short_title}/program/difficulty_levels")
|
||||
expect(page).to_not have_link('Schedules', href: "/admin/conferences/#{conference.short_title}/schedules")
|
||||
expect(page).to_not have_link('Reports', href: "/admin/conferences/#{conference.short_title}/program/reports")
|
||||
expect(page).to_not have_link('Registrations', href: "/admin/conferences/#{conference.short_title}/registrations")
|
||||
expect(page).to_not have_link('Registration Period', href: "/admin/conferences/#{conference.short_title}/registration_period")
|
||||
expect(page).to_not have_link('Questions', href: "/admin/conferences/#{conference.short_title}/questions")
|
||||
expect(page).to_not have_text('Donations')
|
||||
expect(page).to_not have_link('Sponsorship Levels', href: "/admin/conferences/#{conference.short_title}/sponsorship_levels")
|
||||
expect(page).to_not have_link('Sponsors', href: "/admin/conferences/#{conference.short_title}/sponsors")
|
||||
expect(page).to_not have_link('Tickets', href: "/admin/conferences/#{conference.short_title}/tickets")
|
||||
expect(page).to_not have_text('Objectives')
|
||||
expect(page).to_not have_link('Campaigns', href: "/admin/conferences/#{conference.short_title}/campaigns")
|
||||
expect(page).to_not have_link('Goals', href: "/admin/conferences/#{conference.short_title}/targets")
|
||||
expect(page).to_not have_link('E-Mails', href: "/admin/conferences/#{conference.short_title}/emails")
|
||||
expect(page).to have_link('Roles', href: "/admin/conferences/#{conference.short_title}/roles")
|
||||
expect(page).to_not have_link('Resources', href: "/admin/conferences/#{conference.short_title}/resources")
|
||||
expect(page).to_not have_link('New Conference', href: '/admin/conferences/new')
|
||||
|
||||
visit edit_admin_conference_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit edit_admin_conference_contact_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit admin_conference_commercials_path(conference.short_title)
|
||||
expect(current_path).to eq admin_conference_commercials_path(conference.short_title)
|
||||
|
||||
visit new_admin_conference_splashpage_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit edit_admin_conference_splashpage_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit new_admin_conference_venue_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
conference.venue = create(:venue)
|
||||
visit edit_admin_conference_venue_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit admin_conference_venue_rooms_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
create(:room, venue: conference.venue)
|
||||
visit edit_admin_conference_venue_room_path(conference.short_title, conference.venue.rooms.first)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit admin_conference_lodgings_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit new_admin_conference_lodging_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
create(:lodging, conference: conference)
|
||||
visit edit_admin_conference_lodging_path(conference.short_title, conference.lodgings.first)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit new_admin_conference_program_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit edit_admin_conference_program_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit new_admin_conference_program_cfp_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit edit_admin_conference_program_cfp_path(conference.short_title, conference.program.cfp)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit admin_conference_program_events_path(conference.short_title)
|
||||
expect(current_path).to eq admin_conference_program_events_path(conference.short_title)
|
||||
|
||||
create(:event, program: conference.program)
|
||||
visit edit_admin_conference_program_event_path(conference.short_title, conference.program.events.first)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit admin_conference_program_event_types_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit new_admin_conference_program_event_type_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit edit_admin_conference_program_event_type_path(conference.short_title, conference.program.event_types.first)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit admin_conference_program_difficulty_levels_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit new_admin_conference_program_difficulty_level_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit edit_admin_conference_program_difficulty_level_path(conference.short_title, conference.program.difficulty_levels.first)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit admin_conference_schedules_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
create(:schedule, program: conference.program)
|
||||
visit admin_conference_schedule_path(conference.short_title, conference.program.schedules.first)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit admin_conference_program_reports_path(conference.short_title)
|
||||
expect(current_path).to eq admin_conference_program_reports_path(conference.short_title)
|
||||
|
||||
visit admin_conference_registrations_path(conference.short_title)
|
||||
expect(current_path).to eq admin_conference_registrations_path(conference.short_title)
|
||||
|
||||
create(:registration, user: create(:user), conference: conference)
|
||||
visit edit_admin_conference_registration_path(conference.short_title, conference.registrations.first)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit new_admin_conference_registration_period_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
create(:registration_period, conference: conference)
|
||||
visit edit_admin_conference_registration_period_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit admin_conference_questions_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit admin_conference_sponsorship_levels_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit new_admin_conference_sponsorship_level_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
create(:sponsorship_level, conference: conference)
|
||||
visit edit_admin_conference_sponsorship_level_path(conference.short_title, conference.sponsorship_levels.first)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit admin_conference_sponsors_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit new_admin_conference_sponsor_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
create(:sponsor, conference: conference, sponsorship_level: conference.sponsorship_levels.first)
|
||||
visit edit_admin_conference_sponsor_path(conference.short_title, conference.sponsors.first)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit admin_conference_tickets_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit new_admin_conference_ticket_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
create(:ticket, conference: conference)
|
||||
visit edit_admin_conference_ticket_path(conference.short_title, conference.tickets.first)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit admin_conference_campaigns_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit new_admin_conference_campaign_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
create(:campaign, conference: conference)
|
||||
visit edit_admin_conference_campaign_path(conference.short_title, conference.campaigns.first)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit admin_conference_targets_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit new_admin_conference_target_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
create(:target, conference: conference)
|
||||
visit edit_admin_conference_target_path(conference.short_title, conference.targets.first)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit admin_conference_program_tracks_path(conference.short_title)
|
||||
expect(current_path).to eq admin_conference_program_tracks_path(conference.short_title)
|
||||
|
||||
visit new_admin_conference_program_track_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
other_track = create(:track, program: conference.program)
|
||||
visit admin_conference_program_track_path(conference.short_title, other_track.short_name)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit edit_admin_conference_program_track_path(conference.short_title, other_track.short_name)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit admin_conference_program_track_path(conference.short_title, self_organized_track.short_name)
|
||||
expect(current_path).to eq admin_conference_program_track_path(conference.short_title, self_organized_track.short_name)
|
||||
|
||||
visit edit_admin_conference_program_track_path(conference.short_title, self_organized_track.short_name)
|
||||
expect(current_path).to eq edit_admin_conference_program_track_path(conference.short_title, self_organized_track.short_name)
|
||||
|
||||
visit admin_conference_roles_path(conference.short_title)
|
||||
expect(current_path).to eq admin_conference_roles_path(conference.short_title)
|
||||
|
||||
visit admin_conference_emails_path(conference.short_title)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit admin_conference_resources_path(conference.short_title)
|
||||
expect(current_path).to eq admin_conference_resources_path(conference.short_title)
|
||||
|
||||
visit new_admin_conference_resource_path(conference.short_title)
|
||||
expect(current_path).to eq new_admin_conference_resource_path(conference.short_title)
|
||||
|
||||
create(:resource, conference: conference)
|
||||
visit edit_admin_conference_resource_path(conference.short_title, conference.resources.first)
|
||||
expect(current_path).to eq root_path
|
||||
|
||||
visit admin_revision_history_path
|
||||
expect(current_path).to eq root_path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -44,6 +44,8 @@ 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) }
|
||||
|
||||
context 'user #is_admin?' do
|
||||
let(:venue) { my_conference.venue }
|
||||
let(:room) { create(:room, venue: venue) }
|
||||
|
|
@ -69,6 +71,19 @@ describe 'User with admin role' do
|
|||
it{ should be_able_to(:show, Role.find_by(name: role, resource: other_conference)) }
|
||||
it{ should be_able_to(:index, Role.find_by(name: role, resource: other_conference)) }
|
||||
end
|
||||
|
||||
context 'accesses track organizers' do
|
||||
before :each do
|
||||
other_self_organized_track = create(:track, :self_organized)
|
||||
@other_track_organizer_role = Role.find_by(name: 'track_organizer', resource: other_self_organized_track)
|
||||
end
|
||||
|
||||
it{ should_not be_able_to(:toggle_user, @other_track_organizer_role) }
|
||||
it{ should_not be_able_to(:update, @other_track_organizer_role) }
|
||||
it{ should_not be_able_to(:edit, @other_track_organizer_role) }
|
||||
it{ should be_able_to(:show, @other_track_organizer_role) }
|
||||
it{ should be_able_to(:index, @other_track_organizer_role) }
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'user with non-organizer role' do |role_name|
|
||||
|
|
@ -83,6 +98,22 @@ describe 'User with admin role' do
|
|||
it{ should be_able_to(:show, Role.find_by(name: role, resource: my_conference)) }
|
||||
it{ should be_able_to(:index, Role.find_by(name: role, resource: my_conference)) }
|
||||
end
|
||||
|
||||
context 'accesses track organizers' do
|
||||
before :each do
|
||||
@track_organizer_role = Role.find_by(name: 'track_organizer', resource: my_self_organized_track)
|
||||
end
|
||||
|
||||
if role_name == 'track_organizer'
|
||||
it{ should be_able_to(:toggle_user, @track_organizer_role) }
|
||||
else
|
||||
it{ should_not be_able_to(:toggle_user, @track_organizer_role) }
|
||||
end
|
||||
it{ should_not be_able_to(:update, @track_organizer_role) }
|
||||
it{ should_not be_able_to(:edit, @track_organizer_role) }
|
||||
it{ should be_able_to(:show, @track_organizer_role) }
|
||||
it{ should be_able_to(:index, @track_organizer_role) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user has the role organization_admin' do
|
||||
|
|
@ -186,6 +217,18 @@ describe 'User with admin role' do
|
|||
it{ should be_able_to(:index, Role.find_by(name: role, resource: my_conference)) }
|
||||
end
|
||||
|
||||
context 'can manage track organizers' do
|
||||
before :each do
|
||||
@track_organizer_role = Role.find_by(name: 'track_organizer', resource: my_self_organized_track)
|
||||
end
|
||||
|
||||
it{ should be_able_to(:toggle_user, @track_organizer_role) }
|
||||
it{ should be_able_to(:edit, @track_organizer_role) }
|
||||
it{ should be_able_to(:update, @track_organizer_role) }
|
||||
it{ should be_able_to(:show, @track_organizer_role) }
|
||||
it{ should be_able_to(:index, @track_organizer_role) }
|
||||
end
|
||||
|
||||
it_behaves_like 'user with any role'
|
||||
end
|
||||
|
||||
|
|
@ -392,5 +435,74 @@ describe 'User with admin role' do
|
|||
it_behaves_like 'user with any role'
|
||||
it_behaves_like 'user with non-organizer role', 'volunteers_coordinator'
|
||||
end
|
||||
|
||||
context 'when user has the role track_organizer' do
|
||||
let(:role) { Role.find_by(name: 'track_organizer', resource: my_self_organized_track) }
|
||||
let(:user) { create(:user, role_ids: [role.id]) }
|
||||
let(:new_track) { build(:track, program: my_conference.program) }
|
||||
|
||||
it{ should_not be_able_to(:new, Conference.new) }
|
||||
it{ should_not be_able_to(:create, Conference.new) }
|
||||
it{ should_not be_able_to(:manage, my_conference) }
|
||||
it{ should_not be_able_to(:manage, conference_public) }
|
||||
it{ should_not be_able_to(:manage, my_conference.splashpage) }
|
||||
it{ should_not be_able_to(:manage, conference_public.splashpage) }
|
||||
it{ should_not be_able_to(:manage, my_conference.contact) }
|
||||
it{ should_not be_able_to(:manage, conference_public.contact) }
|
||||
it{ should_not be_able_to(:manage, my_conference.email_settings) }
|
||||
it{ should_not be_able_to(:manage, conference_public.email_settings) }
|
||||
it{ should_not be_able_to(:manage, my_conference.campaigns.first) }
|
||||
it{ should_not be_able_to(:manage, conference_public.campaigns.first) }
|
||||
it{ should_not be_able_to(:manage, my_conference.targets.first) }
|
||||
it{ should_not be_able_to(:manage, conference_public.targets.first) }
|
||||
it{ should_not be_able_to(:manage, my_conference.commercials.first) }
|
||||
it{ should_not be_able_to(:manage, conference_public.commercials.first) }
|
||||
it{ should_not be_able_to(:manage, my_conference.registration_period) }
|
||||
it{ should_not be_able_to(:manage, conference_public.registration_period) }
|
||||
it{ should_not be_able_to(:manage, my_conference.questions.first) }
|
||||
it{ should_not be_able_to(:manage, conference_public.questions.first) }
|
||||
it{ should_not be_able_to(:manage, my_conference.program.cfp) }
|
||||
it{ should_not be_able_to(:manage, conference_public.program.cfp) }
|
||||
it{ should_not be_able_to(:manage, my_schedule) }
|
||||
it{ should_not be_able_to(:manage, other_schedule) }
|
||||
it{ should_not be_able_to(:manage, my_event_schedule) }
|
||||
it{ should_not be_able_to(:manage, other_event_schedule) }
|
||||
it{ should_not be_able_to(:manage, my_conference.venue) }
|
||||
it{ should_not be_able_to(:show, my_conference.venue) }
|
||||
it{ should_not be_able_to(:manage, conference_public.venue) }
|
||||
it{ should_not be_able_to(:manage, my_conference.lodgings.first) }
|
||||
it{ should_not be_able_to(:manage, conference_public.lodgings.first) }
|
||||
it{ should_not be_able_to(:manage, my_conference.sponsors.first) }
|
||||
it{ should_not be_able_to(:manage, conference_public.sponsors.first) }
|
||||
it{ should_not be_able_to(:manage, my_conference.sponsorship_levels.first) }
|
||||
it{ should_not be_able_to(:manage, conference_public.sponsorship_levels.first) }
|
||||
it{ should_not be_able_to(:manage, my_conference.tickets.first) }
|
||||
it{ should_not be_able_to(:manage, conference_public.tickets.first) }
|
||||
|
||||
it{ should_not be_able_to(:manage, registration) }
|
||||
it{ should_not be_able_to(:manage, other_registration) }
|
||||
|
||||
it{ should_not be_able_to(:manage, my_event) }
|
||||
it{ should_not be_able_to(:manage, other_event) }
|
||||
it{ should_not be_able_to(:manage, my_event.event_type) }
|
||||
it{ should_not be_able_to(:manage, other_event.event_type) }
|
||||
it{ should_not be_able_to(:manage, my_event.track) }
|
||||
it{ should_not be_able_to(:manage, other_event.track) }
|
||||
it{ should_not be_able_to(:manage, my_event.difficulty_level) }
|
||||
it{ should_not be_able_to(:manage, other_event.difficulty_level) }
|
||||
it{ should_not be_able_to(:manage, my_event.commercials.first) }
|
||||
it{ should_not be_able_to(:manage, other_event.commercials.first) }
|
||||
it{ should_not be_able_to(:index, my_event.comment_threads.first) }
|
||||
it{ should_not be_able_to(:index, other_event.comment_threads.first) }
|
||||
|
||||
it{ should_not be_able_to(:manage, resource) }
|
||||
|
||||
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_behaves_like 'user with any role'
|
||||
it_behaves_like 'user with non-organizer role', 'track_organizer'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
57
spec/models/track_spec.rb
Normal file
57
spec/models/track_spec.rb
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Track do
|
||||
subject { create(:track) }
|
||||
let(:track) { create(:track) }
|
||||
let(:self_organized_track) { create(:track, :self_organized) }
|
||||
|
||||
describe 'association' do
|
||||
it { is_expected.to belong_to(:program) }
|
||||
it { is_expected.to belong_to(:submitter).class_name('User') }
|
||||
it { is_expected.to have_many(:events) }
|
||||
end
|
||||
|
||||
describe 'validation' do
|
||||
it 'has a valid factory' do
|
||||
expect(build(:track)).to be_valid
|
||||
end
|
||||
|
||||
it { is_expected.to validate_presence_of(:name) }
|
||||
it { is_expected.to allow_value('#ABCDEF').for(:color) }
|
||||
it { is_expected.to allow_value('#124689').for(:color) }
|
||||
it { is_expected.to validate_presence_of(: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 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_inclusion_of(:cfp_active).in_array([true, false]) }
|
||||
end
|
||||
|
||||
context 'when regular' do
|
||||
before :each do
|
||||
allow(subject).to receive(:self_organized?).and_return(false)
|
||||
end
|
||||
|
||||
it { is_expected.to_not validate_presence_of(:state) }
|
||||
it { is_expected.to_not validate_inclusion_of(:cfp_active) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#self_organized?' do
|
||||
it 'returns true when it has a submitter' do
|
||||
expect(self_organized_track.submitter).to be_a User
|
||||
expect(self_organized_track.self_organized?).to eq true
|
||||
end
|
||||
|
||||
it 'returns false when it doesn\'t have a submitter' do
|
||||
expect(track.submitter).to eq nil
|
||||
expect(track.self_organized?).to eq false
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue