From ccd7ecbb902a0e4799ca5b7b9dee1bca89d598d5 Mon Sep 17 00:00:00 2001 From: Stella Date: Mon, 12 Jan 2015 23:13:10 +0200 Subject: [PATCH] Roles into their own controller. Rework interface. Add flash messages to ajax calls. Add description to roles. Possible to edit roles in use. --- .rubocop_todo.yml | 2 + Gemfile | 3 + Gemfile.lock | 6 +- app/assets/javascripts/application.js | 2 + .../admin/conference_controller.rb | 44 +----- app/controllers/admin/roles_controller.rb | 87 +++++++++++ app/helpers/application_helper.rb | 4 + app/models/ability.rb | 65 +++++++- app/models/conference.rb | 15 +- app/models/role.rb | 7 +- app/models/user.rb | 6 +- app/views/admin/conference/_roles.html.haml | 29 ---- app/views/admin/conference/roles.html.haml | 22 --- app/views/admin/conference/roles.js.erb | 1 - app/views/admin/roles/_form.html.haml | 15 ++ app/views/admin/roles/_users.html.haml | 20 +++ app/views/admin/roles/index.html.haml | 31 ++++ app/views/admin/roles/show.html.haml | 27 ++++ app/views/admin/roles/toggle_user.js.erb | 1 + app/views/layouts/_admin_sidebar.html.haml | 46 +++--- .../layouts/_admin_sidebar_index.html.haml | 2 +- config/routes.rb | 11 +- .../admin/comments_controller_spec.rb | 2 +- .../admin/conferences_controller_spec.rb | 139 ++---------------- .../admin/programs_controller_spec.rb | 2 +- .../registration_periods_controller_spec.rb | 2 +- .../admin/roles_controller_spec.rb | 137 +++++++++++++++++ spec/factories/conferences.rb | 7 + spec/factories/roles.rb | 1 + spec/factories/users.rb | 4 - spec/features/ability_spec.rb | 20 ++- spec/features/base_controller_spec.rb | 17 +-- spec/features/campaign_spec.rb | 2 +- spec/features/cfp_spec.rb | 2 +- spec/features/commercials_spec.rb | 2 +- spec/features/conference_spec.rb | 2 +- spec/features/contact_spec.rb | 2 +- spec/features/difficulty_levels_spec.rb | 2 +- spec/features/email_spec.rb | 2 +- spec/features/event_types_spec.rb | 2 +- spec/features/lodgings_spec.rb | 2 +- spec/features/program_spec.rb | 2 +- spec/features/proposal_spec.rb | 2 +- spec/features/registration_periods_spec.rb | 2 +- spec/features/rooms_spec.rb | 2 +- spec/features/splashpage_spec.rb | 4 +- spec/features/sponsor_spec.rb | 2 +- spec/features/sponsorship_level_spec.rb | 2 +- spec/features/tickets_spec.rb | 2 +- spec/features/tracks_spec.rb | 2 +- spec/features/venues_spec.rb | 2 +- spec/features/volunteers_spec.rb | 2 +- spec/models/ability_spec.rb | 12 +- spec/models/conference_spec.rb | 6 +- spec/models/role_spec.rb | 14 ++ spec/models/user_spec.rb | 28 ++-- .../admin/conference/roles.html.haml_spec.rb | 26 ---- .../views/admin/roles/index.html.haml_spec.rb | 41 ++++++ spec/views/admin/roles/show.html.haml_spec.rb | 28 ++++ 59 files changed, 618 insertions(+), 356 deletions(-) create mode 100644 app/controllers/admin/roles_controller.rb delete mode 100644 app/views/admin/conference/_roles.html.haml delete mode 100644 app/views/admin/conference/roles.html.haml delete mode 100644 app/views/admin/conference/roles.js.erb create mode 100644 app/views/admin/roles/_form.html.haml create mode 100644 app/views/admin/roles/_users.html.haml create mode 100644 app/views/admin/roles/index.html.haml create mode 100644 app/views/admin/roles/show.html.haml create mode 100644 app/views/admin/roles/toggle_user.js.erb create mode 100644 spec/controllers/admin/roles_controller_spec.rb create mode 100644 spec/models/role_spec.rb delete mode 100644 spec/views/admin/conference/roles.html.haml_spec.rb create mode 100644 spec/views/admin/roles/index.html.haml_spec.rb create mode 100644 spec/views/admin/roles/show.html.haml_spec.rb diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index a42515c3..e81bc65c 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -41,6 +41,8 @@ Metrics/MethodLength: # Configuration parameters: CountComments. Metrics/ModuleLength: Max: 256 + Exclude: + - 'app/helpers/application_helper.rb' # Offense count: 7 Metrics/PerceivedComplexity: diff --git a/Gemfile b/Gemfile index c7f6a766..ae7b2bd2 100644 --- a/Gemfile +++ b/Gemfile @@ -32,6 +32,9 @@ gem 'cancancan' # to set roles gem 'rolify' +# to show flash messages from ajax requests +gem 'unobtrusive_flash', '>=3' + # as state machine gem 'transitions', :require => %w( transitions active_record/transitions ) diff --git a/Gemfile.lock b/Gemfile.lock index 8a6cc996..89ced18a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -455,6 +455,8 @@ GEM execjs (>= 0.3.0) json (>= 1.8.0) unicode-display_width (0.3.1) + unobtrusive_flash (3.1.0) + railties user_agent_parser (2.1.5) uuidtools (2.1.5) warden (1.2.4) @@ -552,8 +554,6 @@ DEPENDENCIES transitions turbolinks uglifier (>= 1.3.0) + unobtrusive_flash (>= 3) web-console (~> 2.0) whenever - -BUNDLED WITH - 1.11.2 diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 98c9fbb1..54421c7b 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -37,6 +37,8 @@ //= require osem-switch //= require osem-bootstrap //= require osem-commercials +//= require unobtrusive_flash +//= require unobtrusive_flash_bootstrap $(document).ready(function() { $('a[disabled=disabled]').click(function(event){ diff --git a/app/controllers/admin/conference_controller.rb b/app/controllers/admin/conference_controller.rb index 4ef6b883..1c1045e9 100644 --- a/app/controllers/admin/conference_controller.rb +++ b/app/controllers/admin/conference_controller.rb @@ -66,13 +66,15 @@ module Admin def create @conference = Conference.new(conference_params) - if @conference.valid? - @conference.save + if @conference.save + flash[:notice] = 'Conference was successfully created.' + # user that creates the conference becomes organizer of that conference current_user.add_role :organizer, @conference - redirect_to(admin_conference_path(id: @conference.short_title), - notice: 'Conference was successfully created.') + + redirect_to admin_conference_path(id: @conference.short_title) else + flash[:error] = 'Could not create conference. ' + @conference.errors.full_messages.to_sentence render action: 'new' end end @@ -173,31 +175,6 @@ module Admin end end - def roles - @user = User.new - @roles = Role::ACTIONABLES + Role::LABELS - - params[:user] ? (@selection = params[:user][:roles].parameterize.underscore) : (@selection = 'organizer') - @role_users = get_users(@selection) - end - - def add_user - @user = User.find_by(email: params[:user][:email]) - @selection = params[:role] - @user.add_role @selection, @conference - - @role_users = get_users(@selection) - render 'roles', formats: [:js] - end - - def remove_user - @selection = params[:role] - @user.revoke @selection, @conference - - @role_users = get_users(@selection) - render 'roles', formats: [:js] - end - private def conference_params @@ -213,14 +190,5 @@ module Admin :photos_attributes, :targets, :targets_attributes, :campaigns, :campaigns_attributes, :registration_limit) end - - def get_users(role_name) - @role_users = {} - # Initialize @role variable, so that view can show the role description - @role = Role.where(name: role_name, resource: @conference) - @role.blank? ? @role_users[role_name] = @role : @role_users[role_name] = @role.first.users - - @role_users - end end end diff --git a/app/controllers/admin/roles_controller.rb b/app/controllers/admin/roles_controller.rb new file mode 100644 index 00000000..d99a1b96 --- /dev/null +++ b/app/controllers/admin/roles_controller.rb @@ -0,0 +1,87 @@ +module Admin + class RolesController < Admin::BaseController + load_and_authorize_resource :conference, find_by: :short_title + before_action :set_selection + # Show flash message with ajax calls + after_action :prepare_unobtrusive_flash, only: :toggle_user + + def index + @roles = Role.where(resource: @conference) + end + + def show + @users = @role.users + end + + def edit + @users = @role.users + end + + def update + role_name = @role.name + + if @role.update_attributes(role_params) + flash[:notice] = 'Successfully updated role ' + @role.name + redirect_to admin_conference_role_path(@conference.short_title, @role.name) + else + @role.name = role_name + flash[:error] = 'Could not update role! ' + @role.errors.full_messages.to_sentence + render :edit + end + end + + def toggle_user + user = User.find_by(email: user_params[:email]) + state = user_params[:state] + + unless user + flash[:error] = 'Could not find user. Please provide a valid email!' + redirect_to(admin_conference_role_path(@conference.short_title, @role.name)) && return + end + + # The conference must have at least 1 organizer + if @role.name == 'organizer' && state == 'false' && @role.users.count == 1 + flash[:error] = 'The conference must have at least 1 organizer!' + redirect_to(admin_conference_role_path(@conference.short_title, @role.name)) && return + end + + # Remove user + if state == 'false' + if user.remove_role @role.name, @conference + 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 + flash[:error] = "User #{user.email} already has the role #{@role.name}" + # Add user + elsif user.add_role @role.name, @conference + flash[:notice] = "Successfully added role #{@role.name} to user #{user.email}" + else + flash[:error] = "Coud not add role #{@role.name} to #{user.email}" + end + + respond_to do |format| + format.js + format.html { redirect_to admin_conference_role_path(@conference.short_title, @role.name) } + end + end + + protected + + def set_selection + # Set 'organizer' as default role, when there is no other selection + @selection = params[:id] ? params[:id].parameterize.underscore : 'organizer' + + @role = Role.find_by(name: @selection, resource: @conference) + end + + def role_params + params.require(:role).permit(:name, :description, user_ids: []) + end + + def user_params + params.require(:user).permit(:email, :state) + end + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 35f127b9..ce2fde95 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -37,6 +37,10 @@ module ApplicationHelper end end + def format_role(role) + role.parameterize.underscore + end + def target_progress_color(progress) progress = progress.to_i result = diff --git a/app/models/ability.rb b/app/models/ability.rb index 58cbed92..16313da9 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -19,15 +19,11 @@ class Ability # This is what sets up the different abilities if user.new_record? not_signed_in + # Checks if the user does not have any role and is not an admin + elsif user.roles.any? || user.is_admin + signed_in_with_roles(user) else - # This maps the actionables name of the role to its name in the DB. - roles = Role::ACTIONABLES.map {|i| i.parameterize.underscore} - # Checks if the user does not have any role and is not an admin - if (user.roles.pluck(:name) & roles).empty? && !user.is_admin - signed_in(user) - else - signed_in_with_roles(user) - end + signed_in(user) end end @@ -151,6 +147,19 @@ class Ability can :manage, Ticket, conference_id: conf_ids_for_organizer can :index, Comment, commentable_type: 'Event', commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_organizer).pluck(:id)).pluck(:id) + + # Abilities for Role (Conference resource) + can :index, Role + can :manage, Role do |role| + role.resource_type == 'Conference' && (conf_ids_for_organizer.include? role.resource_id) + 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') + can :toggle_user, Role do |role| + role.resource_type == 'Conference' && + (Conference.with_role(role.name.parameterize.underscore.to_sym, user).pluck(:id).include? role.resource_id) + end end def signed_in_with_cfp_role(user) @@ -172,6 +181,20 @@ class Ability commercialable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_cfp).pluck(:id)).pluck(:id) can :index, Comment, commentable_type: 'Event', commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_cfp).pluck(:id)).pluck(:id) + + # Abilities for Role (Conference resource) + can :index, Role + + can :manage, Role do |role| + role.resource_type == 'Conference' && (conf_ids_for_cfp.include? role.resource_id) + 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') + can :toggle_user, Role do |role| + role.resource_type == 'Conference' && + (Conference.with_role(role.name.parameterize.underscore.to_sym, user).pluck(:id).include? role.resource_id) + end end def signed_in_with_info_desk_role(user) @@ -185,6 +208,19 @@ class Ability can :manage, Question do |question| !(question.conferences.pluck(:id) & conf_ids_for_info_desk).empty? end + # Abilities for Role (Conference resource) + can :index, Role + + can :manage, Role do |role| + role.resource_type == 'Conference' && (conf_ids_for_info_desk.include? role.resource_id) + 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') + can :toggle_user, Role do |role| + role.resource_type == 'Conference' && + (Conference.with_role(role.name.parameterize.underscore.to_sym, user).pluck(:id).include? role.resource_id) + end end def signed_in_with_volunteers_coordinator_role(user) @@ -195,5 +231,18 @@ class Ability can :manage, Vposition, conference_id: conf_ids_for_volunteers_coordinator can :manage, Vday, conference_id: conf_ids_for_volunteers_coordinator + # Abilities for Role (Conference resource) + can :index, Role + + can :manage, Role do |role| + role.resource_type == 'Conference' && (conf_ids_for_volunteers_coordinator.include? role.resource_id) + 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') + can :toggle_user, Role do |role| + role.resource_type == 'Conference' && + (Conference.with_role(role.name.parameterize.underscore.to_sym, user).pluck(:id).include? role.resource_id) + end end end diff --git a/app/models/conference.rb b/app/models/conference.rb index ac0a849f..6036a962 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -3,7 +3,8 @@ class Conference < ActiveRecord::Base require 'uri' serialize :events_per_week, Hash - resourcify # Needed to call 'Conference.with_role' in /models/ability.rb + # Needed to call 'Conference.with_role' in /models/ability.rb + resourcify default_scope { order('start_date DESC') } @@ -545,6 +546,18 @@ class Conference < ActiveRecord::Base after_create do self.create_contact self.create_program + create_roles + end + + ## + # Creates the roles of the conference + # after the conference has been successfully created + # Will create 4 new records for roles + def create_roles + Role.where(name: 'organizer', resource: self).first_or_create(description: 'For the organizers of the conference (who shall have full access)') + Role.where(name: 'cfp', resource: self).first_or_create(description: 'For the members of the CfP team') + Role.where(name: 'info_desk', resource: self).first_or_create(description: 'For the members of the Info Desk team') + Role.where(name: 'volunteers_coordinator', resource: self).first_or_create(description: 'For the people in charge of volunteers') end ## diff --git a/app/models/role.rb b/app/models/role.rb index 87bbe62f..77ffac2b 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -1,9 +1,10 @@ class Role < ActiveRecord::Base - has_and_belongs_to_many :users belongs_to :resource, polymorphic: true + has_and_belongs_to_many :users scopify - LABELS = ['Attendee', 'Volunteer', 'Speaker', 'Sponsor', 'Press', 'Keynote Speaker'] - ACTIONABLES = ['Organizer', 'CfP', 'Info Desk', 'Volunteers Coordinator'] + validates :name, presence: true + + validates :name, uniqueness: { scope: :resource } end diff --git a/app/models/user.rb b/app/models/user.rb index 567b0e41..f31beb29 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -128,9 +128,9 @@ class User < ActiveRecord::Base # * +Hash+ * -> e.g. 'organizer' => "(conf1, conf2)" def get_roles result = {} - Role::ACTIONABLES.each do |role| - resources = self.roles.where(name: role.parameterize.underscore).map{ |myrole| Conference.find(myrole.resource_id).short_title }.join ', ' - result[role.parameterize.underscore] = "(#{ resources })" unless resources.blank? + Role.all.find_each do |role| + resources = self.roles.map{ |myrole| Conference.find(myrole.resource_id).short_title }.join ', ' + result[role.name] = "(#{ resources })" unless resources.blank? end result end diff --git a/app/views/admin/conference/_roles.html.haml b/app/views/admin/conference/_roles.html.haml deleted file mode 100644 index 54235af3..00000000 --- a/app/views/admin/conference/_roles.html.haml +++ /dev/null @@ -1,29 +0,0 @@ -#myroles.roles - - unless @role.blank? - %p.text-muted - = @role.first.description - - %hr - .row - .col-md-6 - = semantic_form_for(:user, url: add_user_admin_conference_path(@conference.short_title, role: @selection), remote: true) do |f| - %h4 - = f.input :email, label: "Add role '#{@selection.humanize.titleize}' to user: ", placeholder: "User's email", input_html: { required: 'required' } - = f.action :submit, as: :button, label: 'Add User', button_html: {value: 'Add', class: 'btn btn-primary'} - .row - .col-md-12 - %h3 Users with role #{@selection.humanize.titleize} - %table.table.table-striped.table-bordered.table-hover - %thead - %th ID - %th Name - %th Email - %tbody - - @role_users[@selection].each do |user| - %tr - %td - = link_to remove_user_admin_conference_path(@conference.short_title, user_id: user.id, role: @selection), method: :delete, remote: true, title: 'Remove user' do - %i{class: 'fa fa-times'} - = user.id - %td= user.name - %td= user.email diff --git a/app/views/admin/conference/roles.html.haml b/app/views/admin/conference/roles.html.haml deleted file mode 100644 index a49bb17d..00000000 --- a/app/views/admin/conference/roles.html.haml +++ /dev/null @@ -1,22 +0,0 @@ -.row - .col-md-6 - = semantic_form_for(:user, url: roles_admin_conference_path(@conference.short_title), remote: true) do |f| - %h4 - = f.input :roles, collection: @roles, label: 'Show users for role: ' - -= render partial: 'roles' - -:javascript - - $("#user_roles_input").change(function () { - - var url = document.forms[0].action; - var selected_role = $(this).find('option:selected').attr('value'); - - $.ajax({ - url: url, - type: "POST", - data: {user: { roles: selected_role } }, - dataType: "script" - }); - }); diff --git a/app/views/admin/conference/roles.js.erb b/app/views/admin/conference/roles.js.erb deleted file mode 100644 index 15ac7237..00000000 --- a/app/views/admin/conference/roles.js.erb +++ /dev/null @@ -1 +0,0 @@ -$('#myroles').html("<%= escape_javascript(render partial: 'roles').html_safe %>"); diff --git a/app/views/admin/roles/_form.html.haml b/app/views/admin/roles/_form.html.haml new file mode 100644 index 00000000..eb10b23f --- /dev/null +++ b/app/views/admin/roles/_form.html.haml @@ -0,0 +1,15 @@ +.row + .col-md-12 + .page-header + %h2 + Role + = @role.name.titleize + .text-muted + = @role.description + += semantic_form_for @role, url: admin_conference_role_path(@conference.short_title, @role.name) do |f| + .row + .col-md-5 + = f.input :description + + = f.action :submit, as: :button, button_html: { class: 'btn btn-primary' } diff --git a/app/views/admin/roles/_users.html.haml b/app/views/admin/roles/_users.html.haml new file mode 100644 index 00000000..f73af1b8 --- /dev/null +++ b/app/views/admin/roles/_users.html.haml @@ -0,0 +1,20 @@ +.page-header + %h3 Users (#{users.length}) +- if users.present? + %table.table.table-striped.table-bordered.table-hover.datatable#users + %thead + %th.col-md-1 + %th ID + %th Name + %th Email + %tbody + - users.each do |user| + %tr + %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/conference/#{@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' } + %td= user.id + %td= user.name + %td= user.email +- else + %h5 No users found! diff --git a/app/views/admin/roles/index.html.haml b/app/views/admin/roles/index.html.haml new file mode 100644 index 00000000..d88dc22f --- /dev/null +++ b/app/views/admin/roles/index.html.haml @@ -0,0 +1,31 @@ +.row + .col-md-12.page-header + %h2 + Roles + + .text-muted + The available roles for the conference + + .col-md-12 + %table.table.table-bordered.table-striped.table-hover.datatable#roles + %thead + %th ID + %th Name + %th Description + %th Users + %th Actions + %tbody + - @roles.each do |role| + %tr + %td= role.id + %td= role.name.titleize + %td= role.description + %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 + = 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' diff --git a/app/views/admin/roles/show.html.haml b/app/views/admin/roles/show.html.haml new file mode 100644 index 00000000..69d02f6b --- /dev/null +++ b/app/views/admin/roles/show.html.haml @@ -0,0 +1,27 @@ +.unobtrusive-flash-container +.row + .col-md-12 + .page-header + %h2 + Role + = @role.name.titleize + - if can? :edit, @role + = link_to 'Edit', edit_admin_conference_role_path(@conference.short_title, @role.name), class: 'btn btn-primary pull-right' + .text-muted + = @role.description + +.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| + + = u.label 'Add user by email: ' + .input-group + = u.input :email, label: false, placeholder: "User's email" + .input-group-btn + = u.submit 'Add', id: 'user-add', class: 'btn btn-primary' + +.row + .col-md-12 + #users_area + = render partial: 'users', locals: { users: @users } diff --git a/app/views/admin/roles/toggle_user.js.erb b/app/views/admin/roles/toggle_user.js.erb new file mode 100644 index 00000000..6c67f5c3 --- /dev/null +++ b/app/views/admin/roles/toggle_user.js.erb @@ -0,0 +1 @@ +$(".alert").remove(); diff --git a/app/views/layouts/_admin_sidebar.html.haml b/app/views/layouts/_admin_sidebar.html.haml index 928a0fef..770ba40d 100644 --- a/app/views/layouts/_admin_sidebar.html.haml +++ b/app/views/layouts/_admin_sidebar.html.haml @@ -59,29 +59,31 @@ - if can? :update, @conference.lodgings.build %li{ class: active_nav_li(admin_conference_lodgings_path(@conference.short_title)) } = link_to 'Lodgings', admin_conference_lodgings_path(@conference.short_title) + - if can? :show, @conference.program %li{:class=> "#{active_nav_li(admin_conference_program_path(@conference.short_title))}"} = link_to admin_conference_program_path(@conference.short_title) do %span.fa.fa-calendar Program - %ul - - if can? :update, Cfp.new(program_id: @conference.program.id) - %li{:class=> active_nav_li(admin_conference_program_cfp_path(@conference.short_title))} - = link_to 'Call for Papers', admin_conference_program_cfp_path(@conference.short_title) - - if can? :update, @conference.program.events.build - %li{:class=> active_nav_li(admin_conference_program_events_path(@conference.short_title))} - = link_to 'Events', admin_conference_program_events_path(@conference.short_title) - - if can? :update, @conference.program.tracks.build - %li{:class=> active_nav_li(admin_conference_program_tracks_path(@conference.short_title))} - = link_to 'Tracks', admin_conference_program_tracks_path(@conference.short_title) - - if can? :update, @conference.program.event_types.build - %li{:class=> active_nav_li(admin_conference_program_event_types_path(@conference.short_title))} - = link_to 'Event Types', admin_conference_program_event_types_path(@conference.short_title) - - if can? :update, @conference.program.difficulty_levels.build, conference_id: @conference.id - %li{:class=> active_nav_li(admin_conference_program_difficulty_levels_path(@conference.short_title))} - = link_to 'Difficulty Levels', admin_conference_program_difficulty_levels_path(@conference.short_title) - - if can? :update, @conference.program.events.build - %li{class: active_nav_li(admin_conference_schedule_path(@conference.short_title))} - = link_to 'Schedule', admin_conference_schedule_path(@conference.short_title), target: '_blank' + - if @conference.program + %ul + - if can? :update, Cfp.new(program_id: @conference.program.id) + %li{:class=> active_nav_li(admin_conference_program_cfp_path(@conference.short_title))} + = link_to 'Call for Papers', admin_conference_program_cfp_path(@conference.short_title) + - if can? :update, @conference.program.events.build + %li{:class=> active_nav_li(admin_conference_program_events_path(@conference.short_title))} + = link_to 'Events', admin_conference_program_events_path(@conference.short_title) + - if can? :update, @conference.program.tracks.build + %li{:class=> active_nav_li(admin_conference_program_tracks_path(@conference.short_title))} + = link_to 'Tracks', admin_conference_program_tracks_path(@conference.short_title) + - if can? :update, @conference.program.event_types.build + %li{:class=> active_nav_li(admin_conference_program_event_types_path(@conference.short_title))} + = link_to 'Event Types', admin_conference_program_event_types_path(@conference.short_title) + - if can? :update, @conference.program.difficulty_levels.build, conference_id: @conference.id + %li{:class=> active_nav_li(admin_conference_program_difficulty_levels_path(@conference.short_title))} + = link_to 'Difficulty Levels', admin_conference_program_difficulty_levels_path(@conference.short_title) + - if can? :update, @conference.program.events.build + %li{class: active_nav_li(admin_conference_schedule_path(@conference.short_title))} + = link_to 'Schedule', admin_conference_schedule_path(@conference.short_title), target: '_blank' - if can? :update, Registration.new(conference_id: @conference.id) %li{:class=> active_nav_li(admin_conference_registrations_path(@conference.short_title))} @@ -129,8 +131,8 @@ = link_to(admin_conference_emails_path(@conference.short_title)) do %span.fa.fa-envelope E-Mails - - if can? :manage, @conference - %li{:class=> active_nav_li(roles_admin_conference_path(@conference.short_title))} - = link_to(roles_admin_conference_path(@conference.short_title)) do + - if can? :index, Role.new(resource: @conference) + %li{:class=> active_nav_li(admin_conference_roles_path(@conference.short_title))} + = link_to(admin_conference_roles_path(@conference.short_title)) do %span.fa.fa-group Roles diff --git a/app/views/layouts/_admin_sidebar_index.html.haml b/app/views/layouts/_admin_sidebar_index.html.haml index 352ff877..b7a5e9c6 100644 --- a/app/views/layouts/_admin_sidebar_index.html.haml +++ b/app/views/layouts/_admin_sidebar_index.html.haml @@ -16,7 +16,7 @@ %span.fa.fa-cog Manage = conference.short_title - - if (current_user.is_admin) || (current_user.has_role? :organizer, :any) + - if can? :create, Conference %li = link_to(new_admin_conference_path) do %span.fa.fa-plus diff --git a/config/routes.rb b/config/routes.rb index e7976f1f..1df57cbe 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -17,12 +17,6 @@ Osem::Application.routes.draw do resources :people resources :comments, only: [:index] resources :conference do - member do - get :roles - post :roles - post :add_user - delete :remove_user - end resource :contact, except: [:index, :new, :create, :show, :destroy] resources :photos, except: [:show] resource :schedule, only: [:show, :update] @@ -74,6 +68,11 @@ Osem::Application.routes.draw do resources :targets, except: [:show] resources :campaigns, except: [:show] resources :emails, only: [:show, :update, :index] + resources :roles, except: [ :new, :create ] do + member do + post :toggle_user + end + end resources :sponsorship_levels, except: [:show] do member do diff --git a/spec/controllers/admin/comments_controller_spec.rb b/spec/controllers/admin/comments_controller_spec.rb index 759f1538..6cf3ff9a 100644 --- a/spec/controllers/admin/comments_controller_spec.rb +++ b/spec/controllers/admin/comments_controller_spec.rb @@ -5,7 +5,7 @@ describe Admin::CommentsController, type: :controller do # It is necessary to use bang version of let to build roles before user let(:conference) { create(:conference) } let!(:first_user) { create(:user) } - let!(:organizer_role) { create(:role, name: 'organizer', resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let(:organizer) { create(:user, role_ids: organizer_role.id, last_sign_in_at: Time.now - 1.day) } let(:participant) { create(:user) } let(:event) { create(:event, program: conference.program) } diff --git a/spec/controllers/admin/conferences_controller_spec.rb b/spec/controllers/admin/conferences_controller_spec.rb index fd9f2282..ac3a6b2a 100644 --- a/spec/controllers/admin/conferences_controller_spec.rb +++ b/spec/controllers/admin/conferences_controller_spec.rb @@ -5,7 +5,7 @@ describe Admin::ConferenceController do # It is necessary to use bang version of let to build roles before user let(:conference) { create(:conference, end_date: Date.new(2014, 05, 26) + 15) } let!(:first_user) { create(:user) } - let!(:organizer_role) { create(:role, name: 'organizer', resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let(:organizer) { create(:user, role_ids: organizer_role.id) } let(:organizer2) { create(:user, email: 'organizer2@email.osem', role_ids: organizer_role.id) } @@ -93,6 +93,19 @@ describe Admin::ConferenceController do expect(response).to redirect_to admin_conference_path( assigns[:conference].short_title) end + + it 'creates roles for the conference' do + cfp_role = Role.find_by(name: 'cfp', resource: conference) + info_desk_role = Role.find_by(name: 'info_desk', resource: conference) + volunteers_coordinator_role = Role.find_by(name: 'volunteers_coordinator', resource: conference) + + post :create, conference: + attributes_for(:conference, short_title: 'dps15') + + expect(conference.roles.count).to eq 4 + + expect(conference.roles).to eq [organizer_role, cfp_role, info_desk_role, volunteers_coordinator_role] + end end context 'with invalid attributes' do @@ -203,130 +216,6 @@ describe Admin::ConferenceController do expect(response).to render_template :new end end - - describe 'GET #roles' do - before(:each) do - get :roles, id: conference.short_title - end - - it 'assigns default value to selection' do - expect(assigns(:selection)).to eq('organizer') - end - - it 'finds the correct role' do - expect(assigns(:role)).to eq([organizer_role]) - end - - it 'properly assigns role_users hash' do - expect(assigns(:role_users)).to eq('organizer' => [organizer, organizer2]) - end - - it 'properly assigns roles variable' do - expect(assigns(:roles)).to eq(['Organizer', 'CfP', 'Info Desk', 'Volunteers Coordinator', 'Attendee', 'Volunteer', 'Speaker', 'Sponsor', 'Press', 'Keynote Speaker', ]) - end - end - - describe 'POST #roles' do - before(:each) do - post :roles, id: conference.short_title, user: { roles: 'CfP' } - end - - it 'assigns selected value to selection' do - expect(assigns(:selection)).to eq('cfp') - end - - it 'sets role variable' do - post :roles, id: conference.short_title, user: { roles: 'Organizer' } - role = Role.where(name: 'organizer', resource: conference) - expect(assigns(:role)).to eq(role) - end - - it 'sets role variable (returns blank for nil role)' do - expect(assigns(:role)).to eq([]) - end - - it 'sets role_users hash with blank' do - expect(assigns(:role_users)).to eq('cfp' => []) - end - - it 'sets role_users has with data' do - organizer.add_role :cfp, conference - post :roles, id: conference.short_title, user: { roles: 'CfP' } - expect(assigns(:role_users)).to eq('cfp' => [organizer]) - end - - it 'sets roles variable' do - expect(assigns(:roles)).to eq(['Organizer', 'CfP', 'Info Desk', 'Volunteers Coordinator', 'Attendee', 'Volunteer', 'Speaker', 'Sponsor', 'Press', 'Keynote Speaker', ]) - end - end - - describe 'POST #add_user' do - before(:each) do - @new_user = create(:user, email: 'new_user@email.osem') - post :add_user, id: conference.short_title, user: { email: 'new_user@email.osem' }, role: 'organizer' - end - - it 'finds correct user' do - expect(assigns(:user)).to eq(@new_user) - end - - it 'sets role_users variable' do - expect(assigns(:role_users)).to eq('organizer' => organizer_role.users) - - post :add_user, id: conference.short_title, user: { email: 'new_user@email.osem' }, role: 'cfp' - expect(assigns(:role_users)).to eq('cfp' => [@new_user]) - end - - it 'assigns role to user' do - expect(@new_user.roles).to eq([organizer_role]) - end - - it 'assigns second role to user' do - post :add_user, id: conference.short_title, user: { email: @new_user.email }, role: 'cfp' - cfp_role = Role.find_by(name: 'cfp', resource: conference) - expect(@new_user.roles).to eq([organizer_role, cfp_role]) - end - end - - describe 'DELETE #remove_user' do - before(:each) do - - end - - it 'sets selection variable' do - delete :remove_user, id: conference.short_title, user_id: organizer2.id, role: 'organizer' - expect(assigns(:selection)).to eq('organizer') - end - - it 'sets role_users hash' do - delete :remove_user, id: conference.short_title, user_id: organizer2.id, role: 'organizer' - expect(assigns(:role_users)).to eq('organizer' => [organizer]) - end - - it 'removes role from user' do - delete :remove_user, id: conference.short_title, user_id: organizer2.id, role: 'organizer' - organizer2.reload - expect(organizer2.roles).to eq([]) - end - - it 'removes second role from user' do - # Add cfp role - organizer2.add_role :cfp, conference - cfp_role = Role.find_by(name: 'cfp', resource: conference) - # Remove role organizer - delete :remove_user, id: conference.short_title, user_id: organizer2.id, role: 'organizer' - - organizer2.reload - expect(organizer2.roles).to include(cfp_role) - expect(organizer2.roles[0]).to eq(cfp_role) - expect(organizer2.roles.count).to eq(1) - expect(assigns(:role_users)).to eq('organizer' => [organizer]) - - delete :remove_user, id: conference.short_title, user_id: organizer2.id, role: 'cfp' - organizer2.reload - expect(organizer2.roles).to eq([]) - end - end end describe 'organizer access' do diff --git a/spec/controllers/admin/programs_controller_spec.rb b/spec/controllers/admin/programs_controller_spec.rb index 4fe5952c..f65ad5d5 100644 --- a/spec/controllers/admin/programs_controller_spec.rb +++ b/spec/controllers/admin/programs_controller_spec.rb @@ -5,7 +5,7 @@ describe Admin::ProgramsController, type: :controller do # It is necessary to use bang version of let to build roles before user let(:conference) { create(:conference) } let!(:first_user) { create(:user) } - let!(:organizer_role) { create(:role, name: 'organizer', resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let(:organizer) { create(:user, role_ids: organizer_role.id, last_sign_in_at: Time.now - 1.day) } context 'not logged in user' do diff --git a/spec/controllers/admin/registration_periods_controller_spec.rb b/spec/controllers/admin/registration_periods_controller_spec.rb index 01015ea1..6daf08d8 100644 --- a/spec/controllers/admin/registration_periods_controller_spec.rb +++ b/spec/controllers/admin/registration_periods_controller_spec.rb @@ -5,7 +5,7 @@ describe Admin::RegistrationPeriodsController do # It is necessary to use bang version of let to build roles before user let(:conference) { create(:conference) } let!(:first_user) { create(:user) } - let!(:organizer_role) { create(:role, name: 'organizer', resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let(:organizer) { create(:user, role_ids: organizer_role.id) } let(:organizer2) { create(:user, email: 'organizer2@email.osem', role_ids: organizer_role.id) } diff --git a/spec/controllers/admin/roles_controller_spec.rb b/spec/controllers/admin/roles_controller_spec.rb new file mode 100644 index 00000000..5b9fdb62 --- /dev/null +++ b/spec/controllers/admin/roles_controller_spec.rb @@ -0,0 +1,137 @@ +require 'spec_helper' + +describe Admin::RolesController do + + let(:conference) { create(:conference) } + let!(:first_user) { create(:user) } + let(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } + let(:cfp_role) { Role.find_by(name: 'cfp', resource: conference) } + let(:admin) { create(:admin) } + + let!(:user1) { create(:user, email: 'user1@osem.io') } + let!(:user2) { create(:user, email: 'user2@osem.io') } + + describe 'GET #index' do + before :each do + sign_in(admin) + get :index, conference_id: conference.short_title + end + + it 'assigns default value to selection variable' do + expect(assigns(:selection)).to eq 'organizer' + end + + it 'finds the correct role' do + expect(assigns(:role)).to eq organizer_role + end + end + + describe 'GET #show' do + before :each do + sign_in(admin) + xhr :get, :show, conference_id: conference.short_title, + id: 'organizer' + end + + it 'assigns correct value to selection variable' do + expect(assigns(:selection)).to eq 'organizer' + end + + it 'assigns correct value to role variable' do + expect(assigns(:role)).to eq organizer_role + end + end + + describe 'PATCH #update' do + before :each do + sign_in admin + patch :update, conference_id: conference.short_title, + id: 'cfp', + role: { description: 'New description for cfp role!' } + end + + it 'changes the description of the role' do + expect(cfp_role.description).to eq 'New description for cfp role!' + end + end + + describe 'POST #toggle' do + before:each do + sign_in admin + post :toggle_user, conference_id: conference.short_title, + user: { email: 'user1@osem.io' }, + id: 'cfp' + end + + context 'assigns correct values to variables' do + it 'assigns correct value to selection variable' do + expect(assigns(:selection)).to eq 'cfp' + end + + it 'assigns correct value to role variable' do + expect(assigns(:role)).to eq cfp_role + end + + it 'assigns role to user' do + expect(user1.roles).to eq [cfp_role] + end + end + + context 'adds role to user' do + it 'adds second user' do + post :toggle_user, conference_id: conference.short_title, + user: { email: 'user2@osem.io' }, + id: 'cfp' + + expect(user2.roles).to eq [cfp_role] + end + + it 'assigns second role to user' do + post :toggle_user, conference_id: conference.short_title, + user: { email: 'user1@osem.io' }, + id: 'organizer' + + expect(user1.roles).to eq [organizer_role, cfp_role] + end + end + + context 'removes role from user' do + it 'removes role from user' do + post :toggle_user, conference_id: conference.short_title, + user: { email: 'user1@osem.io', state: 'false' }, + id: 'cfp' + + expect(user1.roles).to eq [] + end + + it 'removes second role from user' do + post :toggle_user, conference_id: conference.short_title, + user: { email: 'user1@osem.io' }, + id: 'organizer' + + expect(user1.roles).to eq [organizer_role, cfp_role] + + post :toggle_user, conference_id: conference.short_title, + user: { email: 'user1@osem.io', state: 'false' }, + id: 'cfp' + + user1.reload + expect(user1.roles).to eq [organizer_role] + end + end + + it 'does not remove role if user is the last organizer' do + # Add role organizer + post :toggle_user, conference_id: conference.short_title, + user: { email: 'user1@osem.io', state: 'true' }, + id: 'organizer' + expect(organizer_role.users).to eq [user1] + + # Try to remove role organizer, when there is only 1 user as organizer + post :toggle_user, conference_id: conference.short_title, + user: { email: 'user1@osem.io', state: 'false' }, + id: 'organizer' + expect(organizer_role.users).to eq [user1] + end + end +end diff --git a/spec/factories/conferences.rb b/spec/factories/conferences.rb index d39db79f..a63dd0d5 100644 --- a/spec/factories/conferences.rb +++ b/spec/factories/conferences.rb @@ -9,6 +9,13 @@ FactoryGirl.define do end_date { 6.days.from_now } registration_limit 0 + after(:create) do |conference| + Role.where(name: 'organizer', resource: conference).first_or_create(description: 'For the organizers of the conference (who shall have full access)') + Role.where(name: 'cfp', resource: conference).first_or_create(description: 'For the members of the CfP team') + Role.where(name: 'info_desk', resource: conference).first_or_create(description: 'For the members of the Info Desk team') + Role.where(name: 'volunteers_coordinator', resource: conference).first_or_create(description: 'For the people in charge of volunteers') + end + factory :full_conference do splashpage registration_period diff --git a/spec/factories/roles.rb b/spec/factories/roles.rb index e6d29d75..67d85233 100644 --- a/spec/factories/roles.rb +++ b/spec/factories/roles.rb @@ -1,5 +1,6 @@ FactoryGirl.define do factory :role do + name 'my role' factory :organizer_role do name 'organizer' diff --git a/spec/factories/users.rb b/spec/factories/users.rb index e5c0b7c1..1886b955 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -19,9 +19,5 @@ FactoryGirl.define do factory :admin do is_admin true end - - factory :organizer do - after(:create) { |user| user.role_ids = create(:organizer_role).id } - end end end diff --git a/spec/features/ability_spec.rb b/spec/features/ability_spec.rb index d21f82c1..5330c4bb 100644 --- a/spec/features/ability_spec.rb +++ b/spec/features/ability_spec.rb @@ -8,10 +8,10 @@ feature 'Has correct abilities' do let(:conference4) { create(:full_conference) } # user is volunteer coordinator let(:conference5) { create(:full_conference) } # user has no role - let(:role_organizer) { create(:role, name: 'organizer', resource: conference1) } - let(:role_cfp) { create(:role, name: 'cfp', resource: conference2) } - let(:role_info_desk) { create(:role, name: 'info_desk', resource: conference3) } - let(:role_volunteer_coordinator) { create(:role, name: 'volunteer_coordinator', resource: conference4) } + let(:role_organizer) { Role.find_by(name: 'organizer', resource: conference1) } + let(:role_cfp) { Role.find_by(name: 'cfp', resource: conference2) } + let(:role_info_desk) { Role.find_by(name: 'info_desk', resource: conference3) } + let(:role_volunteer_coordinator) { Role.find_by(name: 'volunteers_coordinator', resource: conference4) } let(:user) { create(:user) } let(:user_organizer) { create(:user, role_ids: [role_organizer.id]) } @@ -20,7 +20,7 @@ feature 'Has correct abilities' do let(:user_volunteer_coordinator) { create(:user, role_ids: [role_volunteer_coordinator.id]) } scenario 'when user has no role' do - user_organizer.is_admin = false + user.is_admin = false sign_in user visit admin_conference_path(conference1.short_title) @@ -31,7 +31,9 @@ feature 'Has correct abilities' do scenario 'when user is organizer' do user_organizer.is_admin = false sign_in user_organizer + visit admin_conference_path(conference1.short_title) + expect(current_path).to eq(admin_conference_path(conference1.short_title)) expect(page).to have_selector('li.nav-header.nav-header-bigger a', text: 'Dashboard') expect(page).to have_link('Basics', href: "/admin/conference/#{conference1.short_title}/edit") @@ -107,7 +109,9 @@ feature 'Has correct abilities' do scenario 'when user is cfp' do user_cfp.is_admin = false sign_in user_cfp + visit admin_conference_path(conference2.short_title) + expect(current_path).to eq(admin_conference_path(conference2.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/conference/#{conference2.short_title}/edit") @@ -132,7 +136,7 @@ feature 'Has correct abilities' do expect(page).to have_link('Event Types', href: "/admin/conference/#{conference2.short_title}/program/event_types") expect(page).to have_link('Difficulty Levels', href: "/admin/conference/#{conference2.short_title}/program/difficulty_levels") expect(page).to_not have_link('Questions', href: "/admin/conference/#{conference2.short_title}/questions") - expect(page).to_not have_link('Roles', href: "/admin/conference/#{conference2.short_title}/roles") + expect(page).to have_link('Roles', href: "/admin/conference/#{conference2.short_title}/roles") visit edit_admin_conference_path(conference2.short_title) expect(current_path).to eq(root_path) @@ -180,7 +184,9 @@ feature 'Has correct abilities' do scenario 'when user is info desk' do user_info_desk.is_admin = false sign_in user_info_desk + visit admin_conference_path(conference3.short_title) + expect(current_path).to eq(admin_conference_path(conference3.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/conference/#{conference2.short_title}/edit") @@ -205,7 +211,7 @@ feature 'Has correct abilities' do expect(page).to_not have_link('Event types', href: "/admin/conference/#{conference3.short_title}/program/event_types") expect(page).to_not have_link('Difficulty levels', href: "/admin/conference/#{conference3.short_title}/program/difficulty_levels") expect(page).to have_link('Questions', href: "/admin/conference/#{conference3.short_title}/questions") - expect(page).to_not have_link('Roles', href: "/admin/conference/#{conference3.short_title}/roles") + expect(page).to have_link('Roles', href: "/admin/conference/#{conference3.short_title}/roles") visit edit_admin_conference_path(conference3.short_title) expect(current_path).to eq(root_path) diff --git a/spec/features/base_controller_spec.rb b/spec/features/base_controller_spec.rb index 90d1fb03..d271c47c 100644 --- a/spec/features/base_controller_spec.rb +++ b/spec/features/base_controller_spec.rb @@ -4,11 +4,10 @@ feature 'BaseController' do let(:conference) { create(:conference) } let(:user) { create(:user) } - let!(:organizer_role) { create(:role, name: 'organizer', resource: conference) } - let!(:volunteers_coordinator_role) { create(:role, name: 'volunteers_coordinator', resource: conference) } - let!(:cfp_role) { create(:role, name: 'cfp', resource: conference) } - let!(:info_desk_role) { create(:role, name: 'info_desk', resource: conference) } - let!(:speaker_role) { create(:role, name: 'speaker', resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } + let!(:volunteers_coordinator_role) { Role.find_by(name: 'volunteers_coordinator', resource: conference) } + let!(:cfp_role) { Role.find_by(name: 'cfp', resource: conference) } + let!(:info_desk_role) { Role.find_by(name: 'info_desk', resource: conference) } describe 'GET #verify_user_admin' do context 'when user is a guest' do @@ -30,14 +29,6 @@ feature 'BaseController' do expect(flash).to eq 'You are not authorized to access this area!' end - it 'a speaker it redirects to the root_path' do - user.is_admin = false - user.role_ids = speaker_role.id - visit admin_conference_index_path - expect(current_path).to eq root_path - expect(flash).to eq 'You are not authorized to access this area!' - end - it 'an admin he can access the admin area' do user.is_admin = true visit admin_conference_index_path diff --git a/spec/features/campaign_spec.rb b/spec/features/campaign_spec.rb index d1043f5d..d7018279 100644 --- a/spec/features/campaign_spec.rb +++ b/spec/features/campaign_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' feature Campaign do let!(:conference) { create(:conference, short_title: 'osc14') } - let!(:organizer_role) { create(:organizer_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } shared_examples 'add and update campaign' do diff --git a/spec/features/cfp_spec.rb b/spec/features/cfp_spec.rb index 6f1539da..2b81dd61 100644 --- a/spec/features/cfp_spec.rb +++ b/spec/features/cfp_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' feature Conference do let!(:conference) { create(:conference) } - let!(:organizer_role) { create(:organizer_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } shared_examples 'add and update cfp' do diff --git a/spec/features/commercials_spec.rb b/spec/features/commercials_spec.rb index df50e260..eaf87f26 100644 --- a/spec/features/commercials_spec.rb +++ b/spec/features/commercials_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' feature Commercial do # It is necessary to use bang version of let to build roles before user let!(:conference) { create(:conference) } - let!(:organizer_role) { create(:organizer_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } let!(:participant) { create(:user) } diff --git a/spec/features/conference_spec.rb b/spec/features/conference_spec.rb index 2aa49733..f6ced652 100644 --- a/spec/features/conference_spec.rb +++ b/spec/features/conference_spec.rb @@ -33,7 +33,7 @@ feature Conference do scenario 'update conference', feature: true, js: true do conference = create(:conference) - organizer_role = create(:organizer_role, resource: conference) + organizer_role = Role.find_by(name: 'organizer', resource: conference) organizer = create(:user, role_ids: [organizer_role.id]) expected_count = Conference.count diff --git a/spec/features/contact_spec.rb b/spec/features/contact_spec.rb index c5612c60..aa9fcf57 100644 --- a/spec/features/contact_spec.rb +++ b/spec/features/contact_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' feature Contact do let!(:conference) { create(:conference) } - let!(:organizer_role) { create(:organizer_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, email: 'admin@example.com', role_ids: [organizer_role.id]) } shared_examples 'update a contact' do diff --git a/spec/features/difficulty_levels_spec.rb b/spec/features/difficulty_levels_spec.rb index c155e672..64427547 100644 --- a/spec/features/difficulty_levels_spec.rb +++ b/spec/features/difficulty_levels_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' feature DifficultyLevel do let!(:conference) { create(:conference) } - let!(:organizer_role) { create(:organizer_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } shared_examples 'difficulty levels' do diff --git a/spec/features/email_spec.rb b/spec/features/email_spec.rb index 11d96ef1..25a67235 100644 --- a/spec/features/email_spec.rb +++ b/spec/features/email_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' feature EmailSettings do let!(:conference) { create(:conference) } - let!(:organizer_role) { create(:organizer_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } shared_examples 'email settings' do diff --git a/spec/features/event_types_spec.rb b/spec/features/event_types_spec.rb index fee4f07b..c9122513 100644 --- a/spec/features/event_types_spec.rb +++ b/spec/features/event_types_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' feature EventType do let!(:conference) { create(:conference) } - let!(:organizer_role) { create(:organizer_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } shared_examples 'event types' do diff --git a/spec/features/lodgings_spec.rb b/spec/features/lodgings_spec.rb index be6359a8..9bcaad6a 100644 --- a/spec/features/lodgings_spec.rb +++ b/spec/features/lodgings_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' feature Lodging do let!(:conference) { create(:conference) } - let!(:organizer_role) { create(:organizer_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } scenario 'Add a lodging', feature: true, js: true do diff --git a/spec/features/program_spec.rb b/spec/features/program_spec.rb index b32a2854..ae4a3e64 100644 --- a/spec/features/program_spec.rb +++ b/spec/features/program_spec.rb @@ -4,7 +4,7 @@ feature Program do let!(:conference) { create(:conference) } let!(:program) { conference.program } - let!(:organizer_role) { create(:organizer_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } describe 'edit program' do diff --git a/spec/features/proposal_spec.rb b/spec/features/proposal_spec.rb index 3c5890ab..720a1bc3 100644 --- a/spec/features/proposal_spec.rb +++ b/spec/features/proposal_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' feature Event do let!(:conference) { create(:conference) } let!(:cfp) { create(:cfp, program_id: conference.program.id) } - let!(:organizer_role) { create(:organizer_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, email: 'admin@example.com', role_ids: [organizer_role.id]) } let!(:participant) { create(:user) } let!(:participant_without_bio) { create(:user, biography: '') } diff --git a/spec/features/registration_periods_spec.rb b/spec/features/registration_periods_spec.rb index c0515e97..4284c92e 100644 --- a/spec/features/registration_periods_spec.rb +++ b/spec/features/registration_periods_spec.rb @@ -4,7 +4,7 @@ feature RegistrationPeriod do # It is necessary to use bang version of let to build roles before user let!(:conference) { create(:conference) } - let!(:organizer_role) { create(:organizer_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, email: 'admin@example.com', role_ids: [organizer_role.id]) } shared_examples 'successfully' do diff --git a/spec/features/rooms_spec.rb b/spec/features/rooms_spec.rb index 0b510c46..d4ff4e0a 100644 --- a/spec/features/rooms_spec.rb +++ b/spec/features/rooms_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' feature Room do let!(:conference) { create(:conference) } let!(:venue) { create(:venue, conference: conference) } - let!(:organizer_role) { create(:organizer_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } shared_examples 'rooms' do diff --git a/spec/features/splashpage_spec.rb b/spec/features/splashpage_spec.rb index 8b5dd122..e913d023 100644 --- a/spec/features/splashpage_spec.rb +++ b/spec/features/splashpage_spec.rb @@ -4,9 +4,9 @@ feature Splashpage do # It is necessary to use bang version of let to build roles before user let!(:conference) { create(:conference) } - let!(:organizer_role) { create(:organizer_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, email: 'admin@example.com', role_ids: [organizer_role.id]) } - let!(:participant) { create(:user, biography: '') } + let!(:participant) { create(:user, biography: '', is_admin: false) } scenario 'create a valid splashpage', js: true do sign_in organizer diff --git a/spec/features/sponsor_spec.rb b/spec/features/sponsor_spec.rb index eca5297a..b0454a52 100644 --- a/spec/features/sponsor_spec.rb +++ b/spec/features/sponsor_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' feature Sponsor do let!(:conference) { create(:conference) } - let!(:organizer_role) { create(:organizer_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } shared_examples 'sponsors' do diff --git a/spec/features/sponsorship_level_spec.rb b/spec/features/sponsorship_level_spec.rb index 9df66e9a..3140a16b 100644 --- a/spec/features/sponsorship_level_spec.rb +++ b/spec/features/sponsorship_level_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' feature SponsorshipLevel do let!(:conference) { create(:conference) } - let!(:organizer_role) { create(:organizer_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } shared_examples 'sponsorship_levels' do diff --git a/spec/features/tickets_spec.rb b/spec/features/tickets_spec.rb index de5b1220..3a40f537 100644 --- a/spec/features/tickets_spec.rb +++ b/spec/features/tickets_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' feature Ticket do let!(:conference) { create(:conference, title: 'ExampleCon') } - let!(:organizer_role) { create(:organizer_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, email: 'admin@example.com', role_ids: [organizer_role.id]) } context 'as a organizer' do diff --git a/spec/features/tracks_spec.rb b/spec/features/tracks_spec.rb index f66bbb87..d1972075 100644 --- a/spec/features/tracks_spec.rb +++ b/spec/features/tracks_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' feature Track do let!(:conference) { create(:conference) } - let!(:organizer_role) { create(:organizer_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } shared_examples 'tracks' do diff --git a/spec/features/venues_spec.rb b/spec/features/venues_spec.rb index 8082d67e..298f9391 100644 --- a/spec/features/venues_spec.rb +++ b/spec/features/venues_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' feature Conference do let!(:conference) { create(:conference) } - let!(:organizer_role) { create(:organizer_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } shared_examples 'venue' do diff --git a/spec/features/volunteers_spec.rb b/spec/features/volunteers_spec.rb index f4e342ed..d3aa88cd 100644 --- a/spec/features/volunteers_spec.rb +++ b/spec/features/volunteers_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' feature Conference do let!(:conference) { create(:conference) } - let!(:organizer_role) { create(:organizer_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } shared_examples 'volunteer' do diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index fd9cd9ff..71e11171 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -107,7 +107,8 @@ describe 'User' do end context 'when user has the role organizer' do - let(:role) { create(:organizer_role, resource: my_conference) } + let!(:my_conference) { create(:full_conference) } + let(:role) { Role.find_by(name: 'organizer', resource: my_conference) } let(:user) { create(:user, role_ids: [role.id], is_admin: false) } it{ should_not be_able_to(:destroy, my_conference.program) } @@ -172,7 +173,8 @@ describe 'User' do end context 'when user has the role cfp' do - let(:role) { create(:cfp_role, resource: my_conference) } + let!(:my_conference) { create(:full_conference) } + let(:role) { Role.find_by(name: 'cfp', resource: my_conference) } let(:user) { create(:user, role_ids: [role.id], is_admin: false) } it{ should_not be_able_to([:create, :new], Conference.new) } @@ -226,7 +228,8 @@ describe 'User' do end context 'when user has the role info_desk' do - let(:role) { create(:info_desk_role, resource: my_conference) } + let!(:my_conference) { create(:full_conference) } + let(:role) { Role.find_by(name: 'info_desk', resource: my_conference) } let(:user) { create(:user, role_ids: [role.id], is_admin: false) } it{ should_not be_able_to([:create, :new], Conference.new) } @@ -280,7 +283,8 @@ describe 'User' do end context 'when user has the role volunteers_coordinator' do - let(:role) { create(:volunteers_coordinator_role, resource: my_conference) } + let!(:my_conference) { create(:full_conference) } + let(:role) { Role.find_by(name: 'volunteers_coordinator', resource: my_conference) } let(:user) { create(:user, role_ids: [role.id], is_admin: false) } it{ should_not be_able_to([:create, :new], Conference.new) } diff --git a/spec/models/conference_spec.rb b/spec/models/conference_spec.rb index d040d00b..95bd5440 100755 --- a/spec/models/conference_spec.rb +++ b/spec/models/conference_spec.rb @@ -274,7 +274,7 @@ describe Conference do describe '#get_top_submitter' do let!(:conference) { create(:conference) } - let!(:organizer_role) { create(:organizer_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } it 'calculates correct hash with top submitters' do @@ -902,7 +902,7 @@ describe Conference do describe 'self#event_distribution' do let!(:conference) { create(:conference) } - let!(:organizer_role) { create(:organizer_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } it 'self#event_distribution calculates correct values with user' do @@ -1451,7 +1451,7 @@ describe Conference do # It is necessary to use bang version of let to build roles before user let!(:conference) { create(:conference) } - let!(:organizer_role) { create(:organizer_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } let(:user) { create(:user) } diff --git a/spec/models/role_spec.rb b/spec/models/role_spec.rb new file mode 100644 index 00000000..36cd9a6b --- /dev/null +++ b/spec/models/role_spec.rb @@ -0,0 +1,14 @@ +require 'spec_helper' + +describe Role do + let(:conference) { create(:conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } + let!(:cfp_role) { Role.find_by(name: 'cfp', resource: conference) } + let!(:organizer) { create(:user, role_ids: organizer_role.id) } + + it 'get_users' do + expect(organizer_role.users).to include organizer + expect(organizer_role.users.count).to eq 1 + expect(cfp_role.users).to eq [] + end +end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index d92a5433..36c6153a 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -5,8 +5,9 @@ describe User do # It is necessary to use bang version of let to build roles before user let!(:user_admin) { create(:user) } let!(:conference) { create(:conference) } - let!(:organizer_role) { create(:organizer_role, resource: conference) } - let!(:cfp_role) { create(:cfp_role, resource: conference) } + let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } + let!(:cfp_role) { Role.find_by(name: 'cfp', resource: conference) } + let!(:volunteers_coordinator_role) { Role.find_by(name: 'volunteers_coordinator', resource: conference) } let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } let!(:user) { create(:user) } @@ -33,20 +34,21 @@ describe User do end describe '#has_role?' do - shared_examples '#role?' do |user, role, expected| - it "returns #{expected} for #{role}" do - user_obj = create(user) - expect(user_obj.has_role?(role.downcase, conference)).to be expected + describe 'when user has a role' do + it 'returns true when the user has the role' do + user = create(:user, role_ids: organizer_role.id) + expect(user.has_role?('organizer', conference)).to be true + end + + it 'returns false when the user does not have the role' do + user = create(:user, role_ids: cfp_role.id) + expect(user.has_role?('organizer', conference)).to be false end end - context 'organizer' do - it_behaves_like '#role?', :organizer, 'organizer', true - it_behaves_like '#role?', :organizer, 'participant', false - end - - context 'participant' do - it_behaves_like '#role?', :user, 'adMin', false + it 'returns false when the user does not have a role' do + user = create(:user, role_ids: []) + expect(user.has_role?('organizer', conference)).to be false end end diff --git a/spec/views/admin/conference/roles.html.haml_spec.rb b/spec/views/admin/conference/roles.html.haml_spec.rb deleted file mode 100644 index cce0bef4..00000000 --- a/spec/views/admin/conference/roles.html.haml_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -require 'spec_helper' - -describe 'admin/conference/roles' do - let(:conference) { create(:conference) } - let(:organizer_role) { create(:organizer_role, description: 'My description for organizer role', resource: conference) } - let(:organizer) { create(:user, name: 'test name', email: 'test@email.com', role_ids: [organizer_role.id]) } - - it 'renders the roles template for the conference' do - assign :conference, conference - assign :selection, 'organizer' - assign :role, [organizer_role] - assign :role_users, 'organizer' => [organizer] - render - expect(rendered).to include('Show users for role:') - expect(rendered).to include(organizer_role.description) - expect(rendered).to include("Add role 'Organizer' to user:") - expect(rendered).to include('Add role') - expect(rendered).to include('Users with role Organizer') - expect(rendered).to have_selector('table thead th:nth-of-type(1)', text: 'ID') - expect(rendered).to have_selector('table thead th:nth-of-type(2)', text: 'Name') - expect(rendered).to have_selector('table thead th:nth-of-type(3)', text: 'Email') - expect(rendered).to have_selector('table tbody tr:nth-of-type(1) td:nth-of-type(1)', text: organizer.id) - expect(rendered).to have_selector('table tbody tr:nth-of-type(1) td:nth-of-type(2)', text: 'test name') - expect(rendered).to have_selector('table tbody tr:nth-of-type(1) td:nth-of-type(3)', text: 'test@email.com') - end -end diff --git a/spec/views/admin/roles/index.html.haml_spec.rb b/spec/views/admin/roles/index.html.haml_spec.rb new file mode 100644 index 00000000..dc4fba6b --- /dev/null +++ b/spec/views/admin/roles/index.html.haml_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +describe 'admin/roles/index' do + let(:conference) { create(:conference) } + let(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } + let!(:organizer) { create(:user, name: 'user name for organizer', email: 'organizer@osem.io', role_ids: organizer_role.id) } + + let(:cfp_role) { Role.find_by(name: 'cfp', resource: conference) } + let!(:cfp_user) { create(:user, name: 'user name for cfp', email: 'cfp@osem.io', role_ids: [cfp_role.id]) } + + let(:info_desk_role) { Role.find_by(name: 'info_desk', resource: conference) } + let(:volunteers_coordinator_role) { Role.find_by(name: 'volunteers_coordinator', resource: conference) } + + before(:each) do + assign :conference, conference + assign :roles, [organizer_role, cfp_role, info_desk_role, volunteers_coordinator_role] + + render + end + + it 'renders index' do + expect(organizer_role.users.count).to eq 1 + expect(rendered).to have_selector('table thead th:nth-of-type(1)', text: 'ID') + expect(rendered).to have_selector('table thead th:nth-of-type(2)', text: 'Name') + expect(rendered).to have_selector('table thead th:nth-of-type(3)', text: 'Description') + expect(rendered).to have_selector('table thead th:nth-of-type(4)', text: 'Users') + expect(rendered).to have_selector('table thead th:nth-of-type(5)', text: 'Actions') + + expect(rendered).to have_selector('table tbody tr:nth-of-type(1) td:nth-of-type(1)', text: organizer_role.id) + expect(rendered).to have_selector('table tbody tr:nth-of-type(1) td:nth-of-type(2)', text: 'Organizer') + expect(rendered).to have_selector('table tbody tr:nth-of-type(1) td:nth-of-type(3)', text: 'For the organizers of the conference (who shall have full access)') + expect(rendered).to have_selector('table tbody tr:nth-of-type(1) td:nth-of-type(4)', text: 'user name for organizer') + expect(rendered).to have_selector('table tbody tr:nth-of-type(1) td:nth-of-type(5)', text: 'Users') + + expect(rendered).to have_selector('table tbody tr:nth-of-type(2) td:nth-of-type(1)', text: cfp_role.id) + expect(rendered).to have_selector('table tbody tr:nth-of-type(2) td:nth-of-type(2)', text: 'Cfp') + expect(rendered).to have_selector('table tbody tr:nth-of-type(2) td:nth-of-type(3)', text: 'For the members of the CfP team') + expect(rendered).to have_selector('table tbody tr:nth-of-type(2) td:nth-of-type(4)', text: 'user name for cfp') + expect(rendered).to have_selector('table tbody tr:nth-of-type(2) td:nth-of-type(5)', text: 'Users') + end +end diff --git a/spec/views/admin/roles/show.html.haml_spec.rb b/spec/views/admin/roles/show.html.haml_spec.rb new file mode 100644 index 00000000..3f05f9e6 --- /dev/null +++ b/spec/views/admin/roles/show.html.haml_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper' + +describe 'admin/roles/show' do + let(:conference) { create(:conference) } + let(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } + let(:organizer) { create(:user, name: 'test name', email: 'test@email.osem', role_ids: [organizer_role.id]) } + + before(:each) do + sign_in organizer + assign :conference, conference + assign :selection, 'organizer' + assign :role, organizer_role + assign :users, [organizer] + render + end + + it 'renders show properly' do + expect(rendered).to include(organizer_role.name.capitalize) + expect(rendered).to include('Add user by email:') + expect(rendered).to have_selector('table thead th:nth-of-type(1)', text: '') + expect(rendered).to have_selector('table thead th:nth-of-type(2)', text: 'ID') + expect(rendered).to have_selector('table thead th:nth-of-type(3)', text: 'Name') + expect(rendered).to have_selector('table thead th:nth-of-type(4)', text: 'Email') + expect(rendered).to have_selector('table tbody tr:nth-of-type(1) td:nth-of-type(2)', text: organizer.id) + expect(rendered).to have_selector('table tbody tr:nth-of-type(1) td:nth-of-type(3)', text: 'test name') + expect(rendered).to have_selector('table tbody tr:nth-of-type(1) td:nth-of-type(4)', text: 'test@email.osem') + end +end