From eb23d838b53ce0dc61e333206a2fa24b1eb80440 Mon Sep 17 00:00:00 2001 From: shlok007 Date: Tue, 11 Jul 2017 04:59:03 +0530 Subject: [PATCH 01/26] correct past and upcoming conferences in admin/organizations#index --- app/models/conference.rb | 2 ++ app/views/admin/organizations/index.html.haml | 4 ++-- spec/models/conference_spec.rb | 17 +++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/app/models/conference.rb b/app/models/conference.rb index 69571dc9..68cdc186 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -7,6 +7,8 @@ class Conference < ActiveRecord::Base resourcify :roles, dependent: :delete_all default_scope { order('start_date DESC') } + scope :upcoming, (-> { where('end_date >= ?', Date.current) }) + scope :past, (-> { where('end_date < ?', Date.current) }) belongs_to :organization diff --git a/app/views/admin/organizations/index.html.haml b/app/views/admin/organizations/index.html.haml index 52e2877a..aa682c57 100644 --- a/app/views/admin/organizations/index.html.haml +++ b/app/views/admin/organizations/index.html.haml @@ -20,9 +20,9 @@ %td = organization.name %td - = organization.conferences.count + = organization.conferences.upcoming.count %td - = organization.conferences.count + = organization.conferences.past.count %td .btn-group = link_to 'Edit', edit_admin_organization_path(organization), diff --git a/spec/models/conference_spec.rb b/spec/models/conference_spec.rb index 89863412..91c06140 100755 --- a/spec/models/conference_spec.rb +++ b/spec/models/conference_spec.rb @@ -1687,4 +1687,21 @@ describe Conference do expect{ room.save }.to change { subject.revision }.by(1) end end + + describe '.upcoming' do + let!(:upcoming_conference) { create(:conference) } + let!(:past_conference) { create(:conference, start_date: Date.current - 1.days, end_date: Date.current - 1.days) } + subject { Conference.upcoming } + + it { is_expected.to eq [upcoming_conference] } + end + + describe '.past' do + let!(:upcoming_conference) { create(:conference) } + let!(:past_conference1) { create(:conference, start_date: Date.current - 1.days, end_date: Date.current - 1.days) } + let!(:past_conference2) { create(:conference, start_date: Date.current - 2.days, end_date: Date.current - 1.days) } + subject { Conference.past } + + it { is_expected.to eq [past_conference1, past_conference2] } + end end From ddf6f4b4c90954b1483fc3d6f446967795eac817 Mon Sep 17 00:00:00 2001 From: shlok007 Date: Tue, 11 Jul 2017 03:59:52 +0530 Subject: [PATCH 02/26] fix new conference links --- app/views/layouts/_admin_sidebar.html.haml | 2 +- app/views/layouts/_admin_sidebar_index.html.haml | 2 +- app/views/layouts/_user_menu.html.haml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/layouts/_admin_sidebar.html.haml b/app/views/layouts/_admin_sidebar.html.haml index 2c3eaf52..1c7bac9a 100644 --- a/app/views/layouts/_admin_sidebar.html.haml +++ b/app/views/layouts/_admin_sidebar.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? :new, Conference.new %li = link_to(new_admin_conference_path) do %span.fa.fa-plus diff --git a/app/views/layouts/_admin_sidebar_index.html.haml b/app/views/layouts/_admin_sidebar_index.html.haml index 3844339b..01356f42 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 can? :create, Conference + - if can? :new, Conference.new %li = link_to(new_admin_conference_path) do %span.fa.fa-plus diff --git a/app/views/layouts/_user_menu.html.haml b/app/views/layouts/_user_menu.html.haml index 01432b3c..38a96b08 100644 --- a/app/views/layouts/_user_menu.html.haml +++ b/app/views/layouts/_user_menu.html.haml @@ -28,10 +28,10 @@ = link_to(admin_conferences_path()) do %span.fa.fa-home Administration - - if can? :create, Conference + - if can? :new, Conference.new =link_to(new_admin_conference_path) do %span.fa.fa-plus - Create Conference + New Conference -if @conference and @conference.id and can? :show, @conference %li = link_to(admin_conference_path(@conference.short_title)) do From ea43b19ef489e5fb61ab3672483a5e589c482e1d Mon Sep 17 00:00:00 2001 From: shlok007 Date: Wed, 12 Jul 2017 17:34:33 +0530 Subject: [PATCH 03/26] add tests for new conference links --- spec/features/cfp_ability_spec.rb | 1 + spec/features/info_desk_ability_spec.rb | 1 + spec/features/organization_admin_ability_spec.rb | 1 + spec/features/organizer_ability_spec.rb | 1 + 4 files changed, 4 insertions(+) diff --git a/spec/features/cfp_ability_spec.rb b/spec/features/cfp_ability_spec.rb index 235dedea..7af4e119 100644 --- a/spec/features/cfp_ability_spec.rb +++ b/spec/features/cfp_ability_spec.rb @@ -46,6 +46,7 @@ feature 'Has correct abilities' do expect(page).to_not have_link('Goals', href: "/admin/conferences/#{conference.short_title}/targets") expect(page).to have_link('Roles', href: "/admin/conferences/#{conference.short_title}/roles") expect(page).to have_link('Resources', href: "/admin/conferences/#{conference.short_title}/resources") + expect(page).to_not have_link('New Conference', href: '/admin/conferences/new') visit admin_conference_venue_rooms_path(conference.short_title) expect(current_path).to eq(admin_conference_venue_rooms_path(conference.short_title)) diff --git a/spec/features/info_desk_ability_spec.rb b/spec/features/info_desk_ability_spec.rb index 7d0039fe..20aa586b 100644 --- a/spec/features/info_desk_ability_spec.rb +++ b/spec/features/info_desk_ability_spec.rb @@ -46,6 +46,7 @@ feature 'Has correct abilities' do expect(page).to have_link('Registrations', href: "/admin/conferences/#{conference.short_title}/registrations") expect(page).to have_link('Questions', href: "/admin/conferences/#{conference.short_title}/questions") expect(page).to_not have_link('E-Mails', href: "/admin/conferences/#{conference.short_title}/emails") + expect(page).to_not have_link('New Conference', href: '/admin/conferences/new') visit admin_organizations_path expect(current_path).to eq(admin_organizations_path) diff --git a/spec/features/organization_admin_ability_spec.rb b/spec/features/organization_admin_ability_spec.rb index 3a5ffcd3..aefb89f4 100644 --- a/spec/features/organization_admin_ability_spec.rb +++ b/spec/features/organization_admin_ability_spec.rb @@ -55,6 +55,7 @@ feature 'Has correct abilities' do expect(page).to 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 have_link('Resources', href: "/admin/conferences/#{conference.short_title}/resources") + expect(page).to have_link('New Conference', href: '/admin/conferences/new') visit edit_admin_conference_path(conference.short_title) expect(current_path).to eq(edit_admin_conference_path(conference.short_title)) diff --git a/spec/features/organizer_ability_spec.rb b/spec/features/organizer_ability_spec.rb index 7617bc0a..34d87b0a 100644 --- a/spec/features/organizer_ability_spec.rb +++ b/spec/features/organizer_ability_spec.rb @@ -58,6 +58,7 @@ feature 'Has correct abilities' do expect(page).to 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 have_link('Resources', href: "/admin/conferences/#{conference.short_title}/resources") + expect(page).to_not have_link('New Conference', href: '/admin/conferences/new') visit admin_conference_path(other_conference.short_title) expect(page).to have_link('Add venue', href: "/admin/conferences/#{other_conference.short_title}/venue/new") From 8652a5cb784562d79671f602bd50f8adbf915ca0 Mon Sep 17 00:00:00 2001 From: Hernan Schmidt Date: Wed, 12 Jul 2017 16:40:13 +0200 Subject: [PATCH 04/26] Update Byebug to latest version --- Gemfile.lock | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 9ea214c2..5ef3f60c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -89,9 +89,7 @@ GEM momentjs-rails (>= 2.8.1) browser (0.6.0) builder (3.2.2) - byebug (3.1.2) - columnize (~> 0.8) - debugger-linecache (~> 1.2) + byebug (9.0.6) cancancan (1.13.1) capybara (2.6.2) addressable @@ -131,7 +129,6 @@ GEM coffee-script-source execjs coffee-script-source (1.10.0) - columnize (0.8.9) countable-rails (0.0.1) railties (>= 3.1) countries (1.2.5) @@ -153,7 +150,6 @@ GEM dante (0.2.0) database_cleaner (1.3.0) debug_inspector (0.0.2) - debugger-linecache (1.2.0) delayed_job (4.1.1) activesupport (>= 3.0, < 5.0) delayed_job_active_record (4.1.0) From 366fced200e007d4ad3bc0dd53b1adb1365d526b Mon Sep 17 00:00:00 2001 From: shlok007 Date: Sat, 24 Jun 2017 05:03:24 +0530 Subject: [PATCH 05/26] Move abilities for admin views in separate model --- app/controllers/admin/base_controller.rb | 6 + .../admin/registration_periods_controller.rb | 2 +- app/models/ability.rb | 246 ++--------- app/models/admin_ability.rb | 237 +++++++++++ spec/models/ability_spec.rb | 361 ---------------- spec/models/admin_ability_spec.rb | 396 ++++++++++++++++++ 6 files changed, 676 insertions(+), 572 deletions(-) create mode 100644 app/models/admin_ability.rb create mode 100644 spec/models/admin_ability_spec.rb diff --git a/app/controllers/admin/base_controller.rb b/app/controllers/admin/base_controller.rb index 85dba43d..3b28a230 100644 --- a/app/controllers/admin/base_controller.rb +++ b/app/controllers/admin/base_controller.rb @@ -2,6 +2,12 @@ module Admin class BaseController < ApplicationController before_filter :verify_user_admin + private + + def current_ability + @current_ability ||= AdminAbility.new(current_user) + end + def verify_user_admin if (current_user.nil?) redirect_to sign_in_path diff --git a/app/controllers/admin/registration_periods_controller.rb b/app/controllers/admin/registration_periods_controller.rb index d955ddd0..4e48c013 100644 --- a/app/controllers/admin/registration_periods_controller.rb +++ b/app/controllers/admin/registration_periods_controller.rb @@ -1,5 +1,5 @@ module Admin - class RegistrationPeriodsController < ApplicationController + class RegistrationPeriodsController < Admin::BaseController load_and_authorize_resource :conference, find_by: :short_title load_and_authorize_resource through: :conference, singleton: true diff --git a/app/models/ability.rb b/app/models/ability.rb index 40965719..6581069c 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -3,30 +3,52 @@ class Ability # Initializes the ability class def initialize(user) - # Order Abilities - # (Check https://github.com/CanCanCommunity/cancancan/wiki/Ability-Precedence) - # Check roles of user, using rolify. Role name is *case sensitive* - # user.is_organizer? or user.has_role? :organizer - # user.is_cfp_of? Conference or user.has_role? :cfp, Conference - # user.is_info_desk_of? Conference - # user.is_volunteers_coordinator_of? Conference - # user.is_attendee_of? Conference - # The following is wrong because a user will only have 'cfp' role for a specific conference - # user.is_cfp? # This is always false - user ||= User.new - # 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) + common_abilities_for_admins(user) else signed_in(user) end end + # Abilities for users with roles wandering around in non-admin views. + def common_abilities_for_admins(user) + signed_in(user) + conf_ids_for_organizer = Conference.with_role(:organizer, user).pluck(:id) + conf_ids_for_cfp = Conference.with_role(:cfp, user).pluck(:id) + conf_ids_for_info_desk = Conference.with_role(:info_desk, user).pluck(:id) + + if conf_ids_for_organizer + + # To access splashpage of their conference if it is not public + can :show, Conference, id: conf_ids_for_organizer + + # To access conference/proposals/registrations + can :manage, Registration, conference_id: conf_ids_for_organizer + + # To access conference/proposals + can :manage, Event, program: { conference_id: conf_ids_for_organizer } + + # To access comment link in menu bar + can :index, Comment, commentable_type: 'Event', + commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_organizer).pluck(:id)).pluck(:id) + elsif conf_ids_for_cfp + + can :index, Comment, commentable_type: 'Event', + commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_cfp).pluck(:id)).pluck(:id) + can :manage, Event, program: { conference_id: conf_ids_for_cfp } + + elsif conf_ids_for_info_desk + can :manage, Registration, conference_id: conf_ids_for_info_desk + end + + can :access, Admin + can :manage, :all if user.is_admin + end + # Abilities for not signed in users (guests) def not_signed_in can [:index], Organization @@ -74,7 +96,6 @@ class Ability def signed_in(user) # Abilities from not_signed_in user are also inherited not_signed_in - can :manage, User, id: user.id can :manage, Registration, user_id: user.id @@ -105,199 +126,4 @@ class Ability can [:destroy], Openid end - - # Abilities for signed in users with roles - def signed_in_with_roles(user) - # Abilities from not_signed_in and signed_in are also inherited - signed_in(user) - - signed_in_with_organization_admin_role(user) if user.has_role? :organization_admin, :any - signed_in_with_organizer_role(user) if user.has_role? :organizer, :any - 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 - - # for users with any role - can :access, Admin - can [:show], Conference - can :index, Commercial, commercialable_type: 'Conference' - cannot [:edit, :update, :destroy], Question, global: true - # for admins - can :manage, :all if user.is_admin - - # even admin cannot create new users with ICHAIN enabled - cannot [:new, :create], User if ENV['OSEM_ICHAIN_ENABLED'] == 'true' - - cannot :revert_object, PaperTrail::Version do |version| - (version.event == 'create' && %w(Conference User Event).include?(version.item_type)) - end - - cannot :revert_attribute, PaperTrail::Version do |version| - version.event != 'update' || version.item.nil? - end - - cannot :destroy, Program - # Do not delete venue, when there are rooms being used - cannot :destroy, Venue do |venue| - venue.conference.program.events.where.not(room_id: nil).any? - end - - # Can't create cfp if there are no available cfp types - cannot [:new, :create], Cfp do |cfp| - cfp.program.remaining_cfp_types.empty? - end - end - - def signed_in_with_organization_admin_role(user) - org_ids_for_organization_admin = Organization.with_role(:organization_admin, user).pluck(:id) - conf_ids_for_organization_admin = Conference.where(organization_id: org_ids_for_organization_admin).pluck(:id) - - can [:read, :update, :destroy], Organization, id: org_ids_for_organization_admin - can :new, Conference - can :manage, Conference, organization_id: org_ids_for_organization_admin - can [:index, :show], Role - can [:edit, :update], Role do |role| - role.resource_type == 'Organization' && (org_ids_for_organization_admin.include? role.resource_id) - end - signed_in_with_organizer_role(user, conf_ids_for_organization_admin) - end - - def signed_in_with_organizer_role(user, conf_ids_for_organization_admin = []) - # 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 - can :manage, Resource, conference_id: conf_ids - can [:read, :update, :destroy], Conference, id: conf_ids - can :manage, Splashpage, conference_id: conf_ids - can :manage, Contact, conference_id: conf_ids - can :manage, EmailSettings, conference_id: conf_ids - can :manage, Campaign, conference_id: conf_ids - can :manage, Target, conference_id: conf_ids - can :manage, Commercial, commercialable_type: 'Conference', - commercialable_id: conf_ids - can :manage, Registration, conference_id: conf_ids - can :manage, RegistrationPeriod, conference_id: conf_ids - can :manage, Question, conference_id: conf_ids - can :manage, Question do |question| - !(question.conferences.pluck(:id) & conf_ids).empty? - end - can :manage, Vposition, conference_id: conf_ids - can :manage, Vday, conference_id: conf_ids - can :manage, Program, conference_id: conf_ids - can :manage, Schedule, program: { conference_id: conf_ids } - can :manage, EventSchedule, schedule: { program: { conference_id: conf_ids } } - can :manage, Cfp, program: { conference_id: conf_ids} - can :manage, Event, program: { conference_id: conf_ids} - can :manage, EventType, program: { conference_id: conf_ids} - can :manage, Track, program: { conference_id: conf_ids} - can :manage, DifficultyLevel, program: { conference_id: conf_ids} - can :manage, Commercial, commercialable_type: 'Event', - commercialable_id: Event.where(program_id: Program.where(conference_id: conf_ids).pluck(:id)).pluck(:id) - can :manage, Venue, conference_id: conf_ids - can :manage, Commercial, commercialable_type: 'Venue', - commercialable_id: Venue.where(conference_id: conf_ids).pluck(:id) - can :manage, Lodging, conference_id: conf_ids - can :manage, Room, venue: { conference_id: conf_ids} - can :manage, Sponsor, conference_id: conf_ids - can :manage, SponsorshipLevel, conference_id: conf_ids - can :manage, Ticket, conference_id: conf_ids - can :index, Comment, commentable_type: 'Event', - commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids).pluck(:id)).pluck(:id) - - # Abilities for Role (Conference resource) - can [:index, :show], Role do |role| - role.resource_type == 'Conference' - end - - can [:edit, :update, :toggle_user], Role do |role| - role.resource_type == 'Conference' && (conf_ids.include? role.resource_id) - end - - can [:index, :revert_object, :revert_attribute], PaperTrail::Version do |version| - version.item_type == 'User' || (conf_ids.include? version.conference_id) - end - end - - def signed_in_with_cfp_role(user) - # ids of all the conferences for which the user has the 'cfp' role - conf_ids_for_cfp = Conference.with_role(:cfp, user).pluck(:id) - - can [:index, :show, :update], Resource, conference_id: conf_ids_for_cfp - can :manage, Event, program: { conference_id: conf_ids_for_cfp } - can :manage, EventType, program: { conference_id: conf_ids_for_cfp } - can :manage, Track, program: { conference_id: conf_ids_for_cfp } - can :manage, DifficultyLevel, program: { conference_id: conf_ids_for_cfp } - can :manage, EmailSettings, conference_id: conf_ids_for_cfp - can :manage, Schedule, program: { conference_id: conf_ids_for_cfp } - can :manage, Room, venue: { conference_id: conf_ids_for_cfp } - can :show, Venue, conference_id: conf_ids_for_cfp - can :show, Commercial, commercialable_type: 'Venue', commercialable_id: Venue.where(conference_id: conf_ids_for_cfp).pluck(:id) - can :manage, Cfp, program: { conference_id: conf_ids_for_cfp } - can :manage, Program, conference_id: conf_ids_for_cfp - can :manage, Commercial, commercialable_type: 'Event', - 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, :show], Role do |role| - role.resource_type == 'Conference' - 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' && role.name == 'cfp' && - (Conference.with_role(:cfp, user).pluck(:id).include? role.resource_id) - end - - can [:index, :revert_object, :revert_attribute], PaperTrail::Version, item_type: 'Event', conference_id: conf_ids_for_cfp - can [:index, :revert_object, :revert_attribute], PaperTrail::Version, item_type: 'Vote', conference_id: conf_ids_for_cfp - can [:index, :revert_object, :revert_attribute], PaperTrail::Version do |version| - version.item_type == 'Commercial' && conf_ids_for_cfp.include?(version.conference_id) && - (version.object.to_s.include?('Event') || version.object_changes.to_s.include?('Event')) - end - end - - def signed_in_with_info_desk_role(user) - # ids of all the conferences for which the user has the 'info_desk' role - conf_ids_for_info_desk = Conference.with_role(:info_desk, user).pluck(:id) - - can [:index, :show, :update], Resource, conference_id: conf_ids_for_info_desk - can :manage, Registration, conference_id: conf_ids_for_info_desk - can :manage, Question, conference_id: conf_ids_for_info_desk - can :manage, Question do |question| - !(question.conferences.pluck(:id) & conf_ids_for_info_desk).empty? - end - - # Abilities for Role (Conference resource) - can [:index, :show], Role do |role| - role.resource_type == 'Conference' - 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' && role.name == 'info_desk' && - (Conference.with_role(:info_desk, user).pluck(:id).include? role.resource_id) - end - end - - def signed_in_with_volunteers_coordinator_role(user) - # ids of all the conferences for which the user has the 'volunteers_coordinator' role - conf_ids_for_volunteers_coordinator = Conference.with_role(:volunteers_coordinator, user).pluck(:id) - - can [:index, :show, :update], Resource, conference_id: conf_ids_for_volunteers_coordinator - 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, :show], Role do |role| - role.resource_type == 'Conference' - 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' && role.name == 'volunteers_coordinator' && - (Conference.with_role(:volunteers_coordinator, user).pluck(:id).include? role.resource_id) - end - end end diff --git a/app/models/admin_ability.rb b/app/models/admin_ability.rb new file mode 100644 index 00000000..99c80401 --- /dev/null +++ b/app/models/admin_ability.rb @@ -0,0 +1,237 @@ +class AdminAbility + include CanCan::Ability + + def initialize(user) + # Order Abilities + # (Check https://github.com/CanCanCommunity/cancancan/wiki/Ability-Precedence) + # Check roles of user, using rolify. Role name is *case sensitive* + # user.is_organizer? or user.has_role? :organizer + # user.is_cfp_of? Conference or user.has_role? :cfp, Conference + # user.is_info_desk_of? Conference + # user.is_volunteers_coordinator_of? Conference + # user.is_attendee_of? Conference + # The following is wrong because a user will only have 'cfp' role for a specific conference + # user.is_cfp? # This is always false + + user ||= User.new + signed_in_with_roles(user) + end + + def common_abilities_for_roles(user) + can :manage, User, id: user.id + can :manage, Registration, user_id: user.id + + can :show, Registration, &:new_record? + + can [:new, :create], Registration do |registration| + conference = registration.conference + conference.registration_open? && !conference.registration_limit_exceeded? || conference.program.speakers.confirmed.include?(user) + end + + can :index, Organization + can :index, Ticket + can :manage, TicketPurchase, user_id: user.id + can [:new, :create], Payment, user_id: user.id + + can [:create, :destroy], Subscription, user_id: user.id + + can [:new, :create], Event do |event| + event.program.cfp_open? && event.new_record? + end + + can [:update, :show, :delete, :index], Event do |event| + event.users.include?(user) + end + + # can manage the commercials of their own events + can :manage, Commercial, commercialable_type: 'Event', commercialable_id: user.events.pluck(:id) + + can [:destroy], Openid + can :access, Admin + can [:show], Conference + can :index, Commercial, commercialable_type: 'Conference' + cannot [:edit, :update, :destroy], Question, global: true + # for admins + can :manage, :all if user.is_admin + # even admin cannot create new users with ICHAIN enabled + cannot [:new, :create], User if ENV['OSEM_ICHAIN_ENABLED'] == 'true' + cannot :revert_object, PaperTrail::Version do |version| + (version.event == 'create' && %w[Conference User Event].include?(version.item_type)) + end + cannot :revert_attribute, PaperTrail::Version do |version| + version.event != 'update' || version.item.nil? + end + # Can't create cfp if there are no available cfp types + cannot [:new, :create], Cfp do |cfp| + cfp.program.remaining_cfp_types.empty? + end + cannot :destroy, Program + # Do not delete venue, when there are rooms being used + cannot :destroy, Venue do |venue| + venue.conference.program.events.where.not(room_id: nil).any? + end + end + + # Abilities for signed in users with roles + def signed_in_with_roles(user) + signed_in_with_organization_admin_role(user) if user.has_role? :organization_admin, :any + signed_in_with_organizer_role(user) if user.has_role? :organizer, :any + 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 + common_abilities_for_roles(user) + end + + def signed_in_with_organization_admin_role(user) + org_ids_for_organization_admin = Organization.with_role(:organization_admin, user).pluck(:id) + conf_ids_for_organization_admin = Conference.where(organization_id: org_ids_for_organization_admin).pluck(:id) + + can [:read, :update, :destroy], Organization, id: org_ids_for_organization_admin + can :new, Conference + can :manage, Conference, organization_id: org_ids_for_organization_admin + can [:index, :show], Role + can [:edit, :update], Role do |role| + role.resource_type == 'Organization' && (org_ids_for_organization_admin.include? role.resource_id) + end + signed_in_with_organizer_role(user, conf_ids_for_organization_admin) + end + + def signed_in_with_organizer_role(user, conf_ids_for_organization_admin = []) + # 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 + can :manage, Resource, conference_id: conf_ids + can [:read, :update, :destroy], Conference, id: conf_ids + can :manage, Splashpage, conference_id: conf_ids + can :manage, Contact, conference_id: conf_ids + can :manage, EmailSettings, conference_id: conf_ids + can :manage, Campaign, conference_id: conf_ids + can :manage, Target, conference_id: conf_ids + can :manage, Commercial, commercialable_type: 'Conference', + commercialable_id: conf_ids + can :manage, Registration, conference_id: conf_ids + can :manage, RegistrationPeriod, conference_id: conf_ids + can :manage, Question, conference_id: conf_ids + can :manage, Question do |question| + !(question.conferences.pluck(:id) & conf_ids).empty? + end + can :manage, Vposition, conference_id: conf_ids + can :manage, Vday, conference_id: conf_ids + can :manage, Program, conference_id: conf_ids + can :manage, Schedule, program: { conference_id: conf_ids } + can :manage, EventSchedule, schedule: { program: { conference_id: conf_ids } } + can :manage, Cfp, program: { conference_id: conf_ids } + can :manage, Event, program: { conference_id: conf_ids } + can :manage, EventType, program: { conference_id: conf_ids } + can :manage, Track, program: { conference_id: conf_ids } + can :manage, DifficultyLevel, program: { conference_id: conf_ids } + can :manage, Commercial, commercialable_type: 'Event', + commercialable_id: Event.where(program_id: Program.where(conference_id: conf_ids).pluck(:id)).pluck(:id) + can :manage, Venue, conference_id: conf_ids + can :manage, Commercial, commercialable_type: 'Venue', + commercialable_id: Venue.where(conference_id: conf_ids).pluck(:id) + can :manage, Lodging, conference_id: conf_ids + can :manage, Room, venue: { conference_id: conf_ids } + can :manage, Sponsor, conference_id: conf_ids + can :manage, SponsorshipLevel, conference_id: conf_ids + can :manage, Ticket, conference_id: conf_ids + can :index, Comment, commentable_type: 'Event', + commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids).pluck(:id)).pluck(:id) + + # Abilities for Role (Conference resource) + can [:index, :show], Role do |role| + role.resource_type == 'Conference' + end + + can [:edit, :update, :toggle_user], Role do |role| + role.resource_type == 'Conference' && (conf_ids.include? role.resource_id) + end + + can [:index, :revert_object, :revert_attribute], PaperTrail::Version do |version| + version.item_type == 'User' || (conf_ids.include? version.conference_id) + end + end + + def signed_in_with_cfp_role(user) + # ids of all the conferences for which the user has the 'cfp' role + conf_ids_for_cfp = Conference.with_role(:cfp, user).pluck(:id) + + can [:index, :show, :update], Resource, conference_id: conf_ids_for_cfp + can :manage, Event, program: { conference_id: conf_ids_for_cfp } + can :manage, EventType, program: { conference_id: conf_ids_for_cfp } + can :manage, Track, program: { conference_id: conf_ids_for_cfp } + can :manage, DifficultyLevel, program: { conference_id: conf_ids_for_cfp } + can :manage, EmailSettings, conference_id: conf_ids_for_cfp + can :manage, Schedule, program: { conference_id: conf_ids_for_cfp } + can :manage, Room, venue: { conference_id: conf_ids_for_cfp } + can :show, Venue, conference_id: conf_ids_for_cfp + can :show, Commercial, commercialable_type: 'Venue', commercialable_id: Venue.where(conference_id: conf_ids_for_cfp).pluck(:id) + can :manage, Cfp, program: { conference_id: conf_ids_for_cfp } + can :manage, Program, conference_id: conf_ids_for_cfp + can :manage, Commercial, commercialable_type: 'Event', + 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, :show], Role do |role| + role.resource_type == 'Conference' + 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' && role.name == 'cfp' && + (Conference.with_role(:cfp, user).pluck(:id).include? role.resource_id) + end + + can [:index, :revert_object, :revert_attribute], PaperTrail::Version, item_type: 'Event', conference_id: conf_ids_for_cfp + can [:index, :revert_object, :revert_attribute], PaperTrail::Version, item_type: 'Vote', conference_id: conf_ids_for_cfp + can [:index, :revert_object, :revert_attribute], PaperTrail::Version do |version| + version.item_type == 'Commercial' && conf_ids_for_cfp.include?(version.conference_id) && + (version.object.to_s.include?('Event') || version.object_changes.to_s.include?('Event')) + end + end + + def signed_in_with_info_desk_role(user) + # ids of all the conferences for which the user has the 'info_desk' role + conf_ids_for_info_desk = Conference.with_role(:info_desk, user).pluck(:id) + + can [:index, :show, :update], Resource, conference_id: conf_ids_for_info_desk + can :manage, Registration, conference_id: conf_ids_for_info_desk + can :manage, Question, conference_id: conf_ids_for_info_desk + can :manage, Question do |question| + !(question.conferences.pluck(:id) & conf_ids_for_info_desk).empty? + end + + # Abilities for Role (Conference resource) + can [:index, :show], Role do |role| + role.resource_type == 'Conference' + 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' && role.name == 'info_desk' && + (Conference.with_role(:info_desk, user).pluck(:id).include? role.resource_id) + end + end + + def signed_in_with_volunteers_coordinator_role(user) + # ids of all the conferences for which the user has the 'volunteers_coordinator' role + conf_ids_for_volunteers_coordinator = Conference.with_role(:volunteers_coordinator, user).pluck(:id) + + can [:index, :show, :update], Resource, conference_id: conf_ids_for_volunteers_coordinator + 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, :show], Role do |role| + role.resource_type == 'Conference' + 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' && role.name == 'volunteers_coordinator' && + (Conference.with_role(:volunteers_coordinator, user).pluck(:id).include? role.resource_id) + end + end +end diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index 02aa4882..55f430f2 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -11,14 +11,8 @@ describe 'User' do let!(:organization) { create(:organization) } let!(:my_conference) { create(:full_conference, organization: organization) } - let(:my_venue) { my_conference.venue || create(:venue, conference: my_conference) } - let(:my_registration) { create(:registration, conference: my_conference, user: admin) } - let(:other_registration) { create(:registration, conference: conference_public) } - let(:my_event) { create(:event_full, program: my_conference.program) } let(:my_room) { create(:room, venue: my_conference.venue) } - let!(:my_event_scheduled) { create(:event_full, program: my_conference.program, room_id: my_room.id) } - let(:other_event) { create(:event_full, program: conference_public.program) } let(:conference_not_public) { create(:conference, splashpage: create(:splashpage, public: false)) } let(:conference_public) { create(:full_conference, splashpage: create(:splashpage, public: true)) } @@ -28,7 +22,6 @@ describe 'User' do let(:commercial_event_confirmed) { create(:commercial, commercialable: event_confirmed) } let(:commercial_event_unconfirmed) { create(:commercial, commercialable: event_unconfirmed) } - let(:resource) { create(:resource, conference: my_conference)} let(:registration) { create(:registration) } let(:program_with_cfp) { create(:program, :with_cfp) } @@ -38,11 +31,6 @@ describe 'User' do let(:conference_with_closed_registration) { create(:conference) } let!(:closed_registration_period) { create(:registration_period, conference: conference_with_closed_registration, start_date: Date.current - 6.days, end_date: Date.current - 6.days) } - let!(:my_schedule) { create(:schedule, program: my_conference.program) } - let!(:other_schedule) { create(:schedule, program: conference_public.program) } - - let!(:my_event_schedule) { create(:event_schedule, schedule: my_schedule) } - let!(:other_event_schedule) { create(:event_schedule, schedule: other_schedule) } # Test abilities for not signed in users context 'when user is not signed in' do it{ should be_able_to(:index, Organization)} @@ -127,354 +115,5 @@ describe 'User' do it{ should be_able_to(:manage, user_commercial) } it{ should_not be_able_to(:manage, commercial_event_unconfirmed) } end - - context 'user #is_admin?' do - let(:venue) { my_conference.venue } - let(:room) { create(:room, venue: venue) } - let!(:event) { create(:event_full, program: my_conference.program, room_id: room.id) } - let(:user) { create(:admin) } - it{ should be_able_to(:manage, :all) } - it{ should_not be_able_to(:destroy, my_conference.program) } - it{ should_not be_able_to(:destroy, my_venue) } - end - - shared_examples 'user with any role' do - let!(:other_organization) { create(:organization) } - let!(:other_conference) { create(:conference, organization: other_organization) } - - it{ should_not be_able_to(:update, Role.find_by(name: 'organization_admin', resource: other_organization)) } - it{ should_not be_able_to(:edit, Role.find_by(name: 'organization_admin', resource: other_organization)) } - it{ should_not be_able_to(:show, Role.find_by(name: 'organization_admin', resource: other_organization)) } - - %w(organizer cfp info_desk volunteers_coordinator).each do |role| - it{ should_not be_able_to(:toggle_user, Role.find_by(name: role, resource: other_conference)) } - it{ should_not be_able_to(:update, Role.find_by(name: role, resource: other_conference)) } - it{ should_not be_able_to(:edit, Role.find_by(name: role, resource: other_conference)) } - 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 - end - - shared_examples 'user with non-organizer role' do |role_name| - %w(organizer cfp info_desk volunteers_coordinator).each do |role| - if role == role_name - it{ should be_able_to(:toggle_user, Role.find_by(name: role, resource: my_conference)) } - else - it{ should_not be_able_to(:toggle_user, Role.find_by(name: role, resource: my_conference)) } - end - it{ should_not be_able_to(:update, Role.find_by(name: role, resource: my_conference)) } - it{ should_not be_able_to(:edit, Role.find_by(name: role, resource: my_conference)) } - 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 - end - - context 'when user has the role organization_admin' do - let(:role) { Role.find_by(name: 'organization_admin', resource: organization) } - let(:user) { create(:user, role_ids: [role.id]) } - let(:other_organization) { create(:organization) } - let(:other_conference) { create(:conference, organization: other_organization) } - - it{ should be_able_to(:manage, my_conference) } - it{ should be_able_to(:read, organization) } - it{ should be_able_to(:update, organization) } - it{ should be_able_to(:destroy, organization) } - it{ should be_able_to(:new, Conference.new) } - it{ should be_able_to(:create, Conference.new(organization_id: organization.id)) } - it{ should_not be_able_to(:manage, other_conference) } - it{ should_not be_able_to(:create, Conference.new(organization_id: other_organization.id)) } - it{ should_not be_able_to(:new, Organization.new) } - it{ should_not be_able_to(:create, Organization.new) } - end - - context 'when user has the role organizer' do - let(:role) { Role.find_by(name: 'organizer', resource: my_conference) } - let(:user) { create(:user, role_ids: [role.id]) } - - it{ should_not be_able_to(:destroy, my_conference.program) } - it 'when there is a room assigned to an event' do - should_not be_able_to(:destroy, my_venue) - end - - it 'when there are no rooms used' do - my_event_scheduled.room_id = nil - my_event_scheduled.save! - my_event_scheduled.reload - should be_able_to(:destroy, my_venue) - end - - it{ should_not be_able_to(:new, Organization.new)} - it{ should_not be_able_to(:create, Organization.new)} - it{ should_not be_able_to(:new, Conference.new)} - it{ should_not be_able_to(:create, Conference.new) } - it{ should be_able_to(:read, my_conference) } - it{ should be_able_to(:update, my_conference) } - it{ should be_able_to(:destroy, my_conference) } - it{ should_not be_able_to(:manage, conference_public) } - it{ should be_able_to(:manage, my_conference.splashpage) } - it{ should_not be_able_to(:manage, conference_public.splashpage) } - it{ should be_able_to(:manage, my_conference.contact) } - it{ should_not be_able_to(:manage, conference_public.contact) } - it{ should be_able_to(:manage, my_conference.email_settings) } - it{ should_not be_able_to(:manage, conference_public.email_settings) } - it{ should be_able_to(:manage, my_conference.campaigns.first) } - it{ should_not be_able_to(:manage, conference_public.campaigns.first) } - it{ should be_able_to(:manage, my_conference.targets.first) } - it{ should_not be_able_to(:manage, conference_public.targets.first) } - it{ should be_able_to(:manage, my_conference.commercials.first) } - it{ should_not be_able_to(:manage, conference_public.commercials.first) } - it{ should be_able_to(:manage, my_conference.registration_period) } - it{ should_not be_able_to(:manage, conference_public.registration_period) } - it{ should be_able_to(:manage, my_conference.questions.first) } - it{ should_not be_able_to(:manage, conference_public.questions.first) } - it{ should be_able_to(:manage, my_conference.program.cfp) } - it{ should_not be_able_to(:manage, conference_public.program.cfp) } - it{ should be_able_to(:manage, my_schedule) } - it{ should_not be_able_to(:manage, other_schedule) } - it{ should be_able_to(:manage, my_event_schedule) } - it{ should_not be_able_to(:manage, other_event_schedule) } - it{ should be_able_to(:manage, my_conference.venue) } - it{ should_not be_able_to(:manage, conference_public.venue) } - it{ should be_able_to(:manage, my_conference.lodgings.first) } - it{ should_not be_able_to(:manage, conference_public.lodgings.first) } - it{ should be_able_to(:manage, my_conference.sponsors.first) } - it{ should_not be_able_to(:manage, conference_public.sponsors.first) } - it{ should be_able_to(:manage, my_conference.sponsorship_levels.first) } - it{ should_not be_able_to(:manage, conference_public.sponsorship_levels.first) } - it{ should be_able_to(:manage, my_conference.tickets.first) } - it{ should_not be_able_to(:manage, conference_public.tickets.first) } - - it{ should be_able_to(:manage, my_registration) } - it{ should_not be_able_to(:manage, other_registration) } - - it{ should be_able_to(:manage, my_event) } - it{ should_not be_able_to(:manage, other_event) } - it{ should be_able_to(:manage, my_event.event_type) } - it{ should_not be_able_to(:manage, other_event.event_type) } - it{ should be_able_to(:manage, my_event.track) } - it{ should_not be_able_to(:manage, other_event.track) } - it{ should be_able_to(:manage, my_event.difficulty_level) } - it{ should_not be_able_to(:manage, other_event.difficulty_level) } - it{ should be_able_to(:manage, my_event.commercials.first) } - it{ should_not be_able_to(:manage, other_event.commercials.first) } - it{ should be_able_to(:index, my_event.comment_threads.first) } - it{ should_not be_able_to(:index, other_event.comment_threads.first) } - - it{ should be_able_to(:manage, resource)} - - %w(organizer cfp info_desk volunteers_coordinator).each do |role| - it{ should be_able_to(:toggle_user, Role.find_by(name: role, resource: my_conference)) } - it{ should be_able_to(:edit, Role.find_by(name: role, resource: my_conference)) } - it{ should be_able_to(:update, Role.find_by(name: role, resource: my_conference)) } - 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 - - it_behaves_like 'user with any role' - end - - context 'when user has the role cfp' do - let(:role) { Role.find_by(name: 'cfp', resource: my_conference) } - let(:user) { create(:user, role_ids: [role.id]) } - - 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 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 be_able_to(:manage, my_conference.program.cfp) } - it{ should_not be_able_to(:manage, conference_public.program.cfp) } - it{ should 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 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, my_registration) } - it{ should_not be_able_to(:manage, other_registration) } - - it{ should be_able_to(:manage, my_event) } - it{ should_not be_able_to(:manage, other_event) } - it{ should be_able_to(:manage, my_event.event_type) } - it{ should_not be_able_to(:manage, other_event.event_type) } - it{ should be_able_to(:manage, my_event.track) } - it{ should_not be_able_to(:manage, other_event.track) } - it{ should be_able_to(:manage, my_event.difficulty_level) } - it{ should_not be_able_to(:manage, other_event.difficulty_level) } - it{ should be_able_to(:manage, my_event.commercials.first) } - it{ should_not be_able_to(:manage, other_event.commercials.first) } - it{ should 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(:index, resource)} - it{ should be_able_to(:show, resource)} - it{ should be_able_to(:update, resource)} - - it_behaves_like 'user with any role' - it_behaves_like 'user with non-organizer role', 'cfp' - end - - context 'when user has the role info_desk' do - let(:role) { Role.find_by(name: 'info_desk', resource: my_conference) } - let(:user) { create(:user, role_ids: [role.id]) } - - 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 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 be_able_to(:manage, my_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(:index, resource)} - it{ should be_able_to(:show, resource)} - it{ should be_able_to(:update, resource)} - - it_behaves_like 'user with any role' - it_behaves_like 'user with non-organizer role', 'info_desk' - end - - context 'when user has the role volunteers_coordinator' do - let(:role) { Role.find_by(name: 'volunteers_coordinator', resource: my_conference) } - let(:user) { create(:user, role_ids: [role.id]) } - - 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(:index, resource)} - it{ should be_able_to(:show, resource)} - it{ should be_able_to(:update, resource)} - - it 'should be_able to :manage Vposition' - it 'should be_able to :manage Vday' - - it_behaves_like 'user with any role' - it_behaves_like 'user with non-organizer role', 'volunteers_coordinator' - end end end diff --git a/spec/models/admin_ability_spec.rb b/spec/models/admin_ability_spec.rb new file mode 100644 index 00000000..486ff295 --- /dev/null +++ b/spec/models/admin_ability_spec.rb @@ -0,0 +1,396 @@ +require 'spec_helper' +require 'cancan/matchers' + +describe 'User with admin role' do + describe 'Abilities' do + let!(:admin) { create(:admin) } + + # see https://github.com/CanCanCommunity/cancancan/wiki/Testing-Abilities + subject(:ability){ AdminAbility.new(user) } + let(:user){ nil } + + let!(:organization) { create(:organization) } + let!(:my_conference) { create(:full_conference, organization: organization) } + let(:my_venue) { my_conference.venue || create(:venue, conference: my_conference) } + let(:my_registration) { create(:registration, conference: my_conference, user: admin) } + + let(:other_registration) { create(:registration, conference: conference_public) } + let(:my_event) { create(:event_full, program: my_conference.program) } + let(:my_room) { create(:room, venue: my_conference.venue) } + let!(:my_event_scheduled) { create(:event_full, program: my_conference.program, room_id: my_room.id) } + let(:other_event) { create(:event_full, program: conference_public.program) } + + let(:conference_not_public) { create(:conference, splashpage: create(:splashpage, public: false)) } + let(:conference_public) { create(:full_conference, splashpage: create(:splashpage, public: true)) } + + let(:event_confirmed) { create(:event, state: 'confirmed') } + let(:event_unconfirmed) { create(:event) } + + let(:commercial_event_confirmed) { create(:commercial, commercialable: event_confirmed) } + let(:commercial_event_unconfirmed) { create(:commercial, commercialable: event_unconfirmed) } + let(:resource) { create(:resource, conference: my_conference) } + let(:registration) { create(:registration) } + + let(:program_with_cfp) { create(:program, :with_cfp) } + let(:program_without_cfp) { create(:program) } + let(:conference_with_open_registration) { create(:conference) } + let!(:open_registration_period) { create(:registration_period, conference: conference_with_open_registration, start_date: Date.current - 6.days) } + let(:conference_with_closed_registration) { create(:conference) } + let!(:closed_registration_period) { create(:registration_period, conference: conference_with_closed_registration, start_date: Date.current - 6.days, end_date: Date.current - 6.days) } + + let!(:my_schedule) { create(:schedule, program: my_conference.program) } + let!(:other_schedule) { create(:schedule, program: conference_public.program) } + + let!(:my_event_schedule) { create(:event_schedule, schedule: my_schedule) } + let!(:other_event_schedule) { create(:event_schedule, schedule: other_schedule) } + + context 'user #is_admin?' do + let(:venue) { my_conference.venue } + let(:room) { create(:room, venue: venue) } + let!(:event) { create(:event_full, program: my_conference.program, room_id: room.id) } + let(:user) { create(:admin) } + it{ should be_able_to(:manage, :all) } + it{ should_not be_able_to(:destroy, my_conference.program) } + it{ should_not be_able_to(:destroy, my_venue) } + end + + shared_examples 'user with any role' do + let!(:other_organization) { create(:organization) } + let!(:other_conference) { create(:conference, organization: other_organization) } + + it{ should_not be_able_to(:update, Role.find_by(name: 'organization_admin', resource: other_organization)) } + it{ should_not be_able_to(:edit, Role.find_by(name: 'organization_admin', resource: other_organization)) } + it{ should_not be_able_to(:show, Role.find_by(name: 'organization_admin', resource: other_organization)) } + + %w[organizer cfp info_desk volunteers_coordinator].each do |role| + it{ should_not be_able_to(:toggle_user, Role.find_by(name: role, resource: other_conference)) } + it{ should_not be_able_to(:update, Role.find_by(name: role, resource: other_conference)) } + it{ should_not be_able_to(:edit, Role.find_by(name: role, resource: other_conference)) } + 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 + end + + shared_examples 'user with non-organizer role' do |role_name| + %w[organizer cfp info_desk volunteers_coordinator].each do |role| + if role == role_name + it{ should be_able_to(:toggle_user, Role.find_by(name: role, resource: my_conference)) } + else + it{ should_not be_able_to(:toggle_user, Role.find_by(name: role, resource: my_conference)) } + end + it{ should_not be_able_to(:update, Role.find_by(name: role, resource: my_conference)) } + it{ should_not be_able_to(:edit, Role.find_by(name: role, resource: my_conference)) } + 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 + end + + context 'when user has the role organization_admin' do + let(:role) { Role.find_by(name: 'organization_admin', resource: organization) } + let(:user) { create(:user, role_ids: [role.id]) } + let(:other_organization) { create(:organization) } + let(:other_conference) { create(:conference, organization: other_organization) } + + it{ should be_able_to(:manage, my_conference) } + it{ should be_able_to(:read, organization) } + it{ should be_able_to(:update, organization) } + it{ should be_able_to(:destroy, organization) } + it{ should be_able_to(:new, Conference.new) } + it{ should be_able_to(:create, Conference.new(organization_id: organization.id)) } + it{ should_not be_able_to(:manage, other_conference) } + it{ should_not be_able_to(:create, Conference.new(organization_id: other_organization.id)) } + it{ should_not be_able_to(:new, Organization.new) } + it{ should_not be_able_to(:create, Organization.new) } + end + + context 'when user has the role organizer' do + let(:role) { Role.find_by(name: 'organizer', resource: my_conference) } + let(:user) { create(:user, role_ids: [role.id]) } + + it{ should_not be_able_to(:destroy, my_conference.program) } + it 'when there is a room assigned to an event' do + should_not be_able_to(:destroy, my_venue) + end + + it 'when there are no rooms used' do + my_event_scheduled.room_id = nil + my_event_scheduled.save! + my_event_scheduled.reload + should be_able_to(:destroy, my_venue) + end + + it{ should_not be_able_to(:new, Organization.new) } + it{ should_not be_able_to(:create, Organization.new) } + it{ should_not be_able_to(:new, Conference.new) } + it{ should_not be_able_to(:create, Conference.new) } + it{ should be_able_to(:read, my_conference) } + it{ should be_able_to(:update, my_conference) } + it{ should be_able_to(:destroy, my_conference) } + it{ should_not be_able_to(:manage, conference_public) } + it{ should be_able_to(:manage, my_conference.splashpage) } + it{ should_not be_able_to(:manage, conference_public.splashpage) } + it{ should be_able_to(:manage, my_conference.contact) } + it{ should_not be_able_to(:manage, conference_public.contact) } + it{ should be_able_to(:manage, my_conference.email_settings) } + it{ should_not be_able_to(:manage, conference_public.email_settings) } + it{ should be_able_to(:manage, my_conference.campaigns.first) } + it{ should_not be_able_to(:manage, conference_public.campaigns.first) } + it{ should be_able_to(:manage, my_conference.targets.first) } + it{ should_not be_able_to(:manage, conference_public.targets.first) } + it{ should be_able_to(:manage, my_conference.commercials.first) } + it{ should_not be_able_to(:manage, conference_public.commercials.first) } + it{ should be_able_to(:manage, my_conference.registration_period) } + it{ should_not be_able_to(:manage, conference_public.registration_period) } + it{ should be_able_to(:manage, my_conference.questions.first) } + it{ should_not be_able_to(:manage, conference_public.questions.first) } + it{ should be_able_to(:manage, my_conference.program.cfp) } + it{ should_not be_able_to(:manage, conference_public.program.cfp) } + it{ should be_able_to(:manage, my_schedule) } + it{ should_not be_able_to(:manage, other_schedule) } + it{ should be_able_to(:manage, my_event_schedule) } + it{ should_not be_able_to(:manage, other_event_schedule) } + it{ should be_able_to(:manage, my_conference.venue) } + it{ should_not be_able_to(:manage, conference_public.venue) } + it{ should be_able_to(:manage, my_conference.lodgings.first) } + it{ should_not be_able_to(:manage, conference_public.lodgings.first) } + it{ should be_able_to(:manage, my_conference.sponsors.first) } + it{ should_not be_able_to(:manage, conference_public.sponsors.first) } + it{ should be_able_to(:manage, my_conference.sponsorship_levels.first) } + it{ should_not be_able_to(:manage, conference_public.sponsorship_levels.first) } + it{ should be_able_to(:manage, my_conference.tickets.first) } + it{ should_not be_able_to(:manage, conference_public.tickets.first) } + + it{ should be_able_to(:manage, my_registration) } + it{ should_not be_able_to(:manage, other_registration) } + + it{ should be_able_to(:manage, my_event) } + it{ should_not be_able_to(:manage, other_event) } + it{ should be_able_to(:manage, my_event.event_type) } + it{ should_not be_able_to(:manage, other_event.event_type) } + it{ should be_able_to(:manage, my_event.track) } + it{ should_not be_able_to(:manage, other_event.track) } + it{ should be_able_to(:manage, my_event.difficulty_level) } + it{ should_not be_able_to(:manage, other_event.difficulty_level) } + it{ should be_able_to(:manage, my_event.commercials.first) } + it{ should_not be_able_to(:manage, other_event.commercials.first) } + it{ should be_able_to(:index, my_event.comment_threads.first) } + it{ should_not be_able_to(:index, other_event.comment_threads.first) } + + it{ should be_able_to(:manage, resource) } + + %w[organizer cfp info_desk volunteers_coordinator].each do |role| + it{ should be_able_to(:toggle_user, Role.find_by(name: role, resource: my_conference)) } + it{ should be_able_to(:edit, Role.find_by(name: role, resource: my_conference)) } + it{ should be_able_to(:update, Role.find_by(name: role, resource: my_conference)) } + 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 + + it_behaves_like 'user with any role' + end + + context 'when user has the role cfp' do + let(:role) { Role.find_by(name: 'cfp', resource: my_conference) } + let(:user) { create(:user, role_ids: [role.id]) } + + 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 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 be_able_to(:manage, my_conference.program.cfp) } + it{ should_not be_able_to(:manage, conference_public.program.cfp) } + it{ should 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 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, my_registration) } + it{ should_not be_able_to(:manage, other_registration) } + + it{ should be_able_to(:manage, my_event) } + it{ should_not be_able_to(:manage, other_event) } + it{ should be_able_to(:manage, my_event.event_type) } + it{ should_not be_able_to(:manage, other_event.event_type) } + it{ should be_able_to(:manage, my_event.track) } + it{ should_not be_able_to(:manage, other_event.track) } + it{ should be_able_to(:manage, my_event.difficulty_level) } + it{ should_not be_able_to(:manage, other_event.difficulty_level) } + it{ should be_able_to(:manage, my_event.commercials.first) } + it{ should_not be_able_to(:manage, other_event.commercials.first) } + it{ should 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(:index, resource) } + it{ should be_able_to(:show, resource) } + it{ should be_able_to(:update, resource) } + + it_behaves_like 'user with any role' + it_behaves_like 'user with non-organizer role', 'cfp' + end + + context 'when user has the role info_desk' do + let(:role) { Role.find_by(name: 'info_desk', resource: my_conference) } + let(:user) { create(:user, role_ids: [role.id]) } + + 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 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 be_able_to(:manage, my_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(:index, resource) } + it{ should be_able_to(:show, resource) } + it{ should be_able_to(:update, resource) } + + it_behaves_like 'user with any role' + it_behaves_like 'user with non-organizer role', 'info_desk' + end + + context 'when user has the role volunteers_coordinator' do + let(:role) { Role.find_by(name: 'volunteers_coordinator', resource: my_conference) } + let(:user) { create(:user, role_ids: [role.id]) } + + 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(:index, resource) } + it{ should be_able_to(:show, resource) } + it{ should be_able_to(:update, resource) } + + it 'should be_able to :manage Vposition' + it 'should be_able to :manage Vday' + + it_behaves_like 'user with any role' + it_behaves_like 'user with non-organizer role', 'volunteers_coordinator' + end + end +end From d26a5dcf9b5e052d6e1735df0a52feded1d06b77 Mon Sep 17 00:00:00 2001 From: shlok007 Date: Tue, 11 Jul 2017 17:25:34 +0530 Subject: [PATCH 06/26] fix failing tests about accessing admin area --- app/models/admin_ability.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/models/admin_ability.rb b/app/models/admin_ability.rb index 99c80401..29253709 100644 --- a/app/models/admin_ability.rb +++ b/app/models/admin_ability.rb @@ -21,6 +21,7 @@ class AdminAbility can :manage, User, id: user.id can :manage, Registration, user_id: user.id + can :index, Conference can :show, Registration, &:new_record? can [:new, :create], Registration do |registration| @@ -48,7 +49,6 @@ class AdminAbility can [:destroy], Openid can :access, Admin - can [:show], Conference can :index, Commercial, commercialable_type: 'Conference' cannot [:edit, :update, :destroy], Question, global: true # for admins @@ -156,6 +156,9 @@ class AdminAbility # ids of all the conferences for which the user has the 'cfp' role conf_ids_for_cfp = Conference.with_role(:cfp, user).pluck(:id) + can :show, Conference do |conf| + conf_ids_for_cfp.include?(conf.id) + end can [:index, :show, :update], Resource, conference_id: conf_ids_for_cfp can :manage, Event, program: { conference_id: conf_ids_for_cfp } can :manage, EventType, program: { conference_id: conf_ids_for_cfp } @@ -196,6 +199,9 @@ class AdminAbility # ids of all the conferences for which the user has the 'info_desk' role conf_ids_for_info_desk = Conference.with_role(:info_desk, user).pluck(:id) + can :show, Conference do |conf| + conf_ids_for_info_desk.include?(conf.id) + end can [:index, :show, :update], Resource, conference_id: conf_ids_for_info_desk can :manage, Registration, conference_id: conf_ids_for_info_desk can :manage, Question, conference_id: conf_ids_for_info_desk @@ -219,6 +225,10 @@ class AdminAbility # ids of all the conferences for which the user has the 'volunteers_coordinator' role conf_ids_for_volunteers_coordinator = Conference.with_role(:volunteers_coordinator, user).pluck(:id) + can :show, Conference do |conf| + conf_ids_for_volunteers_coordinator.include?(conf.id) + end + can :show, Conference, conference_id: conf_ids_for_volunteers_coordinator can [:index, :show, :update], Resource, conference_id: conf_ids_for_volunteers_coordinator can :manage, Vposition, conference_id: conf_ids_for_volunteers_coordinator can :manage, Vday, conference_id: conf_ids_for_volunteers_coordinator From 05fdd443a433fa5f63001eb7a19935c7fe87470c Mon Sep 17 00:00:00 2001 From: shlok007 Date: Tue, 11 Jul 2017 20:56:02 +0530 Subject: [PATCH 07/26] fix failing tests for volunteers_coordinator --- app/models/admin_ability.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/models/admin_ability.rb b/app/models/admin_ability.rb index 29253709..006e919a 100644 --- a/app/models/admin_ability.rb +++ b/app/models/admin_ability.rb @@ -228,7 +228,6 @@ class AdminAbility can :show, Conference do |conf| conf_ids_for_volunteers_coordinator.include?(conf.id) end - can :show, Conference, conference_id: conf_ids_for_volunteers_coordinator can [:index, :show, :update], Resource, conference_id: conf_ids_for_volunteers_coordinator can :manage, Vposition, conference_id: conf_ids_for_volunteers_coordinator can :manage, Vday, conference_id: conf_ids_for_volunteers_coordinator From 98fc1137e17cc229e52482e02ed4cfa71022553f Mon Sep 17 00:00:00 2001 From: shlok007 Date: Thu, 13 Jul 2017 01:23:48 +0530 Subject: [PATCH 08/26] suggested changes --- app/models/ability.rb | 73 +++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/app/models/ability.rb b/app/models/ability.rb index 6581069c..afc51a68 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -7,48 +7,12 @@ class Ability if user.new_record? not_signed_in - elsif user.roles.any? || user.is_admin - common_abilities_for_admins(user) else signed_in(user) + common_abilities_for_admins(user) if user.roles.any? || user.is_admin? end end - # Abilities for users with roles wandering around in non-admin views. - def common_abilities_for_admins(user) - signed_in(user) - conf_ids_for_organizer = Conference.with_role(:organizer, user).pluck(:id) - conf_ids_for_cfp = Conference.with_role(:cfp, user).pluck(:id) - conf_ids_for_info_desk = Conference.with_role(:info_desk, user).pluck(:id) - - if conf_ids_for_organizer - - # To access splashpage of their conference if it is not public - can :show, Conference, id: conf_ids_for_organizer - - # To access conference/proposals/registrations - can :manage, Registration, conference_id: conf_ids_for_organizer - - # To access conference/proposals - can :manage, Event, program: { conference_id: conf_ids_for_organizer } - - # To access comment link in menu bar - can :index, Comment, commentable_type: 'Event', - commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_organizer).pluck(:id)).pluck(:id) - elsif conf_ids_for_cfp - - can :index, Comment, commentable_type: 'Event', - commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_cfp).pluck(:id)).pluck(:id) - can :manage, Event, program: { conference_id: conf_ids_for_cfp } - - elsif conf_ids_for_info_desk - can :manage, Registration, conference_id: conf_ids_for_info_desk - end - - can :access, Admin - can :manage, :all if user.is_admin - end - # Abilities for not signed in users (guests) def not_signed_in can [:index], Organization @@ -126,4 +90,39 @@ class Ability can [:destroy], Openid end + + # Abilities for users with roles wandering around in non-admin views. + def common_abilities_for_admins(user) + can :access, Admin + can :manage, :all if user.is_admin? + + conf_ids_for_organizer = Conference.with_role(:organizer, user).pluck(:id) + conf_ids_for_cfp = Conference.with_role(:cfp, user).pluck(:id) + conf_ids_for_info_desk = Conference.with_role(:info_desk, user).pluck(:id) + + if conf_ids_for_organizer + # To access splashpage of their conference if it is not public + can :show, Conference, id: conf_ids_for_organizer + # To access conference/proposals/registrations + can :manage, Registration, conference_id: conf_ids_for_organizer + # To access conference/proposals + can :manage, Event, program: { conference_id: conf_ids_for_organizer } + # To access comment link in menu bar + can :index, Comment, commentable_type: 'Event', + commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_organizer).pluck(:id)).pluck(:id) + end + + if conf_ids_for_cfp + # To access comment link in menu bar + can :index, Comment, commentable_type: 'Event', + commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_cfp).pluck(:id)).pluck(:id) + # To access conference/proposals + can :manage, Event, program: { conference_id: conf_ids_for_cfp } + end + + if conf_ids_for_info_desk + # To access conference/proposals/registrations + can :manage, Registration, conference_id: conf_ids_for_info_desk + end + end end From 68fc750e9f41a53171dcdee4fc608554c17ef0d7 Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Thu, 8 Jun 2017 12:25:33 +0300 Subject: [PATCH 09/26] 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 --- .haml-lint_todo.yml | 6 + .rubocop.yml | 1 + .rubocop_todo.yml | 3 + app/controllers/admin/base_controller.rb | 3 +- app/controllers/admin/roles_controller.rb | 49 +++- app/controllers/admin/tracks_controller.rb | 11 +- app/controllers/tracks_controller.rb | 47 ++++ app/models/admin_ability.rb | 50 +++- app/models/track.rb | 24 ++ app/models/user.rb | 1 + app/views/admin/roles/_form.html.haml | 2 +- app/views/admin/roles/_users.html.haml | 2 +- app/views/admin/roles/index.html.haml | 18 +- app/views/admin/roles/show.html.haml | 10 +- app/views/admin/tracks/_form.html.haml | 2 + app/views/admin/tracks/index.html.haml | 25 ++ app/views/tracks/_form.html.haml | 17 ++ app/views/tracks/index.html.haml | 43 +++ app/views/tracks/show.html.haml | 26 ++ config/routes.rb | 15 +- ...ctive_and_submitter_reference_to_tracks.rb | 8 + db/schema.rb | 11 +- spec/factories/tracks.rb | 6 + spec/features/track_organizer_ability_spec.rb | 244 ++++++++++++++++++ spec/models/admin_ability_spec.rb | 112 ++++++++ spec/models/track_spec.rb | 57 ++++ 26 files changed, 766 insertions(+), 27 deletions(-) create mode 100644 app/controllers/tracks_controller.rb create mode 100644 app/views/tracks/_form.html.haml create mode 100644 app/views/tracks/index.html.haml create mode 100644 app/views/tracks/show.html.haml create mode 100644 db/migrate/20170705075039_add_state_cfp_active_and_submitter_reference_to_tracks.rb create mode 100644 spec/features/track_organizer_ability_spec.rb create mode 100644 spec/models/track_spec.rb diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index 0f6f5408..df4d0708 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -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: diff --git a/.rubocop.yml b/.rubocop.yml index 22e17db0..5d24032d 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -30,3 +30,4 @@ Metrics/BlockLength: Exclude: - 'spec/models/conference_spec.rb' - 'spec/features/ability_spec.rb' + - 'spec/models/ability_spec.rb' diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 68360907..1c188b60 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -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' diff --git a/app/controllers/admin/base_controller.rb b/app/controllers/admin/base_controller.rb index 3b28a230..631dd4d8 100644 --- a/app/controllers/admin/base_controller.rb +++ b/app/controllers/admin/base_controller.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 diff --git a/app/controllers/admin/roles_controller.rb b/app/controllers/admin/roles_controller.rb index 3bc37bc3..15bf5e2b 100644 --- a/app/controllers/admin/roles_controller.rb +++ b/app/controllers/admin/roles_controller.rb @@ -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,7 +107,12 @@ module Admin # 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) + 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 diff --git a/app/controllers/admin/tracks_controller.rb b/app/controllers/admin/tracks_controller.rb index 4fc9d9c7..c229b9b8 100644 --- a/app/controllers/admin/tracks_controller.rb +++ b/app/controllers/admin/tracks_controller.rb @@ -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 diff --git a/app/controllers/tracks_controller.rb b/app/controllers/tracks_controller.rb new file mode 100644 index 00000000..f346b0d1 --- /dev/null +++ b/app/controllers/tracks_controller.rb @@ -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 diff --git a/app/models/admin_ability.rb b/app/models/admin_ability.rb index 006e919a..d43683fd 100644 --- a/app/models/admin_ability.rb +++ b/app/models/admin_ability.rb @@ -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 diff --git a/app/models/track.rb b/app/models/track.rb index f65506d8..a38cf458 100644 --- a/app/models/track.rb +++ b/app/models/track.rb @@ -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 diff --git a/app/models/user.rb b/app/models/user.rb index 6ffb739f..e79d0b2a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -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) } diff --git a/app/views/admin/roles/_form.html.haml b/app/views/admin/roles/_form.html.haml index eb10b23f..2204ef89 100644 --- a/app/views/admin/roles/_form.html.haml +++ b/app/views/admin/roles/_form.html.haml @@ -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 diff --git a/app/views/admin/roles/_users.html.haml b/app/views/admin/roles/_users.html.haml index 9d73421b..f32c9a99 100644 --- a/app/views/admin/roles/_users.html.haml +++ b/app/views/admin/roles/_users.html.haml @@ -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 diff --git a/app/views/admin/roles/index.html.haml b/app/views/admin/roles/index.html.haml index c6e4c773..1310b133 100644 --- a/app/views/admin/roles/index.html.haml +++ b/app/views/admin/roles/index.html.haml @@ -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 - = 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' + - 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' diff --git a/app/views/admin/roles/show.html.haml b/app/views/admin/roles/show.html.haml index 69d02f6b..d7dcef8d 100644 --- a/app/views/admin/roles/show.html.haml +++ b/app/views/admin/roles/show.html.haml @@ -6,14 +6,20 @@ 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' + - 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 diff --git a/app/views/admin/tracks/_form.html.haml b/app/views/admin/tracks/_form.html.haml index c3c7cf26..76833e66 100644 --- a/app/views/admin/tracks/_form.html.haml +++ b/app/views/admin/tracks/_form.html.haml @@ -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' } diff --git a/app/views/admin/tracks/index.html.haml b/app/views/admin/tracks/index.html.haml index f9ed9036..94193088 100644 --- a/app/views/admin/tracks/index.html.haml +++ b/app/views/admin/tracks/index.html.haml @@ -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), diff --git a/app/views/tracks/_form.html.haml b/app/views/tracks/_form.html.haml new file mode 100644 index 00000000..a10a72a9 --- /dev/null +++ b/app/views/tracks/_form.html.haml @@ -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' } diff --git a/app/views/tracks/index.html.haml b/app/views/tracks/index.html.haml new file mode 100644 index 00000000..a6347747 --- /dev/null +++ b/app/views/tracks/index.html.haml @@ -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' diff --git a/app/views/tracks/show.html.haml b/app/views/tracks/show.html.haml new file mode 100644 index 00000000..7ea80c58 --- /dev/null +++ b/app/views/tracks/show.html.haml @@ -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' diff --git a/config/routes.rb b/config/routes.rb index db88613f..1643fc6b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -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 diff --git a/db/migrate/20170705075039_add_state_cfp_active_and_submitter_reference_to_tracks.rb b/db/migrate/20170705075039_add_state_cfp_active_and_submitter_reference_to_tracks.rb new file mode 100644 index 00000000..9cb7f7de --- /dev/null +++ b/db/migrate/20170705075039_add_state_cfp_active_and_submitter_reference_to_tracks.rb @@ -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 diff --git a/db/schema.rb b/db/schema.rb index b9f8e3f4..f1a213a5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -483,16 +483,21 @@ ActiveRecord::Schema.define(version: 20170711102511) do end create_table "tracks", force: :cascade do |t| - t.string "guid", null: false - t.string "name", null: false + t.string "guid", null: false + t.string "name", null: false t.text "description" t.string "color" t.datetime "created_at" t.datetime "updated_at" t.integer "program_id" - t.string "short_name", null: false + 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 diff --git a/spec/factories/tracks.rb b/spec/factories/tracks.rb index 4334cb4c..091d8d07 100644 --- a/spec/factories/tracks.rb +++ b/spec/factories/tracks.rb @@ -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 diff --git a/spec/features/track_organizer_ability_spec.rb b/spec/features/track_organizer_ability_spec.rb new file mode 100644 index 00000000..f32392ba --- /dev/null +++ b/spec/features/track_organizer_ability_spec.rb @@ -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 diff --git a/spec/models/admin_ability_spec.rb b/spec/models/admin_ability_spec.rb index 486ff295..9baae4a9 100644 --- a/spec/models/admin_ability_spec.rb +++ b/spec/models/admin_ability_spec.rb @@ -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 diff --git a/spec/models/track_spec.rb b/spec/models/track_spec.rb new file mode 100644 index 00000000..840641cb --- /dev/null +++ b/spec/models/track_spec.rb @@ -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 From 9671696adf7e42d4610b96e381459ecaa22548b8 Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Fri, 7 Jul 2017 00:21:26 +0300 Subject: [PATCH 10/26] Add to_param to the Track model And update the urls --- app/controllers/admin/roles_controller.rb | 8 ++++---- app/models/track.rb | 4 ++++ app/views/admin/roles/index.html.haml | 13 +++++++------ app/views/admin/roles/show.html.haml | 2 +- app/views/admin/tracks/_form.html.haml | 2 +- app/views/admin/tracks/index.html.haml | 11 ++++++----- app/views/tracks/_form.html.haml | 2 +- app/views/tracks/index.html.haml | 4 ++-- app/views/tracks/show.html.haml | 2 +- spec/features/track_organizer_ability_spec.rb | 12 ++++++------ 10 files changed, 33 insertions(+), 27 deletions(-) diff --git a/app/controllers/admin/roles_controller.rb b/app/controllers/admin/roles_controller.rb index 15bf5e2b..e4b83241 100644 --- a/app/controllers/admin/roles_controller.rb +++ b/app/controllers/admin/roles_controller.rb @@ -15,7 +15,7 @@ module Admin def show @url = if @track - toggle_user_track_admin_conference_role_path(@conference.short_title, @role.name, @track.name.tr(' ', '_')) + toggle_user_track_admin_conference_role_path(@conference.short_title, @role.name, @track) else toggle_user_admin_conference_role_path(@conference.short_title, @role.name) end @@ -24,7 +24,7 @@ module Admin def edit @url = if @track - track_admin_conference_role_path(@conference.short_title, @role.name, @track.name.tr(' ', '_')) + track_admin_conference_role_path(@conference.short_title, @role.name, @track) else admin_conference_role_path(@conference.short_title, @role.name) end @@ -36,7 +36,7 @@ module Admin if @role.update_attributes(role_params) url = if @track - track_admin_conference_role_path(@conference.short_title, @role.name, @track.name.tr(' ', '_')) + track_admin_conference_role_path(@conference.short_title, @role.name, @track) else admin_conference_role_path(@conference.short_title, @role.name) end @@ -55,7 +55,7 @@ module Admin state = user_params[:state] url = if @track - track_admin_conference_role_path(@conference.short_title, @role.name, @track.name.tr(' ', '_')) + track_admin_conference_role_path(@conference.short_title, @role.name, @track) else admin_conference_role_path(@conference.short_title, @role.name) end diff --git a/app/models/track.rb b/app/models/track.rb index a38cf458..2b37d1bb 100644 --- a/app/models/track.rb +++ b/app/models/track.rb @@ -39,6 +39,10 @@ class Track < ActiveRecord::Base false end + def to_param + short_name + end + private def generate_guid diff --git a/app/views/admin/roles/index.html.haml b/app/views/admin/roles/index.html.haml index 1310b133..4a100025 100644 --- a/app/views/admin/roles/index.html.haml +++ b/app/views/admin/roles/index.html.haml @@ -22,19 +22,20 @@ %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) + = link_to role.resource.name, admin_conference_program_track_path(@conference.short_title, role.resource) %td = role.users.pluck(:name).first(5).join ', ' - if role.users.count > 5 - = link_to '...', admin_conference_role_path(@conference.short_title, role.name) + - if role.resource_type == 'Track' + = link_to '...', track_admin_conference_role_path(@conference.short_title, role.name, role.resource) + - else + = 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' + = link_to 'Users', track_admin_conference_role_path(@conference.short_title, role.name, role.resource), 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' + = link_to 'Edit', track_edit_admin_conference_role_path(@conference.short_title, role.name, role.resource), 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 diff --git a/app/views/admin/roles/show.html.haml b/app/views/admin/roles/show.html.haml index d7dcef8d..ee249975 100644 --- a/app/views/admin/roles/show.html.haml +++ b/app/views/admin/roles/show.html.haml @@ -7,7 +7,7 @@ = @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' + = link_to 'Edit', track_edit_admin_conference_role_path(@conference.short_title, @role.name, @track), 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 diff --git a/app/views/admin/tracks/_form.html.haml b/app/views/admin/tracks/_form.html.haml index 76833e66..fe7f014a 100644 --- a/app/views/admin/tracks/_form.html.haml +++ b/app/views/admin/tracks/_form.html.haml @@ -8,7 +8,7 @@ Track .row .col-md-12 - = semantic_form_for(@track, url: (@track.new_record? ? admin_conference_program_tracks_path : admin_conference_program_track_path(@conference.short_title, @track.short_name))) do |f| + = semantic_form_for(@track, url: (@track.new_record? ? admin_conference_program_tracks_path : admin_conference_program_track_path(@conference.short_title, @track))) do |f| = f.input :name = f.input :short_name, hint: "A short and unique handle for the track, using only letters, numbers, underscores, and dashes. This will be used to identify the track in URLs etc. Example: 'my_awesome_track'", input_html: { required: 'required', pattern: '[a-zA-Z0-9_-]+', title: 'Only letters, numbers, underscores, and dashes.' } = f.input :color, input_html: {size: 6, type: 'color'}, required: true diff --git a/app/views/admin/tracks/index.html.haml b/app/views/admin/tracks/index.html.haml index 94193088..9abf1d98 100644 --- a/app/views/admin/tracks/index.html.haml +++ b/app/views/admin/tracks/index.html.haml @@ -20,7 +20,7 @@ - @tracks.each do |track| %tr %td - = link_to(admin_conference_program_track_path(@conference.short_title, track.short_name)) do + = link_to(admin_conference_program_track_path(@conference.short_title, track)) do = track.name %td = track.short_name @@ -54,11 +54,12 @@ %i.fa.fa-check %td .btn-group{role: "group"} - = link_to 'Edit', edit_admin_conference_program_track_path(@conference.short_title, track.short_name), + = link_to 'Edit', edit_admin_conference_program_track_path(@conference.short_title, track), method: :get, class: 'btn btn-primary' - = link_to 'Delete', admin_conference_program_track_path(@conference.short_title, track.short_name), - method: :delete, class: 'btn btn-danger', - data: { confirm: "Do you really want to delete #{track.name}? Attention: This track will be removed from all Events that have it set" } + - if can? :destroy, track + = link_to 'Delete', admin_conference_program_track_path(@conference.short_title, track), + method: :delete, class: 'btn btn-danger', + data: { confirm: "Do you really want to delete #{track.name}? Attention: This track will be removed from all Events that have it set" } .row .col-md-12.text-right = link_to 'New Track', new_admin_conference_program_track_path(@conference.short_title), class: 'btn btn-success' diff --git a/app/views/tracks/_form.html.haml b/app/views/tracks/_form.html.haml index a10a72a9..0e48a851 100644 --- a/app/views/tracks/_form.html.haml +++ b/app/views/tracks/_form.html.haml @@ -9,7 +9,7 @@ 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| + = semantic_form_for(@track, url: (@track.new_record? ? conference_program_tracks_path : conference_program_track_path(@conference.short_title, @track))) do |f| = f.input :name = f.input :short_name, hint: "A short and unique handle for the track, using only letters, numbers, underscores, and dashes. This will be used to identify the track in URLs etc. Example: 'my_awesome_track'", input_html: { required: 'required', pattern: '[a-zA-Z0-9_-]+', title: 'Only letters, numbers, underscores, and dashes.' } = f.input :color, input_html: {size: 6, type: 'color'}, required: true diff --git a/app/views/tracks/index.html.haml b/app/views/tracks/index.html.haml index a6347747..d4670bf4 100644 --- a/app/views/tracks/index.html.haml +++ b/app/views/tracks/index.html.haml @@ -21,7 +21,7 @@ - @tracks.each do |track| %tr %td - = link_to(conference_program_track_path(@conference.short_title, track.short_name)) do + = link_to(conference_program_track_path(@conference.short_title, track)) do = track.name %td = track.short_name @@ -34,7 +34,7 @@ %td = track.state %td - = link_to 'Edit', edit_conference_program_track_path(@conference.short_title, track.short_name), + = link_to 'Edit', edit_conference_program_track_path(@conference.short_title, track), method: :get, class: 'btn btn-primary' .row diff --git a/app/views/tracks/show.html.haml b/app/views/tracks/show.html.haml index 7ea80c58..c08818eb 100644 --- a/app/views/tracks/show.html.haml +++ b/app/views/tracks/show.html.haml @@ -23,4 +23,4 @@ = @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' + = link_to 'Edit Track request', edit_conference_program_track_path(@conference.short_title, @track), class: 'btn btn-primary' diff --git a/spec/features/track_organizer_ability_spec.rb b/spec/features/track_organizer_ability_spec.rb index f32392ba..f79eba05 100644 --- a/spec/features/track_organizer_ability_spec.rb +++ b/spec/features/track_organizer_ability_spec.rb @@ -209,17 +209,17 @@ feature 'Has correct abilities' do 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) + visit admin_conference_program_track_path(conference.short_title, other_track) expect(current_path).to eq root_path - visit edit_admin_conference_program_track_path(conference.short_title, other_track.short_name) + visit edit_admin_conference_program_track_path(conference.short_title, other_track) 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 admin_conference_program_track_path(conference.short_title, self_organized_track) + expect(current_path).to eq admin_conference_program_track_path(conference.short_title, self_organized_track) - 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 edit_admin_conference_program_track_path(conference.short_title, self_organized_track) + expect(current_path).to eq edit_admin_conference_program_track_path(conference.short_title, self_organized_track) visit admin_conference_roles_path(conference.short_title) expect(current_path).to eq admin_conference_roles_path(conference.short_title) From e3b51dfc2b818c2ed75df915da900495efa1707d Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Fri, 7 Jul 2017 16:31:24 +0300 Subject: [PATCH 11/26] Add TrackControllers specs --- app/controllers/tracks_controller.rb | 2 +- app/views/admin/tracks/index.html.haml | 4 +- .../admin/tracks_controller_spec.rb | 256 ++++++++++++++++++ spec/controllers/tracks_controller_spec.rb | 179 ++++++++++++ 4 files changed, 438 insertions(+), 3 deletions(-) create mode 100644 spec/controllers/admin/tracks_controller_spec.rb create mode 100644 spec/controllers/tracks_controller_spec.rb diff --git a/app/controllers/tracks_controller.rb b/app/controllers/tracks_controller.rb index f346b0d1..529767cd 100644 --- a/app/controllers/tracks_controller.rb +++ b/app/controllers/tracks_controller.rb @@ -31,7 +31,7 @@ class TracksController < ApplicationController def update if @track.update_attributes(track_params) - redirect_to admin_conference_program_tracks_path(conference_id: @conference.short_title), + redirect_to 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('. ')}." diff --git a/app/views/admin/tracks/index.html.haml b/app/views/admin/tracks/index.html.haml index 9abf1d98..1cda360a 100644 --- a/app/views/admin/tracks/index.html.haml +++ b/app/views/admin/tracks/index.html.haml @@ -42,9 +42,9 @@ N/A %td - if track.self_organized? - = check_box_tag "#{@conference.short_title}_#{track.id}", track.id, track.cfp_active, + = check_box_tag "#{@conference.short_title}_#{track.short_name}", track.id, track.cfp_active, class: 'switch-checkbox', method: :patch, - url: toggle_cfp_inclusion_admin_conference_program_track_path(@conference.short_title, id: track.id)+"?included=", + url: toggle_cfp_inclusion_admin_conference_program_track_path(@conference.short_title, id: track.short_name)+"?included=", data: { size: 'small', on_color: 'success', off_color: 'warning', diff --git a/spec/controllers/admin/tracks_controller_spec.rb b/spec/controllers/admin/tracks_controller_spec.rb new file mode 100644 index 00000000..2177af2f --- /dev/null +++ b/spec/controllers/admin/tracks_controller_spec.rb @@ -0,0 +1,256 @@ +require 'spec_helper' + +describe Admin::TracksController do + let(:admin) { create(:admin) } + + let(:conference) { create(:conference) } + let!(:track) { create(:track, program: conference.program, color: '#800080') } + let!(:self_organized_track) { create(:track, :self_organized, program: conference.program) } + + before :each do + sign_in(admin) + end + + describe 'GET #index' do + before :each do + get :index, conference_id: conference.short_title + end + + it 'assigns @tracks with the correct values' do + expect(assigns(:tracks).length).to eq 2 + expect(assigns(:tracks).include?(track)).to eq true + expect(assigns(:tracks).include?(self_organized_track)).to eq true + end + + it 'renders the index template' do + expect(response).to render_template :index + end + end + + describe 'GET #show' do + before :each do + get :show, conference_id: conference.short_title, id: track.short_name + end + + it 'assigns the correct track' do + expect(assigns(:track)).to eq track + end + + it 'renders the show template' do + expect(response).to render_template :show + end + end + + describe 'GET #new' do + before :each do + get :new, conference_id: conference.short_title + end + + it 'assigns a new track with the correct conference' do + expect(assigns(:track)).to be_a Track + expect(assigns(:track).new_record?).to eq true + expect(assigns(:track).program_id).to eq conference.program.id + end + + it 'renders the new template' do + expect(response).to render_template :new + end + end + + describe 'POST #create' do + context 'saves successfuly' do + before :each do + post :create, track: attributes_for(:track), conference_id: conference.short_title + end + + it 'assigns a new track with the correct conference' do + expect(assigns(:track)).to be_a Track + expect(assigns(:track).new_record?).to eq false + expect(assigns(:track).program_id).to eq conference.program.id + end + + it 'redirects to admin tracks index path' do + expect(response).to redirect_to admin_conference_program_tracks_path(conference_id: conference.short_title) + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match('Track successfully created.') + end + + it 'creates new track' do + expect(Track.find(assigns(:track).id)).to be_a Track + end + end + + context 'save fails' do + before :each do + allow_any_instance_of(Track).to receive(:save).and_return(false) + post :create, track: attributes_for(:track, short_name: 'my_track'), conference_id: conference.short_title + end + + it 'assigns a new track with the correct conference' do + expect(assigns(:track)).to be_a Track + expect(assigns(:track).new_record?).to eq true + expect(assigns(:track).program_id).to eq conference.program.id + end + + it 'renders the new template' do + expect(response).to render_template :new + end + + it 'shows error in flash message' do + expect(flash[:error]).to match("Creating Track failed: #{assigns(:track).errors.full_messages.join('. ')}.") + end + + it 'does not create a new track' do + expect(conference.program.tracks.find_by(short_name: 'my_track')).to eq nil + end + end + end + + describe 'GET #edit' do + before :each do + get :edit, conference_id: conference.short_title, id: track.short_name + end + + it 'assigns the correct track' do + expect(assigns(:track)).to eq track + end + + it 'renders the show template' do + expect(response).to render_template :edit + end + end + + describe 'PATCH #update' do + context 'updates successfully' do + before :each do + patch :update, track: attributes_for(:track, color: '#FF0000'), + conference_id: conference.short_title, + id: track.short_name + end + + it 'assigns the correct track' do + expect(assigns(:track)).to eq track + end + + it 'redirects to admin tracks index path' do + expect(response).to redirect_to admin_conference_program_tracks_path(conference_id: conference.short_title) + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match('Track successfully updated.') + end + + it 'updates the track' do + track.reload + expect(track.color).to eq '#FF0000' + end + end + + context 'update fails' do + before :each do + allow_any_instance_of(Track).to receive(:save).and_return(false) + patch :update, track: attributes_for(:track, color: '#FF0000'), + conference_id: conference.short_title, + id: track.short_name + end + + it 'assigns the correct track' do + expect(assigns(:track)).to eq track + end + + it 'renders edit template' do + expect(response).to render_template :edit + end + + it 'shows error in flash message' do + expect(flash[:error]).to match("Track update failed: #{assigns(:track).errors.full_messages.join('. ')}.") + end + + it 'does not update the track' do + track.reload + expect(track.color).to eq '#800080' + end + end + end + + describe 'DELETE #destroy' do + context 'deletes successfully' do + before :each do + delete :destroy, conference_id: conference.short_title, id: track.short_name + end + + it 'redirects to admin tracks index path' do + expect(response).to redirect_to admin_conference_program_tracks_path(conference_id: conference.short_title) + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match('Track successfully deleted.') + end + + it 'deletes the track' do + expect(Track.find_by(id: track)).to eq nil + end + end + + context 'delete fails' do + before :each do + allow_any_instance_of(Track).to receive(:destroy).and_return(false) + delete :destroy, conference_id: conference.short_title, id: track.short_name + end + + it 'assigns the correct track' do + expect(assigns(:track)).to eq track + end + + it 'redirects to admin tracks index path' do + expect(response).to redirect_to admin_conference_program_tracks_path(conference_id: conference.short_title) + end + + it 'shows error in flash message' do + expect(flash[:error]).to match("Track couldn't be deleted. #{track.errors.full_messages.join('. ')}.") + end + + it 'does not delete the track' do + expect(Track.find(track.id)).to eq track + end + end + end + + describe 'PATCH #toggle_cfp_inclusion' do + context 'cfp_active is false' do + before :each do + self_organized_track.cfp_active = false + self_organized_track.save! + patch :toggle_cfp_inclusion, conference_id: conference.short_title, id: self_organized_track.short_name + self_organized_track.reload + end + + it 'assigns the correct track' do + expect(assigns(:track)).to eq self_organized_track + end + + it 'becomes true' do + expect(self_organized_track.cfp_active).to eq true + end + end + + context 'cfp_active is true' do + before :each do + self_organized_track.cfp_active = true + self_organized_track.save! + patch :toggle_cfp_inclusion, conference_id: conference.short_title, id: self_organized_track.short_name + self_organized_track.reload + end + + it 'assigns the correct track' do + expect(assigns(:track)).to eq self_organized_track + end + + it 'becomes false' do + expect(self_organized_track.cfp_active).to eq false + end + end + end +end diff --git a/spec/controllers/tracks_controller_spec.rb b/spec/controllers/tracks_controller_spec.rb new file mode 100644 index 00000000..373435c2 --- /dev/null +++ b/spec/controllers/tracks_controller_spec.rb @@ -0,0 +1,179 @@ +require 'spec_helper' + +describe TracksController do + # A regular user should be used when the track requests have been enabled + let(:user) { create(:admin) } + + let(:conference) { create(:conference) } + let!(:regular_track) { create(:track, program: conference.program) } + let!(:self_organized_track) { create(:track, :self_organized, program: conference.program, submitter: user, color: '#800080') } + + before :each do + sign_in(user) + end + + describe 'GET #index' do + before :each do + get :index, conference_id: conference.short_title + end + + it 'assigns @tracks with the correct values' do + expect(assigns(:tracks).length).to eq 1 + expect(assigns(:tracks).include?(regular_track)).to eq false + expect(assigns(:tracks).include?(self_organized_track)).to eq true + end + + it 'renders the index template' do + expect(response).to render_template :index + end + end + + describe 'GET #show' do + before :each do + get :show, conference_id: conference.short_title, id: self_organized_track.short_name + end + + it 'assigns the correct track' do + expect(assigns(:track)).to eq self_organized_track + end + + it 'renders the show template' do + expect(response).to render_template :show + end + end + + describe 'GET #new' do + before :each do + get :new, conference_id: conference.short_title + end + + it 'assigns a new track with the correct conference' do + expect(assigns(:track)).to be_a Track + expect(assigns(:track).new_record?).to eq true + expect(assigns(:track).program_id).to eq conference.program.id + end + + it 'renders the new template' do + expect(response).to render_template :new + end + end + + describe 'POST #create' do + context 'saves successfuly' do + before :each do + post :create, track: attributes_for(:track, short_name: 'my_track'), conference_id: conference.short_title + end + + it 'redirects to tracks index path' do + expect(response).to redirect_to conference_program_tracks_path(conference_id: conference.short_title) + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match('Track request successfully created.') + end + + it 'creates new track' do + expect(assigns(:track).new_record?).to eq false + end + + it 'the new tracks has the correct attributes' do + expect(assigns(:track).program_id).to eq conference.program.id + expect(assigns(:track).submitter).to eq user + expect(assigns(:track).state).to eq 'new' + expect(assigns(:track).cfp_active).to eq false + end + end + + context 'save fails' do + before :each do + allow_any_instance_of(Track).to receive(:save).and_return(false) + post :create, track: attributes_for(:track, short_name: 'my_track'), conference_id: conference.short_title + end + + it 'assigns a new track with the correct conference' do + expect(assigns(:track)).to be_a Track + expect(assigns(:track).new_record?).to eq true + expect(assigns(:track).program_id).to eq conference.program.id + end + + it 'renders the new template' do + expect(response).to render_template :new + end + + it 'shows error in flash message' do + expect(flash[:error]).to match("Creating Track request failed: #{assigns(:track).errors.full_messages.join('. ')}.") + end + + it 'does not create a new track' do + expect(conference.program.tracks.find_by(short_name: 'my_track')).to eq nil + end + end + end + + describe 'GET #edit' do + before :each do + get :edit, conference_id: conference.short_title, id: self_organized_track.short_name + end + + it 'assigns the correct track' do + expect(assigns(:track)).to eq self_organized_track + end + + it 'renders the show template' do + expect(response).to render_template :edit + end + end + + describe 'PATCH #update' do + context 'updates successfully' do + before :each do + patch :update, track: attributes_for(:track, color: '#FF0000'), + conference_id: conference.short_title, + id: self_organized_track.short_name + end + + it 'assigns the correct track' do + expect(assigns(:track)).to eq self_organized_track + end + + it 'redirects to tracks index path' do + expect(response).to redirect_to conference_program_tracks_path(conference_id: conference.short_title) + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match('Track request successfully updated.') + end + + it 'updates the track' do + self_organized_track.reload + expect(self_organized_track.color).to eq '#FF0000' + end + end + + context 'update fails' do + before :each do + allow_any_instance_of(Track).to receive(:save).and_return(false) + patch :update, track: attributes_for(:track, color: '#FF0000'), + conference_id: conference.short_title, + id: self_organized_track.short_name + end + + it 'assigns the correct track' do + expect(assigns(:track)).to eq self_organized_track + end + + it 'renders edit template' do + expect(response).to render_template :edit + end + + it 'shows error in flash message' do + expect(flash[:error]).to match("Track request update failed: #{assigns(:track).errors.full_messages.join('. ')}.") + end + + it 'does not update the track' do + self_organized_track.reload + expect(self_organized_track.color).to eq '#800080' + end + end + end +end From 9c58397cd21c19d706227a3c0741c7baea9de07e Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Wed, 5 Jul 2017 23:31:22 +0300 Subject: [PATCH 12/26] Enable Style/IndentationWidth cop The offenses were fixed manually --- .rubocop_todo.yml | 11 --- app/helpers/format_helper.rb | 9 +-- app/serializers/conference_serializer.rb | 2 +- ...23203_add_events_per_week_to_conference.rb | 76 +++++++++---------- lib/tasks/demo_data_for_development.rake | 50 ++++++------ spec/models/ability_spec.rb | 6 +- 6 files changed, 71 insertions(+), 83 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 1c188b60..9523593a 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -469,17 +469,6 @@ Style/IndentationConsistency: - 'app/models/event.rb' - 'spec/controllers/subscriptions_controller_spec.rb' -# Offense count: 6 -# Cop supports --auto-correct. -# Configuration parameters: Width, IgnoredPatterns. -Style/IndentationWidth: - Exclude: - - 'app/helpers/format_helper.rb' - - 'app/serializers/conference_serializer.rb' - - 'db/migrate/20140701123203_add_events_per_week_to_conference.rb' - - 'lib/tasks/demo_data_for_development.rake' - - 'spec/models/ability_spec.rb' - # Offense count: 4 # Cop supports --auto-correct. Style/LeadingCommentSpace: diff --git a/app/helpers/format_helper.rb b/app/helpers/format_helper.rb index 472edc38..334c70bf 100644 --- a/app/helpers/format_helper.rb +++ b/app/helpers/format_helper.rb @@ -102,13 +102,12 @@ module FormatHelper end end - # rubocop:disable Lint/EndAlignment def word_pluralize(count, singular, plural = nil) word = if (count == 1 || count =~ /^1(\.0+)?$/) - singular - else - plural || singular.pluralize - end + singular + else + plural || singular.pluralize + end "#{word}" end diff --git a/app/serializers/conference_serializer.rb b/app/serializers/conference_serializer.rb index a7e0c1da..7bb96131 100644 --- a/app/serializers/conference_serializer.rb +++ b/app/serializers/conference_serializer.rb @@ -60,7 +60,7 @@ class ConferenceSerializer < ActiveModel::Serializer def date_range if defined? date_string(object.start_date, object.end_date) - date_string(object.start_date, object.end_date).try(:split, ',').try(:first) + date_string(object.start_date, object.end_date).try(:split, ',').try(:first) end end end diff --git a/db/migrate/20140701123203_add_events_per_week_to_conference.rb b/db/migrate/20140701123203_add_events_per_week_to_conference.rb index 5c2eb9d4..36bbf40d 100644 --- a/db/migrate/20140701123203_add_events_per_week_to_conference.rb +++ b/db/migrate/20140701123203_add_events_per_week_to_conference.rb @@ -22,50 +22,50 @@ class AddEventsPerWeekToConference < ActiveRecord::Migration if event conference = TempConference.find_by_id(event.conference_id) if conference - week = event_version.created_at.end_of_week + week = event_version.created_at.end_of_week - no_events = { - new: 0, - withdrawn: 0, - unconfirmed: 0, - confirmed: 0, - canceled: 0, - rejected: 0, - } - - if !conference.events_per_week - conference.events_per_week = { - week => no_events + no_events = { + new: 0, + withdrawn: 0, + unconfirmed: 0, + confirmed: 0, + canceled: 0, + rejected: 0, } - elsif !conference.events_per_week[week] - conference.events_per_week[week] = no_events - end - if event_version.object_changes && - event_version.event == 'create' - - # Increment the new state - conference.events_per_week[week][:new] += 1 - elsif event_version.object_changes && - event_version.object_changes[:state] - - prev_state = event_version.object_changes[:state][0].to_sym - next_state = event_version.object_changes[:state][1].to_sym - - # Backward compatibility: deprecated state :review now :new - if prev_state == :review - prev_state = :new - elsif next_state == :review - next_state = :new + if !conference.events_per_week + conference.events_per_week = { + week => no_events + } + elsif !conference.events_per_week[week] + conference.events_per_week[week] = no_events end - # Increment the next state - conference.events_per_week[week][next_state] += 1 + if event_version.object_changes && + event_version.event == 'create' - # Decrement the previous state - conference.events_per_week[week][prev_state] -= 1 - end - conference.save + # Increment the new state + conference.events_per_week[week][:new] += 1 + elsif event_version.object_changes && + event_version.object_changes[:state] + + prev_state = event_version.object_changes[:state][0].to_sym + next_state = event_version.object_changes[:state][1].to_sym + + # Backward compatibility: deprecated state :review now :new + if prev_state == :review + prev_state = :new + elsif next_state == :review + next_state = :new + end + + # Increment the next state + conference.events_per_week[week][next_state] += 1 + + # Decrement the previous state + conference.events_per_week[week][prev_state] -= 1 + end + conference.save end end end diff --git a/lib/tasks/demo_data_for_development.rake b/lib/tasks/demo_data_for_development.rake index a86371b3..5be30c8e 100644 --- a/lib/tasks/demo_data_for_development.rake +++ b/lib/tasks/demo_data_for_development.rake @@ -4,37 +4,37 @@ namespace :data do include FactoryGirl::Syntax::Methods def generate_program conference - program = conference.program - user1 = create(:user) - user2 = create(:user) + program = conference.program + user1 = create(:user) + user2 = create(:user) - conference_rooms = conference.venue.rooms + conference_rooms = conference.venue.rooms - selected_schedule = create(:schedule, program: program) - demo_schedule = create(:schedule, program: program) - program.update_attributes!(selected_schedule: selected_schedule) + selected_schedule = create(:schedule, program: program) + demo_schedule = create(:schedule, program: program) + program.update_attributes!(selected_schedule: selected_schedule) - create(:event, program: program, title: 'Demo Event', abstract: 'This is a demo event instance whose state not defined.') - create(:event, program: program, title: 'Demo Rejected Event', state: 'rejected', abstract: 'This is demo event instance in a rejected state.') - create(:event, program: program, title: 'Demo Unconfirmed Event', state: 'unconfirmed', abstract: 'This is a demo event instance in unconfirmed state.') - create(:event, program: program, title: 'Demo Confirmed Unscheduled Event', state: 'confirmed', abstract: 'This is a demo event instance in a confirmed state.') + create(:event, program: program, title: 'Demo Event', abstract: 'This is a demo event instance whose state not defined.') + create(:event, program: program, title: 'Demo Rejected Event', state: 'rejected', abstract: 'This is demo event instance in a rejected state.') + create(:event, program: program, title: 'Demo Unconfirmed Event', state: 'unconfirmed', abstract: 'This is a demo event instance in unconfirmed state.') + create(:event, program: program, title: 'Demo Confirmed Unscheduled Event', state: 'confirmed', abstract: 'This is a demo event instance in a confirmed state.') - first_scheduled_event = create(:event, program: program, title: 'first_scheduled_event', state: 'confirmed', abstract: 'This is a demo scheduled event instance.') - second_scheduled_event = create(:event, program: program, title: 'second_scheduled_event', state: 'confirmed', abstract: 'This is a demo scheduled event instance.') - multiple_speaker_event = create(:event, program: program, title: 'multiple_speaker_event', state: 'confirmed', abstract: 'This is a demo scheduled event instance having multiple speakers.') + first_scheduled_event = create(:event, program: program, title: 'first_scheduled_event', state: 'confirmed', abstract: 'This is a demo scheduled event instance.') + second_scheduled_event = create(:event, program: program, title: 'second_scheduled_event', state: 'confirmed', abstract: 'This is a demo scheduled event instance.') + multiple_speaker_event = create(:event, program: program, title: 'multiple_speaker_event', state: 'confirmed', abstract: 'This is a demo scheduled event instance having multiple speakers.') - create(:event_user, event: multiple_speaker_event, user: user1, event_role: 'speaker') - create(:event_user, event: multiple_speaker_event, user: user2, event_role: 'speaker') + create(:event_user, event: multiple_speaker_event, user: user1, event_role: 'speaker') + create(:event_user, event: multiple_speaker_event, user: user2, event_role: 'speaker') - create(:event_schedule, event: first_scheduled_event, schedule: selected_schedule, start_time: conference.start_date + conference.start_hour.hours, room: conference_rooms.first) - create(:event_schedule, event: second_scheduled_event, schedule: selected_schedule, start_time: conference.start_date + conference.start_hour.hours + 15.minutes, room: conference_rooms.second) - create(:event_schedule, event: multiple_speaker_event, schedule: selected_schedule, start_time: conference.start_date + conference.start_hour.hours + 30.minutes, room: conference_rooms.third) - create(:event_schedule, event: first_scheduled_event, schedule: demo_schedule, start_time: conference.start_date + conference.start_hour.hours + 15.minutes, room: conference_rooms.third) - create(:event_schedule, event: second_scheduled_event, schedule: demo_schedule, start_time: conference.start_date + conference.start_hour.hours + 30.minutes, room: conference_rooms.third) - create(:event_schedule, event: multiple_speaker_event, schedule: demo_schedule, start_time: conference.start_date + conference.start_hour.hours, room: conference_rooms.first) + create(:event_schedule, event: first_scheduled_event, schedule: selected_schedule, start_time: conference.start_date + conference.start_hour.hours, room: conference_rooms.first) + create(:event_schedule, event: second_scheduled_event, schedule: selected_schedule, start_time: conference.start_date + conference.start_hour.hours + 15.minutes, room: conference_rooms.second) + create(:event_schedule, event: multiple_speaker_event, schedule: selected_schedule, start_time: conference.start_date + conference.start_hour.hours + 30.minutes, room: conference_rooms.third) + create(:event_schedule, event: first_scheduled_event, schedule: demo_schedule, start_time: conference.start_date + conference.start_hour.hours + 15.minutes, room: conference_rooms.third) + create(:event_schedule, event: second_scheduled_event, schedule: demo_schedule, start_time: conference.start_date + conference.start_hour.hours + 30.minutes, room: conference_rooms.third) + create(:event_schedule, event: multiple_speaker_event, schedule: demo_schedule, start_time: conference.start_date + conference.start_hour.hours, room: conference_rooms.first) - create(:registration, user: user1, conference: conference) - create(:registration, user: user2, conference: conference) + create(:registration, user: user1, conference: conference) + create(:registration, user: user2, conference: conference) end # This is a full conference demo instance that will happen in the future. @@ -73,5 +73,5 @@ namespace :data do # Registration for this conference has reached its limit. conference = create(:full_conference, title: 'Zypper Docker Conference', short_title: 'zypper', registration_limit: 2, start_date: 3.days.from_now, end_date: 7.days.from_now, start_hour: 7, end_hour: 19, description: 'This is a full conference demo instance. Its registrations has reached the limit.') generate_program conference - end + end end diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index 55f430f2..2144cec6 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -40,9 +40,9 @@ describe 'User' do it{ should_not be_able_to(:show, conference_not_public)} it do - conference_public.program.schedule_public = true - conference_public.program.save - should be_able_to(:schedule, conference_public) + conference_public.program.schedule_public = true + conference_public.program.save + should be_able_to(:schedule, conference_public) end it{ should_not be_able_to(:schedule, conference_not_public)} From b86472ac3c732c65715bd6462fef39a44a0d36fe Mon Sep 17 00:00:00 2001 From: nasia Date: Fri, 7 Jul 2017 16:13:35 +0300 Subject: [PATCH 13/26] Add Call for Booths --- .haml-lint_todo.yml | 1 + app/models/cfp.rb | 2 +- app/views/admin/cfps/_booths_cfp.html.haml | 12 ++++++++++ spec/factories/cfps.rb | 2 +- spec/features/cfp_ability_spec.rb | 22 ++++++++++++++++--- .../organization_admin_ability_spec.rb | 22 ++++++++++++++++--- spec/features/organizer_ability_spec.rb | 22 ++++++++++++++++--- spec/models/program_spec.rb | 22 +++++++++++++++++-- 8 files changed, 92 insertions(+), 13 deletions(-) create mode 100644 app/views/admin/cfps/_booths_cfp.html.haml diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index df4d0708..4644a6bb 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -180,6 +180,7 @@ linters: InstanceVariables: exclude: - "app/views/admin/campaigns/_form.html.haml" + - "app/views/admin/cfps/_booths_cfp.html.haml" - "app/views/admin/cfps/_form.html.haml" - "app/views/admin/conferences/_todo_list.html.haml" - "app/views/admin/difficulty_levels/_form.html.haml" diff --git a/app/models/cfp.rb b/app/models/cfp.rb index f06bec7b..97f276c9 100644 --- a/app/models/cfp.rb +++ b/app/models/cfp.rb @@ -1,7 +1,7 @@ # cannot delete program if there are events submitted class Cfp < ActiveRecord::Base - TYPES = %w(events).freeze + TYPES = %w(events booths).freeze scope :for_events, (-> { find_by(cfp_type: 'events') }) diff --git a/app/views/admin/cfps/_booths_cfp.html.haml b/app/views/admin/cfps/_booths_cfp.html.haml new file mode 100644 index 00000000..89012336 --- /dev/null +++ b/app/views/admin/cfps/_booths_cfp.html.haml @@ -0,0 +1,12 @@ +%dt + Start Date +%dd + = @cfp.start_date.strftime('%A, %B %e. %Y') +%dt + End Date +%dd + = @cfp.end_date.strftime('%A, %B %e. %Y') +%dt + Days Left +%dd + = pluralize(@cfp.remaining_days, 'day') diff --git a/spec/factories/cfps.rb b/spec/factories/cfps.rb index 6a8e96ed..6b061d53 100644 --- a/spec/factories/cfps.rb +++ b/spec/factories/cfps.rb @@ -3,7 +3,7 @@ FactoryGirl.define do factory :cfp do start_date { 1.day.ago } - end_date { 6.days.from_now } + end_date { 2.days.from_now } cfp_type 'events' program diff --git a/spec/features/cfp_ability_spec.rb b/spec/features/cfp_ability_spec.rb index 7af4e119..b12a2ef5 100644 --- a/spec/features/cfp_ability_spec.rb +++ b/spec/features/cfp_ability_spec.rb @@ -60,16 +60,32 @@ feature 'Has correct abilities' do visit edit_admin_conference_program_path(conference.short_title) expect(current_path).to eq(edit_admin_conference_program_path(conference.short_title)) + # Only event type exists + visit new_admin_conference_program_cfp_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_program_cfp_path(conference.short_title)) + + # Both event and booth exists + cfb = create(:cfp, cfp_type: 'booths', program: conference.program) 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(edit_admin_conference_program_cfp_path(conference.short_title, conference.program.cfp)) + conference.program.cfp.destroy! visit new_admin_conference_program_cfp_path(conference.short_title) expect(current_path).to eq new_admin_conference_program_cfp_path(conference.short_title) - create(:cfp, program: conference.program) - visit edit_admin_conference_program_cfp_path(conference.short_title, conference.program.cfp) - expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference.short_title, conference.program.cfp)) + # Only booth exists + visit new_admin_conference_program_cfp_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_program_cfp_path(conference.short_title)) + + visit edit_admin_conference_program_cfp_path(conference.short_title, cfb) + expect(current_path). to eq(edit_admin_conference_program_cfp_path(conference.short_title, cfb)) + + cfb.destroy + visit new_admin_conference_program_cfp_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_program_cfp_path(conference.short_title)) create(:event, program: conference.program) visit edit_admin_conference_program_event_path(conference.short_title, conference.program.events.first) diff --git a/spec/features/organization_admin_ability_spec.rb b/spec/features/organization_admin_ability_spec.rb index aefb89f4..274d345f 100644 --- a/spec/features/organization_admin_ability_spec.rb +++ b/spec/features/organization_admin_ability_spec.rb @@ -102,16 +102,32 @@ feature 'Has correct abilities' do visit edit_admin_conference_program_path(conference.short_title) expect(current_path).to eq(edit_admin_conference_program_path(conference.short_title)) + # Only event exists + visit new_admin_conference_program_cfp_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_program_cfp_path(conference.short_title)) + + # Both event and booth exists + cfb = create(:cfp, cfp_type: 'booths', program: conference.program) 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(edit_admin_conference_program_cfp_path(conference.short_title, conference.program.cfp)) + conference.program.cfp.destroy! visit new_admin_conference_program_cfp_path(conference.short_title) expect(current_path).to eq new_admin_conference_program_cfp_path(conference.short_title) - create(:cfp, program: conference.program) - visit edit_admin_conference_program_cfp_path(conference.short_title, conference.program.cfp) - expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference.short_title, conference.program.cfp)) + # Only booth exists + visit new_admin_conference_program_cfp_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_program_cfp_path(conference.short_title)) + + visit edit_admin_conference_program_cfp_path(conference.short_title, cfb) + expect(current_path). to eq(edit_admin_conference_program_cfp_path(conference.short_title, cfb)) + + cfb.destroy + visit new_admin_conference_program_cfp_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_program_cfp_path(conference.short_title)) visit admin_conference_program_events_path(conference.short_title) expect(current_path).to eq(admin_conference_program_events_path(conference.short_title)) diff --git a/spec/features/organizer_ability_spec.rb b/spec/features/organizer_ability_spec.rb index 34d87b0a..10c5d726 100644 --- a/spec/features/organizer_ability_spec.rb +++ b/spec/features/organizer_ability_spec.rb @@ -108,16 +108,32 @@ feature 'Has correct abilities' do visit edit_admin_conference_program_path(conference.short_title) expect(current_path).to eq(edit_admin_conference_program_path(conference.short_title)) + # Only event type exists + visit new_admin_conference_program_cfp_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_program_cfp_path(conference.short_title)) + + # Both event and booth exists + cfb = create(:cfp, cfp_type: 'booths', program: conference.program) 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(edit_admin_conference_program_cfp_path(conference.short_title, conference.program.cfp)) + conference.program.cfp.destroy! visit new_admin_conference_program_cfp_path(conference.short_title) expect(current_path).to eq new_admin_conference_program_cfp_path(conference.short_title) - create(:cfp, program: conference.program) - visit edit_admin_conference_program_cfp_path(conference.short_title, conference.program.cfp) - expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference.short_title, conference.program.cfp)) + # Only booth exists + visit new_admin_conference_program_cfp_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_program_cfp_path(conference.short_title)) + + visit edit_admin_conference_program_cfp_path(conference.short_title, cfb) + expect(current_path). to eq(edit_admin_conference_program_cfp_path(conference.short_title, cfb)) + + cfb.destroy + visit new_admin_conference_program_cfp_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_program_cfp_path(conference.short_title)) visit admin_conference_program_events_path(conference.short_title) expect(current_path).to eq(admin_conference_program_events_path(conference.short_title)) diff --git a/spec/models/program_spec.rb b/spec/models/program_spec.rb index 208ca386..d81e32bc 100644 --- a/spec/models/program_spec.rb +++ b/spec/models/program_spec.rb @@ -253,10 +253,28 @@ describe Program do end describe '#remaining_cfp_types' do - it 'returns an array with the types for which a cfp doesn\'t exist' do + it 'returns an array with the types for which a cfp doesn\'t exist, when only the Event type does' do expect(program.remaining_cfp_types).to eq(Cfp::TYPES) - create(:cfp, cfp_type: 'events', program: program, end_date: Date.current + 1) + create(:cfp, cfp_type: 'events', program: program) + expect(program.remaining_cfp_types).to eq(['booths']) + end + + it 'returns an array with the types for which a cfp doesn\'t exist, when only the Booth type does' do + expect(program.remaining_cfp_types).to eq(Cfp::TYPES) + create(:cfp, cfp_type: 'booths', program: program) + expect(program.remaining_cfp_types).to eq(['events']) + end + + it 'returns an empty array when all the cfp types exist' do + expect(program.remaining_cfp_types).to eq(Cfp::TYPES) + create(:cfp, cfp_type: 'events', program: program) + create(:cfp, cfp_type: 'booths', program: program) expect(program.remaining_cfp_types).to eq([]) end + + it 'returns all the possible cfp types when there is no existed cfp type' do + expect(program.remaining_cfp_types).to eq(Cfp::TYPES) + expect(program.remaining_cfp_types). to eq(%w[events booths]) + end end end From b2bd6080c2e3949389d47731d965b510ef35a84d Mon Sep 17 00:00:00 2001 From: Hernan Schmidt Date: Fri, 14 Jul 2017 14:02:55 +0200 Subject: [PATCH 14/26] Update Rubocop to 0.49.1 --- Gemfile | 2 +- Gemfile.lock | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 1af89f34..46c8731e 100644 --- a/Gemfile +++ b/Gemfile @@ -205,7 +205,7 @@ group :development do gem 'spring-commands-rspec' gem 'haml_lint', '~> 0.24.0' # for static code analisys - gem 'rubocop', '~> 0.48.1', require: false + gem 'rubocop', '~> 0.49.0', require: false # as database gem 'sqlite3' # to open mails diff --git a/Gemfile.lock b/Gemfile.lock index 5ef3f60c..effbde5b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -323,6 +323,7 @@ GEM activerecord (>= 3.0, < 6.0) activesupport (>= 3.0, < 6.0) request_store (~> 1.1) + parallel (1.11.2) parser (2.4.0.0) ast (~> 2.2) pdf-core (0.2.5) @@ -405,7 +406,8 @@ GEM activesupport (= 4.2.7.1) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) - rainbow (2.2.1) + rainbow (2.2.2) + rake rake (10.5.0) rb-fsevent (0.9.4) rb-inotify (0.9.4) @@ -453,7 +455,8 @@ GEM rspec-mocks (~> 3.0.0) rspec-support (~> 3.0.0) rspec-support (3.0.2) - rubocop (0.48.1) + rubocop (0.49.1) + parallel (~> 1.10) parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) @@ -521,7 +524,7 @@ GEM unf (0.1.4) unf_ext unf_ext (0.0.7.2) - unicode-display_width (1.2.1) + unicode-display_width (1.3.0) unicode_utils (1.4.0) unobtrusive_flash (3.1.0) railties @@ -634,7 +637,7 @@ DEPENDENCIES rqrcode rspec-activemodel-mocks rspec-rails - rubocop (~> 0.48.1) + rubocop (~> 0.49.0) ruby-oembed sass-rails (>= 4.0.2) selectize-rails From 523203ac74910d83f7ecad944317a73b059cc4d7 Mon Sep 17 00:00:00 2001 From: Hernan Schmidt Date: Fri, 14 Jul 2017 14:04:46 +0200 Subject: [PATCH 15/26] Update rubocop_todo.yml Generated automatically by `rubocop --auto-gen-config` --- .rubocop_todo.yml | 762 +++++++++++++++++----------------------------- 1 file changed, 287 insertions(+), 475 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 9523593a..7a9ab03c 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,12 +1,12 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2017-05-06 17:45:40 +0530 using RuboCop version 0.48.1. +# on 2017-07-14 12:03:16 +0000 using RuboCop version 0.49.1. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 13 +# Offense count: 15 # Cop supports --auto-correct. # Configuration parameters: Include, TreatCommentsAsGroupSeparators. # Include: **/Gemfile, **/gems.rb @@ -14,29 +14,271 @@ Bundler/OrderedGems: Exclude: - 'Gemfile' -# Offense count: 29 -Lint/AmbiguousBlockAssociation: +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. +# SupportedStyles: with_first_parameter, with_fixed_indentation +Layout/AlignParameters: Exclude: - - 'app/models/comment.rb' - - 'app/models/event.rb' - - 'app/models/event_schedule.rb' - - 'app/models/ticket_purchase.rb' - - 'app/models/user.rb' - - 'spec/controllers/admin/conferences_controller_spec.rb' - - 'spec/controllers/admin/event_schedules_controller_spec.rb' - - 'spec/controllers/admin/registration_periods_controller_spec.rb' - - 'spec/controllers/proposals_controller_spec.rb' - - 'spec/controllers/schedules_controller_spec.rb' - - 'spec/models/user_spec.rb' - - 'spec/controllers/admin/users_controller_spec.rb' + - 'Vagrantfile' + +# Offense count: 9 +# Cop supports --auto-correct. +Layout/ClosingParenthesisIndentation: + Exclude: + - 'app/controllers/conference_registrations_controller.rb' + - 'spec/support/omniauth_macros.rb' + +# Offense count: 14 +# Cop supports --auto-correct. +Layout/CommentIndentation: + Exclude: + - 'app/controllers/admin/comments_controller.rb' + - 'app/controllers/admin/difficulty_levels_controller.rb' + - 'app/models/conference.rb' + - 'app/models/program.rb' + - 'app/models/track.rb' + - 'spec/features/volunteers_spec.rb' # Offense count: 1 # Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleAlignWith, SupportedStylesAlignWith. -# SupportedStylesAlignWith: either, start_of_block, start_of_line -Lint/BlockAlignment: +Layout/EmptyLineAfterMagicComment: Exclude: - - 'lib/tasks/demo_data_for_development.rake' + - 'spec/models/conference_spec.rb' + +# Offense count: 104 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: empty_lines, no_empty_lines +Layout/EmptyLinesAroundBlockBody: + Enabled: false + +# Offense count: 1 +# Cop supports --auto-correct. +Layout/EmptyLinesAroundExceptionHandlingKeywords: + Exclude: + - 'app/models/payment.rb' + +# Offense count: 9 +# Cop supports --auto-correct. +# Configuration parameters: AllowForAlignment, ForceEqualSignAlignment. +Layout/ExtraSpacing: + Exclude: + - 'Guardfile' + - 'app/controllers/application_controller.rb' + - 'config.ru' + - 'db/migrate/20140623101032_create_ahoy_events.rb' + - 'db/migrate/20140701123203_add_events_per_week_to_conference.rb' + - 'db/migrate/20140719160903_create_delayed_jobs.rb' + - 'spec/models/conference_spec.rb' + +# Offense count: 42 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. +# SupportedStyles: consistent, special_for_inner_method_call, special_for_inner_method_call_in_parentheses +Layout/FirstParameterIndentation: + Enabled: false + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. +# SupportedStyles: special_inside_parentheses, consistent, align_brackets +Layout/IndentArray: + Exclude: + - 'app/models/conference.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: IndentationWidth. +Layout/IndentAssignment: + Exclude: + - 'app/helpers/format_helper.rb' + - 'app/models/conference.rb' + +# Offense count: 3 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. +# SupportedStyles: special_inside_parentheses, consistent, align_braces +Layout/IndentHash: + Exclude: + - 'app/models/user.rb' + - 'db/migrate/20140701123203_add_events_per_week_to_conference.rb' + +# Offense count: 3 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: normal, rails +Layout/IndentationConsistency: + Exclude: + - 'app/controllers/users_controller.rb' + - 'app/models/event.rb' + - 'spec/controllers/subscriptions_controller_spec.rb' + +# Offense count: 4 +# Cop supports --auto-correct. +Layout/LeadingCommentSpace: + Exclude: + - 'Guardfile' + - 'app/models/comment.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: symmetrical, new_line, same_line +Layout/MultilineArrayBraceLayout: + Exclude: + - 'app/controllers/conference_registrations_controller.rb' + +# Offense count: 5 +# Cop supports --auto-correct. +Layout/MultilineBlockLayout: + Exclude: + - 'app/serializers/conference_serializer.rb' + +# Offense count: 6 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: symmetrical, new_line, same_line +Layout/MultilineHashBraceLayout: + Exclude: + - 'app/serializers/conference_serializer.rb' + - 'spec/models/event_spec.rb' + +# Offense count: 40 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: symmetrical, new_line, same_line +Layout/MultilineMethodCallBraceLayout: + Enabled: false + +# Offense count: 55 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. +# SupportedStyles: aligned, indented, indented_relative_to_receiver +Layout/MultilineMethodCallIndentation: + Enabled: false + +# Offense count: 23 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. +# SupportedStyles: aligned, indented +Layout/MultilineOperationIndentation: + Exclude: + - 'app/controllers/admin/events_controller.rb' + - 'app/controllers/application_controller.rb' + - 'app/models/conference.rb' + - 'app/models/event.rb' + - 'db/migrate/20140701123203_add_events_per_week_to_conference.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +Layout/SpaceAfterComma: + Exclude: + - 'lib/tasks/data_demo.rake' + +# Offense count: 3 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: space, no_space +Layout/SpaceAroundEqualsInParameterDefault: + Exclude: + - 'app/helpers/format_helper.rb' + - 'app/models/event.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: AllowForAlignment. +Layout/SpaceAroundOperators: + Exclude: + - 'lib/tasks/data.rake' + +# Offense count: 416 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: space, no_space +Layout/SpaceBeforeBlockBraces: + Enabled: false + +# Offense count: 1 +# Cop supports --auto-correct. +Layout/SpaceBeforeComma: + Exclude: + - 'lib/tasks/data_demo.rake' + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: AllowForAlignment. +Layout/SpaceBeforeFirstArg: + Exclude: + - 'spec/controllers/admin/roles_controller_spec.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +Layout/SpaceBeforeSemicolon: + Exclude: + - 'Guardfile' + +# Offense count: 51 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SupportedStylesForEmptyBraces, SpaceBeforeBlockParameters. +# SupportedStyles: space, no_space +# SupportedStylesForEmptyBraces: space, no_space +Layout/SpaceInsideBlockBraces: + Exclude: + - 'app/controllers/admin/comments_controller.rb' + - 'app/controllers/admin/events_controller.rb' + - 'app/controllers/admin/questions_controller.rb' + - 'app/helpers/application_helper.rb' + - 'app/models/program.rb' + - 'app/models/ticket.rb' + - 'app/models/user.rb' + - 'lib/tasks/events_registrations.rake' + - 'spec/controllers/admin/event_schedules_controller_spec.rb' + - 'spec/controllers/admin/schedules_controller_spec.rb' + - 'spec/features/splashpage_spec.rb' + - 'spec/models/ability_spec.rb' + - 'spec/models/user_spec.rb' + +# Offense count: 19 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SupportedStylesForEmptyBraces. +# SupportedStyles: space, no_space, compact +# SupportedStylesForEmptyBraces: space, no_space +Layout/SpaceInsideHashLiteralBraces: + Exclude: + - 'app/controllers/admin/conferences_controller.rb' + - 'app/controllers/api/v1/speakers_controller.rb' + - 'app/models/conference.rb' + - 'app/models/event_type.rb' + - 'app/models/user.rb' + - 'spec/models/event_spec.rb' + - 'spec/models/payment_spec.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +Layout/SpaceInsidePercentLiteralDelimiters: + Exclude: + - 'Gemfile' + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: final_newline, final_blank_line +Layout/TrailingBlankLines: + Exclude: + - 'lib/tasks/event_attatchments.rake' + - 'lib/tasks/roles.rake' + +# Offense count: 13 +Lint/AmbiguousBlockAssociation: + Exclude: + - 'spec/controllers/admin/conferences_controller_spec.rb' + - 'spec/controllers/admin/event_schedules_controller_spec.rb' + - 'spec/controllers/admin/registration_periods_controller_spec.rb' + - 'spec/controllers/admin/users_controller_spec.rb' + - 'spec/controllers/proposals_controller_spec.rb' + - 'spec/controllers/schedules_controller_spec.rb' + - 'spec/models/user_spec.rb' # Offense count: 2 Lint/DuplicatedKey: @@ -50,6 +292,12 @@ Lint/IneffectiveAccessModifier: - 'app/models/commercial.rb' - 'app/models/conference.rb' +# Offense count: 2 +Lint/ScriptPermission: + Exclude: + - 'Guardfile' + - 'Rakefile' + # Offense count: 1 # Cop supports --auto-correct. # Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments. @@ -57,194 +305,40 @@ Lint/UnusedBlockArgument: Exclude: - 'lib/tasks/user.rake' -# Offense count: 108 +# Offense count: 114 Metrics/AbcSize: - Max: 75 - Exclude: - - 'app/controllers/admin/conferences_controller.rb' + Max: 86 -# Offense count: 202 +# Offense count: 233 # Configuration parameters: CountComments, ExcludedMethods. Metrics/BlockLength: - Max: 487 + Max: 471 -# Offense count: 21 +# Offense count: 23 Metrics/CyclomaticComplexity: Max: 12 -# Offense count: 1991 +# Offense count: 2353 # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. # URISchemes: http, https Metrics/LineLength: Max: 619 -# Offense count: 115 +# Offense count: 120 # Configuration parameters: CountComments. Metrics/MethodLength: Max: 56 -# Offense count: 2 +# Offense count: 3 # Configuration parameters: CountComments. Metrics/ModuleLength: - Max: 472 - Exclude: - - 'app/helpers/application_helper.rb' + Max: 159 - -# Offense count: 14 +# Offense count: 15 Metrics/PerceivedComplexity: - Max: 15 - Exclude: - - 'app/controllers/admin/roles_controller.rb' + Max: 16 -# Offense count: 11 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, Include. -# SupportedStyles: action, filter -# Include: app/controllers/**/*.rb -Rails/ActionFilter: - Exclude: - - 'app/controllers/admin/base_controller.rb' - - 'app/controllers/admin/registrations_controller.rb' - - 'app/controllers/application_controller.rb' - - 'app/controllers/conference_registrations_controller.rb' - - 'app/controllers/subscriptions_controller.rb' - - 'app/controllers/ticket_purchases_controller.rb' - - 'app/controllers/tickets_controller.rb' - - 'app/controllers/users/omniauth_callbacks_controller.rb' - -# Offense count: 7 -# Cop supports --auto-correct. -# Configuration parameters: NilOrEmpty, NotPresent, UnlessPresent. -Rails/Blank: - Exclude: - - 'app/models/program.rb' - - 'app/models/user.rb' - - 'spec/factories/event_schedule.rb' - -# Offense count: 139 -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: strict, flexible -Rails/Date: - Enabled: false - -# Offense count: 3 -# Cop supports --auto-correct. -# Configuration parameters: Whitelist. -# Whitelist: find_by_sql -Rails/DynamicFindBy: - Exclude: - - 'app/controllers/admin/events_controller.rb' - - 'db/migrate/20140701123203_add_events_per_week_to_conference.rb' - -# Offense count: 4 -Rails/FilePath: - Exclude: - - 'spec/features/lodgings_spec.rb' - - 'spec/features/sponsor_spec.rb' - - 'spec/spec_helper.rb' - -# Offense count: 6 -# Cop supports --auto-correct. -# Configuration parameters: Include. -# Include: app/models/**/*.rb -Rails/FindBy: - Exclude: - - 'app/models/conference.rb' - - 'app/models/event.rb' - - 'app/models/openid.rb' - - 'app/models/ticket_purchase.rb' - - 'app/models/user.rb' - -# Offense count: 7 -# Configuration parameters: Include. -# Include: app/models/**/*.rb -Rails/HasAndBelongsToMany: - Exclude: - - 'app/models/conference.rb' - - 'app/models/qanswer.rb' - - 'app/models/question.rb' - - 'app/models/registration.rb' - - 'app/models/vchoice.rb' - -# Offense count: 170 -# Cop supports --auto-correct. -# Configuration parameters: Include. -# Include: spec/**/*, test/**/* -Rails/HttpPositionalArguments: - Enabled: false - -# Offense count: 2 -Rails/OutputSafety: - Exclude: - - 'app/helpers/format_helper.rb' - - 'app/models/commercial.rb' - - 'app/helpers/application_helper.rb' - -# Offense count: 10 -# Cop supports --auto-correct. -Rails/PluralizationGrammar: - Exclude: - - 'spec/models/conference_spec.rb' - -# Offense count: 22 -# Cop supports --auto-correct. -# Configuration parameters: NotNilAndNotEmpty, NotBlank, UnlessBlank. -Rails/Present: - Exclude: - - 'app/helpers/users_helper.rb' - - 'app/models/campaign.rb' - - 'app/models/cfp.rb' - - 'app/models/email_settings.rb' - - 'app/models/event.rb' - - 'app/models/program.rb' - - 'app/models/venue.rb' - -# Offense count: 52 -# Configuration parameters: Include. -# Include: db/migrate/*.rb -Rails/ReversibleMigration: - Exclude: - - 'db/migrate/20140530082708_remove_color_defaults.rb' - - 'db/migrate/20140605125153_update_event_states.rb' - - 'db/migrate/20140610173021_change_person_id_to_user_id_in_registrations.rb' - - 'db/migrate/20140611123926_change_person_id_to_user_id_in_votes.rb' - - 'db/migrate/20140623150541_drop_person_and_event_person_tables.rb' - - 'db/migrate/20140731165107_move_conference_contact_details_to_contact.rb' - - 'db/migrate/20140801164901_move_conference_media_to_commercial.rb' - - 'db/migrate/20140801170430_move_event_media_to_commercial.rb' - - 'db/migrate/20140820093735_migrating_supporter_registrations_to_ticket_users.rb' - - 'db/migrate/20140821103643_split_ticket_price_in_price_and_currency.rb' - - 'db/migrate/20140825093132_move_splashpage_attributes_from_conference_to_splashpage.rb' - - 'db/migrate/20140930092923_move_sponsor_email_to_contact.rb' - - 'db/migrate/20141117222919_drop_splash_descriptions_and_photo.rb' - - 'db/migrate/20141130182139_drop_table_event_attachments.rb' - -# Offense count: 5 -# Configuration parameters: Blacklist. -# Blacklist: decrement!, decrement_counter, increment!, increment_counter, toggle!, touch, update_all, update_attribute, update_column, update_columns, update_counters -Rails/SkipsModelValidations: - Exclude: - - 'app/controllers/payments_controller.rb' - - 'app/models/revision_observer.rb' - - 'db/migrate/20140730104658_migrate_roles_for_cancancan.rb' - - 'lib/tasks/user.rake' - -# Offense count: 46 -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: strict, flexible -Rails/TimeZone: - Exclude: - - 'app/models/comment.rb' - - 'app/models/conference.rb' - - 'lib/tasks/dump_db.rake' - - 'spec/controllers/admin/comments_controller_spec.rb' - - 'spec/controllers/admin/programs_controller_spec.rb' - - 'spec/factories/users.rb' - - 'spec/models/campaign_spec.rb' - - 'spec/models/conference_spec.rb' - -# Offense count: 18 +# Offense count: 20 Style/AccessorMethodName: Exclude: - 'app/controllers/admin/events_controller.rb' @@ -256,33 +350,17 @@ Style/AccessorMethodName: # Offense count: 1 # Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. -# SupportedStyles: with_first_parameter, with_fixed_indentation -Style/AlignParameters: - Exclude: - - 'Vagrantfile' - -# Offense count: 2 -# Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: is_a?, kind_of? Style/ClassCheck: Exclude: - 'app/models/email_settings.rb' - - 'app/models/revision_observer.rb' # Offense count: 1 Style/ClassVars: Exclude: - 'spec/support/kneet_connections.rb' -# Offense count: 9 -# Cop supports --auto-correct. -Style/ClosingParenthesisIndentation: - Exclude: - - 'app/controllers/conference_registrations_controller.rb' - - 'spec/support/omniauth_macros.rb' - # Offense count: 2 # Cop supports --auto-correct. Style/ColonMethodCall: @@ -290,42 +368,20 @@ Style/ColonMethodCall: - 'app/models/commercial.rb' - 'app/models/contact.rb' -# Offense count: 14 -# Cop supports --auto-correct. -Style/CommentIndentation: - Exclude: - - 'app/controllers/admin/comments_controller.rb' - - 'app/controllers/admin/difficulty_levels_controller.rb' - - 'app/models/conference.rb' - - 'app/models/program.rb' - - 'app/models/track.rb' - - 'spec/features/volunteers_spec.rb' - # Offense count: 3 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, SingleLineConditionsOnly, IncludeTernaryExpressions. # SupportedStyles: assign_to_condition, assign_inside_condition Style/ConditionalAssignment: Exclude: - - 'app/controllers/admin/volunteers_controller.rb' - - 'app/controllers/conference_registrations_controller.rb' - 'app/helpers/format_helper.rb' - - 'app/models/conference.rb' - - 'app/models/ticket_purchase.rb' - - 'app/models/user.rb' - 'db/migrate/20140610165551_migrate_data_person_to_user.rb' - 'db/migrate/20140820124117_undo_wrong_migration20140801080705_add_users_to_events.rb' -# Offense count: 436 +# Offense count: 464 Style/Documentation: Enabled: false -# Offense count: 1 -# Cop supports --auto-correct. -Style/ElseAlignment: - Exclude: - - 'app/helpers/format_helper.rb' - # Offense count: 2 # Cop supports --auto-correct. Style/EmptyCaseCondition: @@ -333,25 +389,6 @@ Style/EmptyCaseCondition: - 'app/helpers/format_helper.rb' - 'app/helpers/versions_helper.rb' -# Offense count: 1 -# Cop supports --auto-correct. -Style/EmptyLineAfterMagicComment: - Exclude: - - 'spec/models/conference_spec.rb' - -# Offense count: 109 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: empty_lines, no_empty_lines -Style/EmptyLinesAroundBlockBody: - Enabled: false - -# Offense count: 1 -# Cop supports --auto-correct. -Style/EmptyLinesAroundExceptionHandlingKeywords: - Exclude: - - 'app/models/payment.rb' - # Offense count: 1 # Cop supports --auto-correct. Style/EmptyLiteral: @@ -373,19 +410,6 @@ Style/EmptyMethod: - 'db/migrate/20130206192339_rename_attending_social_events_with_partner.rb' - 'db/migrate/20130216122155_set_registration_defaults_to_false.rb' -# Offense count: 9 -# Cop supports --auto-correct. -# Configuration parameters: AllowForAlignment, ForceEqualSignAlignment. -Style/ExtraSpacing: - Exclude: - - 'Guardfile' - - 'app/controllers/application_controller.rb' - - 'config.ru' - - 'db/migrate/20140623101032_create_ahoy_events.rb' - - 'db/migrate/20140701123203_add_events_per_week_to_conference.rb' - - 'db/migrate/20140719160903_create_delayed_jobs.rb' - - 'spec/models/conference_spec.rb' - # Offense count: 2 # Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms. # AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS @@ -394,14 +418,7 @@ Style/FileName: - 'Gemfile' - 'Vagrantfile' -# Offense count: 42 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. -# SupportedStyles: consistent, special_for_inner_method_call, special_for_inner_method_call_in_parentheses -Style/FirstParameterIndentation: - Enabled: false - -# Offense count: 23 +# Offense count: 24 # Configuration parameters: MinBodyLength. Style/GuardClause: Enabled: false @@ -434,48 +451,6 @@ Style/IfUnlessModifier: - 'spec/controllers/admin/conferences_controller_spec.rb' - 'spec/support/flash.rb' -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. -# SupportedStyles: special_inside_parentheses, consistent, align_brackets -Style/IndentArray: - Exclude: - - 'app/models/conference.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: IndentationWidth. -Style/IndentAssignment: - Exclude: - - 'app/helpers/format_helper.rb' - - 'app/models/conference.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. -# SupportedStyles: special_inside_parentheses, consistent, align_braces -Style/IndentHash: - Exclude: - - 'app/models/user.rb' - - 'db/migrate/20140701123203_add_events_per_week_to_conference.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: normal, rails -Style/IndentationConsistency: - Exclude: - - 'app/controllers/users_controller.rb' - - 'app/models/event.rb' - - 'spec/controllers/subscriptions_controller_spec.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -Style/LeadingCommentSpace: - Exclude: - - 'Guardfile' - - 'app/models/comment.rb' - # Offense count: 8 # Cop supports --auto-correct. Style/LineEndConcatenation: @@ -494,29 +469,6 @@ Style/MethodDefParentheses: - 'app/models/user.rb' - 'lib/tasks/demo_data_for_development.rake' -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: symmetrical, new_line, same_line -Style/MultilineArrayBraceLayout: - Exclude: - - 'app/controllers/conference_registrations_controller.rb' - -# Offense count: 5 -# Cop supports --auto-correct. -Style/MultilineBlockLayout: - Exclude: - - 'app/serializers/conference_serializer.rb' - -# Offense count: 6 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: symmetrical, new_line, same_line -Style/MultilineHashBraceLayout: - Exclude: - - 'app/serializers/conference_serializer.rb' - - 'spec/models/event_spec.rb' - # Offense count: 7 # Cop supports --auto-correct. Style/MultilineIfModifier: @@ -527,33 +479,6 @@ Style/MultilineIfModifier: - 'app/models/event.rb' - 'app/models/registration_period.rb' -# Offense count: 40 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: symmetrical, new_line, same_line -Style/MultilineMethodCallBraceLayout: - Enabled: false - -# Offense count: 55 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. -# SupportedStyles: aligned, indented, indented_relative_to_receiver -Style/MultilineMethodCallIndentation: - Enabled: false - -# Offense count: 27 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. -# SupportedStyles: aligned, indented -Style/MultilineOperationIndentation: - Exclude: - - 'app/controllers/admin/events_controller.rb' - - 'app/controllers/application_controller.rb' - - 'app/models/ability.rb' - - 'app/models/conference.rb' - - 'app/models/event.rb' - - 'db/migrate/20140701123203_add_events_per_week_to_conference.rb' - # Offense count: 2 # Cop supports --auto-correct. Style/MutableConstant: @@ -622,23 +547,21 @@ Style/ParenthesesAroundCondition: - 'app/controllers/application_controller.rb' - 'app/helpers/format_helper.rb' -# Offense count: 17 +# Offense count: 14 # Cop supports --auto-correct. # Configuration parameters: PreferredDelimiters. Style/PercentLiteralDelimiters: Exclude: - 'Gemfile' - 'app/controllers/admin/users_controller.rb' - - 'app/models/ability.rb' + - 'app/models/cfp.rb' - 'app/models/comment.rb' - 'app/models/commercial.rb' - 'app/models/conference.rb' - 'app/models/contact.rb' - 'app/models/registration.rb' - 'app/models/subscription.rb' - - 'app/models/cfp.rb' - 'app/uploaders/picture_uploader.rb' - - 'spec/models/ability_spec.rb' - 'spec/models/program_spec.rb' # Offense count: 2 @@ -667,12 +590,6 @@ Style/PreferredHashMethods: Style/RaiseArgs: EnforcedStyle: compact -# Offense count: 1 -# Cop supports --auto-correct. -Style/RedundantBegin: - Exclude: - - 'app/models/revision_observer.rb' - # Offense count: 1 # Cop supports --auto-correct. Style/RedundantParentheses: @@ -713,96 +630,6 @@ Style/SingleLineMethods: Exclude: - 'Guardfile' -# Offense count: 1 -# Cop supports --auto-correct. -Style/SpaceAfterComma: - Exclude: - - 'lib/tasks/data_demo.rake' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: space, no_space -Style/SpaceAroundEqualsInParameterDefault: - Exclude: - - 'app/helpers/format_helper.rb' - - 'app/models/event.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: AllowForAlignment. -Style/SpaceAroundOperators: - Exclude: - - 'lib/tasks/data.rake' - -# Offense count: 319 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: space, no_space -Style/SpaceBeforeBlockBraces: - Enabled: false - -# Offense count: 1 -# Cop supports --auto-correct. -Style/SpaceBeforeComma: - Exclude: - - 'lib/tasks/data_demo.rake' - -# Offense count: 1 -# Cop supports --auto-correct. -Style/SpaceBeforeSemicolon: - Exclude: - - 'Guardfile' - -# Offense count: 2 -# Cop supports --auto-correct. -Style/SpaceInsideArrayPercentLiteral: - Exclude: - - 'spec/models/ability_spec.rb' - -# Offense count: 62 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SupportedStylesForEmptyBraces, SpaceBeforeBlockParameters. -# SupportedStyles: space, no_space -# SupportedStylesForEmptyBraces: space, no_space -Style/SpaceInsideBlockBraces: - Exclude: - - 'app/controllers/admin/comments_controller.rb' - - 'app/controllers/admin/events_controller.rb' - - 'app/controllers/admin/questions_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/models/program.rb' - - 'app/models/ticket.rb' - - 'app/models/user.rb' - - 'lib/tasks/events_registrations.rake' - - 'spec/controllers/admin/event_schedules_controller_spec.rb' - - 'spec/controllers/admin/schedules_controller_spec.rb' - - 'spec/features/splashpage_spec.rb' - - 'spec/models/ability_spec.rb' - - 'spec/models/user_spec.rb' - -# Offense count: 25 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SupportedStylesForEmptyBraces. -# SupportedStyles: space, no_space, compact -# SupportedStylesForEmptyBraces: space, no_space -Style/SpaceInsideHashLiteralBraces: - Exclude: - - 'app/controllers/admin/conferences_controller.rb' - - 'app/controllers/api/v1/speakers_controller.rb' - - 'app/models/ability.rb' - - 'app/models/conference.rb' - - 'app/models/event_type.rb' - - 'app/models/user.rb' - - 'spec/models/event_spec.rb' - - 'spec/models/payment_spec.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -Style/SpaceInsidePercentLiteralDelimiters: - Exclude: - - 'Gemfile' - # Offense count: 16 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, ConsistentQuotesInMultiline. @@ -824,14 +651,14 @@ Style/StringLiteralsInInterpolation: Exclude: - 'lib/tasks/dump_db.rake' -# Offense count: 60 +# Offense count: 73 # Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. +# Configuration parameters: EnforcedStyle, MinSize, SupportedStyles. # SupportedStyles: percent, brackets Style/SymbolArray: Enabled: false -# Offense count: 10 +# Offense count: 11 # Cop supports --auto-correct. # Configuration parameters: IgnoredMethods. # IgnoredMethods: respond_to, define_method @@ -854,15 +681,6 @@ Style/TernaryParentheses: Exclude: - 'app/helpers/format_helper.rb' -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: final_newline, final_blank_line -Style/TrailingBlankLines: - Exclude: - - 'lib/tasks/event_attatchments.rake' - - 'lib/tasks/roles.rake' - # Offense count: 23 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyleForMultiline, SupportedStylesForMultiline. @@ -873,12 +691,6 @@ Style/TrailingCommaInLiteral: - 'db/migrate/20140701123203_add_events_per_week_to_conference.rb' - 'spec/models/conference_spec.rb' -# Offense count: 1 -# Cop supports --auto-correct. -Style/TrailingWhitespace: - Exclude: - - 'Gemfile' - # Offense count: 3 # Cop supports --auto-correct. Style/UnneededInterpolation: From d9a3b0de72a737ae830efbbd44e5d944dbe41297 Mon Sep 17 00:00:00 2001 From: Hernan Schmidt Date: Fri, 14 Jul 2017 14:12:54 +0200 Subject: [PATCH 16/26] Fix Style/ConditionalAssignment errors They did not get excluded by `--auto-gen-config` --- .../admin/volunteers_controller.rb | 10 +++++----- .../conference_registrations_controller.rb | 12 +++++------ app/models/conference.rb | 20 +++++++++---------- app/models/ticket_purchase.rb | 10 +++++----- app/models/user.rb | 10 +++++----- 5 files changed, 31 insertions(+), 31 deletions(-) diff --git a/app/controllers/admin/volunteers_controller.rb b/app/controllers/admin/volunteers_controller.rb index e8676bae..aefa682a 100644 --- a/app/controllers/admin/volunteers_controller.rb +++ b/app/controllers/admin/volunteers_controller.rb @@ -13,11 +13,11 @@ module Admin def show if can_manage_volunteers?(@conference) - if @conference.use_vpositions - @volunteers = @conference.registrations.joins(:vchoices).uniq - else - @volunteers = @conference.registrations.where(volunteer: true) - end + @volunteers = if @conference.use_vpositions + @conference.registrations.joins(:vchoices).uniq + else + @conference.registrations.where(volunteer: true) + end else authorize! :index, :volunteer end diff --git a/app/controllers/conference_registrations_controller.rb b/app/controllers/conference_registrations_controller.rb index c229440e..c2037318 100644 --- a/app/controllers/conference_registrations_controller.rb +++ b/app/controllers/conference_registrations_controller.rb @@ -38,12 +38,12 @@ class ConferenceRegistrationsController < ApplicationController def create @registration = @conference.registrations.new(registration_params) - if current_user.nil? - # @user variable needs to be set so that _sign_up_form_embedded works properly - @user = @registration.build_user(user_params) - else - @user = current_user - end + @user = if current_user.nil? + # @user variable needs to be set so that _sign_up_form_embedded works properly + @registration.build_user(user_params) + else + current_user + end @registration.user = @user authorize! :create, @registration diff --git a/app/models/conference.rb b/app/models/conference.rb index 68cdc186..db6b4745 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -563,11 +563,11 @@ class Conference < ActiveRecord::Base # ====Returns # * +hash+ -> track => {color, value} def tracks_distribution(state = nil) - if state - tracks_grouped = program.events.select(:track_id).where('state = ?', state).group(:track_id) - else - tracks_grouped = program.events.select(:track_id).group(:track_id) - end + tracks_grouped = if state + program.events.select(:track_id).where('state = ?', state).group(:track_id) + else + program.events.select(:track_id).group(:track_id) + end tracks_counted = tracks_grouped.count calculate_track_distribution_hash(tracks_grouped, tracks_counted) @@ -1001,11 +1001,11 @@ class Conference < ActiveRecord::Base # ====Returns # * +hash+ -> object_type => {color, value} def calculate_event_distribution(group_by_id, association_symbol, state = nil) - if state - grouped = program.events.select(group_by_id).where('state = ?', 'confirmed').group(group_by_id) - else - grouped = program.events.select(group_by_id).group(group_by_id) - end + grouped = if state + program.events.select(group_by_id).where('state = ?', 'confirmed').group(group_by_id) + else + program.events.select(group_by_id).group(group_by_id) + end counted = grouped.count calculate_distribution_hash(grouped, counted, association_symbol) diff --git a/app/models/ticket_purchase.rb b/app/models/ticket_purchase.rb index 88e1f4de..a19678a7 100644 --- a/app/models/ticket_purchase.rb +++ b/app/models/ticket_purchase.rb @@ -29,11 +29,11 @@ class TicketPurchase < ActiveRecord::Base conference.tickets.each do |ticket| quantity = purchases[ticket.id.to_s].to_i # if the user bought the ticket and is still unpaid, just update the quantity - if ticket.bought?(user) && ticket.unpaid?(user) - purchase = update_quantity(conference, quantity, ticket, user) - else - purchase = purchase_ticket(conference, quantity, ticket, user) - end + purchase = if ticket.bought?(user) && ticket.unpaid?(user) + update_quantity(conference, quantity, ticket, user) + else + purchase_ticket(conference, quantity, ticket, user) + end if purchase && !purchase.save errors.push(purchase.errors.full_messages) diff --git a/app/models/user.rb b/app/models/user.rb index e79d0b2a..54a9deba 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -30,13 +30,13 @@ class User < ActiveRecord::Base # :lockable, :timeoutable and :omniauthable devise_modules = [] - if ENV['OSEM_ICHAIN_ENABLED'] == 'true' - devise_modules += [:ichain_authenticatable, :ichain_registerable, :omniauthable, omniauth_providers: []] - else - devise_modules += [:database_authenticatable, :registerable, + devise_modules += if ENV['OSEM_ICHAIN_ENABLED'] == 'true' + [:ichain_authenticatable, :ichain_registerable, :omniauthable, omniauth_providers: []] + else + [:database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable, :omniauthable, omniauth_providers: [:suse, :google, :facebook, :github]] - end + end devise(*devise_modules) From e2a4cfd9fd5a9e2a47da9656ed734f58c07b1e5c Mon Sep 17 00:00:00 2001 From: siddhantbajaj Date: Sat, 15 Jul 2017 03:37:32 +0530 Subject: [PATCH 17/26] Added ticket pdf prawn document --- app/controllers/physical_ticket_controller.rb | 10 +++ app/pdfs/ticket_pdf.rb | 81 +++++++++++++++++++ app/views/physical_ticket/show.pdf.prawn | 62 -------------- 3 files changed, 91 insertions(+), 62 deletions(-) create mode 100644 app/pdfs/ticket_pdf.rb delete mode 100644 app/views/physical_ticket/show.pdf.prawn diff --git a/app/controllers/physical_ticket_controller.rb b/app/controllers/physical_ticket_controller.rb index 8617e0d9..6bb7f50b 100644 --- a/app/controllers/physical_ticket_controller.rb +++ b/app/controllers/physical_ticket_controller.rb @@ -13,5 +13,15 @@ class PhysicalTicketController < ApplicationController @file_name = "ticket_for_#{@conference.short_title}" @user = @physical_ticket.user @ticket_layout = @conference.ticket_layout.to_sym + respond_to do |format| + format.html + format.pdf do + pdf = TicketPdf.new(@conference, @user, @physical_ticket, @ticket_layout, @file_name) + send_data pdf.render, + filename: @file_name, + type: 'application/pdf', + disposition: 'attachment' + end + end end end diff --git a/app/pdfs/ticket_pdf.rb b/app/pdfs/ticket_pdf.rb new file mode 100644 index 00000000..1c26ec77 --- /dev/null +++ b/app/pdfs/ticket_pdf.rb @@ -0,0 +1,81 @@ +class TicketPdf < Prawn::Document + def initialize(conference, user, physical_ticket, ticket_layout, file_name) + super(page_layout: ticket_layout, page_size: 'A4', filename: file_name) + @user = user + @physical_ticket = physical_ticket + @conference = conference + + @left = bounds.left + @right = bounds.right + @mid_vertical = (bounds.top - bounds.bottom) / 2 + @mid_horizontal = (bounds.right - bounds.left) / 2 + @x = 0 + + draw_first_square + draw_second_square + draw_third_square + draw_fourth_square + end + + def draw_first_square + move_down @mid_vertical + dash(2, space: 1) + stroke_horizontal_rule + stroke_vertical_line bounds.top, bounds.bottom, at: @mid_horizontal + move_up @mid_vertical + draw_text 'TICKET HOLDER', at: [@x, cursor - 30], size: 17 + dash(2, space: 0) + stroke_rectangle [@x, cursor - 50], 230, 150 + move_down 80 + draw_text 'NAME', at: [@x + 10, cursor], size: 13 + fill_color '808080' + draw_text @user.name.to_s, at: [@x + 10, cursor - 25], size: 20 + fill_color '000000' + draw_text 'EMAIL', at: [@x + 10, cursor - 50], size: 13 + fill_color '808080' + draw_text @user.email.to_s, at: [@x + 10, cursor - 75], size: 20 + fill_color '000000' + move_up 20 + end + + def draw_second_square + if @conference.picture? + if 7 * @conference.picture.image[:width] > 12 * @conference.picture.image[:height] + image "#{Rails.root}/public#{@conference.picture_url}", at: [@mid_horizontal + 30, cursor], width: 120 + else + image "#{Rails.root}/public#{@conference.picture_url}", at: [@mid_horizontal + 30, cursor], height: 70 + end + else + image "#{Rails.root}/public/img/osem-logo.png", at: [@mid_horizontal + 30, cursor], height: 70 + end + move_down 70 + draw_text @conference.title.to_s, at: [@mid_horizontal + 30, cursor - 30], size: 12 + draw_text @conference.organization.name.to_s, at: [@mid_horizontal + 30, cursor - 50], size: 12 + draw_text @conference.venue.name.to_s, at: [@mid_horizontal + 30, cursor - 70] + move_up 130 + move_down @mid_vertical + end + + def draw_third_square + draw_text 'EVENT', at: [@x, cursor - 40], size: 15 + fill_color '808080' + draw_text @conference.title.to_s, at: [@x, cursor - 60], size: 12 + draw_text @conference.start_date.strftime('%B %d, %Y').to_s, at: [@x, cursor - 80], size: 12 + move_down 80 + fill_color '000000' + draw_text 'TICKET', at: [@x, cursor - 30], size: 15 + fill_color '808080' + draw_text @physical_ticket.ticket.title.to_s, at: [@x, cursor - 50], size: 12 + move_down 50 + fill_color '000000' + draw_text 'TICKET REF.', at: [@x, cursor - 30], size: 15 + fill_color '808080' + draw_text @physical_ticket.ticket_purchase.id.to_s, at: [@x, cursor - 50], size: 12 + move_down 50 + fill_color '000000' + draw_text 'Powered By OSEM', at: [(@mid_horizontal - @left - 100) / 2, cursor - 100], size: 11 + move_up 180 + end + + def draw_fourth_square; end +end diff --git a/app/views/physical_ticket/show.pdf.prawn b/app/views/physical_ticket/show.pdf.prawn deleted file mode 100644 index 92206baf..00000000 --- a/app/views/physical_ticket/show.pdf.prawn +++ /dev/null @@ -1,62 +0,0 @@ -prawn_document(filename: @file_name, page_layout: @ticket_layout, :page_size =>'A4' ) do |pdf| - # Vertical Layout - top = pdf.bounds.top - bottom = pdf.bounds.bottom - left = pdf.bounds.left - right = pdf.bounds.right - mid_vertical = (pdf.bounds.top-pdf.bounds.bottom)/2 - mid_horizontal = (pdf.bounds.right-pdf.bounds.left)/2 - x = 0 - - pdf.move_down mid_vertical - pdf.dash(2, :space => 1) - pdf.stroke_horizontal_rule - pdf.stroke_vertical_line pdf.bounds.top, pdf.bounds.bottom, :at => mid_horizontal - pdf.move_up mid_vertical - pdf.draw_text "TICKET HOLDER", :at => [x,pdf.cursor-30], :size => 17 - pdf.dash(2, :space => 0) - pdf.stroke_rectangle [x, pdf.cursor-50], 230, 150 - pdf.move_down 80 - pdf.draw_text "NAME", :at => [x+10,pdf.cursor], :size => 13 - pdf.fill_color "808080" - pdf.draw_text "#{@user.name}", :at => [x+10,pdf.cursor-25], size: 20 - pdf.fill_color "000000" - pdf.draw_text "EMAIL", :at => [x+10,pdf.cursor-50], :size => 13 - pdf.fill_color "808080" - pdf.draw_text "#{@user.email}", :at => [x+10,pdf.cursor-75], size: 20 - pdf.fill_color "000000" - pdf.move_up 20 - if @conference.picture? - if 7 * @conference.picture.image[:width] > 12 * @conference.picture.image[:height] - pdf.image "#{Rails.root}/public#{@conference.picture_url}", :at => [mid_horizontal+30, pdf.cursor], :width => 120 - else - pdf.image "#{Rails.root}/public#{@conference.picture_url}", :at => [mid_horizontal+30, pdf.cursor], :height => 70 - end - else - pdf.image "#{Rails.root}/public/img/osem-logo.png", :at => [mid_horizontal+30, pdf.cursor], :height => 70 - end - pdf.move_down 70 - pdf.draw_text "#{@conference.title}", :at => [mid_horizontal+30,pdf.cursor-30], :size => 12 - pdf.draw_text "#{@conference.organization.name}", :at => [mid_horizontal+30,pdf.cursor-50], :size => 12 - pdf.draw_text "#{@conference.venue.name}", :at => [mid_horizontal+30,pdf.cursor-70] - pdf.move_up 130 - pdf.move_down mid_vertical - pdf.draw_text "EVENT", :at => [x,pdf.cursor-40], :size => 15 - pdf.fill_color "808080" - pdf.draw_text "#{@conference.title}", :at => [x,pdf.cursor-60], size: 12 - pdf.draw_text "#{@conference.start_date.strftime('%B %d, %Y')}", :at => [x,pdf.cursor-80], size: 12 - pdf.move_down 80 - pdf.fill_color "000000" - pdf.draw_text "TICKET", :at => [x,pdf.cursor-30], :size => 15 - pdf.fill_color "808080" - pdf.draw_text "#{@physical_ticket.ticket.title}", :at => [x,pdf.cursor-50], size: 12 - pdf.move_down 50 - pdf.fill_color "000000" - pdf.draw_text "TICKET REF.", :at => [x,pdf.cursor-30], :size => 15 - pdf.fill_color "808080" - pdf.draw_text "#{@physical_ticket.ticket_purchase.id}", :at => [x,pdf.cursor-50], size: 12 - pdf.move_down 50 - pdf.fill_color "000000" - pdf.draw_text "Powered By OSEM", :at => [(mid_horizontal-left-100)/2,pdf.cursor-100], :size => 11 - pdf.move_up 180 -end From f9d8c9715c241d0bf9a3bb735ea37630c2dd6cf5 Mon Sep 17 00:00:00 2001 From: Svante Date: Fri, 14 Jul 2017 15:21:05 +0200 Subject: [PATCH 18/26] Add bootstrap styling to sign in form Add class `.form-control` to inputs and remove additional width styling --- app/assets/stylesheets/osem-navbar.css.scss | 8 -------- app/views/layouts/_navigation.html.haml | 8 ++++---- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/app/assets/stylesheets/osem-navbar.css.scss b/app/assets/stylesheets/osem-navbar.css.scss index 385cf93d..ef05c0a9 100644 --- a/app/assets/stylesheets/osem-navbar.css.scss +++ b/app/assets/stylesheets/osem-navbar.css.scss @@ -20,14 +20,6 @@ color: black; background-color: #eeeeee; } - input[type=text], - input[type=password] { - text-align: center; - padding: 5px; - display: block; - margin: auto; - width: 255px; - } .btn-group { width: 100%; text-align: center; diff --git a/app/views/layouts/_navigation.html.haml b/app/views/layouts/_navigation.html.haml index 48066cd7..6683ea23 100644 --- a/app/views/layouts/_navigation.html.haml +++ b/app/views/layouts/_navigation.html.haml @@ -60,13 +60,13 @@ .dropdown-menu - if ENV['OSEM_ICHAIN_ENABLED'] == 'true' = form_tag User.ichain_login_url do - = text_field_tag 'username', nil, id: 'user_ichain_email_dd', placeholder: 'Username' - = password_field_tag 'password', nil, id: 'user_ichain_password_dd', placeholder: 'Password' + = text_field_tag 'username', nil, id: 'user_ichain_email_dd', class: 'form-control', placeholder: 'Username' + = password_field_tag 'password', nil, id: 'user_ichain_password_dd', class: 'form-control', placeholder: 'Password' %button.btn.btn-success.btn-block Sign in - else = form_tag new_user_session_path do - = text_field_tag 'user[login]', nil, id: 'user_login_dd', placeholder: 'Username / E-Mail' - = password_field_tag 'user[password]', nil, id: 'user_password_dd', placeholder: 'Password' + = text_field_tag 'user[login]', nil, id: 'user_login_dd', class: 'form-control', placeholder: 'Username / E-Mail' + = password_field_tag 'user[password]', nil, id: 'user_password_dd', class: 'form-control', placeholder: 'Password' %p.text-right %small %label{for: 'user_remember_me'} Remember me From e71b06bd572992d9fcb1f61a0b66a5076574b687 Mon Sep 17 00:00:00 2001 From: rahul Date: Fri, 14 Jul 2017 01:23:03 +0530 Subject: [PATCH 19/26] Add ruby 2.4 to travis and vagrant --- .travis.yml | 2 +- bootstrap.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6c83258b..9191bbd7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ dist: trusty language: ruby cache: bundler rvm: - - 2.2.3 + - 2.4.0 before_install: - "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" - "echo `phantomjs -v`" diff --git a/bootstrap.sh b/bootstrap.sh index 197b6be2..f0ac49fb 100644 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -2,7 +2,7 @@ pushd /vagrant echo -e "\ninstalling required software packages...\n" -zypper -q -n install update-alternatives ruby2.2-devel make gcc gcc-c++ \ +zypper -q -n install update-alternatives ruby2.4-devel make gcc gcc-c++ \ libxml2-devel libxslt-devel nodejs screen mariadb \ libmysqld-devel sqlite3-devel ImageMagick @@ -10,7 +10,7 @@ echo -e "\ndisabling versioned gem binary names...\n" echo 'install: --no-format-executable' >> /etc/gemrc echo -e "\ninstalling bundler...\n" -gem.ruby2.2 install bundler +gem.ruby2.4 install bundler echo -e "\ninstalling your bundle...\n" su - vagrant -c "cd /vagrant/; bundle install --quiet" From 7f28ff3ac9041c1a791d4f7587979673e487130b Mon Sep 17 00:00:00 2001 From: rahul Date: Fri, 14 Jul 2017 01:32:27 +0530 Subject: [PATCH 20/26] Updated rdoc-generator-fivefish gem This update is required to update yajl-ruby 1.2 to yajl-ruby 1.3 that support ruby 2.4 --- Gemfile.lock | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index effbde5b..583286a0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -228,8 +228,8 @@ GEM domain_name (~> 0.5) i18n (0.7.0) i18n_data (0.7.0) - inversion (0.12.3) - loggability (~> 0.4) + inversion (1.0.0) + loggability (~> 0.12) iso-639 (0.2.5) jquery-datatables-rails (2.2.3) jquery-rails @@ -257,7 +257,7 @@ GEM celluloid-io (>= 0.15.0) rb-fsevent (>= 0.9.3) rb-inotify (>= 0.9) - loggability (0.11.0) + loggability (0.14.0) loofah (2.0.3) nokogiri (>= 1.5.9) lumberjack (1.0.5) @@ -412,13 +412,12 @@ GEM rb-fsevent (0.9.4) rb-inotify (0.9.4) ffi (>= 0.5.0) - rdoc (4.1.1) - json (~> 1.4) - rdoc-generator-fivefish (0.1.0) - inversion (~> 0.12) - loggability (~> 0.6) - rdoc (~> 4.0) - yajl-ruby (~> 1.1) + rdoc (5.1.0) + rdoc-generator-fivefish (0.3.0) + inversion (~> 1.0) + loggability (~> 0.12) + rdoc (~> 5.0) + yajl-ruby (~> 1.3) redcarpet (3.2.3) referer-parser (0.2.1) request_store (1.1.0) @@ -548,7 +547,7 @@ GEM chronic (>= 0.6.3) xpath (2.0.0) nokogiri (~> 1.3) - yajl-ruby (1.2.0) + yajl-ruby (1.3.0) PLATFORMS ruby From a6f9fdbb4350ea0beb81e1ac79038c2c48613f04 Mon Sep 17 00:00:00 2001 From: rahul Date: Fri, 14 Jul 2017 01:48:47 +0530 Subject: [PATCH 21/26] Updated rails to 4.2.8 Rails update to 4.2.8 is necessary to get rid of Bignum and Fixnum warnings. Ruby had two visible Integer classes: Fixnum and Bignum. Ruby 2.4 unifies them into Integer. All C extensions which touch the Fixnum or Bignum class need to be fixed. --- Gemfile | 2 +- Gemfile.lock | 94 +++++++++++++++++++++++++++------------------------- 2 files changed, 49 insertions(+), 47 deletions(-) diff --git a/Gemfile b/Gemfile index 46c8731e..d58a9fe2 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ if Gem::Version.new(Bundler::VERSION) < Gem::Version.new('1.8.4') end # as web framework -gem 'rails', '~> 4.2' +gem 'rails', '~> 4.2.8' # enables serving assets in production and setting your logger to standard out # both of which are required to run an application on a twelve-factor provider diff --git a/Gemfile.lock b/Gemfile.lock index 583286a0..71c317e2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -12,40 +12,39 @@ GEM remote: https://rubygems.org/ remote: https://rails-assets.org/ specs: - actionmailer (4.2.7.1) - actionpack (= 4.2.7.1) - actionview (= 4.2.7.1) - activejob (= 4.2.7.1) + actionmailer (4.2.9) + actionpack (= 4.2.9) + actionview (= 4.2.9) + activejob (= 4.2.9) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 1.0, >= 1.0.5) - actionpack (4.2.7.1) - actionview (= 4.2.7.1) - activesupport (= 4.2.7.1) + actionpack (4.2.9) + actionview (= 4.2.9) + activesupport (= 4.2.9) rack (~> 1.6) rack-test (~> 0.6.2) rails-dom-testing (~> 1.0, >= 1.0.5) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (4.2.7.1) - activesupport (= 4.2.7.1) + actionview (4.2.9) + activesupport (= 4.2.9) builder (~> 3.1) erubis (~> 2.7.0) rails-dom-testing (~> 1.0, >= 1.0.5) - rails-html-sanitizer (~> 1.0, >= 1.0.2) + rails-html-sanitizer (~> 1.0, >= 1.0.3) active_model_serializers (0.9.4) activemodel (>= 3.2) - activejob (4.2.7.1) - activesupport (= 4.2.7.1) + activejob (4.2.9) + activesupport (= 4.2.9) globalid (>= 0.3.0) - activemodel (4.2.7.1) - activesupport (= 4.2.7.1) + activemodel (4.2.9) + activesupport (= 4.2.9) builder (~> 3.1) - activerecord (4.2.7.1) - activemodel (= 4.2.7.1) - activesupport (= 4.2.7.1) + activerecord (4.2.9) + activemodel (= 4.2.9) + activesupport (= 4.2.9) arel (~> 6.0) - activesupport (4.2.7.1) + activesupport (4.2.9) i18n (~> 0.7) - json (~> 1.7, >= 1.7.7) minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) @@ -67,7 +66,7 @@ GEM request_store user_agent_parser uuidtools - arel (6.0.3) + arel (6.0.4) ast (2.3.0) autoprefixer-rails (5.1.9) execjs @@ -88,8 +87,11 @@ GEM bootstrap3-datetimepicker-rails (3.0.3) momentjs-rails (>= 2.8.1) browser (0.6.0) - builder (3.2.2) byebug (9.0.6) + + builder (3.2.3) + columnize (~> 0.8) + debugger-linecache (~> 1.2) cancancan (1.13.1) capybara (2.6.2) addressable @@ -193,8 +195,8 @@ GEM formtastic-bootstrap (3.1.1) formtastic (>= 3.0) geocoder (1.2.2) - globalid (0.3.6) - activesupport (>= 4.1.0) + globalid (0.4.0) + activesupport (>= 4.2.0) gravtastic (3.2.6) guard (2.6.0) formatador (>= 0.2.4) @@ -261,17 +263,17 @@ GEM loofah (2.0.3) nokogiri (>= 1.5.9) lumberjack (1.0.5) - mail (2.6.3) - mime-types (>= 1.16, < 3) + mail (2.6.6) + mime-types (>= 1.16, < 4) method_source (0.8.2) - mime-types (2.99.1) + mime-types (2.99.3) mimemagic (0.3.2) mina (0.3.8) open4 (~> 1.3.4) rake mini_magick (4.5.1) mini_portile2 (2.2.0) - minitest (5.10.1) + minitest (5.10.2) momentjs-rails (2.8.1) railties (>= 3.1) monetize (1.4.0) @@ -284,7 +286,7 @@ GEM monetize (~> 1.4.0) money (~> 6.7) railties (>= 3.0) - multi_json (1.11.2) + multi_json (1.12.1) multi_xml (0.5.5) multipart-post (2.0.0) mysql2 (0.4.2) @@ -351,22 +353,22 @@ GEM coderay (~> 1.0) method_source (~> 0.8) slop (~> 3.4) - rack (1.6.4) + rack (1.6.8) rack-openid (1.3.1) rack (>= 1.1.0) ruby-openid (>= 2.1.8) rack-test (0.6.3) rack (>= 1.0) - rails (4.2.7.1) - actionmailer (= 4.2.7.1) - actionpack (= 4.2.7.1) - actionview (= 4.2.7.1) - activejob (= 4.2.7.1) - activemodel (= 4.2.7.1) - activerecord (= 4.2.7.1) - activesupport (= 4.2.7.1) + rails (4.2.9) + actionmailer (= 4.2.9) + actionpack (= 4.2.9) + actionview (= 4.2.9) + activejob (= 4.2.9) + activemodel (= 4.2.9) + activerecord (= 4.2.9) + activesupport (= 4.2.9) bundler (>= 1.3.0, < 2.0) - railties (= 4.2.7.1) + railties (= 4.2.9) sprockets-rails rails-assets-bootstrap (3.3.6) rails-assets-jquery (>= 1.9.1, < 3) @@ -401,14 +403,14 @@ GEM rails_stdout_logging rails_serve_static_assets (0.0.4) rails_stdout_logging (0.0.3) - railties (4.2.7.1) - actionpack (= 4.2.7.1) - activesupport (= 4.2.7.1) + railties (4.2.9) + actionpack (= 4.2.9) + activesupport (= 4.2.9) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) - rainbow (2.2.2) - rake - rake (10.5.0) + + rainbow (2.2.1) + rake (12.0.0) rb-fsevent (0.9.4) rb-inotify (0.9.4) ffi (>= 0.5.0) @@ -506,7 +508,7 @@ GEM sysexits (1.2.0) term-ansicolor (1.3.2) tins (~> 1.0) - thor (0.19.1) + thor (0.19.4) thread_safe (0.3.6) tilt (1.4.1) timecop (0.7.1) @@ -615,7 +617,7 @@ DEPENDENCIES poltergeist prawn-qrcode (~> 0.2.2.1) prawn_rails - rails (~> 4.2) + rails (~> 4.2.8) rails-assets-bootstrap-markdown! rails-assets-date.format! rails-assets-holderjs! From d4d1512c61b39291816ffa42a07054af03203008 Mon Sep 17 00:00:00 2001 From: rahul Date: Fri, 14 Jul 2017 01:56:49 +0530 Subject: [PATCH 22/26] Updated rspec-rails and guard rspec Updated this gem to fix nomethoderror old version of rspec use last_comment method which is deprecated in latest versions --- Gemfile | 4 +- Gemfile.lock | 101 +++++++++--------- .../admin/roles_controller_spec.rb | 2 +- 3 files changed, 56 insertions(+), 51 deletions(-) diff --git a/Gemfile b/Gemfile index d58a9fe2..1b0a3c1d 100644 --- a/Gemfile +++ b/Gemfile @@ -201,7 +201,7 @@ gem 'selectize-rails' # Use guard and spring for testing in development group :development do # to launch specs when files are modified - gem 'guard-rspec', '~> 4.2.8' + gem 'guard-rspec' gem 'spring-commands-rspec' gem 'haml_lint', '~> 0.24.0' # for static code analisys @@ -220,7 +220,7 @@ end group :test do # as test framework - gem 'rspec-rails' + gem 'rspec-rails', '~> 3.5', '>= 3.5.2' gem 'database_cleaner' gem 'capybara' gem 'poltergeist' diff --git a/Gemfile.lock b/Gemfile.lock index 71c317e2..928c3b84 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -109,11 +109,6 @@ GEM activesupport (>= 3.2.0) carrierwave fastimage - celluloid (0.15.2) - timers (~> 1.1.0) - celluloid-io (0.15.0) - celluloid (>= 0.15.0) - nio4r (>= 0.5.0) chart-js-rails (0.0.6) railties (> 3.1) chronic (0.10.2) @@ -123,7 +118,7 @@ GEM aws_cf_signer rest-client cocoon (1.2.6) - coderay (1.1.0) + coderay (1.1.1) coffee-rails (4.1.1) coffee-script (>= 2.2.0) railties (>= 4.0.0, < 5.1.x) @@ -165,7 +160,7 @@ GEM warden (~> 1.2.3) devise_ichain_authenticatable (0.3.1) devise (>= 2.2) - diff-lcs (1.2.5) + diff-lcs (1.3) docile (1.1.5) domain_name (0.5.20160310) unf (>= 0.0.5, < 1.0.0) @@ -186,10 +181,10 @@ GEM multipart-post (>= 1.2, < 3) fastimage (2.0.0) addressable (~> 2) - ffi (1.9.3) + ffi (1.9.18) font-awesome-rails (4.1.0.0) railties (>= 3.2, < 5.0) - formatador (0.2.4) + formatador (0.2.5) formtastic (3.1.3) actionpack (>= 3.2.13) formtastic-bootstrap (3.1.1) @@ -198,15 +193,20 @@ GEM globalid (0.4.0) activesupport (>= 4.2.0) gravtastic (3.2.6) - guard (2.6.0) + guard (2.14.1) formatador (>= 0.2.4) - listen (~> 2.7) + listen (>= 2.7, < 4.0) lumberjack (~> 1.0) + nenv (~> 0.1) + notiffany (~> 0.0) pry (>= 0.9.12) + shellany (~> 0.0) thor (>= 0.18.1) - guard-rspec (4.2.8) + guard-compat (1.2.1) + guard-rspec (4.7.3) guard (~> 2.1) - rspec (>= 2.14, < 4.0) + guard-compat (~> 1.1) + rspec (>= 2.99.0, < 4.0) haml (4.0.5) tilt haml-rails (0.5.3) @@ -254,15 +254,14 @@ GEM actionmailer (>= 3.2) letter_opener (~> 1.0) railties (>= 3.2) - listen (2.7.2) - celluloid (>= 0.15.2) - celluloid-io (>= 0.15.0) - rb-fsevent (>= 0.9.3) - rb-inotify (>= 0.9) + listen (3.1.5) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + ruby_dep (~> 1.2) loggability (0.14.0) loofah (2.0.3) nokogiri (>= 1.5.9) - lumberjack (1.0.5) + lumberjack (1.0.12) mail (2.6.6) mime-types (>= 1.16, < 4) method_source (0.8.2) @@ -290,10 +289,13 @@ GEM multi_xml (0.5.5) multipart-post (2.0.0) mysql2 (0.4.2) + nenv (0.3.0) netrc (0.11.0) - nio4r (1.2.1) nokogiri (1.8.0) mini_portile2 (~> 2.2.0) + notiffany (0.1.1) + nenv (~> 0.1) + shellany (~> 0.0) oauth2 (0.9.4) faraday (>= 0.8, < 0.10) jwt (~> 1.0) @@ -349,9 +351,9 @@ GEM prawn_rails (0.0.11) prawn (>= 0.11.1) railties (>= 3.0.0) - pry (0.9.12.6) - coderay (~> 1.0) - method_source (~> 0.8) + pry (0.10.4) + coderay (~> 1.1.0) + method_source (~> 0.8.1) slop (~> 3.4) rack (1.6.8) rack-openid (1.3.1) @@ -411,9 +413,9 @@ GEM rainbow (2.2.1) rake (12.0.0) - rb-fsevent (0.9.4) - rb-inotify (0.9.4) - ffi (>= 0.5.0) + rb-fsevent (0.10.2) + rb-inotify (0.9.10) + ffi (>= 0.5.0, < 2) rdoc (5.1.0) rdoc-generator-fivefish (0.3.0) inversion (~> 1.0) @@ -432,32 +434,33 @@ GEM rolify (5.1.0) rqrcode (0.10.1) chunky_png (~> 1.0) - rspec (3.0.0) - rspec-core (~> 3.0.0) - rspec-expectations (~> 3.0.0) - rspec-mocks (~> 3.0.0) + rspec (3.6.0) + rspec-core (~> 3.6.0) + rspec-expectations (~> 3.6.0) + rspec-mocks (~> 3.6.0) rspec-activemodel-mocks (1.0.1) activemodel (>= 3.0) activesupport (>= 3.0) rspec-mocks (>= 2.99, < 4.0) - rspec-core (3.0.2) - rspec-support (~> 3.0.0) - rspec-expectations (3.0.2) + rspec-core (3.6.0) + rspec-support (~> 3.6.0) + rspec-expectations (3.6.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.0.0) - rspec-mocks (3.0.2) - rspec-support (~> 3.0.0) - rspec-rails (3.0.0) + rspec-support (~> 3.6.0) + rspec-mocks (3.6.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.6.0) + rspec-rails (3.6.0) actionpack (>= 3.0) activesupport (>= 3.0) railties (>= 3.0) - rspec-core (~> 3.0.0) - rspec-expectations (~> 3.0.0) - rspec-mocks (~> 3.0.0) - rspec-support (~> 3.0.0) - rspec-support (3.0.2) - rubocop (0.49.1) - parallel (~> 1.10) + + rspec-core (~> 3.6.0) + rspec-expectations (~> 3.6.0) + rspec-mocks (~> 3.6.0) + rspec-support (~> 3.6.0) + rspec-support (3.6.0) + rubocop (0.48.1) parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) @@ -466,6 +469,7 @@ GEM ruby-oembed (0.8.14) ruby-openid (2.5.0) ruby-progressbar (1.8.1) + ruby_dep (1.5.0) rubyzip (1.2.1) safe_yaml (1.0.4) sass (3.2.19) @@ -475,6 +479,7 @@ GEM sprockets (~> 2.8, < 2.12) sprockets-rails (~> 2.0) selectize-rails (0.12.4) + shellany (0.0.1) shoulda-matchers (2.8.0) activesupport (>= 3.0.0) simplecov (0.11.2) @@ -512,7 +517,6 @@ GEM thread_safe (0.3.6) tilt (1.4.1) timecop (0.7.1) - timers (1.1.0) tins (1.6.0) transitions (0.1.12) ttfunk (1.1.1) @@ -590,7 +594,7 @@ DEPENDENCIES formtastic (~> 3.1.1) formtastic-bootstrap gravtastic - guard-rspec (~> 4.2.8) + guard-rspec haml-rails haml_lint (~> 0.24.0) hoptoad_notifier (~> 2.3) @@ -637,8 +641,9 @@ DEPENDENCIES rolify rqrcode rspec-activemodel-mocks - rspec-rails - rubocop (~> 0.49.0) + + rspec-rails (~> 3.5, >= 3.5.2) + rubocop (~> 0.48.1) ruby-oembed sass-rails (>= 4.0.2) selectize-rails diff --git a/spec/controllers/admin/roles_controller_spec.rb b/spec/controllers/admin/roles_controller_spec.rb index 964346ef..d5cdc67e 100644 --- a/spec/controllers/admin/roles_controller_spec.rb +++ b/spec/controllers/admin/roles_controller_spec.rb @@ -55,7 +55,7 @@ describe Admin::RolesController do end describe 'POST #toggle' do - before:each do + before :each do sign_in admin post :toggle_user, conference_id: conference.short_title, user: { email: 'user1@osem.io' }, From 5c0a565e8d5f136c9d668e840decd8f4bd74cbc0 Mon Sep 17 00:00:00 2001 From: rahul Date: Sat, 15 Jul 2017 19:59:02 +0530 Subject: [PATCH 23/26] webmock updated Updated Webmock as previous version was not compatible with the new gems --- Gemfile.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 928c3b84..8f7ef5d6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -57,7 +57,8 @@ GEM awesome_nested_set (>= 2.0) acts_as_list (0.4.0) activerecord (>= 3.0) - addressable (2.3.6) + addressable (2.5.1) + public_suffix (~> 2.0, >= 2.0.2) ahoy_matey (1.0.0) addressable browser (>= 0.4.0) @@ -87,11 +88,8 @@ GEM bootstrap3-datetimepicker-rails (3.0.3) momentjs-rails (>= 2.8.1) browser (0.6.0) - byebug (9.0.6) - builder (3.2.3) - columnize (~> 0.8) - debugger-linecache (~> 1.2) + byebug (9.0.6) cancancan (1.13.1) capybara (2.6.2) addressable @@ -140,7 +138,7 @@ GEM term-ansicolor (~> 1.3) thor (~> 0.19.1) tins (~> 1.6.0) - crack (0.4.2) + crack (0.4.3) safe_yaml (~> 1.0.0) currencies (0.4.2) daemons (1.1.9) @@ -220,6 +218,7 @@ GEM rake (>= 10, < 13) rubocop (>= 0.47.0) sysexits (~> 1.1) + hashdiff (0.3.4) hashie (2.1.1) hike (1.2.3) hoptoad_notifier (2.4.11) @@ -355,6 +354,7 @@ GEM coderay (~> 1.1.0) method_source (~> 0.8.1) slop (~> 3.4) + public_suffix (2.0.5) rack (1.6.8) rack-openid (1.3.1) rack (>= 1.1.0) @@ -410,8 +410,8 @@ GEM activesupport (= 4.2.9) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) - - rainbow (2.2.1) + rainbow (2.2.2) + rake rake (12.0.0) rb-fsevent (0.10.2) rb-inotify (0.9.10) @@ -454,13 +454,13 @@ GEM actionpack (>= 3.0) activesupport (>= 3.0) railties (>= 3.0) - rspec-core (~> 3.6.0) rspec-expectations (~> 3.6.0) rspec-mocks (~> 3.6.0) rspec-support (~> 3.6.0) rspec-support (3.6.0) - rubocop (0.48.1) + rubocop (0.49.1) + parallel (~> 1.10) parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) @@ -542,9 +542,10 @@ GEM binding_of_caller (>= 0.7.2) railties (>= 4.0) sprockets-rails (>= 2.0, < 4.0) - webmock (1.20.4) + webmock (3.0.1) addressable (>= 2.3.6) crack (>= 0.3.2) + hashdiff websocket-driver (0.6.3) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.2) @@ -641,9 +642,8 @@ DEPENDENCIES rolify rqrcode rspec-activemodel-mocks - rspec-rails (~> 3.5, >= 3.5.2) - rubocop (~> 0.48.1) + rubocop (~> 0.49.0) ruby-oembed sass-rails (>= 4.0.2) selectize-rails From f4f05b4e9bed440f486ca81cc07c1fdc70d7fb88 Mon Sep 17 00:00:00 2001 From: gotens1211 Date: Tue, 21 Mar 2017 17:57:01 +0530 Subject: [PATCH 24/26] Fixes #1195 Made the charts responsive for small screens --- .../conferences/_doughnut_chart.html.haml | 19 ++++++++++++++++++- .../admin/conferences/_line_chart.html.haml | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/app/views/admin/conferences/_doughnut_chart.html.haml b/app/views/admin/conferences/_doughnut_chart.html.haml index c8ef55fc..f4a8f0ba 100644 --- a/app/views/admin/conferences/_doughnut_chart.html.haml +++ b/app/views/admin/conferences/_doughnut_chart.html.haml @@ -1,6 +1,23 @@ .text-center %h4 #{title} - %canvas.doughnut_chart{ 'data-chart' => data.to_json } + %canvas.doughnut_chart{ id: "dough_#{title}", 'data-chart' => data.to_json } - if data - data.each do |key, value| %span{ 'style' => "border-bottom: 3px solid #{value['color']}" } #{key}: #{value['value']} + +:javascript + $(document).ready( function(){ + + var d = $("#dough_#{title}"); + var dt = d.get(0).getContext('2d'); + + $(window).resize( respondCanvas ); + + function respondCanvas(){ + dt.canvas.width = 150; + dt.canvas.height = 150; + } + + respondCanvas(); + + }); diff --git a/app/views/admin/conferences/_line_chart.html.haml b/app/views/admin/conferences/_line_chart.html.haml index cd49df10..12d825e7 100644 --- a/app/views/admin/conferences/_line_chart.html.haml +++ b/app/views/admin/conferences/_line_chart.html.haml @@ -27,3 +27,21 @@ %span{ 'style' => "border-bottom: 3px solid #{conference[:color]};", 'data-chart' => "#{name}" } %input{ 'type' => 'checkbox', 'name' => "#{conference[:short_title]}" } #{conference[:short_title]} + +:javascript + $(document).ready( function(){ + + var c = $("#line_chart_#{name}"); + var ct = c.get(0).getContext('2d'); + var container = $(c).parent(); + + $(window).resize( respondCanvas ); + + function respondCanvas(){ + c.attr('width', $(container).width() ); + c.attr('height', $(container).height() ); + } + + respondCanvas(); + + }); From 003926ea8f0c78e5586b576a150bfcaafa4721fe Mon Sep 17 00:00:00 2001 From: Stella Rouzi Date: Fri, 14 Jul 2017 15:03:14 +0300 Subject: [PATCH 25/26] Move some contributing info on wiki --- CONTRIBUTING.md | 101 ------------------------------------------------ 1 file changed, 101 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c0688999..5193725d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -71,59 +71,6 @@ You can access the app [localhost:3000](http://localhost:3000). Whatever you cha * If you are already a contributor and you get a positive review, you can merge your pull-request yourself * If you are not already a contributor please request a merge via the pull-request comments -### Getting Started - -* When you get involved with OSEM for the first time, you can choose issues labeled as [Junior]( https://github.com/openSUSE/osem/issues?q=is%3Aissue+is%3Aopen+label%3AJunior) -* Leave a comment on the issue that you want to work on it - * We expect you to work on it and show progress by either opening a PR or commenting on the issue - * If you change your mind, and do not want to work on the issue any more, please be fair to others and leave a comment to let us know - * Do **not** work on issues that are assigned to others. If you are uncertain, ask and wait for a **contributor** to reply -* Avoid working on issues that have no label - * If you have opened a new issue, please wait for a contributor to add relevant labels -* If an issue is a feature, we should first have a rough idea on how we want to implement it - * If there is already such a discussion on the issue, you can go ahead and pick this up - * If not, please first leave a comment on how you want to implement it and wait for contributors' feedback - -### Commits -* Commit title should be short and descriptive - * title (or summary line) is the first line of the commit message - * that says what the commit is doing - * in no more than 50 characters - * starting with a word like 'Fix' or 'Add' or 'Change' - * **without** a period (.) at the end - * followed by a blank line -* Commit messages are - * up to 72 characters - * with break lines -* Reference the issue(s) the commit closes - * https://help.github.com/articles/closing-issues-via-commit-messages - * If you haven't done so since the beginning, you should reference the issue when you squash your commits - -### Pull Requests workflow -Please open a pull request (PR) only when you have finished coding, and your changes are ready to be reviewed for merging. - -* Title - * Include a comprehensive title about what this PR is doing - * Referencing the issue number on the PR title is not giving any information about what this PR is about - * The title should be short (50 characters maximum); you can add more information in the description -* Description - * Add a couple of lines about what is the problem you are trying to solve and how you have addressed it - * Add bullet points about the new things you are introducing, if applicable - * Reference the issue(s) you are solving - * Add a screenshot of your change, if you are working on something that changes how the app looks like -* Automated checks - * We automatically run the [test suite](https://github.com/openSUSE/osem/blob/master/CONTRIBUTING.md#test-suite) and security checks on every PR - * Check back later to see if all checks were successful, if not, address them or leave a comment to ask for help -* Pushing new changes to your PR - * Always add **new** commits; this tremendously helps reviewers - * Do not squash commits, unless explicitly requested by the reviewer -* Take care of your PR - * Make sure you check the status of your PR regularly - * Address your reviews, make the necessary changes, ask if something is not clear to you - * Rebase against newest changes, when needed; we cannot properly review PRs that are not rebased - -Reviewing your PR might take some time, as we are all volunteers. Please be responsive and respectful. - ### Coding Style We are using [rubocop](https://github.com/bbatsov/rubocop) as a style checker. It is checking code style each time the test suite runs. You can run it locally with @@ -141,16 +88,6 @@ We are using [rspec](http://rspec.info/)+[capybara](http://jnicklas.github.io/ca vagrant exec bundle exec rspec ``` -### Review App of your PR - -OSEM uses [Review Apps](https://devcenter.heroku.com/articles/github-integration-review-apps) on Heroku. - -* The review app can be manually created by a maintainer, and when that happens you will see a relevant message in the PR - -* Please help reviewers by adding the necessary data relevant to your PR, -eg. if your PR is doing something related to conference registrations, go to the review app and make sure there is a conference with registrations. - - ### Email Notifications **Note**: We use [letter_opener](https://github.com/ryanb/letter_opener) in development environment. You can check out your mails by visiting [localhost:3000/letter_opener](http://localhost:3000/letter_opener). @@ -181,44 +118,6 @@ OSEM_GITHUB_SECRET='sample' If you don't already have a `.env` file you can use the `dotenv.example` as a template. -## Labels for issues and PRs -...and what they mean! - -1. **Bug** - * A bug in the application, something is wrong and needs to be fixed! - * Ideally the issue includes details on how to reproduce the bug - * Reproduce the bug in master branch, and send a PR that solves it -2. **Design** - * Related to the looks and/or usability of the application; needs attention from someone who understands front-end and UX - * If you are good with graphics and design, give it a shot! -3. **Documentation** - * Related to the documentation of our application, eg our INSTALL.md file or a wiki page with instructions on how to use the app, or part of it. - * If you are working on a documentation issue, make sure you are covering all cases. -4. **Epic** - * We may, or may not, solve this, thus it is epic. It's bigger than a feature request, because it fundamentally changes or affects the app, or a significant part of it. - * Do **not** work on this without prior discussion with the maintainers, it's called epic for a reason! -5. **Feature** - * This is a new feature for something new in the app! - * If an issue is labeled *Feature*, don't work on the issue, unless the maintainers have decided on how to proceed - * Ideally, leave a comment with your proposed solution in the issue and wait for feedback -6. **Grooming** - * This is working, but could look better, thus needs some attention and grooming. -7. **Hacktoberfest** - * This is for the issues included in the coding event of Hacktoberfest. You can ignore it, when the event is not on -8. **in progress** -9. **Junior** - * For new comers! RoR beginners or people unfamiliar with the application. Where you must start if you are interested in a mentoring program we participate in. -10. **need feedback** - * Maintainers' attention is needed to decide if this is something we want in the app, and/or how it should be implemented -11. **Operation** -12. **ready** -13. **Refactorization** - * Our code needs to be re-written; to avoid code duplication, or make the code more readable, or do things in a simpler way! -14. **Research** - * Ideas to explore; and think if there is anything we want to include in our app. -15. **GSoC** - * To group all the issues and PRs related to Google Summer of Code together. - ## Code of Conduct OSEM is part of the openSUSE project. We follow all the [openSUSE Guiding Principles!](http://en.opensuse.org/openSUSE:Guiding_principles) If you think someone doesn't do that, please let us know at maintainers@osem.io From 526b7ed2a3819a5814ac6fdd901e15bc45d08ce6 Mon Sep 17 00:00:00 2001 From: Stella Rouzi Date: Mon, 17 Jul 2017 17:05:02 +0300 Subject: [PATCH 26/26] Add code of conduct file --- CODE_OF_CONDUCT.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..7e9792fa --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1 @@ +OSEM is part of the openSUSE project. We follow all the [openSUSE Guiding Principles!](http://en.opensuse.org/openSUSE:Guiding_principles) If you think someone doesn't do that, please let us know at maintainers@osem.io