From d860ec560791873ddda904290934022ecd69114c Mon Sep 17 00:00:00 2001 From: Alator Date: Tue, 14 Mar 2017 20:37:56 +0200 Subject: [PATCH 001/185] Update proposal link in reports --- app/views/admin/events/reports.html.haml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/admin/events/reports.html.haml b/app/views/admin/events/reports.html.haml index f300d10c..09659f06 100644 --- a/app/views/admin/events/reports.html.haml +++ b/app/views/admin/events/reports.html.haml @@ -46,7 +46,7 @@ %tr - progress_status = event.progress_status %td - = link_to event.title, edit_conference_program_proposal_path(@conference.short_title, event) + = link_to event.title, edit_admin_conference_program_event_path(@conference.short_title, event) %br .small (Presented by #{event.speaker_names}) @@ -76,7 +76,7 @@ %tbody - @events_missing_commercial.each do |event| %tr - %td= link_to event.title, edit_conference_program_proposal_path(@conference.short_title, event) + %td= link_to event.title, edit_admin_conference_program_event_path(@conference.short_title, event) %td #{event.speaker_names} #requirements.tab-pane @@ -97,7 +97,7 @@ %tbody - @events_with_requirements.each do |event| %tr - %td= link_to event.title, edit_conference_program_proposal_path(@conference.short_title, event) + %td= link_to event.title, edit_admin_conference_program_event_path(@conference.short_title, event) %td #{event.speaker_names} %td= event.description @@ -122,6 +122,6 @@ %tr %td= speaker.user.name %td= @conference.user_registered?(speaker.user) ? 'Yes' : 'No' - %td= link_to speaker.event.title, edit_conference_program_proposal_path(@conference.short_title, speaker.event) + %td= link_to speaker.event.title, edit_admin_conference_program_event_path(@conference.short_title, speaker.event) - event_start_time = speaker.event.time %td= event_start_time.present? ? event_start_time : '-' From 0e8e626156683dfd11779f8659d6f92c3b09e1e9 Mon Sep 17 00:00:00 2001 From: Chaitanya Date: Fri, 24 Mar 2017 20:52:27 +0530 Subject: [PATCH 002/185] Allow to view schedule without login Add show and events action's can abilities of schedule for not_signed_in user in order to make schedule available to view without login. Closes #1343 --- app/controllers/schedules_controller.rb | 3 ++- app/models/ability.rb | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/controllers/schedules_controller.rb b/app/controllers/schedules_controller.rb index 0b135328..e0d1e1ca 100644 --- a/app/controllers/schedules_controller.rb +++ b/app/controllers/schedules_controller.rb @@ -1,7 +1,8 @@ class SchedulesController < ApplicationController + load_and_authorize_resource protect_from_forgery with: :null_session before_action :respond_to_options - load_and_authorize_resource :conference, find_by: :short_title + load_resource :conference, find_by: :short_title load_resource :program, through: :conference, singleton: true, except: :index def show diff --git a/app/models/ability.rb b/app/models/ability.rb index ce047a1b..14913e75 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -62,6 +62,10 @@ class Ability can [:new, :create], Event do |event| event.program.cfp_open? && event.new_record? end + + can [:show, :events], Schedule do |schedule| + schedule.program.schedule_public + end end end From 50b2153754f6b1457ce2e646e354d2a78bcae83b Mon Sep 17 00:00:00 2001 From: Emanuel Hayford Date: Fri, 24 Mar 2017 20:13:02 +0100 Subject: [PATCH 003/185] Group related cops together This groups related cops in rubocop configuration file together and arranges them in an alphabetical order Close #1385 --- .rubocop.yml | 161 ++++++++++++++++++++++++++++----------------------- 1 file changed, 90 insertions(+), 71 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 74f9706b..b21081ea 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,17 +1,46 @@ -Rails: - Enabled: true +# Inherit style from another configuration inherit_from: .rubocop_todo.yml -Style/HashSyntax: - Enabled: true - EnforcedStyle: ruby19 +# Apply rule to all cops +AllCops: + Include: + - '**/Rakefile' + - '**/config.ru' + Exclude: + - 'db/schema.rb' + - 'vendor/bundle/**/*' + - 'bundle/**/*' + - 'config/**/*' + - 'bin/*' -# Things deprecated in current ruby API -Lint/DeprecatedClassMethods: +#################### Style ############################### + +# Align the elements of a hash literal if they span more than one line +Style/AlignHash: Enabled: true -# Do not compare with nil. Use .nil? instead -Style/NilComparison: +# Align the parameters of a method call if they span more than one line +Style/AlignParameters: + Enabled: true + +# Use && instead of and, use || instead of or +Style/AndOr: + Enabled: true + +# Avoid redundunt curly braces when it is obvious that hash is used +Style/BracesAroundHashParameters: + Enabled: true + +# Avoid the use of the case equality operator `===` +Style/CaseEquality: + Enabled: true + +# Use nested module/class definitions instead of compact style +Style/ClassAndModuleChildren: + Enabled: true + +# Checks for uses of double negation (!!) to convert something to a boolean value. +Style/DoubleNegation: Enabled: true # Use one empty line between method definitions @@ -34,6 +63,45 @@ Style/EmptyLiteral: Style/For: Enabled: true +# Checks that operators have space around them, except for ** which should not have surrounding space. +Style/SpaceAroundOperators: + Enabled: true + +# Use the new Ruby 1.9 hash syntax +Style/HashSyntax: + Enabled: true + EnforcedStyle: ruby19 + +# Do not compare with nil. Use .nil? instead +Style/NilComparison: + Enabled: true + +# Use single quotes unless there's string interpolation +Style/StringLiterals: + Enabled: true + +# Avoid trailing blank lines +Style/TrailingBlankLines: + Enabled: true + +# Avoid trailing whitespace +Style/TrailingWhitespace: + Enabled: true + +#################### Metrics ############################### + +# Avoid deep blocks nesting +Metrics/BlockNesting: + Max: 4 + +# Avoid writing classes that are more than 300 lines +Metrics/ClassLength: + Max: 300 + Exclude: + - 'app/models/conference.rb' + +#################### Lint ############################### + # Wrap your assignment in condition if you mean it, otherwise it is most likely equality check Lint/AssignmentInCondition: Enabled: true @@ -42,6 +110,10 @@ Lint/AssignmentInCondition: Lint/BlockAlignment: Enabled: true +# Things deprecated in current ruby API +Lint/DeprecatedClassMethods: + Enabled: true + # Do not use literal in conditions. We have it enabled for now Lint/LiteralInCondition: Enabled: false @@ -50,7 +122,7 @@ Lint/LiteralInCondition: Lint/Loop: Enabled: true -# do not put space before arguments when they are in parentheses +# Do not put space before arguments when they are in parentheses Lint/ParenthesesAsGroupedExpression: Enabled: true @@ -58,19 +130,19 @@ Lint/ParenthesesAsGroupedExpression: Lint/RescueException: Enabled: true -# do not shadow local variables in blocks, choose other name +# Do not shadow local variables in blocks, choose other name Lint/ShadowingOuterLocalVariable: Enabled: true -# use _ or variable_name to explicitly mark variable as unused +# Use _ or variable_name to explicitly mark variable as unused Lint/UnusedBlockArgument: Enabled: true -# use _ or _argument_name to explicitly mark argument as unused +# Use _ or _argument_name to explicitly mark argument as unused Lint/UnusedMethodArgument: Enabled: true -# avoid useless assignment +# Avoid useless assignment Lint/UselessAssignment: Enabled: true @@ -78,61 +150,8 @@ Lint/UselessAssignment: Lint/Void: Enabled: true -# Align the elements of a hash literal if they span more than one line -Style/AlignHash: +#################### Rails ############################### + +# Enforce Rails specific style +Rails: Enabled: true - -# Align the parameters of a method call if they span more than one line -Style/AlignParameters: - Enabled: true - -# Use && instead of and, use || instead of or -Style/AndOr: - Enabled: true - -# avoid deep blocks nesting -Metrics/BlockNesting: - Max: 4 - -Metrics/ClassLength: - Max: 300 - Exclude: - - 'app/models/conference.rb' - -# avoid redundunt curly braces when it is obvious that hash is used -Style/BracesAroundHashParameters: - Enabled: true - -# Checks that operators have space around them, except for ** which should not have surrounding space. -Style/SpaceAroundOperators: - Enabled: true - -Style/CaseEquality: - Enabled: true - -Style/ClassAndModuleChildren: - Enabled: true - -Style/StringLiterals: - Enabled: true - -Style/TrailingBlankLines: - Enabled: true - -Style/TrailingWhitespace: - Enabled: true - -# Checks for uses of double negation (!!) to convert something to a boolean value. -Style/DoubleNegation: - Enabled: true - -AllCops: - Include: - - '**/Rakefile' - - '**/config.ru' - Exclude: - - 'db/schema.rb' - - 'vendor/bundle/**/*' - - 'bundle/**/*' - - 'config/**/*' - - 'bin/*' From a1d9cc39f90de4399a0b45b1eeb3f8d978b6f5e6 Mon Sep 17 00:00:00 2001 From: gotens1211 Date: Sat, 25 Mar 2017 01:43:17 +0530 Subject: [PATCH 004/185] Fixes #1402 Updated nokogiri in gemfile.lock --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index e73c9b5e..13b5d012 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -280,7 +280,7 @@ GEM mysql2 (0.4.2) netrc (0.11.0) nio4r (1.2.1) - nokogiri (1.6.8) + nokogiri (1.7.1) mini_portile2 (~> 2.1.0) pkg-config (~> 1.1.7) oauth2 (0.9.4) From e46953e03f59707a014c26a00788cac0e488648e Mon Sep 17 00:00:00 2001 From: Chaitanya Date: Sat, 25 Mar 2017 10:41:53 +0530 Subject: [PATCH 005/185] Fix SyntaxError in SchedulesController#events Remove unexpected => from app/views/schedules/_event.html.haml to resolve syntax error Closes #1404 --- app/views/schedules/_event.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/schedules/_event.html.haml b/app/views/schedules/_event.html.haml index ec846c8a..a5f2c569 100644 --- a/app/views/schedules/_event.html.haml +++ b/app/views/schedules/_event.html.haml @@ -18,7 +18,7 @@ presented by #{event.speaker_names} %p = markdown(truncate(event.abstract, length: 400)) - = link_to 'more', conference_program_proposal_path(@conference.short_title, event.id) if event.abstract.length > 400=> + = link_to 'more', conference_program_proposal_path(@conference.short_title, event.id) if event.abstract.length > 400 - if event_schedule.present? %span.track %span.fa.fa-clock-o From e8aa7c8a982039486b3ad2d145d503ceb48bc31d Mon Sep 17 00:00:00 2001 From: Siddhant Bajaj Date: Sun, 26 Mar 2017 00:20:37 +0530 Subject: [PATCH 006/185] Fixed Venue link in todo list for organiser "Add venue" link in todo list is not active for the organiser of that conference. Fixes #1383 --- app/views/admin/conferences/_todo_list.html.haml | 8 +++++--- spec/features/ability_spec.rb | 9 +++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/app/views/admin/conferences/_todo_list.html.haml b/app/views/admin/conferences/_todo_list.html.haml index 6a091f11..cd98391d 100644 --- a/app/views/admin/conferences/_todo_list.html.haml +++ b/app/views/admin/conferences/_todo_list.html.haml @@ -21,14 +21,16 @@ = link_to 'Set up call for papers', admin_conference_program_cfp_path(conference_progress['short_title']) - else Set up call for papers - %li{ 'class' => "list-group-item #{class_for_todo(conference_progress['venue'])}" } - %span{ 'class' => icon_for_todo(conference_progress['venue']) } - - if can? :update, @conference.venue + %li{'class'=>"list-group-item #{class_for_todo(conference_progress['venue'])}"} + %span{'class'=>icon_for_todo(conference_progress['venue'])} + - if can? :update, Venue.new(conference: @conference) + - @conference.reload - if conference.venue = link_to 'Add venue', edit_admin_conference_venue_path(conference_progress['short_title']) - else = link_to 'Add venue', new_admin_conference_venue_path(conference_progress['short_title']) - else + - @conference.reload Add venue %li{ 'class' => "list-group-item #{class_for_todo(conference_progress['rooms'])}" } %span{ 'class' => icon_for_todo(conference_progress['rooms']) } diff --git a/spec/features/ability_spec.rb b/spec/features/ability_spec.rb index 6e884a68..e304b4b2 100644 --- a/spec/features/ability_spec.rb +++ b/spec/features/ability_spec.rb @@ -7,14 +7,16 @@ feature 'Has correct abilities' do let(:conference3) { create(:full_conference) } # user is info_desk let(:conference4) { create(:full_conference) } # user is volunteer coordinator let(:conference5) { create(:full_conference) } # user has no role + let(:conference6) { create(:conference) } # user is organizer, venue is not set by default - let(:role_organizer) { Role.find_by(name: 'organizer', resource: conference1) } + let(:role_organizer_conf1) { Role.find_by(name: 'organizer', resource: conference1) } + let(:role_organizer_conf6) { Role.find_by(name: 'organizer', resource: conference6) } let(:role_cfp) { Role.find_by(name: 'cfp', resource: conference2) } let(:role_info_desk) { Role.find_by(name: 'info_desk', resource: conference3) } let(:role_volunteers_coordinator) { Role.find_by(name: 'volunteers_coordinator', resource: conference4) } let(:user) { create(:user) } - let(:user_organizer) { create(:user, role_ids: [role_organizer.id]) } + let(:user_organizer) { create(:user, role_ids: [role_organizer_conf1.id, role_organizer_conf6.id]) } let(:user_cfp) { create(:user, role_ids: [role_cfp.id]) } let(:user_info_desk) { create(:user, role_ids: [role_info_desk.id]) } let(:user_volunteers_coordinator) { create(:user, role_ids: [role_volunteers_coordinator.id]) } @@ -58,6 +60,9 @@ feature 'Has correct abilities' do expect(page).to have_link('Roles', href: "/admin/conferences/#{conference1.short_title}/roles") expect(page).to have_link('Resources', href: "/admin/conferences/#{conference1.short_title}/resources") + visit admin_conference_path(conference6.short_title) + expect(page).to have_link('Add venue', href: "/admin/conferences/#{conference6.short_title}/venue/new") + visit edit_admin_conference_path(conference1.short_title) expect(current_path).to eq(edit_admin_conference_path(conference1.short_title)) From 4427f43bdff7cb5c2a63fe40b7ea2794b98c5971 Mon Sep 17 00:00:00 2001 From: Chaitanya Date: Tue, 28 Mar 2017 13:27:52 +0530 Subject: [PATCH 007/185] Enable Style/RedundantSelf Rubocop cop This cop checks for redundant uses of self. It supports autocorrection, so all the offenses where automatically solved. Closes #1373 --- .rubocop.yml | 4 ++++ .rubocop_todo.yml | 16 ---------------- app/models/cfp.rb | 12 ++++++------ app/models/comment.rb | 2 +- app/models/conference.rb | 12 ++++++------ app/models/event.rb | 26 +++++++++++++------------- app/models/program.rb | 22 +++++++++++----------- app/models/question.rb | 2 +- app/models/ticket.rb | 2 +- app/models/user.rb | 8 ++++---- app/models/venue.rb | 2 +- 11 files changed, 48 insertions(+), 60 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index b21081ea..ca819d9d 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -76,6 +76,10 @@ Style/HashSyntax: Style/NilComparison: Enabled: true +# Checks for redundant uses of self. +Style/RedundantSelf: + Enabled: true + # Use single quotes unless there's string interpolation Style/StringLiterals: Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 72d3fb23..47e50eb9 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -527,22 +527,6 @@ Style/RedundantReturn: Exclude: - 'app/helpers/application_helper.rb' -# Offense count: 61 -# Cop supports --auto-correct. -Style/RedundantSelf: - Exclude: - - 'app/models/ahoy/program.rb' - - 'app/models/call_for_paper.rb' - - 'app/models/cfp.rb' - - 'app/models/comment.rb' - - 'app/models/conference.rb' - - 'app/models/event.rb' - - 'app/models/program.rb' - - 'app/models/question.rb' - - 'app/models/ticket.rb' - - 'app/models/user.rb' - - 'app/models/venue.rb' - # Offense count: 2 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerSlashes. diff --git a/app/models/cfp.rb b/app/models/cfp.rb index 3e516ae6..827d0f1c 100644 --- a/app/models/cfp.rb +++ b/app/models/cfp.rb @@ -16,11 +16,11 @@ class Cfp < ActiveRecord::Base # * +True+ -> If cfp dates is updated and all other parameters are set # * +False+ -> Either cfp date is not updated or one or more parameter is not set def notify_on_cfp_date_update? - !self.end_date.blank? && !self.start_date.blank?\ - && (self.start_date_changed? || self.end_date_changed?)\ - && self.program.conference.email_settings.send_on_cfp_dates_updated\ - && !self.program.conference.email_settings.cfp_dates_updated_subject.blank?\ - && !self.program.conference.email_settings.cfp_dates_updated_body.blank? + !end_date.blank? && !start_date.blank?\ + && (start_date_changed? || end_date_changed?)\ + && program.conference.email_settings.send_on_cfp_dates_updated\ + && !program.conference.email_settings.cfp_dates_updated_subject.blank?\ + && !program.conference.email_settings.cfp_dates_updated_body.blank? end ## @@ -51,7 +51,7 @@ class Cfp < ActiveRecord::Base end def remaining_days(date = Date.today) - result = (self.end_date - date).to_i + result = (end_date - date).to_i result > 0 ? result : 0 end diff --git a/app/models/comment.rb b/app/models/comment.rb index 31531f8e..00751bb8 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -27,7 +27,7 @@ class Comment < ActiveRecord::Base #helper method to check if a comment has children def has_children? - self.children.any? + children.any? end # Helper class method to lookup all comments assigned diff --git a/app/models/conference.rb b/app/models/conference.rb index d5e05f3c..5b868ca9 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -555,9 +555,9 @@ class Conference < ActiveRecord::Base # * +True+ -> If conference is updated and all other parameters are set # * +False+ -> Either conference is not updated or one or more parameter is not set def notify_on_dates_changed? - return false unless self.email_settings.send_on_conference_dates_updated + return false unless email_settings.send_on_conference_dates_updated # do not notify unless one of the dates changed - return false unless self.start_date_changed? || self.end_date_changed? + return false unless start_date_changed? || end_date_changed? # do not notify unless the mail content is set up (!email_settings.conference_dates_updated_subject.blank? && !email_settings.conference_dates_updated_body.blank?) end @@ -569,9 +569,9 @@ class Conference < ActiveRecord::Base # * +True+ -> If registration dates is updated and all other parameters are set # * +False+ -> Either registration date is not updated or one or more parameter is not set def notify_on_registration_dates_changed? - return false unless self.email_settings.send_on_conference_registration_dates_updated + return false unless email_settings.send_on_conference_registration_dates_updated # do not notify unless we allow a registration - return false unless self.registration_period + return false unless registration_period # do not notify unless one of the dates changed return false unless registration_period.start_date_changed? || registration_period.end_date_changed? # do not notify unless the mail content is set up @@ -628,8 +628,8 @@ class Conference < ActiveRecord::Base end after_create do - self.create_contact - self.create_program + create_contact + create_program create_roles end diff --git a/app/models/event.rb b/app/models/event.rb index 1eebb0b0..e138d9d9 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -185,12 +185,12 @@ class Event < ActiveRecord::Base end begin if mail - self.send(transition, - send_mail: send_mail_param) + send(transition, + send_mail: send_mail_param) else - self.send(transition) + send(transition) end - self.save + save rescue Transitions::InvalidTransition => e alert = "Update state failed. #{e.message}" end @@ -210,12 +210,12 @@ class Event < ActiveRecord::Base # Returns +Hash+ def progress_status { - registered: self.program.conference.user_registered?(self.submitter), - commercials: self.commercials.any?, - biography: !self.submitter.biography.blank?, - subtitle: !self.subtitle.blank?, - track: (!self.track.blank? unless self.program.tracks.empty?), - difficulty_level: !self.difficulty_level.blank?, + registered: program.conference.user_registered?(submitter), + commercials: commercials.any?, + biography: !submitter.biography.blank?, + subtitle: !subtitle.blank?, + track: (!track.blank? unless program.tracks.empty?), + difficulty_level: !difficulty_level.blank?, title: true, abstract: true }.with_indifferent_access @@ -227,7 +227,7 @@ class Event < ActiveRecord::Base # ====Returns # * +String+ -> Progress in Percent def calculate_progress - result = self.progress_status + result = progress_status (100 * result.values.count(true) / result.values.compact.count).to_s end @@ -280,8 +280,8 @@ class Event < ActiveRecord::Base def set_week self.week = created_at.strftime('%W') - self.without_versioning do - self.save! + without_versioning do + save! end end diff --git a/app/models/program.rb b/app/models/program.rb index 6432d56b..f8b46b18 100644 --- a/app/models/program.rb +++ b/app/models/program.rb @@ -115,7 +115,7 @@ class Program < ActiveRecord::Base # * +false+ -> If rating is not enabled # * +true+ -> If rating is enabled def rating_enabled? - self.rating && self.rating > 0 + rating && rating > 0 end ## @@ -139,7 +139,7 @@ class Program < ActiveRecord::Base end def languages_list - self.languages.split(',').map {|l| ISO_639.find(l).english_name} if self.languages.present? + languages.split(',').map {|l| ISO_639.find(l).english_name} if languages.present? end ## @@ -161,10 +161,10 @@ class Program < ActiveRecord::Base def create_event_types EventType.create(title: 'Talk', length: 30, color: '#FF0000', description: 'Presentation in lecture format', minimum_abstract_length: 0, - maximum_abstract_length: 500, program_id: self.id) + maximum_abstract_length: 500, program_id: id) EventType.create(title: 'Workshop', length: 60, color: '#0000FF', description: 'Interactive hands-on practice', minimum_abstract_length: 0, - maximum_abstract_length: 500, program_id: self.id) + maximum_abstract_length: 500, program_id: id) true end @@ -174,13 +174,13 @@ class Program < ActiveRecord::Base def create_difficulty_levels DifficultyLevel.create(title: 'Easy', description: 'Events are understandable for everyone without knowledge of the topic.', - color: '#70EF69', program_id: self.id) + color: '#70EF69', program_id: id) DifficultyLevel.create(title: 'Medium', description: 'Events require a basic understanding of the topic.', - color: '#EEEF69', program_id: self.id) + color: '#EEEF69', program_id: id) DifficultyLevel.create(title: 'Hard', description: 'Events require expert knowledge of the topic.', - color: '#EF6E69', program_id: self.id) + color: '#EF6E69', program_id: id) true end @@ -188,12 +188,12 @@ class Program < ActiveRecord::Base # Check if languages string has the right format. Used as validation. # def check_languages_format - return unless self.languages.present? + return unless languages.present? # All white spaces are removed to allow languages to be separated by ',' and ', '. The languages string without spaces is saved - self.languages = self.languages.delete(' ').downcase + self.languages = languages.delete(' ').downcase errors.add(:languages, 'must be two letters separated by commas') && return unless - self.languages.match(/^$|(\A[a-z][a-z](,[a-z][a-z])*\z)/).present? - languages_array = self.languages.split(',') + languages.match(/^$|(\A[a-z][a-z](,[a-z][a-z])*\z)/).present? + languages_array = languages.split(',') # We check that languages are not repeated errors.add(:languages, "can't be repeated") && return unless languages_array.uniq!.nil? # We check if every language is a valid ISO 639-1 language diff --git a/app/models/question.rb b/app/models/question.rb index f49e95a5..4d8a33d0 100644 --- a/app/models/question.rb +++ b/app/models/question.rb @@ -12,6 +12,6 @@ class Question < ActiveRecord::Base private def existing_answers - errors.add(:base, 'Must have answers') if self.answers.blank? + errors.add(:base, 'Must have answers') if answers.blank? end end diff --git a/app/models/ticket.rb b/app/models/ticket.rb index 8c93f5c9..e7af9809 100644 --- a/app/models/ticket.rb +++ b/app/models/ticket.rb @@ -66,7 +66,7 @@ class Ticket < ActiveRecord::Base private def tickets_of_conference_have_same_currency - unless Ticket.where(conference_id: conference_id).all?{|t| t.price_currency == self.price_currency } + unless Ticket.where(conference_id: conference_id).all?{|t| t.price_currency == price_currency } errors.add(:price_currency, 'is different from the existing tickets of this conference.') end end diff --git a/app/models/user.rb b/app/models/user.rb index 05edcce6..60bbab80 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -72,7 +72,7 @@ class User < ActiveRecord::Base # * +true+ if the user attended the event # * +false+ if the user did not attend the event def attended_event? event - event_registration = event.events_registrations.find_by(registration: self.registrations) + event_registration = event.events_registrations.find_by(registration: registrations) return false unless event_registration.present? event_registration.attended @@ -91,7 +91,7 @@ class User < ActiveRecord::Base end def subscribed? conference - self.subscriptions.find_by(conference_id: conference.id).present? + subscriptions.find_by(conference_id: conference.id).present? end def supports? conference @@ -206,8 +206,8 @@ class User < ActiveRecord::Base # Check if biography has an allowed number of words. Used as validation. # def biography_limit - if self.biography.present? - errors.add(:biography, 'is limited to 150 words.') if self.biography.split.length > 150 + if biography.present? + errors.add(:biography, 'is limited to 150 words.') if biography.split.length > 150 end end end diff --git a/app/models/venue.rb b/app/models/venue.rb index 302171b5..76d7de5e 100644 --- a/app/models/venue.rb +++ b/app/models/venue.rb @@ -35,7 +35,7 @@ class Venue < ActiveRecord::Base def notify_on_venue_changed? return false unless conference.try(:email_settings).try(:send_on_venue_updated) # do not notify unless the address changed - return false unless self.name_changed? || self.street_changed? || self.city_changed? || self.country_changed? + return false unless name_changed? || street_changed? || city_changed? || country_changed? # do not notify unless the mail content is set up (!conference.email_settings.venue_updated_subject.blank? && !conference.email_settings.venue_updated_body.blank?) end From 782937b1d940acd6e58405d3a68dfb2911e9e31d Mon Sep 17 00:00:00 2001 From: Chaitanya Date: Tue, 28 Mar 2017 14:42:21 +0530 Subject: [PATCH 008/185] Enable Style/ZeroLengthPredicate Rubocop cop This cop checks for numeric comparisons that can be replaced by a predicate method. It supports autocorrection, so all the offenses where automatically solved. Closes #1416 --- .rubocop.yml | 4 ++++ .rubocop_todo.yml | 5 ----- app/models/conference.rb | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index ca819d9d..bf158032 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -92,6 +92,10 @@ Style/TrailingBlankLines: Style/TrailingWhitespace: Enabled: true +#This cop checks for numeric comparisons that can be replaced by a predicate method. +Style/ZeroLengthPredicate: + Enabled: true + #################### Metrics ############################### # Avoid deep blocks nesting diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 47e50eb9..a0487443 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -680,8 +680,3 @@ Style/UnneededInterpolation: Style/WordArray: EnforcedStyle: percent MinSize: 3 - -# Offense count: 1 -Style/ZeroLengthPredicate: - Exclude: - - 'app/models/conference.rb' diff --git a/app/models/conference.rb b/app/models/conference.rb index 5b868ca9..1d549ec7 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -464,7 +464,7 @@ class Conference < ActiveRecord::Base result = Conference.where('start_date > ?', Time.now). select('id, short_title, color, start_date') - if result.length == 0 + if result.empty? result = Conference. select('id, short_title, color, start_date').limit(2). order(start_date: :desc) From e5587d42a2ab019865816395bb038147c4ca873b Mon Sep 17 00:00:00 2001 From: Emanuel Hayford Date: Tue, 28 Mar 2017 21:47:17 +0200 Subject: [PATCH 009/185] Enable Rails/Validation Rubocop cop Cop checks for the use of old-style attribute validation. Supports autocorrection which was run to fix the files concerned Closes #1414 --- .rubocop.yml | 6 +++++- .rubocop_todo.yml | 17 ----------------- app/models/comment.rb | 8 ++++---- app/models/conference.rb | 24 ++++++++++++------------ app/models/registration.rb | 4 ++-- app/models/sponsor.rb | 2 +- app/models/sponsorship_level.rb | 2 +- app/models/subscription.rb | 6 +++--- app/models/ticket.rb | 2 +- app/models/ticket_purchase.rb | 6 +++--- app/models/vposition.rb | 2 +- 11 files changed, 33 insertions(+), 46 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index bf158032..0ad83c9d 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -160,6 +160,10 @@ Lint/Void: #################### Rails ############################### -# Enforce Rails specific style +# Enforce Rails specific style Rails: Enabled: true + +# Avoid use of old-style attribute validation +Rails/Validation: + Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index a0487443..2ada8e94 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -141,23 +141,6 @@ Rails/TimeZone: - 'spec/models/campaign_spec.rb' - 'spec/models/conference_spec.rb' -# Offense count: 16 -# Configuration parameters: Include. -# Include: app/models/**/*.rb -Rails/Validation: - Exclude: - - 'app/models/call_for_paper.rb' - - 'app/models/comment.rb' - - 'app/models/conference.rb' - - 'app/models/photo.rb' - - 'app/models/registration.rb' - - 'app/models/sponsor.rb' - - 'app/models/sponsorship_level.rb' - - 'app/models/subscription.rb' - - 'app/models/ticket.rb' - - 'app/models/ticket_purchase.rb' - - 'app/models/vposition.rb' - # Offense count: 18 Style/AccessorMethodName: Exclude: diff --git a/app/models/comment.rb b/app/models/comment.rb index 00751bb8..947b2f54 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -1,7 +1,7 @@ class Comment < ActiveRecord::Base - acts_as_nested_set scope: [:commentable_id, :commentable_type] - validates_presence_of :body - validates_presence_of :user + acts_as_nested_set scope: %i(commentable_id commentable_type) + validates :body, presence: true + validates :user, presence: true after_create :send_notification # NOTE: install the acts_as_votable plugin if you @@ -13,7 +13,7 @@ class Comment < ActiveRecord::Base # NOTE: Comments belong to a user belongs_to :user - has_paper_trail on: [:create, :destroy], meta: { conference_id: :conference_id } + has_paper_trail on: %i(create destroy), meta: { conference_id: :conference_id } # Helper class method that allows you to build a comment # by passing a commentable object, a user_id, and comment text diff --git a/app/models/conference.rb b/app/models/conference.rb index 1d549ec7..e3b1d3dd 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -7,7 +7,7 @@ class Conference < ActiveRecord::Base default_scope { order('start_date DESC') } - has_paper_trail ignore: [:updated_at, :guid, :revision, :events_per_week], meta: { conference_id: :id } + has_paper_trail ignore: %i(updated_at guid revision events_per_week), meta: { conference_id: :id } has_and_belongs_to_many :questions @@ -48,15 +48,15 @@ class Conference < ActiveRecord::Base mount_uploader :picture, PictureUploader, mount_on: :logo_file_name - validates_presence_of :title, - :short_title, - :start_date, - :end_date, - :start_hour, - :end_hour + validates :title, + :short_title, + :start_date, + :end_date, + :start_hour, + :end_hour, presence: true - validates_uniqueness_of :short_title - validates_format_of :short_title, with: /\A[a-zA-Z0-9_-]*\z/ + validates :short_title, uniqueness: true + validates :short_title, format: { with: /\A[a-zA-Z0-9_-]*\z/ } validates :registration_limit, numericality: { only_integer: true, greater_than_or_equal_to: 0 } # This validation is needed since a conference with a start date greater than the end date is not possible @@ -559,7 +559,7 @@ class Conference < ActiveRecord::Base # do not notify unless one of the dates changed return false unless start_date_changed? || end_date_changed? # do not notify unless the mail content is set up - (!email_settings.conference_dates_updated_subject.blank? && !email_settings.conference_dates_updated_body.blank?) + (email_settings.conference_dates_updated_subject.present? && email_settings.conference_dates_updated_body.present?) end ## @@ -575,7 +575,7 @@ class Conference < ActiveRecord::Base # do not notify unless one of the dates changed return false unless registration_period.start_date_changed? || registration_period.end_date_changed? # do not notify unless the mail content is set up - (!email_settings.conference_registration_dates_updated_subject.blank? && !email_settings.conference_registration_dates_updated_body.blank?) + (email_settings.conference_registration_dates_updated_subject.present? && email_settings.conference_registration_dates_updated_body.present?) end def registration_limit_exceeded? @@ -699,7 +699,7 @@ class Conference < ActiveRecord::Base # Completed weeks events_per_week.each do |week, values| values.each do |state, value| - if [:confirmed, :unconfirmed].include?(state) + if %i(confirmed unconfirmed).include?(state) unless result[state.to_s.capitalize] result[state.to_s.capitalize] = {} end diff --git a/app/models/registration.rb b/app/models/registration.rb index 33507ec1..5d2555f2 100644 --- a/app/models/registration.rb +++ b/app/models/registration.rb @@ -9,7 +9,7 @@ class Registration < ActiveRecord::Base has_many :events_registrations has_many :events, through: :events_registrations, dependent: :destroy - has_paper_trail ignore: [:updated_at, :week], meta: { conference_id: :conference_id } + has_paper_trail ignore: %i(updated_at week), meta: { conference_id: :conference_id } accepts_nested_attributes_for :user accepts_nested_attributes_for :qanswers @@ -24,7 +24,7 @@ class Registration < ActiveRecord::Base validates :user, presence: true - validates_uniqueness_of :user_id, scope: :conference_id, message: 'already Registered!' + validates :user_id, uniqueness: { scope: :conference_id, message: 'already Registered!' } validate :registration_limit_not_exceed, on: :create validate :registration_to_events_only_if_present diff --git a/app/models/sponsor.rb b/app/models/sponsor.rb index 985cef44..df687f20 100644 --- a/app/models/sponsor.rb +++ b/app/models/sponsor.rb @@ -6,5 +6,5 @@ class Sponsor < ActiveRecord::Base mount_uploader :picture, PictureUploader, mount_on: :logo_file_name - validates_presence_of :name, :website_url, :sponsorship_level + validates :name, :website_url, :sponsorship_level, presence: true end diff --git a/app/models/sponsorship_level.rb b/app/models/sponsorship_level.rb index d4630971..da411859 100644 --- a/app/models/sponsorship_level.rb +++ b/app/models/sponsorship_level.rb @@ -1,5 +1,5 @@ class SponsorshipLevel < ActiveRecord::Base - validates_presence_of :title + validates :title, presence: true belongs_to :conference acts_as_list scope: :conference has_many :sponsors diff --git a/app/models/subscription.rb b/app/models/subscription.rb index 1ee97ca6..aa688ae8 100644 --- a/app/models/subscription.rb +++ b/app/models/subscription.rb @@ -1,9 +1,9 @@ class Subscription < ActiveRecord::Base - validates_uniqueness_of :user_id, scope: [:conference_id] + validates :user_id, uniqueness: { scope: [:conference_id] } belongs_to :conference belongs_to :user - has_paper_trail on: [:create, :destroy], ignore: [:updated_at], meta: { conference_id: :conference_id } + has_paper_trail on: %i(create destroy), ignore: [:updated_at], meta: { conference_id: :conference_id } - validates_uniqueness_of :user_id, scope: :conference_id, message: 'already subscribed!' + validates :user_id, uniqueness: { scope: :conference_id, message: 'already subscribed!' } end diff --git a/app/models/ticket.rb b/app/models/ticket.rb index e7af9809..7bac9462 100644 --- a/app/models/ticket.rb +++ b/app/models/ticket.rb @@ -13,7 +13,7 @@ class Ticket < ActiveRecord::Base validates :price_cents, :price_currency, :title, presence: true - validates_numericality_of :price_cents, greater_than_or_equal_to: 0 + validates :price_cents, numericality: { greater_than_or_equal_to: 0 } def bought?(user) buyers.include?(user) diff --git a/app/models/ticket_purchase.rb b/app/models/ticket_purchase.rb index 793f6926..07fb7e16 100644 --- a/app/models/ticket_purchase.rb +++ b/app/models/ticket_purchase.rb @@ -5,7 +5,7 @@ class TicketPurchase < ActiveRecord::Base validates :ticket_id, :user_id, :conference_id, :quantity, presence: true - validates_numericality_of :quantity, greater_than: 0 + validates :quantity, numericality: { greater_than: 0 } delegate :title, to: :ticket delegate :description, to: :ticket @@ -15,8 +15,8 @@ class TicketPurchase < ActiveRecord::Base scope :paid, -> { where(paid: true) } scope :unpaid, -> { where(paid: false) } - scope :by_conference, -> (conference) { where(conference_id: conference.id) } - scope :by_user, -> (user) { where(user_id: user.id) } + scope :by_conference, ->(conference) { where(conference_id: conference.id) } + scope :by_user, ->(user) { where(user_id: user.id) } def self.purchase(conference, user, purchases) errors = [] diff --git a/app/models/vposition.rb b/app/models/vposition.rb index 3220aaa7..8a7dbdf9 100644 --- a/app/models/vposition.rb +++ b/app/models/vposition.rb @@ -4,5 +4,5 @@ class Vposition < ActiveRecord::Base has_many :vchoices has_many :vdays, through: :vchoices - validates_presence_of :title, :vdays + validates :title, :vdays, presence: true end From 8a96bd137c61a7b42d0da05e4e14325669484acd Mon Sep 17 00:00:00 2001 From: Alator Date: Tue, 28 Mar 2017 17:54:27 +0300 Subject: [PATCH 010/185] Added hints for username and name in sign up form and in edit profile --- app/views/devise/registrations/new.html.haml | 4 ++-- app/views/users/edit.html.haml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml index 36eeb6e3..aa9c4db4 100644 --- a/app/views/devise/registrations/new.html.haml +++ b/app/views/devise/registrations/new.html.haml @@ -7,9 +7,9 @@ Sign Up .panel-body = semantic_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| - = f.input :username, input_html: { required: true } + = f.input :username, input_html: { required: true }, hint: 'This is how the other users see you, not your real name' = f.input :email, input_html: { required: true } - = f.input :name, input_html: { required: true } + = f.input :name, input_html: { required: true }, hint: 'This is your real name' = f.input :password, input_html: { required: true } = f.input :password_confirmation, input_html: { required: true } %p.text-right diff --git a/app/views/users/edit.html.haml b/app/views/users/edit.html.haml index f199347f..6f70b651 100644 --- a/app/views/users/edit.html.haml +++ b/app/views/users/edit.html.haml @@ -6,8 +6,8 @@ .row .col-md-12 = semantic_form_for(@user, url: user_path(@user.id)) do |f| - = f.input :name, as: :string - = f.input :nickname, as: :string + = f.input :name, as: :string, hint: 'This is your real name.' + = f.input :nickname, as: :string, hint: 'This is how the other users see you, not your real name' .control-label = "Avatar" = image_tag(@user.gravatar_url(size: '48'), title: "Yo #{@user.name}!", alt: '') From 29650beddbd9ccb1c5386466bd68a40e19c687ef Mon Sep 17 00:00:00 2001 From: Iris Sprague Date: Tue, 28 Mar 2017 22:20:27 -0400 Subject: [PATCH 011/185] enable negatedif and correct db file fix spacing --- .rubocop.yml | 12 ++++++++---- .rubocop_todo.yml | 14 -------------- ...ting_supporter_registrations_to_ticket_users.rb | 2 +- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index bf158032..e9475b21 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -63,15 +63,15 @@ Style/EmptyLiteral: Style/For: Enabled: true -# Checks that operators have space around them, except for ** which should not have surrounding space. -Style/SpaceAroundOperators: - Enabled: true - # Use the new Ruby 1.9 hash syntax Style/HashSyntax: Enabled: true EnforcedStyle: ruby19 +# Checks for uses of if with negated condition. Use unless instead +Style/NegatedIf: + Enabled: true + # Do not compare with nil. Use .nil? instead Style/NilComparison: Enabled: true @@ -80,6 +80,10 @@ Style/NilComparison: Style/RedundantSelf: Enabled: true +# Checks that operators have space around them, except for ** which should not have surrounding space. +Style/SpaceAroundOperators: + Enabled: true + # Use single quotes unless there's string interpolation Style/StringLiterals: Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index a0487443..d6a99f84 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -439,20 +439,6 @@ Style/MutableConstant: - 'app/models/event_user.rb' - 'app/models/role.rb' -# Offense count: 16 -# Cop supports --auto-correct. -Style/NegatedIf: - Exclude: - - 'app/controllers/admin/events_controller.rb' - - 'app/controllers/application_controller.rb' - - 'app/controllers/conference_registrations_controller.rb' - - 'app/controllers/proposal_controller.rb' - - 'app/models/conference.rb' - - 'app/models/datatable.rb' - - 'app/models/event.rb' - - 'app/models/venue.rb' - - 'db/migrate/20140820093735_migrating_supporter_registrations_to_ticket_users.rb' - # Offense count: 4 Style/NestedParenthesizedCalls: Exclude: diff --git a/db/migrate/20140820093735_migrating_supporter_registrations_to_ticket_users.rb b/db/migrate/20140820093735_migrating_supporter_registrations_to_ticket_users.rb index 5affe0cf..8be20de2 100644 --- a/db/migrate/20140820093735_migrating_supporter_registrations_to_ticket_users.rb +++ b/db/migrate/20140820093735_migrating_supporter_registrations_to_ticket_users.rb @@ -30,7 +30,7 @@ class MigratingSupporterRegistrationsToTicketUsers < ActiveRecord::Migration s.save end end - if !s.user_id + unless s.user_id s.user_id = deleted_user.id s.save end From 73a6e06fd3db5397a5869f8d269728063631dfae Mon Sep 17 00:00:00 2001 From: gotens1211 Date: Mon, 20 Mar 2017 19:11:03 +0530 Subject: [PATCH 012/185] Show event time in conference timezone Added an application helper method `time_with_timezone` to return time with the conference timezone which solves the issue of wrong timezone in `scheule.xml` and `admin/events#show`. Fixes #1188 --- app/helpers/application_helper.rb | 5 +++++ app/views/admin/events/_proposal.html.haml | 2 +- app/views/schedules/show.xml.haml | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 2c5e4ebe..1d91e975 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -34,6 +34,11 @@ module ApplicationHelper result end + # Returns time with conference timezone + def time_with_timezone(time) + time.strftime('%F %R') + ' ' + @conference.timezone.to_s + end + ## # Checks if the voting has already started, or if it has already ended # diff --git a/app/views/admin/events/_proposal.html.haml b/app/views/admin/events/_proposal.html.haml index 26f2f686..24f84f48 100644 --- a/app/views/admin/events/_proposal.html.haml +++ b/app/views/admin/events/_proposal.html.haml @@ -117,7 +117,7 @@ %td %b Scheduled time %td - = @event.time + = time_with_timezone(@event.time) %tr %td %b Submitter diff --git a/app/views/schedules/show.xml.haml b/app/views/schedules/show.xml.haml index 953a331f..7e5ea8e0 100644 --- a/app/views/schedules/show.xml.haml +++ b/app/views/schedules/show.xml.haml @@ -16,7 +16,7 @@ %room{ name: room.name } - events_in_rooms[room].each do |event| %event{ guid: event.guid, id: event.id } - %date= event.time.iso8601 + %date= time_with_timezone(event.time) %start= event.time.strftime('%H:%M') %duration= length_timestamp(event.event_type.length) %room= event.room.name From bd51be45e5eff0e1d6b699a6552e9c6a2c95349b Mon Sep 17 00:00:00 2001 From: gotens1211 Date: Thu, 30 Mar 2017 07:00:55 +0530 Subject: [PATCH 013/185] Added Include Venue and Lodgings to Splashpage components Fixes #1422 --- app/views/admin/splashpages/show.html.haml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/views/admin/splashpages/show.html.haml b/app/views/admin/splashpages/show.html.haml index ae340cad..542d990e 100644 --- a/app/views/admin/splashpages/show.html.haml +++ b/app/views/admin/splashpages/show.html.haml @@ -59,6 +59,20 @@ Yes - else No + %dt + Include Venue: + %dd + - if @splashpage.include_venue + Yes + - else + No + %dt + Include Lodgings: + %dd + - if @splashpage.include_lodgings + Yes + - else + No %dt Public %dd From 962bbaedb2171d5f409d75c9704cf1aff2da8e92 Mon Sep 17 00:00:00 2001 From: nasia Date: Fri, 31 Mar 2017 15:48:44 +0300 Subject: [PATCH 014/185] Fix dublicated routes --- config/routes.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/config/routes.rb b/config/routes.rb index c8c55bc4..9fa1c29a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -18,7 +18,6 @@ Osem::Application.routes.draw do resources :users, except: [:new, :index, :create, :destroy] namespace :admin do - resources :users resources :users do member do patch :toggle_confirmation From f6e74461ba9368be3a7f786ce6c26d7d0244b34a Mon Sep 17 00:00:00 2001 From: JewelSam Date: Thu, 2 Mar 2017 20:53:20 +0300 Subject: [PATCH 015/185] Add schedule interval as attribute of a program Also, the part of the schedule event is deleted and the length of the event types changes to the nearest suitable after changing the length of the interval. This closes #1220 --- INSTALL.md | 1 - app.json | 4 -- app/controllers/admin/programs_controller.rb | 8 ++-- app/controllers/schedules_controller.rb | 2 +- app/models/event_type.rb | 8 +--- app/models/program.rb | 32 +++++++++++++++ app/serializers/event_serializer.rb | 2 +- app/views/admin/event_types/_form.html.haml | 2 +- app/views/admin/programs/_form.html.haml | 1 + app/views/admin/programs/show.html.haml | 5 +++ app/views/admin/schedules/_day_tab.html.haml | 6 +-- app/views/admin/schedules/_event.html.haml | 4 +- app/views/schedules/_carousel.html.haml | 4 +- app/views/schedules/show.xml.haml | 2 +- config/initializers/schedule_parameters.rb | 6 --- ...45716_add_schedule_interval_to_programs.rb | 5 +++ db/schema.rb | 3 +- dotenv.example | 3 -- spec/models/program_spec.rb | 41 +++++++++++++++++++ 19 files changed, 104 insertions(+), 35 deletions(-) delete mode 100644 config/initializers/schedule_parameters.rb create mode 100644 db/migrate/20170302145716_add_schedule_interval_to_programs.rb diff --git a/INSTALL.md b/INSTALL.md index 33023af6..02b496eb 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -43,7 +43,6 @@ There are a couple of environment variables you can set to configure OSEM. Check | OSEM_FACEBOOK_SECRET | *string* | OMNIAUTH Developer Secret for Facebook | OSEM_GITHUB_KEY | *string* | OMNIAUTH Developer Key for GitHub | OSEM_GITHUB_SECRET | *string* | OMNIAUTH Developer Secret for GitHub -| OSEM_SCHEDULE_CELL_SIZE | *integer* | Schedule timeslot size to use (in minutes), should be greater than zero, should be divisor of 60 | OSEM_SMTP_ADDRESS | smtp.opensuse.org | The smtp server to use | OSEM_SMTP_PORT | *int* | The port on the smtp server | OSEM_SMTP_USERNAME | *string* | The user for the smtp server diff --git a/app.json b/app.json index 6b28f6b9..f77f6c9c 100644 --- a/app.json +++ b/app.json @@ -54,10 +54,6 @@ "description": "The user for the smtp server", "required": false }, - "OSEM_SCHEDULE_CELL_SIZE": { - "description": "Schedule timeslot size in minutes", - "required": false - }, "RACK_ENV": { "required": false }, diff --git a/app/controllers/admin/programs_controller.rb b/app/controllers/admin/programs_controller.rb index 77b45a57..772ae779 100644 --- a/app/controllers/admin/programs_controller.rb +++ b/app/controllers/admin/programs_controller.rb @@ -12,13 +12,15 @@ module Admin @program = @conference.program @program.assign_attributes(program_params) send_mail_on_schedule_public = @program.notify_on_schedule_public? + event_schedules_count_was = @program.event_schedules.count if @program.update_attributes(program_params) ConferenceScheduleUpdateMailJob.perform_later(@conference) if send_mail_on_schedule_public respond_to do |format| format.html do - redirect_to admin_conference_program_path(@conference.short_title), - notice: 'The program was successfully updated.' + notice = 'The program was successfully updated.' + notice += ' You changed schedule interval and some events were unscheduled.' if @program.event_schedules.count != event_schedules_count_was + redirect_to admin_conference_program_path(@conference.short_title), notice: notice end format.js { render json: {} } end @@ -36,7 +38,7 @@ module Admin private def program_params - params.require(:program).permit(:rating, :schedule_public, :schedule_fluid, :languages, :blind_voting, :voting_start_date, :voting_end_date, :selected_schedule_id) + params.require(:program).permit(:rating, :schedule_public, :schedule_interval, :schedule_fluid, :languages, :blind_voting, :voting_start_date, :voting_end_date, :selected_schedule_id) end end end diff --git a/app/controllers/schedules_controller.rb b/app/controllers/schedules_controller.rb index 0b135328..c759d337 100644 --- a/app/controllers/schedules_controller.rb +++ b/app/controllers/schedules_controller.rb @@ -13,7 +13,7 @@ class SchedulesController < ApplicationController @events_xml = schedules.map(&:event).group_by{ |event| event.time.to_date } if schedules @dates = @conference.start_date..@conference.end_date - @step_minutes = EventType::LENGTH_STEP.minutes + @step_minutes = @program.schedule_interval.minutes @conf_start = @conference.start_hour @conf_period = @conference.end_hour - @conf_start diff --git a/app/models/event_type.rb b/app/models/event_type.rb index 50d8d551..47da514f 100644 --- a/app/models/event_type.rb +++ b/app/models/event_type.rb @@ -15,17 +15,13 @@ class EventType < ActiveRecord::Base alias_attribute :name, :title - # If LENGTH_STEP must be divisor of 60, otherwise the schedule wont be displayed properly - - LENGTH_STEP = defined?(SCHEDULE_CELL_SIZE) ? SCHEDULE_CELL_SIZE : 15 - private ## - # Check if length is multiple of LENGTH_STEP. Used as validation. + # Check if length is a divisor of program schedule cell size. Used as validation. # def length_step - errors.add(:length, "must be multiple of #{LENGTH_STEP}") if length % LENGTH_STEP != 0 + errors.add(:length, "must be a divisor of #{program.schedule_interval}") if program && length % program.schedule_interval != 0 end def capitalize_color diff --git a/app/models/program.rb b/app/models/program.rb index f8b46b18..ff0ab094 100644 --- a/app/models/program.rb +++ b/app/models/program.rb @@ -38,6 +38,7 @@ class Program < ActiveRecord::Base where(state: :confirmed, is_highlight: true) end end + has_many :event_schedules, through: :events has_many :event_users, through: :events has_many :speakers, -> { distinct }, through: :event_users, source: :user do @@ -52,11 +53,15 @@ class Program < ActiveRecord::Base # validates :conference_id, presence: true, uniqueness: true validates :rating, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 10, only_integer: true } + validates :schedule_interval, numericality: { greater_than_or_equal_to: 5, less_than_or_equal_to: 60 }, presence: true + validate :schedule_interval_divisor_60 validate :voting_start_date_before_end_date validate :voting_dates_exist after_create :create_event_types after_create :create_difficulty_levels + after_save :unschedule_unfit_events, if: :schedule_interval_changed? + after_save :normalize_event_types_length, if: :schedule_interval_changed? validate :check_languages_format # Returns all event_schedules for the selected schedule ordered by start_time @@ -199,4 +204,31 @@ class Program < ActiveRecord::Base # We check if every language is a valid ISO 639-1 language errors.add(:languages, 'must be ISO 639-1 valid codes') unless languages_array.select{ |x| ISO_639.find(x).nil? }.empty? end + + ## + # Check if schedule_interval is a divisor of 60 minutes + # + def schedule_interval_divisor_60 + errors.add(:schedule_interval, 'must be a divisor of 60') if schedule_interval > 0 && 60 % schedule_interval > 0 + end + + ## + # Unschedule all the events which don't fit + # + def unschedule_unfit_events + unfit_schedules = event_schedules.select do |event_schedule| + event_schedule.start_time.min % schedule_interval > 0 + end + EventSchedule.where(id: unfit_schedules.map(&:id)).destroy_all + end + + ## + # Change event type length according schedule interval + # + def normalize_event_types_length + event_types.each do |event_type| + new_length = event_type.length > schedule_interval ? event_type.length - (event_type.length % schedule_interval) : schedule_interval + event_type.update_attributes length: new_length + end + end end diff --git a/app/serializers/event_serializer.rb b/app/serializers/event_serializer.rb index c2dffbeb..d58d23d2 100644 --- a/app/serializers/event_serializer.rb +++ b/app/serializers/event_serializer.rb @@ -26,6 +26,6 @@ class EventSerializer < ActiveModel::Serializer end def length - object.event_type.try(:length) || EventType::LENGTH_STEP + object.event_type.try(:length) || object.event_type.program.schedule_interval end end diff --git a/app/views/admin/event_types/_form.html.haml b/app/views/admin/event_types/_form.html.haml index 3f3702b4..51a0ad99 100644 --- a/app/views/admin/event_types/_form.html.haml +++ b/app/views/admin/event_types/_form.html.haml @@ -10,7 +10,7 @@ .col-md-12 = semantic_form_for(@event_type, url: (@event_type.new_record? ? admin_conference_program_event_types_path : admin_conference_program_event_type_path(@conference.short_title, @event_type))) do |f| = f.input :title - = f.input :length, input_html: {size: 3, type: 'number', step: EventType::LENGTH_STEP, min: EventType::LENGTH_STEP} + = f.input :length, input_html: {size: 3, type: 'number', step: @event_type.program.schedule_interval, min: @event_type.program.schedule_interval} = f.input :description = f.input :minimum_abstract_length, input_html: {size: 3} = f.input :maximum_abstract_length, input_html: {size: 3} diff --git a/app/views/admin/programs/_form.html.haml b/app/views/admin/programs/_form.html.haml index 8eb5ea47..035093f0 100644 --- a/app/views/admin/programs/_form.html.haml +++ b/app/views/admin/programs/_form.html.haml @@ -9,6 +9,7 @@ = f.input :schedule_fluid, label: 'Allow submitters to change their event after it is scheduled' = f.input :rating, hint: 'Enter the number of different rating levels you want to have for voting on proposals. Enter 0 if you do not want to vote on proposals.' = f.input :languages, hint: "Enter the languages allowed for events as values of #{link_to('ISO 639-1', 'http://www.loc.gov/standards/iso639-2/php/code_list.php', target: "_blank")} language codes separated with commas. The first language would be the default language. Leave it blank if you do not want to specify languages.".html_safe + = f.input :schedule_interval, hint: "It is the minimal time interval of your schedule. The value should be 5, 6, 10, 12, 15, 20, 30 or 60. Warning! Some events could be unscheduled when changing this value." = f.input :blind_voting, hint: 'Enable this feature if you do not want to show voting results and voters prior to user submitting a vote. For the feature to work you need to set the voting dates below as well' = f.input :voting_start_date, as: :string, input_html: { id: 'datetimepicker-voting_start_date', readonly: true, value: (f.object.voting_start_date.to_formatted_s(:db_without_seconds) unless f.object.voting_start_date.nil?) } = f.input :voting_end_date, as: :string, input_html: { id: 'datetimepicker-voting_start_date', readonly: true, value: (f.object.voting_end_date.to_formatted_s(:db_without_seconds) unless f.object.voting_end_date.nil?) } diff --git a/app/views/admin/programs/show.html.haml b/app/views/admin/programs/show.html.haml index 085a47c1..47e50fb6 100644 --- a/app/views/admin/programs/show.html.haml +++ b/app/views/admin/programs/show.html.haml @@ -49,6 +49,11 @@ Yes - else No + %dt + Schedule interval + %dd + = @program.schedule_interval + minutes %h3 Voting Options %hr diff --git a/app/views/admin/schedules/_day_tab.html.haml b/app/views/admin/schedules/_day_tab.html.haml index 61f6e862..7bfe3ec6 100644 --- a/app/views/admin/schedules/_day_tab.html.haml +++ b/app/views/admin/schedules/_day_tab.html.haml @@ -1,5 +1,5 @@ -- compact_grid = EventType::LENGTH_STEP < 15 -- cells_per_hour = 60 / EventType::LENGTH_STEP +- compact_grid = @program.schedule_interval < 15 +- cells_per_hour = 60 / @program.schedule_interval / use smaller cell heights for more compact grids - cell_height = compact_grid ? 32 : 58 - date_event_schedules = @event_schedules.select{ |e| e.start_time.to_date.eql? date } @@ -11,7 +11,7 @@ = room.name - (@conference.start_hour * cells_per_hour..@conference.end_hour * cells_per_hour).each do |slot| - hour = slot / cells_per_hour - - minutes = (EventType::LENGTH_STEP * (slot % cells_per_hour)).to_s.rjust(2, '0') + - minutes = (@program.schedule_interval * (slot % cells_per_hour)).to_s.rjust(2, '0') - time = "#{hour}:#{minutes}" .schedule-room-slot{ id: "schedule-room-#{room.guid}-#{hour}-#{minutes}", | room_id: room.id, | diff --git a/app/views/admin/schedules/_event.html.haml b/app/views/admin/schedules/_event.html.haml index 3c9c0c75..3a13323b 100644 --- a/app/views/admin/schedules/_event.html.haml +++ b/app/views/admin/schedules/_event.html.haml @@ -1,6 +1,6 @@ -- cells_length = event.event_type.length / EventType::LENGTH_STEP +- cells_length = event.event_type.length / @program.schedule_interval / this height fits the room cells -- compact_grid = EventType::LENGTH_STEP < 15 +- compact_grid = @program.schedule_interval < 15 - single_cell_height = compact_grid ? 32 : 58 - height = (cells_length * single_cell_height) - height -= 23 unless compact_grid diff --git a/app/views/schedules/_carousel.html.haml b/app/views/schedules/_carousel.html.haml index 5c5acc29..ce28e909 100644 --- a/app/views/schedules/_carousel.html.haml +++ b/app/views/schedules/_carousel.html.haml @@ -1,4 +1,4 @@ -- intervals = hrs_per_slide * 60 / EventType::LENGTH_STEP + 1 +- intervals = hrs_per_slide * 60 / @conference.program.schedule_interval + 1 - width = 85 / intervals - carousel_number = (@conf_period / hrs_per_slide.to_f).ceil .carousel.slide{ id: "carousel-#{ date }-#{ hrs_per_slide }", | @@ -41,7 +41,7 @@ - if event_schedule / There is an event, calculate the span and show it - - event_span = (event_schedule.end_time.to_i - start_room_time.to_i) / 60 / EventType::LENGTH_STEP + - event_span = (event_schedule.end_time.to_i - start_room_time.to_i) / 60 / @conference.program.schedule_interval - span = ((event_span + i - 1 ) > intervals ? intervals + 1 - i : event_span) = render partial: 'schedule_item', locals: {event: event_schedule.event, event_schedule: event_schedule, span: span, width: width} - else diff --git a/app/views/schedules/show.xml.haml b/app/views/schedules/show.xml.haml index 953a331f..d84e98de 100644 --- a/app/views/schedules/show.xml.haml +++ b/app/views/schedules/show.xml.haml @@ -6,7 +6,7 @@ %start= @conference.start_date %end= @conference.end_date %days= (@conference.end_date - @conference.start_date).to_i + 1 - %timeslot_duration= length_timestamp(EventType::LENGTH_STEP) + %timeslot_duration= length_timestamp(@conference.program.schedule_interval) - if @events_xml.any? - @events_xml.keys.each.with_index(1) do |day, index| diff --git a/config/initializers/schedule_parameters.rb b/config/initializers/schedule_parameters.rb deleted file mode 100644 index 7d1ca08d..00000000 --- a/config/initializers/schedule_parameters.rb +++ /dev/null @@ -1,6 +0,0 @@ -#sanitize the OSEM_SCHEUDLE_CELL_SIZE to be used for EventType::LENGTH_STEP -sched_cell_size = ENV['OSEM_SCHEDULE_CELL_SIZE'].to_i - -if (sched_cell_size > 0 and 60 % sched_cell_size == 0) - SCHEDULE_CELL_SIZE = sched_cell_size -end diff --git a/db/migrate/20170302145716_add_schedule_interval_to_programs.rb b/db/migrate/20170302145716_add_schedule_interval_to_programs.rb new file mode 100644 index 00000000..617aaf1e --- /dev/null +++ b/db/migrate/20170302145716_add_schedule_interval_to_programs.rb @@ -0,0 +1,5 @@ +class AddScheduleIntervalToPrograms < ActiveRecord::Migration + def change + add_column :programs, :schedule_interval, :integer, default: 15, null: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 34c30a04..ab95b4dc 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170213145807) do +ActiveRecord::Schema.define(version: 20170302145716) do create_table "ahoy_events", force: :cascade do |t| t.uuid "visit_id", limit: 16 @@ -289,6 +289,7 @@ ActiveRecord::Schema.define(version: 20170213145807) do t.datetime "voting_start_date" t.datetime "voting_end_date" t.integer "selected_schedule_id" + t.integer "schedule_interval", default: 15, null: false end add_index "programs", ["selected_schedule_id"], name: "index_programs_on_selected_schedule_id" diff --git a/dotenv.example b/dotenv.example index b9c2a668..ec2715ea 100644 --- a/dotenv.example +++ b/dotenv.example @@ -57,6 +57,3 @@ OSEM_SMTP_DOMAIN="" # Enable the usage of the devise ichain plugin OSEM_ICHAIN_ENABLED=false - -# Schedule grid parameters, cell size in minutes -OSEM_SCHEDULE_CELL_SIZE=15 diff --git a/spec/models/program_spec.rb b/spec/models/program_spec.rb index f491499b..ac720def 100644 --- a/spec/models/program_spec.rb +++ b/spec/models/program_spec.rb @@ -13,6 +13,7 @@ describe Program do it { is_expected.to have_many(:tracks).dependent(:destroy) } it { is_expected.to have_many(:difficulty_levels).dependent(:destroy) } it { is_expected.to have_many(:events).dependent(:destroy) } + it { is_expected.to have_many(:event_schedules).through(:events) } it { is_expected.to have_many(:event_users).through(:events) } it { is_expected.to have_many(:speakers).through(:event_users).source(:user) } @@ -32,6 +33,18 @@ describe Program do it { is_expected.to validate_numericality_of(:rating).is_greater_than_or_equal_to(0).is_less_than_or_equal_to(10).only_integer } + it { is_expected.to validate_numericality_of(:schedule_interval).is_greater_than_or_equal_to(5).is_less_than_or_equal_to(60) } + + describe 'schedule_interval_divisor_60' do + it 'is valid, when schedule_interval is divisor of 60' do + expect(build(:program, schedule_interval: 20)).to be_valid + end + + it 'is not valid, when schedule_interval is not divisor of 60' do + expect(build(:program, schedule_interval: 35)).to_not be_valid + end + end + describe 'voting_start_date_before_end_date' do it 'is valid, when voting_start_date is the same day as voting_end_date' do expect(build(:program, voting_start_date: Date.today, voting_end_date: Date.today)).to be_valid @@ -167,6 +180,34 @@ describe Program do end end + describe 'excecutes after_save functions' do + it 'and unschedule unfit events if schedule interval was changed' do + start_date = program.conference.start_date.to_datetime.change(hour: program.conference.start_hour) + create(:event_schedule, event: create(:event, program: program), start_time: start_date.change(min: program.schedule_interval)) + create(:event_schedule, event: create(:event, program: program), start_time: start_date) + expect(program.event_schedules.count).to eq 2 + + program.schedule_interval = 10 + program.save! + program.reload + expect(program.event_schedules.count).to eq 1 + expect(program.event_schedules.first.start_time).to eq start_date + end + + it 'and change event type length if schedule interval was changed' do + program.schedule_interval = 5 + program.save! + + program.event_types.first.update_attributes length: 5 + program.event_types.last.update_attributes length: 25 + create(:event_type, program: program, length: 30) + + program.schedule_interval = 10 + program.save! + expect(program.event_types.pluck(:length).sort).to eq [10, 20, 30] + end + end + describe 'languages' do it "is not valid if languages aren't two letters separated by commas" do program.languages = 'eng, De es' From b7bdb29cbeba9659da74a7037d2f0bd07b70ce73 Mon Sep 17 00:00:00 2001 From: Eugene Dubinin Date: Mon, 3 Apr 2017 18:34:37 +0300 Subject: [PATCH 016/185] use flash.now instead of flash where page is rendered in the same controller methods --- app/controllers/admin/campaigns_controller.rb | 4 ++-- app/controllers/admin/cfps_controller.rb | 4 ++-- app/controllers/admin/conferences_controller.rb | 2 +- app/controllers/admin/difficulty_levels_controller.rb | 4 ++-- app/controllers/admin/event_types_controller.rb | 4 ++-- app/controllers/admin/events_controller.rb | 2 +- app/controllers/admin/lodgings_controller.rb | 4 ++-- app/controllers/admin/programs_controller.rb | 2 +- app/controllers/admin/registration_periods_controller.rb | 4 ++-- app/controllers/admin/registrations_controller.rb | 2 +- app/controllers/admin/resources_controller.rb | 4 ++-- app/controllers/admin/roles_controller.rb | 2 +- app/controllers/admin/rooms_controller.rb | 4 ++-- app/controllers/admin/sponsors_controller.rb | 4 ++-- app/controllers/admin/sponsorship_levels_controller.rb | 4 ++-- app/controllers/admin/targets_controller.rb | 4 ++-- app/controllers/admin/tickets_controller.rb | 4 ++-- app/controllers/admin/tracks_controller.rb | 4 ++-- app/controllers/admin/venues_controller.rb | 2 +- app/controllers/conference_registrations_controller.rb | 4 ++-- app/controllers/payments_controller.rb | 2 +- app/controllers/proposals_controller.rb | 6 +++--- app/controllers/users_controller.rb | 2 +- 23 files changed, 39 insertions(+), 39 deletions(-) diff --git a/app/controllers/admin/campaigns_controller.rb b/app/controllers/admin/campaigns_controller.rb index 74d0c0ad..142e07ac 100644 --- a/app/controllers/admin/campaigns_controller.rb +++ b/app/controllers/admin/campaigns_controller.rb @@ -15,7 +15,7 @@ module Admin redirect_to admin_conference_campaigns_path(conference_id: @conference.short_title), notice: 'Campaign successfully created.' else - flash[:error] = 'Campaign creation failed. ' + @campaign.errors.full_messages.to_sentence + flash.now[:error] = 'Campaign creation failed. ' + @campaign.errors.full_messages.to_sentence render action: 'new' end end @@ -29,7 +29,7 @@ module Admin redirect_to admin_conference_campaigns_path(conference_id: @conference.short_title), notice: "Campaign '#{@campaign.name}' successfully updated." else - flash[:error] = "Campaign update failed. #{@campaign.errors.full_messages.to_sentence}" + flash.now[:error] = "Campaign update failed. #{@campaign.errors.full_messages.to_sentence}" render action: 'edit' end end diff --git a/app/controllers/admin/cfps_controller.rb b/app/controllers/admin/cfps_controller.rb index 22bc3899..42d10218 100644 --- a/app/controllers/admin/cfps_controller.rb +++ b/app/controllers/admin/cfps_controller.rb @@ -21,7 +21,7 @@ module Admin redirect_to admin_conference_program_cfp_path, notice: 'Call for papers successfully created.' else - flash[:error] = "Creating the call for papers failed. #{@cfp.errors.full_messages.join('. ')}." + flash.now[:error] = "Creating the call for papers failed. #{@cfp.errors.full_messages.join('. ')}." render :new end end @@ -37,7 +37,7 @@ module Admin redirect_to admin_conference_program_cfp_path(@conference.short_title), notice: 'Call for papers successfully updated.' else - flash[:error] = "Updating call for papers failed. #{@cfp.errors.to_a.join('. ')}." + flash.now[:error] = "Updating call for papers failed. #{@cfp.errors.to_a.join('. ')}." render :new end end diff --git a/app/controllers/admin/conferences_controller.rb b/app/controllers/admin/conferences_controller.rb index 84f92838..f5b4bf71 100644 --- a/app/controllers/admin/conferences_controller.rb +++ b/app/controllers/admin/conferences_controller.rb @@ -73,7 +73,7 @@ module Admin redirect_to admin_conference_path(id: @conference.short_title), notice: 'Conference was successfully created.' else - flash[:error] = 'Could not create conference. ' + @conference.errors.full_messages.to_sentence + flash.now[:error] = 'Could not create conference. ' + @conference.errors.full_messages.to_sentence render action: 'new' end end diff --git a/app/controllers/admin/difficulty_levels_controller.rb b/app/controllers/admin/difficulty_levels_controller.rb index 1579bf0f..7e02412c 100644 --- a/app/controllers/admin/difficulty_levels_controller.rb +++ b/app/controllers/admin/difficulty_levels_controller.rb @@ -20,7 +20,7 @@ module Admin redirect_to admin_conference_program_difficulty_levels_path(conference_id: @conference.short_title), notice: 'Difficulty level successfully created.' else - flash[:error] = "Creating difficulty level failed: #{@difficulty_level.errors.full_messages.join('. ')}." + flash.now[:error] = "Creating difficulty level failed: #{@difficulty_level.errors.full_messages.join('. ')}." render :new end end @@ -30,7 +30,7 @@ module Admin redirect_to admin_conference_program_difficulty_levels_path(conference_id: @conference.short_title), notice: 'Difficulty level successfully updated.' else - flash[:error] = "Update difficulty level failed: #{@difficulty_level.errors.full_messages.join('. ')}." + flash.now[:error] = "Update difficulty level failed: #{@difficulty_level.errors.full_messages.join('. ')}." render :edit end end diff --git a/app/controllers/admin/event_types_controller.rb b/app/controllers/admin/event_types_controller.rb index d1e4af7f..4576ad5d 100644 --- a/app/controllers/admin/event_types_controller.rb +++ b/app/controllers/admin/event_types_controller.rb @@ -18,7 +18,7 @@ module Admin redirect_to admin_conference_program_event_types_path(conference_id: @conference.short_title), notice: 'Event type successfully created.' else - flash[:error] = "Creating event type failed: #{@event_type.errors.full_messages.join('. ')}." + flash.now[:error] = "Creating event type failed: #{@event_type.errors.full_messages.join('. ')}." render :new end end @@ -28,7 +28,7 @@ module Admin redirect_to admin_conference_program_event_types_path(conference_id: @conference.short_title), notice: 'Event type successfully updated.' else - flash[:error] = "Update event type failed: #{@event_type.errors.full_messages.join('. ')}." + flash.now[:error] = "Update event type failed: #{@event_type.errors.full_messages.join('. ')}." render :edit end end diff --git a/app/controllers/admin/events_controller.rb b/app/controllers/admin/events_controller.rb index 31b07bf3..2ed1690c 100644 --- a/app/controllers/admin/events_controller.rb +++ b/app/controllers/admin/events_controller.rb @@ -89,7 +89,7 @@ module Admin end else @url = admin_conference_program_event_path(@conference.short_title, @event) - flash[:error] = 'Update not successful. ' + @event.errors.full_messages.to_sentence + flash.now[:error] = 'Update not successful. ' + @event.errors.full_messages.to_sentence render :edit end end diff --git a/app/controllers/admin/lodgings_controller.rb b/app/controllers/admin/lodgings_controller.rb index e128dcd5..85c5ff26 100644 --- a/app/controllers/admin/lodgings_controller.rb +++ b/app/controllers/admin/lodgings_controller.rb @@ -16,7 +16,7 @@ module Admin redirect_to admin_conference_lodgings_path(conference_id: @conference.short_title), notice: 'Lodging successfully created.' else - flash[:error] = "Creating Lodging failed: #{@lodging.errors.full_messages.join('. ')}." + flash.now[:error] = "Creating Lodging failed: #{@lodging.errors.full_messages.join('. ')}." render :new end end @@ -28,7 +28,7 @@ module Admin redirect_to admin_conference_lodgings_path(conference_id: @conference.short_title), notice: 'Lodging successfully updated.' else - flash[:error] = "Update Lodging failed: #{@lodging.errors.full_messages.join('. ')}." + flash.now[:error] = "Update Lodging failed: #{@lodging.errors.full_messages.join('. ')}." render :edit end end diff --git a/app/controllers/admin/programs_controller.rb b/app/controllers/admin/programs_controller.rb index 772ae779..fe401078 100644 --- a/app/controllers/admin/programs_controller.rb +++ b/app/controllers/admin/programs_controller.rb @@ -27,7 +27,7 @@ module Admin else respond_to do |format| format.html do - flash[:error] = "Updating program failed. #{@program.errors.to_a.join('. ')}." + flash.now[:error] = "Updating program failed. #{@program.errors.to_a.join('. ')}." render :new end format.js { render json: { errors: "The selected schedule couldn't been updated #{@program.errors.to_a.join('. ')}" }, status: 422 } diff --git a/app/controllers/admin/registration_periods_controller.rb b/app/controllers/admin/registration_periods_controller.rb index 07e9a735..d955ddd0 100644 --- a/app/controllers/admin/registration_periods_controller.rb +++ b/app/controllers/admin/registration_periods_controller.rb @@ -16,7 +16,7 @@ module Admin redirect_to admin_conference_registration_period_path(@conference.short_title), notice: 'Registration Period successfully updated.' else - flash[:error] = "An error prohibited the Registration Period from being saved: #{@registration_period.errors.full_messages.join('. ')}." + flash.now[:error] = "An error prohibited the Registration Period from being saved: #{@registration_period.errors.full_messages.join('. ')}." render :new end end @@ -36,7 +36,7 @@ module Admin redirect_to admin_conference_registration_period_path(@conference.short_title), notice: 'Registration Period successfully updated.' else - flash[:error] = 'An error prohibited the Registration Period from being saved: ' \ + flash.now[:error] = 'An error prohibited the Registration Period from being saved: ' \ "#{@registration_period.errors.full_messages.join('. ')}." render :edit end diff --git a/app/controllers/admin/registrations_controller.rb b/app/controllers/admin/registrations_controller.rb index 1ab957f9..2afb8f6a 100644 --- a/app/controllers/admin/registrations_controller.rb +++ b/app/controllers/admin/registrations_controller.rb @@ -24,7 +24,7 @@ module Admin redirect_to admin_conference_registrations_path(@conference.short_title), notice: "Successfully updated registration for #{@registration.user.email}!" else - flash[:error] = "An error prohibited the Registration for #{@registration.user.email}: "\ + flash.now[:error] = "An error prohibited the Registration for #{@registration.user.email}: "\ "#{@registration.errors.full_messages.join('. ')}." render :edit end diff --git a/app/controllers/admin/resources_controller.rb b/app/controllers/admin/resources_controller.rb index 7501f9ae..d5bf072b 100644 --- a/app/controllers/admin/resources_controller.rb +++ b/app/controllers/admin/resources_controller.rb @@ -17,7 +17,7 @@ module Admin redirect_to admin_conference_resources_path(conference_id: @conference.short_title), notice: 'Resource successfully created.' else - flash[:error] = "Creating resource failed: #{@resource.errors.full_messages.join('. ')}." + flash.now[:error] = "Creating resource failed: #{@resource.errors.full_messages.join('. ')}." render :new end end @@ -27,7 +27,7 @@ module Admin redirect_to admin_conference_resources_path(conference_id: @conference.short_title), notice: 'Resource successfully updated.' else - flash[:error] = "Resource update failed: #{@resource.errors.full_messages.join('. ')}." + flash.now[:error] = "Resource update failed: #{@resource.errors.full_messages.join('. ')}." render :edit end end diff --git a/app/controllers/admin/roles_controller.rb b/app/controllers/admin/roles_controller.rb index d68b0883..3bc37bc3 100644 --- a/app/controllers/admin/roles_controller.rb +++ b/app/controllers/admin/roles_controller.rb @@ -27,7 +27,7 @@ module Admin notice: 'Successfully updated role ' + @role.name else @role.name = role_name - flash[:error] = 'Could not update role! ' + @role.errors.full_messages.to_sentence + flash.now[:error] = 'Could not update role! ' + @role.errors.full_messages.to_sentence render :edit end end diff --git a/app/controllers/admin/rooms_controller.rb b/app/controllers/admin/rooms_controller.rb index 70cceaf5..da7dfc57 100644 --- a/app/controllers/admin/rooms_controller.rb +++ b/app/controllers/admin/rooms_controller.rb @@ -18,7 +18,7 @@ module Admin redirect_to admin_conference_venue_rooms_path(conference_id: @conference.short_title), notice: 'Room successfully created.' else - flash[:error] = "Creating Room failed: #{@room.errors.full_messages.join('. ')}." + flash.now[:error] = "Creating Room failed: #{@room.errors.full_messages.join('. ')}." render :new end end @@ -28,7 +28,7 @@ module Admin redirect_to admin_conference_venue_rooms_path(conference_id: @conference.short_title), notice: 'Room successfully updated.' else - flash[:error] = "Update Room failed: #{@room.errors.full_messages.join('. ')}." + flash.now[:error] = "Update Room failed: #{@room.errors.full_messages.join('. ')}." render :edit end end diff --git a/app/controllers/admin/sponsors_controller.rb b/app/controllers/admin/sponsors_controller.rb index 1c212236..909c2d7c 100644 --- a/app/controllers/admin/sponsors_controller.rb +++ b/app/controllers/admin/sponsors_controller.rb @@ -20,7 +20,7 @@ module Admin redirect_to admin_conference_sponsors_path(conference_id: @conference.short_title), notice: 'Sponsor successfully created.' else - flash[:error] = "Creating sponsor failed: #{@sponsor.errors.full_messages.join('. ')}." + flash.now[:error] = "Creating sponsor failed: #{@sponsor.errors.full_messages.join('. ')}." render :new end end @@ -31,7 +31,7 @@ module Admin conference_id: @conference.short_title), notice: 'Sponsor successfully updated.' else - flash[:error] = "Update sponsor failed: #{@sponsor.errors.full_messages.join('. ')}." + flash.now[:error] = "Update sponsor failed: #{@sponsor.errors.full_messages.join('. ')}." render :edit end end diff --git a/app/controllers/admin/sponsorship_levels_controller.rb b/app/controllers/admin/sponsorship_levels_controller.rb index e78f8746..714b1ed5 100644 --- a/app/controllers/admin/sponsorship_levels_controller.rb +++ b/app/controllers/admin/sponsorship_levels_controller.rb @@ -19,7 +19,7 @@ module Admin redirect_to admin_conference_sponsorship_levels_path(conference_id: @conference.short_title), notice: 'Sponsorship level successfully created.' else - flash[:error] = "Creating Sponsorship Level failed: #{@sponsorship_level.errors.full_messages.join('. ')}." + flash.now[:error] = "Creating Sponsorship Level failed: #{@sponsorship_level.errors.full_messages.join('. ')}." render :new end end @@ -30,7 +30,7 @@ module Admin conference_id: @conference.short_title), notice: 'Sponsorship level successfully updated.' else - flash[:error] = "Update Sponsorship level failed: #{@sponsorship_level.errors.full_messages.join('. ')}." + flash.now[:error] = "Update Sponsorship level failed: #{@sponsorship_level.errors.full_messages.join('. ')}." render :edit end end diff --git a/app/controllers/admin/targets_controller.rb b/app/controllers/admin/targets_controller.rb index f1ffcc66..a04925b7 100644 --- a/app/controllers/admin/targets_controller.rb +++ b/app/controllers/admin/targets_controller.rb @@ -15,7 +15,7 @@ module Admin redirect_to admin_conference_targets_path(conference_id: @conference.short_title), notice: 'Target successfully created.' else - flash[:error] = "Creating target failed: #{@target.errors.full_messages.join('. ')}." + flash.now[:error] = "Creating target failed: #{@target.errors.full_messages.join('. ')}." render :new end end @@ -27,7 +27,7 @@ module Admin redirect_to admin_conference_targets_path(conference_id: @conference.short_title), notice: 'Target successfully updated.' else - flash[:error] = "Target update failed: #{@target.errors.full_messages.join('. ')}." + flash.now[:error] = "Target update failed: #{@target.errors.full_messages.join('. ')}." render :edit end end diff --git a/app/controllers/admin/tickets_controller.rb b/app/controllers/admin/tickets_controller.rb index fb17fc59..9042297b 100644 --- a/app/controllers/admin/tickets_controller.rb +++ b/app/controllers/admin/tickets_controller.rb @@ -17,7 +17,7 @@ module Admin redirect_to admin_conference_tickets_path(conference_id: @conference.short_title), notice: 'Ticket successfully created.' else - flash[:error] = "Creating Ticket failed: #{@ticket.errors.full_messages.join('. ')}." + flash.now[:error] = "Creating Ticket failed: #{@ticket.errors.full_messages.join('. ')}." render :new end end @@ -29,7 +29,7 @@ module Admin redirect_to admin_conference_tickets_path(conference_id: @conference.short_title), notice: 'Ticket successfully updated.' else - flash[:error] = "Ticket update failed: #{@ticket.errors.full_messages.join('. ')}." + flash.now[:error] = "Ticket update failed: #{@ticket.errors.full_messages.join('. ')}." render :edit end end diff --git a/app/controllers/admin/tracks_controller.rb b/app/controllers/admin/tracks_controller.rb index 643350f9..2df7db67 100644 --- a/app/controllers/admin/tracks_controller.rb +++ b/app/controllers/admin/tracks_controller.rb @@ -23,7 +23,7 @@ module Admin redirect_to admin_conference_program_tracks_path(conference_id: @conference.short_title), notice: 'Track successfully created.' else - flash[:error] = "Creating Track failed: #{@track.errors.full_messages.join('. ')}." + flash.now[:error] = "Creating Track failed: #{@track.errors.full_messages.join('. ')}." render :new end end @@ -35,7 +35,7 @@ module Admin redirect_to admin_conference_program_tracks_path(conference_id: @conference.short_title), notice: 'Track successfully updated.' else - flash[:error] = "Track update failed: #{@track.errors.full_messages.join('. ')}." + flash.now[:error] = "Track update failed: #{@track.errors.full_messages.join('. ')}." render :edit end end diff --git a/app/controllers/admin/venues_controller.rb b/app/controllers/admin/venues_controller.rb index a049ea7c..ba8531ab 100644 --- a/app/controllers/admin/venues_controller.rb +++ b/app/controllers/admin/venues_controller.rb @@ -27,7 +27,7 @@ module Admin redirect_to admin_conference_venue_path(conference_id: @conference.short_title), notice: 'Venue was successfully updated.' else - flash[:error] = "Update venue failed: #{@venue.errors.full_messages.join('. ')}." + flash.now[:error] = "Update venue failed: #{@venue.errors.full_messages.join('. ')}." render :edit end end diff --git a/app/controllers/conference_registrations_controller.rb b/app/controllers/conference_registrations_controller.rb index ea02202e..8e911333 100644 --- a/app/controllers/conference_registrations_controller.rb +++ b/app/controllers/conference_registrations_controller.rb @@ -65,7 +65,7 @@ class ConferenceRegistrationsController < ApplicationController notice: 'You are now registered and will be receiving E-Mail notifications.' end else - flash[:error] = "Could not create your registration for #{@conference.title}: "\ + flash.now[:error] = "Could not create your registration for #{@conference.title}: "\ "#{@registration.errors.full_messages.join('. ')}." render :new end @@ -76,7 +76,7 @@ class ConferenceRegistrationsController < ApplicationController redirect_to conference_conference_registration_path(@conference.short_title), notice: 'Registration was successfully updated.' else - flash[:error] = "Could not update your registration for #{@conference.title}: "\ + flash.now[:error] = "Could not update your registration for #{@conference.title}: "\ "#{@registration.errors.full_messages.join('. ')}." render :edit end diff --git a/app/controllers/payments_controller.rb b/app/controllers/payments_controller.rb index db42a201..e8766548 100644 --- a/app/controllers/payments_controller.rb +++ b/app/controllers/payments_controller.rb @@ -23,7 +23,7 @@ class PaymentsController < ApplicationController else @total_amount_to_pay = Ticket.total_price(@conference, current_user, paid: false) @unpaid_ticket_purchases = current_user.ticket_purchases.unpaid.by_conference(@conference) - flash[:error] = @payment.errors.full_messages.to_sentence + ' Please try again with correct credentials.' + flash.now[:error] = @payment.errors.full_messages.to_sentence + ' Please try again with correct credentials.' render :new end end diff --git a/app/controllers/proposals_controller.rb b/app/controllers/proposals_controller.rb index 3ef8bd5f..56ea9735 100644 --- a/app/controllers/proposals_controller.rb +++ b/app/controllers/proposals_controller.rb @@ -40,7 +40,7 @@ class ProposalsController < ApplicationController if @user.save sign_in(@user) else - flash[:error] = "Could not save user: #{@user.errors.full_messages.join(', ')}" + flash.now[:error] = "Could not save user: #{@user.errors.full_messages.join(', ')}" render action: 'new' return end @@ -57,7 +57,7 @@ class ProposalsController < ApplicationController ahoy.track 'Event submission', title: 'New submission' redirect_to conference_program_proposals_path(@conference.short_title), notice: 'Proposal was successfully submitted.' else - flash[:error] = "Could not submit proposal: #{@event.errors.full_messages.join(', ')}" + flash.now[:error] = "Could not submit proposal: #{@event.errors.full_messages.join(', ')}" render action: 'new' end end @@ -69,7 +69,7 @@ class ProposalsController < ApplicationController redirect_to conference_program_proposals_path(conference_id: @conference.short_title), notice: 'Proposal was successfully updated.' else - flash[:error] = "Could not update proposal: #{@event.errors.full_messages.join(', ')}" + flash.now[:error] = "Could not update proposal: #{@event.errors.full_messages.join(', ')}" render action: 'edit' end end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index a453c83f..6c027abd 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -15,7 +15,7 @@ class UsersController < ApplicationController if @user.update(user_params) redirect_to @user, notice: 'User was successfully updated.' else - flash[:error] = "An error prohibited your Profile from being saved: #{@user.errors.full_messages.join('. ')}." + flash.now[:error] = "An error prohibited your Profile from being saved: #{@user.errors.full_messages.join('. ')}." render :edit end end From dcd57934fbb62d9d8416544b6ea8341011451600 Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Mon, 13 Mar 2017 18:16:07 +0200 Subject: [PATCH 017/185] Add OpenID test documentation * Write a paragraph that informs contributors about the openID test accounts that are available and provide instructions on how to enable them in development (#1315) in CONTRIBUTING.md * Add missing environment variable for openID logins via openSUSE (OSEM_SUSE_KEY, OSEM_SUSE_SECRET) in dotenv.example --- CONTRIBUTING.md | 12 ++++++++++++ INSTALL.md | 2 ++ dotenv.example | 4 ++++ 3 files changed, 18 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 62c0bf27..ec8376ce 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -169,6 +169,18 @@ config.ichain_force_test_username = "testuser" # set email of 'testuser' config.ichain_force_test_attributes = {:email => "testuser@example.com"} ``` + +### Using OpenID in developement +OSEM supports [OpenID](https://openid.net/) logins via [OmniAuth](https://github.com/omniauth/omniauth) and related provider specific gems. OmniAuth provides the ablity to define per-provider mock accounts for testing. The supported providers are Facebook, Google, openSUSE and GitHub. If you want to use the OSEM provided mock accounts you need to set the appropriate `OSEM_PROVIDER_KEY` and `OSEM_PROVIDER_SECRET` environment variables to a non empty string in the `.env` file. + +e.g. +``` +OSEM_GITHUB_KEY='sample' +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! diff --git a/INSTALL.md b/INSTALL.md index 02b496eb..5629272d 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -43,6 +43,8 @@ There are a couple of environment variables you can set to configure OSEM. Check | OSEM_FACEBOOK_SECRET | *string* | OMNIAUTH Developer Secret for Facebook | OSEM_GITHUB_KEY | *string* | OMNIAUTH Developer Key for GitHub | OSEM_GITHUB_SECRET | *string* | OMNIAUTH Developer Secret for GitHub +| OSEM_SUSE_KEY | *string* | OMNIAUTH Developer Key for openSUSE +| OSEM_SUSE_SECRET | *string* | OMNIAUTH Developer Secret for openSUSE | OSEM_SMTP_ADDRESS | smtp.opensuse.org | The smtp server to use | OSEM_SMTP_PORT | *int* | The port on the smtp server | OSEM_SMTP_USERNAME | *string* | The user for the smtp server diff --git a/dotenv.example b/dotenv.example index ec2715ea..0c852658 100644 --- a/dotenv.example +++ b/dotenv.example @@ -37,6 +37,10 @@ OSEM_FACEBOOK_SECRET='' OSEM_GITHUB_KEY='' OSEM_GITHUB_SECRET='' +# OMNIAUTH Developer KEY/Secret for SUSE/openSUSE +OSEM_SUSE_KEY='' +OSEM_SUSE_SECRET='' + # STRIPE Publishable/Secret keys # test keys for development mode, live for production mode STRIPE_PUBLISHABLE_KEY='' From 3f46fed0b209b637072b57e63965b8418240bf04 Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Sat, 25 Mar 2017 23:19:59 +0200 Subject: [PATCH 018/185] Remove reference to secrets.yml in INSTALL.md INSTALL.md references two methods for enabling openID 1) adding the provider's API keys in config/secrets.yml and 2) adding the provider's API keys as environment variable in the relevant .env files The first method is not acceptable anymore, so it is no longer mentioned --- INSTALL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/INSTALL.md b/INSTALL.md index 5629272d..9cbfafcc 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -71,7 +71,7 @@ $ bundle exec rake logo:reprocess ``` ### openID -In order to use [openID](http://openid.net/) logins for your OSEM installation you need to register your application with the providers ([Google](https://code.google.com/apis/console#:access), [GitHub](https://github.com/settings/applications/new) or [Facebook](https://developers.facebook.com/)) and enter their API keys, changing the existing sample values, in `config/secrets.yml` file, or in your environment variables found in *.env.production* file. +In order to use [openID](http://openid.net/) logins for your OSEM installation you need to register your application with the providers ([Google](https://code.google.com/apis/console#:access), [GitHub](https://github.com/settings/applications/new) or [Facebook](https://developers.facebook.com/)) and enter their API keys in the environment variables found in your *.env* file(s). ## Recurring Jobs Open a separate terminal and go into the directory where the rails app is present, and type the following to start the delayed_jobs worker for sending email notifications. From 6414631a327a5d32154abe8e6b0cefa4b04aa3cf Mon Sep 17 00:00:00 2001 From: nasia Date: Tue, 4 Apr 2017 21:30:16 +0300 Subject: [PATCH 019/185] Fix admin/resources inherit --- app/controllers/admin/resources_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/resources_controller.rb b/app/controllers/admin/resources_controller.rb index 7501f9ae..8684d73e 100644 --- a/app/controllers/admin/resources_controller.rb +++ b/app/controllers/admin/resources_controller.rb @@ -1,5 +1,5 @@ module Admin - class ResourcesController < ApplicationController + class ResourcesController < Admin::BaseController load_and_authorize_resource :conference, find_by: :short_title load_and_authorize_resource :resource, only: [:show, :edit, :update, :destroy] From eb1e8ed23827689000f41d2fcde85decd93e44bf Mon Sep 17 00:00:00 2001 From: gotens1211 Date: Wed, 8 Mar 2017 15:27:38 +0530 Subject: [PATCH 020/185] Changed the default state of components in splashpage to selected Mark the splashpage components to checked for the new action, also modified the display changes in splashpages test Fixes #1340 --- app/views/admin/splashpages/_form.html.haml | 18 +++++++++--------- spec/features/versions_spec.rb | 14 ++++++++++---- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/app/views/admin/splashpages/_form.html.haml b/app/views/admin/splashpages/_form.html.haml index 38335b31..f945b2c9 100644 --- a/app/views/admin/splashpages/_form.html.haml +++ b/app/views/admin/splashpages/_form.html.haml @@ -6,15 +6,15 @@ .col-md-8 = semantic_form_for(@splashpage, url: admin_conference_splashpage_path(@conference.short_title)) do |f| = f.inputs name: 'Components' do - = f.input :include_tracks, label: 'Display tracks on the splashpage?' - = f.input :include_program, label: 'Display program on the splashpage?' - = f.input :include_cfp, label: 'Display call for papers information on splashpage, while cfp is open?' - = f.input :include_venue, label: 'Display venue on the splashpage?' - = f.input :include_registrations, label: 'Display the registration period on the splashpage?' - = f.input :include_tickets, label: 'Display tickets on the splashpage?' - = f.input :include_lodgings, label: 'Display the lodgings on the splashpage?' - = f.input :include_sponsors, label: 'Display sponsors on the splashpage?' - = f.input :include_social_media, label: 'Display social media on the splashpage?' + = f.input :include_tracks, label: 'Display tracks', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_tracks) } + = f.input :include_program, label: 'Display program', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_program) } + = f.input :include_cfp, label: 'Display call for papers information on splashpage, while cfp is open', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_cfp) } + = f.input :include_venue, label: 'Display venue', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_venue) } + = f.input :include_registrations, label: 'Display the registration period', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_registrations) } + = f.input :include_tickets, label: 'Display tickets', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_tickets) } + = f.input :include_lodgings, label: 'Display the lodgings', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_lodgings) } + = f.input :include_sponsors, label: 'Display sponsors', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_sponsors) } + = f.input :include_social_media, label: 'Display social media', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_social_media) } = f.inputs name: 'Access' do = f.input :public, label: 'Make splash page public?' %p.text-right diff --git a/spec/features/versions_spec.rb b/spec/features/versions_spec.rb index 1d800572..ba43bc27 100644 --- a/spec/features/versions_spec.rb +++ b/spec/features/versions_spec.rb @@ -221,15 +221,21 @@ feature 'Version' do click_button 'Save Splashpage' click_link 'Edit' - check('Make splash page public') - check('Display tracks on the splashpage?') - check('Display the registration period on the splashpage?') + uncheck('Display program') + uncheck('Display call for papers information on splashpage, while cfp is open') + uncheck('Display venue') + uncheck('Display tickets') + uncheck('Display the lodgings') + uncheck('Display sponsors') + uncheck('Display social media') + check('Make splash page public?') click_button 'Save Splashpage' click_link 'Delete' visit admin_revision_history_path expect(page).to have_text("#{organizer.name} created new splashpage in conference #{conference.short_title}") - expect(page).to have_text("#{organizer.name} updated public, include tracks and include registrations of splashpage in conference #{conference.short_title}") + expect(page).to have_text("#{organizer.name} updated public, include program, include cfp, include venue, include tickets, include lodgings, + include sponsors and include social media of splashpage in conference #{conference.short_title}") expect(page).to have_text("#{organizer.name} deleted splashpage in conference #{conference.short_title}") end From 7497d0394e7116b080f85223e7e152626a13dc11 Mon Sep 17 00:00:00 2001 From: nasia Date: Wed, 5 Apr 2017 19:18:17 +0300 Subject: [PATCH 021/185] Fix Splashpages#show so it matches splashpages#edit --- app/views/admin/splashpages/show.html.haml | 70 +++++++++++----------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/app/views/admin/splashpages/show.html.haml b/app/views/admin/splashpages/show.html.haml index 542d990e..0c6be8a8 100644 --- a/app/views/admin/splashpages/show.html.haml +++ b/app/views/admin/splashpages/show.html.haml @@ -10,27 +10,6 @@ .row .col-md-8 %dl.dl-horizontal - %dt - Include Tickets: - %dd - - if @splashpage.include_tickets - Yes - - else - No - %dt - Include Sponsors: - %dd - - if @splashpage.include_sponsors - Yes - - else - No - %dt - Include Registrations: - %dd - - if @splashpage.include_registrations - Yes - - else - No %dt Include Tracks: %dd @@ -52,6 +31,41 @@ Yes - else No + %dt + Include Venue: + %dd + -if @splashpage.include_venue + Yes + -else + No + %dt + Include Registrations: + %dd + - if @splashpage.include_registrations + Yes + - else + No + %dt + Include Tickets: + %dd + - if @splashpage.include_tickets + Yes + - else + No + %dt + Include Lodgins + %dd + -if @splashpage.include_lodgings + Yes + -else + No + %dt + Include Sponsors: + %dd + - if @splashpage.include_sponsors + Yes + - else + No %dt Include Social Media: %dd @@ -59,20 +73,6 @@ Yes - else No - %dt - Include Venue: - %dd - - if @splashpage.include_venue - Yes - - else - No - %dt - Include Lodgings: - %dd - - if @splashpage.include_lodgings - Yes - - else - No %dt Public %dd From c74e91468395140c600424a50c347aea40ae0e7d Mon Sep 17 00:00:00 2001 From: Neil Halligan Date: Wed, 5 Apr 2017 17:33:14 +0100 Subject: [PATCH 022/185] Add Lint/DuplicatedKey to rubocop Fixes openSUSE/osem#1437 --- .rubocop.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index 0ad83c9d..da914bc3 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -158,6 +158,10 @@ Lint/UselessAssignment: Lint/Void: Enabled: true +# Do not use duplicated keys in hash literals. +Lint/DuplicatedKey: + Enabled: true + #################### Rails ############################### # Enforce Rails specific style From 535b3f86d6e88ca363e79ced231c4000be42f525 Mon Sep 17 00:00:00 2001 From: Cody Borders Date: Tue, 4 Apr 2017 11:48:52 -0600 Subject: [PATCH 023/185] Fixes Style/Tab cops Removes exclusions for Style/Tab cops in rubocop_todo Places Style/Tab cop in appropriate alphabetical order All cops now fixed. --- .rubocop.yml | 4 ++++ .rubocop_todo.yml | 11 ----------- ...545_add_require_handicapped_access_to_questions.rb | 10 +++++----- ...1225606_add_attending_with_partner_to_questions.rb | 10 +++++----- ...620_add_staying_at_suggested_hotel_to_questions.rb | 10 +++++----- ...225635_add_attending_social_events_to_questions.rb | 10 +++++----- ...162030_change_lodging_association_to_conference.rb | 2 +- spec/features/event_types_spec.rb | 2 +- 8 files changed, 26 insertions(+), 33 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index c6b31025..4fc99f50 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -88,6 +88,10 @@ Style/SpaceAroundOperators: Style/StringLiterals: Enabled: true +# This cop checks for tabs where spaces should be used. +Style/Tab: + Enabled: true + # Avoid trailing blank lines Style/TrailingBlankLines: Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index efef81bc..e0b537fb 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -609,17 +609,6 @@ Style/SymbolProc: - 'spec/controllers/admin/conferences_controller_spec.rb' - 'spec/support/flash.rb' -# Offense count: 23 -# Cop supports --auto-correct. -Style/Tab: - Exclude: - - 'db/migrate/20141031225545_add_require_handicapped_access_to_questions.rb' - - 'db/migrate/20141031225606_add_attending_with_partner_to_questions.rb' - - 'db/migrate/20141031225620_add_staying_at_suggested_hotel_to_questions.rb' - - 'db/migrate/20141031225635_add_attending_social_events_to_questions.rb' - - 'db/migrate/20141118162030_change_lodging_association_to_conference.rb' - - 'spec/features/campaign_spec.rb' - - 'spec/features/event_types_spec.rb' # Offense count: 26 # Cop supports --auto-correct. diff --git a/db/migrate/20141031225545_add_require_handicapped_access_to_questions.rb b/db/migrate/20141031225545_add_require_handicapped_access_to_questions.rb index ed0d1f99..ad2328c9 100644 --- a/db/migrate/20141031225545_add_require_handicapped_access_to_questions.rb +++ b/db/migrate/20141031225545_add_require_handicapped_access_to_questions.rb @@ -75,11 +75,11 @@ class AddRequireHandicappedAccessToQuestions < ActiveRecord::Migration TempConferencesQuestions.find_or_create_by!(conference_id: c.id, question_id: q.id) TempRegistration.where(conference_id: c.id).each do |r| - if r.handicapped_access_required - TempQanswerRegistration.find_or_create_by!(registration_id: r.id, qanswer_id: qa_yes.id) - else - TempQanswerRegistration.find_or_create_by!(registration_id: r.id, qanswer_id: qa_no.id) - end + if r.handicapped_access_required + TempQanswerRegistration.find_or_create_by!(registration_id: r.id, qanswer_id: qa_yes.id) + else + TempQanswerRegistration.find_or_create_by!(registration_id: r.id, qanswer_id: qa_no.id) + end end end remove_column :registrations, :handicapped_access_required, :boolean diff --git a/db/migrate/20141031225606_add_attending_with_partner_to_questions.rb b/db/migrate/20141031225606_add_attending_with_partner_to_questions.rb index a7014539..0a63a380 100644 --- a/db/migrate/20141031225606_add_attending_with_partner_to_questions.rb +++ b/db/migrate/20141031225606_add_attending_with_partner_to_questions.rb @@ -75,11 +75,11 @@ class AddAttendingWithPartnerToQuestions < ActiveRecord::Migration TempConferencesQuestions.find_or_create_by!(conference_id: c.id, question_id: q.id) TempRegistration.where(conference_id: c.id).each do |r| - if r.attending_with_partner - TempQanswerRegistration.find_or_create_by!(registration_id: r.id, qanswer_id: qa_yes.id) - else - TempQanswerRegistration.find_or_create_by!(registration_id: r.id, qanswer_id: qa_no.id) - end + if r.attending_with_partner + TempQanswerRegistration.find_or_create_by!(registration_id: r.id, qanswer_id: qa_yes.id) + else + TempQanswerRegistration.find_or_create_by!(registration_id: r.id, qanswer_id: qa_no.id) + end end end remove_column :registrations, :attending_with_partner, :boolean diff --git a/db/migrate/20141031225620_add_staying_at_suggested_hotel_to_questions.rb b/db/migrate/20141031225620_add_staying_at_suggested_hotel_to_questions.rb index 71897787..fb0d8781 100644 --- a/db/migrate/20141031225620_add_staying_at_suggested_hotel_to_questions.rb +++ b/db/migrate/20141031225620_add_staying_at_suggested_hotel_to_questions.rb @@ -75,11 +75,11 @@ class AddStayingAtSuggestedHotelToQuestions < ActiveRecord::Migration TempConferencesQuestions.find_or_create_by!(conference_id: c.id, question_id: q.id) TempRegistration.where(conference_id: c.id).each do |r| - if r.using_affiliated_lodging - TempQanswerRegistration.find_or_create_by!(registration_id: r.id, qanswer_id: qa_yes.id) - else - TempQanswerRegistration.find_or_create_by!(registration_id: r.id, qanswer_id: qa_no.id) - end + if r.using_affiliated_lodging + TempQanswerRegistration.find_or_create_by!(registration_id: r.id, qanswer_id: qa_yes.id) + else + TempQanswerRegistration.find_or_create_by!(registration_id: r.id, qanswer_id: qa_no.id) + end end end remove_column :registrations, :using_affiliated_lodging, :boolean diff --git a/db/migrate/20141031225635_add_attending_social_events_to_questions.rb b/db/migrate/20141031225635_add_attending_social_events_to_questions.rb index ba950b10..54e3bb33 100644 --- a/db/migrate/20141031225635_add_attending_social_events_to_questions.rb +++ b/db/migrate/20141031225635_add_attending_social_events_to_questions.rb @@ -75,11 +75,11 @@ class AddAttendingSocialEventsToQuestions < ActiveRecord::Migration TempConferencesQuestions.find_or_create_by!(conference_id: c.id, question_id: q.id) TempRegistration.where(conference_id: c.id).each do |r| - if r.attending_social_events - TempQanswerRegistration.find_or_create_by!(registration_id: r.id, qanswer_id: qa_yes.id) - else - TempQanswerRegistration.find_or_create_by!(registration_id: r.id, qanswer_id: qa_no.id) - end + if r.attending_social_events + TempQanswerRegistration.find_or_create_by!(registration_id: r.id, qanswer_id: qa_yes.id) + else + TempQanswerRegistration.find_or_create_by!(registration_id: r.id, qanswer_id: qa_no.id) + end end end remove_column :registrations, :attending_social_events, :boolean diff --git a/db/migrate/20141118162030_change_lodging_association_to_conference.rb b/db/migrate/20141118162030_change_lodging_association_to_conference.rb index e8699a07..352075ec 100644 --- a/db/migrate/20141118162030_change_lodging_association_to_conference.rb +++ b/db/migrate/20141118162030_change_lodging_association_to_conference.rb @@ -21,7 +21,7 @@ class ChangeLodgingAssociationToConference < ActiveRecord::Migration venue = TempVenue.find_by(conference_id: conference.id) lodgings = TempLodging.where(venue_id: venue.id) lodgings.each do |lodging| - lodging.update_attributes(conference_id: conference.id) + lodging.update_attributes(conference_id: conference.id) end end end diff --git a/spec/features/event_types_spec.rb b/spec/features/event_types_spec.rb index ea0fa735..6b3c9f0c 100644 --- a/spec/features/event_types_spec.rb +++ b/spec/features/event_types_spec.rb @@ -38,7 +38,7 @@ feature EventType do # Remove event type within('tr', text: 'Party') do - click_link 'Delete' + click_link 'Delete' end expect(flash).to eq('Event type successfully deleted.') From 03fa299058b9c292308c0356badf06f14a813909 Mon Sep 17 00:00:00 2001 From: Sunny Date: Thu, 6 Apr 2017 23:19:58 -0400 Subject: [PATCH 024/185] enable style/dotposition rubocop cop --- .rubocop.yml | 4 ++ .rubocop_todo.yml | 7 --- .../admin/conferences_controller.rb | 12 ++-- app/controllers/admin/reports_controller.rb | 8 +-- .../conference_registrations_controller.rb | 4 +- app/controllers/registrations_controller.rb | 8 +-- app/helpers/application_helper.rb | 8 +-- app/models/cfp.rb | 16 +++-- app/models/conference.rb | 20 +++---- app/models/event.rb | 4 +- app/models/registration_period.rb | 12 ++-- .../admin/conferences_controller_spec.rb | 8 +-- .../admin/users_controller_spec.rb | 4 +- spec/features/cfp_spec.rb | 16 ++--- spec/features/conference_spec.rb | 28 ++++----- spec/features/contact_spec.rb | 4 +- spec/features/email_spec.rb | 60 +++++++++---------- spec/features/program_spec.rb | 4 +- spec/features/proposals_spec.rb | 4 +- spec/features/registration_periods_spec.rb | 12 ++-- spec/features/venues_spec.rb | 12 ++-- spec/features/volunteers_spec.rb | 12 ++-- spec/helpers/application_helper_spec.rb | 10 ++-- spec/models/conference_spec.rb | 4 +- spec/support/external_request.rb | 4 +- 25 files changed, 143 insertions(+), 142 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index e9475b21..f86cca4c 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -39,6 +39,10 @@ Style/CaseEquality: Style/ClassAndModuleChildren: Enabled: true +# Checks the . position in multi-line method calls. +Style/DotPosition: + Enabled: true + # Checks for uses of double negation (!!) to convert something to a boolean value. Style/DoubleNegation: Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index d6a99f84..022f6c1b 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -239,13 +239,6 @@ Style/ConditionalAssignment: Style/Documentation: Enabled: false -# Offense count: 74 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: leading, trailing -Style/DotPosition: - Enabled: false - # Offense count: 1 # Cop supports --auto-correct. Style/ElseAlignment: diff --git a/app/controllers/admin/conferences_controller.rb b/app/controllers/admin/conferences_controller.rb index 84f92838..66709617 100644 --- a/app/controllers/admin/conferences_controller.rb +++ b/app/controllers/admin/conferences_controller.rb @@ -21,8 +21,8 @@ module Admin @new_submissions = Event.where('created_at > ?', current_user.last_sign_in_at).count @active_conferences = Conference.get_active_conferences_for_dashboard # pending or the last two - @deactive_conferences = Conference. - get_conferences_without_active_for_dashboard(@active_conferences) # conferences without active + @deactive_conferences = Conference + .get_conferences_without_active_for_dashboard(@active_conferences) # conferences without active @conferences = @active_conferences + @deactive_conferences @recent_users = User.limit(5).order(created_at: :desc) @@ -106,8 +106,8 @@ module Admin @new_reg = @conference.registrations.where('created_at > ?', current_user.last_sign_in_at).count @total_submissions = @program.events.count - @new_submissions = @program.events. - where('created_at > ?', current_user.last_sign_in_at).count + @new_submissions = @program.events + .where('created_at > ?', current_user.last_sign_in_at).count @program_length = @conference.current_program_hours @new_program_length = @conference.new_program_hours(current_user.last_sign_in_at) @@ -139,8 +139,8 @@ module Admin @event_type_distribution_confirmed = @conference.event_type_distribution(:confirmed) @difficulty_levels_distribution = @conference.difficulty_levels_distribution - @difficulty_levels_distribution_confirmed = @conference. - difficulty_levels_distribution(:confirmed) + @difficulty_levels_distribution_confirmed = @conference + .difficulty_levels_distribution(:confirmed) @tracks_distribution = @conference.tracks_distribution @tracks_distribution_confirmed = @conference.tracks_distribution(:confirmed) diff --git a/app/controllers/admin/reports_controller.rb b/app/controllers/admin/reports_controller.rb index 2075243e..c6d4003c 100644 --- a/app/controllers/admin/reports_controller.rb +++ b/app/controllers/admin/reports_controller.rb @@ -10,10 +10,10 @@ module Admin @events_with_requirements = @events.where.not(description: ['', nil]) attended_registrants_ids = @conference.registrations.where(attended: true).pluck(:user_id) - @missing_event_speakers = EventUser.joins(:event). - where('event_role = ? and program_id = ?', 'submitter', @program.id). - where.not(user_id: attended_registrants_ids). - includes(:user, :event) + @missing_event_speakers = EventUser.joins(:event) + .where('event_role = ? and program_id = ?', 'submitter', @program.id) + .where.not(user_id: attended_registrants_ids) + .includes(:user, :event) end end end diff --git a/app/controllers/conference_registrations_controller.rb b/app/controllers/conference_registrations_controller.rb index ea02202e..c6073b32 100644 --- a/app/controllers/conference_registrations_controller.rb +++ b/app/controllers/conference_registrations_controller.rb @@ -108,8 +108,8 @@ class ConferenceRegistrationsController < ApplicationController end def registration_params - params.require(:registration). - permit( + params.require(:registration) + .permit( :conference_id, :arrival, :departure, :volunteer, vchoice_ids: [], qanswer_ids: [], diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 7bc3fca3..e141084c 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -23,12 +23,12 @@ class RegistrationsController < Devise::RegistrationsController def configure_permitted_parameters devise_parameter_sanitizer.permit(:account_update) do |u| - u. - permit(:email, :password, :password_confirmation, :current_password, :username, :email_public) + u + .permit(:email, :password, :password_confirmation, :current_password, :username, :email_public) end devise_parameter_sanitizer.permit(:sign_up) do |u| - u. - permit(:email, :password, :password_confirmation, :name, :username) + u + .permit(:email, :password, :password_confirmation, :name, :username) end end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 2c5e4ebe..d6025dd4 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -412,10 +412,10 @@ module ApplicationHelper # Eg: If version.changeset = '{"title"=>[nil, "Premium"], "description"=>[nil, "Premium = Super cool"], "conference_id"=>[nil, 3]}' # Output will be 'title, description and conference' def updated_attributes(version) - version.changeset. - reject{ |_, values| values[0].blank? && values[1].blank? }. - keys.map{ |key| key.gsub('_id', '').tr('_', ' ')}.join(', '). - reverse.sub(',', ' dna ').reverse + version.changeset + .reject{ |_, values| values[0].blank? && values[1].blank? } + .keys.map{ |key| key.gsub('_id', '').tr('_', ' ')}.join(', ') + .reverse.sub(',', ' dna ').reverse end def link_to_user(user_id) diff --git a/app/models/cfp.rb b/app/models/cfp.rb index 827d0f1c..affcc408 100644 --- a/app/models/cfp.rb +++ b/app/models/cfp.rb @@ -58,16 +58,20 @@ class Cfp < ActiveRecord::Base private def before_end_of_conference - errors. - add(:end_date, "can't be after the conference end date (#{program.conference.end_date})") if program.conference && program.conference.end_date && end_date && (end_date > program.conference.end_date) + if program.conference && program.conference.end_date && end_date && (end_date > program.conference.end_date) + errors + .add(:end_date, "can't be after the conference end date (#{program.conference.end_date})") + end - errors. - add(:start_date, "can't be after the conference end date (#{program.conference.end_date})") if program.conference && program.conference.end_date && start_date && (start_date > program.conference.end_date) + if program.conference && program.conference.end_date && start_date && (start_date > program.conference.end_date) + errors + .add(:start_date, "can't be after the conference end date (#{program.conference.end_date})") + end end def start_after_end_date - errors. - add(:start_date, "can't be after the end date") if start_date && end_date && start_date > end_date + errors + .add(:start_date, "can't be after the end date") if start_date && end_date && start_date > end_date end def conference_id diff --git a/app/models/conference.rb b/app/models/conference.rb index 1d549ec7..0786b9ae 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -180,8 +180,8 @@ class Conference < ActiveRecord::Base if registration_period && registration_period.start_date && registration_period.end_date - weeks = Date.new(registration_period.start_date.year, 12, 31). - strftime('%W').to_i + weeks = Date.new(registration_period.start_date.year, 12, 31) + .strftime('%W').to_i result = get_registration_end_week - get_registration_start_week + 1 end @@ -277,9 +277,9 @@ class Conference < ActiveRecord::Base # ====Returns # * +hash+ -> user: submissions def get_top_submitter(limit = 5) - submitter = EventUser.joins(:event). - where('event_role = ? and program_id = ?', 'submitter', Conference.find(id).program.id). - limit(limit).group(:user_id) + submitter = EventUser.joins(:event) + .where('event_role = ? and program_id = ?', 'submitter', Conference.find(id).program.id) + .limit(limit).group(:user_id) counter = submitter.order('count_all desc').count Conference.calculate_user_submission_hash(submitter, counter) end @@ -461,13 +461,13 @@ class Conference < ActiveRecord::Base # ====Returns # * +ActiveRecord+ def self.get_active_conferences_for_dashboard - result = Conference.where('start_date > ?', Time.now). - select('id, short_title, color, start_date') + result = Conference.where('start_date > ?', Time.now) + .select('id, short_title, color, start_date') if result.empty? - result = Conference. - select('id, short_title, color, start_date').limit(2). - order(start_date: :desc) + result = Conference + .select('id, short_title, color, start_date').limit(2) + .order(start_date: :desc) end result end diff --git a/app/models/event.rb b/app/models/event.rb index e138d9d9..27fc1ad9 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -286,8 +286,8 @@ class Event < ActiveRecord::Base end def before_end_of_conference - errors. - add(:created_at, "can't be after the conference end date!") if program.conference && program.conference.end_date && + errors + .add(:created_at, "can't be after the conference end date!") if program.conference && program.conference.end_date && (Date.today > program.conference.end_date) end diff --git a/app/models/registration_period.rb b/app/models/registration_period.rb index a7c251ac..fb9e6225 100644 --- a/app/models/registration_period.rb +++ b/app/models/registration_period.rb @@ -10,15 +10,15 @@ class RegistrationPeriod < ActiveRecord::Base private def before_end_of_conference - errors. - add(:start_date, "can't be after the conference end date (#{conference.end_date})") if conference && conference.end_date && start_date && (start_date > conference.end_date) + errors + .add(:start_date, "can't be after the conference end date (#{conference.end_date})") if conference && conference.end_date && start_date && (start_date > conference.end_date) - errors. - add(:end_date, "can't be after the conference end date (#{conference.end_date})") if conference && conference.end_date && end_date && (end_date > conference.end_date) + errors + .add(:end_date, "can't be after the conference end date (#{conference.end_date})") if conference && conference.end_date && end_date && (end_date > conference.end_date) end def start_date_before_end_date - errors. - add(:start_date, "can't be after the end date") if start_date && end_date && start_date > end_date + errors + .add(:start_date, "can't be after the end date") if start_date && end_date && start_date > end_date end end diff --git a/spec/controllers/admin/conferences_controller_spec.rb b/spec/controllers/admin/conferences_controller_spec.rb index eac4c68c..3964996f 100644 --- a/spec/controllers/admin/conferences_controller_spec.rb +++ b/spec/controllers/admin/conferences_controller_spec.rb @@ -56,8 +56,8 @@ describe Admin::ConferencesController do short_title: nil) conference.reload - expect(flash[:error]). - to eq("Updating conference failed. Short title can't be blank.") + expect(flash[:error]) + .to eq("Updating conference failed. Short title can't be blank.") expect(conference.title).to eq("#{conference.title}") expect(conference.short_title).to eq("#{conference.short_title}") end @@ -67,8 +67,8 @@ describe Admin::ConferencesController do attributes_for(:conference, title: 'Example Con', short_title: nil) - expect(flash[:error]). - to eq("Updating conference failed. Short title can't be blank.") + expect(flash[:error]) + .to eq("Updating conference failed. Short title can't be blank.") expect(response).to redirect_to edit_admin_conference_path( conference.short_title) end diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb index be9e4cef..6114f6ed 100644 --- a/spec/controllers/admin/users_controller_spec.rb +++ b/spec/controllers/admin/users_controller_spec.rb @@ -42,8 +42,8 @@ describe Admin::UsersController do end it 'changes @users attributes' do expect(build( - :user, email: 'email_new@osem.io', id: user.id).email). - to eq('email_new@osem.io') + :user, email: 'email_new@osem.io', id: user.id).email) + .to eq('email_new@osem.io') end it 'redirects to the updated user' do expect(response).to redirect_to admin_users_path diff --git a/spec/features/cfp_spec.rb b/spec/features/cfp_spec.rb index b7ee2a01..8869de1f 100644 --- a/spec/features/cfp_spec.rb +++ b/spec/features/cfp_spec.rb @@ -16,8 +16,8 @@ feature Conference do click_button 'Create Cfp' - expect(flash). - to eq('Creating the call for papers failed. ' + + expect(flash) + .to eq('Creating the call for papers failed. ' + "Start date can't be blank. End date can't be blank.") today = Date.today - 1 @@ -29,8 +29,8 @@ feature Conference do click_button 'Create Cfp' # Validations - expect(flash). - to eq('Call for papers successfully created.') + expect(flash) + .to eq('Call for papers successfully created.') expect(find('#start_date').text).to eq(today.strftime('%A, %B %-d. %Y')) expect(find('#end_date').text).to eq((today + 6).strftime('%A, %B %-d. %Y')) @@ -49,8 +49,8 @@ feature Conference do page.execute_script( "$('#registration-period-start-datepicker').val('')") click_button 'Update Cfp' - expect(flash). - to eq('Updating call for papers failed. ' + + expect(flash) + .to eq('Updating call for papers failed. ' + "Start date can't be blank.") # Fill in date @@ -63,8 +63,8 @@ feature Conference do click_button 'Update Cfp' # Validations - expect(flash). - to eq('Call for papers successfully updated.') + expect(flash) + .to eq('Call for papers successfully updated.') expect(find('#start_date').text).to eq(today.strftime('%A, %B %-d. %Y')) expect(find('#end_date').text).to eq((today + 14).strftime('%A, %B %-d. %Y')) expect(Cfp.count).to eq(expected_count) diff --git a/spec/features/conference_spec.rb b/spec/features/conference_spec.rb index f6ced652..d17ce5fc 100644 --- a/spec/features/conference_spec.rb +++ b/spec/features/conference_spec.rb @@ -15,17 +15,17 @@ feature Conference do select('(GMT+01:00) Berlin', from: 'conference[timezone]') today = Date.today - 1 - page. - execute_script("$('#conference-start-datepicker').val('" + + page + .execute_script("$('#conference-start-datepicker').val('" + "#{today.strftime('%d/%m/%Y')}')") - page. - execute_script("$('#conference-end-datepicker').val('" + + page + .execute_script("$('#conference-end-datepicker').val('" + "#{(today + 7).strftime('%d/%m/%Y')}')") click_button 'Create Conference' - expect(flash). - to eq('Conference was successfully created.') + expect(flash) + .to eq('Conference was successfully created.') expect(Conference.count).to eq(expected_count) expect(user.has_role? :organizer, Conference.last).to eq(true) @@ -45,23 +45,23 @@ feature Conference do fill_in 'conference_short_title', with: '' click_button 'Update Conference' - expect(flash). - to eq("Updating conference failed. Short title can't be blank.") + expect(flash) + .to eq("Updating conference failed. Short title can't be blank.") fill_in 'conference_title', with: 'New Con' fill_in 'conference_short_title', with: 'NewCon' day = Date.today + 10 - page. - execute_script("$('#conference-start-datepicker').val('" + + page + .execute_script("$('#conference-start-datepicker').val('" + "#{day.strftime('%d/%m/%Y')}')") - page. - execute_script("$('#conference-end-datepicker').val('" + + page + .execute_script("$('#conference-end-datepicker').val('" + "#{(day + 7).strftime('%d/%m/%Y')}')") click_button 'Update Conference' - expect(flash). - to eq('Conference was successfully updated.') + expect(flash) + .to eq('Conference was successfully updated.') conference.reload expect(conference.title).to eq('New Con') diff --git a/spec/features/contact_spec.rb b/spec/features/contact_spec.rb index aa9fcf57..513f3cab 100644 --- a/spec/features/contact_spec.rb +++ b/spec/features/contact_spec.rb @@ -25,8 +25,8 @@ feature Contact do click_button 'Update Contact' - expect(flash). - to eq('Contact details were successfully updated.') + expect(flash) + .to eq('Contact details were successfully updated.') contact.reload expect(contact.email).to eq('example@example.com') expect(contact.sponsor_email).to eq('sponsor@example.com') diff --git a/spec/features/email_spec.rb b/spec/features/email_spec.rb index cdc6cdfe..c1bfef5d 100644 --- a/spec/features/email_spec.rb +++ b/spec/features/email_spec.rb @@ -53,39 +53,39 @@ feature EmailSettings do click_button 'Update Email settings' - expect(flash). - to eq('Email settings have been successfully updated.') + expect(flash) + .to eq('Email settings have been successfully updated.') - expect(find('#email_settings_registration_subject'). - value).to eq('Registration subject') - expect(find('#email_settings_registration_body'). - value).to eq('Registration email body') + expect(find('#email_settings_registration_subject') + .value).to eq('Registration subject') + expect(find('#email_settings_registration_body') + .value).to eq('Registration email body') click_link 'Proposal' - expect(find('#email_settings_accepted_subject'). - value).to eq('Accepted subject') - expect(find('#email_settings_accepted_body'). - value).to eq('Accepted email body') - expect(find('#email_settings_rejected_subject'). - value).to eq('Rejected subject') - expect(find('#email_settings_rejected_body'). - value).to eq('Rejected email body') - expect(find('#email_settings_confirmed_without_registration_subject'). - value).to eq('Confirmed without registration subject') - expect(find('#email_settings_confirmed_without_registration_body'). - value).to eq('Confirmed without registration email body') + expect(find('#email_settings_accepted_subject') + .value).to eq('Accepted subject') + expect(find('#email_settings_accepted_body') + .value).to eq('Accepted email body') + expect(find('#email_settings_rejected_subject') + .value).to eq('Rejected subject') + expect(find('#email_settings_rejected_body') + .value).to eq('Rejected email body') + expect(find('#email_settings_confirmed_without_registration_subject') + .value).to eq('Confirmed without registration subject') + expect(find('#email_settings_confirmed_without_registration_body') + .value).to eq('Confirmed without registration email body') click_link 'Update Notifications' - expect(find('#email_settings_conference_dates_updated_subject'). - value).to eq('Updated conference dates subject') - expect(find('#email_settings_conference_dates_updated_body'). - value).to eq('Updated conference dates email template') - expect(find('#email_settings_conference_registration_dates_updated_subject'). - value).to eq('Updated conference registration dates subject') - expect(find('#email_settings_conference_registration_dates_updated_body'). - value).to eq('Updated conference registration dates template') - expect(find('#email_settings_venue_updated_subject'). - value).to eq('Updated conference venue subject') - expect(find('#email_settings_venue_updated_body'). - value).to eq('Updated conference venue template') + expect(find('#email_settings_conference_dates_updated_subject') + .value).to eq('Updated conference dates subject') + expect(find('#email_settings_conference_dates_updated_body') + .value).to eq('Updated conference dates email template') + expect(find('#email_settings_conference_registration_dates_updated_subject') + .value).to eq('Updated conference registration dates subject') + expect(find('#email_settings_conference_registration_dates_updated_body') + .value).to eq('Updated conference registration dates template') + expect(find('#email_settings_venue_updated_subject') + .value).to eq('Updated conference venue subject') + expect(find('#email_settings_venue_updated_body') + .value).to eq('Updated conference venue template') expect(EmailSettings.count).to eq(expected_count) diff --git a/spec/features/program_spec.rb b/spec/features/program_spec.rb index ae4a3e64..369a0525 100644 --- a/spec/features/program_spec.rb +++ b/spec/features/program_spec.rb @@ -22,8 +22,8 @@ feature Program do click_button 'Update Program' # Validations - expect(flash). - to eq('The program was successfully updated.') + expect(flash) + .to eq('The program was successfully updated.') expect(find('#rating').text).to eq('4') end end diff --git a/spec/features/proposals_spec.rb b/spec/features/proposals_spec.rb index 4c6d6dfe..b5620475 100644 --- a/spec/features/proposals_spec.rb +++ b/spec/features/proposals_spec.rb @@ -131,8 +131,8 @@ feature Event do expect(page.has_content?('Example Proposal')).to be true expect(@event.state).to eq('unconfirmed') click_link "confirm_proposal_#{@event.id}" - expect(flash). - to eq('The proposal was confirmed. Please register to attend the conference.') + expect(flash) + .to eq('The proposal was confirmed. Please register to attend the conference.') expect(current_path).to eq(new_conference_conference_registration_path(conference.short_title)) @event.reload expect(@event.state).to eq('confirmed') diff --git a/spec/features/registration_periods_spec.rb b/spec/features/registration_periods_spec.rb index 4284c92e..c6cc992e 100644 --- a/spec/features/registration_periods_spec.rb +++ b/spec/features/registration_periods_spec.rb @@ -16,15 +16,15 @@ feature RegistrationPeriod do click_link 'New Registration Period' click_button 'Save Registration Period' - expect(flash). - to eq('An error prohibited the Registration Period from being saved: ' \ + expect(flash) + .to eq('An error prohibited the Registration Period from being saved: ' \ "Start date can't be blank. End date can't be blank.") - page. - execute_script("$('#registration-period-start-datepicker').val('" + + page + .execute_script("$('#registration-period-start-datepicker').val('" + "#{Date.today.strftime('%d/%m/%Y')}')") - page. - execute_script("$('#registration-period-end-datepicker').val('" + + page + .execute_script("$('#registration-period-end-datepicker').val('" + "#{(Date.today + 5).strftime('%d/%m/%Y')}')") click_button 'Save Registration Period' diff --git a/spec/features/venues_spec.rb b/spec/features/venues_spec.rb index 298f9391..2931b6e8 100644 --- a/spec/features/venues_spec.rb +++ b/spec/features/venues_spec.rb @@ -24,8 +24,8 @@ feature Conference do with: 'Lorem ipsum dolor sit amet, consetetur' \ 'sadipscing elitr, sed diam nonumy eirmod tempor' click_button 'Create Venue' - expect(flash). - to eq('Venue was successfully created.') + expect(flash) + .to eq('Venue was successfully created.') venue = Conference.find(conference.id).venue expect(venue.name).to eq('Example University') expect(venue.street).to eq('Example Street 42') @@ -35,14 +35,14 @@ feature Conference do # edit the venue click_link 'Edit Venue' - expect(page.find("//*[@id='venue_submit_action']"). - text).to eq('Update Venue') + expect(page.find("//*[@id='venue_submit_action']") + .text).to eq('Update Venue') fill_in 'venue_name', with: 'Example University new' fill_in 'venue_website', with: 'www.example.com new' fill_in 'venue_description', with: 'new' click_button 'Update Venue' - expect(flash). - to eq('Venue was successfully updated.') + expect(flash) + .to eq('Venue was successfully updated.') venue.reload expect(venue.name).to eq('Example University new') expect(venue.website).to eq('www.example.com new') diff --git a/spec/features/volunteers_spec.rb b/spec/features/volunteers_spec.rb index d3aa88cd..a27ba0b1 100644 --- a/spec/features/volunteers_spec.rb +++ b/spec/features/volunteers_spec.rb @@ -27,8 +27,8 @@ feature Conference do # find('div.nested-fields:nth-of-type(1) div:nth-of-type(1) textarea'). # set('Example Person') click_button 'Update Conference' - expect(flash). - to eq('Volunteering options were successfully updated.') + expect(flash) + .to eq('Volunteering options were successfully updated.') # # Validations # expect(find('div.nested-fields:nth-of-type(1) select:nth-of-type(1)'). @@ -73,8 +73,8 @@ feature Conference do # find('div.nested-fields:nth-of-type(1) div:nth-of-type(1) textarea'). # set('Example Person') click_button 'Update Conference' - expect(flash). - to eq('Volunteering options were successfully updated.') + expect(flash) + .to eq('Volunteering options were successfully updated.') # Add vposition check('Use vpositions') @@ -90,8 +90,8 @@ feature Conference do # "[id$='_vday_ids']"). # find(:option, "#{Date.today.strftime}").select_option click_button 'Update Conference' - expect(flash). - to eq('Volunteering options were successfully updated.') + expect(flash) + .to eq('Volunteering options were successfully updated.') # Validations # expect(find('div.vpositions div.nested-fields:nth-of-type(1)'\ diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index e58f57fc..242f03e5 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -50,11 +50,11 @@ describe ApplicationHelper, type: :helper do end it 'should return HTML for header markdown' do - expect(Redcarpet::Markdown).to receive(:new). - with(Redcarpet::Render::HTML, autolink: true, - space_after_headers: true, - no_intra_emphasis: true). - and_call_original + expect(Redcarpet::Markdown).to receive(:new) + .with(Redcarpet::Render::HTML, autolink: true, + space_after_headers: true, + no_intra_emphasis: true) + .and_call_original expect(markdown('# this is my header')).to eq "

this is my header

\n" end diff --git a/spec/models/conference_spec.rb b/spec/models/conference_spec.rb index aa824319..edb719e5 100755 --- a/spec/models/conference_spec.rb +++ b/spec/models/conference_spec.rb @@ -743,8 +743,8 @@ describe Conference do c = create(:conference, start_date: Time.now - 1.year, end_date: Time.now - 360.days) result = [a, b, c] - expect(Conference.get_conferences_without_active_for_dashboard([subject])). - to match_array(result) + expect(Conference.get_conferences_without_active_for_dashboard([subject])) + .to match_array(result) end it 'returns all conferences if there are no active conferences' do diff --git a/spec/support/external_request.rb b/spec/support/external_request.rb index 645067aa..d09ebc0a 100644 --- a/spec/support/external_request.rb +++ b/spec/support/external_request.rb @@ -24,6 +24,6 @@ def mock_commercial_request author_url: 'https://www.youtube.com/user/Confreaks', height: 344 } - WebMock.stub_request(:get, /.*youtube.*/). - to_return(status: 200, body: response.to_json, headers: {}) + WebMock.stub_request(:get, /.*youtube.*/) + .to_return(status: 200, body: response.to_json, headers: {}) end From 790e2fd3a285fc765e681712754c23661619da27 Mon Sep 17 00:00:00 2001 From: Eugene Dubinin Date: Thu, 2 Feb 2017 16:34:59 +0200 Subject: [PATCH 025/185] implement manual event management and support for multiple speakers per event --- Gemfile | 3 ++ Gemfile.lock | 3 ++ app/assets/javascripts/application.js | 1 + app/assets/stylesheets/application.css | 2 + app/assets/stylesheets/osem-schedule.css.scss | 6 ++- app/controllers/admin/events_controller.rb | 29 ++++++++++++-- app/controllers/proposals_controller.rb | 16 ++++---- app/models/event.rb | 32 ++++++++------- app/models/user.rb | 1 + app/views/admin/events/_form.html.haml | 11 ++++++ app/views/admin/events/_proposal.html.haml | 21 +++++++++- app/views/admin/events/index.html.haml | 15 +++---- app/views/proposals/_proposal_form.html.haml | 17 +++++++- app/views/proposals/show.html.haml | 39 +++++++++++-------- app/views/schedules/_event.html.haml | 8 ++-- app/views/schedules/_schedule_item.html.haml | 6 +++ app/views/users/show.html.haml | 6 +-- .../api/v1/speakers_controller_spec.rb | 5 +-- spec/controllers/proposals_controller_spec.rb | 3 +- spec/factories/events.rb | 3 +- spec/mailers/mailbot_spec.rb | 3 +- spec/models/email_settings_spec.rb | 3 +- spec/models/event_spec.rb | 24 ++++++------ spec/serializers/event_serializer_spec.rb | 12 +++--- 24 files changed, 180 insertions(+), 89 deletions(-) create mode 100644 app/views/admin/events/_form.html.haml diff --git a/Gemfile b/Gemfile index b1c5764f..f1c77a63 100644 --- a/Gemfile +++ b/Gemfile @@ -193,6 +193,9 @@ gem 'stripe' # Provides Sprockets implementation for Rails Asset Pipeline gem 'sprockets-rails' +# for multiple speakers select on proposal/event forms +gem 'selectize-rails' + # Use guard and spring for testing in development group :development do # to launch specs when files are modified diff --git a/Gemfile.lock b/Gemfile.lock index 13b5d012..581e0d4c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -459,6 +459,7 @@ GEM sass (~> 3.2.2) sprockets (~> 2.8, < 2.12) sprockets-rails (~> 2.0) + selectize-rails (0.12.4) shoulda-matchers (2.6.1) activesupport (>= 3.0.0) simplecov (0.11.2) @@ -621,6 +622,7 @@ DEPENDENCIES rubocop ruby-oembed sass-rails (>= 4.0.2) + selectize-rails shoulda-matchers spring-commands-rspec sprockets-rails @@ -638,3 +640,4 @@ DEPENDENCIES BUNDLED WITH 1.14.3 + diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 01cb83ee..b347821b 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -46,6 +46,7 @@ //= require unobtrusive_flash //= require unobtrusive_flash_bootstrap //= require countable +//= require selectize $(document).ready(function() { $('a[disabled=disabled]').click(function(event){ diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 912e50e3..c95bbb87 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -16,4 +16,6 @@ *= require bootstrap3-switch *= require osem-payments *= require osem-navbar + *= require selectize + *= require selectize.bootstrap3 */ diff --git a/app/assets/stylesheets/osem-schedule.css.scss b/app/assets/stylesheets/osem-schedule.css.scss index f2a97b83..21fda6f3 100644 --- a/app/assets/stylesheets/osem-schedule.css.scss +++ b/app/assets/stylesheets/osem-schedule.css.scss @@ -106,7 +106,11 @@ background-image: -webkit-gradient( } .speakerinfo { - margin-top: 20px; + margin-top: 40px; +} + +.speakerbio { + margin-top: 10px; } .schedule-title, .schedule-subtitle, .schedule-speaker, .schedule-track { diff --git a/app/controllers/admin/events_controller.rb b/app/controllers/admin/events_controller.rb index 2ed1690c..6cf31ddb 100644 --- a/app/controllers/admin/events_controller.rb +++ b/app/controllers/admin/events_controller.rb @@ -5,7 +5,7 @@ module Admin load_and_authorize_resource :event, through: :program load_and_authorize_resource :events_registration, only: :toggle_attendance - before_action :get_event, except: [:index, :create] + before_action :get_event, except: [:index, :create, :new] # FIXME: The timezome should only be applied on output, otherwise # you get lost in timezone conversions... @@ -62,6 +62,7 @@ module Admin @comments = @event.root_comments @comment_count = @event.comment_threads.count @user = @event.submitter + @users = User.all.order(:name) @url = admin_conference_program_event_path(@conference.short_title, @event) @languages = @program.languages_list end @@ -79,6 +80,8 @@ module Admin end def update + @users = User.all.order(:name) + @languages = @program.languages_list if @event.update_attributes(event_params) if request.xhr? @@ -94,7 +97,26 @@ module Admin end end - def create; end + def create + @url = admin_conference_program_events_path(@conference.short_title, @event) + @users = User.all.order(:name) + @languages = @program.languages_list + @event.submitter = current_user + + if @event.save + ahoy.track 'Event submission', title: 'New submission' + redirect_to admin_conference_program_events_path(@conference.short_title), notice: 'Event was successfully submitted.' + else + flash[:error] = "Could not submit proposal: #{@event.errors.full_messages.join(', ')}" + render action: 'new' + end + end + + def new + @url = admin_conference_program_events_path(@conference.short_title, @event) + @languages = @program.languages_list + @users = User.all.order(:name) + end def accept send_mail = @event.program.conference.email_settings.send_on_accepted @@ -161,7 +183,8 @@ module Admin # Set only in admin/events controller :track_id, :state, :language, :is_highlight, :max_attendees, # Not used anymore? - :proposal_additional_speakers, :user, :users_attributes) + :proposal_additional_speakers, :user, :users_attributes, + speaker_ids: []) end def comment_params diff --git a/app/controllers/proposals_controller.rb b/app/controllers/proposals_controller.rb index 56ea9735..f940e7ee 100644 --- a/app/controllers/proposals_controller.rb +++ b/app/controllers/proposals_controller.rb @@ -13,9 +13,8 @@ class ProposalsController < ApplicationController end def show - # FIXME: We should show more than the first speaker - @speaker = @event.speakers.first || @event.submitter @event_schedule = @event.event_schedules.find_by(schedule_id: @program.selected_schedule_id) + @speakers_ordered = @event.speakers_ordered end def new @@ -26,6 +25,7 @@ class ProposalsController < ApplicationController def edit @url = conference_program_proposal_path(@conference.short_title, params[:id]) + @users = User.all.order(:name) @languages = @program.languages_list end @@ -48,11 +48,8 @@ class ProposalsController < ApplicationController # User which creates the proposal is both `submitter` and `speaker` of proposal # by default. - # TODO: Allow submitter to add speakers to proposals - @event.event_users.new(user: current_user, - event_role: 'submitter') - @event.event_users.new(user: current_user, - event_role: 'speaker') + @event.speakers = [current_user] + @event.submitter = current_user if @event.save ahoy.track 'Event submission', title: 'New submission' redirect_to conference_program_proposals_path(@conference.short_title), notice: 'Proposal was successfully submitted.' @@ -64,6 +61,7 @@ class ProposalsController < ApplicationController def update @url = conference_program_proposal_path(@conference.short_title, params[:id]) + @users = User.all.order(:name) if @event.update(event_params) redirect_to conference_program_proposals_path(conference_id: @conference.short_title), @@ -147,7 +145,9 @@ class ProposalsController < ApplicationController def event_params params.require(:event).permit(:event_type_id, :track_id, :difficulty_level_id, :title, :subtitle, :abstract, :description, - :require_registration, :max_attendees, :language) + :require_registration, :max_attendees, :language, + speaker_ids: [] + ) end def user_params diff --git a/app/models/event.rb b/app/models/event.rb index 27fc1ad9..2bb526b9 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -8,7 +8,13 @@ class Event < ActiveRecord::Base has_many :event_users, dependent: :destroy has_many :users, through: :event_users - has_many :speakers, through: :event_users, source: :user + + has_many :speaker_event_users, -> { where(event_role: 'speaker') }, class_name: 'EventUser' + has_many :speakers, through: :speaker_event_users, source: :user + + has_one :submitter_event_user, -> { where(event_role: 'submitter') }, class_name: 'EventUser' + has_one :submitter, through: :submitter_event_user, source: :user + has_many :votes, dependent: :destroy has_many :voters, through: :votes, source: :user has_many :commercials, as: :commercialable, dependent: :destroy @@ -23,6 +29,7 @@ class Event < ActiveRecord::Base belongs_to :program accepts_nested_attributes_for :event_users, allow_destroy: true + accepts_nested_attributes_for :speakers, allow_destroy: true accepts_nested_attributes_for :users before_create :generate_guid @@ -33,6 +40,7 @@ class Event < ActiveRecord::Base validates :abstract, presence: true validates :event_type, presence: true validates :program, presence: true + validates :speakers, presence: true validates :max_attendees, numericality: { only_integer: true, greater_than_or_equal_to: 1, allow_nil: true } validate :max_attendees_no_more_than_room_size @@ -113,20 +121,16 @@ class Event < ActiveRecord::Base @total_rating > 0 ? number_with_precision(@total_rating / @total.to_f, precision: 2, strip_insignificant_zeros: true) : 0 end - def submitter - result = event_users.where(event_role: 'submitter').first - if result.nil? - user = nil - # Perhaps the event_users haven't been saved, if this is a new proposal - event_users.each do |u| - if u.event_role == 'submitter' - user = u.user - end - end - user - else - result.user + # get event speakers with the event sumbmitter at the first position + # if the submitter is also a speaker for this event + def speakers_ordered + speakers_list = speakers.to_a + + if speakers_list.reject! { |speaker| speaker == submitter } + speakers_list.unshift(submitter) end + + speakers_list end def transition_possible?(transition) diff --git a/app/models/user.rb b/app/models/user.rb index 60bbab80..5f41e693 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -41,6 +41,7 @@ class User < ActiveRecord::Base has_many :event_users, dependent: :destroy has_many :events, -> { uniq }, through: :event_users + has_many :presented_events, -> { joins(:event_users).where(event_users: {event_role: 'speaker'}).uniq }, through: :event_users, source: :event has_many :registrations, dependent: :destroy has_many :events_registrations, through: :registrations has_many :ticket_purchases, dependent: :destroy diff --git a/app/views/admin/events/_form.html.haml b/app/views/admin/events/_form.html.haml new file mode 100644 index 00000000..36e62439 --- /dev/null +++ b/app/views/admin/events/_form.html.haml @@ -0,0 +1,11 @@ +.row + .col-md-12 + .page-header + %h1 + -if @event.new_record? + New + = @event.title + Event +.row + .col-md-12 + = render 'proposals/proposal_form' diff --git a/app/views/admin/events/_proposal.html.haml b/app/views/admin/events/_proposal.html.haml index 24f84f48..15894f26 100644 --- a/app/views/admin/events/_proposal.html.haml +++ b/app/views/admin/events/_proposal.html.haml @@ -131,9 +131,26 @@ %i Hidden %tr %td - %b Biography + %b Speakers %td - = markdown(@event.submitter.biography) + - if @program.show_voting? + - @event.speakers.each do |speaker| + %div + = link_to speaker.name, admin_user_path(speaker) + ( + = link_to speaker.email, "mailto: #{speaker.email}" + ) + - else + %i Hidden + %tr + %td + %b Biographies + %td + - @event.speakers.each do |speaker| + - unless speaker.biography.blank? + %b + = speaker.name + = markdown(speaker.biography) %tr %td %b Submitted on diff --git a/app/views/admin/events/index.html.haml b/app/views/admin/events/index.html.haml index 0e265aba..0e204c87 100644 --- a/app/views/admin/events/index.html.haml +++ b/app/views/admin/events/index.html.haml @@ -4,7 +4,9 @@ %h1 Events = "(#{@events.length})" if @events.any? - .btn-group.pull-right + .pull-right + - if can? :create, Event + =link_to 'Add Event', new_admin_conference_program_event_path(@conference.short_title), class: 'button btn btn-default btn-info' - if can? :read, Event .btn-group %button.btn.btn-default.dropdown-toggle{ 'data-toggle' => 'dropdown', type: 'button', class: 'btn btn-success' } @@ -54,8 +56,8 @@ %th %b Submitter %th - %b Speaker - - if @program.languages.present? + %b Speakers + -if @program.languages.present? %th %b Language %th @@ -99,10 +101,9 @@ %i Hidden %td - if @program.show_voting? - - if speaker = event.speakers.first - = link_to speaker.name, admin_user_path(speaker) - - else - Unknown speaker + - event.speakers_ordered.each do |speaker| + .speaker + = link_to speaker.name, admin_user_path(speaker) - else %i Hidden diff --git a/app/views/proposals/_proposal_form.html.haml b/app/views/proposals/_proposal_form.html.haml index 8551ad1b..3116d532 100644 --- a/app/views/proposals/_proposal_form.html.haml +++ b/app/views/proposals/_proposal_form.html.haml @@ -4,6 +4,10 @@ = f.input :subtitle, as: :string + = f.input :speakers, as: :select, + collection: options_for_select(@users.map {|user| ["#{user.name} (#{user.email})", user.id]}, @event.speakers.map(&:id)), + include_blank: false, label: 'Speakers', input_html: { class: 'select-help-toggle', multiple: 'true' } + - if @program.tracks.any? = f.input :track_id, as: :select, collection: @program.tracks.map {|track| ["#{track.name}", track.id] }, @@ -60,4 +64,15 @@ %p.text-right - = f.submit 'Update Proposal', class: 'btn btn-success' + - if @event.new_record? + = f.submit 'Create Proposal', class: 'btn btn-success' + - else + = f.submit 'Update Proposal', class: 'btn btn-success' + +:javascript + $(document).ready(function() { + $('#event_speaker_ids').selectize({ + plugins: ['remove_button'], + maxItems: 5 + } ) + }); diff --git a/app/views/proposals/show.html.haml b/app/views/proposals/show.html.haml index 76fa6a85..2d38d3a8 100644 --- a/app/views/proposals/show.html.haml +++ b/app/views/proposals/show.html.haml @@ -3,8 +3,9 @@ %meta{ property: "og:url", content: conference_program_proposal_url(@conference.short_title, @event) } %meta{ property: "og:description", content: @event.abstract } %meta{ property: "og:site_name", content: (ENV['OSEM_NAME'] || 'OSEM') } - %meta{ property: "og:image", content: @speaker.gravatar_url } - %meta{ property: "og:image:secure_url", content: @speaker.gravatar_url } + - if @speakers_ordered.any? + %meta{ property: "og:image", content: @speakers_ordered.first.gravatar_url } + %meta{ property: "og:image:secure_url", content: @speakers_ordered.first.gravatar_url } .container .row @@ -25,21 +26,25 @@ .row .col-md-3 - .speakerinfo - .col-md-12 - = image_tag @speaker.gravatar_url(size: 200), class: 'img-responsive img-rounded' - .col-md-12 - %h3 - by - = link_to @speaker.name, user_path(@speaker.id) - = "(#{@speaker.email})" if @speaker.email_public - - if @speaker.affiliation? - %br - %span.muted - from - = @speaker.affiliation - -if @speaker.biography? - = markdown(@speaker.biography) + %h3 + Presented by: + - @speakers_ordered.each do |speaker| + .speakerinfo + .row + .col-md-4 + = image_tag speaker.gravatar_url(:size => 120), class: 'img-responsive img-rounded' + .col-md-8 + %h4 + = link_to speaker.name, user_path(speaker.id) + = "(#{speaker.email})" + - if speaker.affiliation? + .text-muted + from + = speaker.affiliation + -if speaker.biography? + .row.speakerbio + .col-md-12 + = markdown(speaker.biography) .col-md-9 .row .col-md-12 diff --git a/app/views/schedules/_event.html.haml b/app/views/schedules/_event.html.haml index a5f2c569..a19d01cd 100644 --- a/app/views/schedules/_event.html.haml +++ b/app/views/schedules/_event.html.haml @@ -1,9 +1,9 @@ .panel.panel-default.event-panel{ onClick: 'eventClicked(event, this);', "data-url" => "#{url_for(conference_program_proposal_path(@conference.short_title, event.id))}" } .panel-body - - if speaker = event.speakers.first - = image_tag speaker.gravatar_url, class: "img-circle pull-right all-speaker-pic", | - alt: speaker.name, | - title: speaker.name | + - event.speakers_ordered.each do |speaker| + = image_tag speaker.gravatar_url, :class => "img-circle pull-right all-speaker-pic", | + :alt => speaker.name, | + :title => speaker.name | %p = canceled_replacement_event_label(event, event_schedule) diff --git a/app/views/schedules/_schedule_item.html.haml b/app/views/schedules/_schedule_item.html.haml index 2a8a636e..d475ec80 100644 --- a/app/views/schedules/_schedule_item.html.haml +++ b/app/views/schedules/_schedule_item.html.haml @@ -14,3 +14,9 @@ alt: speaker.name, | title: speaker.name, | style: "height: #{ speaker_height(@rooms) }px; width: #{ speaker_width(@rooms) }px;" + - event.speakers_ordered.each do |speaker| + = image_tag speaker.gravatar_url, :class => "img-circle pull-right speaker-pic", | + :alt => speaker.name, | + :title => speaker.name, | + :style => "height: #{ speaker_height(@rooms) }px; width: #{ speaker_width(@rooms) }px;" + diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index 7e246062..b20891f8 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -11,11 +11,11 @@ = markdown(@user.biography) .row .col-md-12 - - if @user.events.confirmed.any? + - if @user.presented_events.confirmed.any? %h3 - = "#{@user.name} presents #{pluralize(@user.events.confirmed.count, 'Event')}:" + = "#{@user.name} presents #{pluralize(@user.presented_events.confirmed.count, 'Event')}:" %ul.list-unstyled - - @user.events.confirmed.each do |event| + - @user.presented_events.confirmed.each do |event| %li %h4 = link_to event.title, conference_program_proposal_path(event.program.conference.short_title, event.id) diff --git a/spec/controllers/api/v1/speakers_controller_spec.rb b/spec/controllers/api/v1/speakers_controller_spec.rb index 8efefa57..539baeaf 100644 --- a/spec/controllers/api/v1/speakers_controller_spec.rb +++ b/spec/controllers/api/v1/speakers_controller_spec.rb @@ -10,8 +10,8 @@ describe Api::V1::SpeakersController do describe 'GET #index' do before do - event.event_users << create(:speaker, user: speaker) - conference_event.event_users << create(:speaker, user: conference_speaker) + event.speakers = [speaker] + conference_event.speakers = [conference_speaker] end context 'without conference scope' do @@ -20,7 +20,6 @@ describe Api::V1::SpeakersController do get :index, format: :json json = JSON.parse(response.body)['speakers'] expect(response).to be_success - expect(json.length).to eq(2) expect(json[0]['name']).to eq('Speaker') expect(json[1]['name']).to eq('Conf_Speaker') diff --git a/spec/controllers/proposals_controller_spec.rb b/spec/controllers/proposals_controller_spec.rb index 43d6e4fa..8f033973 100644 --- a/spec/controllers/proposals_controller_spec.rb +++ b/spec/controllers/proposals_controller_spec.rb @@ -180,9 +180,8 @@ describe ProposalsController do get :show, conference_id: conference.short_title, id: event.id end - it 'assigns event and speaker variables' do + it 'assigns event variable' do expect(assigns(:event)).to eq event - expect(assigns(:speaker)).to eq event.submitter end it 'renders show template' do diff --git a/spec/factories/events.rb b/spec/factories/events.rb index 06d791e2..09c74afd 100644 --- a/spec/factories/events.rb +++ b/spec/factories/events.rb @@ -8,7 +8,8 @@ FactoryGirl.define do program after(:build) do |event| - event.event_users << build(:submitter) unless event.submitter # so that we don't have two submitters + event.submitter = build(:submitter).user unless event.submitter # so that we don't have two submitters + event.speakers << build(:speaker).user unless event.speakers.any? # set an event_type if none is passed to the factory. # needs to be created here because otherwise it doesn't belong to the # same conference as the event diff --git a/spec/mailers/mailbot_spec.rb b/spec/mailers/mailbot_spec.rb index 5bafb4f7..76c6ef00 100644 --- a/spec/mailers/mailbot_spec.rb +++ b/spec/mailers/mailbot_spec.rb @@ -8,8 +8,7 @@ describe Mailbot do before { conference.contact.update_attributes(email: 'conf@domain.com') } context 'onboarding and proposal' do - let(:event_user) { create(:submitter, user: user) } - let(:event) { create(:event, program: conference.program, event_users: [event_user]) } + let(:event) { create(:event, program: conference.program, submitter: user) } shared_examples 'mailer actions' do it 'assigns the email subject' do diff --git a/spec/models/email_settings_spec.rb b/spec/models/email_settings_spec.rb index c66e3421..949f5762 100644 --- a/spec/models/email_settings_spec.rb +++ b/spec/models/email_settings_spec.rb @@ -3,8 +3,7 @@ require 'spec_helper' describe EmailSettings do let(:conference) { create(:conference, short_title: 'goto', start_date: Date.new(2014, 05, 01), end_date: Date.new(2014, 05, 06)) } let(:user) { create(:user, username: 'johnd', email: 'john@doe.com', name: 'John Doe') } - let(:event_user) { create(:submitter, user: user) } - let(:event) { create(:event, program: conference.program, title: 'Talk about talks', event_users: [event_user]) } + let(:event) { create(:event, program: conference.program, title: 'Talk about talks', submitter: user) } let(:expected_hash) do { 'email' => 'john@doe.com', diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index f9c46559..e1c2297c 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -236,9 +236,7 @@ describe Event do describe '#submitter' do it 'returns the user that submitted the event' do submitter = create(:user) - submitted_event = create(:event) - submitted_event.event_users = [create(:event_user, user: submitter, event_role: 'submitter')] - + submitted_event = create(:event, submitter: submitter) expect(submitted_event.submitter).to eq submitter end end @@ -288,9 +286,10 @@ describe Event do describe '#speaker_names' do context 'returns the speakers of the event' do it 'when submitter is a speaker too' do - speaker1 = create(:user, name: 'user speaker 1') - new_event.event_users = [create(:event_user, user: speaker1, event_role: 'submitter')] - new_event.event_users << [create(:event_user, user: speaker1, event_role: 'speaker')] + submitter = create(:user, name: 'user speaker 1') + + new_event.submitter = submitter + new_event.speakers = [submitter] expect(new_event.speaker_names).to eq 'user speaker 1' end @@ -299,10 +298,10 @@ describe Event do submitter = create(:user, name: 'user submitter 1') speaker1 = create(:user, name: 'user speaker 1') - new_event.event_users = [create(:event_user, user: submitter, event_role: 'submitter')] - new_event.event_users << [create(:event_user, user: speaker1, event_role: 'speaker')] + new_event.submitter = submitter + new_event.speakers = [speaker1] - expect(new_event.speaker_names).to eq 'user submitter 1 and user speaker 1' + expect(new_event.speaker_names).to eq 'user speaker 1' end it 'when there are multiple speakers' do @@ -310,11 +309,10 @@ describe Event do speaker1 = create(:user, name: 'user speaker 1') speaker2 = create(:user, name: 'user speaker 2') - new_event.event_users = [create(:event_user, user: submitter, event_role: 'submitter')] - new_event.event_users << [create(:event_user, user: speaker1, event_role: 'speaker')] - new_event.event_users << [create(:event_user, user: speaker2, event_role: 'speaker')] + new_event.submitter = submitter + new_event.speakers = [speaker1, speaker2] - expect(new_event.speaker_names).to eq 'user submitter 1, user speaker 1, and user speaker 2' + expect(new_event.speaker_names).to eq 'user speaker 1 and user speaker 2' end end end diff --git a/spec/serializers/event_serializer_spec.rb b/spec/serializers/event_serializer_spec.rb index b4edc2d1..af459e1d 100644 --- a/spec/serializers/event_serializer_spec.rb +++ b/spec/serializers/event_serializer_spec.rb @@ -3,7 +3,7 @@ describe EventSerializer, type: :serializer do let(:event) { create(:event, title: 'Some Talk', abstract: 'Lorem ipsum dolor sit amet') } let(:serializer) { EventSerializer.new(event) } - context 'event does not have date, speakers, room and tracks assigned' do + context 'event does not have date, room and tracks assigned' do it 'sets guid, title, length, abstract and type' do expected_json = { event: { @@ -13,7 +13,7 @@ describe EventSerializer, type: :serializer do scheduled_date: '', language: nil, abstract: 'Lorem ipsum dolor sit amet', - speaker_ids: [], + speaker_ids: event.speaker_ids, type: 'Example Event Type', room: nil, track: nil @@ -25,13 +25,13 @@ describe EventSerializer, type: :serializer do end context 'event has date, speakers, room and tracks assigned' do - let(:speaker) { create(:speaker) } + let(:speaker) { create(:user) } let(:room) { create(:room) } let(:track) { create(:track) } before do - event.language = 'English' - event.event_users << speaker + event.language = 'English' + event.speakers = [speaker] create(:event_schedule, event: event, room: room, start_time: Date.new(2014, 03, 04)) event.track = track end @@ -45,7 +45,7 @@ describe EventSerializer, type: :serializer do scheduled_date: ' 2014-03-04T00:00:00+0000 ', language: 'English', abstract: 'Lorem ipsum dolor sit amet', - speaker_ids: [speaker.user.id], + speaker_ids: [speaker.id], type: 'Example Event Type', room: room.guid, track: track.guid From 11938025cf86f2364714246ee471d7dedb7bbc15 Mon Sep 17 00:00:00 2001 From: nasia Date: Fri, 7 Apr 2017 14:36:18 +0300 Subject: [PATCH 026/185] Add permission to access admin/shedule by cfp#1432 --- app/models/ability.rb | 1 + spec/features/ability_spec.rb | 4 ++-- spec/models/ability_spec.rb | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/models/ability.rb b/app/models/ability.rb index 14913e75..decf8cb8 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -198,6 +198,7 @@ class Ability 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) diff --git a/spec/features/ability_spec.rb b/spec/features/ability_spec.rb index e304b4b2..88d218f4 100644 --- a/spec/features/ability_spec.rb +++ b/spec/features/ability_spec.rb @@ -129,7 +129,7 @@ feature 'Has correct abilities' do expect(page).to have_link('Commercials', href: "/admin/conferences/#{conference2.short_title}/commercials") expect(page).to have_link('Events', href: "/admin/conferences/#{conference2.short_title}/program/events") expect(page).to_not have_link('Registrations', href: "/admin/conferences/#{conference2.short_title}/registrations") - expect(page).to_not have_link('Schedules', href: "/admin/conferences/#{conference2.short_title}/schedules") + expect(page).to have_link('Schedules', href: "/admin/conferences/#{conference2.short_title}/schedules") expect(page).to_not have_link('Campaigns', href: "/admin/conferences/#{conference2.short_title}/campaigns") expect(page).to_not have_link('Goals', href: "/admin/conferences/#{conference2.short_title}/targets") expect(page).to have_link('Venue', href: "/admin/conferences/#{conference2.short_title}/venue") @@ -161,7 +161,7 @@ feature 'Has correct abilities' do expect(current_path).to eq(admin_conference_program_events_path(conference2.short_title)) visit admin_conference_schedules_path(conference2.short_title) - expect(current_path).to eq(root_path) + expect(current_path).to eq(admin_conference_schedules_path(conference2.short_title)) visit admin_conference_campaigns_path(conference2.short_title) expect(current_path).to eq(root_path) diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index 8637f3dd..6ddc44e6 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -274,7 +274,7 @@ describe 'User' do 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_not be_able_to(:manage, my_schedule) } + 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) } From 0564d2df7aaf6cc8e9c728c386c01c45e34085a5 Mon Sep 17 00:00:00 2001 From: Sunny Date: Fri, 7 Apr 2017 23:58:43 -0400 Subject: [PATCH 027/185] add performance/stringreplacement rubocop cop Enabled the performance/stringreplacement rubocop in the .rubocop.yml file and removed it from .rubocop_todo.yml. This cop checks for instances where gsub can be replaced with tr or delete. Supports auto correct, but there weren't any offenses. Closes #1444 --- .rubocop.yml | 8 +++++++- .rubocop_todo.yml | 6 ------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 08bc0e68..c2e973f0 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -104,7 +104,7 @@ Style/TrailingBlankLines: Style/TrailingWhitespace: Enabled: true -#This cop checks for numeric comparisons that can be replaced by a predicate method. +# This cop checks for numeric comparisons that can be replaced by a predicate method. Style/ZeroLengthPredicate: Enabled: true @@ -183,3 +183,9 @@ Rails: # Avoid use of old-style attribute validation Rails/Validation: Enabled: true + +#################### Performance ############################### + +# Identifies places where gsub can be replaced by tr or delete. +Performance/StringReplacement: + Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 18fd7930..330eb3cd 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -48,12 +48,6 @@ Metrics/ModuleLength: Metrics/PerceivedComplexity: Max: 15 -# Offense count: 1 -# Cop supports --auto-correct. -Performance/StringReplacement: - Exclude: - - 'spec/support/save_feature_failures.rb' - # Offense count: 13 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, Include. From f04c7a7cab8d4dcbb4793451e0b069064e4d9482 Mon Sep 17 00:00:00 2001 From: shlok007 Date: Mon, 6 Mar 2017 14:02:33 +0530 Subject: [PATCH 028/185] improved features/ability_spec.rb --- spec/features/ability_spec.rb | 609 +++++++++++++++++++++++++++------- 1 file changed, 492 insertions(+), 117 deletions(-) diff --git a/spec/features/ability_spec.rb b/spec/features/ability_spec.rb index 88d218f4..b3d8e5fa 100644 --- a/spec/features/ability_spec.rb +++ b/spec/features/ability_spec.rb @@ -5,21 +5,17 @@ feature 'Has correct abilities' do let(:conference1) { create(:full_conference) } # user is organizer let(:conference2) { create(:full_conference) } # user is cfp let(:conference3) { create(:full_conference) } # user is info_desk - let(:conference4) { create(:full_conference) } # user is volunteer coordinator - let(:conference5) { create(:full_conference) } # user has no role let(:conference6) { create(:conference) } # user is organizer, venue is not set by default let(:role_organizer_conf1) { Role.find_by(name: 'organizer', resource: conference1) } let(:role_organizer_conf6) { Role.find_by(name: 'organizer', resource: conference6) } let(:role_cfp) { Role.find_by(name: 'cfp', resource: conference2) } let(:role_info_desk) { Role.find_by(name: 'info_desk', resource: conference3) } - let(:role_volunteers_coordinator) { Role.find_by(name: 'volunteers_coordinator', resource: conference4) } let(:user) { create(:user) } let(:user_organizer) { create(:user, role_ids: [role_organizer_conf1.id, role_organizer_conf6.id]) } let(:user_cfp) { create(:user, role_ids: [role_cfp.id]) } let(:user_info_desk) { create(:user, role_ids: [role_info_desk.id]) } - let(:user_volunteers_coordinator) { create(:user, role_ids: [role_volunteers_coordinator.id]) } scenario 'when user has no role' do sign_in user @@ -39,24 +35,29 @@ feature 'Has correct abilities' do expect(page).to have_link('Basics', href: "/admin/conferences/#{conference1.short_title}/edit") expect(page).to have_link('Contact', href: "/admin/conferences/#{conference1.short_title}/contact/edit") expect(page).to have_link('Commercials', href: "/admin/conferences/#{conference1.short_title}/commercials") - expect(page).to have_link('Events', href: "/admin/conferences/#{conference1.short_title}/program/events") - expect(page).to have_link('Registrations', href: "/admin/conferences/#{conference1.short_title}/registrations") - expect(page).to have_link('Schedules', href: "/admin/conferences/#{conference1.short_title}/schedules") - expect(page).to have_link('Campaigns', href: "/admin/conferences/#{conference1.short_title}/campaigns") - expect(page).to have_link('Goals', href: "/admin/conferences/#{conference1.short_title}/targets") + expect(page).to have_link('Splashpage', href: "/admin/conferences/#{conference1.short_title}/splashpage") expect(page).to have_link('Venue', href: "/admin/conferences/#{conference1.short_title}/venue") expect(page).to have_link('Rooms', href: "/admin/conferences/#{conference1.short_title}/venue/rooms") expect(page).to have_link('Lodgings', href: "/admin/conferences/#{conference1.short_title}/lodgings") - expect(page).to have_link('Sponsorship', href: "/admin/conferences/#{conference1.short_title}/sponsorship_levels") - expect(page).to have_link('Sponsors', href: "/admin/conferences/#{conference1.short_title}/sponsors") - expect(page).to have_link('Tickets', href: "/admin/conferences/#{conference1.short_title}/tickets") - expect(page).to have_link('E-Mails', href: "/admin/conferences/#{conference1.short_title}/emails") expect(page).to have_link('Program', href: "/admin/conferences/#{conference1.short_title}/program") expect(page).to have_link('Call for Papers', href: "/admin/conferences/#{conference1.short_title}/program/cfp") + expect(page).to have_link('Events', href: "/admin/conferences/#{conference1.short_title}/program/events") expect(page).to have_link('Tracks', href: "/admin/conferences/#{conference1.short_title}/program/tracks") expect(page).to have_link('Event Types', href: "/admin/conferences/#{conference1.short_title}/program/event_types") expect(page).to have_link('Difficulty Levels', href: "/admin/conferences/#{conference1.short_title}/program/difficulty_levels") + expect(page).to have_link('Schedules', href: "/admin/conferences/#{conference1.short_title}/schedules") + expect(page).to have_link('Reports', href: "/admin/conferences/#{conference1.short_title}/program/reports") + expect(page).to have_link('Registrations', href: "/admin/conferences/#{conference1.short_title}/registrations") + expect(page).to have_link('Registration Period', href: "/admin/conferences/#{conference1.short_title}/registration_period") expect(page).to have_link('Questions', href: "/admin/conferences/#{conference1.short_title}/questions") + expect(page).to have_text('Donations') + expect(page).to have_link('Sponsorship Levels', href: "/admin/conferences/#{conference1.short_title}/sponsorship_levels") + expect(page).to have_link('Sponsors', href: "/admin/conferences/#{conference1.short_title}/sponsors") + expect(page).to have_link('Tickets', href: "/admin/conferences/#{conference1.short_title}/tickets") + expect(page).to have_text('Objectives') + expect(page).to have_link('Campaigns', href: "/admin/conferences/#{conference1.short_title}/campaigns") + expect(page).to have_link('Goals', href: "/admin/conferences/#{conference1.short_title}/targets") + expect(page).to have_link('E-Mails', href: "/admin/conferences/#{conference1.short_title}/emails") expect(page).to have_link('Roles', href: "/admin/conferences/#{conference1.short_title}/roles") expect(page).to have_link('Resources', href: "/admin/conferences/#{conference1.short_title}/resources") @@ -66,23 +67,17 @@ feature 'Has correct abilities' do visit edit_admin_conference_path(conference1.short_title) expect(current_path).to eq(edit_admin_conference_path(conference1.short_title)) - visit admin_conference_path(conference1.short_title) - expect(current_path).to eq(admin_conference_path(conference1.short_title)) + visit edit_admin_conference_contact_path(conference1.short_title) + expect(current_path).to eq(edit_admin_conference_contact_path(conference1.short_title)) - visit admin_conference_registrations_path(conference1.short_title) - expect(current_path).to eq(admin_conference_registrations_path(conference1.short_title)) + visit admin_conference_commercials_path(conference1.short_title) + expect(current_path).to eq(admin_conference_commercials_path(conference1.short_title)) - visit admin_conference_program_events_path(conference1.short_title) - expect(current_path).to eq(admin_conference_program_events_path(conference1.short_title)) + visit new_admin_conference_splashpage_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_splashpage_path(conference1.short_title)) - visit admin_conference_schedules_path(conference1.short_title) - expect(current_path).to eq(admin_conference_schedules_path(conference1.short_title)) - - visit admin_conference_campaigns_path(conference1.short_title) - expect(current_path).to eq(admin_conference_campaigns_path(conference1.short_title)) - - visit admin_conference_targets_path(conference1.short_title) - expect(current_path).to eq(admin_conference_targets_path(conference1.short_title)) + visit edit_admin_conference_splashpage_path(conference1.short_title) + expect(current_path).to eq(edit_admin_conference_splashpage_path(conference1.short_title)) visit new_admin_conference_venue_path(conference1.short_title) expect(current_path).to eq(new_admin_conference_venue_path(conference1.short_title)) @@ -91,27 +86,156 @@ feature 'Has correct abilities' do visit edit_admin_conference_venue_path(conference1.short_title) expect(current_path).to eq(edit_admin_conference_venue_path(conference1.short_title)) - visit admin_conference_sponsorship_levels_path(conference1.short_title) - expect(current_path).to eq(admin_conference_sponsorship_levels_path(conference1.short_title)) + visit admin_conference_venue_rooms_path(conference1.short_title) + expect(current_path).to eq(admin_conference_venue_rooms_path(conference1.short_title)) - visit admin_conference_tickets_path(conference1.short_title) - expect(current_path).to eq(admin_conference_tickets_path(conference1.short_title)) + create(:room, venue: conference1.venue) + visit edit_admin_conference_venue_room_path(conference1.short_title, conference1.venue.rooms.first) + expect(current_path).to eq(edit_admin_conference_venue_room_path(conference1.short_title, conference1.venue.rooms.first)) - visit admin_conference_emails_path(conference1.short_title) - expect(current_path).to eq(admin_conference_emails_path(conference1.short_title)) + visit admin_conference_lodgings_path(conference1.short_title) + expect(current_path).to eq(admin_conference_lodgings_path(conference1.short_title)) + + visit new_admin_conference_lodging_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_lodging_path(conference1.short_title)) + + create(:lodging, conference: conference1) + visit edit_admin_conference_lodging_path(conference1.short_title, conference1.lodgings.first) + expect(current_path).to eq(edit_admin_conference_lodging_path(conference1.short_title, conference1.lodgings.first)) + + visit new_admin_conference_program_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_program_path(conference1.short_title)) + + visit edit_admin_conference_program_path(conference1.short_title) + expect(current_path).to eq(edit_admin_conference_program_path(conference1.short_title)) visit new_admin_conference_program_cfp_path(conference1.short_title) expect(current_path).to eq(new_admin_conference_program_cfp_path(conference1.short_title)) + visit edit_admin_conference_program_cfp_path(conference1.short_title) + expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference1.short_title)) + + visit admin_conference_program_events_path(conference1.short_title) + expect(current_path).to eq(admin_conference_program_events_path(conference1.short_title)) + + create(:event, program: conference1.program) + visit edit_admin_conference_program_event_path(conference1.short_title, conference1.program.events.first) + expect(current_path).to eq(edit_admin_conference_program_event_path(conference1.short_title, conference1.program.events.first)) + + visit admin_conference_program_event_types_path(conference1.short_title) + expect(current_path).to eq(admin_conference_program_event_types_path(conference1.short_title)) + + visit new_admin_conference_program_event_type_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_program_event_type_path(conference1.short_title)) + + visit edit_admin_conference_program_event_type_path(conference1.short_title, conference1.program.event_types.first) + expect(current_path).to eq(edit_admin_conference_program_event_type_path(conference1.short_title, conference1.program.event_types.first)) + + visit admin_conference_program_difficulty_levels_path(conference1.short_title) + expect(current_path).to eq(admin_conference_program_difficulty_levels_path(conference1.short_title)) + + visit new_admin_conference_program_difficulty_level_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_program_difficulty_level_path(conference1.short_title)) + + visit edit_admin_conference_program_difficulty_level_path(conference1.short_title, conference1.program.difficulty_levels.first) + expect(current_path).to eq(edit_admin_conference_program_difficulty_level_path(conference1.short_title, conference1.program.difficulty_levels.first)) + + visit admin_conference_schedules_path(conference1.short_title) + expect(current_path).to eq(admin_conference_schedules_path(conference1.short_title)) + + create(:schedule, program: conference1.program) + visit admin_conference_schedule_path(conference1.short_title, conference1.program.schedules.first) + expect(current_path).to eq(admin_conference_schedule_path(conference1.short_title, conference1.program.schedules.first)) + + visit admin_conference_program_reports_path(conference1.short_title) + expect(current_path).to eq(admin_conference_program_reports_path(conference1.short_title)) + + visit admin_conference_registrations_path(conference1.short_title) + expect(current_path).to eq(admin_conference_registrations_path(conference1.short_title)) + + create(:registration, user: create(:user), conference: conference1) + visit edit_admin_conference_registration_path(conference1.short_title, conference1.registrations.first) + expect(current_path).to eq(edit_admin_conference_registration_path(conference1.short_title, conference1.registrations.first)) + + visit new_admin_conference_registration_period_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_registration_period_path(conference1.short_title)) + + create(:registration_period, conference: conference1) + visit edit_admin_conference_registration_period_path(conference1.short_title) + expect(current_path).to eq(edit_admin_conference_registration_period_path(conference1.short_title)) + visit admin_conference_questions_path(conference1.short_title) expect(current_path).to eq(admin_conference_questions_path(conference1.short_title)) - visit admin_conference_commercials_path(conference1.short_title) - expect(current_path).to eq(admin_conference_commercials_path(conference1.short_title)) + visit admin_conference_sponsorship_levels_path(conference1.short_title) + expect(current_path).to eq(admin_conference_sponsorship_levels_path(conference1.short_title)) + + visit new_admin_conference_sponsorship_level_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_sponsorship_level_path(conference1.short_title)) + + create(:sponsorship_level, conference: conference1) + visit edit_admin_conference_sponsorship_level_path(conference1.short_title, conference1.sponsorship_levels.first) + expect(current_path).to eq(edit_admin_conference_sponsorship_level_path(conference1.short_title, conference1.sponsorship_levels.first)) + + visit admin_conference_sponsors_path(conference1.short_title) + expect(current_path).to eq(admin_conference_sponsors_path(conference1.short_title)) + + visit new_admin_conference_sponsor_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_sponsor_path(conference1.short_title)) + + create(:sponsor, conference: conference1, sponsorship_level: conference1.sponsorship_levels.first) + visit edit_admin_conference_sponsor_path(conference1.short_title, conference1.sponsors.first) + expect(current_path).to eq(edit_admin_conference_sponsor_path(conference1.short_title, conference1.sponsors.first)) + + visit admin_conference_tickets_path(conference1.short_title) + expect(current_path).to eq(admin_conference_tickets_path(conference1.short_title)) + + visit new_admin_conference_ticket_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_ticket_path(conference1.short_title)) + + create(:ticket, conference: conference1) + visit edit_admin_conference_ticket_path(conference1.short_title, conference1.tickets.first) + expect(current_path).to eq(edit_admin_conference_ticket_path(conference1.short_title, conference1.tickets.first)) + + visit admin_conference_campaigns_path(conference1.short_title) + expect(current_path).to eq(admin_conference_campaigns_path(conference1.short_title)) + + visit new_admin_conference_campaign_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_campaign_path(conference1.short_title)) + + create(:campaign, conference: conference1) + visit edit_admin_conference_campaign_path(conference1.short_title, conference1.campaigns.first) + expect(current_path).to eq(edit_admin_conference_campaign_path(conference1.short_title, conference1.campaigns.first)) + + visit admin_conference_targets_path(conference1.short_title) + expect(current_path).to eq(admin_conference_targets_path(conference1.short_title)) + + visit new_admin_conference_target_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_target_path(conference1.short_title)) + + create(:target, conference: conference1) + visit edit_admin_conference_target_path(conference1.short_title, conference1.targets.first) + expect(current_path).to eq(edit_admin_conference_target_path(conference1.short_title, conference1.targets.first)) + + visit admin_conference_program_tracks_path(conference1.short_title) + expect(current_path).to eq(admin_conference_program_tracks_path(conference1.short_title)) + + visit admin_conference_roles_path(conference1.short_title) + expect(current_path).to eq(admin_conference_roles_path(conference1.short_title)) + + visit admin_conference_emails_path(conference1.short_title) + expect(current_path).to eq(admin_conference_emails_path(conference1.short_title)) visit admin_conference_resources_path(conference1.short_title) expect(current_path).to eq(admin_conference_resources_path(conference1.short_title)) + visit new_admin_conference_resource_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_resource_path(conference1.short_title)) + + create(:resource, conference: conference1) + visit edit_admin_conference_resource_path(conference1.short_title, conference1.resources.first) + expect(current_path).to eq(edit_admin_conference_resource_path(conference1.short_title, conference1.resources.first)) + visit admin_revision_history_path expect(current_path).to eq(admin_revision_history_path) end @@ -127,72 +251,203 @@ feature 'Has correct abilities' do expect(page).to have_text('Basics') expect(page).to_not have_link('Contact', href: "/admin/conferences/#{conference2.short_title}/contact/edit") expect(page).to have_link('Commercials', href: "/admin/conferences/#{conference2.short_title}/commercials") - expect(page).to have_link('Events', href: "/admin/conferences/#{conference2.short_title}/program/events") - expect(page).to_not have_link('Registrations', href: "/admin/conferences/#{conference2.short_title}/registrations") - expect(page).to have_link('Schedules', href: "/admin/conferences/#{conference2.short_title}/schedules") - expect(page).to_not have_link('Campaigns', href: "/admin/conferences/#{conference2.short_title}/campaigns") - expect(page).to_not have_link('Goals', href: "/admin/conferences/#{conference2.short_title}/targets") + expect(page).to_not have_link('Splashpage', href: "/admin/conferences/#{conference2.short_title}/splashpage") expect(page).to have_link('Venue', href: "/admin/conferences/#{conference2.short_title}/venue") expect(page).to have_link('Rooms', href: "/admin/conferences/#{conference2.short_title}/venue/rooms") expect(page).to_not have_link('Lodgings', href: "/admin/conferences/#{conference2.short_title}/lodgings") - expect(page).to_not have_link('Sponsorship', href: "/admin/conferences/#{conference2.short_title}/sponsorship_levels") - expect(page).to_not have_link('Sponsors', href: "/admin/conferences/#{conference2.short_title}/sponsors") - expect(page).to_not have_link('Supporter Levels', href: "/admin/conferences/#{conference2.short_title}/supporter_levels") - expect(page).to have_link('E-Mails', href: "/admin/conferences/#{conference2.short_title}/emails") expect(page).to have_link('Program', href: "/admin/conferences/#{conference2.short_title}/program") expect(page).to have_link('Call for Papers', href: "/admin/conferences/#{conference2.short_title}/program/cfp") + expect(page).to have_link('Events', href: "/admin/conferences/#{conference2.short_title}/program/events") expect(page).to have_link('Tracks', href: "/admin/conferences/#{conference2.short_title}/program/tracks") expect(page).to have_link('Event Types', href: "/admin/conferences/#{conference2.short_title}/program/event_types") expect(page).to have_link('Difficulty Levels', href: "/admin/conferences/#{conference2.short_title}/program/difficulty_levels") + expect(page).to have_link('Schedules', href: "/admin/conferences/#{conference2.short_title}/schedules") + expect(page).to have_link('Reports', href: "/admin/conferences/#{conference2.short_title}/program/reports") + expect(page).to_not have_link('Registrations', href: "/admin/conferences/#{conference2.short_title}/registrations") + expect(page).to_not have_link('Registration Period', href: "/admin/conferences/#{conference2.short_title}/registration_period") expect(page).to_not have_link('Questions', href: "/admin/conferences/#{conference2.short_title}/questions") + expect(page).to_not have_text('Donations') + expect(page).to_not have_link('Sponsorship Levels', href: "/admin/conferences/#{conference2.short_title}/supporter_levels") + expect(page).to_not have_link('Sponsors', href: "/admin/conferences/#{conference2.short_title}/sponsors") + expect(page).to_not have_link('Tickets', href: "/admin/conferences/#{conference2.short_title}/tickets") + expect(page).to_not have_text('Objectives') + expect(page).to_not have_link('Campaigns', href: "/admin/conferences/#{conference2.short_title}/campaigns") + expect(page).to_not have_link('Goals', href: "/admin/conferences/#{conference2.short_title}/targets") + expect(page).to have_link('E-Mails', href: "/admin/conferences/#{conference2.short_title}/emails") expect(page).to have_link('Roles', href: "/admin/conferences/#{conference2.short_title}/roles") expect(page).to have_link('Resources', href: "/admin/conferences/#{conference2.short_title}/resources") visit edit_admin_conference_path(conference2.short_title) expect(current_path).to eq(root_path) - visit admin_conference_path(conference2.short_title) - expect(current_path).to eq(admin_conference_path(conference2.short_title)) - - visit admin_conference_registrations_path(conference2.short_title) - expect(current_path).to eq(admin_conference_registrations_path(conference2.short_title)) - - visit admin_conference_program_events_path(conference2.short_title) - expect(current_path).to eq(admin_conference_program_events_path(conference2.short_title)) - - visit admin_conference_schedules_path(conference2.short_title) - expect(current_path).to eq(admin_conference_schedules_path(conference2.short_title)) - - visit admin_conference_campaigns_path(conference2.short_title) - expect(current_path).to eq(root_path) - - visit admin_conference_targets_path(conference2.short_title) - expect(current_path).to eq(root_path) - - visit edit_admin_conference_venue_path(conference2.short_title) - expect(current_path).to eq(root_path) - - visit admin_conference_sponsorship_levels_path(conference2.short_title) - expect(current_path).to eq(root_path) - - visit admin_conference_tickets_path(conference2.short_title) - expect(current_path).to eq(root_path) - - visit admin_conference_emails_path(conference2.short_title) - expect(current_path).to eq(admin_conference_emails_path(conference2.short_title)) - - visit new_admin_conference_program_cfp_path(conference2.short_title) - expect(current_path).to eq(new_admin_conference_program_cfp_path(conference2.short_title)) - - visit admin_conference_questions_path(conference2.short_title) + visit edit_admin_conference_contact_path(conference2.short_title) expect(current_path).to eq(root_path) visit admin_conference_commercials_path(conference2.short_title) expect(current_path).to eq(root_path) + visit new_admin_conference_splashpage_path(conference2.short_title) + expect(current_path).to eq(root_path) + + visit edit_admin_conference_splashpage_path(conference2.short_title) + expect(current_path).to eq(root_path) + + visit new_admin_conference_venue_path(conference2.short_title) + expect(current_path).to eq(root_path) + + conference2.venue = create(:venue) + visit edit_admin_conference_venue_path(conference2.short_title) + expect(current_path).to eq(root_path) + + visit admin_conference_venue_rooms_path(conference2.short_title) + expect(current_path).to eq(admin_conference_venue_rooms_path(conference2.short_title)) + create(:room, venue: conference2.venue) + visit edit_admin_conference_venue_room_path(conference2.short_title, conference2.venue.rooms.first) + expect(current_path).to eq(edit_admin_conference_venue_room_path(conference2.short_title, conference2.venue.rooms.first)) + + visit admin_conference_lodgings_path(conference2.short_title) + expect(current_path).to eq(root_path) + + visit new_admin_conference_lodging_path(conference2.short_title) + expect(current_path).to eq(root_path) + + create(:lodging, conference: conference2) + visit edit_admin_conference_lodging_path(conference2.short_title, conference2.lodgings.first) + expect(current_path).to eq(root_path) + + visit new_admin_conference_program_path(conference2.short_title) + expect(current_path).to eq(new_admin_conference_program_path(conference2.short_title)) + + visit edit_admin_conference_program_path(conference2.short_title) + expect(current_path).to eq(edit_admin_conference_program_path(conference2.short_title)) + + visit new_admin_conference_program_cfp_path(conference2.short_title) + expect(current_path).to eq(new_admin_conference_program_cfp_path(conference2.short_title)) + + visit edit_admin_conference_program_cfp_path(conference2.short_title) + expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference2.short_title)) + + visit admin_conference_program_events_path(conference2.short_title) + expect(current_path).to eq(admin_conference_program_events_path(conference2.short_title)) + + create(:event, program: conference2.program) + visit edit_admin_conference_program_event_path(conference2.short_title, conference2.program.events.first) + expect(current_path).to eq(edit_admin_conference_program_event_path(conference2.short_title, conference2.program.events.first)) + + visit admin_conference_program_event_types_path(conference2.short_title) + expect(current_path).to eq(admin_conference_program_event_types_path(conference2.short_title)) + + visit new_admin_conference_program_event_type_path(conference2.short_title) + expect(current_path).to eq(new_admin_conference_program_event_type_path(conference2.short_title)) + + visit edit_admin_conference_program_event_type_path(conference2.short_title, conference2.program.event_types.first) + expect(current_path).to eq(edit_admin_conference_program_event_type_path(conference2.short_title, conference2.program.event_types.first)) + + visit admin_conference_program_difficulty_levels_path(conference2.short_title) + expect(current_path).to eq(admin_conference_program_difficulty_levels_path(conference2.short_title)) + + visit new_admin_conference_program_difficulty_level_path(conference2.short_title) + expect(current_path).to eq(new_admin_conference_program_difficulty_level_path(conference2.short_title)) + + visit edit_admin_conference_program_difficulty_level_path(conference2.short_title, conference2.program.difficulty_levels.first) + expect(current_path).to eq(edit_admin_conference_program_difficulty_level_path(conference2.short_title, conference2.program.difficulty_levels.first)) + + visit admin_conference_schedules_path(conference2.short_title) + expect(current_path).to eq(admin_conference_schedules_path(conference2.short_title)) + + create(:schedule, program: conference2.program) + visit admin_conference_schedule_path(conference2.short_title, conference2.program.schedules.first) + expect(current_path).to eq(admin_conference_schedule_path(conference2.short_title, conference2.program.schedules.first)) + + visit admin_conference_program_reports_path(conference2.short_title) + expect(current_path).to eq(admin_conference_program_reports_path(conference2.short_title)) + + visit admin_conference_registrations_path(conference2.short_title) + expect(current_path).to eq(admin_conference_registrations_path(conference2.short_title)) + + create(:registration, user: create(:user), conference: conference2) + visit edit_admin_conference_registration_path(conference2.short_title, conference2.registrations.first) + expect(current_path).to eq(root_path) + + visit new_admin_conference_registration_period_path(conference2.short_title) + expect(current_path).to eq(root_path) + + create(:registration_period, conference: conference2) + visit edit_admin_conference_registration_period_path(conference2.short_title) + expect(current_path).to eq(root_path) + + visit admin_conference_questions_path(conference2.short_title) + expect(current_path).to eq(root_path) + + visit admin_conference_sponsorship_levels_path(conference2.short_title) + expect(current_path).to eq(root_path) + + visit new_admin_conference_sponsorship_level_path(conference2.short_title) + expect(current_path).to eq(root_path) + + create(:sponsorship_level, conference: conference2) + visit edit_admin_conference_sponsorship_level_path(conference2.short_title, conference2.sponsorship_levels.first) + expect(current_path).to eq(root_path) + + visit admin_conference_sponsors_path(conference2.short_title) + expect(current_path).to eq(root_path) + + visit new_admin_conference_sponsor_path(conference2.short_title) + expect(current_path).to eq(root_path) + + create(:sponsor, conference: conference2, sponsorship_level: conference2.sponsorship_levels.first) + visit edit_admin_conference_sponsor_path(conference2.short_title, conference2.sponsors.first) + expect(current_path).to eq(root_path) + + visit admin_conference_tickets_path(conference2.short_title) + expect(current_path).to eq(root_path) + + visit new_admin_conference_ticket_path(conference2.short_title) + expect(current_path).to eq(root_path) + + create(:ticket, conference: conference2) + visit edit_admin_conference_ticket_path(conference2.short_title, conference2.tickets.first) + expect(current_path).to eq(root_path) + + visit admin_conference_campaigns_path(conference2.short_title) + expect(current_path).to eq(root_path) + + visit new_admin_conference_campaign_path(conference2.short_title) + expect(current_path).to eq(root_path) + + create(:campaign, conference: conference2) + visit edit_admin_conference_campaign_path(conference2.short_title, conference2.campaigns.first) + expect(current_path).to eq(root_path) + + visit admin_conference_targets_path(conference2.short_title) + expect(current_path).to eq(root_path) + + visit new_admin_conference_target_path(conference2.short_title) + expect(current_path).to eq(root_path) + + create(:target, conference: conference2) + visit edit_admin_conference_target_path(conference2.short_title, conference2.targets.first) + expect(current_path).to eq(root_path) + + visit admin_conference_program_tracks_path(conference2.short_title) + expect(current_path).to eq(admin_conference_program_tracks_path(conference2.short_title)) + + visit admin_conference_roles_path(conference2.short_title) + expect(current_path).to eq(admin_conference_roles_path(conference2.short_title)) + + visit admin_conference_emails_path(conference2.short_title) + expect(current_path).to eq(admin_conference_emails_path(conference2.short_title)) + visit admin_conference_resources_path(conference2.short_title) expect(current_path).to eq(admin_conference_resources_path(conference2.short_title)) + visit new_admin_conference_resource_path(conference2.short_title) + expect(current_path).to eq(new_admin_conference_resource_path(conference2.short_title)) + + create(:resource, conference: conference2) + visit edit_admin_conference_resource_path(conference2.short_title, conference2.resources.first) + expect(current_path).to eq(edit_admin_conference_resource_path(conference2.short_title, conference2.resources.first)) + visit admin_revision_history_path expect(current_path).to eq(root_path) end @@ -204,89 +459,209 @@ feature 'Has correct abilities' do expect(current_path).to eq(admin_conference_path(conference3.short_title)) expect(page).to have_selector('li.nav-header.nav-header-bigger a', text: 'Dashboard') - expect(page).to_not have_link('Basics', href: "/admin/conferences/#{conference2.short_title}/edit") + expect(page).to_not have_link('Basics', href: "/admin/conferences/#{conference3.short_title}/edit") expect(page).to have_text('Basics') expect(page).to_not have_link('Contact', href: "/admin/conferences/#{conference3.short_title}/contact/edit") expect(page).to have_link('Commercials', href: "/admin/conferences/#{conference3.short_title}/commercials") - expect(page).to_not have_link('Events', href: "/admin/conferences/#{conference3.short_title}/program/events") - expect(page).to have_link('Registrations', href: "/admin/conferences/#{conference3.short_title}/registrations") - expect(page).to_not have_link('Schedules', href: "/admin/conferences/#{conference3.short_title}/schedules") - expect(page).to_not have_link('Campaigns', href: "/admin/conferences/#{conference3.short_title}/campaigns") - expect(page).to_not have_link('Targets', href: "/admin/conferences/#{conference3.short_title}/targets") + expect(page).to_not have_link('Splashpage', href: "/admin/conferences/#{conference3.short_title}/splashpage") expect(page).to_not have_link('Venue', href: "/admin/conferences/#{conference3.short_title}/venue") expect(page).to_not have_link('Rooms', href: "/admin/conferences/#{conference3.short_title}/venue/rooms") expect(page).to_not have_link('Lodgings', href: "/admin/conferences/#{conference3.short_title}/lodgings") - expect(page).to_not have_link('Sponsorship', href: "/admin/conferences/#{conference3.short_title}/sponsorship_levels") - expect(page).to_not have_link('Sponsors', href: "/admin/conferences/#{conference3.short_title}/sponsors") - expect(page).to_not have_link('Supporter Levels', href: "/admin/conferences/#{conference3.short_title}/supporter_levels") - expect(page).to_not have_link('E-Mails', href: "/admin/conferences/#{conference3.short_title}/emails") expect(page).to_not have_link('Program', href: "/admin/conferences/#{conference3.short_title}/program") - expect(page).to_not have_link('Call for papers', href: "/admin/conferences/#{conference3.short_title}/program/cfp") + expect(page).to_not have_link('Call for Papers', href: "/admin/conferences/#{conference2.short_title}/program/cfp") + expect(page).to_not have_link('Events', href: "/admin/conferences/#{conference3.short_title}/program/events") expect(page).to_not have_link('Tracks', href: "/admin/conferences/#{conference3.short_title}/program/tracks") - expect(page).to_not have_link('Event types', href: "/admin/conferences/#{conference3.short_title}/program/event_types") - expect(page).to_not have_link('Difficulty levels', href: "/admin/conferences/#{conference3.short_title}/program/difficulty_levels") + expect(page).to_not have_link('Event Types', href: "/admin/conferences/#{conference3.short_title}/program/event_types") + expect(page).to_not have_link('Difficulty Levels', href: "/admin/conferences/#{conference3.short_title}/program/difficulty_levels") + expect(page).to_not have_link('Schedules', href: "/admin/conferences/#{conference3.short_title}/schedules") + expect(page).to_not have_link('Reports', href: "/admin/conferences/#{conference3.short_title}/program/reports") + expect(page).to have_link('Registrations', href: "/admin/conferences/#{conference3.short_title}/registrations") + expect(page).to_not have_link('Registration Period', href: "/admin/conferences/#{conference3.short_title}/registration_period") expect(page).to have_link('Questions', href: "/admin/conferences/#{conference3.short_title}/questions") + expect(page).to_not have_text('Donations') + expect(page).to_not have_link('Sponsorship Levels', href: "/admin/conferences/#{conference3.short_title}/sponsorship_levels") + expect(page).to_not have_link('Sponsors', href: "/admin/conferences/#{conference3.short_title}/sponsors") + expect(page).to_not have_link('Tickets', href: "/admin/conferences/#{conference3.short_title}/tickets") + expect(page).to_not have_text('Objectives') + expect(page).to_not have_link('Campaigns', href: "/admin/conferences/#{conference3.short_title}/campaigns") + expect(page).to_not have_link('Goals', href: "/admin/conferences/#{conference3.short_title}/targets") + expect(page).to_not have_link('E-Mails', href: "/admin/conferences/#{conference3.short_title}/emails") expect(page).to have_link('Roles', href: "/admin/conferences/#{conference3.short_title}/roles") expect(page).to have_link('Resources', href: "/admin/conferences/#{conference3.short_title}/resources") visit edit_admin_conference_path(conference3.short_title) expect(current_path).to eq(root_path) - visit admin_conference_path(conference3.short_title) - expect(current_path).to eq(admin_conference_path(conference3.short_title)) - - visit admin_conference_registrations_path(conference3.short_title) - expect(current_path).to eq(admin_conference_registrations_path(conference3.short_title)) - - visit admin_conference_program_events_path(conference3.short_title) + visit edit_admin_conference_contact_path(conference3.short_title) expect(current_path).to eq(root_path) - visit admin_conference_schedules_path(conference3.short_title) + visit admin_conference_commercials_path(conference3.short_title) expect(current_path).to eq(root_path) - visit admin_conference_campaigns_path(conference3.short_title) + visit new_admin_conference_splashpage_path(conference3.short_title) expect(current_path).to eq(root_path) - visit admin_conference_targets_path(conference3.short_title) + visit edit_admin_conference_splashpage_path(conference3.short_title) expect(current_path).to eq(root_path) + visit new_admin_conference_venue_path(conference3.short_title) + expect(current_path).to eq(root_path) + + conference3.venue = create(:venue) visit edit_admin_conference_venue_path(conference3.short_title) expect(current_path).to eq(root_path) - visit admin_conference_sponsorship_levels_path(conference3.short_title) + visit admin_conference_venue_rooms_path(conference3.short_title) expect(current_path).to eq(root_path) - visit admin_conference_tickets_path(conference3.short_title) + create(:room, venue: conference3.venue) + visit edit_admin_conference_venue_room_path(conference3.short_title, conference3.venue.rooms.first) expect(current_path).to eq(root_path) - visit admin_conference_emails_path(conference3.short_title) + visit admin_conference_lodgings_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit new_admin_conference_lodging_path(conference3.short_title) + expect(current_path).to eq(root_path) + + create(:lodging, conference: conference3) + visit edit_admin_conference_lodging_path(conference3.short_title, conference3.lodgings.first) + expect(current_path).to eq(root_path) + + visit new_admin_conference_program_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit edit_admin_conference_program_path(conference3.short_title) expect(current_path).to eq(root_path) visit new_admin_conference_program_cfp_path(conference3.short_title) expect(current_path).to eq(root_path) + visit edit_admin_conference_program_cfp_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit admin_conference_program_events_path(conference3.short_title) + expect(current_path).to eq(root_path) + + create(:event, program: conference3.program) + visit edit_admin_conference_program_event_path(conference3.short_title, conference3.program.events.first) + expect(current_path).to eq(root_path) + + visit admin_conference_program_event_types_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit new_admin_conference_program_event_type_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit edit_admin_conference_program_event_type_path(conference3.short_title, conference3.program.event_types.first) + expect(current_path).to eq(root_path) + + visit admin_conference_program_difficulty_levels_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit new_admin_conference_program_difficulty_level_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit edit_admin_conference_program_difficulty_level_path(conference3.short_title, conference3.program.difficulty_levels.first) + expect(current_path).to eq(root_path) + + visit admin_conference_schedules_path(conference3.short_title) + expect(current_path).to eq(root_path) + + create(:schedule, program: conference3.program) + visit admin_conference_schedule_path(conference3.short_title, conference3.program.schedules.first) + expect(current_path).to eq(root_path) + + visit admin_conference_program_reports_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit admin_conference_registrations_path(conference3.short_title) + expect(current_path).to eq(admin_conference_registrations_path(conference3.short_title)) + + create(:registration, user: create(:user), conference: conference3) + visit edit_admin_conference_registration_path(conference3.short_title, conference3.registrations.first) + expect(current_path).to eq(edit_admin_conference_registration_path(conference3.short_title, conference3.registrations.first)) + + visit new_admin_conference_registration_period_path(conference3.short_title) + expect(current_path).to eq(root_path) + + create(:registration_period, conference: conference3) + visit edit_admin_conference_registration_period_path(conference3.short_title) + expect(current_path).to eq(root_path) + visit admin_conference_questions_path(conference3.short_title) expect(current_path).to eq(admin_conference_questions_path(conference3.short_title)) - visit admin_conference_commercials_path(conference3.short_title) + visit admin_conference_sponsorship_levels_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit new_admin_conference_sponsorship_level_path(conference3.short_title) + expect(current_path).to eq(root_path) + + create(:sponsorship_level, conference: conference3) + visit edit_admin_conference_sponsorship_level_path(conference3.short_title, conference3.sponsorship_levels.first) + expect(current_path).to eq(root_path) + + visit admin_conference_sponsors_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit new_admin_conference_sponsor_path(conference3.short_title) + expect(current_path).to eq(root_path) + + create(:sponsor, conference: conference3, sponsorship_level: conference3.sponsorship_levels.first) + visit edit_admin_conference_sponsor_path(conference3.short_title, conference3.sponsors.first) + expect(current_path).to eq(root_path) + + visit admin_conference_tickets_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit new_admin_conference_ticket_path(conference3.short_title) + expect(current_path).to eq(root_path) + + create(:ticket, conference: conference3) + visit edit_admin_conference_ticket_path(conference3.short_title, conference3.tickets.first) + expect(current_path).to eq(root_path) + + visit admin_conference_campaigns_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit new_admin_conference_campaign_path(conference3.short_title) + expect(current_path).to eq(root_path) + + create(:campaign, conference: conference3) + visit edit_admin_conference_campaign_path(conference3.short_title, conference3.campaigns.first) + expect(current_path).to eq(root_path) + + visit admin_conference_targets_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit new_admin_conference_target_path(conference3.short_title) + expect(current_path).to eq(root_path) + + create(:target, conference: conference3) + visit edit_admin_conference_target_path(conference3.short_title, conference3.targets.first) + expect(current_path).to eq(root_path) + + visit admin_conference_program_tracks_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit admin_conference_roles_path(conference3.short_title) + expect(current_path).to eq(admin_conference_roles_path(conference3.short_title)) + + visit admin_conference_emails_path(conference3.short_title) expect(current_path).to eq(root_path) visit admin_conference_resources_path(conference3.short_title) expect(current_path).to eq(admin_conference_resources_path(conference3.short_title)) + visit new_admin_conference_resource_path(conference3.short_title) + expect(current_path).to eq(new_admin_conference_resource_path(conference3.short_title)) + + create(:resource, conference: conference3) + visit edit_admin_conference_resource_path(conference3.short_title, conference3.resources.first) + expect(current_path).to eq(edit_admin_conference_resource_path(conference3.short_title, conference3.resources.first)) + visit admin_revision_history_path expect(current_path).to eq(root_path) end - - scenario 'when user is volunteers_coordinator' do - sign_in user_volunteers_coordinator - - visit admin_conference_path(conference4.short_title) - expect(current_path).to eq(admin_conference_path(conference4.short_title)) - - expect(page).to have_link('Resources', href: "/admin/conferences/#{conference4.short_title}/resources") - - visit admin_conference_resources_path(conference4.short_title) - expect(current_path).to eq(admin_conference_resources_path(conference4.short_title)) - end end From 3ead7ef586b488d07809f2676ddd5cf12ede4fee Mon Sep 17 00:00:00 2001 From: gotens1211 Date: Mon, 17 Apr 2017 17:40:23 +0530 Subject: [PATCH 029/185] Removed the extra condition for displaying the first speaker image Removed the if statement in schedule_item.html.haml file which was generating an extra img_tag for the first speaker Fixes #1454 --- app/views/schedules/_schedule_item.html.haml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/views/schedules/_schedule_item.html.haml b/app/views/schedules/_schedule_item.html.haml index d475ec80..b6d8708e 100644 --- a/app/views/schedules/_schedule_item.html.haml +++ b/app/views/schedules/_schedule_item.html.haml @@ -9,11 +9,6 @@ = event.title - - if speaker = event.speakers.first - = image_tag speaker.gravatar_url, class: "img-circle pull-right speaker-pic", | - alt: speaker.name, | - title: speaker.name, | - style: "height: #{ speaker_height(@rooms) }px; width: #{ speaker_width(@rooms) }px;" - event.speakers_ordered.each do |speaker| = image_tag speaker.gravatar_url, :class => "img-circle pull-right speaker-pic", | :alt => speaker.name, | From cd9f329939247d35b7c7e8c96dc6d1190e3ec455 Mon Sep 17 00:00:00 2001 From: Siddhant Bajaj Date: Tue, 18 Apr 2017 18:30:42 +0530 Subject: [PATCH 030/185] Fixed Confirmed Scheduled Events issue Fixed issues with scheduled_event_distribution method in conference.rb and added test in conference_spec.rb to confirm issue is fixed. Fixes #1302 --- app/models/conference.rb | 7 ++++--- spec/models/conference_spec.rb | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/app/models/conference.rb b/app/models/conference.rb index aa73e5d4..f4d55d2e 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -311,9 +311,10 @@ class Conference < ActiveRecord::Base # ====Returns # * +hash+ -> hash def scheduled_event_distribution - confirmed_events = program.events.where(state: 'confirmed') - scheduled_value = { 'value' => confirmed_events.where.not(start_time: nil).count, 'color' => 'green' } - unscheduled_value = { 'value' => confirmed_events.where(start_time: nil).count, 'color' => 'red' } + confirmed_scheduled_events = program.events.confirmed.scheduled(program.selected_schedule.try(:id)) + confirmed_unscheduled_events = program.events.confirmed - confirmed_scheduled_events + scheduled_value = { 'value' => confirmed_scheduled_events.count, 'color' => 'green' } + unscheduled_value = { 'value' => confirmed_unscheduled_events.count, 'color' => 'red' } { 'Scheduled' => scheduled_value, 'Unscheduled' => unscheduled_value } end diff --git a/spec/models/conference_spec.rb b/spec/models/conference_spec.rb index edb719e5..47d64164 100755 --- a/spec/models/conference_spec.rb +++ b/spec/models/conference_spec.rb @@ -778,6 +778,28 @@ describe Conference do end end + describe '#scheduled_event_distribution' do + let(:conference) { create(:conference) } + let(:confirmed_unscheduled_event) { create(:event, program: conference.program, state: 'confirmed') } + let(:confirmed_scheduled_event) { create(:event_scheduled, program: conference.program) } + + it '#scheduled_event_distribution does calculate correct values with events' do + confirmed_unscheduled_event + confirmed_scheduled_event + result = {} + result['Scheduled'] = { 'value' => 1, 'color' => 'green' } + result['Unscheduled'] = { 'value' => 1, 'color' => 'red' } + expect(conference.scheduled_event_distribution).to eq(result) + end + + it '#scheduled_event_distribution does calculate correct values with no events' do + result = {} + result['Scheduled'] = { 'value' => 0, 'color' => 'green' } + result['Unscheduled'] = { 'value' => 0, 'color' => 'red' } + expect(conference.scheduled_event_distribution).to eq(result) + end + end + describe '#event_distribution' do before(:each) do From c27ab2d4a99546ddae701131e732b152728671d3 Mon Sep 17 00:00:00 2001 From: Agrim Mittal Date: Wed, 12 Apr 2017 20:21:44 +0530 Subject: [PATCH 031/185] update to rubocop v0.48.1 Updated other gems(nokogiri rails-dom-testing) to be able to update rubocop --- Gemfile | 2 +- Gemfile.lock | 35 ++++++++++++++++------------------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/Gemfile b/Gemfile index f1c77a63..1b882aab 100644 --- a/Gemfile +++ b/Gemfile @@ -202,7 +202,7 @@ group :development do gem 'guard-rspec', '~> 4.2.8' gem 'spring-commands-rspec' # for static code analisys - gem 'rubocop', require: false + gem 'rubocop', '~> 0.48.1', require: false # as database gem 'sqlite3' # to open mails diff --git a/Gemfile.lock b/Gemfile.lock index 581e0d4c..3bc396d4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -58,7 +58,7 @@ GEM user_agent_parser uuidtools arel (6.0.3) - ast (2.2.0) + ast (2.3.0) autoprefixer-rails (5.1.9) execjs json @@ -230,7 +230,7 @@ GEM thor (>= 0.14, < 2.0) jquery-ui-rails (4.2.1) railties (>= 3.2.16) - json (1.8.3) + json (1.8.6) json-schema (2.5.0) addressable (~> 2.3) jwt (1.0.0) @@ -261,7 +261,7 @@ GEM rake mini_magick (4.5.1) mini_portile2 (2.1.0) - minitest (5.9.0) + minitest (5.10.1) momentjs-rails (2.8.1) railties (>= 3.1) monetize (1.4.0) @@ -282,7 +282,6 @@ GEM nio4r (1.2.1) nokogiri (1.7.1) mini_portile2 (~> 2.1.0) - pkg-config (~> 1.1.7) oauth2 (0.9.4) faraday (>= 0.8, < 0.10) jwt (~> 1.0) @@ -314,7 +313,7 @@ GEM activerecord (>= 3.0, < 6.0) activesupport (>= 3.0, < 6.0) request_store (~> 1.1) - parser (2.3.0.3) + parser (2.4.0.0) ast (~> 2.2) pdf-core (0.2.5) phantomjs (2.1.1.0) @@ -322,7 +321,6 @@ GEM actionpack activesupport rails (>= 3.0.0) - pkg-config (1.1.7) poltergeist (1.9.0) capybara (~> 2.1) cliver (~> 0.3.1) @@ -375,9 +373,9 @@ GEM rails-assets-waypoints (4.0.0) rails-deprecated_sanitizer (1.0.3) activesupport (>= 4.2.0.alpha) - rails-dom-testing (1.0.7) + rails-dom-testing (1.0.8) activesupport (>= 4.2.0.beta, < 5.0) - nokogiri (~> 1.6.0) + nokogiri (~> 1.6) rails-deprecated_sanitizer (>= 1.0.1) rails-html-sanitizer (1.0.3) loofah (~> 2.0) @@ -396,7 +394,7 @@ GEM activesupport (= 4.2.7.1) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) - rainbow (2.1.0) + rainbow (2.2.1) rake (10.5.0) rb-fsevent (0.9.4) rb-inotify (0.9.4) @@ -442,15 +440,15 @@ GEM rspec-mocks (~> 3.0.0) rspec-support (~> 3.0.0) rspec-support (3.0.2) - rubocop (0.37.0) - parser (>= 2.3.0.2, < 3.0) + rubocop (0.48.1) + parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.7) - unicode-display_width (~> 0.3) + unicode-display_width (~> 1.0, >= 1.0.1) ruby-oembed (0.8.14) ruby-openid (2.5.0) - ruby-progressbar (1.7.5) + ruby-progressbar (1.8.1) rubyzip (1.2.1) safe_yaml (1.0.4) sass (3.2.19) @@ -493,7 +491,7 @@ GEM term-ansicolor (1.3.2) tins (~> 1.0) thor (0.19.1) - thread_safe (0.3.5) + thread_safe (0.3.6) tilt (1.4.1) timecop (0.7.1) timers (1.1.0) @@ -502,14 +500,14 @@ GEM ttfunk (1.1.1) turbolinks (2.5.3) coffee-rails - tzinfo (1.2.2) + tzinfo (1.2.3) thread_safe (~> 0.1) uglifier (3.0.0) execjs (>= 0.3.0, < 3) unf (0.1.4) unf_ext unf_ext (0.0.7.2) - unicode-display_width (0.3.1) + unicode-display_width (1.2.1) unicode_utils (1.4.0) unobtrusive_flash (3.1.0) railties @@ -619,7 +617,7 @@ DEPENDENCIES rolify rspec-activemodel-mocks rspec-rails - rubocop + rubocop (~> 0.48.1) ruby-oembed sass-rails (>= 4.0.2) selectize-rails @@ -639,5 +637,4 @@ DEPENDENCIES whenever BUNDLED WITH - 1.14.3 - + 1.14.5 From 7a10d69f1499cafdeaff157025382ab77bbc3449 Mon Sep 17 00:00:00 2001 From: Agrim Mittal Date: Thu, 13 Apr 2017 00:00:02 +0530 Subject: [PATCH 032/185] regenerate rubocop_todo Automatically generated using --auto-gen-config --- .rubocop_todo.yml | 641 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 488 insertions(+), 153 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 330eb3cd..c2122773 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,11 +1,42 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2016-02-08 14:42:45 +0100 using RuboCop version 0.37.0. +# on 2017-04-21 21:35:17 +0530 using RuboCop version 0.48.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 +# Cop supports --auto-correct. +# Configuration parameters: Include, TreatCommentsAsGroupSeparators. +# Include: **/Gemfile, **/gems.rb +Bundler/OrderedGems: + Exclude: + - 'Gemfile' + +# Offense count: 28 +Lint/AmbiguousBlockAssociation: + 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' + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyleAlignWith, SupportedStylesAlignWith. +# SupportedStylesAlignWith: either, start_of_block, start_of_line +Lint/BlockAlignment: + Exclude: + - 'lib/tasks/demo_data_for_development.rake' + # Offense count: 2 Lint/DuplicatedKey: Exclude: @@ -18,21 +49,33 @@ Lint/IneffectiveAccessModifier: - 'app/models/commercial.rb' - 'app/models/conference.rb' -# Offense count: 84 +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments. +Lint/UnusedBlockArgument: + Exclude: + - 'lib/tasks/user.rake' + +# Offense count: 106 Metrics/AbcSize: Max: 75 -# Offense count: 12 +# Offense count: 225 +# Configuration parameters: CountComments, ExcludedMethods. +Metrics/BlockLength: + Max: 1364 + +# Offense count: 19 Metrics/CyclomaticComplexity: Max: 12 -# Offense count: 956 -# Configuration parameters: AllowHeredoc, AllowURI, URISchemes. +# Offense count: 1967 +# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. # URISchemes: http, https Metrics/LineLength: - Max: 208 + Max: 619 -# Offense count: 100 +# Offense count: 115 # Configuration parameters: CountComments. Metrics/MethodLength: Max: 56 @@ -40,15 +83,13 @@ Metrics/MethodLength: # Offense count: 1 # Configuration parameters: CountComments. Metrics/ModuleLength: - Max: 256 - Exclude: - - 'app/helpers/application_helper.rb' + Max: 472 -# Offense count: 7 +# Offense count: 14 Metrics/PerceivedComplexity: Max: 15 -# Offense count: 13 +# Offense count: 11 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, Include. # SupportedStyles: action, filter @@ -57,17 +98,24 @@ Rails/ActionFilter: Exclude: - 'app/controllers/admin/base_controller.rb' - 'app/controllers/admin/registrations_controller.rb' - - 'app/controllers/admin/schedules_controller.rb' - 'app/controllers/application_controller.rb' - - 'app/controllers/conference_controller.rb' - 'app/controllers/conference_registrations_controller.rb' - - 'app/controllers/proposal_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: 101 +# Offense count: 9 +# Cop supports --auto-correct. +# Configuration parameters: NilOrEmpty, NotPresent, UnlessPresent. +Rails/Blank: + Exclude: + - 'app/models/program.rb' + - 'app/models/user.rb' + - 'lib/tasks/update_resource_quantity.rake' + - 'spec/factories/event_schedule.rb' + +# Offense count: 140 # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: strict, flexible Rails/Date: @@ -79,7 +127,23 @@ Rails/Delegate: Exclude: - 'app/serializers/speaker_serializer.rb' -# Offense count: 10 +# 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 @@ -88,7 +152,6 @@ Rails/FindBy: - 'app/models/conference.rb' - 'app/models/event.rb' - 'app/models/openid.rb' - - 'app/models/ticket.rb' - 'app/models/ticket_purchase.rb' - 'app/models/user.rb' @@ -100,35 +163,87 @@ Rails/FindEach: Exclude: - 'app/models/conference.rb' -# Offense count: 12 +# Offense count: 7 # Configuration parameters: Include. # Include: app/models/**/*.rb Rails/HasAndBelongsToMany: Exclude: - 'app/models/conference.rb' - - 'app/models/event.rb' - 'app/models/qanswer.rb' - 'app/models/question.rb' - 'app/models/registration.rb' - - 'app/models/role.rb' - - 'app/models/social_event.rb' - - 'app/models/user.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/application_helper.rb' + - 'app/models/commercial.rb' + # Offense count: 10 # Cop supports --auto-correct. Rails/PluralizationGrammar: Exclude: - 'spec/models/conference_spec.rb' -# Offense count: 47 +# Offense count: 22 +# Cop supports --auto-correct. +# Configuration parameters: NotNilAndNotEmpty, NotBlank, UnlessBlank. +Rails/Present: + Exclude: + - 'app/helpers/application_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/helpers/application_helper.rb' - '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' @@ -145,13 +260,20 @@ Style/AccessorMethodName: - 'app/models/target.rb' - 'app/models/user.rb' -# Offense count: 4 +# 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/helpers/application_helper.rb' - 'app/models/email_settings.rb' - 'app/models/revision_observer.rb' @@ -160,13 +282,12 @@ Style/ClassVars: Exclude: - 'spec/support/kneet_connections.rb' -# Offense count: 6 +# Offense count: 5 # Cop supports --auto-correct. Style/ClosingParenthesisIndentation: Exclude: - 'app/controllers/conference_registrations_controller.rb' - 'spec/support/omniauth_macros.rb' - - 'spec/views/admin/sponsors/index.html.haml_spec.rb' # Offense count: 2 # Cop supports --auto-correct. @@ -183,36 +304,28 @@ Style/CommentAnnotation: Exclude: - 'app/models/event_user.rb' -# Offense count: 17 +# Offense count: 14 # Cop supports --auto-correct. Style/CommentIndentation: Exclude: - 'app/controllers/admin/comments_controller.rb' - 'app/controllers/admin/difficulty_levels_controller.rb' - - 'app/controllers/admin/programs_controller.rb' - - 'app/models/ahoy/program.rb' - 'app/models/conference.rb' - 'app/models/program.rb' - 'app/models/track.rb' - 'spec/features/volunteers_spec.rb' -# Offense count: 7 +# Offense count: 3 # Cop supports --auto-correct. -# Configuration parameters: SingleLineConditionsOnly. +# Configuration parameters: EnforcedStyle, SupportedStyles, SingleLineConditionsOnly, IncludeTernaryExpressions. +# SupportedStyles: assign_to_condition, assign_inside_condition Style/ConditionalAssignment: Exclude: - - 'app/controllers/admin/schedules_controller.rb' - - 'app/controllers/admin/volunteers_controller.rb' - - 'app/controllers/conference_controller.rb' - - 'app/controllers/conference_registrations_controller.rb' - - 'app/controllers/admin/conference_controller.rb' - 'app/helpers/application_helper.rb' - - 'app/models/ticket_purchase.rb' - - 'app/models/conference.rb' - 'db/migrate/20140610165551_migrate_data_person_to_user.rb' - 'db/migrate/20140820124117_undo_wrong_migration20140801080705_add_users_to_events.rb' -# Offense count: 366 +# Offense count: 429 Style/Documentation: Enabled: false @@ -222,46 +335,73 @@ Style/ElseAlignment: Exclude: - 'app/helpers/application_helper.rb' +# Offense count: 2 +# Cop supports --auto-correct. +Style/EmptyCaseCondition: + Exclude: + - 'app/helpers/application_helper.rb' + # Offense count: 1 # Cop supports --auto-correct. -# Configuration parameters: AllowAdjacentOneLineDefs. -Style/EmptyLineBetweenDefs: +Style/EmptyLineAfterMagicComment: Exclude: - - 'app/models/call_for_paper.rb' + - 'spec/models/conference_spec.rb' -# Offense count: 98 +# Offense count: 107 # 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: Exclude: - 'spec/models/conference_spec.rb' -# Offense count: 17 +# Offense count: 9 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: compact, expanded +Style/EmptyMethod: + Exclude: + - 'app/controllers/admin/lodgings_controller.rb' + - 'app/controllers/admin/registration_periods_controller.rb' + - 'app/controllers/users_controller.rb' + - 'db/migrate/20121223115125_create_tracks_table.rb' + - 'db/migrate/20121223115135_create_events_table.rb' + - 'db/migrate/20130103134212_create_registrations_table.rb' + - '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/conference_registrations_controller.rb' - - 'app/models/conference.rb' - - 'app/models/event.rb' - - 'app/models/target.rb' - - 'app/models/ticket.rb' - - 'bin/rails' + - '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/controllers/conference_controller_spec.rb' - - 'spec/factories/splashpages.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 +Style/FileName: + Exclude: + - 'Gemfile' + - 'Vagrantfile' + # Offense count: 38 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. @@ -269,64 +409,78 @@ Style/ExtraSpacing: Style/FirstParameterIndentation: Enabled: false -# Offense count: 6 +# Offense count: 22 # Configuration parameters: MinBodyLength. Style/GuardClause: Exclude: - - 'app/helpers/application_helper.rb' - - 'app/models/commercial.rb' - - 'app/models/conference.rb' - - 'app/models/user.rb' - - 'app/models/registration.rb' - - 'app/models/ticket.rb' - - 'app/serializers/conference_serializer.rb' + - 'app/controllers/admin/questions_controller.rb' - 'app/controllers/conference_registrations_controller.rb' - 'app/controllers/tickets_controller.rb' - - 'app/controllers/admin/questions_controller.rb' - -# Offense count: 14 -Style/IdenticalConditionalBranches: - Exclude: - - 'app/controllers/admin/campaigns_controller.rb' - - 'app/controllers/admin/difficulty_levels_controller.rb' - - 'app/controllers/admin/event_types_controller.rb' - - 'app/controllers/admin/rooms_controller.rb' - - 'app/controllers/admin/tracks_controller.rb' - - 'app/controllers/subscriptions_controller.rb' - -# Offense count: 1 -Style/IfInsideElse: - Exclude: - 'app/helpers/application_helper.rb' + - 'app/models/ability.rb' + - 'app/models/cfp.rb' + - 'app/models/commercial.rb' + - 'app/models/conference.rb' + - 'app/models/registration.rb' + - 'app/models/ticket.rb' + - 'app/models/user.rb' + - 'app/serializers/conference_serializer.rb' + - 'db/migrate/20140820124117_undo_wrong_migration20140801080705_add_users_to_events.rb' + - 'lib/tasks/data.rake' -# Offense count: 29 +# Offense count: 4 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols. +# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys +Style/HashSyntax: + Exclude: + - 'Gemfile' + - 'lib/tasks/user.rake' + +# Offense count: 23 # Cop supports --auto-correct. # Configuration parameters: MaxLineLength. Style/IfUnlessModifier: - Enabled: false + Exclude: + - 'app/controllers/admin/events_controller.rb' + - 'app/controllers/api/v1/events_controller.rb' + - 'app/controllers/conference_registrations_controller.rb' + - 'app/controllers/users/omniauth_callbacks_controller.rb' + - 'app/helpers/application_helper.rb' + - 'app/models/commercial.rb' + - 'app/models/conference.rb' + - 'app/models/ticket_purchase.rb' + - 'app/models/user.rb' + - 'db/migrate/20151031092713_change_conference_id_to_venue_id_in_rooms.rb' + - 'lib/tasks/events_registrations.rake' + - 'spec/controllers/admin/conferences_controller_spec.rb' + - 'spec/features/omniauth_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: - Enabled: false + Exclude: + - 'app/models/conference.rb' -# Offense count: 5 +# Offense count: 2 # Cop supports --auto-correct. # Configuration parameters: IndentationWidth. Style/IndentAssignment: Exclude: - 'app/helpers/application_helper.rb' - - 'app/models/ability.rb' - 'app/models/conference.rb' -# Offense count: 4 +# Offense count: 3 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. # SupportedStyles: special_inside_parentheses, consistent, align_braces Style/IndentHash: - Enabled: false + Exclude: + - 'app/models/user.rb' + - 'db/migrate/20140701123203_add_events_per_week_to_conference.rb' # Offense count: 3 # Cop supports --auto-correct. @@ -338,27 +492,16 @@ Style/IndentationConsistency: - 'app/models/event.rb' - 'spec/controllers/subscriptions_controller_spec.rb' -# Offense count: 10 +# Offense count: 7 # Cop supports --auto-correct. -# Configuration parameters: Width. +# Configuration parameters: Width, IgnoredPatterns. Style/IndentationWidth: Exclude: - 'app/helpers/application_helper.rb' - - 'db/migrate/20140701123203_add_events_per_week_to_conference.rb' - - 'db/migrate/20141031225545_add_require_handicapped_access_to_questions.rb' - - 'db/migrate/20141031225606_add_attending_with_partner_to_questions.rb' - - 'db/migrate/20141031225620_add_staying_at_suggested_hotel_to_questions.rb' - - 'db/migrate/20141031225635_add_attending_social_events_to_questions.rb' - - 'db/migrate/20141118162030_change_lodging_association_to_conference.rb' - - 'spec/features/event_types_spec.rb' - - 'spec/models/ability_spec.rb' - 'app/serializers/conference_serializer.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Style/InfiniteLoop: - Exclude: - - 'app/models/datatable.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. @@ -375,12 +518,23 @@ Style/LineEndConcatenation: - 'spec/features/conference_spec.rb' - 'spec/features/registration_periods_spec.rb' -# Offense count: 7 +# Offense count: 6 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: require_parentheses, require_no_parentheses, require_no_parentheses_except_multiline Style/MethodDefParentheses: - Enabled: false + Exclude: + - 'app/models/conference.rb' + - '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. @@ -388,45 +542,114 @@ Style/MultilineBlockLayout: Exclude: - 'app/serializers/conference_serializer.rb' -# Offense count: 58 +# 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: + Exclude: + - 'app/controllers/conferences_controller.rb' + - 'app/controllers/schedules_controller.rb' + - 'app/models/cfp.rb' + - '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: 53 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. -# SupportedStyles: aligned, indented +# SupportedStyles: aligned, indented, indented_relative_to_receiver Style/MultilineMethodCallIndentation: Enabled: false -# Offense count: 26 +# Offense count: 27 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. # SupportedStyles: aligned, indented Style/MultilineOperationIndentation: - Enabled: false + Exclude: + - 'app/controllers/admin/conferences_controller.rb' + - '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: 3 +# Offense count: 2 # Cop supports --auto-correct. Style/MutableConstant: Exclude: - 'app/models/event_user.rb' - - 'app/models/role.rb' + - 'lib/tasks/migrate_config.rake' + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: both, prefix, postfix +Style/NegatedIf: + Exclude: + - 'lib/tasks/update_resource_quantity.rake' # Offense count: 4 +# Cop supports --auto-correct. Style/NestedParenthesizedCalls: Exclude: - 'spec/features/conference_spec.rb' - 'spec/models/conference_spec.rb' -# Offense count: 21 +# Offense count: 26 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, MinBodyLength, SupportedStyles. # SupportedStyles: skip_modifier_ifs, always Style/Next: Enabled: false -# Offense count: 1 +# Offense count: 117 # Cop supports --auto-correct. +# Configuration parameters: EnforcedOctalStyle, SupportedOctalStyles. +# SupportedOctalStyles: zero_with_o, zero_only +Style/NumericLiteralPrefix: + Exclude: + - 'spec/controllers/admin/conferences_controller_spec.rb' + - 'spec/controllers/conference_registration_controller_spec.rb' + - 'spec/helpers/application_helper_spec.rb' + - 'spec/models/conference_spec.rb' + - 'spec/models/email_settings_spec.rb' + - 'spec/models/registration_spec.rb' + - 'spec/serializers/conference_serializer_spec.rb' + - 'spec/serializers/event_serializer_spec.rb' + +# Offense count: 7 +# Cop supports --auto-correct. +# Configuration parameters: Strict. Style/NumericLiterals: MinDigits: 15 +# Offense count: 7 +# Cop supports --auto-correct. +# Configuration parameters: AutoCorrect, EnforcedStyle, SupportedStyles. +# SupportedStyles: predicate, comparison +Style/NumericPredicate: + Exclude: + - 'spec/**/*' + - 'app/controllers/admin/conferences_controller.rb' + - 'app/helpers/application_helper.rb' + - 'app/models/user.rb' + # Offense count: 3 Style/OptionalArguments: Exclude: @@ -441,12 +664,23 @@ Style/ParenthesesAroundCondition: - 'app/controllers/application_controller.rb' - 'app/helpers/application_helper.rb' -# Offense count: 1 +# Offense count: 17 # Cop supports --auto-correct. # Configuration parameters: PreferredDelimiters. Style/PercentLiteralDelimiters: Exclude: - - 'app/serializers/event_serializer.rb' + - 'Gemfile' + - 'app/controllers/admin/users_controller.rb' + - 'app/models/ability.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/uploaders/picture_uploader.rb' + - 'spec/models/ability_spec.rb' + - 'spec/models/program_spec.rb' # Offense count: 2 # Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist. @@ -455,10 +689,20 @@ Style/PercentLiteralDelimiters: # NameWhitelist: is_a? Style/PredicateName: Exclude: + - 'spec/**/*' - 'app/models/comment.rb' - 'app/models/contact.rb' +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: short, verbose +Style/PreferredHashMethods: + Exclude: + - 'lib/tasks/migrate_config.rake' + # Offense count: 6 +# Cop supports --auto-correct. # Configuration parameters: SupportedStyles. # SupportedStyles: compact, exploded Style/RaiseArgs: @@ -476,7 +720,7 @@ Style/RedundantParentheses: Exclude: - 'app/controllers/admin/base_controller.rb' -# Offense count: 4 +# Offense count: 10 # Cop supports --auto-correct. # Configuration parameters: AllowMultipleReturnValues. Style/RedundantReturn: @@ -499,12 +743,13 @@ Style/SelfAssignment: - 'db/migrate/20141104131625_generate_username.rb' - 'spec/support/save_feature_failures.rb' -# Offense count: 1 +# Offense count: 3 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: only_raise, only_fail, semantic Style/SignalException: Exclude: + - 'lib/tasks/user.rake' - 'spec/support/flash.rb' # Offense count: 1 @@ -516,33 +761,46 @@ Style/SingleLineMethods: # Offense count: 1 # Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleInsidePipes, SupportedStyles. -# SupportedStyles: space, no_space +Style/SpaceAfterComma: + Exclude: + - 'lib/tasks/data_demo.rake' + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyleInsidePipes, SupportedStylesInsidePipes. +# SupportedStylesInsidePipes: space, no_space Style/SpaceAroundBlockParameters: Exclude: - 'app/helpers/application_helper.rb' -# Offense count: 4 +# Offense count: 2 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: space, no_space Style/SpaceAroundEqualsInParameterDefault: - Enabled: false + Exclude: + - 'app/helpers/application_helper.rb' + - 'app/models/event.rb' -# Offense count: 223 +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: AllowForAlignment. +Style/SpaceAroundOperators: + Exclude: + - 'lib/tasks/data.rake' + +# Offense count: 315 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: space, no_space Style/SpaceBeforeBlockBraces: Enabled: false -# Offense count: 2 +# Offense count: 1 # Cop supports --auto-correct. -# Configuration parameters: AllowForAlignment. -Style/SpaceBeforeFirstArg: +Style/SpaceBeforeComma: Exclude: - - 'app/controllers/conference_registrations_controller.rb' - - 'spec/factories/splashpages.rb' + - 'lib/tasks/data_demo.rake' # Offense count: 1 # Cop supports --auto-correct. @@ -550,42 +808,94 @@ Style/SpaceBeforeSemicolon: Exclude: - 'Guardfile' -# Offense count: 36 +# Offense count: 2 # Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters. -# SupportedStyles: space, no_space -Style/SpaceInsideBlockBraces: - Enabled: false +Style/SpaceInsideArrayPercentLiteral: + Exclude: + - 'spec/models/ability_spec.rb' -# Offense count: 17 +# 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: 5 # Cop supports --auto-correct. Style/SpaceInsideBrackets: Exclude: - - 'app/controllers/admin/schedules_controller.rb' - 'app/models/conference.rb' - 'app/models/user.rb' - - 'spec/controllers/admin/conferences_controller_spec.rb' - - 'spec/views/admin/events/index.html.haml_spec.rb' -# Offense count: 14 +# Offense count: 25 # Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SupportedStyles. -# SupportedStyles: space, no_space +# Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SupportedStylesForEmptyBraces. +# SupportedStyles: space, no_space, compact +# SupportedStylesForEmptyBraces: space, no_space Style/SpaceInsideHashLiteralBraces: - Enabled: false + 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: 1 +# Offense count: 2 +# Cop supports --auto-correct. +Style/SpaceInsidePercentLiteralDelimiters: + Exclude: + - 'Gemfile' + +# Offense count: 16 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, ConsistentQuotesInMultiline. +# SupportedStyles: single_quotes, double_quotes +Style/StringLiterals: + Exclude: + - 'Gemfile' + - 'Vagrantfile' + - 'lib/tasks/dump_db.rake' + - 'lib/tasks/events_registrations.rake' + - 'lib/tasks/factory_girl.rake' + - 'lib/tasks/user.rake' + +# Offense count: 6 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: space, no_space -Style/SpaceInsideStringInterpolation: +# SupportedStyles: single_quotes, double_quotes +Style/StringLiteralsInInterpolation: Exclude: - - 'app/models/user.rb' + - 'lib/tasks/dump_db.rake' + +# Offense count: 59 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: percent, brackets +Style/SymbolArray: + Enabled: false # Offense count: 10 # Cop supports --auto-correct. # Configuration parameters: IgnoredMethods. -# IgnoredMethods: respond_to +# IgnoredMethods: respond_to, define_method Style/SymbolProc: Exclude: - 'app/controllers/admin/comments_controller.rb' @@ -596,29 +906,54 @@ Style/SymbolProc: - 'spec/controllers/admin/conferences_controller_spec.rb' - 'spec/support/flash.rb' - -# Offense count: 26 +# Offense count: 2 # Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleForMultiline, SupportedStyles. -# SupportedStyles: comma, consistent_comma, no_comma +# Configuration parameters: EnforcedStyle, SupportedStyles, AllowSafeAssignment. +# SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex +Style/TernaryParentheses: + Exclude: + - 'app/helpers/application_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. +# SupportedStylesForMultiline: comma, consistent_comma, no_comma Style/TrailingCommaInLiteral: Exclude: - 'Guardfile' - - 'app/models/target.rb' - 'db/migrate/20140701123203_add_events_per_week_to_conference.rb' - - 'spec/controllers/admin/conferences_controller_spec.rb' - 'spec/models/conference_spec.rb' -# Offense count: 8 +# Offense count: 1 +# Cop supports --auto-correct. +Style/TrailingWhitespace: + Exclude: + - 'Gemfile' + +# Offense count: 3 # Cop supports --auto-correct. Style/UnneededInterpolation: Exclude: - - 'app/controllers/admin/events_controller.rb' - 'app/helpers/application_helper.rb' - 'spec/controllers/admin/conferences_controller_spec.rb' - - 'spec/views/admin/volunteers/index.html.haml_spec.rb' -# Offense count: 3 +# Offense count: 2 +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: snake_case, normalcase, non_integer +Style/VariableNumber: + Exclude: + - 'spec/models/ticket_purchase_spec.rb' + +# Offense count: 6 # Cop supports --auto-correct. # Configuration parameters: SupportedStyles, WordRegex. # SupportedStyles: percent, brackets From aaeca108a8ea1436863e66a157dd31215dc28a99 Mon Sep 17 00:00:00 2001 From: Agrim Mittal Date: Thu, 13 Apr 2017 17:38:38 +0530 Subject: [PATCH 033/185] Add missed offenses to rubocop_todo A known rubocop bug, solved by adding files manually Closes #1450 --- .rubocop_todo.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index c2122773..ccc0aca3 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -321,7 +321,12 @@ Style/CommentIndentation: # SupportedStyles: assign_to_condition, assign_inside_condition Style/ConditionalAssignment: Exclude: + - 'app/controllers/admin/volunteers_controller.rb' + - 'app/controllers/conference_registrations_controller.rb' - 'app/helpers/application_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' From 95d459f058dfe616efe27e2e4eed485ee543cea6 Mon Sep 17 00:00:00 2001 From: Siddhant Bajaj Date: Sat, 22 Apr 2017 01:20:05 +0530 Subject: [PATCH 034/185] Added validation in EventSchedule model and test in event_schedule_spec EventSchedule start time should be in hours range of the conference.Therefore it adds validation on start_time attribute of event schedule model. It also adds test for the same. --- app/models/event_schedule.rb | 12 ++++++++ .../admin/event_schedules_controller_spec.rb | 6 ++-- spec/factories/event_schedule.rb | 2 +- spec/helpers/application_helper_spec.rb | 4 +-- spec/models/event_schedule_spec.rb | 28 +++++++++++++++++++ spec/serializers/event_serializer_spec.rb | 4 +-- 6 files changed, 48 insertions(+), 8 deletions(-) diff --git a/app/models/event_schedule.rb b/app/models/event_schedule.rb index 045070d6..82f1e55a 100644 --- a/app/models/event_schedule.rb +++ b/app/models/event_schedule.rb @@ -10,6 +10,8 @@ class EventSchedule < ActiveRecord::Base validates :room, presence: true validates :start_time, presence: true validates :event, uniqueness: { scope: :schedule } + validate :start_after_end_hour + validate :start_before_start_hour scope :confirmed, -> { joins(:event).where('state = ?', 'confirmed') } scope :canceled, -> { joins(:event).where('state = ?', 'canceled') } @@ -37,6 +39,16 @@ class EventSchedule < ActiveRecord::Base private + def start_after_end_hour + return unless event && start_time && event.program && event.program.conference && event.program.conference.end_hour + errors.add(:start_time, "can't be after the conference end hour (#{event.program.conference.end_hour})") if start_time.hour >= event.program.conference.end_hour + end + + def start_before_start_hour + return unless event && start_time && event.program && event.program.conference && event.program.conference.start_hour + errors.add(:start_time, "can't be before the conference start hour (#{event.program.conference.start_hour})") if start_time.hour < event.program.conference.start_hour + end + def conference_id schedule.program.conference_id end diff --git a/spec/controllers/admin/event_schedules_controller_spec.rb b/spec/controllers/admin/event_schedules_controller_spec.rb index 4d0569ec..6c1cfedd 100644 --- a/spec/controllers/admin/event_schedules_controller_spec.rb +++ b/spec/controllers/admin/event_schedules_controller_spec.rb @@ -23,7 +23,7 @@ describe Admin::EventSchedulesController do schedule_id: schedule.id, event_id: create(:event, program: conference.program).id, room_id: create(:room, venue: venue).id, - start_time: conference.start_date) + start_time: conference.start_date + conference.start_hour.hours) end it 'saves the event schedule to the database' do @@ -66,7 +66,7 @@ describe Admin::EventSchedulesController do schedule_id: schedule.id, event_id: create(:event, program: conference.program).id, room_id: room.id, - start_time: conference.start_date) + start_time: conference.start_date + conference.start_hour.hours) event_schedule.reload end @@ -75,7 +75,7 @@ describe Admin::EventSchedulesController do end it 'updates the start_time' do - expect(event_schedule.start_time).to eq(conference.start_date) + expect(event_schedule.start_time).to eq(conference.start_date + conference.start_hour.hours) end it 'has 200 status code' do diff --git a/spec/factories/event_schedule.rb b/spec/factories/event_schedule.rb index 80abe677..a72e3745 100644 --- a/spec/factories/event_schedule.rb +++ b/spec/factories/event_schedule.rb @@ -9,7 +9,7 @@ FactoryGirl.define do venue = create(:venue, conference: program.conference) end (event_schedule.room = create(:room, venue: venue)) unless event_schedule.room.present? - (event_schedule.start_time = program.conference.start_date.to_time) unless event_schedule.start_time.present? + (event_schedule.start_time = program.conference.start_date + program.conference.start_hour.hours) unless event_schedule.start_time.present? unless event_schedule.schedule.present? unless program.selected_schedule.present? schedule = create(:schedule, program: program) diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index 242f03e5..bc951e08 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -98,8 +98,8 @@ describe ApplicationHelper, type: :helper do @other_event = create(:event, program: conference.program, state: 'confirmed') schedule = create(:schedule, program: conference.program) conference.program.update_attributes!(selected_schedule: schedule) - @event_schedule = create(:event_schedule, event: event, start_time: conference.start_date, room: create(:room), schedule: schedule) - @other_event_schedule = create(:event_schedule, event: @other_event, start_time: conference.start_date, room: create(:room), schedule: schedule) + @event_schedule = create(:event_schedule, event: event, start_time: conference.start_date + conference.start_hour.hours, room: create(:room), schedule: schedule) + @other_event_schedule = create(:event_schedule, event: @other_event, start_time: conference.start_date + conference.start_hour.hours, room: create(:room), schedule: schedule) end describe 'does return correct concurrent events' do diff --git a/spec/models/event_schedule_spec.rb b/spec/models/event_schedule_spec.rb index 28b04ddf..6d1325b7 100644 --- a/spec/models/event_schedule_spec.rb +++ b/spec/models/event_schedule_spec.rb @@ -1,6 +1,7 @@ require 'spec_helper' describe EventSchedule do + let(:conference) { create(:conference) } describe 'association' do it { should belong_to(:schedule) } @@ -17,5 +18,32 @@ describe EventSchedule do it { is_expected.to validate_presence_of(:event) } it { is_expected.to validate_presence_of(:room) } it { is_expected.to validate_presence_of(:start_time) } + + describe '#start_after_end_hour' do + context 'is invalid' do + it 'when event schedule start_time is after the conference end_hour, and returns an error message' do + new_scheduled_event = build(:event_scheduled, program: conference.program, hour: conference.start_date + conference.end_hour.hours + 1.hour) + expect(new_scheduled_event.valid?).to eq false + expect(new_scheduled_event.event_schedules.first.errors[:start_time]).to eq ["can't be after the conference end hour (#{conference.end_hour})"] + end + end + + context 'is valid' do + it 'when event schedule start_time is between the conference end_hour and start_hour' do + new_scheduled_event = build(:event_scheduled, program: conference.program, hour: conference.start_date + conference.end_hour.hours - 1.hour) + expect(new_scheduled_event.valid?).to eq true + end + end + end + + describe '#start_before_start_hour' do + context 'is invalid' do + it 'when event schedule start_time is before the conference start_hour, and returns an error message' do + new_scheduled_event = build(:event_scheduled, program: conference.program, hour: conference.start_date) + expect(new_scheduled_event.valid?).to eq false + expect(new_scheduled_event.event_schedules.first.errors[:start_time]).to eq ["can't be before the conference start hour (#{conference.start_hour})"] + end + end + end end end diff --git a/spec/serializers/event_serializer_spec.rb b/spec/serializers/event_serializer_spec.rb index af459e1d..8bb29fa2 100644 --- a/spec/serializers/event_serializer_spec.rb +++ b/spec/serializers/event_serializer_spec.rb @@ -32,7 +32,7 @@ describe EventSerializer, type: :serializer do before do event.language = 'English' event.speakers = [speaker] - create(:event_schedule, event: event, room: room, start_time: Date.new(2014, 03, 04)) + create(:event_schedule, event: event, room: room, start_time: Date.new(2014, 03, 04) + 9.hours) event.track = track end @@ -42,7 +42,7 @@ describe EventSerializer, type: :serializer do guid: event.guid, title: 'Some Talk', length: 30, - scheduled_date: ' 2014-03-04T00:00:00+0000 ', + scheduled_date: ' 2014-03-04T09:00:00+0000 ', language: 'English', abstract: 'Lorem ipsum dolor sit amet', speaker_ids: [speaker.id], From 23473e1476cb18c4f5d84bcbfa4644e88c846d2c Mon Sep 17 00:00:00 2001 From: Siddhant Bajaj Date: Sat, 22 Apr 2017 01:28:49 +0530 Subject: [PATCH 035/185] Added hour transient attribute to event_scheduled factory It allows event_scheduled to be created with custom time. --- spec/factories/events.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/spec/factories/events.rb b/spec/factories/events.rb index 09c74afd..731c774e 100644 --- a/spec/factories/events.rb +++ b/spec/factories/events.rb @@ -29,9 +29,13 @@ FactoryGirl.define do end factory :event_scheduled do - after(:build) do |event| + transient do + hour nil + end + + after(:build) do |event, evaluator| event.state = 'confirmed' - event.event_schedules << build(:event_schedule, event: event) + event.event_schedules << build(:event_schedule, event: event, start_time: evaluator.hour) end end end From a6e8283bcf9fa52e0f55601bc4f2bdccd4272813 Mon Sep 17 00:00:00 2001 From: nasia Date: Sun, 23 Apr 2017 13:13:56 +0300 Subject: [PATCH 036/185] Fix commercial option for users in dashboard#show #1390 --- app/controllers/admin/commercials_controller.rb | 1 - spec/features/ability_spec.rb | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/controllers/admin/commercials_controller.rb b/app/controllers/admin/commercials_controller.rb index 703423fe..f13b4322 100644 --- a/app/controllers/admin/commercials_controller.rb +++ b/app/controllers/admin/commercials_controller.rb @@ -7,7 +7,6 @@ module Admin @commercials = @conference.commercials @commercial = @conference.commercials.build - authorize! :create, @conference.commercials.new end def create diff --git a/spec/features/ability_spec.rb b/spec/features/ability_spec.rb index b3d8e5fa..80e968bd 100644 --- a/spec/features/ability_spec.rb +++ b/spec/features/ability_spec.rb @@ -284,7 +284,7 @@ feature 'Has correct abilities' do expect(current_path).to eq(root_path) visit admin_conference_commercials_path(conference2.short_title) - expect(current_path).to eq(root_path) + expect(current_path).to eq(admin_conference_commercials_path(conference2.short_title)) visit new_admin_conference_splashpage_path(conference2.short_title) expect(current_path).to eq(root_path) @@ -496,7 +496,7 @@ feature 'Has correct abilities' do expect(current_path).to eq(root_path) visit admin_conference_commercials_path(conference3.short_title) - expect(current_path).to eq(root_path) + expect(current_path).to eq(admin_conference_commercials_path(conference3.short_title)) visit new_admin_conference_splashpage_path(conference3.short_title) expect(current_path).to eq(root_path) From ec71b111fe50f05e892e4c752a04267c09aac6c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sede=C3=B1o?= Date: Tue, 4 Apr 2017 22:27:42 +0200 Subject: [PATCH 037/185] Add description to xml. fixes #1435 --- app/views/schedules/show.xml.haml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/views/schedules/show.xml.haml b/app/views/schedules/show.xml.haml index 39665c5a..541377ad 100644 --- a/app/views/schedules/show.xml.haml +++ b/app/views/schedules/show.xml.haml @@ -27,6 +27,7 @@ %subtitle= event.subtitle %track= event.track.name if event.track %abstract= event.abstract + %description= event.abstract %recording %license/ %optout=false #FIXME From 7ce816e146ee59dd9b9c6e383cad1ec1eb775894 Mon Sep 17 00:00:00 2001 From: Siddhant Bajaj Date: Mon, 6 Mar 2017 21:45:48 +0530 Subject: [PATCH 038/185] Fixed DeleteEventSchedules issue Issues with DeleteEventSchedules method in conference controller: 1.It deletes EventSchedules of all the conferences that are not in the hours range. Instead it should delete EventSchedules of those events only that belong to that particular conference only. 2.If we set invalid start or end hour attribute of a conference then also EventSchedules gets deleted even though conference is not successfully updated. Fixed both the issues and added test for the same. --- .../admin/conferences_controller.rb | 10 ---------- app/models/conference.rb | 15 +++++++++++++++ spec/models/conference_spec.rb | 19 +++++++++++++++++++ 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/app/controllers/admin/conferences_controller.rb b/app/controllers/admin/conferences_controller.rb index 6aafe6c5..50360a64 100644 --- a/app/controllers/admin/conferences_controller.rb +++ b/app/controllers/admin/conferences_controller.rb @@ -82,7 +82,6 @@ module Admin short_title = @conference.short_title @conference.assign_attributes(conference_params) send_mail_on_conf_update = @conference.notify_on_dates_changed? - delete_event_schedules if @conference.start_hour_changed? || @conference.end_hour_changed? if @conference.update_attributes(conference_params) ConferenceDateUpdateMailJob.perform_later(@conference) if send_mail_on_conf_update @@ -189,14 +188,5 @@ module Admin :targets, :targets_attributes, :campaigns, :campaigns_attributes, :registration_limit) end - - def delete_event_schedules - event_schedules = EventSchedule.select do |e| - e.start_time.strftime('%H').to_i < @conference.start_hour || - e.end_time.strftime('%H').to_i > @conference.end_hour || - (e.end_time.strftime('%H').to_i == @conference.end_hour && e.end_time.strftime('%M').to_i > 0) - end - event_schedules.each(&:destroy) - end end end diff --git a/app/models/conference.rb b/app/models/conference.rb index f4d55d2e..224c1dfb 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -67,6 +67,7 @@ class Conference < ActiveRecord::Base before_create :create_email_settings after_create :create_free_ticket + after_update :delete_event_schedules ## # Checks if the user is registered to the conference @@ -80,6 +81,20 @@ class Conference < ActiveRecord::Base user.present? && registrations.where(user_id: user.id).count > 0 end + ## + # Delete all EventSchedules that are not in the hours range + # After the conference has been successfully updated + def delete_event_schedules + if start_hour_changed? || end_hour_changed? + event_schedules = program.event_schedules.select do |event_schedule| + event_schedule.start_time.hour < start_hour || + event_schedule.end_time.hour > end_hour || + (event_schedule.end_time.hour == end_hour && event_schedule.end_time.minute > 0) + end + event_schedules.each(&:destroy) + end + end + ## # Checks if the registration for the conference is currently open # diff --git a/spec/models/conference_spec.rb b/spec/models/conference_spec.rb index 47d64164..b5a6d5f0 100755 --- a/spec/models/conference_spec.rb +++ b/spec/models/conference_spec.rb @@ -1639,4 +1639,23 @@ describe Conference do expect(free_ticket.price_cents).to eq(0) end end + + describe 'after_update' do + let(:conference) { create(:conference) } + let(:scheduled_event_before_conference) { create(:event_scheduled, program: conference.program, hour: conference.start_date + conference.start_hour.hours) } + let(:scheduled_event_after_conference) { create(:event_scheduled, program: conference.program, hour: conference.start_date + conference.end_hour.hours - 1.hour) } + let!(:scheduled_event_during_conference) { create(:event_scheduled, program: conference.program, hour: conference.start_date + conference.start_hour.hours + 3.hours) } + + it 'delete event schedules that are not in hour ranges, when conference start hour is updated' do + scheduled_event_before_conference + conference.start_hour = conference.start_hour + 1 + expect{ conference.save }.to change{ EventSchedule.count }.from(2).to(1) + end + + it 'delete event schedules that are not in hour ranges, when conference end hour is updated' do + scheduled_event_after_conference + conference.end_hour = conference.end_hour - 2 + expect{ conference.save }.to change{ EventSchedule.count }.from(2).to(1) + end + end end From 7ff34c5b23655af18deaf919eb687ccf948f803d Mon Sep 17 00:00:00 2001 From: Siddhant Bajaj Date: Wed, 12 Apr 2017 23:06:17 +0530 Subject: [PATCH 039/185] Added relation between EventSchedule and program model Program has many event_schedules through schedules --- app/models/program.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/program.rb b/app/models/program.rb index ff0ab094..e8114f99 100644 --- a/app/models/program.rb +++ b/app/models/program.rb @@ -10,6 +10,7 @@ class Program < ActiveRecord::Base has_many :tracks, dependent: :destroy has_many :difficulty_levels, dependent: :destroy has_many :schedules, dependent: :destroy + has_many :event_schedules, through: :schedules belongs_to :selected_schedule, class_name: 'Schedule' has_many :events, dependent: :destroy do def require_registration From dc865abaaa50a4aa3142603f1dd810a8db6d3acc Mon Sep 17 00:00:00 2001 From: Siddhant Bajaj Date: Tue, 25 Apr 2017 16:36:43 +0530 Subject: [PATCH 040/185] Excluded conference_spec from block cop Fixes #1333 --- .rubocop.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index c2e973f0..9410af03 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -120,6 +120,10 @@ Metrics/ClassLength: Exclude: - 'app/models/conference.rb' +Metrics/BlockLength: + Exclude: + - 'spec/models/conference_spec.rb' + #################### Lint ############################### # Wrap your assignment in condition if you mean it, otherwise it is most likely equality check From 605a1a9c5f34385101d6f225ab89c4b917bca8e3 Mon Sep 17 00:00:00 2001 From: Agrim Mittal Date: Tue, 25 Apr 2017 04:36:10 +0530 Subject: [PATCH 041/185] Add haml-lint gem Added haml_lint gem v0.24.0 --- Gemfile | 1 + Gemfile.lock | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/Gemfile b/Gemfile index 1b882aab..497c56b1 100644 --- a/Gemfile +++ b/Gemfile @@ -201,6 +201,7 @@ group :development do # to launch specs when files are modified gem 'guard-rspec', '~> 4.2.8' gem 'spring-commands-rspec' + gem 'haml_lint', '~> 0.24.0' # for static code analisys gem 'rubocop', '~> 0.48.1', require: false # as database diff --git a/Gemfile.lock b/Gemfile.lock index 3bc396d4..90ae82f0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -209,6 +209,12 @@ GEM activesupport (>= 4.0.1) haml (>= 3.1, < 5.0) railties (>= 4.0.1) + haml_lint (0.24.0) + haml (>= 4.0, < 5.1) + rainbow + rake (>= 10, < 13) + rubocop (>= 0.47.0) + sysexits (~> 1.1) hashie (2.1.1) hike (1.2.3) hoptoad_notifier (2.4.11) @@ -488,6 +494,7 @@ GEM dante (>= 0.2.0) multi_json (>= 1.0.0) stripe (>= 1.31.0, <= 1.43) + sysexits (1.2.0) term-ansicolor (1.3.2) tins (~> 1.0) thor (0.19.1) @@ -573,6 +580,7 @@ DEPENDENCIES gravtastic guard-rspec (~> 4.2.8) haml-rails + haml_lint (~> 0.24.0) hoptoad_notifier (~> 2.3) iso-639 jquery-datatables-rails (~> 2.2.1) From b69eb7d262dce09e5829420b30a88b18f79a8e30 Mon Sep 17 00:00:00 2001 From: Agrim Mittal Date: Tue, 25 Apr 2017 04:37:39 +0530 Subject: [PATCH 042/185] generate haml-lint_todo Automatically generated using --auto-gen-config and added haml-lint.yml which inherits from haml-lint_todo --- .haml-lint.yml | 1 + .haml-lint_todo.yml | 427 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 428 insertions(+) create mode 100644 .haml-lint.yml create mode 100644 .haml-lint_todo.yml diff --git a/.haml-lint.yml b/.haml-lint.yml new file mode 100644 index 00000000..013b144f --- /dev/null +++ b/.haml-lint.yml @@ -0,0 +1 @@ +inherits_from: .haml-lint_todo.yml diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml new file mode 100644 index 00000000..2c51e966 --- /dev/null +++ b/.haml-lint_todo.yml @@ -0,0 +1,427 @@ +# This configuration was generated by +# `haml-lint --auto-gen-config` +# on 2017-04-25 04:36:49 +0530 using Haml-Lint version 0.24.0. +# The point is for the user to remove these configuration records +# one by one as the lints are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of Haml-Lint, may require this file to be generated again. + +linters: + + # Offense count: 952 + LineLength: + exclude: + - "app/views/admin/campaigns/_form.html.haml" + - "app/views/admin/campaigns/index.html.haml" + - "app/views/admin/cfps/_form.html.haml" + - "app/views/admin/cfps/show.html.haml" + - "app/views/admin/comments/_all_comments.html.haml" + - "app/views/admin/comments/_posted_comments.html.haml" + - "app/views/admin/comments/_unread_comments.html.haml" + - "app/views/admin/commercials/index.html.haml" + - "app/views/admin/conferences/_campaigns.html.haml" + - "app/views/admin/conferences/_doughnut_chart.html.haml" + - "app/views/admin/conferences/_line_chart.html.haml" + - "app/views/admin/conferences/_recent_registrations.html.haml" + - "app/views/admin/conferences/_recent_submissions.html.haml" + - "app/views/admin/conferences/_recent_users.html.haml" + - "app/views/admin/conferences/_targets.html.haml" + - "app/views/admin/conferences/_todo_list.html.haml" + - "app/views/admin/conferences/_top_submitter.html.haml" + - "app/views/admin/conferences/edit.html.haml" + - "app/views/admin/conferences/index.html.haml" + - "app/views/admin/conferences/new.html.haml" + - "app/views/admin/conferences/show.html.haml" + - "app/views/admin/contacts/edit.html.haml" + - "app/views/admin/difficulty_levels/_form.html.haml" + - "app/views/admin/difficulty_levels/index.html.haml" + - "app/views/admin/emails/_help.html.haml" + - "app/views/admin/emails/index.html.haml" + - "app/views/admin/event_types/_form.html.haml" + - "app/views/admin/event_types/index.html.haml" + - "app/views/admin/events/_all_events.csv.haml" + - "app/views/admin/events/_all_with_comments.csv.haml" + - "app/views/admin/events/_change_state_dropdown.html.haml" + - "app/views/admin/events/_confirmed_events.csv.haml" + - "app/views/admin/events/_nested_comments.html.haml" + - "app/views/admin/events/_proposal.html.haml" + - "app/views/admin/events/_voting.html.haml" + - "app/views/admin/events/_voting_index.html.haml" + - "app/views/admin/events/index.html.haml" + - "app/views/admin/events/registrations.html.haml" + - "app/views/admin/events/reports.html.haml" + - "app/views/admin/events/show.html.haml" + - "app/views/admin/lodgings/_form.html.haml" + - "app/views/admin/lodgings/index.html.haml" + - "app/views/admin/programs/_form.html.haml" + - "app/views/admin/programs/show.html.haml" + - "app/views/admin/questions/_form.html.haml" + - "app/views/admin/questions/_questions.html.haml" + - "app/views/admin/questions/edit.html.haml" + - "app/views/admin/questions/index.html.haml" + - "app/views/admin/questions/show.html.haml" + - "app/views/admin/registration_periods/_form.html.haml" + - "app/views/admin/registration_periods/show.html.haml" + - "app/views/admin/registrations/edit.html.haml" + - "app/views/admin/registrations/index.html.haml" + - "app/views/admin/reports/_all_events.html.haml" + - "app/views/admin/reports/_events_with_requirements.html.haml" + - "app/views/admin/reports/_events_without_commercials.html.haml" + - "app/views/admin/reports/_missing_speakers.html.haml" + - "app/views/admin/resources/_form.html.haml" + - "app/views/admin/resources/index.html.haml" + - "app/views/admin/resources/show.html.haml" + - "app/views/admin/roles/_form.html.haml" + - "app/views/admin/roles/_users.html.haml" + - "app/views/admin/roles/index.html.haml" + - "app/views/admin/roles/show.html.haml" + - "app/views/admin/rooms/_form.html.haml" + - "app/views/admin/rooms/index.html.haml" + - "app/views/admin/schedules/_day_tab.html.haml" + - "app/views/admin/schedules/_event.html.haml" + - "app/views/admin/schedules/index.html.haml" + - "app/views/admin/schedules/show.html.haml" + - "app/views/admin/splashpages/_form.html.haml" + - "app/views/admin/splashpages/show.html.haml" + - "app/views/admin/sponsors/_form.html.haml" + - "app/views/admin/sponsors/index.html.haml" + - "app/views/admin/sponsorship_levels/_form.html.haml" + - "app/views/admin/sponsorship_levels/index.html.haml" + - "app/views/admin/targets/_form.html.haml" + - "app/views/admin/targets/index.html.haml" + - "app/views/admin/tickets/_form.html.haml" + - "app/views/admin/tickets/index.html.haml" + - "app/views/admin/tickets/show.html.haml" + - "app/views/admin/tracks/_form.html.haml" + - "app/views/admin/tracks/index.html.haml" + - "app/views/admin/tracks/show.html.haml" + - "app/views/admin/users/_event_registrations.html.haml" + - "app/views/admin/users/_form.html.haml" + - "app/views/admin/users/_submissions.html.haml" + - "app/views/admin/users/index.html.haml" + - "app/views/admin/users/show.html.haml" + - "app/views/admin/venues/_form.html.haml" + - "app/views/admin/venues/show.html.haml" + - "app/views/admin/versions/_object_desc_and_link.html.haml" + - "app/views/admin/versions/index.html.haml" + - "app/views/admin/volunteers/index.html.haml" + - "app/views/commercials/edit.html.haml" + - "app/views/commercials/new.html.haml" + - "app/views/conference_registrations/_form.html.haml" + - "app/views/conference_registrations/_questions.html.haml" + - "app/views/conference_registrations/_registration_info.html.haml" + - "app/views/conference_registrations/_volunteer.html.haml" + - "app/views/conference_registrations/show.html.haml" + - "app/views/conferences/_call_for_paper.html.haml" + - "app/views/conferences/_conference_details.html.haml" + - "app/views/conferences/_gallery.html.haml" + - "app/views/conferences/_lodging.html.haml" + - "app/views/conferences/_program.html.haml" + - "app/views/conferences/_registration.html.haml" + - "app/views/conferences/_schedule_splashpage.html.haml" + - "app/views/conferences/_sponsors.html.haml" + - "app/views/conferences/_tickets.html.haml" + - "app/views/conferences/_venue.html.haml" + - "app/views/conferences/_venue_map.html.haml" + - "app/views/conferences/index.html.haml" + - "app/views/conferences/show.html.haml" + - "app/views/devise/confirmations/new.html.haml" + - "app/views/devise/ichain_sessions/new.html.haml" + - "app/views/devise/ichain_sessions/new_test.html.haml" + - "app/views/devise/passwords/edit.html.haml" + - "app/views/devise/passwords/new.html.haml" + - "app/views/devise/registrations/_volunteeruser.html.haml" + - "app/views/devise/registrations/edit.html.haml" + - "app/views/devise/registrations/new.html.haml" + - "app/views/devise/sessions/new.html.haml" + - "app/views/devise/shared/_help.html.haml" + - "app/views/devise/shared/_links.html.haml" + - "app/views/devise/shared/_openid_links.html.haml" + - "app/views/devise/shared/_sign_in_form_embedded.html.haml" + - "app/views/devise/shared/_sign_up_form_embedded.html.haml" + - "app/views/layouts/_admin_sidebar.html.haml" + - "app/views/layouts/_admin_sidebar_index.html.haml" + - "app/views/layouts/_messages.html.haml" + - "app/views/layouts/_navigation.html.haml" + - "app/views/layouts/application.html.haml" + - "app/views/payments/_payment.html.haml" + - "app/views/proposals/_form.html.haml" + - "app/views/proposals/_proposal_form.html.haml" + - "app/views/proposals/_tooltip.html.haml" + - "app/views/proposals/index.html.haml" + - "app/views/proposals/new.html.haml" + - "app/views/proposals/registrations.html.haml" + - "app/views/proposals/show.html.haml" + - "app/views/schedules/_carousel.html.haml" + - "app/views/schedules/_event.html.haml" + - "app/views/schedules/_schedule.html.haml" + - "app/views/schedules/_schedule_item.html.haml" + - "app/views/schedules/_schedule_tabs.html.haml" + - "app/views/schedules/events.html.haml" + - "app/views/schedules/show.html.haml" + - "app/views/schedules/show.xml.haml" + - "app/views/shared/_changelog_actions.haml" + - "app/views/shared/_dynamic_association.html.haml" + - "app/views/shared/_media_item.html.haml" + - "app/views/shared/_media_items.html.haml" + - "app/views/shared/_object_changes.html.haml" + - "app/views/tickets/_ticket.html.haml" + - "app/views/tickets/index.html.haml" + - "app/views/users/edit.html.haml" + - "app/views/users/show.html.haml" + + # Offense count: 222 + InstanceVariables: + exclude: + - "app/views/admin/campaigns/_form.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" + - "app/views/admin/event_types/_form.html.haml" + - "app/views/admin/events/_change_state_dropdown.html.haml" + - "app/views/admin/events/_form.html.haml" + - "app/views/admin/events/_proposal.html.haml" + - "app/views/admin/events/_voting.html.haml" + - "app/views/admin/events/_voting_index.html.haml" + - "app/views/admin/lodgings/_form.html.haml" + - "app/views/admin/questions/_questions.html.haml" + - "app/views/admin/registration_periods/_form.html.haml" + - "app/views/admin/reports/_all_events.html.haml" + - "app/views/admin/reports/_events_with_requirements.html.haml" + - "app/views/admin/reports/_events_without_commercials.html.haml" + - "app/views/admin/reports/_missing_speakers.html.haml" + - "app/views/admin/roles/_form.html.haml" + - "app/views/admin/roles/_users.html.haml" + - "app/views/admin/rooms/_form.html.haml" + - "app/views/admin/schedules/_day_tab.html.haml" + - "app/views/admin/schedules/_event.html.haml" + - "app/views/admin/splashpages/_form.html.haml" + - "app/views/admin/sponsors/_form.html.haml" + - "app/views/admin/sponsorship_levels/_form.html.haml" + - "app/views/admin/tickets/_form.html.haml" + - "app/views/admin/tracks/_form.html.haml" + - "app/views/admin/users/_form.html.haml" + - "app/views/admin/users/_submissions.html.haml" + - "app/views/admin/venues/_form.html.haml" + - "app/views/conference_registrations/_form.html.haml" + - "app/views/conference_registrations/_registration_info.html.haml" + - "app/views/conference_registrations/_volunteer.html.haml" + - "app/views/conferences/_call_for_paper.html.haml" + - "app/views/conferences/_lodging.html.haml" + - "app/views/conferences/_program.html.haml" + - "app/views/conferences/_registration.html.haml" + - "app/views/conferences/_schedule_splashpage.html.haml" + - "app/views/conferences/_sponsors.html.haml" + - "app/views/conferences/_tickets.html.haml" + - "app/views/conferences/_venue.html.haml" + - "app/views/conferences/_venue_map.html.haml" + - "app/views/layouts/_admin_sidebar.html.haml" + - "app/views/layouts/_user_menu.html.haml" + - "app/views/payments/_payment.html.haml" + - "app/views/proposals/_encouragement_text.html.haml" + - "app/views/proposals/_form.html.haml" + - "app/views/proposals/_proposal_form.html.haml" + - "app/views/schedules/_carousel.html.haml" + - "app/views/schedules/_event.html.haml" + - "app/views/schedules/_schedule.html.haml" + - "app/views/schedules/_schedule_item.html.haml" + - "app/views/schedules/_schedule_tabs.html.haml" + + # Offense count: 32 + IdNames: + exclude: + - "app/views/admin/cfps/show.html.haml" + - "app/views/admin/comments/index.html.haml" + - "app/views/admin/conferences/index.html.haml" + - "app/views/admin/conferences/show.html.haml" + - "app/views/admin/difficulty_levels/index.html.haml" + - "app/views/admin/event_types/index.html.haml" + - "app/views/admin/programs/show.html.haml" + - "app/views/admin/questions/show.html.haml" + - "app/views/admin/roles/show.html.haml" + - "app/views/admin/schedules/index.html.haml" + - "app/views/admin/sponsorship_levels/index.html.haml" + - "app/views/admin/users/_event_registrations.html.haml" + - "app/views/admin/users/show.html.haml" + - "app/views/users/edit.html.haml" + + # Offense count: 8 + UnnecessaryInterpolation: + exclude: + - "app/views/admin/conferences/_doughnut_chart.html.haml" + - "app/views/admin/conferences/_recent_submissions.html.haml" + - "app/views/admin/events/reports.html.haml" + - "app/views/admin/reports/_events_with_requirements.html.haml" + - "app/views/admin/reports/_events_without_commercials.html.haml" + - "app/views/proposals/_proposal_form.html.haml" + - "app/views/proposals/new.html.haml" + + # Offense count: 48 + UnnecessaryStringOutput: + exclude: + - "app/views/admin/conferences/_targets.html.haml" + - "app/views/admin/event_types/index.html.haml" + - "app/views/admin/events/show.html.haml" + - "app/views/admin/users/_submissions.html.haml" + - "app/views/admin/venues/show.html.haml" + - "app/views/admin/versions/_object_desc_and_link.html.haml" + - "app/views/admin/volunteers/show.html.haml" + - "app/views/conference_registrations/show.html.haml" + - "app/views/conferences/_call_for_paper.html.haml" + - "app/views/conferences/_conference_details.html.haml" + - "app/views/conferences/_program.html.haml" + - "app/views/conferences/_venue.html.haml" + - "app/views/conferences/show.html.haml" + - "app/views/devise/registrations/edit.html.haml" + - "app/views/proposals/_encouragement_text.html.haml" + - "app/views/proposals/_form.html.haml" + - "app/views/users/edit.html.haml" + - "app/views/users/show.html.haml" + + # Offense count: 268 + SpaceInsideHashAttributes: + exclude: + - "app/views/admin/conferences/_todo_list.html.haml" + - "app/views/admin/questions/_form.html.haml" + - "app/views/admin/questions/index.html.haml" + - "app/views/admin/registrations/index.html.haml" + - "app/views/admin/reports/_all_events.html.haml" + - "app/views/admin/reports/index.html.haml" + - "app/views/admin/schedules/_day_tab.html.haml" + - "app/views/admin/schedules/_event.html.haml" + - "app/views/admin/schedules/index.html.haml" + - "app/views/admin/schedules/show.html.haml" + - "app/views/admin/sponsorship_levels/index.html.haml" + - "app/views/admin/targets/index.html.haml" + - "app/views/admin/tickets/show.html.haml" + - "app/views/admin/tracks/index.html.haml" + - "app/views/admin/users/show.html.haml" + - "app/views/admin/venues/_form.html.haml" + - "app/views/admin/venues/show.html.haml" + - "app/views/conference_registrations/_form.html.haml" + - "app/views/conference_registrations/_ticket.html.haml" + - "app/views/conference_registrations/_volunteer.html.haml" + - "app/views/conferences/_venue.html.haml" + - "app/views/conferences/_venue_map.html.haml" + - "app/views/conferences/index.html.haml" + - "app/views/devise/shared/_help.html.haml" + - "app/views/devise/shared/_openid_links.html.haml" + - "app/views/devise/shared/_sign_in_form_embedded.html.haml" + - "app/views/layouts/_admin_sidebar.html.haml" + - "app/views/layouts/_admin_sidebar_index.html.haml" + - "app/views/layouts/_messages.html.haml" + - "app/views/layouts/_navigation.html.haml" + - "app/views/layouts/application.html.haml" + - "app/views/payments/_payment.html.haml" + - "app/views/proposals/_form.html.haml" + - "app/views/proposals/_tooltip.html.haml" + - "app/views/proposals/index.html.haml" + - "app/views/proposals/new.html.haml" + - "app/views/proposals/show.html.haml" + - "app/views/schedules/_carousel.html.haml" + - "app/views/schedules/_schedule_item.html.haml" + - "app/views/shared/_changelog_actions.haml" + - "app/views/shared/_dynamic_association.html.haml" + - "app/views/shared/_media_item.html.haml" + - "app/views/shared/_media_items.html.haml" + - "app/views/shared/_object_changes.html.haml" + - "app/views/tickets/_ticket.html.haml" + - "app/views/tickets/index.html.haml" + + # Offense count: 27 + ClassesBeforeIds: + exclude: + - "app/views/admin/emails/index.html.haml" + - "app/views/admin/events/reports.html.haml" + - "app/views/admin/events/show.html.haml" + - "app/views/admin/reports/index.html.haml" + - "app/views/admin/users/show.html.haml" + - "app/views/admin/venues/_form.html.haml" + - "app/views/conferences/index.html.haml" + - "app/views/devise/shared/_help.html.haml" + - "app/views/devise/shared/_sign_in_form_embedded.html.haml" + - "app/views/layouts/_navigation.html.haml" + - "app/views/proposals/_form.html.haml" + + # Offense count: 55 + SpaceBeforeScript: + exclude: + - "app/views/admin/events/_form.html.haml" + - "app/views/admin/events/index.html.haml" + - "app/views/admin/registrations/index.html.haml" + - "app/views/admin/splashpages/show.html.haml" + - "app/views/admin/sponsors/_form.html.haml" + - "app/views/admin/targets/_form.html.haml" + - "app/views/admin/tracks/_form.html.haml" + - "app/views/admin/tracks/show.html.haml" + - "app/views/admin/venues/show.html.haml" + - "app/views/admin/versions/index.html.haml" + - "app/views/conference_registrations/_form.html.haml" + - "app/views/conference_registrations/_ticket.html.haml" + - "app/views/conference_registrations/show.html.haml" + - "app/views/conferences/_lodging.html.haml" + - "app/views/conferences/_schedule_splashpage.html.haml" + - "app/views/conferences/_sponsors.html.haml" + - "app/views/conferences/_tickets.html.haml" + - "app/views/conferences/_venue.html.haml" + - "app/views/conferences/index.html.haml" + - "app/views/layouts/_admin.html.haml" + - "app/views/layouts/_navigation.html.haml" + - "app/views/layouts/_user_menu.html.haml" + - "app/views/layouts/application.html.haml" + - "app/views/proposals/_encouragement_text.html.haml" + - "app/views/proposals/new.html.haml" + - "app/views/proposals/registrations.html.haml" + - "app/views/proposals/show.html.haml" + - "app/views/schedules/events.html.haml" + - "app/views/schedules/show.xml.haml" + - "app/views/tickets/index.html.haml" + + # Offense count: 14 + ConsecutiveSilentScripts: + exclude: + - "app/views/admin/events/index.html.haml" + - "app/views/admin/schedules/_day_tab.html.haml" + - "app/views/admin/schedules/_event.html.haml" + - "app/views/admin/versions/_object_desc_and_link.html.haml" + - "app/views/schedules/_carousel.html.haml" + + # Offense count: 2 + FinalNewline: + exclude: + - "app/views/admin/registrations/index.csv.haml" + - "app/views/layouts/_admin.html.haml" + + # Offense count: 1 + ImplicitDiv: + exclude: + - "app/views/admin/registrations/index.html.haml" + + # Offense count: 9 + MultilinePipe: + exclude: + - "app/views/admin/schedules/_day_tab.html.haml" + - "app/views/admin/schedules/_event.html.haml" + - "app/views/schedules/_carousel.html.haml" + - "app/views/schedules/_event.html.haml" + - "app/views/schedules/_schedule_item.html.haml" + + # Offense count: 38 + TrailingWhitespace: + exclude: + - "app/views/admin/users/_form.html.haml" + - "app/views/admin/users/index.html.haml" + - "app/views/admin/users/show.html.haml" + - "app/views/admin/volunteers/index.html.haml" + - "app/views/admin/volunteers/show.html.haml" + - "app/views/conference_registrations/_volunteer.html.haml" + - "app/views/devise/passwords/new.html.haml" + - "app/views/payments/new.html.haml" + - "app/views/tickets/index.html.haml" + + # Offense count: 7 + ClassAttributeWithStaticValue: + exclude: + - "app/views/conferences/_gallery.html.haml" + - "app/views/layouts/_navigation.html.haml" + - "app/views/schedules/events.html.haml" \ No newline at end of file From 681dfb7889fa2258b908227820ab5bdfd5584393 Mon Sep 17 00:00:00 2001 From: Agrim Mittal Date: Tue, 25 Apr 2017 21:59:23 +0530 Subject: [PATCH 043/185] Add haml-lint to travis script --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index ae8030b0..0be912e1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,4 +25,5 @@ before_script: - RAILS_ENV=test bundle exec rake db:migrate --trace script: - 'bundle exec rubocop -Dc .rubocop.yml' + - 'bundle exec haml-lint app/views' - 'bundle exec rspec --color --format documentation' From 9341edd9cbf176748dd03d730a5b2f2404b09df9 Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Sat, 18 Mar 2017 22:43:46 +0200 Subject: [PATCH 044/185] Change mock accounts credentials The names and usernames don't follow a canonical pattern And the emails point to a valid domain not owned by osem and not reserved for illustration purposes Normalize the users' names and usernames and change the domain of the email addresses to example.com Fix #1365 --- config/environments/development.rb | 24 ++++++++++++------------ spec/features/omniauth_spec.rb | 26 +++++++++++++------------- spec/support/omniauth_macros.rb | 8 ++++---- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/config/environments/development.rb b/config/environments/development.rb index 4c981699..2557e892 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -54,9 +54,9 @@ Osem::Application.configure do provider: 'facebook', uid: 'facebook-test-uid-1', info: { - name: 'admin admin', - email: 'admin@email.com', - username: 'admin_admin' + name: 'facebook user', + email: 'user-facebook@example.com', + username: 'user_facebook' }, credentials: { token: 'fb_mock_token', @@ -69,9 +69,9 @@ Osem::Application.configure do provider: 'google', uid: 'google-test-uid-1', info: { - name: 'simple user', - email: 'user0@email.com', - username: 'simple_user0' + name: 'google user', + email: 'user-google@example.com', + username: 'user_google' }, credentials: { token: 'google_mock_token', @@ -84,9 +84,9 @@ Osem::Application.configure do provider: 'suse', uid: 'suse-test-uid-1', info: { - name: 'another user', - email: 'user1@email.com', - username: 'another_user' + name: 'suse user', + email: 'user-suse@example.com', + username: 'user_suse' }, credentials: { token: 'suse_mock_token', @@ -99,9 +99,9 @@ Osem::Application.configure do provider: 'github', uid: 'github-test-uid-1', info: { - name: 'someother user', - email: 'user2@email.com', - username: 'someother_user' + name: 'github user', + email: 'user-github@example.com', + username: 'user_github' }, credentials: { token: 'github_mock_token', diff --git a/spec/features/omniauth_spec.rb b/spec/features/omniauth_spec.rb index 94949d58..6e05b06d 100644 --- a/spec/features/omniauth_spec.rb +++ b/spec/features/omniauth_spec.rb @@ -18,13 +18,13 @@ feature Openid do within('#openidlinks') do click_link 'omniauth-google' end - expect(flash).to eq('test-1@gmail.com signed in successfully with google') + expect(flash).to eq('test-1@example.com signed in successfully with google') expect(Openid.count).to eq(expected_count_openid) expect(User.count).to eq(expected_count_user) end scenario 'signs in an existing user' do - create(:user, email: 'test-participant-1@google.com') + create(:user, email: 'test-participant-1@example.com') expected_count_openid = Openid.count + 1 expected_count_user = User.count visit '/accounts/sign_in' @@ -33,7 +33,7 @@ feature Openid do within('#openidlinks') do click_link 'omniauth-google' end - expect(flash).to eq('test-participant-1@google.com signed in successfully with google') + expect(flash).to eq('test-participant-1@example.com signed in successfully with google') expect(Openid.count).to eq(expected_count_openid) expect(User.count).to eq(expected_count_user) end @@ -51,7 +51,7 @@ feature Openid do scenario 'adds openid to existing user' do # Sign in user - user = create(:user, email: 'test-participant-1@google.com') + user = create(:user, email: 'test-participant-1@example.com') sign_in user # Add openID to current user @@ -63,15 +63,15 @@ feature Openid do within('#openidlinks') do click_link 'omniauth-google' end - expect(flash).to eq('test-participant-1@google.com signed in successfully with google') + expect(flash).to eq('test-participant-1@example.com signed in successfully with google') expect(Openid.count).to eq(expected_count_openid) expect(User.count).to eq(expected_count_user) - expect(Openid.where(email: 'test-1@gmail.com').first.nil?).to eq(false) + expect(Openid.where(email: 'test-1@example.com').first.nil?).to eq(false) end scenario 'signs in with openID using the same email as another associated openid' do # Sign in user - create(:user, email: 'test-participant-1@google.com') + create(:user, email: 'test-participant-1@example.com') expected_count_openid = Openid.count + 1 expected_count_user = User.count visit '/accounts/sign_in' @@ -80,7 +80,7 @@ feature Openid do within('#openidlinks') do click_link 'omniauth-google' end - expect(flash).to eq('test-participant-1@google.com signed in successfully with google') + expect(flash).to eq('test-participant-1@example.com signed in successfully with google') expect(Openid.count).to eq(expected_count_openid) expect(User.count).to eq(expected_count_user) @@ -93,11 +93,11 @@ feature Openid do within('#openidlinks') do click_link 'omniauth-google' end - expect(flash).to eq('test-participant-1@google.com signed in successfully with google') + expect(flash).to eq('test-participant-1@example.com signed in successfully with google') expect(Openid.count).to eq(expected_count_openid) expect(User.count).to eq(expected_count_user) - expect(Openid.where(email: 'test-participant-1@google.com').first.nil?).to eq(false) - expect(Openid.where(email: 'test-1@gmail.com').first.nil?).to eq(false) + expect(Openid.where(email: 'test-participant-1@example.com').first.nil?).to eq(false) + expect(Openid.where(email: 'test-1@example.com').first.nil?).to eq(false) # Sign in with different openID using same email (test-1@gmail.com) sign_out @@ -109,12 +109,12 @@ feature Openid do within('#openidlinks') do click_link 'omniauth-facebook' end - expect(flash).to eq('test-participant-1@google.com signed in successfully with facebook') + expect(flash).to eq('test-participant-1@example.com signed in successfully with facebook') expect(Openid.count).to eq(expected_count_openid) expect(User.count).to eq(expected_count_user) last_openid = Openid.last expect(last_openid.uid).to eq('facebook-test-uid-1') - expect(last_openid.email).to eq('test-1@gmail.com') + expect(last_openid.email).to eq('test-1@example.com') end end diff --git a/spec/support/omniauth_macros.rb b/spec/support/omniauth_macros.rb index 76351686..1f81efe0 100644 --- a/spec/support/omniauth_macros.rb +++ b/spec/support/omniauth_macros.rb @@ -14,7 +14,7 @@ module OmniauthMacros uid: 'google-test-uid-1', info: { name: 'new user name', - email: 'test-1@gmail.com' + email: 'test-1@example.com' }, credentials: { token: 'mock_token', @@ -30,7 +30,7 @@ module OmniauthMacros uid: 'facebook-test-uid-1', info: { name: 'new user fb name', - email: 'test-1@gmail.com' + email: 'test-1@example.com' }, credentials: { token: 'mock_token', @@ -48,7 +48,7 @@ module OmniauthMacros uid: 'google-test-uid-participant-1', info: { name: 'existing user participant name', - email: 'test-participant-1@google.com' + email: 'test-participant-1@example.com' }, credentials: { token: 'mock_token', @@ -66,7 +66,7 @@ module OmniauthMacros uid: 'google-test-uid-admin-1', info: { name: 'existing user admin name', - email: 'test-admin-1@google.com' + email: 'test-admin-1@example.com' }, credentials: { token: 'mock_token', From 95b88be061da8b4068e7b3e78597282a9fc033ee Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Thu, 13 Apr 2017 22:40:56 +0300 Subject: [PATCH 045/185] Add tests for openid signup with every provider The spec for omniauth doesn't test signup for every provider, and it doesn't test if it has tests for all available providers Also, we no longer use secrets * Add model test to check if the omniauth providers have changed * Test signup using every provider * Replace secretswith environment variables --- spec/features/omniauth_spec.rb | 26 +++++++++++ spec/models/user_spec.rb | 6 +++ spec/support/omniauth_macros.rb | 79 +++++++++++++++++++++++++++++++-- 3 files changed, 107 insertions(+), 4 deletions(-) diff --git a/spec/features/omniauth_spec.rb b/spec/features/omniauth_spec.rb index 6e05b06d..419d1f03 100644 --- a/spec/features/omniauth_spec.rb +++ b/spec/features/omniauth_spec.rb @@ -118,9 +118,35 @@ feature Openid do end end + shared_examples 'sign up with openid' do |provider| + scenario "has option to sign in with #{provider}" do + visit '/accounts/sign_up' + expect(page.has_content?('or sign in using')).to eq true + expect(page.has_link?("omniauth-#{provider}")).to eq true + end + + scenario "sign up with #{provider}" do + expected_count_openid = Openid.count + 1 + expected_count_user = User.count + 1 + visit '/accounts/sign_up' + + mock_auth_accounts + within('#openidlinks') do + click_link "omniauth-#{provider}" + end + expect(flash).to eq("user-#{provider}@example.com signed in successfully with #{provider}") + expect(Openid.count).to eq(expected_count_openid) + expect(User.count).to eq(expected_count_user) + end + end + describe 'omniauth' do if User.omniauth_providers.present? it_behaves_like 'sign in with openid' + + User.omniauth_providers.each do |provider| + it_behaves_like 'sign up with openid', provider + end end end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index def87319..d9b24c79 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -426,4 +426,10 @@ describe User do expect(user.events_registrations).to eq [@events_registration1, @events_registration2] end end + + describe '.omniauth_providers' do + it 'contains providers' do + expect(User.omniauth_providers).to eq [:suse, :google, :facebook, :github] + end + end end diff --git a/spec/support/omniauth_macros.rb b/spec/support/omniauth_macros.rb index 1f81efe0..47ff191e 100644 --- a/spec/support/omniauth_macros.rb +++ b/spec/support/omniauth_macros.rb @@ -2,10 +2,14 @@ module OmniauthMacros # The mock_auth configuration allows you to set per-provider (or default) # authentication hashes to return during integration testing. - Rails.application.secrets.google_key = 'test key google' - Rails.application.secrets.google_secret = 'test secret google' - Rails.application.secrets.facebook_key = 'test key facebook' - Rails.application.secrets.facebook_secret = 'test secret facebook' + ENV['OSEM_GOOGLE_KEY'] = 'test key google' + ENV['OSEM_GOOGLE_SECRET'] = 'test secret google' + ENV['OSEM_FACEBOOK_KEY'] = 'test key facebook' + ENV['OSEM_FACEBOOK_SECRET'] = 'test secret facebook' + ENV['OSEM_SUSE_KEY'] = 'test key suse' + ENV['OSEM_SUSE_SECRET'] = 'test secret suse' + ENV['OSEM_GITHUB_KEY'] = 'test key github' + ENV['OSEM_GITHUB_SECRET'] = 'test secret github' def mock_auth_new_user OmniAuth.config.mock_auth[:google] = @@ -74,4 +78,71 @@ module OmniauthMacros } ) end + + # We use these mock accounts to ensure that the ones which are available in + # development are valid, to test omniauth actions and verify that a mock + # account is available for every supported omniauth provider. + # These must be identical to the ones in /config/environments/development.rb + # Remember to keep them in sync with development.rb + def mock_auth_accounts + OmniAuth.config.mock_auth[:facebook] = + OmniAuth::AuthHash.new( + provider: 'facebook', + uid: 'facebook-test-uid-1', + info: { + name: 'facebook user', + email: 'user-facebook@example.com', + username: 'user_facebook' + }, + credentials: { + token: 'fb_mock_token', + secret: 'fb_mock_secret' + } + ) + + OmniAuth.config.mock_auth[:google] = + OmniAuth::AuthHash.new( + provider: 'google', + uid: 'google-test-uid-1', + info: { + name: 'google user', + email: 'user-google@example.com', + username: 'user_google' + }, + credentials: { + token: 'google_mock_token', + secret: 'google_mock_secret' + } + ) + + OmniAuth.config.mock_auth[:suse] = + OmniAuth::AuthHash.new( + provider: 'suse', + uid: 'suse-test-uid-1', + info: { + name: 'suse user', + email: 'user-suse@example.com', + username: 'user_suse' + }, + credentials: { + token: 'suse_mock_token', + secret: 'suse_mock_secret' + } + ) + + OmniAuth.config.mock_auth[:github] = + OmniAuth::AuthHash.new( + provider: 'github', + uid: 'github-test-uid-1', + info: { + name: 'github user', + email: 'user-github@example.com', + username: 'user_github' + }, + credentials: { + token: 'github_mock_token', + secret: 'github_mock_secret' + } + ) + end end From f057900fb16aba1983f495556d055b8fc08eead7 Mon Sep 17 00:00:00 2001 From: divyanshumehta Date: Sun, 7 May 2017 21:32:39 +0530 Subject: [PATCH 046/185] Added link to lodging section in splashpage's navbar --- app/views/conferences/_lodging.html.haml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/views/conferences/_lodging.html.haml b/app/views/conferences/_lodging.html.haml index 1f87f442..e94286a4 100644 --- a/app/views/conferences/_lodging.html.haml +++ b/app/views/conferences/_lodging.html.haml @@ -1,3 +1,7 @@ += content_for :splash_nav do + %li + %a.smoothscroll{ href: '#lodging' } Lodging + .container .row .col-md-12.text-center From 93404d543f2deffdc6f4311c5b0c55a22f753bb1 Mon Sep 17 00:00:00 2001 From: Eugene Dubinin Date: Tue, 10 Jan 2017 17:07:28 +0200 Subject: [PATCH 047/185] implement user creation by admin --- app/controllers/admin/users_controller.rb | 16 +++++- app/models/ability.rb | 3 ++ app/views/admin/users/_form.html.haml | 37 +++++++------ app/views/admin/users/index.html.haml | 5 +- .../admin/users_controller_spec.rb | 53 ++++++++++++++++++- 5 files changed, 93 insertions(+), 21 deletions(-) diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 44625964..b67792e1 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -6,6 +6,17 @@ module Admin @user = User.new end + def create + @user = User.new(user_params) + @user.skip_confirmation! + if @user.save + redirect_to admin_users_path, notice: 'User successfully created.' + else + flash.now[:error] = "Creating User failed: #{@user.errors.full_messages.join('. ')}." + render :new + end + end + def index @users = User.all end @@ -50,8 +61,9 @@ module Admin private def user_params - params.require(:user).permit(:email, :name, :email_public, :biography, :nickname, :affiliation, :is_admin, :username, :login, :is_disabled, - :tshirt, :mobile, :volunteer_experience, :languages, :to_confirm, role_ids: []) + params.require(:user).permit(:email, :name, :email_public, :biography, :nickname, :affiliation, :is_admin, + :username, :login, :is_disabled, :tshirt, :mobile, :volunteer_experience, + :languages, :to_confirm, :password, role_ids: []) end end end diff --git a/app/models/ability.rb b/app/models/ability.rb index decf8cb8..654345b8 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -119,6 +119,9 @@ class Ability # 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 diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml index 888260de..36a4919e 100644 --- a/app/views/admin/users/_form.html.haml +++ b/app/views/admin/users/_form.html.haml @@ -1,25 +1,28 @@ = semantic_form_for [:admin, @user] do |f| = f.inputs 'Basic Information' do - .pull-right - %b - Confirmed? - - if can? :toggle_confirmation, @user - = check_box_tag @user.id, @user.id, @user.confirmed?, - method: :patch, - url: "/admin/users/#{@user.id}/toggle_confirmation?user[to_confirm]=", - class: 'switch-checkbox', - readonly: false, - data: { size: 'small', on_color: 'success', off_color: 'warning', on_text: 'Yes', off_text: 'No' } - - else - = check_box_tag @user.id, @user.id, @user.confirmed?, - method: :patch, - url: "/admin/users/#{@user.id}/toggle_confirmation?user[to_confirm]=", - class: 'switch-checkbox', - readonly: true, - data: { size: 'small', on_color: 'success', off_color: 'warning', on_text: 'Yes', off_text: 'No' } + - unless @user.new_record? + .pull-right + %b + Confirmed? + - if can? :toggle_confirmation, @user + = check_box_tag @user.id, @user.id, @user.confirmed?, + method: :patch, + url: "/admin/users/#{@user.id}/toggle_confirmation?user[to_confirm]=", + class: 'switch-checkbox', + readonly: false, + data: { size: 'small', on_color: 'success', off_color: 'warning', on_text: 'Yes', off_text: 'No' } + - else + = check_box_tag @user.id, @user.id, @user.confirmed?, + method: :patch, + url: "/admin/users/#{@user.id}/toggle_confirmation?user[to_confirm]=", + class: 'switch-checkbox', + readonly: true, + data: { size: 'small', on_color: 'success', off_color: 'warning', on_text: 'Yes', off_text: 'No' } = f.input :is_admin, hint: 'An admin can create a new conference, manage users and make other users admins.' = f.input :name, as: :string + = f.input :username, :as => :string if @user.new_record? = f.input :email + = f.input :password if @user.new_record? = f.input :affiliation, as: :string = f.input :biography, input_html: { rows: 10, data: { provide: 'markdown-editable' } }, hint: markdown_hint diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml index 14cfcc0d..6ac6f03c 100644 --- a/app/views/admin/users/index.html.haml +++ b/app/views/admin/users/index.html.haml @@ -1,10 +1,13 @@ .row .col-md-12 .page-header - %h2 + %h1 Users - if @users = "(#{@users.length})" + - if can? :create, User + .pull-right + =link_to 'Add User', new_admin_user_path, :class => 'button btn btn-default btn-info' .row .col-md-12.table-responsive %table.table.table-striped.table-bordered.table-hover.datatable diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb index 6114f6ed..c0ba43ba 100644 --- a/spec/controllers/admin/users_controller_spec.rb +++ b/spec/controllers/admin/users_controller_spec.rb @@ -6,7 +6,7 @@ describe Admin::UsersController do sign_in(admin) end describe 'GET #index' do - it 'populates an array of users' do + it 'sets up users array with existing users records' do user1 = create(:user, email: 'user1@email.osem') user2 = create(:user, email: 'user2@email.osem') user_deleted = User.find_by(name: 'User deleted') @@ -50,4 +50,55 @@ describe Admin::UsersController do end end end + describe 'GET #new' do + it 'sets up a user instance for the form' do + get :new + expect(assigns(:user)).to be_instance_of(User) + end + it 'renders new user template' do + get :new + expect(response).to render_template :new + end + end + + describe 'POST #create' do + context 'saves successfuly' do + before do + post :create, user: attributes_for(:user) + end + + it 'redirects to admin users index path' do + expect(response).to redirect_to admin_users_path + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match('User successfully created.') + end + + it 'creates new user' do + expect(User.find(user.id)).to be_instance_of(User) + end + end + + context 'save fails' do + before do + allow_any_instance_of(User).to receive(:save).and_return(false) + post :create, user: attributes_for(:user) + end + + it 'renders new template' do + expect(response).to render_template('new') + end + + it 'shows error in flash message' do + expect(flash[:error]).to match("Creating User failed: #{user.errors.full_messages.join('. ')}.") + end + + it 'does not create new user' do + expect do + post :create, user: attributes_for(:user) + end.not_to change{ Event.count } + end + end + end end From 8a0f3c99b0e4376e9c82f264b2935f1cb372079c Mon Sep 17 00:00:00 2001 From: selini Date: Tue, 21 Mar 2017 21:08:53 +0200 Subject: [PATCH 048/185] Create links for speakers in admin/reports#index --- app/helpers/application_helper.rb | 4 ++++ app/views/admin/reports/_all_events.html.haml | 5 ++++- app/views/admin/reports/_events_with_requirements.html.haml | 3 ++- .../admin/reports/_events_without_commercials.html.haml | 3 ++- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index c82e6bab..5bb129ae 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -597,4 +597,8 @@ module ApplicationHelper end concurrent_events end + + def speaker_links(event) + event.speakers.map{ |speaker| link_to speaker.name, admin_user_path(speaker) }.join(', ').html_safe + end end diff --git a/app/views/admin/reports/_all_events.html.haml b/app/views/admin/reports/_all_events.html.haml index 6aef4178..7e76e927 100644 --- a/app/views/admin/reports/_all_events.html.haml +++ b/app/views/admin/reports/_all_events.html.haml @@ -27,7 +27,10 @@ %td = link_to event.title, edit_admin_conference_program_event_path(@conference.short_title, event) %br - .small (Presented by #{event.speaker_names}) + .small + (Presented by + = speaker_links(event) + ) - %w(registered biography commercials subtitle difficulty_level).each do |info| %td{'data-order' => "#{progress_status[info]}"} diff --git a/app/views/admin/reports/_events_with_requirements.html.haml b/app/views/admin/reports/_events_with_requirements.html.haml index b0759af8..9e01a8ae 100644 --- a/app/views/admin/reports/_events_with_requirements.html.haml +++ b/app/views/admin/reports/_events_with_requirements.html.haml @@ -21,7 +21,8 @@ %tr %td= event.id %td= link_to event.title, edit_admin_conference_program_event_path(@conference.short_title, event) - %td #{event.speaker_names} + %td + = speaker_links(event) %td= event.description %td= event.room.name if event.room %td= event.time.to_date if event.time diff --git a/app/views/admin/reports/_events_without_commercials.html.haml b/app/views/admin/reports/_events_without_commercials.html.haml index 1aaff358..7156beb9 100644 --- a/app/views/admin/reports/_events_without_commercials.html.haml +++ b/app/views/admin/reports/_events_without_commercials.html.haml @@ -17,4 +17,5 @@ %tr %td= event.id %td= link_to event.title, edit_admin_conference_program_event_path(@conference.short_title, event) - %td #{event.speaker_names} + %td + = speaker_links(event) From 0aff947f05a8f87bedc91d484f9204869ff8cceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ana=20Mar=C3=ADa=20Mart=C3=ADnez=20G=C3=B3mez?= Date: Thu, 11 May 2017 11:59:33 +0200 Subject: [PATCH 049/185] Fix haml-lint error The error was introduced when merging https://github.com/openSUSE/osem/pull/1469 as a offense was introduced since the tests there were run and the PR got merged. --- app/views/admin/users/index.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml index 6ac6f03c..204665a3 100644 --- a/app/views/admin/users/index.html.haml +++ b/app/views/admin/users/index.html.haml @@ -7,7 +7,7 @@ = "(#{@users.length})" - if can? :create, User .pull-right - =link_to 'Add User', new_admin_user_path, :class => 'button btn btn-default btn-info' + = link_to 'Add User', new_admin_user_path, :class => 'button btn btn-default btn-info' .row .col-md-12.table-responsive %table.table.table-striped.table-bordered.table-hover.datatable From 1c12200003bc16d35325dbf75f743bd94c2f4ddb Mon Sep 17 00:00:00 2001 From: Siddhant Bajaj Date: Mon, 24 Apr 2017 15:39:39 +0530 Subject: [PATCH 050/185] Fixed paper trail inconsistent results for numeric values There is a known issue in paper_trail that whenever we Query the 'versions.object' column it evaluates inconsistent results for numeric values due to limitations of SQL wildcard matchers against the serialized objects. So to fix this issue I have manually formed the where query instead of using where_object and where_object_changes. I have also added test for the same. Fixes #1307 --- app/controllers/admin/events_controller.rb | 4 +-- .../admin/events_controller_spec.rb | 26 +++++++++++++++++++ spec/features/versions_spec.rb | 25 ++++++++++++++---- 3 files changed, 48 insertions(+), 7 deletions(-) create mode 100644 spec/controllers/admin/events_controller_spec.rb diff --git a/app/controllers/admin/events_controller.rb b/app/controllers/admin/events_controller.rb index 6cf31ddb..a3b6a3cb 100644 --- a/app/controllers/admin/events_controller.rb +++ b/app/controllers/admin/events_controller.rb @@ -50,8 +50,8 @@ module Admin @ratings = @event.votes.includes(:user) @difficulty_levels = @program.difficulty_levels @versions = @event.versions | - PaperTrail::Version.where(item_type: 'Commercial').where_object(commercialable_id: @event.id, commercialable_type: 'Event') | - PaperTrail::Version.where(item_type: 'Commercial').where_object_changes(commercialable_id: @event.id, commercialable_type: 'Event') | + PaperTrail::Version.where(item_type: 'Commercial').where('object LIKE ?', "%commercialable_id: #{@event.id}\ncommercialable_type: Event%") | + PaperTrail::Version.where(item_type: 'Commercial').where('object_changes LIKE ?', "%commercialable_id:\n- \n- #{@event.id}\ncommercialable_type:\n- \n- Event%") | PaperTrail::Version.where(item_type: 'Vote').where('object_changes LIKE ?', "%\nevent_id:\n- \n- #{@event.id}\n%") | PaperTrail::Version.where(item_type: 'Vote').where('object LIKE ?', "%\nevent_id: #{@event.id}\n%") end diff --git a/spec/controllers/admin/events_controller_spec.rb b/spec/controllers/admin/events_controller_spec.rb new file mode 100644 index 00000000..a413ba7a --- /dev/null +++ b/spec/controllers/admin/events_controller_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' + +describe Admin::EventsController do + let(:conference) { create(:conference) } + let(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } + let(:organizer) { create(:user, role_ids: organizer_role.id) } + let!(:event_without_commercial) { create(:event, program: conference.program) } + let!(:event_with_commercial) { create(:event, program: conference.program) } + let!(:event_commercial) { create(:event_commercial, commercialable: event_with_commercial, url: 'https://www.youtube.com/watch?v=M9bq_alk-sw') } + + with_versioning do + describe 'GET #show' do + before :each do + sign_in(organizer) + get :show, id: event_without_commercial.id, conference_id: conference.short_title + end + + it 'assigns versions' do + versions = event_without_commercial.versions + expect(event_without_commercial.id).to eq event_commercial.id + expect(event_commercial.id).not_to eq event_commercial.commercialable_id + expect(assigns(:versions)).to eq versions + end + end + end +end diff --git a/spec/features/versions_spec.rb b/spec/features/versions_spec.rb index ba43bc27..ff73eee0 100644 --- a/spec/features/versions_spec.rb +++ b/spec/features/versions_spec.rb @@ -4,6 +4,8 @@ feature 'Version' do let!(:conference) { create(:conference) } let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } + let(:event_with_commercial) { create(:event, program: conference.program) } + let(:event_commercial) { create(:event_commercial, commercialable: event_with_commercial, url: 'https://www.youtube.com/watch?v=M9bq_alk-sw') } before(:each) do sign_in organizer @@ -265,15 +267,28 @@ feature 'Version' do end scenario 'display changes in event commercials', feature: true, versioning: true, js: true do - event = create(:event, program: conference.program) - event_commercial = create(:event_commercial, commercialable: event, url: 'https://www.youtube.com/watch?v=M9bq_alk-sw') + event_commercial event_commercial.update_attributes(url: 'https://www.youtube.com/watch?v=VNkDJk5_9eU') event_commercial.destroy visit admin_revision_history_path - expect(page).to have_text("Someone (probably via the console) created new commercial in event #{event.title} in conference #{conference.short_title}") - expect(page).to have_text("Someone (probably via the console) updated url of commercial in event #{event.title} in conference #{conference.short_title}") - expect(page).to have_text("Someone (probably via the console) deleted commercial in event #{event.title} in conference #{conference.short_title}") + expect(page).to have_text("Someone (probably via the console) created new commercial in event #{event_with_commercial.title} in conference #{conference.short_title}") + expect(page).to have_text("Someone (probably via the console) updated url of commercial in event #{event_with_commercial.title} in conference #{conference.short_title}") + expect(page).to have_text("Someone (probably via the console) deleted commercial in event #{event_with_commercial.title} in conference #{conference.short_title}") + end + + scenario 'display changes in event commercials in event history', feature: true, versioning: true, js: true do + event_without_commercial = create(:event, program: conference.program) + event_commercial + + visit admin_conference_program_event_path(conference.short_title, event_with_commercial) + click_link 'History' + expect(page).to have_text('Someone (probably via the console) created new commercial') + visit admin_conference_program_event_path(conference.short_title, event_without_commercial) + click_link 'History' + expect(event_commercial.id).not_to eq event_commercial.commercialable_id + expect(event_without_commercial.id).to eq event_commercial.id + expect(page).to have_no_text('Someone (probably via the console) created new commercial') end scenario 'display changes in users_role', feature: true, versioning: true, js: true do From fdff485b3e53d12615130c83ac7b2c9ac228354c Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Wed, 3 May 2017 23:42:53 +0300 Subject: [PATCH 051/185] Allow confirmed speakers to register anytime If the registration period is over then speakers of confirmed events can't register anymore. They should be able to, since they are gonna be there anyway. * Allow the speakers of confirmed events to register regardless of the registration period * Provision for registrations of confirmed speakers, so as not to exceed the registration limit * Add scope for registered speakers Fix #829 and fix #802 --- app/models/ability.rb | 2 +- app/models/conference.rb | 9 ++++++++- app/models/program.rb | 4 ++++ app/views/admin/conferences/edit.html.haml | 2 +- app/views/conferences/_conference_details.html.haml | 4 ++-- 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/app/models/ability.rb b/app/models/ability.rb index 654345b8..ff1628a1 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -80,7 +80,7 @@ class Ability can [:new, :create], Registration do |registration| conference = registration.conference - conference.registration_open? && !conference.registration_limit_exceeded? + conference.registration_open? && !conference.registration_limit_exceeded? || conference.program.speakers.confirmed.include?(user) end can :index, Ticket diff --git a/app/models/conference.rb b/app/models/conference.rb index 224c1dfb..1c4ccc73 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -594,8 +594,15 @@ class Conference < ActiveRecord::Base (email_settings.conference_registration_dates_updated_subject.present? && email_settings.conference_registration_dates_updated_body.present?) end + ## + # Checks if the registration limit has been exceeded + # Additionally, it takes into account the confirmed speakers that haven't registered yet + # + # ====Returns + # * +True+ -> If the registration limit has been reached or exceeded + # * +False+ -> If the registration limit hasn't been exceeded def registration_limit_exceeded? - registration_limit > 0 && registrations.count >= registration_limit + registration_limit > 0 && registrations.count + program.speakers.confirmed.count - program.speakers.confirmed.registered(program.conference).count >= registration_limit end # Returns an hexadecimal color given a collection. The returned color changed diff --git a/app/models/program.rb b/app/models/program.rb index e8114f99..c7168849 100644 --- a/app/models/program.rb +++ b/app/models/program.rb @@ -46,6 +46,10 @@ class Program < ActiveRecord::Base def confirmed joins(:events).where(events: { state: :confirmed }) end + + def registered(conference) + joins(:registrations).where('registrations.conference_id = ?', conference.id) + end end accepts_nested_attributes_for :event_types, allow_destroy: true diff --git a/app/views/admin/conferences/edit.html.haml b/app/views/admin/conferences/edit.html.haml index de8d6316..5aa717ea 100644 --- a/app/views/admin/conferences/edit.html.haml +++ b/app/views/admin/conferences/edit.html.haml @@ -24,5 +24,5 @@ = f.input :start_hour, input_html: {size: 2, type: 'number', min: 0, max: 23} = f.input :end_hour, input_html: {size: 2, type: 'number', min: 1, max: 24} = f.inputs name: 'Registrations' do - = f.input :registration_limit, as: :number, in: 0..9999, hint: 'Limit the number of registrations to the conference (0 no limit). You currently have ' + pluralize(@conference.registrations.count, 'registration') + = f.input :registration_limit, as: :number, in: 0..9999, hint: 'Limit the number of registrations to the conference (0 no limit). Please note that the registration limit doesn\'t apply to speakers of confirmed events (they will still be able to register even if it has been reached). You currently have ' + pluralize(@conference.registrations.count, 'registration') = f.action :submit, as: :button, button_html: {class: 'btn btn-primary'} diff --git a/app/views/conferences/_conference_details.html.haml b/app/views/conferences/_conference_details.html.haml index 6ee51573..bdbd5fc6 100644 --- a/app/views/conferences/_conference_details.html.haml +++ b/app/views/conferences/_conference_details.html.haml @@ -27,8 +27,8 @@ - if conference.user_registered?(current_user) = link_to "My Registration", conference_conference_registration_path(conference.short_title), class: 'btn btn-default' - else - = link_to "Register", new_conference_conference_registration_path(conference.short_title), class: "btn btn-default", disabled: conference.registration_limit_exceeded? - - if conference.registration_limit_exceeded? + = link_to "Register", new_conference_conference_registration_path(conference.short_title), class: "btn btn-default", disabled: cannot?(:new, Registration.new(conference_id: conference.id)) + - if cannot?(:new, Registration.new(conference_id: conference.id)) && conference.registration_limit_exceeded? Sorry, no places left - if !current_user.nil? && current_user.proposal_count(conference) > 0 = link_to "My Proposals", conference_program_proposals_path(conference.short_title), class: 'btn btn-default' From dbf7b73d1a42d36706ad2b300397fe8ded9dae9e Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Thu, 4 May 2017 13:55:37 +0300 Subject: [PATCH 052/185] Test ConferenceRegistration#new behaviour Create shared example for when the user can create a new registration Change older tests to use the shared example Add tests for confirmed speakers --- ...conference_registration_controller_spec.rb | 146 +++++++++++------- 1 file changed, 94 insertions(+), 52 deletions(-) diff --git a/spec/controllers/conference_registration_controller_spec.rb b/spec/controllers/conference_registration_controller_spec.rb index c919d90d..9afaaed8 100644 --- a/spec/controllers/conference_registration_controller_spec.rb +++ b/spec/controllers/conference_registration_controller_spec.rb @@ -23,12 +23,33 @@ describe ConferenceRegistrationsController, type: :controller do end end + shared_examples 'can access #new action' do |user, ichain| + before :each do + sign_in send(user) if user + stub_const('ENV', ENV.to_hash.merge('OSEM_ICHAIN_ENABLED' => ichain)) + get :new, conference_id: conference.short_title + end + + it 'user variable exists' do + expect(assigns(:user)).not_to be_nil + end + + it 'renders the new template' do + expect(response).to render_template('new') + end + end + context 'user is signed in' do before :each do sign_in user end describe 'GET #new' do + let(:not_registered_confirmed_speaker) { create(:user) } + let(:registered_confirmed_speaker) { create(:user) } + let!(:speaker_registration) { create(:registration, conference: conference, user: registered_confirmed_speaker, created_at: 1.day.ago) } + let!(:confirmed_event) { create(:event, program: conference.program, speakers: [not_registered_confirmed_speaker, registered_confirmed_speaker], state: 'confirmed') } + context 'registration period open' do before :each do create(:registration_period, conference: conference, start_date: 3.days.ago, end_date: 1.day.from_now) @@ -40,52 +61,36 @@ describe ConferenceRegistrationsController, type: :controller do conference.save! end - context 'OSEM_ICHAIN_ENABLED is true' do - before :each do - stub_const('ENV', ENV.to_hash.merge('OSEM_ICHAIN_ENABLED' => 'true')) - end - - context 'user registered' do - it_behaves_like 'access #new action', :registered_user, 'true', '/conferences/myconf/register/edit', nil - end - - context 'user not registered' do - before :each do - get :new, conference_id: conference.short_title - end - - it 'user variable exists' do - expect(assigns(:user)).not_to be_nil - end - - it 'renders the new template' do - expect(response).to render_template('new') - end - end + context 'OSEM_ICHAIN_ENABLED true, user registered' do + it_behaves_like 'access #new action', :registered_user, 'true', '/conferences/myconf/register/edit', nil end - context 'OSEM_ICHAIN_ENABLED is false' do - before :each do - stub_const('ENV', ENV.to_hash.merge('OSEM_ICHAIN_ENABLED' => 'false')) - end + context 'OSEM_ICHAIN_ENABLED true, user not registered' do + it_behaves_like 'can access #new action', :not_registered_user, 'true' + end - context 'user registered' do - it_behaves_like 'access #new action', :registered_user, 'false', '/conferences/myconf/register/edit', nil - end + context 'OSEM_ICHAIN_ENABLED true, user registered, confirmed speaker' do + it_behaves_like 'access #new action', :registered_confirmed_speaker, 'true', '/conferences/myconf/register/edit', nil + end - context 'user not registered' do - before :each do - get :new, conference_id: conference.short_title - end + context 'OSEM_ICHAIN_ENABLED true, user not registered, confirmed speaker' do + it_behaves_like 'can access #new action', :not_registered_confirmed_speaker, 'true' + end - it 'user variable exists' do - expect(assigns(:user)).not_to be_nil - end + context 'OSEM_ICHAIN_ENABLED false, user registered' do + it_behaves_like 'access #new action', :registered_user, 'false', '/conferences/myconf/register/edit', nil + end - it 'renders the new template' do - expect(response).to render_template('new') - end - end + context 'OSEM_ICHAIN_ENABLED false, user not registered' do + it_behaves_like 'can access #new action', :not_registered_user, 'false' + end + + context 'OSEM_ICHAIN_ENABLED false, user registered, confirmed speaker' do + it_behaves_like 'access #new action', :registered_confirmed_speaker, 'false', '/conferences/myconf/register/edit', nil + end + + context 'OSEM_ICHAIN_ENABLED false, user not registered, confirmed speaker' do + it_behaves_like 'can access #new action', :not_registered_confirmed_speaker, 'false' end end @@ -103,6 +108,14 @@ describe ConferenceRegistrationsController, type: :controller do it_behaves_like 'access #new action', :not_registered_user, 'true', '/', 'Sorry, you can not register for My Conference. Registration limit exceeded or the registration is not open.' end + context 'OSEM_ICHAIN_ENABLED true, user registered, confirmed speaker' do + it_behaves_like 'access #new action', :registered_confirmed_speaker, 'true', '/conferences/myconf/register/edit', nil + end + + context 'OSEM_ICHAIN_ENABLED true, user not registered, confirmed speaker' do + it_behaves_like 'can access #new action', :not_registered_confirmed_speaker, 'true' + end + context 'OSEM_ICHAIN_ENABLED false, user registered' do it_behaves_like 'access #new action', :registered_user, 'false', '/conferences/myconf/register/edit', nil end @@ -110,6 +123,14 @@ describe ConferenceRegistrationsController, type: :controller do context 'OSEM_ICHAIN_ENABLED false, user not registered' do it_behaves_like 'access #new action', :not_registered_user, 'false', '/', 'Sorry, you can not register for My Conference. Registration limit exceeded or the registration is not open.' end + + context 'OSEM_ICHAIN_ENABLED false, user registered, confirmed speaker' do + it_behaves_like 'access #new action', :registered_confirmed_speaker, 'false', '/conferences/myconf/register/edit', nil + end + + context 'OSEM_ICHAIN_ENABLED false, user not registered, confirmed speaker' do + it_behaves_like 'can access #new action', :not_registered_confirmed_speaker, 'false' + end end end @@ -132,6 +153,14 @@ describe ConferenceRegistrationsController, type: :controller do it_behaves_like 'access #new action', :not_registered_user, 'true', '/', 'Sorry, you can not register for My Conference. Registration limit exceeded or the registration is not open.' end + context 'OSEM_ICHAIN_ENABLED true, user registered, confirmed speaker' do + it_behaves_like 'access #new action', :registered_confirmed_speaker, 'true', '/conferences/myconf/register/edit', nil + end + + context 'OSEM_ICHAIN_ENABLED true, user not registered, confirmed speaker' do + it_behaves_like 'can access #new action', :not_registered_confirmed_speaker, 'true' + end + context 'OSEM_ICHAIN_ENABLED false, user registered' do it_behaves_like 'access #new action', :registered_user, 'false', '/conferences/myconf/register/edit', nil end @@ -139,6 +168,14 @@ describe ConferenceRegistrationsController, type: :controller do context 'OSEM_ICHAIN_ENABLED false, user not registered' do it_behaves_like 'access #new action', :not_registered_user, 'false', '/', 'Sorry, you can not register for My Conference. Registration limit exceeded or the registration is not open.' end + + context 'OSEM_ICHAIN_ENABLED false, user registered, confirmed speaker' do + it_behaves_like 'access #new action', :registered_confirmed_speaker, 'false', '/conferences/myconf/register/edit', nil + end + + context 'OSEM_ICHAIN_ENABLED false, user not registered, confirmed speaker' do + it_behaves_like 'can access #new action', :not_registered_confirmed_speaker, 'false' + end end context 'registration limit exceeded' do @@ -155,6 +192,14 @@ describe ConferenceRegistrationsController, type: :controller do it_behaves_like 'access #new action', :not_registered_user, 'true', '/', 'Sorry, you can not register for My Conference. Registration limit exceeded or the registration is not open.' end + context 'OSEM_ICHAIN_ENABLED true, user registered, confirmed speaker' do + it_behaves_like 'access #new action', :registered_confirmed_speaker, 'true', '/conferences/myconf/register/edit', nil + end + + context 'OSEM_ICHAIN_ENABLED true, user not registered, confirmed speaker' do + it_behaves_like 'can access #new action', :not_registered_confirmed_speaker, 'true' + end + context 'OSEM_ICHAIN_ENABLED false, user registered' do it_behaves_like 'access #new action', :registered_user, 'false', '/conferences/myconf/register/edit', nil end @@ -162,6 +207,14 @@ describe ConferenceRegistrationsController, type: :controller do context 'OSEM_ICHAIN_ENABLED false, user not registered' do it_behaves_like 'access #new action', :not_registered_user, 'false', '/', 'Sorry, you can not register for My Conference. Registration limit exceeded or the registration is not open.' end + + context 'OSEM_ICHAIN_ENABLED false, user registered, confirmed speaker' do + it_behaves_like 'access #new action', :registered_confirmed_speaker, 'false', '/conferences/myconf/register/edit', nil + end + + context 'OSEM_ICHAIN_ENABLED false, user not registered, confirmed speaker' do + it_behaves_like 'can access #new action', :not_registered_confirmed_speaker, 'false' + end end end end @@ -345,18 +398,7 @@ describe ConferenceRegistrationsController, type: :controller do end context 'OSEM_ICHAIN_ENABLED is false' do - before :each do - stub_const('ENV', ENV.to_hash.merge('OSEM_ICHAIN_ENABLED' => 'false')) - get :new, conference_id: conference.short_title - end - - it 'user variable exists' do - expect(assigns(:user)).not_to be_nil - end - - it 'renders the new template' do - expect(response).to render_template('new') - end + it_behaves_like 'can access #new action', nil, 'false' end end From 53a2246ff233a5df0e6a07efc8556c1979985f73 Mon Sep 17 00:00:00 2001 From: Siddhant Bajaj Date: Fri, 12 May 2017 00:42:48 +0530 Subject: [PATCH 053/185] Fixed issue in notification drop down menu Fixed an indentation issue in notification drop down layout. --- app/views/layouts/_navigation.html.haml | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/app/views/layouts/_navigation.html.haml b/app/views/layouts/_navigation.html.haml index 844f74a9..48066cd7 100644 --- a/app/views/layouts/_navigation.html.haml +++ b/app/views/layouts/_navigation.html.haml @@ -28,19 +28,18 @@ - if can? :index, Comment %ul.nav.navbar-nav.navbar-right %li.dropdown - %a.dropdown-toggle{"data-toggle" => "dropdown", href: '#'} - - if unread_notifications(current_user) - Notifications (#{unread_notifications(current_user).length}) - %span.fa.fa-comment - %b.caret - %ul.dropdown-menu - - if unread_notifications(current_user).length > 0 - %li.dropdown-header Last 5 Comments for: - - unread_notifications(current_user).limit(5).group_by{ |comment| comment.commentable}.each do |event, comments| - %li= link_to("#{event.title}(#{comments.count})", admin_conference_program_event_path(event.program.conference.short_title, event.id)) - %li.divider - %li= link_to "See all unread Comments (#{unread_notifications(current_user).length})", admin_comments_path - %li= link_to 'See all Comments', admin_comments_path(anchor: 'all_comments') + %a.dropdown-toggle{"data-toggle" => "dropdown", :href => "#"} + Notifications (#{unread_notifications(current_user).length}) + %span.fa.fa-comment + %b.caret + %ul.dropdown-menu + - if unread_notifications(current_user).length > 0 + %li.dropdown-header Last 5 Comments for: + - unread_notifications(current_user).limit(5).group_by{ |comment| comment.commentable}.each do |event, comments| + %li= link_to("#{event.title}(#{comments.count})", admin_conference_program_event_path(event.program.conference.short_title, event.id)) + %li.divider + %li= link_to "See all unread Comments (#{unread_notifications(current_user).length})", admin_comments_path + %li= link_to 'See all Comments', admin_comments_path(anchor: 'all_comments') - else %ul.nav.navbar-nav.navbar-right - if ENV['OSEM_ICHAIN_ENABLED'] == 'true' From 4b72d383ea1f07708cae347291804a2fa29b7797 Mon Sep 17 00:00:00 2001 From: Chaitanya Date: Thu, 11 May 2017 16:32:44 +0530 Subject: [PATCH 054/185] Fix Travis-Ci errors Rubocop offenses lead to failure of Travis-ci build. Offensive files are added as exclude files of respective offense in rubocop_todo.yml --- .rubocop_todo.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index ccc0aca3..11fedc97 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -14,7 +14,7 @@ Bundler/OrderedGems: Exclude: - 'Gemfile' -# Offense count: 28 +# Offense count: 29 Lint/AmbiguousBlockAssociation: Exclude: - 'app/models/comment.rb' @@ -28,6 +28,7 @@ Lint/AmbiguousBlockAssociation: - 'spec/controllers/proposals_controller_spec.rb' - 'spec/controllers/schedules_controller_spec.rb' - 'spec/models/user_spec.rb' + - 'spec/controllers/admin/users_controller_spec.rb' # Offense count: 1 # Cop supports --auto-correct. @@ -80,10 +81,12 @@ Metrics/LineLength: Metrics/MethodLength: Max: 56 -# Offense count: 1 +# Offense count: 2 # Configuration parameters: CountComments. Metrics/ModuleLength: Max: 472 + Exclude: + - 'app/helpers/application_helper.rb' # Offense count: 14 Metrics/PerceivedComplexity: From e73baa2754fb02c807afa3457ce08b141d9029a6 Mon Sep 17 00:00:00 2001 From: hitman Date: Tue, 21 Mar 2017 16:46:09 +0530 Subject: [PATCH 055/185] add validation for name, used and quantity --- app/helpers/application_helper.rb | 1 + app/models/resource.rb | 8 +++++--- app/views/admin/resources/_form.html.haml | 2 +- spec/models/resource_spec.rb | 18 ++++++++++++++++++ 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 5bb129ae..0d281c18 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -578,6 +578,7 @@ module ApplicationHelper end def quantity_left_of(resource) + return '-/-' if resource.quantity.blank? "#{resource.quantity - resource.used}/#{resource.quantity}" end diff --git a/app/models/resource.rb b/app/models/resource.rb index c113522e..ce6e7b94 100644 --- a/app/models/resource.rb +++ b/app/models/resource.rb @@ -1,10 +1,12 @@ class Resource < ActiveRecord::Base belongs_to :conference - validate :used_less_than_quantity + validates :name, :used, :quantity, presence: true + validates :used, :quantity, numericality: { greater_than_or_equal_to: 0, only_integer: true } + validate :used_no_more_than_quantity private - def used_less_than_quantity - errors.add(:used, 'can not be higher than total quantity') unless used <= quantity + def used_no_more_than_quantity + errors.add(:used, 'cannot be higher than total quantity') if used.present? && quantity.present? && used > quantity end end diff --git a/app/views/admin/resources/_form.html.haml b/app/views/admin/resources/_form.html.haml index 818bfc27..ef999104 100644 --- a/app/views/admin/resources/_form.html.haml +++ b/app/views/admin/resources/_form.html.haml @@ -9,7 +9,7 @@ .col-md-8 = semantic_form_for(@resource, :url => (@resource.new_record? ? admin_conference_resources_path : admin_conference_resource_path(@conference.short_title, @resource))) do |f| = f.input :name - = f.input :description, input_html: { rows: 5, data: { provide: "markdown-editable" } } + = f.input :description, input_html: { rows: 5, data: { provide: 'markdown-editable' } } = f.input :used = f.input :quantity %p.text-right diff --git a/spec/models/resource_spec.rb b/spec/models/resource_spec.rb index 51406f62..03a6a502 100644 --- a/spec/models/resource_spec.rb +++ b/spec/models/resource_spec.rb @@ -4,6 +4,24 @@ describe Resource do let(:conference) { create(:conference) } let(:resource) { create :resource } + it { is_expected.to validate_presence_of(:name) } + + it { is_expected.to validate_presence_of(:used) } + + it { is_expected.to validate_presence_of(:quantity) } + + it { is_expected.to validate_numericality_of(:used) } + + it { is_expected.to validate_numericality_of(:quantity) } + + it { is_expected.not_to allow_value(-1).for(:used) } + + it { is_expected.to allow_value(0).for(:used) } + + it { is_expected.not_to allow_value(-1).for(:quantity) } + + it { is_expected.to allow_value(0).for(:quantity) } + it 'has a valid factory' do expect(build(:resource)).to be_valid end From 6c7e8bc8a16b500460f5742f6e5681e24d64947c Mon Sep 17 00:00:00 2001 From: Agrim Mittal Date: Wed, 5 Apr 2017 01:31:05 +0530 Subject: [PATCH 056/185] Add rake task for resources --- lib/tasks/normalize_resources.rake | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 lib/tasks/normalize_resources.rake diff --git a/lib/tasks/normalize_resources.rake b/lib/tasks/normalize_resources.rake new file mode 100644 index 00000000..e05d0d69 --- /dev/null +++ b/lib/tasks/normalize_resources.rake @@ -0,0 +1,12 @@ +namespace :data do + desc 'Update resources with nil quantity/used fields' + task normalize_resources: :environment do + Resource.where('used is ? or quantity is ?', nil, nil).each do |resource| + resource.used = 0 if resource.used.blank? + resource.quantity = resource.used if resource.quantity.blank? + unless resource.save + puts "Failed to update resource #{resource.name} (ID #{resource.id})" + end + end + end +end From 008ccf8b6d09d84e73ac139d1b587b3d2f7fc286 Mon Sep 17 00:00:00 2001 From: Chaitanya Date: Sat, 13 May 2017 21:08:40 +0530 Subject: [PATCH 057/185] Add user path to Attendee and Speaker avatar in registration show page Avatars of attendee and speaker are not linked to respective attendee and speaker. Add user path to each avatar to give more information of attendee and speaker --- app/views/conference_registrations/show.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/conference_registrations/show.html.haml b/app/views/conference_registrations/show.html.haml index 53d55bd8..c510a263 100644 --- a/app/views/conference_registrations/show.html.haml +++ b/app/views/conference_registrations/show.html.haml @@ -142,7 +142,7 @@ Registered = word_pluralize(@conference.participants.count, 'Attendee') - @conference.participants.each do |participant| - = image_tag(participant.gravatar_url(size: '25'), title: "#{participant.name}!", class: 'img-circle') + = link_to image_tag(participant.gravatar_url(size: '25'), title: "#{participant.name}!", class: 'img-circle'), user_path(participant) .col-md-4.col-md-offset-2 - if @conference.program.speakers.confirmed.any? %h4 @@ -153,4 +153,4 @@ Confirmed = word_pluralize(@conference.program.speakers.confirmed.count, 'Speaker') - @conference.program.speakers.confirmed.each do |speaker| - = image_tag(speaker.gravatar_url(size: '25'), title: "#{speaker.name}!", class: 'img-circle') + = link_to image_tag(speaker.gravatar_url(size: '25'), title: "#{speaker.name}!", class: 'img-circle'), user_path(speaker) From 207b3611c67cdab74bb0051abd69f544849ae6bb Mon Sep 17 00:00:00 2001 From: Sergio Lindo Mansilla Date: Mon, 15 May 2017 15:17:16 +0200 Subject: [PATCH 058/185] Change too bright color to matte - The bright colors makes the labels unreadable on some screens. --- app/models/program.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/program.rb b/app/models/program.rb index c7168849..e36d65bf 100644 --- a/app/models/program.rb +++ b/app/models/program.rb @@ -184,10 +184,10 @@ class Program < ActiveRecord::Base def create_difficulty_levels DifficultyLevel.create(title: 'Easy', description: 'Events are understandable for everyone without knowledge of the topic.', - color: '#70EF69', program_id: id) + color: '#32CB2A', program_id: id) DifficultyLevel.create(title: 'Medium', description: 'Events require a basic understanding of the topic.', - color: '#EEEF69', program_id: id) + color: '#E6B65B', program_id: id) DifficultyLevel.create(title: 'Hard', description: 'Events require expert knowledge of the topic.', color: '#EF6E69', program_id: id) From 36b8088726c35943898161d3888d4d68582034f9 Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Tue, 9 May 2017 00:14:05 +0300 Subject: [PATCH 059/185] Replace submitter with speakers in reports#index Also, in events#show and proposals#index It is more relevant to check if the speakers have registered to the conference and filled their biographies than the submitter, because, there can be multiple speakers and the submitter isn't necessarily one of them And, remove admin/events/reports.html.haml, since, it isn't used anymore Fix #1477, fix #1479 --- app/models/event.rb | 4 +- app/views/admin/events/reports.html.haml | 127 ------------------ app/views/admin/events/show.html.haml | 13 +- app/views/admin/reports/_all_events.html.haml | 6 +- app/views/proposals/_tooltip.html.haml | 15 ++- 5 files changed, 24 insertions(+), 141 deletions(-) delete mode 100644 app/views/admin/events/reports.html.haml diff --git a/app/models/event.rb b/app/models/event.rb index 2bb526b9..0c786066 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -214,9 +214,9 @@ class Event < ActiveRecord::Base # Returns +Hash+ def progress_status { - registered: program.conference.user_registered?(submitter), + registered: speakers.all? { |speaker| program.conference.user_registered? speaker }, commercials: commercials.any?, - biography: !submitter.biography.blank?, + biographies: speakers.all? { |speaker| !speaker.biography.blank? }, subtitle: !subtitle.blank?, track: (!track.blank? unless program.tracks.empty?), difficulty_level: !difficulty_level.blank?, diff --git a/app/views/admin/events/reports.html.haml b/app/views/admin/events/reports.html.haml deleted file mode 100644 index 09659f06..00000000 --- a/app/views/admin/events/reports.html.haml +++ /dev/null @@ -1,127 +0,0 @@ -.tabbable - %ul.nav.nav-tabs - %li.active - = link_to 'All Events', '#all', 'data-toggle' => 'tab' - %li - %a{ href: '#missing-commercial', 'data-toggle' => 'tab' } - Events without Commercials - %span.label.label-danger{ style: 'border-radius: 1em;' } - = @events_missing_commercial.length - %li - %a{ href: '#requirements', 'data-toggle' => 'tab' } - Speaker Requirements - %span.label.label-success{ style: 'border-radius: 1em;' } - = @events_with_requirements.length - - %li - %a{ href: '#missing-speakers', 'data-toggle' => 'tab' } - Missing Speakers - %span.label.label-danger{ style: 'border-radius: 1em;' } - = @missing_event_speakers.length - - .tab-content - #all.tab-pane.active - .row - .col-md-12 - .page-header - %h1 - All Events - = "(#{@events.length})" - %p.text-muted - All submissions and the information that they are mssing - - .col-md-12 - %table.table.table-striped.table-bordered.table-hover.datatable - %thead - %th Title - %th Submitter Registered - %th Submitter Biography - %th Commercial - %th Subtitle - %th Difficulty Level - - if @program.tracks.any? - %th Track - %tbody - - @events.each do |event| - %tr - - progress_status = event.progress_status - %td - = link_to event.title, edit_admin_conference_program_event_path(@conference.short_title, event) - %br - .small (Presented by #{event.speaker_names}) - - - %w(registered biography commercials subtitle difficulty_level).each do |info| - %td{ 'data-order' => "#{progress_status[info]}" } - %span{ class: class_for_todo(progress_status[info]) } - %span{ class: [icon_for_todo(progress_status[info]), 'fa-lg'] } - - if @program.tracks.any? - %td{ 'data-order' => "#{progress_status['track']}" } - %span{ class: class_for_todo(progress_status['track']) } - %span{ class: [icon_for_todo(progress_status['track']), 'fa-lg'] } - - #missing-commercial.tab-pane - .row - .col-md-12 - .page-header - %h1 - Events without commercials - = "(#{@events_missing_commercial.length})" - %p.text-muted - All submissions that have no commercial - .col-md-12 - %table.table.table-striped.table-bordered.table-hover.datatable - %thead - %th Title - %th Speaker(s) - %tbody - - @events_missing_commercial.each do |event| - %tr - %td= link_to event.title, edit_admin_conference_program_event_path(@conference.short_title, event) - %td #{event.speaker_names} - - #requirements.tab-pane - .row - .col-md-12 - .page-header - %h1 - Requirements - = "(#{@events_with_requirements.length})" - %p.text-muted - All submissions where the speakers have special requirements - .col-md-12 - %table.table.table-striped.table-bordered.table-hover.datatable - %thead - %th Title - %th Speaker(s) - %th Requirements - %tbody - - @events_with_requirements.each do |event| - %tr - %td= link_to event.title, edit_admin_conference_program_event_path(@conference.short_title, event) - %td #{event.speaker_names} - %td= event.description - - #missing-speakers.tab-pane - .row - .col-md-12 - .page-header - %h1 - Missing Speakers - = "(#{@missing_event_speakers.length})" - %p.text-muted - All event speakers who haven't checked in - .col-md-12 - %table.table.table-striped.table-bordered.table-hover.datatable - %thead - %th Speaker Name - %th Registered? - %th Event - %th Start Time - %tbody - - @missing_event_speakers.each do |speaker| - %tr - %td= speaker.user.name - %td= @conference.user_registered?(speaker.user) ? 'Yes' : 'No' - %td= link_to speaker.event.title, edit_admin_conference_program_event_path(@conference.short_title, speaker.event) - - event_start_time = speaker.event.time - %td= event_start_time.present? ? event_start_time : '-' diff --git a/app/views/admin/events/show.html.haml b/app/views/admin/events/show.html.haml index 9969bbaf..0fe17c78 100644 --- a/app/views/admin/events/show.html.haml +++ b/app/views/admin/events/show.html.haml @@ -64,13 +64,18 @@ %br %table.table.table-hover %tr - %td= link_to 'Submitter must be registered to the conference', admin_conference_registrations_path(@event.program.conference.short_title) + %td= link_to "#{'Speaker'.pluralize(@event.speakers.count)} must be registered to the conference", admin_conference_registrations_path(@event.program.conference.short_title) %td{ 'class' => class_for_todo(progress_status['registered']) } %span{ 'class' => [icon_for_todo(progress_status['registered']), 'fa-lg'] } %tr - %td= link_to 'Fill out submitter biography', edit_admin_user_path(@event.submitter) - %td{ 'class' => class_for_todo(progress_status['biography']) } - %span{ 'class' => [icon_for_todo(progress_status['biography']), 'fa-lg'] } + %td + - if @event.speakers.count == 1 + = link_to 'Fill out speaker\'s biography', edit_admin_user_path(@event.speakers.first) + - else + Fill out speaker's biography: + = speaker_links(@event) + %td{ 'class' => class_for_todo(progress_status['biographies']) } + %span{ 'class' => [icon_for_todo(progress_status['biographies']), 'fa-lg'] } %tr %td= link_to 'Add a subtitle', edit_admin_conference_program_event_path(@event.program.conference.short_title, @event) %td{ 'class' => class_for_todo(progress_status['subtitle']) } diff --git a/app/views/admin/reports/_all_events.html.haml b/app/views/admin/reports/_all_events.html.haml index 7e76e927..98f405ea 100644 --- a/app/views/admin/reports/_all_events.html.haml +++ b/app/views/admin/reports/_all_events.html.haml @@ -12,8 +12,8 @@ %thead %th ID %th Title - %th Submitter Registered - %th Submitter Biography + %th Speakers Registered + %th Speakers Biographies %th Commercial %th Subtitle %th Difficulty Level @@ -32,7 +32,7 @@ = speaker_links(event) ) - - %w(registered biography commercials subtitle difficulty_level).each do |info| + - %w(registered biographies commercials subtitle difficulty_level).each do |info| %td{'data-order' => "#{progress_status[info]}"} %span{class: class_for_todo(progress_status[info])} %span{class: [icon_for_todo(progress_status[info]), 'fa-lg']} diff --git a/app/views/proposals/_tooltip.html.haml b/app/views/proposals/_tooltip.html.haml index 254b829b..168d2d26 100644 --- a/app/views/proposals/_tooltip.html.haml +++ b/app/views/proposals/_tooltip.html.haml @@ -3,12 +3,17 @@ %li{'class'=>class_for_todo(progress_status['registered'])} %span{'class'=>icon_for_todo(progress_status['registered'])} - if progress_status['registered'] - = link_to 'Register to the conference', edit_conference_conference_registration_path(event.program.conference.short_title) + Speaker(s) registered to the conference - else - = link_to 'Register to the conference', new_conference_conference_registration_path(event.program.conference.short_title) - %li{'class'=>class_for_todo(progress_status['biography'])} - %span{'class'=>icon_for_todo(progress_status['biography'])} - = link_to 'Fill out your biography', edit_user_path(event.submitter) + = link_to 'Speaker(s) not registered to the conference', new_conference_conference_registration_path(event.program.conference.short_title) + %li{'class'=>class_for_todo(progress_status['biographies'])} + %span{'class'=>icon_for_todo(progress_status['biographies'])} + - if progress_status['biographies'] + Speakers have filled out their biographies + - elsif current_user.biography.blank? && event.speakers.include?(current_user) + = link_to 'Fill out your biography', edit_user_path(current_user) + - else + Speakers' biographies missing %li{'class'=>class_for_todo(progress_status['subtitle'])} %span{'class'=>icon_for_todo(progress_status['subtitle'])} = link_to 'Add a subtitle', edit_conference_program_proposal_path(event.program.conference.short_title, event) From fa56ff7f6d48395a70d08799b6b3f4fc79a463a2 Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Sat, 22 Apr 2017 09:40:08 +0300 Subject: [PATCH 060/185] Add helper function for speaker selection The line '@users = User.all.order(:name)' is replicated a lot of times in EventsController and ProposalsController. So, this commit removes it and adds a helper function 'speaker_selector_input' that generates the field where the @users variable was used. Also, it makes the query more specific. Fix #1455 Other changes: * Include the username in the drop down menu * Add .active scope to User and corresponding tests * Add :disabled trait to User factory --- app/controllers/admin/events_controller.rb | 4 ---- app/controllers/proposals_controller.rb | 2 -- app/helpers/application_helper.rb | 7 +++++++ app/models/user.rb | 1 + app/views/proposals/_proposal_form.html.haml | 4 +--- spec/factories/users.rb | 5 +++++ spec/models/user_spec.rb | 11 +++++++++++ 7 files changed, 25 insertions(+), 9 deletions(-) diff --git a/app/controllers/admin/events_controller.rb b/app/controllers/admin/events_controller.rb index a3b6a3cb..125d1ef1 100644 --- a/app/controllers/admin/events_controller.rb +++ b/app/controllers/admin/events_controller.rb @@ -62,7 +62,6 @@ module Admin @comments = @event.root_comments @comment_count = @event.comment_threads.count @user = @event.submitter - @users = User.all.order(:name) @url = admin_conference_program_event_path(@conference.short_title, @event) @languages = @program.languages_list end @@ -80,7 +79,6 @@ module Admin end def update - @users = User.all.order(:name) @languages = @program.languages_list if @event.update_attributes(event_params) @@ -99,7 +97,6 @@ module Admin def create @url = admin_conference_program_events_path(@conference.short_title, @event) - @users = User.all.order(:name) @languages = @program.languages_list @event.submitter = current_user @@ -115,7 +112,6 @@ module Admin def new @url = admin_conference_program_events_path(@conference.short_title, @event) @languages = @program.languages_list - @users = User.all.order(:name) end def accept diff --git a/app/controllers/proposals_controller.rb b/app/controllers/proposals_controller.rb index f940e7ee..baf86f3c 100644 --- a/app/controllers/proposals_controller.rb +++ b/app/controllers/proposals_controller.rb @@ -25,7 +25,6 @@ class ProposalsController < ApplicationController def edit @url = conference_program_proposal_path(@conference.short_title, params[:id]) - @users = User.all.order(:name) @languages = @program.languages_list end @@ -61,7 +60,6 @@ class ProposalsController < ApplicationController def update @url = conference_program_proposal_path(@conference.short_title, params[:id]) - @users = User.all.order(:name) if @event.update(event_params) redirect_to conference_program_proposals_path(conference_id: @conference.short_title), diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 0d281c18..b0a157a7 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -602,4 +602,11 @@ module ApplicationHelper def speaker_links(event) event.speakers.map{ |speaker| link_to speaker.name, admin_user_path(speaker) }.join(', ').html_safe end + + def speaker_selector_input(form) + users = User.active.pluck(:id, :name, :username, :email).map { |user| [user[0], user[1].blank? ? user[2] : user[1], user[2], user[3]] }.sort_by { |user| user[1].downcase } + form.input :speakers, as: :select, + collection: options_for_select(users.map {|user| ["#{user[1]} (#{user[2]}) #{user[3]}", user[0]]}, @event.speakers.map(&:id)), + include_blank: false, label: 'Speakers', input_html: { class: 'select-help-toggle', multiple: 'true' } + end end diff --git a/app/models/user.rb b/app/models/user.rb index 5f41e693..a63d721e 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -53,6 +53,7 @@ class User < ActiveRecord::Base accepts_nested_attributes_for :roles scope :admin, -> { where(is_admin: true) } + scope :active, -> { where(is_disabled: false) } validates :email, presence: true diff --git a/app/views/proposals/_proposal_form.html.haml b/app/views/proposals/_proposal_form.html.haml index 3116d532..f31651a1 100644 --- a/app/views/proposals/_proposal_form.html.haml +++ b/app/views/proposals/_proposal_form.html.haml @@ -4,9 +4,7 @@ = f.input :subtitle, as: :string - = f.input :speakers, as: :select, - collection: options_for_select(@users.map {|user| ["#{user.name} (#{user.email})", user.id]}, @event.speakers.map(&:id)), - include_blank: false, label: 'Speakers', input_html: { class: 'select-help-toggle', multiple: 'true' } + = speaker_selector_input f - if @program.tracks.any? = f.input :track_id, as: :select, diff --git a/spec/factories/users.rb b/spec/factories/users.rb index 346ddb80..e2e78c16 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -29,6 +29,7 @@ FactoryGirl.define do Quisque cursus facilisis consequat. Etiam volutpat ligula turpis, at gravida. EOS + is_disabled false after(:create) do |user| user.is_admin = false @@ -44,6 +45,10 @@ FactoryGirl.define do user.save! end end + + trait :disabled do + is_disabled true + end end factory :user_xss, parent: :user do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index d9b24c79..d0517212 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -10,6 +10,7 @@ describe User do let(:volunteers_coordinator_role) { Role.find_by(name: 'volunteers_coordinator', resource: conference) } let(:organizer) { create(:user, role_ids: [organizer_role.id]) } let(:user) { create(:user) } + let(:user_disabled) { create(:user, :disabled) } let(:event1) { create(:event, program: conference.program) } let(:another_conference) { create(:conference) } @@ -75,6 +76,16 @@ describe User do end end + describe '.active' do + it 'includes users without is_disabled flag' do + expect(User.active).to include(user) + end + + it 'excludes users with is_disabled flag' do + expect(User.active).not_to include(user_disabled) + end + end + describe '.comment_notifiable' do let(:cfp_user) { create(:user, role_ids: [cfp_role.id]) } From 4824537aebfc88ace86bf46b7f00c0100a27fbac Mon Sep 17 00:00:00 2001 From: divyanshumehta Date: Sun, 21 May 2017 21:02:30 +0530 Subject: [PATCH 061/185] Added Rails/Delegate Rubucop Cop --- .rubocop.yml | 4 ++++ .rubocop_todo.yml | 6 ------ app/serializers/speaker_serializer.rb | 4 +--- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 9410af03..c333e43a 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -188,6 +188,10 @@ Rails: Rails/Validation: Enabled: true +# Looks for delegations, that could have been created automatically with delegate method +Rails/Delegate: + Enabled: true + #################### Performance ############################### # Identifies places where gsub can be replaced by tr or delete. diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 11fedc97..4356de97 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -124,12 +124,6 @@ Rails/Blank: Rails/Date: Enabled: false -# Offense count: 1 -# Cop supports --auto-correct. -Rails/Delegate: - Exclude: - - 'app/serializers/speaker_serializer.rb' - # Offense count: 3 # Cop supports --auto-correct. # Configuration parameters: Whitelist. diff --git a/app/serializers/speaker_serializer.rb b/app/serializers/speaker_serializer.rb index c017fb31..4a455a61 100644 --- a/app/serializers/speaker_serializer.rb +++ b/app/serializers/speaker_serializer.rb @@ -3,7 +3,5 @@ class SpeakerSerializer < ActiveModel::Serializer attributes :name, :affiliation, :biography - def name - object.name - end + delegate :name, to: :object end From 4594626670e822c551b88d29a4ac1524cca9dadf Mon Sep 17 00:00:00 2001 From: divyanshumehta Date: Tue, 23 May 2017 10:43:03 +0530 Subject: [PATCH 062/185] Added link for Cop:Rails in contributing.md --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ec8376ce..2ef507a8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -131,7 +131,7 @@ We are using [rubocop](https://github.com/bbatsov/rubocop) as a style checker. I vagrant exec bundle exec rubocop ``` -You can read through current enabled rules in `.rubocop.yml` file. Explanations of the defined [rules](http://rubydoc.info/github/bbatsov/rubocop/master/frames) can be found in modules [Cop::Lint](http://rubydoc.info/github/bbatsov/rubocop/master/Rubocop/Cop/Lint) and [Cop::Style](http://rubydoc.info/github/bbatsov/rubocop/master/Rubocop/Cop/Style). +You can read through current enabled rules in `.rubocop.yml` file. Explanations of the defined [rules](http://rubydoc.info/github/bbatsov/rubocop/master/frames) can be found in modules [Cop::Lint](http://rubydoc.info/github/bbatsov/rubocop/master/Rubocop/Cop/Lint) and [Cop::Style](http://rubydoc.info/github/bbatsov/rubocop/master/Rubocop/Cop/Style) and [Cop:Rails](https://rubocop.readthedocs.io/en/latest/cops_rails/). Additionally you can read through the [ruby style-guide](https://github.com/bbatsov/ruby-style-guide) to better understand core principles. ### Test Suite From e2657bb10dbab7cffa401a3c570c9fba9c510995 Mon Sep 17 00:00:00 2001 From: hitman Date: Mon, 6 Mar 2017 23:54:29 +0530 Subject: [PATCH 063/185] refractor code into different files --- app/helpers/application_helper.rb | 447 ----------------------- app/helpers/change_description_helper.rb | 88 +++++ app/helpers/date_time_helper.rb | 72 ++++ app/helpers/events_helper.rb | 44 +++ app/helpers/format_helper.rb | 202 ++++++++++ app/helpers/paths_helper.rb | 42 +++ app/helpers/users_helper.rb | 58 +++ 7 files changed, 506 insertions(+), 447 deletions(-) create mode 100644 app/helpers/change_description_helper.rb create mode 100644 app/helpers/date_time_helper.rb create mode 100644 app/helpers/events_helper.rb create mode 100644 app/helpers/format_helper.rb create mode 100644 app/helpers/paths_helper.rb create mode 100644 app/helpers/users_helper.rb diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index b0a157a7..09014502 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -51,173 +51,11 @@ module ApplicationHelper end end - ## - # Gets an EventType object, and returns its length in timestamp format (HH:MM) - # ====Gets - # * +Integer+ -> 30 - # ====Returns - # * +String+ -> "00:30" - def length_timestamp(length) - [length / 60, length % 60].map { |t| t.to_s.rjust(2, '0') }.join(':') - end - - ## - # Gets a datetime object - # ====Returns - # * +String+ -> formated datetime object - def format_datetime(obj) - return unless obj - obj.strftime('%Y-%m-%d %H:%M') - end - - ## - # ====Returns - # * +String+ -> number of registrations / max allowed registrations - def registered_text(event) - return "Registered: #{event.registrations.count}/#{event.max_attendees}" if event.max_attendees - "Registered: #{event.registrations.count}" - end - # Set resource_name for devise so that we can call the devise help links (views/devise/shared/_links) from anywhere (eg sign_up form in proposals#new) def resource_name :user end - # Set devise_mapping for devise so that we can call the devise help links (views/devise/shared/_links) from anywhere (eg sign_up form in proposals#new) - def devise_mapping - @devise_mapping ||= Devise.mappings[:user] - end - - def event_status_icon(event) - case event.state - when 'new' - 'fa-eye' - when 'unconfirmed' - 'fa-check text-muted' - when 'confirmed' - 'fa-check text-success' - when 'rejected', 'withdrawn', 'canceled' - 'fa-ban' - end - end - - def event_progress_color(progress) - progress = progress.to_i - if progress == 100 - 'progress-bar-success' - elsif progress >= 85 - 'progress-bar-info' - elsif progress >= 71 - 'progress-bar-warning' - else - 'progress-bar-danger' - end - end - - def target_progress_color(progress) - progress = progress.to_i - result = - case - when progress >= 90 then 'green' - when progress < 90 && progress >= 80 then 'orange' - else 'red' - end - - result - end - - def days_left_color(days_left) - days_left = days_left.to_i - if days_left > 30 - result = 'green' - elsif days_left < 30 && days_left > 10 - result = 'orange' - else - result = 'red' - end - result - end - - def bootstrap_class_for(flash_type) - case flash_type - when 'success' - 'alert-success' - when 'error' - 'alert-danger' - when 'alert' - 'alert-warning' - when 'notice' - 'alert-info' - else - 'alert-warning' - end - end - - def label_for(event_state) - result = '' - case event_state - when 'new' - result = 'label label-primary' - when 'withdrawn' - result = 'label label-danger' - when 'unconfirmed' - result = 'label label-success' - when 'confirmed' - result = 'label label-success' - when 'rejected' - result = 'label label-warning' - when 'canceled' - result = 'label label-danger' - end - result - end - - def icon_for_todo(bool) - if bool - return 'fa fa-check' - else - return 'fa fa-times' - end - end - - def class_for_todo(bool) - if bool - return 'todolist-ok' - else - return 'todolist-missing' - end - end - - def normalize_array_length(hashmap, length) - hashmap.each do |_, value| - if value.length < length - value.fill(value[-1], value.length...length) - end - end - end - - def active_nav_li(link) - if current_page?(link) - return 'active' - else - return '' - end - end - - def show_time(length) - return '0 h 0 min' if length.blank? - - h, min = length.divmod(60) - - if h == 0 - "#{min.round} min" - elsif min == 0 - "#{h} h" - else - "#{h} h #{min.round} min" - end - end - def add_association_link(association_name, form_builder, div_class, html_options = {}) link_to_add_association 'Add ' + association_name.to_s.singularize, form_builder, div_class, html_options.merge(class: 'assoc btn btn-success') end @@ -230,29 +68,6 @@ module ApplicationHelper render 'shared/dynamic_association', association_name: association_name, title: title, f: form_builder, hint: options[:hint] end - # Same as redirect_to(:back) if there is a valid HTTP referer, otherwise redirect_to() - def redirect_back_or_to(options = {}, response_status = {}) - if request.env['HTTP_REFERER'] - redirect_to :back - else - redirect_to options, response_status - end - end - - def event_types(conference) - all = conference.program.event_types.map { |et | et.title.pluralize } - first = all[0...-1] - last = all[-1] - ets = '' - if all.length > 1 - ets << first.join(', ') - ets << " and #{last}" - else - ets = all.join - end - return ets - end - def tracks(conference) all = conference.program.tracks.map {|t| t.name} first = all[0...-1] @@ -281,137 +96,10 @@ module ApplicationHelper return ts 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 - - "#{word}" - end - - def markdown(text) - return '' if text.nil? - - options = { - autolink: true, - space_after_headers: true, - no_intra_emphasis: true - } - markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new(escape_html: true), options) - markdown.render(text).html_safe - end - - def markdown_hint(text='') - markdown("#{text}\n\nPlease look at [**Markdown Syntax**](https://daringfireball.net/projects/markdown/syntax) to format your text") - end - - def omniauth_configured - providers = [] - Devise.omniauth_providers.each do |provider| - provider_key = "#{provider}_key" - provider_secret = "#{provider}_secret" - unless Rails.application.secrets.send(provider_key).blank? || Rails.application.secrets.send(provider_secret).blank? - providers << provider - end - providers << provider if !ENV["OSEM_#{provider.upcase}_KEY"].blank? && !ENV["OSEM_#{provider.upcase}_SECRET"].blank? - end - - return providers.uniq - end - - # Receives a hash, generated from User model, function get_roles - # Outputs the roles of a user, including the conferences for which the user has the roles - # Eg. organizer(oSC13, oSC14), cfp(oSC12, oSC13) - def show_roles(roles) - roles.map{ |x| x[0].titleize + ' (' + x[1].join(', ') + ')' }.join ', ' - end - - def can_manage_volunteers(conference) - if (current_user.has_role? :organizer, conference) || (current_user.has_role? :volunteers_coordinator, conference) - true - else - false - end - end - - def sign_in_path - if ENV['OSEM_ICHAIN_ENABLED'] == 'true' - new_user_ichain_session_path - else - new_user_session_path - end - end - def unread_notifications(user) Comment.accessible_by(current_ability).find_since_last_login(user) end - # Returns black or white deppending on what of them contrast more with the - # given color. Useful to print text in a coloured background. - # hexcolor is a hex color of 7 characters, being the first one '#'. - # Reference: https://24ways.org/2010/calculating-color-contrast - def contrast_color(hexcolor) - r = hexcolor[1..2].to_i(16) - g = hexcolor[3..4].to_i(16) - b = hexcolor[5..6].to_i(16) - yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000 - (yiq >= 128) ? 'black' : 'white' - end - - def td_height(rooms) - td_height = 500 / rooms.length - # we want all least 3 lines in events and td padding = 3px, speaker picture height >= 25px - # and line-height = 17px => (17 * 3) + 6 + 25 = 82 - td_height < 82 ? 82 : td_height - end - - def room_height(rooms) - room_lines(rooms) * 17 - end - - def room_lines(rooms) - # line-height = 17px, td padding = 3px - (td_height(rooms) - 6) / 17 - end - - def event_height(rooms) - event_lines(rooms) * 17 - end - - def event_lines(rooms) - # line-height = 17px, td padding = 3px, speaker picture height >= 25px - (td_height(rooms) - 31) / 17 - end - - def speaker_height(rooms) - # td padding = 3px - speaker_height = td_height(rooms) - 6 - event_height(rooms) - # The speaker picture is a circle and the width must be <= 37 to avoid making the cell widther - speaker_height >= 37 ? 37 : speaker_height - end - - def speaker_width(rooms) - # speaker picture padding: 4px 2px; and we want the picture to be a circle - speaker_height(rooms) - 4 - end - - def carousel_item_class(number, carousel_number, num_cols, col) - item_class = 'item' - item_class += ' first' if number == 0 - item_class += ' last' if number == (carousel_number - 1) - if (col && ((col / num_cols) == number)) || (!col && number == 0) - item_class += ' active' - end - item_class - end - - def selected_scheduled?(schedule) - (schedule == @selected_schedule) ? 'Yes' : 'No' - end - # Recieves a PaperTrail::Version object # Outputs the list of attributes that were changed in the version (ignoring changes from one blank value to another) # Eg: If version.changeset = '{"title"=>[nil, "Premium"], "description"=>[nil, "Premium = Super cool"], "conference_id"=>[nil, 3]}' @@ -423,15 +111,6 @@ module ApplicationHelper .reverse.sub(',', ' dna ').reverse end - def link_to_user(user_id) - user = User.find_by(id: user_id) - if user - link_to user.name, admin_user_path(id: user_id) - else - 'Someone (probably via the console)' - end - end - # Recieves a model_name and id # Returns nil if model_name is invalid # Returns object in its current state if its alive @@ -451,132 +130,6 @@ module ApplicationHelper object end - def event_change_description(version) - case - when version.event == 'create' then 'submitted new' - - when version.changeset['state'] - case version.changeset['state'][1] - when 'unconfirmed' then 'accepted' - when 'withdrawn' then 'withdrew' - when 'canceled', 'rejected', 'confirmed' then version.changeset['state'][1] - when 'new' then 'resubmitted' - end - - else - "updated #{updated_attributes(version)} of" - end - end - - def users_role_change_description(version) - version.event == 'create' ? 'added' : 'removed' - end - - def subscription_change_description(version) - user = current_or_last_object_state(version.item_type, version.item_id).user - user_name = user.name unless user.id.to_s == version.whodunnit - version.event == 'create' ? "subscribed #{user_name} to" : "unsubscribed #{user_name} from" - end - - def registration_change_description(version) - if version.item_type == 'Registration' - user = current_or_last_object_state(version.item_type, version.item_id).user - elsif version.item_type == 'EventsRegistration' - registration_id = current_or_last_object_state(version.item_type, version.item_id).registration_id - user = current_or_last_object_state('Registration', registration_id).user - end - - if user.id.to_s == version.whodunnit - case version.event - when 'create' then 'registered to' - when 'update' then "updated #{updated_attributes(version)} of the registration for" - when 'destroy' then 'unregistered from' - end - else - case version.event - when 'create' then "registered #{user.name} to" - when 'update' then "updated #{updated_attributes(version)} of #{user.name}'s registration for" - when 'destroy' then "unregistered #{user.name} from" - end - end - end - - def comment_change_description(version) - user = current_or_last_object_state(version.item_type, version.item_id).user - if version.event == 'create' - version.previous.nil? ? 'commented on' : "re-added #{user.name}'s comment on" - else - "deleted #{user.name}'s comment on" - end - end - - def vote_change_description(version) - user = current_or_last_object_state(version.item_type, version.item_id).user - if version.event == 'create' - version.previous.nil? ? 'voted on' : "re-added #{user.name}'s vote on" - elsif version.event == 'update' - "updated #{user.name}'s vote on" - else - "deleted #{user.name}'s vote on" - end - end - - def user_change_description(version) - if version.event == 'create' - link_to_user(version.item_id) + ' signed up' - elsif version.event == 'update' - if version.changeset.keys.include?('reset_password_sent_at') - 'Someone requested password reset of' - elsif version.changeset.keys.include?('confirmed_at') && version.changeset['confirmed_at'][0].nil? - (version.whodunnit.nil? ? link_to_user(version.item_id) : link_to_user(version.whodunnit)) + ' confirmed account of' - elsif version.changeset.keys.include?('confirmed_at') && version.changeset['confirmed_at'][1].nil? - link_to_user(version.whodunnit) + ' unconfirmed account of' - else - link_to_user(version.whodunnit) + " updated #{updated_attributes(version)} of" - end - end - end - - def event_schedule_change_description(version) - case version.event - when 'create' then 'scheduled' - when 'update' then 'rescheduled' - when 'destroy' then 'unscheduled' - end - end - - def general_change_description(version) - if version.event == 'create' - 'created new' - elsif version.event == 'update' - "updated #{updated_attributes(version)} of" - else - 'deleted' - end - end - - def link_if_alive(version, link_text, link_url) - version.item ? link_to(link_text, link_url) : link_text - end - - def canceled_replacement_event_label(event, event_schedule, *label_classes) - if event.state == 'canceled' || event.state == 'withdrawn' - content_tag :span, 'CANCELED', class: (['label', 'label-danger'] + label_classes) - elsif event_schedule.present? && event_schedule.replacement? - content_tag :span, 'REPLACEMENT', class: (['label', 'label-info'] + label_classes) - end - end - - def replacement_event_notice(event_schedule) - if event_schedule.present? && event_schedule.replacement? - replaced_event = (event_schedule.intersecting_event_schedules.withdrawn.first || event_schedule.intersecting_event_schedules.canceled.first).event - content_tag :span do - concat content_tag :span, 'Please note that this talk replaces ' - concat link_to replaced_event.title, conference_program_proposal_path(@conference.short_title, replaced_event.id) - end - end - end - def quantity_left_of(resource) return '-/-' if resource.quantity.blank? "#{resource.quantity - resource.used}/#{resource.quantity}" diff --git a/app/helpers/change_description_helper.rb b/app/helpers/change_description_helper.rb new file mode 100644 index 00000000..99b51bc7 --- /dev/null +++ b/app/helpers/change_description_helper.rb @@ -0,0 +1,88 @@ +module ChangeDescriptionHelper + ## + # Groups functions related to change description + ## + def subscription_change_description(version) + user = current_or_last_object_state(version.item_type, version.item_id).user + user_name = user.name unless user.id.to_s == version.whodunnit + version.event == 'create' ? "subscribed #{user_name} to" : "unsubscribed #{user_name} from" + end + + def registration_change_description(version) + if version.item_type == 'Registration' + user = current_or_last_object_state(version.item_type, version.item_id).user + elsif version.item_type == 'EventsRegistration' + registration_id = current_or_last_object_state(version.item_type, version.item_id).registration_id + user = current_or_last_object_state('Registration', registration_id).user + end + + if user.id.to_s == version.whodunnit + case version.event + when 'create' then 'registered to' + when 'update' then "updated #{updated_attributes(version)} of the registration for" + when 'destroy' then 'unregistered from' + end + else + case version.event + when 'create' then "registered #{user.name} to" + when 'update' then "updated #{updated_attributes(version)} of #{user.name}'s registration for" + when 'destroy' then "unregistered #{user.name} from" + end + end + end + + def comment_change_description(version) + user = current_or_last_object_state(version.item_type, version.item_id).user + if version.event == 'create' + version.previous.nil? ? 'commented on' : "re-added #{user.name}'s comment on" + else + "deleted #{user.name}'s comment on" + end + end + + def vote_change_description(version) + user = current_or_last_object_state(version.item_type, version.item_id).user + if version.event == 'create' + version.previous.nil? ? 'voted on' : "re-added #{user.name}'s vote on" + elsif version.event == 'update' + "updated #{user.name}'s vote on" + else + "deleted #{user.name}'s vote on" + end + end + + def general_change_description(version) + if version.event == 'create' + 'created new' + elsif version.event == 'update' + "updated #{updated_attributes(version)} of" + else + 'deleted' + end + end + + def event_change_description(version) + case + when version.event == 'create' then 'submitted new' + + when version.changeset['state'] + case version.changeset['state'][1] + when 'unconfirmed' then 'accepted' + when 'withdrawn' then 'withdrew' + when 'canceled', 'rejected', 'confirmed' then version.changeset['state'][1] + when 'new' then 'resubmitted' + end + + else + "updated #{updated_attributes(version)} of" + end + end + + def event_schedule_change_description(version) + case version.event + when 'create' then 'scheduled' + when 'update' then 'rescheduled' + when 'destroy' then 'unscheduled' + end + end +end diff --git a/app/helpers/date_time_helper.rb b/app/helpers/date_time_helper.rb new file mode 100644 index 00000000..0acb2aef --- /dev/null +++ b/app/helpers/date_time_helper.rb @@ -0,0 +1,72 @@ +module DateTimeHelper + ## + # Includes functions related to date or time manipulations + ## + ## + # Returns a string build from the start and end date of the given conference. + # + # If the conference is only one day long + # * %B %d %Y (January 17 2014) + # If the conference starts and ends in the same month and year + # * %B %d - %d, %Y (January 17 - 21 2014) + # If the conference ends in another month but in the same year + # * %B %d - %B %d, %Y (January 31 - February 02 2014) + # All other cases + # * %B %d, %Y - %B %d, %Y (December 30, 2013 - January 02, 2014) + def date_string(start_date, end_date) + startstr = 'Unknown - ' + endstr = 'Unknown' + # When the conference is in the same month + if start_date.month == end_date.month && start_date.year == end_date.year + if start_date.day == end_date.day + startstr = start_date.strftime('%B %d') + endstr = end_date.strftime(' %Y') + else + startstr = start_date.strftime('%B %d - ') + endstr = end_date.strftime('%d, %Y') + end + elsif start_date.month != end_date.month && start_date.year == end_date.year + startstr = start_date.strftime('%B %d - ') + endstr = end_date.strftime('%B %d, %Y') + else + startstr = start_date.strftime('%B %d, %Y - ') + endstr = end_date.strftime('%B %d, %Y') + end + + result = startstr + endstr + result + end + + ## + # Gets an EventType object, and returns its length in timestamp format (HH:MM) + # ====Gets + # * +Integer+ -> 30 + # ====Returns + # * +String+ -> "00:30" + def length_timestamp(length) + [length / 60, length % 60].map { |t| t.to_s.rjust(2, '0') }.join(':') + end + + ## + # Gets a datetime object + # ====Returns + # * +String+ -> formated datetime object + def format_datetime(obj) + return unless obj + obj.strftime('%Y-%m-%d %H:%M') + end + + def show_time(length) + return '0 h 0 min' if length.blank? + + h, min = length.divmod(60) + + if h == 0 + "#{min.round} min" + elsif min == 0 + "#{h} h" + else + "#{h} h #{min.round} min" + end + end +end diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb new file mode 100644 index 00000000..38b380b5 --- /dev/null +++ b/app/helpers/events_helper.rb @@ -0,0 +1,44 @@ +module EventsHelper + ## + # Includes functions related to events + ## + ## + # ====Returns + # * +String+ -> number of registrations / max allowed registrations + def registered_text(event) + return "Registered: #{event.registrations.count}/#{event.max_attendees}" if event.max_attendees + "Registered: #{event.registrations.count}" + end + + def event_types(conference) + all = conference.program.event_types.map { |et| et.title.pluralize } + first = all[0...-1] + last = all[-1] + ets = '' + if all.length > 1 + ets << first.join(', ') + ets << " and #{last}" + else + ets = all.join + end + ets + end + + def replacement_event_notice(event_schedule) + if event_schedule.present? && event_schedule.replacement? + replaced_event = (event_schedule.intersecting_event_schedules.withdrawn.first || event_schedule.intersecting_event_schedules.canceled.first).event + content_tag :span do + concat content_tag :span, 'Please note that this talk replaces ' + concat link_to replaced_event.title, conference_program_proposal_path(@conference.short_title, replaced_event.id) + end + end + end + + def canceled_replacement_event_label(event, event_schedule, *label_classes) + if event.state == 'canceled' || event.state == 'withdrawn' + content_tag :span, 'CANCELED', class: (['label', 'label-danger'] + label_classes) + elsif event_schedule.present? && event_schedule.replacement? + content_tag :span, 'REPLACEMENT', class: (['label', 'label-info'] + label_classes) + end + end +end diff --git a/app/helpers/format_helper.rb b/app/helpers/format_helper.rb new file mode 100644 index 00000000..da9ee598 --- /dev/null +++ b/app/helpers/format_helper.rb @@ -0,0 +1,202 @@ +module FormatHelper + ## + # Includes functions related to formatting (like adding classes, colors) + ## + def event_status_icon(event) + case event.state + when 'new' + 'fa-eye' + when 'unconfirmed' + 'fa-check text-muted' + when 'confirmed' + 'fa-check text-success' + when 'rejected', 'withdrawn', 'canceled' + 'fa-ban' + end + end + + def event_progress_color(progress) + progress = progress.to_i + if progress == 100 + 'progress-bar-success' + elsif progress >= 85 + 'progress-bar-info' + elsif progress >= 71 + 'progress-bar-warning' + else + 'progress-bar-danger' + end + end + + def target_progress_color(progress) + progress = progress.to_i + result = + case + when progress >= 90 then 'green' + when progress < 90 && progress >= 80 then 'orange' + else 'red' + end + + result + end + + def days_left_color(days_left) + days_left = days_left.to_i + if days_left > 30 + result = 'green' + elsif days_left < 30 && days_left > 10 + result = 'orange' + else + result = 'red' + end + result + end + + def bootstrap_class_for(flash_type) + case flash_type + when 'success' + 'alert-success' + when 'error' + 'alert-danger' + when 'alert' + 'alert-warning' + when 'notice' + 'alert-info' + else + 'alert-warning' + end + end + + def label_for(event_state) + result = '' + case event_state + when 'new' + result = 'label label-primary' + when 'withdrawn' + result = 'label label-danger' + when 'unconfirmed' + result = 'label label-success' + when 'confirmed' + result = 'label label-success' + when 'rejected' + result = 'label label-warning' + when 'canceled' + result = 'label label-danger' + end + result + end + + def icon_for_todo(bool) + if bool + return 'fa fa-check' + else + return 'fa fa-times' + end + end + + def class_for_todo(bool) + if bool + return 'todolist-ok' + else + return 'todolist-missing' + 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 + + "#{word}" + end + + # Returns black or white deppending on what of them contrast more with the + # given color. Useful to print text in a coloured background. + # hexcolor is a hex color of 7 characters, being the first one '#'. + # Reference: https://24ways.org/2010/calculating-color-contrast + def contrast_color(hexcolor) + r = hexcolor[1..2].to_i(16) + g = hexcolor[3..4].to_i(16) + b = hexcolor[5..6].to_i(16) + yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000 + (yiq >= 128) ? 'black' : 'white' + end + + def td_height(rooms) + td_height = 500 / rooms.length + # we want all least 3 lines in events and td padding = 3px, speaker picture height >= 25px + # and line-height = 17px => (17 * 3) + 6 + 25 = 82 + td_height < 82 ? 82 : td_height + end + + def room_height(rooms) + room_lines(rooms) * 17 + end + + def room_lines(rooms) + # line-height = 17px, td padding = 3px + (td_height(rooms) - 6) / 17 + end + + def event_height(rooms) + event_lines(rooms) * 17 + end + + def event_lines(rooms) + # line-height = 17px, td padding = 3px, speaker picture height >= 25px + (td_height(rooms) - 31) / 17 + end + + def speaker_height(rooms) + # td padding = 3px + speaker_height = td_height(rooms) - 6 - event_height(rooms) + # The speaker picture is a circle and the width must be <= 37 to avoid making the cell widther + speaker_height >= 37 ? 37 : speaker_height + end + + def speaker_width(rooms) + # speaker picture padding: 4px 2px; and we want the picture to be a circle + speaker_height(rooms) - 4 + end + + def carousel_item_class(number, carousel_number, num_cols, col) + item_class = 'item' + item_class += ' first' if number == 0 + item_class += ' last' if number == (carousel_number - 1) + if (col && ((col / num_cols) == number)) || (!col && number == 0) + item_class += ' active' + end + item_class + end + + def selected_scheduled?(schedule) + (schedule == @selected_schedule) ? 'Yes' : 'No' + end + + def markdown(text) + return '' if text.nil? + + options = { + autolink: true, + space_after_headers: true, + no_intra_emphasis: true + } + markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new(escape_html: true), options) + markdown.render(text).html_safe + end + + def markdown_hint(text='') + markdown("#{text} Please look at #{link_to '**Markdown Syntax**', 'https://daringfireball.net/projects/markdown/syntax', target: '_blank'} to format your text") + end + + def normalize_array_length(hashmap, length) + hashmap.each do |_, value| + if value.length < length + value.fill(value[-1], value.length...length) + end + end + end +end diff --git a/app/helpers/paths_helper.rb b/app/helpers/paths_helper.rb new file mode 100644 index 00000000..8b235ccd --- /dev/null +++ b/app/helpers/paths_helper.rb @@ -0,0 +1,42 @@ +module PathsHelper + ## + # Includes functions related to links or redirects + ## + def link_if_alive(version, link_text, link_url) + version.item ? link_to(link_text, link_url) : link_text + end + + def link_to_user(user_id) + user = User.find_by(id: user_id) + if user + link_to user.name, admin_user_path(id: user_id) + else + 'Someone (probably via the console)' + end + end + + def sign_in_path + if ENV['OSEM_ICHAIN_ENABLED'] == 'true' + new_user_ichain_session_path + else + new_user_session_path + end + end + + def active_nav_li(link) + if current_page?(link) + return 'active' + else + return '' + end + end + + # Same as redirect_to(:back) if there is a valid HTTP referer, otherwise redirect_to() + def redirect_back_or_to(options = {}, response_status = {}) + if request.env['HTTP_REFERER'] + redirect_to :back + else + redirect_to options, response_status + end + end +end diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb new file mode 100644 index 00000000..916fcb63 --- /dev/null +++ b/app/helpers/users_helper.rb @@ -0,0 +1,58 @@ +module UsersHelper + ## + # Includes functions related to users + ## + # Set devise_mapping for devise so that we can call the devise help links (views/devise/shared/_links) from anywhere (eg sign_up form in proposals#new) + def devise_mapping + @devise_mapping ||= Devise.mappings[:user] + end + + def omniauth_configured + providers = [] + Devise.omniauth_providers.each do |provider| + provider_key = "#{provider}_key" + provider_secret = "#{provider}_secret" + unless Rails.application.secrets.send(provider_key).blank? || Rails.application.secrets.send(provider_secret).blank? + providers << provider + end + providers << provider if !ENV["OSEM_#{provider.upcase}_KEY"].blank? && !ENV["OSEM_#{provider.upcase}_SECRET"].blank? + end + + return providers.uniq + end + + # Receives a hash, generated from User model, function get_roles + # Outputs the roles of a user, including the conferences for which the user has the roles + # Eg. organizer(oSC13, oSC14), cfp(oSC12, oSC13) + def show_roles(roles) + roles.map{ |x| x[0].titleize + ' (' + x[1].join(', ') + ')' }.join ', ' + end + + def can_manage_volunteers(conference) + if (current_user.has_role? :organizer, conference) || (current_user.has_role? :volunteers_coordinator, conference) + true + else + false + end + end + + def user_change_description(version) + if version.event == 'create' + link_to_user(version.item_id) + ' signed up' + elsif version.event == 'update' + if version.changeset.keys.include?('reset_password_sent_at') + 'Someone requested password reset of' + elsif version.changeset.keys.include?('confirmed_at') && version.changeset['confirmed_at'][0].nil? + (version.whodunnit.nil? ? link_to_user(version.item_id) : link_to_user(version.whodunnit)) + ' confirmed account of' + elsif version.changeset.keys.include?('confirmed_at') && version.changeset['confirmed_at'][1].nil? + link_to_user(version.whodunnit) + ' unconfirmed account of' + else + link_to_user(version.whodunnit) + " updated #{updated_attributes(version)} of" + end + end + end + + def users_role_change_description(version) + version.event == 'create' ? 'added' : 'removed' + end +end From f63259f18705cd62b2296dcd34bede26956e8096 Mon Sep 17 00:00:00 2001 From: hitman Date: Mon, 6 Mar 2017 23:54:52 +0530 Subject: [PATCH 064/185] update rubocop.yml for new files --- .rubocop_todo.yml | 113 ++++++++++++++++++---------------------------- 1 file changed, 44 insertions(+), 69 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 4356de97..c745c398 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2017-04-21 21:35:17 +0530 using RuboCop version 0.48.1. +# on 2017-05-06 15:57:26 +0530 using RuboCop version 0.48.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 @@ -57,26 +57,26 @@ Lint/UnusedBlockArgument: Exclude: - 'lib/tasks/user.rake' -# Offense count: 106 +# Offense count: 109 Metrics/AbcSize: Max: 75 -# Offense count: 225 +# Offense count: 201 # Configuration parameters: CountComments, ExcludedMethods. Metrics/BlockLength: - Max: 1364 + Max: 487 -# Offense count: 19 +# Offense count: 21 Metrics/CyclomaticComplexity: Max: 12 -# Offense count: 1967 +# Offense count: 1990 # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. # URISchemes: http, https Metrics/LineLength: Max: 619 -# Offense count: 115 +# Offense count: 117 # Configuration parameters: CountComments. Metrics/MethodLength: Max: 56 @@ -88,7 +88,8 @@ Metrics/ModuleLength: Exclude: - 'app/helpers/application_helper.rb' -# Offense count: 14 + +# Offense count: 15 Metrics/PerceivedComplexity: Max: 15 @@ -108,17 +109,16 @@ Rails/ActionFilter: - 'app/controllers/tickets_controller.rb' - 'app/controllers/users/omniauth_callbacks_controller.rb' -# Offense count: 9 +# Offense count: 7 # Cop supports --auto-correct. # Configuration parameters: NilOrEmpty, NotPresent, UnlessPresent. Rails/Blank: Exclude: - 'app/models/program.rb' - 'app/models/user.rb' - - 'lib/tasks/update_resource_quantity.rake' - 'spec/factories/event_schedule.rb' -# Offense count: 140 +# Offense count: 139 # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: strict, flexible Rails/Date: @@ -181,7 +181,7 @@ Rails/HttpPositionalArguments: # Offense count: 2 Rails/OutputSafety: Exclude: - - 'app/helpers/application_helper.rb' + - 'app/helpers/format_helper.rb' - 'app/models/commercial.rb' # Offense count: 10 @@ -195,7 +195,7 @@ Rails/PluralizationGrammar: # Configuration parameters: NotNilAndNotEmpty, NotBlank, UnlessBlank. Rails/Present: Exclude: - - 'app/helpers/application_helper.rb' + - 'app/helpers/users_helper.rb' - 'app/models/campaign.rb' - 'app/models/cfp.rb' - 'app/models/email_settings.rb' @@ -279,7 +279,7 @@ Style/ClassVars: Exclude: - 'spec/support/kneet_connections.rb' -# Offense count: 5 +# Offense count: 9 # Cop supports --auto-correct. Style/ClosingParenthesisIndentation: Exclude: @@ -312,7 +312,7 @@ Style/CommentIndentation: - 'app/models/track.rb' - 'spec/features/volunteers_spec.rb' -# Offense count: 3 +# Offense count: 8 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, SingleLineConditionsOnly, IncludeTernaryExpressions. # SupportedStyles: assign_to_condition, assign_inside_condition @@ -320,14 +320,14 @@ Style/ConditionalAssignment: Exclude: - 'app/controllers/admin/volunteers_controller.rb' - 'app/controllers/conference_registrations_controller.rb' - - 'app/helpers/application_helper.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: 429 +# Offense count: 435 Style/Documentation: Enabled: false @@ -335,13 +335,14 @@ Style/Documentation: # Cop supports --auto-correct. Style/ElseAlignment: Exclude: - - 'app/helpers/application_helper.rb' + - 'app/helpers/format_helper.rb' # Offense count: 2 # Cop supports --auto-correct. Style/EmptyCaseCondition: Exclude: - - 'app/helpers/application_helper.rb' + - 'app/helpers/change_description_helper.rb' + - 'app/helpers/format_helper.rb' # Offense count: 1 # Cop supports --auto-correct. @@ -349,7 +350,7 @@ Style/EmptyLineAfterMagicComment: Exclude: - 'spec/models/conference_spec.rb' -# Offense count: 107 +# Offense count: 106 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: empty_lines, no_empty_lines @@ -404,31 +405,17 @@ Style/FileName: - 'Gemfile' - 'Vagrantfile' -# Offense count: 38 +# 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: 22 +# Offense count: 23 # Configuration parameters: MinBodyLength. Style/GuardClause: - Exclude: - - 'app/controllers/admin/questions_controller.rb' - - 'app/controllers/conference_registrations_controller.rb' - - 'app/controllers/tickets_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/models/ability.rb' - - 'app/models/cfp.rb' - - 'app/models/commercial.rb' - - 'app/models/conference.rb' - - 'app/models/registration.rb' - - 'app/models/ticket.rb' - - 'app/models/user.rb' - - 'app/serializers/conference_serializer.rb' - - 'db/migrate/20140820124117_undo_wrong_migration20140801080705_add_users_to_events.rb' - - 'lib/tasks/data.rake' + Enabled: false # Offense count: 4 # Cop supports --auto-correct. @@ -439,7 +426,7 @@ Style/HashSyntax: - 'Gemfile' - 'lib/tasks/user.rake' -# Offense count: 23 +# Offense count: 22 # Cop supports --auto-correct. # Configuration parameters: MaxLineLength. Style/IfUnlessModifier: @@ -448,7 +435,7 @@ Style/IfUnlessModifier: - 'app/controllers/api/v1/events_controller.rb' - 'app/controllers/conference_registrations_controller.rb' - 'app/controllers/users/omniauth_callbacks_controller.rb' - - 'app/helpers/application_helper.rb' + - 'app/helpers/format_helper.rb' - 'app/models/commercial.rb' - 'app/models/conference.rb' - 'app/models/ticket_purchase.rb' @@ -456,7 +443,6 @@ Style/IfUnlessModifier: - 'db/migrate/20151031092713_change_conference_id_to_venue_id_in_rooms.rb' - 'lib/tasks/events_registrations.rake' - 'spec/controllers/admin/conferences_controller_spec.rb' - - 'spec/features/omniauth_spec.rb' - 'spec/support/flash.rb' # Offense count: 2 @@ -472,7 +458,7 @@ Style/IndentArray: # Configuration parameters: IndentationWidth. Style/IndentAssignment: Exclude: - - 'app/helpers/application_helper.rb' + - 'app/helpers/format_helper.rb' - 'app/models/conference.rb' # Offense count: 3 @@ -494,12 +480,12 @@ Style/IndentationConsistency: - 'app/models/event.rb' - 'spec/controllers/subscriptions_controller_spec.rb' -# Offense count: 7 +# Offense count: 6 # Cop supports --auto-correct. # Configuration parameters: Width, IgnoredPatterns. Style/IndentationWidth: Exclude: - - 'app/helpers/application_helper.rb' + - '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' @@ -583,7 +569,6 @@ Style/MultilineMethodCallIndentation: # SupportedStyles: aligned, indented Style/MultilineOperationIndentation: Exclude: - - 'app/controllers/admin/conferences_controller.rb' - 'app/controllers/admin/events_controller.rb' - 'app/controllers/application_controller.rb' - 'app/models/ability.rb' @@ -598,14 +583,6 @@ Style/MutableConstant: - 'app/models/event_user.rb' - 'lib/tasks/migrate_config.rake' -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: both, prefix, postfix -Style/NegatedIf: - Exclude: - - 'lib/tasks/update_resource_quantity.rake' - # Offense count: 4 # Cop supports --auto-correct. Style/NestedParenthesizedCalls: @@ -649,7 +626,8 @@ Style/NumericPredicate: Exclude: - 'spec/**/*' - 'app/controllers/admin/conferences_controller.rb' - - 'app/helpers/application_helper.rb' + - 'app/helpers/date_time_helper.rb' + - 'app/helpers/format_helper.rb' - 'app/models/user.rb' # Offense count: 3 @@ -664,7 +642,7 @@ Style/ParenthesesAroundCondition: Exclude: - 'app/controllers/admin/base_controller.rb' - 'app/controllers/application_controller.rb' - - 'app/helpers/application_helper.rb' + - 'app/helpers/format_helper.rb' # Offense count: 17 # Cop supports --auto-correct. @@ -722,12 +700,15 @@ Style/RedundantParentheses: Exclude: - 'app/controllers/admin/base_controller.rb' -# Offense count: 10 +# Offense count: 9 # Cop supports --auto-correct. # Configuration parameters: AllowMultipleReturnValues. Style/RedundantReturn: Exclude: - 'app/helpers/application_helper.rb' + - 'app/helpers/format_helper.rb' + - 'app/helpers/paths_helper.rb' + - 'app/helpers/users_helper.rb' # Offense count: 2 # Cop supports --auto-correct. @@ -767,21 +748,13 @@ Style/SpaceAfterComma: Exclude: - 'lib/tasks/data_demo.rake' -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleInsidePipes, SupportedStylesInsidePipes. -# SupportedStylesInsidePipes: space, no_space -Style/SpaceAroundBlockParameters: - Exclude: - - 'app/helpers/application_helper.rb' - # Offense count: 2 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: space, no_space Style/SpaceAroundEqualsInParameterDefault: Exclude: - - 'app/helpers/application_helper.rb' + - 'app/helpers/format_helper.rb' - 'app/models/event.rb' # Offense count: 1 @@ -791,7 +764,7 @@ Style/SpaceAroundOperators: Exclude: - 'lib/tasks/data.rake' -# Offense count: 315 +# Offense count: 319 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: space, no_space @@ -887,7 +860,7 @@ Style/StringLiteralsInInterpolation: Exclude: - 'lib/tasks/dump_db.rake' -# Offense count: 59 +# Offense count: 60 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: percent, brackets @@ -914,14 +887,16 @@ Style/SymbolProc: # SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex Style/TernaryParentheses: Exclude: - - 'app/helpers/application_helper.rb' + - 'app/helpers/format_helper.rb' -# Offense count: 2 +# Offense count: 4 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: final_newline, final_blank_line Style/TrailingBlankLines: Exclude: + - 'app/helpers/change_description_helper.rb' + - 'app/helpers/paths_helper.rb' - 'lib/tasks/event_attatchments.rake' - 'lib/tasks/roles.rake' @@ -945,7 +920,7 @@ Style/TrailingWhitespace: # Cop supports --auto-correct. Style/UnneededInterpolation: Exclude: - - 'app/helpers/application_helper.rb' + - 'app/helpers/format_helper.rb' - 'spec/controllers/admin/conferences_controller_spec.rb' # Offense count: 2 From 5b1a730e199fc637697c472657cc107d85ba5675 Mon Sep 17 00:00:00 2001 From: hitman Date: Fri, 10 Mar 2017 02:18:26 +0530 Subject: [PATCH 065/185] rearrange helper functions --- app/helpers/application_helper.rb | 36 +++++++++++++------------------ app/helpers/date_time_helper.rb | 35 ------------------------------ app/helpers/events_helper.rb | 12 +++++++++++ app/helpers/format_helper.rb | 9 +++----- app/helpers/paths_helper.rb | 9 -------- 5 files changed, 30 insertions(+), 71 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 09014502..f6f11e00 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,5 +1,4 @@ module ApplicationHelper - ## # Returns a string build from the start and end date of the given conference. # # If the conference is only one day long @@ -34,23 +33,6 @@ module ApplicationHelper result end - # Returns time with conference timezone - def time_with_timezone(time) - time.strftime('%F %R') + ' ' + @conference.timezone.to_s - end - - ## - # Checks if the voting has already started, or if it has already ended - # - def voting_open_or_close(program) - return if program.voting_period? - if program.voting_start_date > Time.current - return 'Voting period has not started yet!' - else # voting_end_date > Date.today because voting_start_date < voting_end_date - return 'Voting period is over!' - end - end - # Set resource_name for devise so that we can call the devise help links (views/devise/shared/_links) from anywhere (eg sign_up form in proposals#new) def resource_name :user @@ -130,9 +112,21 @@ module ApplicationHelper object end - def quantity_left_of(resource) - return '-/-' if resource.quantity.blank? - "#{resource.quantity - resource.used}/#{resource.quantity}" + def normalize_array_length(hashmap, length) + hashmap.each do |_, value| + if value.length < length + value.fill(value[-1], value.length...length) + end + end + end + + # Same as redirect_to(:back) if there is a valid HTTP referer, otherwise redirect_to() + def redirect_back_or_to(options = {}, response_status = {}) + if request.env['HTTP_REFERER'] + redirect_to :back + else + redirect_to options, response_status + end end def concurrent_events(event) diff --git a/app/helpers/date_time_helper.rb b/app/helpers/date_time_helper.rb index 0acb2aef..a8e4f660 100644 --- a/app/helpers/date_time_helper.rb +++ b/app/helpers/date_time_helper.rb @@ -2,41 +2,6 @@ module DateTimeHelper ## # Includes functions related to date or time manipulations ## - ## - # Returns a string build from the start and end date of the given conference. - # - # If the conference is only one day long - # * %B %d %Y (January 17 2014) - # If the conference starts and ends in the same month and year - # * %B %d - %d, %Y (January 17 - 21 2014) - # If the conference ends in another month but in the same year - # * %B %d - %B %d, %Y (January 31 - February 02 2014) - # All other cases - # * %B %d, %Y - %B %d, %Y (December 30, 2013 - January 02, 2014) - def date_string(start_date, end_date) - startstr = 'Unknown - ' - endstr = 'Unknown' - # When the conference is in the same month - if start_date.month == end_date.month && start_date.year == end_date.year - if start_date.day == end_date.day - startstr = start_date.strftime('%B %d') - endstr = end_date.strftime(' %Y') - else - startstr = start_date.strftime('%B %d - ') - endstr = end_date.strftime('%d, %Y') - end - elsif start_date.month != end_date.month && start_date.year == end_date.year - startstr = start_date.strftime('%B %d - ') - endstr = end_date.strftime('%B %d, %Y') - else - startstr = start_date.strftime('%B %d, %Y - ') - endstr = end_date.strftime('%B %d, %Y') - end - - result = startstr + endstr - result - end - ## # Gets an EventType object, and returns its length in timestamp format (HH:MM) # ====Gets diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb index 38b380b5..8f078db1 100644 --- a/app/helpers/events_helper.rb +++ b/app/helpers/events_helper.rb @@ -10,6 +10,18 @@ module EventsHelper "Registered: #{event.registrations.count}" end + ## + # Checks if the voting has already started, or if it has already ended + # + def voting_open_or_close(program) + return if program.voting_period? + if program.voting_start_date > Time.current + return 'Voting period has not started yet!' + else # voting_end_date > Date.today because voting_start_date < voting_end_date + return 'Voting period is over!' + end + end + def event_types(conference) all = conference.program.event_types.map { |et| et.title.pluralize } first = all[0...-1] diff --git a/app/helpers/format_helper.rb b/app/helpers/format_helper.rb index da9ee598..bd64e3ac 100644 --- a/app/helpers/format_helper.rb +++ b/app/helpers/format_helper.rb @@ -192,11 +192,8 @@ module FormatHelper markdown("#{text} Please look at #{link_to '**Markdown Syntax**', 'https://daringfireball.net/projects/markdown/syntax', target: '_blank'} to format your text") end - def normalize_array_length(hashmap, length) - hashmap.each do |_, value| - if value.length < length - value.fill(value[-1], value.length...length) - end - end + def quantity_left_of(resource) + return '-/-' if resource.quantity.blank? + "#{resource.quantity - resource.used}/#{resource.quantity}" end end diff --git a/app/helpers/paths_helper.rb b/app/helpers/paths_helper.rb index 8b235ccd..3633292a 100644 --- a/app/helpers/paths_helper.rb +++ b/app/helpers/paths_helper.rb @@ -30,13 +30,4 @@ module PathsHelper return '' end end - - # Same as redirect_to(:back) if there is a valid HTTP referer, otherwise redirect_to() - def redirect_back_or_to(options = {}, response_status = {}) - if request.env['HTTP_REFERER'] - redirect_to :back - else - redirect_to options, response_status - end - end end From 2e0f7e9b423e68237ced37cd1dc470857105cd75 Mon Sep 17 00:00:00 2001 From: hitman Date: Thu, 16 Mar 2017 22:30:03 +0530 Subject: [PATCH 066/185] relocate some functions --- app/helpers/application_helper.rb | 22 ++++++++++++++++++++++ app/helpers/events_helper.rb | 14 -------------- app/helpers/paths_helper.rb | 8 -------- app/helpers/users_helper.rb | 8 -------- 4 files changed, 22 insertions(+), 30 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index f6f11e00..e3b1a692 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -156,4 +156,26 @@ module ApplicationHelper collection: options_for_select(users.map {|user| ["#{user[1]} (#{user[2]}) #{user[3]}", user[0]]}, @event.speakers.map(&:id)), include_blank: false, label: 'Speakers', input_html: { class: 'select-help-toggle', multiple: 'true' } end + + def event_types(conference) + all = conference.program.event_types.map { |et| et.title.pluralize } + first = all[0...-1] + last = all[-1] + ets = '' + if all.length > 1 + ets << first.join(', ') + ets << " and #{last}" + else + ets = all.join + end + ets + end + + def sign_in_path + if ENV['OSEM_ICHAIN_ENABLED'] == 'true' + new_user_ichain_session_path + else + new_user_session_path + end + end end diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb index 8f078db1..012bd930 100644 --- a/app/helpers/events_helper.rb +++ b/app/helpers/events_helper.rb @@ -22,20 +22,6 @@ module EventsHelper end end - def event_types(conference) - all = conference.program.event_types.map { |et| et.title.pluralize } - first = all[0...-1] - last = all[-1] - ets = '' - if all.length > 1 - ets << first.join(', ') - ets << " and #{last}" - else - ets = all.join - end - ets - end - def replacement_event_notice(event_schedule) if event_schedule.present? && event_schedule.replacement? replaced_event = (event_schedule.intersecting_event_schedules.withdrawn.first || event_schedule.intersecting_event_schedules.canceled.first).event diff --git a/app/helpers/paths_helper.rb b/app/helpers/paths_helper.rb index 3633292a..50bedfb6 100644 --- a/app/helpers/paths_helper.rb +++ b/app/helpers/paths_helper.rb @@ -15,14 +15,6 @@ module PathsHelper end end - def sign_in_path - if ENV['OSEM_ICHAIN_ENABLED'] == 'true' - new_user_ichain_session_path - else - new_user_session_path - end - end - def active_nav_li(link) if current_page?(link) return 'active' diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index 916fcb63..e2fd1349 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -28,14 +28,6 @@ module UsersHelper roles.map{ |x| x[0].titleize + ' (' + x[1].join(', ') + ')' }.join ', ' end - def can_manage_volunteers(conference) - if (current_user.has_role? :organizer, conference) || (current_user.has_role? :volunteers_coordinator, conference) - true - else - false - end - end - def user_change_description(version) if version.event == 'create' link_to_user(version.item_id) + ' signed up' From d9925f00e969a611385efe986c796a34adef79b5 Mon Sep 17 00:00:00 2001 From: hitman Date: Thu, 16 Mar 2017 22:31:42 +0530 Subject: [PATCH 067/185] add volunteers helper --- .../admin/volunteers_controller.rb | 1 + app/helpers/admin/volunteers_helper.rb | 11 ++++++++++ spec/helpers/events_helper_spec.rb | 21 +++++++++++++++++++ spec/helpers/format_helper_spec.rb | 20 ++++++++++++++++++ spec/helpers/users_helper_spec.rb | 11 ++++++++++ 5 files changed, 64 insertions(+) create mode 100644 app/helpers/admin/volunteers_helper.rb create mode 100644 spec/helpers/events_helper_spec.rb create mode 100644 spec/helpers/format_helper_spec.rb create mode 100644 spec/helpers/users_helper_spec.rb diff --git a/app/controllers/admin/volunteers_controller.rb b/app/controllers/admin/volunteers_controller.rb index ec6d7ac7..a6ce367b 100644 --- a/app/controllers/admin/volunteers_controller.rb +++ b/app/controllers/admin/volunteers_controller.rb @@ -1,5 +1,6 @@ module Admin class VolunteersController < Admin::BaseController + include VolunteersHelper load_and_authorize_resource :conference, find_by: :short_title def index diff --git a/app/helpers/admin/volunteers_helper.rb b/app/helpers/admin/volunteers_helper.rb new file mode 100644 index 00000000..d71719db --- /dev/null +++ b/app/helpers/admin/volunteers_helper.rb @@ -0,0 +1,11 @@ +module Admin + module VolunteersHelper + def can_manage_volunteers(conference) + if (current_user.has_role? :organizer, conference) || (current_user.has_role? :volunteers_coordinator, conference) + true + else + false + end + end + end +end diff --git a/spec/helpers/events_helper_spec.rb b/spec/helpers/events_helper_spec.rb new file mode 100644 index 00000000..4d92ce0b --- /dev/null +++ b/spec/helpers/events_helper_spec.rb @@ -0,0 +1,21 @@ +require 'spec_helper' + +describe EventsHelper, type: :helper do + let(:conference) { create(:conference) } + let(:event) { create(:event, program: conference.program) } + + describe '#registered_text' do + describe 'returns correct string' do + it 'when there are no registrations' do + expect(registered_text(event)).to eq 'Registered: 0' + end + + it 'when there is 1 registration' do + event.require_registration = true + event.max_attendees = 3 + event.registrations << create(:registration, user: event.submitter) + expect(registered_text(event)).to eq 'Registered: 1/3' + end + end + end +end diff --git a/spec/helpers/format_helper_spec.rb b/spec/helpers/format_helper_spec.rb new file mode 100644 index 00000000..dd306b5f --- /dev/null +++ b/spec/helpers/format_helper_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +describe FormatHelper, type: :helper do + + describe 'markdown' do + it 'should return empty string for nil' do + expect(markdown(nil)).to eq '' + end + + it 'should return HTML for header markdown' do + expect(Redcarpet::Markdown).to receive(:new). + with(Redcarpet::Render::HTML, autolink: true, + space_after_headers: true, + no_intra_emphasis: true). + and_call_original + + expect(markdown('# this is my header')).to eq "

this is my header

\n" + end + end +end diff --git a/spec/helpers/users_helper_spec.rb b/spec/helpers/users_helper_spec.rb new file mode 100644 index 00000000..dfc337e6 --- /dev/null +++ b/spec/helpers/users_helper_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' + +describe UsersHelper, type: :helper do + + describe 'show_roles' do + it 'formats the hash passed' do + roles = { 'organizer' => ['oSC16', 'oSC15'], 'cfp' => ['oSC16'] } + expect(show_roles(roles)).to eq 'Organizer (oSC16, oSC15), Cfp (oSC16)' + end + end +end From 8320f78d0bd487a739eba8d085c2a51f2922aadb Mon Sep 17 00:00:00 2001 From: hitman Date: Thu, 16 Mar 2017 22:32:11 +0530 Subject: [PATCH 068/185] add test for new helpers --- spec/helpers/application_helper_spec.rb | 71 ------------------------- spec/helpers/date_time_helper_spec.rb | 37 +++++++++++++ 2 files changed, 37 insertions(+), 71 deletions(-) create mode 100644 spec/helpers/date_time_helper_spec.rb diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index bc951e08..139a5cf9 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -4,62 +4,6 @@ describe ApplicationHelper, type: :helper do let(:conference) { create(:conference) } let(:event) { create(:event, program: conference.program) } - describe 'format_datetme' do - it 'returns nothing if there is no parameter' do - expect(format_datetime(nil)).to eq nil - end - - it 'returns formatted string' do - datetime = Time.zone.local(2016, 05, 04, 11, 30) - expect(format_datetime(datetime)).to eq '2016-05-04 11:30' - end - end - - describe 'show_time' do - it 'when length > 60' do - expect(show_time(67)).to eq '1 h 7 min' - end - - it 'when length = 60' do - expect(show_time(60)).to eq '1 h' - end - - it 'when length < 60' do - expect(show_time(58)).to eq '58 min' - end - - it 'when length > 60 and is a decimal number' do - expect(show_time(68.3)).to eq '1 h 8 min' - end - - it 'when length is nil' do - expect(show_time(nil)).to eq '0 h 0 min' - end - end - - describe 'show_roles' do - it 'formats the hash passed' do - roles = { 'organizer' => ['oSC16', 'oSC15'], 'cfp' => ['oSC16'] } - expect(show_roles(roles)).to eq 'Organizer (oSC16, oSC15), Cfp (oSC16)' - end - end - - describe 'markdown' do - it 'should return empty string for nil' do - expect(markdown(nil)).to eq '' - end - - it 'should return HTML for header markdown' do - expect(Redcarpet::Markdown).to receive(:new) - .with(Redcarpet::Render::HTML, autolink: true, - space_after_headers: true, - no_intra_emphasis: true) - .and_call_original - - expect(markdown('# this is my header')).to eq "

this is my header

\n" - end - end - describe '#date_string' do it 'when conference lasts 1 day' do expect(date_string('Sun, 19 Feb 2017'.to_time, 'Sun, 19 Feb 2017'.to_time)).to eq 'February 19 2017' @@ -78,21 +22,6 @@ describe ApplicationHelper, type: :helper do end end - describe '#registered_text' do - describe 'returns correct string' do - it 'when there are no registrations' do - expect(registered_text(event)).to eq 'Registered: 0' - end - - it 'when there is 1 registration' do - event.require_registration = true - event.max_attendees = 3 - event.registrations << create(:registration, user: event.submitter) - expect(registered_text(event)).to eq 'Registered: 1/3' - end - end - end - describe '#concurrent_events' do before :each do @other_event = create(:event, program: conference.program, state: 'confirmed') diff --git a/spec/helpers/date_time_helper_spec.rb b/spec/helpers/date_time_helper_spec.rb new file mode 100644 index 00000000..09c7e4a4 --- /dev/null +++ b/spec/helpers/date_time_helper_spec.rb @@ -0,0 +1,37 @@ +require 'spec_helper' + +describe DateTimeHelper, type: :helper do + + describe 'format_datetime' do + it 'returns nothing if there is no parameter' do + expect(format_datetime(nil)).to eq nil + end + + it 'returns formatted string' do + datetime = Time.zone.local(2016, 05, 04, 11, 30) + expect(format_datetime(datetime)).to eq '2016-05-04 11:30' + end + end + + describe 'show_time' do + it 'when length > 60' do + expect(show_time(67)).to eq '1 h 7 min' + end + + it 'when length = 60' do + expect(show_time(60)).to eq '1 h' + end + + it 'when length < 60' do + expect(show_time(58)).to eq '58 min' + end + + it 'when length > 60 and is a decimal number' do + expect(show_time(68.3)).to eq '1 h 8 min' + end + + it 'when length is nil' do + expect(show_time(nil)).to eq '0 h 0 min' + end + end +end From 5dece1ea482fc17298de584a1b5fdfbe55b16f65 Mon Sep 17 00:00:00 2001 From: hitman Date: Mon, 6 Mar 2017 23:54:29 +0530 Subject: [PATCH 069/185] refractor code into different files --- app/helpers/application_helper.rb | 61 ++++++++++++------------------- app/helpers/date_time_helper.rb | 37 +++++++++++++++++++ app/helpers/format_helper.rb | 7 ++++ app/helpers/paths_helper.rb | 8 ++++ 4 files changed, 75 insertions(+), 38 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index e3b1a692..b662bf84 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,36 +1,20 @@ module ApplicationHelper - # Returns a string build from the start and end date of the given conference. + include DateTimeHelper + include FormatHelper + include EventsHelper + include UsersHelper + include PathsHelper + include ChangeDescriptionHelper + ## + # Checks if the voting has already started, or if it has already ended # - # If the conference is only one day long - # * %B %d %Y (January 17 2014) - # If the conference starts and ends in the same month and year - # * %B %d - %d, %Y (January 17 - 21 2014) - # If the conference ends in another month but in the same year - # * %B %d - %B %d, %Y (January 31 - February 02 2014) - # All other cases - # * %B %d, %Y - %B %d, %Y (December 30, 2013 - January 02, 2014) - def date_string(start_date, end_date) - startstr = 'Unknown - ' - endstr = 'Unknown' - # When the conference is in the same month - if start_date.month == end_date.month && start_date.year == end_date.year - if start_date.day == end_date.day - startstr = start_date.strftime('%B %d') - endstr = end_date.strftime(' %Y') - else - startstr = start_date.strftime('%B %d - ') - endstr = end_date.strftime('%d, %Y') - end - elsif start_date.month != end_date.month && start_date.year == end_date.year - startstr = start_date.strftime('%B %d - ') - endstr = end_date.strftime('%B %d, %Y') - else - startstr = start_date.strftime('%B %d, %Y - ') - endstr = end_date.strftime('%B %d, %Y') + def voting_open_or_close(program) + return if program.voting_period? + if program.voting_start_date > Time.current + return 'Voting period has not started yet!' + else # voting_end_date > Date.today because voting_start_date < voting_end_date + return 'Voting period is over!' end - - result = startstr + endstr - result end # Set resource_name for devise so that we can call the devise help links (views/devise/shared/_links) from anywhere (eg sign_up form in proposals#new) @@ -50,6 +34,15 @@ module ApplicationHelper render 'shared/dynamic_association', association_name: association_name, title: title, f: form_builder, hint: options[:hint] end + # Same as redirect_to(:back) if there is a valid HTTP referer, otherwise redirect_to() + def redirect_back_or_to(options = {}, response_status = {}) + if request.env['HTTP_REFERER'] + redirect_to :back + else + redirect_to options, response_status + end + end + def tracks(conference) all = conference.program.tracks.map {|t| t.name} first = all[0...-1] @@ -112,14 +105,6 @@ module ApplicationHelper object end - def normalize_array_length(hashmap, length) - hashmap.each do |_, value| - if value.length < length - value.fill(value[-1], value.length...length) - end - end - end - # Same as redirect_to(:back) if there is a valid HTTP referer, otherwise redirect_to() def redirect_back_or_to(options = {}, response_status = {}) if request.env['HTTP_REFERER'] diff --git a/app/helpers/date_time_helper.rb b/app/helpers/date_time_helper.rb index a8e4f660..49c7f983 100644 --- a/app/helpers/date_time_helper.rb +++ b/app/helpers/date_time_helper.rb @@ -1,7 +1,44 @@ module DateTimeHelper ## +<<<<<<< HEAD # Includes functions related to date or time manipulations ## +======= + # Returns a string build from the start and end date of the given conference. + # + # If the conference is only one day long + # * %B %d %Y (January 17 2014) + # If the conference starts and ends in the same month and year + # * %B %d - %d, %Y (January 17 - 21 2014) + # If the conference ends in another month but in the same year + # * %B %d - %B %d, %Y (January 31 - February 02 2014) + # All other cases + # * %B %d, %Y - %B %d, %Y (December 30, 2013 - January 02, 2014) + def date_string(start_date, end_date) + startstr = 'Unknown - ' + endstr = 'Unknown' + # When the conference is in the same month + if start_date.month == end_date.month && start_date.year == end_date.year + if start_date.day == end_date.day + startstr = start_date.strftime('%B %d') + endstr = end_date.strftime(' %Y') + else + startstr = start_date.strftime('%B %d - ') + endstr = end_date.strftime('%d, %Y') + end + elsif start_date.month != end_date.month && start_date.year == end_date.year + startstr = start_date.strftime('%B %d - ') + endstr = end_date.strftime('%B %d, %Y') + else + startstr = start_date.strftime('%B %d, %Y - ') + endstr = end_date.strftime('%B %d, %Y') + end + + result = startstr + endstr + result + end + +>>>>>>> refractor code into different files ## # Gets an EventType object, and returns its length in timestamp format (HH:MM) # ====Gets diff --git a/app/helpers/format_helper.rb b/app/helpers/format_helper.rb index bd64e3ac..92f5ef15 100644 --- a/app/helpers/format_helper.rb +++ b/app/helpers/format_helper.rb @@ -195,5 +195,12 @@ module FormatHelper def quantity_left_of(resource) return '-/-' if resource.quantity.blank? "#{resource.quantity - resource.used}/#{resource.quantity}" + + def normalize_array_length(hashmap, length) + hashmap.each do |_, value| + if value.length < length + value.fill(value[-1], value.length...length) + end + end end end diff --git a/app/helpers/paths_helper.rb b/app/helpers/paths_helper.rb index 50bedfb6..3633292a 100644 --- a/app/helpers/paths_helper.rb +++ b/app/helpers/paths_helper.rb @@ -15,6 +15,14 @@ module PathsHelper end end + def sign_in_path + if ENV['OSEM_ICHAIN_ENABLED'] == 'true' + new_user_ichain_session_path + else + new_user_session_path + end + end + def active_nav_li(link) if current_page?(link) return 'active' From a5d637fcf15c6f511bb4900737eafeb83297668c Mon Sep 17 00:00:00 2001 From: hitman Date: Tue, 7 Mar 2017 01:42:33 +0530 Subject: [PATCH 070/185] add documentation for each helper --- app/helpers/application_helper.rb | 10 +--------- app/helpers/date_time_helper.rb | 4 +--- app/helpers/paths_helper.rb | 9 +++++++++ 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index b662bf84..d817cca1 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,4 +1,5 @@ module ApplicationHelper + # Including custom made helpers include DateTimeHelper include FormatHelper include EventsHelper @@ -34,15 +35,6 @@ module ApplicationHelper render 'shared/dynamic_association', association_name: association_name, title: title, f: form_builder, hint: options[:hint] end - # Same as redirect_to(:back) if there is a valid HTTP referer, otherwise redirect_to() - def redirect_back_or_to(options = {}, response_status = {}) - if request.env['HTTP_REFERER'] - redirect_to :back - else - redirect_to options, response_status - end - end - def tracks(conference) all = conference.program.tracks.map {|t| t.name} first = all[0...-1] diff --git a/app/helpers/date_time_helper.rb b/app/helpers/date_time_helper.rb index 49c7f983..0acb2aef 100644 --- a/app/helpers/date_time_helper.rb +++ b/app/helpers/date_time_helper.rb @@ -1,9 +1,8 @@ module DateTimeHelper ## -<<<<<<< HEAD # Includes functions related to date or time manipulations ## -======= + ## # Returns a string build from the start and end date of the given conference. # # If the conference is only one day long @@ -38,7 +37,6 @@ module DateTimeHelper result end ->>>>>>> refractor code into different files ## # Gets an EventType object, and returns its length in timestamp format (HH:MM) # ====Gets diff --git a/app/helpers/paths_helper.rb b/app/helpers/paths_helper.rb index 3633292a..8b235ccd 100644 --- a/app/helpers/paths_helper.rb +++ b/app/helpers/paths_helper.rb @@ -30,4 +30,13 @@ module PathsHelper return '' end end + + # Same as redirect_to(:back) if there is a valid HTTP referer, otherwise redirect_to() + def redirect_back_or_to(options = {}, response_status = {}) + if request.env['HTTP_REFERER'] + redirect_to :back + else + redirect_to options, response_status + end + end end From bb0857cbaddc41679035405fd7e0f08a5b364100 Mon Sep 17 00:00:00 2001 From: hitman Date: Thu, 9 Mar 2017 16:51:16 +0530 Subject: [PATCH 071/185] remove unnecessary includes from ApplicationHelper --- app/helpers/application_helper.rb | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index d817cca1..91883d84 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,11 +1,4 @@ module ApplicationHelper - # Including custom made helpers - include DateTimeHelper - include FormatHelper - include EventsHelper - include UsersHelper - include PathsHelper - include ChangeDescriptionHelper ## # Checks if the voting has already started, or if it has already ended # From c6203a4ed4beb666882c683df7a47a878adeb17d Mon Sep 17 00:00:00 2001 From: hitman Date: Fri, 10 Mar 2017 02:18:26 +0530 Subject: [PATCH 072/185] rearrange helper functions --- app/helpers/application_helper.rb | 46 +++++++++++++++++++++++++------ app/helpers/date_time_helper.rb | 35 ----------------------- app/helpers/format_helper.rb | 7 ----- app/helpers/paths_helper.rb | 9 ------ 4 files changed, 38 insertions(+), 59 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 91883d84..e3b1a692 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,14 +1,36 @@ module ApplicationHelper - ## - # Checks if the voting has already started, or if it has already ended + # Returns a string build from the start and end date of the given conference. # - def voting_open_or_close(program) - return if program.voting_period? - if program.voting_start_date > Time.current - return 'Voting period has not started yet!' - else # voting_end_date > Date.today because voting_start_date < voting_end_date - return 'Voting period is over!' + # If the conference is only one day long + # * %B %d %Y (January 17 2014) + # If the conference starts and ends in the same month and year + # * %B %d - %d, %Y (January 17 - 21 2014) + # If the conference ends in another month but in the same year + # * %B %d - %B %d, %Y (January 31 - February 02 2014) + # All other cases + # * %B %d, %Y - %B %d, %Y (December 30, 2013 - January 02, 2014) + def date_string(start_date, end_date) + startstr = 'Unknown - ' + endstr = 'Unknown' + # When the conference is in the same month + if start_date.month == end_date.month && start_date.year == end_date.year + if start_date.day == end_date.day + startstr = start_date.strftime('%B %d') + endstr = end_date.strftime(' %Y') + else + startstr = start_date.strftime('%B %d - ') + endstr = end_date.strftime('%d, %Y') + end + elsif start_date.month != end_date.month && start_date.year == end_date.year + startstr = start_date.strftime('%B %d - ') + endstr = end_date.strftime('%B %d, %Y') + else + startstr = start_date.strftime('%B %d, %Y - ') + endstr = end_date.strftime('%B %d, %Y') end + + result = startstr + endstr + result end # Set resource_name for devise so that we can call the devise help links (views/devise/shared/_links) from anywhere (eg sign_up form in proposals#new) @@ -90,6 +112,14 @@ module ApplicationHelper object end + def normalize_array_length(hashmap, length) + hashmap.each do |_, value| + if value.length < length + value.fill(value[-1], value.length...length) + end + end + end + # Same as redirect_to(:back) if there is a valid HTTP referer, otherwise redirect_to() def redirect_back_or_to(options = {}, response_status = {}) if request.env['HTTP_REFERER'] diff --git a/app/helpers/date_time_helper.rb b/app/helpers/date_time_helper.rb index 0acb2aef..a8e4f660 100644 --- a/app/helpers/date_time_helper.rb +++ b/app/helpers/date_time_helper.rb @@ -2,41 +2,6 @@ module DateTimeHelper ## # Includes functions related to date or time manipulations ## - ## - # Returns a string build from the start and end date of the given conference. - # - # If the conference is only one day long - # * %B %d %Y (January 17 2014) - # If the conference starts and ends in the same month and year - # * %B %d - %d, %Y (January 17 - 21 2014) - # If the conference ends in another month but in the same year - # * %B %d - %B %d, %Y (January 31 - February 02 2014) - # All other cases - # * %B %d, %Y - %B %d, %Y (December 30, 2013 - January 02, 2014) - def date_string(start_date, end_date) - startstr = 'Unknown - ' - endstr = 'Unknown' - # When the conference is in the same month - if start_date.month == end_date.month && start_date.year == end_date.year - if start_date.day == end_date.day - startstr = start_date.strftime('%B %d') - endstr = end_date.strftime(' %Y') - else - startstr = start_date.strftime('%B %d - ') - endstr = end_date.strftime('%d, %Y') - end - elsif start_date.month != end_date.month && start_date.year == end_date.year - startstr = start_date.strftime('%B %d - ') - endstr = end_date.strftime('%B %d, %Y') - else - startstr = start_date.strftime('%B %d, %Y - ') - endstr = end_date.strftime('%B %d, %Y') - end - - result = startstr + endstr - result - end - ## # Gets an EventType object, and returns its length in timestamp format (HH:MM) # ====Gets diff --git a/app/helpers/format_helper.rb b/app/helpers/format_helper.rb index 92f5ef15..bd64e3ac 100644 --- a/app/helpers/format_helper.rb +++ b/app/helpers/format_helper.rb @@ -195,12 +195,5 @@ module FormatHelper def quantity_left_of(resource) return '-/-' if resource.quantity.blank? "#{resource.quantity - resource.used}/#{resource.quantity}" - - def normalize_array_length(hashmap, length) - hashmap.each do |_, value| - if value.length < length - value.fill(value[-1], value.length...length) - end - end end end diff --git a/app/helpers/paths_helper.rb b/app/helpers/paths_helper.rb index 8b235ccd..3633292a 100644 --- a/app/helpers/paths_helper.rb +++ b/app/helpers/paths_helper.rb @@ -30,13 +30,4 @@ module PathsHelper return '' end end - - # Same as redirect_to(:back) if there is a valid HTTP referer, otherwise redirect_to() - def redirect_back_or_to(options = {}, response_status = {}) - if request.env['HTTP_REFERER'] - redirect_to :back - else - redirect_to options, response_status - end - end end From 85fa39870d391369fc3df3e4f216da8822804f29 Mon Sep 17 00:00:00 2001 From: hitman Date: Thu, 16 Mar 2017 22:30:03 +0530 Subject: [PATCH 073/185] relocate some functions --- app/helpers/paths_helper.rb | 8 -------- 1 file changed, 8 deletions(-) diff --git a/app/helpers/paths_helper.rb b/app/helpers/paths_helper.rb index 3633292a..50bedfb6 100644 --- a/app/helpers/paths_helper.rb +++ b/app/helpers/paths_helper.rb @@ -15,14 +15,6 @@ module PathsHelper end end - def sign_in_path - if ENV['OSEM_ICHAIN_ENABLED'] == 'true' - new_user_ichain_session_path - else - new_user_session_path - end - end - def active_nav_li(link) if current_page?(link) return 'active' From b36d02ceec940ed58f3e046fe6662d86f0e2c4dd Mon Sep 17 00:00:00 2001 From: hitman Date: Fri, 17 Mar 2017 18:50:29 +0530 Subject: [PATCH 074/185] change to can_manage_volunteers? --- app/controllers/admin/volunteers_controller.rb | 4 ++-- app/helpers/admin/volunteers_helper.rb | 8 ++------ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/app/controllers/admin/volunteers_controller.rb b/app/controllers/admin/volunteers_controller.rb index a6ce367b..e8676bae 100644 --- a/app/controllers/admin/volunteers_controller.rb +++ b/app/controllers/admin/volunteers_controller.rb @@ -4,7 +4,7 @@ module Admin load_and_authorize_resource :conference, find_by: :short_title def index - if can_manage_volunteers(@conference) + if can_manage_volunteers?(@conference) render :index else authorize! :index, :volunteer @@ -12,7 +12,7 @@ module Admin end def show - if can_manage_volunteers(@conference) + if can_manage_volunteers?(@conference) if @conference.use_vpositions @volunteers = @conference.registrations.joins(:vchoices).uniq else diff --git a/app/helpers/admin/volunteers_helper.rb b/app/helpers/admin/volunteers_helper.rb index d71719db..f29c65fe 100644 --- a/app/helpers/admin/volunteers_helper.rb +++ b/app/helpers/admin/volunteers_helper.rb @@ -1,11 +1,7 @@ module Admin module VolunteersHelper - def can_manage_volunteers(conference) - if (current_user.has_role? :organizer, conference) || (current_user.has_role? :volunteers_coordinator, conference) - true - else - false - end + def can_manage_volunteers?(conference) + !!(current_user.has_role? :organizer, conference) || (current_user.has_role? :volunteers_coordinator, conference) end end end From 4fbb7db16b42d5d6028aa061f9d7c4ed2b5c083c Mon Sep 17 00:00:00 2001 From: hitman Date: Fri, 17 Mar 2017 18:52:10 +0530 Subject: [PATCH 075/185] modify event_type function --- app/helpers/application_helper.rb | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index e3b1a692..b3081f9b 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -158,17 +158,7 @@ module ApplicationHelper end def event_types(conference) - all = conference.program.event_types.map { |et| et.title.pluralize } - first = all[0...-1] - last = all[-1] - ets = '' - if all.length > 1 - ets << first.join(', ') - ets << " and #{last}" - else - ets = all.join - end - ets + conference.program.event_types.map { |et| et.title.pluralize }.to_sentence end def sign_in_path From dbffece956dc45fc2924bf0466ba0fc4928ce295 Mon Sep 17 00:00:00 2001 From: hitman Date: Fri, 17 Mar 2017 23:05:51 +0530 Subject: [PATCH 076/185] remove !! from can_manage_volunteers --- app/helpers/admin/volunteers_helper.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/helpers/admin/volunteers_helper.rb b/app/helpers/admin/volunteers_helper.rb index f29c65fe..79c94126 100644 --- a/app/helpers/admin/volunteers_helper.rb +++ b/app/helpers/admin/volunteers_helper.rb @@ -1,7 +1,11 @@ module Admin module VolunteersHelper def can_manage_volunteers?(conference) - !!(current_user.has_role? :organizer, conference) || (current_user.has_role? :volunteers_coordinator, conference) + if (current_user.has_role? :organizer, conference) || (current_user.has_role? :volunteers_coordinator, conference) + true + else + false + end end end end From 60afb2a474b53b016bc5e15c4493d16e99a95870 Mon Sep 17 00:00:00 2001 From: hitman Date: Mon, 20 Mar 2017 22:22:50 +0530 Subject: [PATCH 077/185] refractor can_manage_volunteers? --- app/helpers/admin/volunteers_helper.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/helpers/admin/volunteers_helper.rb b/app/helpers/admin/volunteers_helper.rb index 79c94126..0f6fa305 100644 --- a/app/helpers/admin/volunteers_helper.rb +++ b/app/helpers/admin/volunteers_helper.rb @@ -1,11 +1,7 @@ module Admin module VolunteersHelper def can_manage_volunteers?(conference) - if (current_user.has_role? :organizer, conference) || (current_user.has_role? :volunteers_coordinator, conference) - true - else - false - end + current_user.has_role?(:organizer, conference) || current_user.has_role?(:volunteers_coordinator, conference) end end end From b4c2eeb772b41d5e3f92bd4d66181c3b635300bb Mon Sep 17 00:00:00 2001 From: Agrim Mittal Date: Fri, 24 Mar 2017 04:12:07 +0530 Subject: [PATCH 078/185] change name to versions_helper --- ...scription_helper.rb => versions_helper.rb} | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) rename app/helpers/{change_description_helper.rb => versions_helper.rb} (73%) diff --git a/app/helpers/change_description_helper.rb b/app/helpers/versions_helper.rb similarity index 73% rename from app/helpers/change_description_helper.rb rename to app/helpers/versions_helper.rb index 99b51bc7..e919eb79 100644 --- a/app/helpers/change_description_helper.rb +++ b/app/helpers/versions_helper.rb @@ -1,7 +1,11 @@ -module ChangeDescriptionHelper +module VersionsHelper ## # Groups functions related to change description ## + def link_if_alive(version, link_text, link_url) + version.item ? link_to(link_text, link_url) : link_text + end + def subscription_change_description(version) user = current_or_last_object_state(version.item_type, version.item_id).user user_name = user.name unless user.id.to_s == version.whodunnit @@ -85,4 +89,24 @@ module ChangeDescriptionHelper when 'destroy' then 'unscheduled' end end + + def user_change_description(version) + if version.event == 'create' + link_to_user(version.item_id) + ' signed up' + elsif version.event == 'update' + if version.changeset.keys.include?('reset_password_sent_at') + 'Someone requested password reset of' + elsif version.changeset.keys.include?('confirmed_at') && version.changeset['confirmed_at'][0].nil? + (version.whodunnit.nil? ? link_to_user(version.item_id) : link_to_user(version.whodunnit)) + ' confirmed account of' + elsif version.changeset.keys.include?('confirmed_at') && version.changeset['confirmed_at'][1].nil? + link_to_user(version.whodunnit) + ' unconfirmed account of' + else + link_to_user(version.whodunnit) + " updated #{updated_attributes(version)} of" + end + end + end + + def users_role_change_description(version) + version.event == 'create' ? 'added' : 'removed' + end end From 255744268b2b7e9ea123878bab22272f7471630f Mon Sep 17 00:00:00 2001 From: Agrim Mittal Date: Fri, 24 Mar 2017 04:12:25 +0530 Subject: [PATCH 079/185] shift relevant functions to versions_helper --- app/helpers/paths_helper.rb | 4 ---- app/helpers/users_helper.rb | 20 -------------------- spec/helpers/format_helper_spec.rb | 8 +++----- 3 files changed, 3 insertions(+), 29 deletions(-) diff --git a/app/helpers/paths_helper.rb b/app/helpers/paths_helper.rb index 50bedfb6..97de8bca 100644 --- a/app/helpers/paths_helper.rb +++ b/app/helpers/paths_helper.rb @@ -2,10 +2,6 @@ module PathsHelper ## # Includes functions related to links or redirects ## - def link_if_alive(version, link_text, link_url) - version.item ? link_to(link_text, link_url) : link_text - end - def link_to_user(user_id) user = User.find_by(id: user_id) if user diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index e2fd1349..50becf0c 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -27,24 +27,4 @@ module UsersHelper def show_roles(roles) roles.map{ |x| x[0].titleize + ' (' + x[1].join(', ') + ')' }.join ', ' end - - def user_change_description(version) - if version.event == 'create' - link_to_user(version.item_id) + ' signed up' - elsif version.event == 'update' - if version.changeset.keys.include?('reset_password_sent_at') - 'Someone requested password reset of' - elsif version.changeset.keys.include?('confirmed_at') && version.changeset['confirmed_at'][0].nil? - (version.whodunnit.nil? ? link_to_user(version.item_id) : link_to_user(version.whodunnit)) + ' confirmed account of' - elsif version.changeset.keys.include?('confirmed_at') && version.changeset['confirmed_at'][1].nil? - link_to_user(version.whodunnit) + ' unconfirmed account of' - else - link_to_user(version.whodunnit) + " updated #{updated_attributes(version)} of" - end - end - end - - def users_role_change_description(version) - version.event == 'create' ? 'added' : 'removed' - end end diff --git a/spec/helpers/format_helper_spec.rb b/spec/helpers/format_helper_spec.rb index dd306b5f..f14de8b3 100644 --- a/spec/helpers/format_helper_spec.rb +++ b/spec/helpers/format_helper_spec.rb @@ -8,11 +8,9 @@ describe FormatHelper, type: :helper do end it 'should return HTML for header markdown' do - expect(Redcarpet::Markdown).to receive(:new). - with(Redcarpet::Render::HTML, autolink: true, - space_after_headers: true, - no_intra_emphasis: true). - and_call_original + expect(Redcarpet::Markdown).to receive(:new) + .with(Redcarpet::Render::HTML, autolink: true, space_after_headers: true, no_intra_emphasis: true) + .and_call_original expect(markdown('# this is my header')).to eq "

this is my header

\n" end From e68738c154f784058eb6ea4471b770fa0c2089ef Mon Sep 17 00:00:00 2001 From: Agrim Mittal Date: Sat, 6 May 2017 17:48:27 +0530 Subject: [PATCH 080/185] update rubocop_todo.yml --- .rubocop_todo.yml | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index c745c398..e0c6dd97 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2017-05-06 15:57:26 +0530 using RuboCop version 0.48.1. +# on 2017-05-06 17:45:40 +0530 using RuboCop version 0.48.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 @@ -57,11 +57,11 @@ Lint/UnusedBlockArgument: Exclude: - 'lib/tasks/user.rake' -# Offense count: 109 +# Offense count: 108 Metrics/AbcSize: Max: 75 -# Offense count: 201 +# Offense count: 202 # Configuration parameters: CountComments, ExcludedMethods. Metrics/BlockLength: Max: 487 @@ -70,13 +70,13 @@ Metrics/BlockLength: Metrics/CyclomaticComplexity: Max: 12 -# Offense count: 1990 +# Offense count: 1991 # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. # URISchemes: http, https Metrics/LineLength: Max: 619 -# Offense count: 117 +# Offense count: 115 # Configuration parameters: CountComments. Metrics/MethodLength: Max: 56 @@ -89,7 +89,7 @@ Metrics/ModuleLength: - 'app/helpers/application_helper.rb' -# Offense count: 15 +# Offense count: 14 Metrics/PerceivedComplexity: Max: 15 @@ -312,7 +312,7 @@ Style/CommentIndentation: - 'app/models/track.rb' - 'spec/features/volunteers_spec.rb' -# Offense count: 8 +# Offense count: 3 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, SingleLineConditionsOnly, IncludeTernaryExpressions. # SupportedStyles: assign_to_condition, assign_inside_condition @@ -327,7 +327,7 @@ Style/ConditionalAssignment: - 'db/migrate/20140610165551_migrate_data_person_to_user.rb' - 'db/migrate/20140820124117_undo_wrong_migration20140801080705_add_users_to_events.rb' -# Offense count: 435 +# Offense count: 436 Style/Documentation: Enabled: false @@ -341,8 +341,8 @@ Style/ElseAlignment: # Cop supports --auto-correct. Style/EmptyCaseCondition: Exclude: - - 'app/helpers/change_description_helper.rb' - 'app/helpers/format_helper.rb' + - 'app/helpers/versions_helper.rb' # Offense count: 1 # Cop supports --auto-correct. @@ -350,7 +350,7 @@ Style/EmptyLineAfterMagicComment: Exclude: - 'spec/models/conference_spec.rb' -# Offense count: 106 +# Offense count: 109 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: empty_lines, no_empty_lines @@ -435,7 +435,7 @@ Style/IfUnlessModifier: - 'app/controllers/api/v1/events_controller.rb' - 'app/controllers/conference_registrations_controller.rb' - 'app/controllers/users/omniauth_callbacks_controller.rb' - - 'app/helpers/format_helper.rb' + - 'app/helpers/application_helper.rb' - 'app/models/commercial.rb' - 'app/models/conference.rb' - 'app/models/ticket_purchase.rb' @@ -556,7 +556,7 @@ Style/MultilineIfModifier: Style/MultilineMethodCallBraceLayout: Enabled: false -# Offense count: 53 +# Offense count: 55 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. # SupportedStyles: aligned, indented, indented_relative_to_receiver @@ -605,7 +605,7 @@ Style/NumericLiteralPrefix: Exclude: - 'spec/controllers/admin/conferences_controller_spec.rb' - 'spec/controllers/conference_registration_controller_spec.rb' - - 'spec/helpers/application_helper_spec.rb' + - 'spec/helpers/date_time_helper_spec.rb' - 'spec/models/conference_spec.rb' - 'spec/models/email_settings_spec.rb' - 'spec/models/registration_spec.rb' @@ -889,14 +889,12 @@ Style/TernaryParentheses: Exclude: - 'app/helpers/format_helper.rb' -# Offense count: 4 +# Offense count: 2 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: final_newline, final_blank_line Style/TrailingBlankLines: Exclude: - - 'app/helpers/change_description_helper.rb' - - 'app/helpers/paths_helper.rb' - 'lib/tasks/event_attatchments.rake' - 'lib/tasks/roles.rake' From 1f0601be1bb0e3d03796792778873156733c510d Mon Sep 17 00:00:00 2001 From: shlok007 Date: Mon, 29 May 2017 17:20:59 +0530 Subject: [PATCH 081/185] Introduce label to group GSoC work together --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ec8376ce..a6115296 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -216,6 +216,8 @@ If you don't already have a `.env` file you can use the `dotenv.example` as a te * 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 02d75ec7294e99464ef6be0a05bdfad7f87032f4 Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Sat, 27 May 2017 11:23:03 +0200 Subject: [PATCH 082/185] Fix registration sorting Sort the 'Actions' column by registration.attended --- app/views/admin/registrations/index.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/registrations/index.html.haml b/app/views/admin/registrations/index.html.haml index 0e7035c0..a51d41fc 100644 --- a/app/views/admin/registrations/index.html.haml +++ b/app/views/admin/registrations/index.html.haml @@ -56,7 +56,7 @@ -if @conference.questions.any? %td = link_to 'Questions','#', class: 'btn btn-success question-btn', 'data-id' => index, 'data-name' => registration.name - %td + %td{ 'data-order' => registration.attended.to_s } = check_box_tag "#{@conference.short_title}_#{registration.id}", registration.id, registration.attended, class: 'switch-checkbox', method: :patch, url: toggle_attendance_admin_conference_registration_path(@conference.short_title, id: registration.id)+"?attended=", From 5bb52f24a5d7ca5525579e830a0e443e68e566b8 Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Sun, 4 Jun 2017 12:54:15 +0300 Subject: [PATCH 083/185] Ignore html_safe in application helper --- .rubocop_todo.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index e0c6dd97..bc17a090 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -183,6 +183,7 @@ Rails/OutputSafety: Exclude: - 'app/helpers/format_helper.rb' - 'app/models/commercial.rb' + - 'app/helpers/application_helper.rb' # Offense count: 10 # Cop supports --auto-correct. From 6cb11ff2f3dc02dd30dbbaadbe4f94d4ad63a123 Mon Sep 17 00:00:00 2001 From: nasia Date: Sat, 3 Jun 2017 13:48:49 +0300 Subject: [PATCH 084/185] Add Style/WordArray at rubocop.yml #1463 --- .rubocop.yml | 4 ++++ .rubocop_todo.yml | 8 -------- app/models/event_user.rb | 2 +- lib/tasks/version.rake | 2 +- spec/helpers/users_helper_spec.rb | 2 +- spec/models/user_spec.rb | 2 +- 6 files changed, 8 insertions(+), 12 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index c333e43a..de234a2a 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -104,6 +104,10 @@ Style/TrailingBlankLines: Style/TrailingWhitespace: Enabled: true +# Check for array literals made up of word-like strings, that are not using the %w() syntax +Style/WordArray: + Enabled: true + # This cop checks for numeric comparisons that can be replaced by a predicate method. Style/ZeroLengthPredicate: Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index bc17a090..a7ea415b 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -928,11 +928,3 @@ Style/UnneededInterpolation: Style/VariableNumber: Exclude: - 'spec/models/ticket_purchase_spec.rb' - -# Offense count: 6 -# Cop supports --auto-correct. -# Configuration parameters: SupportedStyles, WordRegex. -# SupportedStyles: percent, brackets -Style/WordArray: - EnforcedStyle: percent - MinSize: 3 diff --git a/app/models/event_user.rb b/app/models/event_user.rb index 64952a28..58adadad 100644 --- a/app/models/event_user.rb +++ b/app/models/event_user.rb @@ -1,6 +1,6 @@ class EventUser < ActiveRecord::Base # TODO Do we need these roles? - ROLES = [['Speaker', 'speaker'], ['Submitter', 'submitter'], ['Moderator', 'moderator']] + ROLES = [%w[Speaker speaker], %w[Submitter submitter], %w[Moderator moderator]] belongs_to :event belongs_to :user diff --git a/lib/tasks/version.rake b/lib/tasks/version.rake index 084ff181..e4005c15 100644 --- a/lib/tasks/version.rake +++ b/lib/tasks/version.rake @@ -2,7 +2,7 @@ namespace :data do desc 'Sets conference_id in all pre-existing PaperTrail::Version objects' task set_conference_in_versions: :environment do - PaperTrail::Version.where(conference_id: nil, item_type: ['Conference', 'Event']).each do |version| + PaperTrail::Version.where(conference_id: nil, item_type: %w[Conference Event]).each do |version| # All pre-existing versions are either of Conference or Event if version.item_type == 'Conference' version.update_attributes(conference_id: version.item_id) diff --git a/spec/helpers/users_helper_spec.rb b/spec/helpers/users_helper_spec.rb index dfc337e6..e0c2d3fd 100644 --- a/spec/helpers/users_helper_spec.rb +++ b/spec/helpers/users_helper_spec.rb @@ -4,7 +4,7 @@ describe UsersHelper, type: :helper do describe 'show_roles' do it 'formats the hash passed' do - roles = { 'organizer' => ['oSC16', 'oSC15'], 'cfp' => ['oSC16'] } + roles = { 'organizer' => %w[oSC16 oSC15], 'cfp' => ['oSC16'] } expect(show_roles(roles)).to eq 'Organizer (oSC16, oSC15), Cfp (oSC16)' end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index d0517212..e742b993 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -282,7 +282,7 @@ describe User do it 'returns hash of role and conference' do expected_hash = { - 'organizer' => ['oSC16', 'oSC15'], + 'organizer' => %w[oSC16 oSC15], 'cfp' => ['oSC16'] } From 7a7fcced487de914c9bd2bfc9e4e51839413aa8e Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Tue, 6 Jun 2017 19:03:23 +0300 Subject: [PATCH 085/185] Replace .today with .current in program spec The cfp_open? method uses Date.current, so it should also be tested with Date.current and not Date.today Also, build was replaced with create to fix a false negative This is a partial fix for #1522 --- spec/models/program_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/models/program_spec.rb b/spec/models/program_spec.rb index ac720def..a2106791 100644 --- a/spec/models/program_spec.rb +++ b/spec/models/program_spec.rb @@ -141,7 +141,7 @@ describe Program do describe '#cfp_open?' do describe 'returns true' do it 'when there is an open Call for Papers for the conference' do - create(:cfp, start_date: Date.today - 2, end_date: Date.today, program_id: program.id) + create(:cfp, start_date: Date.current - 2, end_date: Date.current, program_id: program.id) expect(program.cfp_open?).to be true end end @@ -152,7 +152,7 @@ describe Program do end it 'when the Call for Papers period is over' do - build(:cfp, start_date: Date.today - 2, end_date: Date.today - 1, program_id: program.id) + create(:cfp, start_date: Date.current - 2, end_date: Date.current - 1, program_id: program.id) expect(program.cfp_open?).to be false end end From 5acb4a93392c613f3a43bbec04b5aae2e849d957 Mon Sep 17 00:00:00 2001 From: mdeniz Date: Fri, 9 Jun 2017 14:41:44 +0200 Subject: [PATCH 086/185] Split in 2 jobs Travis build --- .travis.yml | 9 ++++++--- travis_script.sh | 27 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) create mode 100755 travis_script.sh diff --git a/.travis.yml b/.travis.yml index 0be912e1..6c83258b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,9 @@ before_script: - mysql -u root -e 'create database osem_test;' - RAILS_ENV=test bundle exec rake db:migrate --trace script: - - 'bundle exec rubocop -Dc .rubocop.yml' - - 'bundle exec haml-lint app/views' - - 'bundle exec rspec --color --format documentation' + - "./travis_script.sh $TEST_SUITE" +env: + - TEST_SUITE=rspec + - TEST_SUITE=linters +matrix: + fast_finish: true diff --git a/travis_script.sh b/travis_script.sh new file mode 100755 index 00000000..77ca2329 --- /dev/null +++ b/travis_script.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# This script runs the test suites for the CI build + +# Be verbose and fail script on the first error +set -xe + +# By default: all test runs +if [ -z $1 ]; then + TEST_SUITE="all" +else + TEST_SUITE="$1" +fi + +case $TEST_SUITE in + linters) + bundle exec rubocop -Dc .rubocop.yml + bundle exec haml-lint app/views + ;; + rspec) + bundle exec rspec --color --format documentation + ;; + *) + bundle exec rubocop -Dc .rubocop.yml + bundle exec haml-lint app/views + bundle exec rspec --color --format documentation + ;; +esac From ebe1ca374da3366e29efe1e63a65d618cdfe9fe5 Mon Sep 17 00:00:00 2001 From: mdeniz Date: Fri, 9 Jun 2017 14:41:51 +0200 Subject: [PATCH 087/185] Fix the Travis failure in the last PR about axlsx dependencies --- Gemfile | 3 ++- Gemfile.lock | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 497c56b1..76c49ce3 100644 --- a/Gemfile +++ b/Gemfile @@ -128,6 +128,7 @@ gem 'country_select' gem 'prawn_rails' # to render XLS spreadsheets +gem 'axlsx', git: 'https://github.com/randym/axlsx.git' gem 'axlsx_rails' # as error catcher @@ -178,7 +179,7 @@ gem 'cloudinary' # for setting app configuration in the environment gem 'dotenv-rails' -# For countable.js +# For countable.js gem "countable-rails", "~> 0.0.1" # Both are not in a group as we use it also for rake data:demo diff --git a/Gemfile.lock b/Gemfile.lock index 90ae82f0..e1c8218f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,13 @@ +GIT + remote: https://github.com/randym/axlsx.git + revision: c8ac844572b25fda358cc01d2104720c4c42f450 + specs: + axlsx (2.1.0.pre) + htmlentities (~> 4.3.4) + mimemagic (~> 0.3) + nokogiri (>= 1.6.6) + rubyzip (>= 1.2.1) + GEM remote: https://rubygems.org/ remote: https://rails-assets.org/ @@ -65,10 +75,6 @@ GEM awesome_nested_set (3.0.0.rc.5) activerecord (>= 4.0.0, < 5) aws_cf_signer (0.1.3) - axlsx (2.0.1) - htmlentities (~> 4.3.1) - nokogiri (>= 1.4.1) - rubyzip (~> 1.2.1) axlsx_rails (0.2.0) axlsx (>= 2.0.1) rails (>= 3.1) @@ -262,6 +268,7 @@ GEM mime-types (>= 1.16, < 3) method_source (0.8.2) mime-types (2.99.1) + mimemagic (0.3.2) mina (0.3.8) open4 (~> 1.3.4) rake @@ -551,6 +558,7 @@ DEPENDENCIES ahoy_matey autoprefixer-rails awesome_nested_set (~> 3.0.0.rc.5) + axlsx! axlsx_rails bootstrap-sass (~> 3.3.4.1) bootstrap-switch-rails (~> 3.0.0) From 0d01ed08b0351ef7839c7e8ef53d03ac24ed7c72 Mon Sep 17 00:00:00 2001 From: divyanshumehta Date: Mon, 29 May 2017 09:32:57 +0530 Subject: [PATCH 088/185] Added Style/SpaceInsideBrackets Rubocop cop --- .rubocop.yml | 4 ++++ .rubocop_todo.yml | 7 ------- app/models/conference.rb | 2 +- app/models/user.rb | 4 ++-- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index de234a2a..9f7f0d00 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -88,6 +88,10 @@ Style/RedundantSelf: Style/SpaceAroundOperators: Enabled: true +# Checks for spaces inside square brackets. +Style/SpaceInsideBrackets: + Enabled: true + # Use single quotes unless there's string interpolation Style/StringLiterals: Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index a7ea415b..37164318 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -811,13 +811,6 @@ Style/SpaceInsideBlockBraces: - 'spec/models/ability_spec.rb' - 'spec/models/user_spec.rb' -# Offense count: 5 -# Cop supports --auto-correct. -Style/SpaceInsideBrackets: - Exclude: - - 'app/models/conference.rb' - - 'app/models/user.rb' - # Offense count: 25 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SupportedStylesForEmptyBraces. diff --git a/app/models/conference.rb b/app/models/conference.rb index 1c4ccc73..79b38be2 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -803,7 +803,7 @@ class Conference < ActiveRecord::Base hash[key] = 0 end end - Hash[ hash.sort ] + Hash[hash.sort] end ## diff --git a/app/models/user.rb b/app/models/user.rb index a63d721e..4be77fe8 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -26,11 +26,11 @@ class User < ActiveRecord::Base devise_modules = [] if ENV['OSEM_ICHAIN_ENABLED'] == 'true' - devise_modules += [ :ichain_authenticatable, :ichain_registerable, :omniauthable, omniauth_providers: [] ] + devise_modules += [:ichain_authenticatable, :ichain_registerable, :omniauthable, omniauth_providers: []] else devise_modules += [:database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable, - :omniauthable, omniauth_providers: [:suse, :google, :facebook, :github] ] + :omniauthable, omniauth_providers: [:suse, :google, :facebook, :github]] end devise(*devise_modules) From 1223fef87c0467ce58fab121832852e77217f0eb Mon Sep 17 00:00:00 2001 From: divyanshumehta Date: Mon, 29 May 2017 15:02:14 +0530 Subject: [PATCH 089/185] Use of rubocop compliant unescaping methods in application_helper.rb --- app/helpers/application_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index b3081f9b..e0b3b85b 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -147,7 +147,7 @@ module ApplicationHelper end def speaker_links(event) - event.speakers.map{ |speaker| link_to speaker.name, admin_user_path(speaker) }.join(', ').html_safe + safe_join(event.speakers.map{ |speaker| link_to speaker.name, admin_user_path(speaker) }, ',') end def speaker_selector_input(form) From 071ed50acb3a6f34253b8561e167ddce97794877 Mon Sep 17 00:00:00 2001 From: selini Date: Tue, 21 Mar 2017 21:08:53 +0200 Subject: [PATCH 090/185] Hide recent Registrations/Submissions when conference is over --- app/helpers/application_helper.rb | 53 +++++++++++++++++++ .../admin/conferences/_todo_list.html.haml | 18 +++---- app/views/admin/conferences/show.html.haml | 4 +- 3 files changed, 64 insertions(+), 11 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index b3081f9b..d1d64fbd 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -33,6 +33,50 @@ module ApplicationHelper result end + # Returns time with conference timezone + def time_with_timezone(time) + time.strftime('%F %R') + ' ' + @conference.timezone.to_s + end + + ## + # Checks if the voting has already started, or if it has already ended + # + def voting_open_or_close(program) + return if program.voting_period? + if program.voting_start_date > Time.current + return 'Voting period has not started yet!' + else # voting_end_date > Date.today because voting_start_date < voting_end_date + return 'Voting period is over!' + end + end + + ## + # Gets an EventType object, and returns its length in timestamp format (HH:MM) + # ====Gets + # * +Integer+ -> 30 + # ====Returns + # * +String+ -> "00:30" + def length_timestamp(length) + [length / 60, length % 60].map { |t| t.to_s.rjust(2, '0') }.join(':') + end + + ## + # Gets a datetime object + # ====Returns + # * +String+ -> formated datetime object + def format_datetime(obj) + return unless obj + obj.strftime('%Y-%m-%d %H:%M') + end + + ## + # ====Returns + # * +String+ -> number of registrations / max allowed registrations + def registered_text(event) + return "Registered: #{event.registrations.count}/#{event.max_attendees}" if event.max_attendees + "Registered: #{event.registrations.count}" + end + # Set resource_name for devise so that we can call the devise help links (views/devise/shared/_links) from anywhere (eg sign_up form in proposals#new) def resource_name :user @@ -168,4 +212,13 @@ module ApplicationHelper new_user_session_path end end + + ## + # ====Gets + # a conference object + # ==== Returns + # class hidden if conference is over + def hidden_if_conference_over(conference) + 'hidden' if Date.today > conference.end_date + end end diff --git a/app/views/admin/conferences/_todo_list.html.haml b/app/views/admin/conferences/_todo_list.html.haml index cd98391d..63f4e3aa 100644 --- a/app/views/admin/conferences/_todo_list.html.haml +++ b/app/views/admin/conferences/_todo_list.html.haml @@ -1,12 +1,12 @@ .list-group - %li.list-group-item + %li{ 'class' => "list-group-item #{hidden_if_conference_over(conference)}" } %h4 Conference progress .progress .progress-bar{ 'role' => 'progressbar', 'aria-valuenow' => "#{conference_progress['process']}", 'aria-valuemin' => '0', 'aria-valuemax' => '100', 'style' => "width: #{conference_progress['process']}%;" } = conference_progress['process'] + '%' - %li{ 'class' => "list-group-item #{class_for_todo(conference_progress['registration'])}" } + %li{ 'class' => "list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['registration'])}" } %span{ 'class' => icon_for_todo(conference_progress['registration']) } - if can? :update, @conference - if conference.registration_period @@ -15,13 +15,13 @@ = link_to 'Set up registration period', new_admin_conference_registration_period_path(conference_progress['short_title']) - else Set up registration period - %li{ 'class' => "list-group-item #{class_for_todo(conference_progress['cfp'])}" } + %li{ 'class' => "list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['cfp'])}" } %span{ 'class' => icon_for_todo(conference_progress['cfp']) } - if can? :update, Cfp.new(program_id: @program.id) = link_to 'Set up call for papers', admin_conference_program_cfp_path(conference_progress['short_title']) - else Set up call for papers - %li{'class'=>"list-group-item #{class_for_todo(conference_progress['venue'])}"} + %li{'class'=>"list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['venue'])}"} %span{'class'=>icon_for_todo(conference_progress['venue'])} - if can? :update, Venue.new(conference: @conference) - @conference.reload @@ -32,31 +32,31 @@ - else - @conference.reload Add venue - %li{ 'class' => "list-group-item #{class_for_todo(conference_progress['rooms'])}" } + %li{ 'class' => "list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['rooms'])}" } %span{ 'class' => icon_for_todo(conference_progress['rooms']) } - if @conference.venue && (can? :update, @conference.venue.rooms.build) = link_to 'Add rooms', admin_conference_venue_rooms_path(conference_progress['short_title']) - else Add rooms - %li{ 'class' => "list-group-item #{class_for_todo(conference_progress['tracks'])}" } + %li{ 'class' => "list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['tracks'])}" } %span{ 'class' => icon_for_todo(conference_progress['tracks']) } - if can? :update, @conference.program.tracks.build = link_to 'Add tracks', admin_conference_program_tracks_path(conference_progress['short_title']) - else Add tracks - %li{ 'class' => "list-group-item #{class_for_todo(conference_progress['event_types'])}" } + %li{ 'class' => "list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['event_types'])}" } %span{ 'class' => icon_for_todo(conference_progress['event_types']) } - if can? :update, @conference.program.event_types.build = link_to 'Add event types', admin_conference_program_event_types_path(conference_progress['short_title']) - else Add event types - %li{ 'class' => "list-group-item #{class_for_todo(conference_progress['difficulty_levels'])}" } + %li{ 'class' => "list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['difficulty_levels'])}" } %span{ 'class' => icon_for_todo(conference_progress['difficulty_levels']) } - if can? :update, @conference.program.difficulty_levels.build = link_to 'Add difficulty levels', admin_conference_program_difficulty_levels_path(conference_progress['short_title']) - else Add difficulty levels - %li{ class: "list-group-item #{class_for_todo(conference_progress['splashpage'])}" } + %li{ class: "list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['splashpage'])}" } %span{ 'class' => icon_for_todo(conference_progress['splashpage']) } - if can? :update, @conference = link_to 'Set up a Splashpage', admin_conference_splashpage_path(conference_progress['short_title']) diff --git a/app/views/admin/conferences/show.html.haml b/app/views/admin/conferences/show.html.haml index dec58da8..39d48f54 100644 --- a/app/views/admin/conferences/show.html.haml +++ b/app/views/admin/conferences/show.html.haml @@ -101,11 +101,11 @@ .row .col-md-8 %ul.nav.nav-tabs#recentTable - %li.active + %li{ 'class' => "active #{hidden_if_conference_over(@conference)}" } %a{ href: '#recent_reg', 'data-toggle' => 'tab' } %span.fa.fa-user Recent Registrations - %li + %li{ 'class' => "#{hidden_if_conference_over(@conference)}" } %a{ href: '#recent_submissions', 'data-toggle' => 'tab' } %span.fa.fa-file-text Recent Submissions From 9ff3601453e72a2e041b52359283152b7932291b Mon Sep 17 00:00:00 2001 From: selini Date: Sun, 11 Jun 2017 18:15:10 +0300 Subject: [PATCH 091/185] remove unnecessary functions --- app/helpers/application_helper.rb | 39 ------------------------------- 1 file changed, 39 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index d1d64fbd..0efe5321 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -38,45 +38,6 @@ module ApplicationHelper time.strftime('%F %R') + ' ' + @conference.timezone.to_s end - ## - # Checks if the voting has already started, or if it has already ended - # - def voting_open_or_close(program) - return if program.voting_period? - if program.voting_start_date > Time.current - return 'Voting period has not started yet!' - else # voting_end_date > Date.today because voting_start_date < voting_end_date - return 'Voting period is over!' - end - end - - ## - # Gets an EventType object, and returns its length in timestamp format (HH:MM) - # ====Gets - # * +Integer+ -> 30 - # ====Returns - # * +String+ -> "00:30" - def length_timestamp(length) - [length / 60, length % 60].map { |t| t.to_s.rjust(2, '0') }.join(':') - end - - ## - # Gets a datetime object - # ====Returns - # * +String+ -> formated datetime object - def format_datetime(obj) - return unless obj - obj.strftime('%Y-%m-%d %H:%M') - end - - ## - # ====Returns - # * +String+ -> number of registrations / max allowed registrations - def registered_text(event) - return "Registered: #{event.registrations.count}/#{event.max_attendees}" if event.max_attendees - "Registered: #{event.registrations.count}" - end - # Set resource_name for devise so that we can call the devise help links (views/devise/shared/_links) from anywhere (eg sign_up form in proposals#new) def resource_name :user From c2184c1c4fe4b355810032e55164c6be665d2d45 Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Wed, 19 Apr 2017 16:47:59 +0300 Subject: [PATCH 092/185] Add 'week' column to TicketPurchases --- app/models/ticket_purchase.rb | 9 +++++++++ ...20170419132148_add_week_to_ticket_purchases.rb | 15 +++++++++++++++ db/schema.rb | 3 ++- 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20170419132148_add_week_to_ticket_purchases.rb diff --git a/app/models/ticket_purchase.rb b/app/models/ticket_purchase.rb index 07fb7e16..d1c370c4 100644 --- a/app/models/ticket_purchase.rb +++ b/app/models/ticket_purchase.rb @@ -18,6 +18,8 @@ class TicketPurchase < ActiveRecord::Base scope :by_conference, ->(conference) { where(conference_id: conference.id) } scope :by_user, ->(user) { where(user_id: user.id) } + after_create :set_week + def self.purchase(conference, user, purchases) errors = [] ActiveRecord::Base.transaction do @@ -59,3 +61,10 @@ class TicketPurchase < ActiveRecord::Base purchase end end + +private + +def set_week + self.week = created_at.strftime('%W') + save! +end diff --git a/db/migrate/20170419132148_add_week_to_ticket_purchases.rb b/db/migrate/20170419132148_add_week_to_ticket_purchases.rb new file mode 100644 index 00000000..0862eb16 --- /dev/null +++ b/db/migrate/20170419132148_add_week_to_ticket_purchases.rb @@ -0,0 +1,15 @@ +class AddWeekToTicketPurchases < ActiveRecord::Migration + class TmpTicketPurchase < ActiveRecord::Base + self.table_name = 'ticket_purchases' + end + + def change + add_column :ticket_purchases, :week, :integer + + TmpTicketPurchase.reset_column_information + TmpTicketPurchase.find_each do |purchase| + purchase.week = purchase.created_at ? purchase.created_at.strftime('%W') : 0 + purchase.save! + end + end +end diff --git a/db/schema.rb b/db/schema.rb index ab95b4dc..5d74950a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170302145716) do +ActiveRecord::Schema.define(version: 20170419132148) do create_table "ahoy_events", force: :cascade do |t| t.uuid "visit_id", limit: 16 @@ -447,6 +447,7 @@ ActiveRecord::Schema.define(version: 20170302145716) do t.integer "quantity", default: 1 t.integer "user_id" t.integer "payment_id" + t.integer "week" end create_table "tickets", force: :cascade do |t| From 41503bb7a044ce2cc1c8285b8f846a3b1a857131 Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Thu, 20 Apr 2017 09:47:19 +0300 Subject: [PATCH 093/185] Compute ticket statistics And exclude admin/ConferencesController from rubocop_todo.yml --- .rubocop_todo.yml | 2 + .../admin/conferences_controller.rb | 25 +++++ app/controllers/admin/tickets_controller.rb | 2 + app/models/conference.rb | 93 +++++++++++++++++++ 4 files changed, 122 insertions(+) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index a7ea415b..e70a8709 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -60,6 +60,8 @@ Lint/UnusedBlockArgument: # Offense count: 108 Metrics/AbcSize: Max: 75 + Exclude: + - 'app/controllers/admin/conferences_controller.rb' # Offense count: 202 # Configuration parameters: CountComments, ExcludedMethods. diff --git a/app/controllers/admin/conferences_controller.rb b/app/controllers/admin/conferences_controller.rb index 50360a64..f9e1177d 100644 --- a/app/controllers/admin/conferences_controller.rb +++ b/app/controllers/admin/conferences_controller.rb @@ -37,6 +37,9 @@ module Admin @registrations = {} @registration_weeks = [0] + @tickets = {} + @ticket_weeks = [0] + @conferences.each do |c| # Event submissions over time chart @submissions[c.short_title] = c.get_submissions_per_week @@ -45,6 +48,10 @@ module Admin # Conference registrations over time chart @registrations[c.short_title] = c.get_registrations_per_week @registration_weeks.push(@registrations[c.short_title].length) + + # Tickets sold over time chart + @tickets[c.short_title] = c.get_tickets_sold_per_week + @ticket_weeks.push(@tickets[c.short_title].length) end @cfp_weeks = @cfp_weeks.max @@ -55,6 +62,10 @@ module Admin @registrations = normalize_array_length(@registrations, @registration_weeks) @registration_weeks = @registration_weeks > 0 ? (1..@registration_weeks).to_a : 1 + @ticket_weeks = @ticket_weeks.max + @tickets = normalize_array_length(@tickets, @ticket_weeks) + @ticket_weeks = @ticket_weeks > 0 ? (1..@ticket_weeks).to_a : 1 + @event_distribution = Conference.event_distribution @user_distribution = Conference.user_distribution end @@ -133,6 +144,20 @@ module Admin @submissions_data = @submissions_data.except('Weeks') end + @tickets_data = {} + @tickets_data = @conference.get_tickets_data + @ticket_weeks = 0 + if @tickets_data['Weeks'] + @ticket_weeks = @tickets_data['Weeks'] + @tickets_data = @tickets_data.except('Weeks') + end + + # Set line color using a hash function + @tickets = [] + @tickets_data.keys.each do |title| + @tickets.append(short_title: title, color: "\##{Digest::MD5.hexdigest(title)[0..5]}") + end + # Doughnut charts @event_type_distribution = @conference.event_type_distribution @event_type_distribution_confirmed = @conference.event_type_distribution(:confirmed) diff --git a/app/controllers/admin/tickets_controller.rb b/app/controllers/admin/tickets_controller.rb index 9042297b..c7161409 100644 --- a/app/controllers/admin/tickets_controller.rb +++ b/app/controllers/admin/tickets_controller.rb @@ -5,6 +5,8 @@ module Admin def index authorize! :update, Ticket.new(conference_id: @conference.id) + @tickets_sold_distribution = @conference.tickets_sold_distribution + @tickets_turnover_distribution = @conference.tickets_turnover_distribution end def new diff --git a/app/models/conference.rb b/app/models/conference.rb index 1c4ccc73..2f623a4c 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -184,6 +184,59 @@ class Conference < ActiveRecord::Base result end + ## + # Returns an array with the summarized ticket sales per week. + # + # ====Returns + # * +Array+ -> e.g. [0, 3, 3, 5] -> first week 0, second week 3 tickets sold + def get_tickets_sold_per_week + result = [] + + if tickets && ticket_purchases && registration_period + tickets_sold = ticket_purchases.paid.group(:week).sum(:quantity) + start_week = get_registration_start_week + weeks = registration_weeks + result = calculate_items_per_week(start_week, weeks, tickets_sold) + end + result + end + + ## + # Returns an hash with ticket sales by ticket title + # per week. + # + # ====Returns + # * +Array+ -> e.g. 'Free Access' => [0, 3, 3, 5] -> first week 0 tickets sold, second week 3 tickets sold. + def get_tickets_data + result = {} + if tickets && ticket_purchases && registration_period + tickets_per_ticket_id_and_week = ticket_purchases.paid.group(:ticket_id, :week).sum(:quantity) + + start_week = get_registration_start_week + weeks = registration_weeks + + tickets_by_id_per_week = {} + + tickets.each do |ticket| + tickets_by_id_per_week[ticket.id] = {} + (start_week...(start_week + weeks)).each do |week| + tickets_by_id_per_week[ticket.id][week] = 0 + end + end + + tickets_per_ticket_id_and_week.each do |ticket_week, value| + tickets_by_id_per_week[ticket_week[0]][ticket_week[1]] = value + end + + tickets_by_id_per_week.each do |ticket, values| + result[Ticket.find(ticket).title] = pad_array_left_not_kumulative(start_week, values) + end + + result['Weeks'] = weeks > 0 ? (1..weeks).to_a : 0 + end + result + end + ## # Calculates how many weeks the registration is. # @@ -396,6 +449,46 @@ class Conference < ActiveRecord::Base calculate_user_distribution_hash(active_user, unconfirmed_user, dead_user) end + ## + # Returns a hash with per ticket sales => { "Title" => { value: number of tickets sold, + # color: generated from the title using a hash function }, ...} + # + # ====Returns + # * +hash+ -> hash + def tickets_sold_distribution + result = {} + + if tickets && ticket_purchases + tickets.each do |ticket| + result[ticket.title] = { + 'value' => ApplicationController.helpers.humanized_money(ticket.tickets_sold).delete(',').to_i, + 'color' => "\##{Digest::MD5.hexdigest(ticket.title)[0..5]}" + } + end + end + result + end + + ## + # Returns a hash with per ticket turnover => { "Title" => { value: ticket turnover, + # color: generated from the title using a hash function }, ...} + # + # ====Returns + # * +hash+ -> hash + def tickets_turnover_distribution + result = {} + + if tickets && ticket_purchases + tickets.each do |ticket| + result[ticket.title] = { + 'value' => ApplicationController.helpers.humanized_money(ticket.tickets_turnover).delete(',').to_i, + 'color' => "\##{Digest::MD5.hexdigest(ticket.title)[0..5]}" + } + end + end + result + end + ## # Calculates the overall program minutes # From 8cd3326520fb4c133e0ad30e0717fffbc0acfe48 Mon Sep 17 00:00:00 2001 From: nasia Date: Tue, 25 Apr 2017 18:22:39 +0300 Subject: [PATCH 094/185] Add charts about sold tickets --- app/views/admin/conferences/index.html.haml | 11 +++++++++++ app/views/admin/conferences/show.html.haml | 11 +++++++++++ app/views/admin/tickets/index.html.haml | 7 ++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/app/views/admin/conferences/index.html.haml b/app/views/admin/conferences/index.html.haml index 24c2d0f2..02208aeb 100644 --- a/app/views/admin/conferences/index.html.haml +++ b/app/views/admin/conferences/index.html.haml @@ -60,6 +60,17 @@ unit: 'weeks' } .col-md-4 = render partial: 'doughnut_chart', locals: { title: 'User', data: @user_distribution } +.row#tickets + .col-md-8 + = render partial: 'line_chart', locals: { title: 'Tickets sold over time', + name: 'tickets', + conferences: @conferences, + active_conferences: @active_conferences, + deactive_conferences: @deactive_conferences, + y: @tickets, + x: @ticket_weeks, + unit: 'weeks' } +%br .row .col-md-8 %ul.nav.nav-tabs#recentTable diff --git a/app/views/admin/conferences/show.html.haml b/app/views/admin/conferences/show.html.haml index 39d48f54..b425dfca 100644 --- a/app/views/admin/conferences/show.html.haml +++ b/app/views/admin/conferences/show.html.haml @@ -69,6 +69,17 @@ .col-md-4 = render partial: 'todo_list', locals: { conference_progress: @conference_progress, conference: @conference } + .row#tickets + .col-md-8 + =render partial: 'line_chart', locals: { title: 'Tickets sold over time', + name: 'tickets', + conferences: @tickets, + active_conferences: @tickets, + deactive_conferences: [], + y: @tickets_data, + x: @ticket_weeks, + unit: 'weeks' } +%br .row .col-md-12#doughnut %ul.nav.nav-tabs#doughnut_tabs diff --git a/app/views/admin/tickets/index.html.haml b/app/views/admin/tickets/index.html.haml index 7fa3e37c..6a0c7dca 100644 --- a/app/views/admin/tickets/index.html.haml +++ b/app/views/admin/tickets/index.html.haml @@ -4,6 +4,12 @@ %h1 Tickets %p.text-muted Tickets to get during registration +.row + .col-md-4 + = render partial: 'admin/conferences/doughnut_chart', locals: { title: 'Tickets sold', data: @tickets_sold_distribution,} + .col-md-4 + = render partial: 'admin/conferences/doughnut_chart', locals: { title: 'Tickets turnover', data: @tickets_turnover_distribution } +%br - if @conference.tickets.any? .row .col-md-12 @@ -36,4 +42,3 @@ .row .col-md-12 = link_to 'Add Ticket', new_admin_conference_ticket_path, class: 'btn btn-success pull-right' - From ce9d2b3c5b790d327e69e8177bd5356da7c0b000 Mon Sep 17 00:00:00 2001 From: shlok007 Date: Mon, 12 Jun 2017 18:37:50 +0530 Subject: [PATCH 095/185] fixes failing haml-lint in admin/conference/show --- app/views/admin/conferences/show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/conferences/show.html.haml b/app/views/admin/conferences/show.html.haml index b425dfca..cddae4c2 100644 --- a/app/views/admin/conferences/show.html.haml +++ b/app/views/admin/conferences/show.html.haml @@ -71,7 +71,7 @@ conference: @conference } .row#tickets .col-md-8 - =render partial: 'line_chart', locals: { title: 'Tickets sold over time', + = render partial: 'line_chart', locals: { title: 'Tickets sold over time', name: 'tickets', conferences: @tickets, active_conferences: @tickets, From 8edf896d86593bc888b9d7b39a031544bdb3eb04 Mon Sep 17 00:00:00 2001 From: shlok007 Date: Wed, 31 May 2017 18:42:52 +0530 Subject: [PATCH 096/185] introduce organizations --- .../admin/organizations_controller.rb | 19 ++++ app/controllers/organizations_controller.rb | 50 +++++++++ app/models/conference.rb | 5 +- app/models/organization.rb | 7 ++ app/views/admin/organizations/_form.html.haml | 13 +++ app/views/admin/organizations/index.html.haml | 31 ++++++ .../layouts/_admin_sidebar_index.html.haml | 4 + app/views/layouts/_user_menu.html.haml | 4 + app/views/organizations/_form.html.haml | 13 +++ app/views/organizations/edit.html.haml | 4 + app/views/organizations/index.html.haml | 17 +++ app/views/organizations/new.html.haml | 4 + config/routes.rb | 3 +- .../20170529215453_create_organizations.rb | 9 ++ ...094817_add_organizaton_id_to_conference.rb | 5 + db/schema.rb | 9 +- .../admin/organizations_controller_spec.rb | 14 +++ .../organizations_controller_spec.rb | 104 ++++++++++++++++++ spec/factories/conferences.rb | 2 +- spec/factories/organizations.rb | 13 +++ spec/models/organization_spec.rb | 19 ++++ 21 files changed, 345 insertions(+), 4 deletions(-) create mode 100644 app/controllers/admin/organizations_controller.rb create mode 100644 app/controllers/organizations_controller.rb create mode 100644 app/models/organization.rb create mode 100644 app/views/admin/organizations/_form.html.haml create mode 100644 app/views/admin/organizations/index.html.haml create mode 100644 app/views/organizations/_form.html.haml create mode 100644 app/views/organizations/edit.html.haml create mode 100644 app/views/organizations/index.html.haml create mode 100644 app/views/organizations/new.html.haml create mode 100644 db/migrate/20170529215453_create_organizations.rb create mode 100644 db/migrate/20170531094817_add_organizaton_id_to_conference.rb create mode 100644 spec/controllers/admin/organizations_controller_spec.rb create mode 100644 spec/controllers/organizations_controller_spec.rb create mode 100644 spec/factories/organizations.rb create mode 100644 spec/models/organization_spec.rb diff --git a/app/controllers/admin/organizations_controller.rb b/app/controllers/admin/organizations_controller.rb new file mode 100644 index 00000000..1dc6bcd5 --- /dev/null +++ b/app/controllers/admin/organizations_controller.rb @@ -0,0 +1,19 @@ +module Admin + class OrganizationsController < Admin::BaseController + load_and_authorize_resource :organization + + def index + @organizations = Organization.all + end + + def destroy + if @organization.destroy + redirect_to admin_organizations_path, + notice: 'Organization successfully destroyed' + else + redirect_to admin_organizations_path, + error: 'Organization cannot be destroyed' + end + end + end +end diff --git a/app/controllers/organizations_controller.rb b/app/controllers/organizations_controller.rb new file mode 100644 index 00000000..58910526 --- /dev/null +++ b/app/controllers/organizations_controller.rb @@ -0,0 +1,50 @@ +class OrganizationsController < ApplicationController + load_and_authorize_resource :organization + + def index + @organizations = Organization.all + end + + def create + @organization = Organization.new(organization_params) + if @organization.save + redirect_to organizations_path, + notice: 'Organization successfully created' + else + redirect_to new_organization_path, + error: @organization.errors.full_messages.join(', ') + end + end + + def new + @organization = Organization.new + end + + def edit; end + + def update + if @organization.update_attributes(organization_params) + redirect_to organizations_path, + notice: 'Organization successfully updated' + else + redirect_to edit_organization_path(@organization), + error: @organization.errors.full_messages.join(', ') + end + end + + def destroy + if @organization.destroy + redirect_to organizations_path, + notice: 'Organization successfully destroyed' + else + redirect_to organizations_path, + error: 'Organization cannot be destroyed' + end + end + + private + + def organization_params + params.require(:organization).permit(:name, :description, :picture) + end +end diff --git a/app/models/conference.rb b/app/models/conference.rb index 2f623a4c..0f09d694 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -7,6 +7,8 @@ class Conference < ActiveRecord::Base default_scope { order('start_date DESC') } + belongs_to :organization + has_paper_trail ignore: %i(updated_at guid revision events_per_week), meta: { conference_id: :id } has_and_belongs_to_many :questions @@ -53,7 +55,8 @@ class Conference < ActiveRecord::Base :start_date, :end_date, :start_hour, - :end_hour, presence: true + :end_hour, + :organization, presence: true validates :short_title, uniqueness: true validates :short_title, format: { with: /\A[a-zA-Z0-9_-]*\z/ } diff --git a/app/models/organization.rb b/app/models/organization.rb new file mode 100644 index 00000000..60a83fef --- /dev/null +++ b/app/models/organization.rb @@ -0,0 +1,7 @@ +class Organization < ActiveRecord::Base + has_many :conferences, dependent: :destroy + + validates :name, presence: true + + mount_uploader :picture, PictureUploader, mount_on: :picture +end diff --git a/app/views/admin/organizations/_form.html.haml b/app/views/admin/organizations/_form.html.haml new file mode 100644 index 00000000..c41f0cff --- /dev/null +++ b/app/views/admin/organizations/_form.html.haml @@ -0,0 +1,13 @@ += semantic_form_for(@organization) do |f| + = f.inputs name: 'Organization details' do + = f.input :name, as: :string, required: true + = f.input :description, input_html: { rows: 5 }, placeholder: 'Decribe about your organization..' + = image_tag f.object.picture.thumb.url if f.object.picture? + - if @organization.picture + = image_tag(@organization.picture.thumb.url, width: '20%') + = f.input :picture + %p.text-right + - if @organization.new_record? + = f.submit 'Create Organization', class: 'btn btn-success' + - else + = f.submit 'Update Organization', class: 'btn btn-success' \ No newline at end of file diff --git a/app/views/admin/organizations/index.html.haml b/app/views/admin/organizations/index.html.haml new file mode 100644 index 00000000..0a751460 --- /dev/null +++ b/app/views/admin/organizations/index.html.haml @@ -0,0 +1,31 @@ +.row + .col-md-12 + .page-header + %h1 Organizations + .btn-group.pull-right + = link_to 'Add Organization', new_admin_organization_path, class: 'btn btn-success pull-right' + %p.text-muted + Manage organizations in OSEM + .row + .col-md-12 + %table.table.table-hover.datatable + %thead + %th Name + %th Upcoming Conferences + %th Past Conferences + %th Actions + %tbody + - @organizations.each do |organization| + %tr + %td + = organization.name + %td + = organization.conferences.count + %td + = organization.conferences.count + %td + .btn-group + = link_to 'Edit', edit_organization_path(organization), + method: :get, class: 'btn btn-primary' + = link_to 'Delete', admin_organization_path(organization), + method: :delete, class: 'btn btn-danger' diff --git a/app/views/layouts/_admin_sidebar_index.html.haml b/app/views/layouts/_admin_sidebar_index.html.haml index 4ae56dce..f1cf8b75 100644 --- a/app/views/layouts/_admin_sidebar_index.html.haml +++ b/app/views/layouts/_admin_sidebar_index.html.haml @@ -32,3 +32,7 @@ = link_to(admin_revision_history_path) do %span.fa.fa-history Revision History + %li + = link_to(admin_organizations_path) do + %span.fa.fa-group + Organizations diff --git a/app/views/layouts/_user_menu.html.haml b/app/views/layouts/_user_menu.html.haml index 3fb32273..14d32fed 100644 --- a/app/views/layouts/_user_menu.html.haml +++ b/app/views/layouts/_user_menu.html.haml @@ -49,3 +49,7 @@ = link_to(admin_revision_history_path) do %span.fa.fa-history Revision History + %li + = link_to(admin_organizations_path) do + %span.fa.fa-group + Organizations diff --git a/app/views/organizations/_form.html.haml b/app/views/organizations/_form.html.haml new file mode 100644 index 00000000..c41f0cff --- /dev/null +++ b/app/views/organizations/_form.html.haml @@ -0,0 +1,13 @@ += semantic_form_for(@organization) do |f| + = f.inputs name: 'Organization details' do + = f.input :name, as: :string, required: true + = f.input :description, input_html: { rows: 5 }, placeholder: 'Decribe about your organization..' + = image_tag f.object.picture.thumb.url if f.object.picture? + - if @organization.picture + = image_tag(@organization.picture.thumb.url, width: '20%') + = f.input :picture + %p.text-right + - if @organization.new_record? + = f.submit 'Create Organization', class: 'btn btn-success' + - else + = f.submit 'Update Organization', class: 'btn btn-success' \ No newline at end of file diff --git a/app/views/organizations/edit.html.haml b/app/views/organizations/edit.html.haml new file mode 100644 index 00000000..1f65d485 --- /dev/null +++ b/app/views/organizations/edit.html.haml @@ -0,0 +1,4 @@ +.container + .row + .col-md-12 + = render 'form' diff --git a/app/views/organizations/index.html.haml b/app/views/organizations/index.html.haml new file mode 100644 index 00000000..b87f156b --- /dev/null +++ b/app/views/organizations/index.html.haml @@ -0,0 +1,17 @@ +.container + .row + .col-md-12.page-header + %h1 + Organizations + .btn-group.pull-right + = link_to 'Add new', new_organization_path, class: 'btn btn-mini btn-success' + - @organizations.each do |organization| + .col-md-4 + .thumbnail + = image_tag(organization.picture.thumb.url, width: '20%') + .caption + %h4 + = organization.name + %button.btn.btn-success Conferences + = link_to 'Edit', edit_organization_path(organization), class: 'btn btn-mini btn-default' + diff --git a/app/views/organizations/new.html.haml b/app/views/organizations/new.html.haml new file mode 100644 index 00000000..1f65d485 --- /dev/null +++ b/app/views/organizations/new.html.haml @@ -0,0 +1,4 @@ +.container + .row + .col-md-12 + = render 'form' diff --git a/config/routes.rb b/config/routes.rb index 9fa1c29a..e2cfe7f7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -18,6 +18,7 @@ Osem::Application.routes.draw do resources :users, except: [:new, :index, :create, :destroy] namespace :admin do + resources :organizations resources :users do member do patch :toggle_confirmation @@ -102,7 +103,7 @@ Osem::Application.routes.draw do get '/revision_history/:id/revert_object' => 'versions#revert_object', as: 'revision_history_revert_object' get '/revision_history/:id/revert_attribute' => 'versions#revert_attribute', as: 'revision_history_revert_attribute' end - + resources :organizations resources :conferences, only: [:index, :show] do resource :program, only: [] do resources :proposals, except: :destroy do diff --git a/db/migrate/20170529215453_create_organizations.rb b/db/migrate/20170529215453_create_organizations.rb new file mode 100644 index 00000000..11caf736 --- /dev/null +++ b/db/migrate/20170529215453_create_organizations.rb @@ -0,0 +1,9 @@ +class CreateOrganizations < ActiveRecord::Migration + def change + create_table :organizations do |t| + t.string :name + t.text :description + t.string :picture + end + end +end diff --git a/db/migrate/20170531094817_add_organizaton_id_to_conference.rb b/db/migrate/20170531094817_add_organizaton_id_to_conference.rb new file mode 100644 index 00000000..4397ed7a --- /dev/null +++ b/db/migrate/20170531094817_add_organizaton_id_to_conference.rb @@ -0,0 +1,5 @@ +class AddOrganizatonIdToConference < ActiveRecord::Migration + def change + add_column :conferences, :organization_id, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index 5d74950a..c50e6b45 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170419132148) do +ActiveRecord::Schema.define(version: 20170531094817) do create_table "ahoy_events", force: :cascade do |t| t.uuid "visit_id", limit: 16 @@ -100,6 +100,7 @@ ActiveRecord::Schema.define(version: 20170419132148) do t.string "picture" t.integer "start_hour", default: 9 t.integer "end_hour", default: 20 + t.integer "organization_id" end create_table "conferences_questions", id: false, force: :cascade do |t| @@ -266,6 +267,12 @@ ActiveRecord::Schema.define(version: 20170419132148) do t.datetime "updated_at" end + create_table "organizations", force: :cascade do |t| + t.string "name" + t.text "description" + t.string "picture" + end + create_table "payments", force: :cascade do |t| t.string "last4" t.integer "amount" diff --git a/spec/controllers/admin/organizations_controller_spec.rb b/spec/controllers/admin/organizations_controller_spec.rb new file mode 100644 index 00000000..4635dfdf --- /dev/null +++ b/spec/controllers/admin/organizations_controller_spec.rb @@ -0,0 +1,14 @@ +require 'spec_helper' + +describe Admin::OrganizationsController do + let(:admin) { create(:admin) } + + describe 'GET #index' do + before :each do + sign_in admin + get :index + end + + it { expect(response).to render_template('index') } + end +end diff --git a/spec/controllers/organizations_controller_spec.rb b/spec/controllers/organizations_controller_spec.rb new file mode 100644 index 00000000..94007630 --- /dev/null +++ b/spec/controllers/organizations_controller_spec.rb @@ -0,0 +1,104 @@ +require 'spec_helper' + +describe OrganizationsController do + let!(:organization) { create(:organization) } + let!(:admin) { create(:admin, is_admin: true) } + + describe 'GET #new' do + before :each do + sign_in admin + get :new + end + + it { expect(response).to render_template('new') } + end + + describe 'GET #index' do + before :each do + sign_in admin + get :index + end + + it { expect(response).to render_template('index') } + end + + describe 'POST #create' do + before :each do + sign_in admin + end + context 'with valid attributes' do + it 'creates new organization' do + expected = expect do + post :create, organization: attributes_for(:organization) + end + expected.to change { Organization.count }.by(1) + end + + it 'redirects to index' do + post :create, organization: attributes_for(:organization) + + expect(flash[:notice]).to eq('Organization successfully created') + expect(response).to redirect_to(organizations_path) + end + end + + context 'with invalid attributes' do + it 'does not create new organization' do + expected = expect do + post :create, organization: attributes_for(:organization, name: '') + end + expected.to_not change { Organization.count } + end + + it 'redirects to new' do + post :create, organization: attributes_for(:organization, name: '') + + expect(flash[:error]).to eq("Name can't be blank") + expect(response).to redirect_to(new_organization_path) + end + end + end + + describe 'PATCH #update' do + before :each do + sign_in admin + end + + it 'saves and redirects to index when the attributes are valid' do + patch :update, id: organization.id, organization: attributes_for(:organization, name: 'changed name') + + expect(organization.name).to eq('changed name') + expect(flash).to eq('Organization successfully updated') + expect(response).to redirect_to(organizations_path) + end + + it 'redirects to edit when attributes are invalid' do + patch :update, id: organization.id, organization: attributes_for(:organization, name: '') + + expect(flash[:error]).to eq("Name can't be blank") + expect(response).to redirect_to(edit_organization_path(organization)) + end + end + + describe 'DELETE #destroy' do + before :each do + sign_in admin + end + + context 'for a valid organization' do + it 'should successfully destroy a resource' do + expected = expect do + delete :destroy, id: organization.id + end + expected.to change { Organization.count }.by(-1) + end + + it 'redirects to index' do + delete :destroy, id: organization.id + + expect(flash[:notice]).to eq('Organization successfully destroyed') + expect(response).to redirect_to(organizations_path) + end + end + end +end diff --git a/spec/factories/conferences.rb b/spec/factories/conferences.rb index 8a9186a6..e1ef7d84 100644 --- a/spec/factories/conferences.rb +++ b/spec/factories/conferences.rb @@ -11,7 +11,7 @@ FactoryGirl.define do end_hour 20 registration_limit 0 description { Faker::Hipster.paragraph } - + organization after(:create) do |conference| Role.where(name: 'organizer', resource: conference).first_or_create(description: 'For the organizers of the conference (who shall have full access)') Role.where(name: 'cfp', resource: conference).first_or_create(description: 'For the members of the CfP team') diff --git a/spec/factories/organizations.rb b/spec/factories/organizations.rb new file mode 100644 index 00000000..0ee76554 --- /dev/null +++ b/spec/factories/organizations.rb @@ -0,0 +1,13 @@ +FactoryGirl.define do + factory :organization do + name { Faker::Company.name } + description { Faker::Lorem.paragraph } + + # after(:create) do |organization| + # File.open("spec/support/logos/#{1 + rand(13)}.png") do |file| + # organization.picture = file + # end + # organization.save! + # end + end +end diff --git a/spec/models/organization_spec.rb b/spec/models/organization_spec.rb new file mode 100644 index 00000000..748205d5 --- /dev/null +++ b/spec/models/organization_spec.rb @@ -0,0 +1,19 @@ +require 'spec_helper' + +describe Organization do + let(:organization) { create(:organization) } + + describe 'validation' do + it 'has a valid factory' do + expect(build(:organization)).to be_valid + end + + it 'is not valid without a name' do + should validate_presence_of(:name) + end + end + + describe 'associations' do + it { should have_many(:conferences).dependent(:destroy) } + end +end From e0d8e85808cadb8f708ed991b019a176d1a8bfbb Mon Sep 17 00:00:00 2001 From: shlok007 Date: Mon, 5 Jun 2017 11:56:47 +0530 Subject: [PATCH 097/185] suggested changes --- .../admin/organizations_controller.rb | 33 ++++++++++++++ app/controllers/organizations_controller.rb | 43 ------------------- app/models/organization.rb | 2 +- app/views/admin/organizations/_form.html.haml | 6 +-- app/views/admin/organizations/index.html.haml | 4 +- .../layouts/_admin_sidebar_index.html.haml | 9 ++-- app/views/layouts/_user_menu.html.haml | 9 ++-- app/views/organizations/_form.html.haml | 13 ------ app/views/organizations/edit.html.haml | 4 -- app/views/organizations/index.html.haml | 5 +-- app/views/organizations/new.html.haml | 4 -- 11 files changed, 51 insertions(+), 81 deletions(-) delete mode 100644 app/views/organizations/_form.html.haml delete mode 100644 app/views/organizations/edit.html.haml delete mode 100644 app/views/organizations/new.html.haml diff --git a/app/controllers/admin/organizations_controller.rb b/app/controllers/admin/organizations_controller.rb index 1dc6bcd5..087bf7f8 100644 --- a/app/controllers/admin/organizations_controller.rb +++ b/app/controllers/admin/organizations_controller.rb @@ -6,6 +6,33 @@ module Admin @organizations = Organization.all end + def create + @organization = Organization.new(organization_params) + if @organization.save + redirect_to admin_organizations_path, + notice: 'Organization successfully created' + else + redirect_to new_admin_organization_path, + error: @organization.errors.full_messages.join(', ') + end + end + + def new + @organization = Organization.new + end + + def edit; end + + def update + if @organization.update_attributes(organization_params) + redirect_to admin_organizations_path, + notice: 'Organization successfully updated' + else + redirect_to edit_admin_organization_path(@organization), + error: @organization.errors.full_messages.join(', ') + end + end + def destroy if @organization.destroy redirect_to admin_organizations_path, @@ -15,5 +42,11 @@ module Admin error: 'Organization cannot be destroyed' end end + + private + + def organization_params + params.require(:organization).permit(:name, :description, :picture) + end end end diff --git a/app/controllers/organizations_controller.rb b/app/controllers/organizations_controller.rb index 58910526..3d549dfa 100644 --- a/app/controllers/organizations_controller.rb +++ b/app/controllers/organizations_controller.rb @@ -4,47 +4,4 @@ class OrganizationsController < ApplicationController def index @organizations = Organization.all end - - def create - @organization = Organization.new(organization_params) - if @organization.save - redirect_to organizations_path, - notice: 'Organization successfully created' - else - redirect_to new_organization_path, - error: @organization.errors.full_messages.join(', ') - end - end - - def new - @organization = Organization.new - end - - def edit; end - - def update - if @organization.update_attributes(organization_params) - redirect_to organizations_path, - notice: 'Organization successfully updated' - else - redirect_to edit_organization_path(@organization), - error: @organization.errors.full_messages.join(', ') - end - end - - def destroy - if @organization.destroy - redirect_to organizations_path, - notice: 'Organization successfully destroyed' - else - redirect_to organizations_path, - error: 'Organization cannot be destroyed' - end - end - - private - - def organization_params - params.require(:organization).permit(:name, :description, :picture) - end end diff --git a/app/models/organization.rb b/app/models/organization.rb index 60a83fef..15362d7a 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -1,5 +1,5 @@ class Organization < ActiveRecord::Base - has_many :conferences, dependent: :destroy + has_many :conferences validates :name, presence: true diff --git a/app/views/admin/organizations/_form.html.haml b/app/views/admin/organizations/_form.html.haml index c41f0cff..c83facbb 100644 --- a/app/views/admin/organizations/_form.html.haml +++ b/app/views/admin/organizations/_form.html.haml @@ -1,7 +1,7 @@ -= semantic_form_for(@organization) do |f| += semantic_form_for(@organization, url: (@organization.new_record? ? admin_organizations_path : admin_organization_path(@organization))) do |f| = f.inputs name: 'Organization details' do = f.input :name, as: :string, required: true - = f.input :description, input_html: { rows: 5 }, placeholder: 'Decribe about your organization..' + = f.input :description, as: :text, input_html: { rows: 10 }, placeholder: 'Decribe about your organization..' = image_tag f.object.picture.thumb.url if f.object.picture? - if @organization.picture = image_tag(@organization.picture.thumb.url, width: '20%') @@ -10,4 +10,4 @@ - if @organization.new_record? = f.submit 'Create Organization', class: 'btn btn-success' - else - = f.submit 'Update Organization', class: 'btn btn-success' \ No newline at end of file + = f.submit 'Update Organization', class: 'btn btn-success' diff --git a/app/views/admin/organizations/index.html.haml b/app/views/admin/organizations/index.html.haml index 0a751460..f0a8c3c7 100644 --- a/app/views/admin/organizations/index.html.haml +++ b/app/views/admin/organizations/index.html.haml @@ -25,7 +25,7 @@ = organization.conferences.count %td .btn-group - = link_to 'Edit', edit_organization_path(organization), + = link_to 'Edit', edit_admin_organization_path(organization), method: :get, class: 'btn btn-primary' = link_to 'Delete', admin_organization_path(organization), - method: :delete, class: 'btn btn-danger' + method: :delete, class: 'btn btn-danger', data: { confirm: "Warning: This will delete #{organization.name} and all its data which includes data for all conferences within #{organization.name}. Do you really want to continue?" } diff --git a/app/views/layouts/_admin_sidebar_index.html.haml b/app/views/layouts/_admin_sidebar_index.html.haml index f1cf8b75..3844339b 100644 --- a/app/views/layouts/_admin_sidebar_index.html.haml +++ b/app/views/layouts/_admin_sidebar_index.html.haml @@ -32,7 +32,8 @@ = link_to(admin_revision_history_path) do %span.fa.fa-history Revision History - %li - = link_to(admin_organizations_path) do - %span.fa.fa-group - Organizations + - if ENV['ORGANIZATIONS_ENABLED'] == 'true' + %li + = link_to(admin_organizations_path) do + %span.fa.fa-group + Organizations diff --git a/app/views/layouts/_user_menu.html.haml b/app/views/layouts/_user_menu.html.haml index 14d32fed..01432b3c 100644 --- a/app/views/layouts/_user_menu.html.haml +++ b/app/views/layouts/_user_menu.html.haml @@ -49,7 +49,8 @@ = link_to(admin_revision_history_path) do %span.fa.fa-history Revision History - %li - = link_to(admin_organizations_path) do - %span.fa.fa-group - Organizations + - if ENV['ORGANIZATIONS_ENABLED'] == 'true' + %li + = link_to(admin_organizations_path) do + %span.fa.fa-group + Organizations diff --git a/app/views/organizations/_form.html.haml b/app/views/organizations/_form.html.haml deleted file mode 100644 index c41f0cff..00000000 --- a/app/views/organizations/_form.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -= semantic_form_for(@organization) do |f| - = f.inputs name: 'Organization details' do - = f.input :name, as: :string, required: true - = f.input :description, input_html: { rows: 5 }, placeholder: 'Decribe about your organization..' - = image_tag f.object.picture.thumb.url if f.object.picture? - - if @organization.picture - = image_tag(@organization.picture.thumb.url, width: '20%') - = f.input :picture - %p.text-right - - if @organization.new_record? - = f.submit 'Create Organization', class: 'btn btn-success' - - else - = f.submit 'Update Organization', class: 'btn btn-success' \ No newline at end of file diff --git a/app/views/organizations/edit.html.haml b/app/views/organizations/edit.html.haml deleted file mode 100644 index 1f65d485..00000000 --- a/app/views/organizations/edit.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -.container - .row - .col-md-12 - = render 'form' diff --git a/app/views/organizations/index.html.haml b/app/views/organizations/index.html.haml index b87f156b..b2794bd8 100644 --- a/app/views/organizations/index.html.haml +++ b/app/views/organizations/index.html.haml @@ -4,7 +4,7 @@ %h1 Organizations .btn-group.pull-right - = link_to 'Add new', new_organization_path, class: 'btn btn-mini btn-success' + / = link_to 'Add new', new_organization_path, class: 'btn btn-mini btn-success' - @organizations.each do |organization| .col-md-4 .thumbnail @@ -13,5 +13,4 @@ %h4 = organization.name %button.btn.btn-success Conferences - = link_to 'Edit', edit_organization_path(organization), class: 'btn btn-mini btn-default' - + / = link_to 'Edit', edit_organization_path(organization), class: 'btn btn-mini btn-default' diff --git a/app/views/organizations/new.html.haml b/app/views/organizations/new.html.haml deleted file mode 100644 index 1f65d485..00000000 --- a/app/views/organizations/new.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -.container - .row - .col-md-12 - = render 'form' From ac85bad9b3066f05791edf98adfdf91cda80ba37 Mon Sep 17 00:00:00 2001 From: shlok007 Date: Mon, 5 Jun 2017 11:59:27 +0530 Subject: [PATCH 098/185] migrate conferences to organizations --- ...094817_add_organizaton_id_to_conference.rb | 5 ----- ...94819_move_conferences_to_organizations.rb | 21 +++++++++++++++++++ db/schema.rb | 4 +++- 3 files changed, 24 insertions(+), 6 deletions(-) delete mode 100644 db/migrate/20170531094817_add_organizaton_id_to_conference.rb create mode 100644 db/migrate/20170531094819_move_conferences_to_organizations.rb diff --git a/db/migrate/20170531094817_add_organizaton_id_to_conference.rb b/db/migrate/20170531094817_add_organizaton_id_to_conference.rb deleted file mode 100644 index 4397ed7a..00000000 --- a/db/migrate/20170531094817_add_organizaton_id_to_conference.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddOrganizatonIdToConference < ActiveRecord::Migration - def change - add_column :conferences, :organization_id, :integer - end -end diff --git a/db/migrate/20170531094819_move_conferences_to_organizations.rb b/db/migrate/20170531094819_move_conferences_to_organizations.rb new file mode 100644 index 00000000..80c2ebd6 --- /dev/null +++ b/db/migrate/20170531094819_move_conferences_to_organizations.rb @@ -0,0 +1,21 @@ +class MoveConferencesToOrganizations < ActiveRecord::Migration + class TempConference < ActiveRecord::Base + self.table_name = 'conferences' + end + + class TempOrganization < ActiveRecord::Base + self.table_name = 'organizations' + end + + def change + add_reference :conferences, :organization, index: true + add_foreign_key :conferences, :organizations, dependent: :delete + + TempConference.reset_column_information + organization = TempOrganization.create(name: 'organization', description: 'Default organization to migrate old conferences to the new version of OSEM') + TempConference.all.each do |conference| + conference.organization_id = organization.id + conference.save! + end + end +end diff --git a/db/schema.rb b/db/schema.rb index c50e6b45..7db5faa0 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170531094817) do +ActiveRecord::Schema.define(version: 20170531094819) do create_table "ahoy_events", force: :cascade do |t| t.uuid "visit_id", limit: 16 @@ -103,6 +103,8 @@ ActiveRecord::Schema.define(version: 20170531094817) do t.integer "organization_id" end + add_index "conferences", ["organization_id"], name: "index_conferences_on_organization_id" + create_table "conferences_questions", id: false, force: :cascade do |t| t.integer "conference_id" t.integer "question_id" From 3fb316482c92d5c140c1aa0806cc02c0ddbb8a1e Mon Sep 17 00:00:00 2001 From: shlok007 Date: Tue, 6 Jun 2017 20:04:39 +0530 Subject: [PATCH 099/185] suggested changes --- app/models/ability.rb | 1 + app/models/organization.rb | 2 +- app/views/admin/organizations/index.html.haml | 2 +- config/routes.rb | 2 +- .../20170529215453_create_organizations.rb | 2 +- ...94819_move_conferences_to_organizations.rb | 13 +- db/schema.rb | 2 +- .../admin/organizations_controller_spec.rb | 165 +++++++++++++++++- .../organizations_controller_spec.rb | 93 +--------- spec/models/organization_spec.rb | 4 - 10 files changed, 176 insertions(+), 110 deletions(-) diff --git a/app/models/ability.rb b/app/models/ability.rb index ff1628a1..dba29fa7 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -83,6 +83,7 @@ class Ability 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 diff --git a/app/models/organization.rb b/app/models/organization.rb index 15362d7a..60a83fef 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -1,5 +1,5 @@ class Organization < ActiveRecord::Base - has_many :conferences + has_many :conferences, dependent: :destroy validates :name, presence: true diff --git a/app/views/admin/organizations/index.html.haml b/app/views/admin/organizations/index.html.haml index f0a8c3c7..03bf11f9 100644 --- a/app/views/admin/organizations/index.html.haml +++ b/app/views/admin/organizations/index.html.haml @@ -3,7 +3,7 @@ .page-header %h1 Organizations .btn-group.pull-right - = link_to 'Add Organization', new_admin_organization_path, class: 'btn btn-success pull-right' + = link_to 'Create Organization', new_admin_organization_path, class: 'btn btn-success pull-right' %p.text-muted Manage organizations in OSEM .row diff --git a/config/routes.rb b/config/routes.rb index e2cfe7f7..b10d5d9c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -103,7 +103,7 @@ Osem::Application.routes.draw do get '/revision_history/:id/revert_object' => 'versions#revert_object', as: 'revision_history_revert_object' get '/revision_history/:id/revert_attribute' => 'versions#revert_attribute', as: 'revision_history_revert_attribute' end - resources :organizations + resources :organizations, only: [:index] resources :conferences, only: [:index, :show] do resource :program, only: [] do resources :proposals, except: :destroy do diff --git a/db/migrate/20170529215453_create_organizations.rb b/db/migrate/20170529215453_create_organizations.rb index 11caf736..0fa5450b 100644 --- a/db/migrate/20170529215453_create_organizations.rb +++ b/db/migrate/20170529215453_create_organizations.rb @@ -1,7 +1,7 @@ class CreateOrganizations < ActiveRecord::Migration def change create_table :organizations do |t| - t.string :name + t.string :name, null: false t.text :description t.string :picture end diff --git a/db/migrate/20170531094819_move_conferences_to_organizations.rb b/db/migrate/20170531094819_move_conferences_to_organizations.rb index 80c2ebd6..12bc7580 100644 --- a/db/migrate/20170531094819_move_conferences_to_organizations.rb +++ b/db/migrate/20170531094819_move_conferences_to_organizations.rb @@ -8,14 +8,15 @@ class MoveConferencesToOrganizations < ActiveRecord::Migration end def change - add_reference :conferences, :organization, index: true - add_foreign_key :conferences, :organizations, dependent: :delete + add_reference :conferences, :organization, index: true, foreign_key: true TempConference.reset_column_information - organization = TempOrganization.create(name: 'organization', description: 'Default organization to migrate old conferences to the new version of OSEM') - TempConference.all.each do |conference| - conference.organization_id = organization.id - conference.save! + if TempConference.count != 0 + organization = TempOrganization.create(name: 'organization', description: 'Default organization') + TempConference.all.each do |conference| + conference.organization_id = organization.id + conference.save! + end end end end diff --git a/db/schema.rb b/db/schema.rb index 7db5faa0..9772066a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -270,7 +270,7 @@ ActiveRecord::Schema.define(version: 20170531094819) do end create_table "organizations", force: :cascade do |t| - t.string "name" + t.string "name", null: false t.text "description" t.string "picture" end diff --git a/spec/controllers/admin/organizations_controller_spec.rb b/spec/controllers/admin/organizations_controller_spec.rb index 4635dfdf..43f7266f 100644 --- a/spec/controllers/admin/organizations_controller_spec.rb +++ b/spec/controllers/admin/organizations_controller_spec.rb @@ -2,13 +2,170 @@ require 'spec_helper' describe Admin::OrganizationsController do let(:admin) { create(:admin) } + let(:organization) { create(:organization) } + let(:user) { create(:user) } - describe 'GET #index' do + context 'logged in as user with no role' do before :each do - sign_in admin - get :index + sign_in user end - it { expect(response).to render_template('index') } + describe 'GET #new' do + before :each do + get :new + end + + it 'redirects to root' do + expect(flash[:alert]).to eq('You are not authorized to access this area!') + expect(response).to redirect_to(root_path) + end + end + + describe 'GET #index' do + before :each do + get :index + end + + it 'redirects to root' do + expect(flash[:alert]).to eq('You are not authorized to access this area!') + expect(response).to redirect_to(root_path) + end + end + + describe 'POST #create' do + it 'does not create new organization' do + expected = expect do + post :create, organization: attributes_for(:organization) + end + expected.to_not change { Organization.count } + end + + it 'redirects to root' do + post :create, organization: attributes_for(:organization) + + expect(flash[:alert]).to eq('You are not authorized to access this area!') + expect(response).to redirect_to(root_path) + end + end + + describe 'PATCH #update' do + it 'does not update and redirects to root' do + old_name = organization.name + patch :update, id: organization.id, organization: attributes_for(:organization, name: 'new name') + + organization.reload + expect(organization.name).to eq(old_name) + expect(flash[:alert]).to eq('You are not authorized to access this area!') + expect(response).to redirect_to(root_path) + end + end + + describe 'DELETE #destroy' do + context 'for a valid organization' do + it 'does not destroy a resource' do + expected = expect do + delete :destroy, id: organization.id + end + expected.to_not change { Organization.count } + end + + it 'redirects to root' do + delete :destroy, id: organization.id + + expect(flash[:alert]).to eq('You are not authorized to access this area!') + expect(response).to redirect_to(root_path) + end + end + end + end + + context 'logged in as admin' do + before :each do + sign_in admin + end + + describe 'GET #new' do + before do + get :new + end + it { expect(response).to render_template('new') } + end + + describe 'GET #index' do + before do + get :index + end + it { expect(response).to render_template('index') } + end + + describe 'POST #create' do + context 'with valid attributes' do + it 'creates new organization' do + expected = expect do + post :create, organization: attributes_for(:organization) + end + expected.to change { Organization.count }.by(1) + end + + it 'redirects to index' do + post :create, organization: attributes_for(:organization) + + expect(flash[:notice]).to eq('Organization successfully created') + expect(response).to redirect_to(admin_organizations_path) + end + end + + context 'with invalid attributes' do + it 'does not create new organization' do + expected = expect do + post :create, organization: attributes_for(:organization, name: '') + end + expected.to_not change { Organization.count } + end + + it 'redirects to new' do + post :create, organization: attributes_for(:organization, name: '') + + expect(flash[:error]).to eq("Name can't be blank") + expect(response).to redirect_to(new_admin_organization_path) + end + end + end + + describe 'PATCH #update' do + it 'saves and redirects to index when the attributes are valid' do + patch :update, id: organization.id, organization: attributes_for(:organization, name: 'changed name') + + organization.reload + expect(organization.name).to eq('changed name') + expect(flash[:notice]).to eq('Organization successfully updated') + expect(response).to redirect_to(admin_organizations_path) + end + + it 'redirects to edit when attributes are invalid' do + patch :update, id: organization.id, organization: attributes_for(:organization, name: '') + + expect(flash[:error]).to eq("Name can't be blank") + expect(response).to redirect_to(edit_admin_organization_path(organization)) + end + end + + describe 'DELETE #destroy' do + context 'for a valid organization' do + it 'should successfully destroy a resource' do + expected = expect do + delete :destroy, id: organization.id + end + expected.to change { Organization.count }.by(-1) + end + + it 'redirects to index' do + delete :destroy, id: organization.id + + expect(flash[:notice]).to eq('Organization successfully destroyed') + expect(response).to redirect_to(admin_organizations_path) + end + end + end end end diff --git a/spec/controllers/organizations_controller_spec.rb b/spec/controllers/organizations_controller_spec.rb index 94007630..2916fdea 100644 --- a/spec/controllers/organizations_controller_spec.rb +++ b/spec/controllers/organizations_controller_spec.rb @@ -2,103 +2,14 @@ require 'spec_helper' describe OrganizationsController do let!(:organization) { create(:organization) } - let!(:admin) { create(:admin, is_admin: true) } - - describe 'GET #new' do - before :each do - sign_in admin - get :new - end - - it { expect(response).to render_template('new') } - end + let!(:user) { create(:user) } describe 'GET #index' do before :each do - sign_in admin + sign_in user get :index end it { expect(response).to render_template('index') } end - - describe 'POST #create' do - before :each do - sign_in admin - end - context 'with valid attributes' do - it 'creates new organization' do - expected = expect do - post :create, organization: attributes_for(:organization) - end - expected.to change { Organization.count }.by(1) - end - - it 'redirects to index' do - post :create, organization: attributes_for(:organization) - - expect(flash[:notice]).to eq('Organization successfully created') - expect(response).to redirect_to(organizations_path) - end - end - - context 'with invalid attributes' do - it 'does not create new organization' do - expected = expect do - post :create, organization: attributes_for(:organization, name: '') - end - expected.to_not change { Organization.count } - end - - it 'redirects to new' do - post :create, organization: attributes_for(:organization, name: '') - - expect(flash[:error]).to eq("Name can't be blank") - expect(response).to redirect_to(new_organization_path) - end - end - end - - describe 'PATCH #update' do - before :each do - sign_in admin - end - - it 'saves and redirects to index when the attributes are valid' do - patch :update, id: organization.id, organization: attributes_for(:organization, name: 'changed name') - - expect(organization.name).to eq('changed name') - expect(flash).to eq('Organization successfully updated') - expect(response).to redirect_to(organizations_path) - end - - it 'redirects to edit when attributes are invalid' do - patch :update, id: organization.id, organization: attributes_for(:organization, name: '') - - expect(flash[:error]).to eq("Name can't be blank") - expect(response).to redirect_to(edit_organization_path(organization)) - end - end - - describe 'DELETE #destroy' do - before :each do - sign_in admin - end - - context 'for a valid organization' do - it 'should successfully destroy a resource' do - expected = expect do - delete :destroy, id: organization.id - end - expected.to change { Organization.count }.by(-1) - end - - it 'redirects to index' do - delete :destroy, id: organization.id - - expect(flash[:notice]).to eq('Organization successfully destroyed') - expect(response).to redirect_to(organizations_path) - end - end - end end diff --git a/spec/models/organization_spec.rb b/spec/models/organization_spec.rb index 748205d5..ca84f532 100644 --- a/spec/models/organization_spec.rb +++ b/spec/models/organization_spec.rb @@ -4,10 +4,6 @@ describe Organization do let(:organization) { create(:organization) } describe 'validation' do - it 'has a valid factory' do - expect(build(:organization)).to be_valid - end - it 'is not valid without a name' do should validate_presence_of(:name) end From cce3ff7aea589d18d4da96acda3341afbaf024a3 Mon Sep 17 00:00:00 2001 From: shlok007 Date: Wed, 7 Jun 2017 11:11:29 +0530 Subject: [PATCH 100/185] creating default organization while creating a conference --- app/controllers/admin/conferences_controller.rb | 14 +++++++++++--- app/views/admin/conferences/new.html.haml | 2 ++ spec/models/conference_spec.rb | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/app/controllers/admin/conferences_controller.rb b/app/controllers/admin/conferences_controller.rb index f9e1177d..c6d54f04 100644 --- a/app/controllers/admin/conferences_controller.rb +++ b/app/controllers/admin/conferences_controller.rb @@ -72,11 +72,19 @@ module Admin def new @conference = Conference.new + @organizations = {} + Organization.all.each do |organization| + @organizations.store(organization.name, organization.id) if can? :create, Conference.new(organization: organization) + end end def create - @conference = Conference.new(conference_params) - + conference_params_copy = conference_params + if ENV['ORGANIZATIONS_ENABLED'] != 'true' + org = Organization.exists?(name: 'default') ? Organization.find_by(name: 'default') : Organization.create(name: 'default') + conference_params_copy[:organization_id] = org.id + end + @conference = Conference.new(conference_params_copy) if @conference.save # user that creates the conference becomes organizer of that conference current_user.add_role :organizer, @conference @@ -211,7 +219,7 @@ module Admin :vpositions_attributes, :use_volunteers, :color, :sponsorship_levels_attributes, :sponsors_attributes, :targets, :targets_attributes, - :campaigns, :campaigns_attributes, :registration_limit) + :campaigns, :campaigns_attributes, :registration_limit, :organization_id) end end end diff --git a/app/views/admin/conferences/new.html.haml b/app/views/admin/conferences/new.html.haml index 014758de..7f414563 100644 --- a/app/views/admin/conferences/new.html.haml +++ b/app/views/admin/conferences/new.html.haml @@ -6,6 +6,8 @@ input_html: { required: 'required' } = f.input :short_title, hint: "A short and unique handle for your conference, using only letters, numbers, underscores, and dashes. This will be used to identify your conference in URLs etc. Example: 'froscon2011'", input_html: { required: 'required', pattern: '[a-zA-Z0-9_-]+', title: 'Only letters, numbers, underscores, and dashes.' }, prepend: conferences_url + '/' + - if ENV['ORGANIZATIONS_ENABLED'] == 'true' + = f.input :organization, as: :select, collection: @organizations = f.inputs 'Scheduling' do = f.input :timezone, as: :time_zone, default: Time.zone.name, hint: 'Please select in what time zone your conference will take place.' = f.input :start_date, as: :string, input_html: { id: 'conference-start-datepicker', required: 'required' } diff --git a/spec/models/conference_spec.rb b/spec/models/conference_spec.rb index b5a6d5f0..9bdbea83 100755 --- a/spec/models/conference_spec.rb +++ b/spec/models/conference_spec.rb @@ -1630,7 +1630,7 @@ describe Conference do end describe 'after_create' do - let(:conference) { Conference.new(title: 'ABC', short_title: 'XYZ', start_date: Date.today, end_date: Date.today + 10, timezone: 'GMT') } + let(:conference) { create(:conference) } it 'calls back to create free ticket' do conference.save From 949f5cb591468e2053bdbc44f29ee659d14e915e Mon Sep 17 00:00:00 2001 From: shlok007 Date: Wed, 7 Jun 2017 12:37:30 +0530 Subject: [PATCH 101/185] add foreign key to conferences --- .../20170531094819_move_conferences_to_organizations.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/db/migrate/20170531094819_move_conferences_to_organizations.rb b/db/migrate/20170531094819_move_conferences_to_organizations.rb index 12bc7580..e70acf16 100644 --- a/db/migrate/20170531094819_move_conferences_to_organizations.rb +++ b/db/migrate/20170531094819_move_conferences_to_organizations.rb @@ -8,7 +8,7 @@ class MoveConferencesToOrganizations < ActiveRecord::Migration end def change - add_reference :conferences, :organization, index: true, foreign_key: true + add_reference :conferences, :organization, index: true TempConference.reset_column_information if TempConference.count != 0 @@ -18,5 +18,7 @@ class MoveConferencesToOrganizations < ActiveRecord::Migration conference.save! end end + + add_foreign_key :conferences, :organizations, null: false, on_delete: :cascade end end From b29856a1222f5158f9e4e87ccfb9d366ace260b5 Mon Sep 17 00:00:00 2001 From: shlok007 Date: Wed, 7 Jun 2017 14:14:42 +0530 Subject: [PATCH 102/185] suggested changes --- app/controllers/admin/conferences_controller.rb | 9 +++------ app/views/admin/conferences/new.html.haml | 2 -- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/app/controllers/admin/conferences_controller.rb b/app/controllers/admin/conferences_controller.rb index c6d54f04..0ff0289d 100644 --- a/app/controllers/admin/conferences_controller.rb +++ b/app/controllers/admin/conferences_controller.rb @@ -79,12 +79,9 @@ module Admin end def create - conference_params_copy = conference_params - if ENV['ORGANIZATIONS_ENABLED'] != 'true' - org = Organization.exists?(name: 'default') ? Organization.find_by(name: 'default') : Organization.create(name: 'default') - conference_params_copy[:organization_id] = org.id - end - @conference = Conference.new(conference_params_copy) + org = Organization.find_or_create_by(name: 'organization') + @conference = Conference.new(conference_params) + @conference.organization = org if @conference.save # user that creates the conference becomes organizer of that conference current_user.add_role :organizer, @conference diff --git a/app/views/admin/conferences/new.html.haml b/app/views/admin/conferences/new.html.haml index 7f414563..014758de 100644 --- a/app/views/admin/conferences/new.html.haml +++ b/app/views/admin/conferences/new.html.haml @@ -6,8 +6,6 @@ input_html: { required: 'required' } = f.input :short_title, hint: "A short and unique handle for your conference, using only letters, numbers, underscores, and dashes. This will be used to identify your conference in URLs etc. Example: 'froscon2011'", input_html: { required: 'required', pattern: '[a-zA-Z0-9_-]+', title: 'Only letters, numbers, underscores, and dashes.' }, prepend: conferences_url + '/' - - if ENV['ORGANIZATIONS_ENABLED'] == 'true' - = f.input :organization, as: :select, collection: @organizations = f.inputs 'Scheduling' do = f.input :timezone, as: :time_zone, default: Time.zone.name, hint: 'Please select in what time zone your conference will take place.' = f.input :start_date, as: :string, input_html: { id: 'conference-start-datepicker', required: 'required' } From 521c05af61d7533371bff03930fc145b13be045a Mon Sep 17 00:00:00 2001 From: shlok007 Date: Fri, 9 Jun 2017 04:35:16 +0530 Subject: [PATCH 103/185] skip failing tests --- .haml-lint_todo.yml | 45 +++++++------ .../admin/organizations_controller_spec.rb | 64 +++++++++---------- 2 files changed, 54 insertions(+), 55 deletions(-) diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index 2c51e966..918178e2 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `haml-lint --auto-gen-config` -# on 2017-04-25 04:36:49 +0530 using Haml-Lint version 0.24.0. +# on 2017-06-09 04:02:20 +0530 using Haml-Lint version 0.24.0. # The point is for the user to remove these configuration records # one by one as the lints are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -8,7 +8,7 @@ linters: - # Offense count: 952 + # Offense count: 945 LineLength: exclude: - "app/views/admin/campaigns/_form.html.haml" @@ -49,10 +49,11 @@ linters: - "app/views/admin/events/_voting_index.html.haml" - "app/views/admin/events/index.html.haml" - "app/views/admin/events/registrations.html.haml" - - "app/views/admin/events/reports.html.haml" - "app/views/admin/events/show.html.haml" - "app/views/admin/lodgings/_form.html.haml" - "app/views/admin/lodgings/index.html.haml" + - "app/views/admin/organizations/_form.html.haml" + - "app/views/admin/organizations/index.html.haml" - "app/views/admin/programs/_form.html.haml" - "app/views/admin/programs/show.html.haml" - "app/views/admin/questions/_form.html.haml" @@ -144,6 +145,7 @@ linters: - "app/views/layouts/_messages.html.haml" - "app/views/layouts/_navigation.html.haml" - "app/views/layouts/application.html.haml" + - "app/views/organizations/index.html.haml" - "app/views/payments/_payment.html.haml" - "app/views/proposals/_form.html.haml" - "app/views/proposals/_proposal_form.html.haml" @@ -170,7 +172,7 @@ linters: - "app/views/users/edit.html.haml" - "app/views/users/show.html.haml" - # Offense count: 222 + # Offense count: 223 InstanceVariables: exclude: - "app/views/admin/campaigns/_form.html.haml" @@ -184,6 +186,7 @@ linters: - "app/views/admin/events/_voting.html.haml" - "app/views/admin/events/_voting_index.html.haml" - "app/views/admin/lodgings/_form.html.haml" + - "app/views/admin/organizations/_form.html.haml" - "app/views/admin/questions/_questions.html.haml" - "app/views/admin/registration_periods/_form.html.haml" - "app/views/admin/reports/_all_events.html.haml" @@ -245,14 +248,11 @@ linters: - "app/views/admin/users/show.html.haml" - "app/views/users/edit.html.haml" - # Offense count: 8 + # Offense count: 4 UnnecessaryInterpolation: exclude: - "app/views/admin/conferences/_doughnut_chart.html.haml" - "app/views/admin/conferences/_recent_submissions.html.haml" - - "app/views/admin/events/reports.html.haml" - - "app/views/admin/reports/_events_with_requirements.html.haml" - - "app/views/admin/reports/_events_without_commercials.html.haml" - "app/views/proposals/_proposal_form.html.haml" - "app/views/proposals/new.html.haml" @@ -328,11 +328,10 @@ linters: - "app/views/tickets/_ticket.html.haml" - "app/views/tickets/index.html.haml" - # Offense count: 27 + # Offense count: 23 ClassesBeforeIds: exclude: - "app/views/admin/emails/index.html.haml" - - "app/views/admin/events/reports.html.haml" - "app/views/admin/events/show.html.haml" - "app/views/admin/reports/index.html.haml" - "app/views/admin/users/show.html.haml" @@ -386,6 +385,19 @@ linters: - "app/views/admin/versions/_object_desc_and_link.html.haml" - "app/views/schedules/_carousel.html.haml" + # Offense count: 29 + TrailingWhitespace: + exclude: + - "app/views/admin/organizations/_form.html.haml" + - "app/views/admin/users/index.html.haml" + - "app/views/admin/users/show.html.haml" + - "app/views/admin/volunteers/index.html.haml" + - "app/views/admin/volunteers/show.html.haml" + - "app/views/conference_registrations/_volunteer.html.haml" + - "app/views/devise/passwords/new.html.haml" + - "app/views/payments/new.html.haml" + - "app/views/tickets/index.html.haml" + # Offense count: 2 FinalNewline: exclude: @@ -406,19 +418,6 @@ linters: - "app/views/schedules/_event.html.haml" - "app/views/schedules/_schedule_item.html.haml" - # Offense count: 38 - TrailingWhitespace: - exclude: - - "app/views/admin/users/_form.html.haml" - - "app/views/admin/users/index.html.haml" - - "app/views/admin/users/show.html.haml" - - "app/views/admin/volunteers/index.html.haml" - - "app/views/admin/volunteers/show.html.haml" - - "app/views/conference_registrations/_volunteer.html.haml" - - "app/views/devise/passwords/new.html.haml" - - "app/views/payments/new.html.haml" - - "app/views/tickets/index.html.haml" - # Offense count: 7 ClassAttributeWithStaticValue: exclude: diff --git a/spec/controllers/admin/organizations_controller_spec.rb b/spec/controllers/admin/organizations_controller_spec.rb index 43f7266f..14423cbd 100644 --- a/spec/controllers/admin/organizations_controller_spec.rb +++ b/spec/controllers/admin/organizations_controller_spec.rb @@ -37,7 +37,7 @@ describe Admin::OrganizationsController do expected = expect do post :create, organization: attributes_for(:organization) end - expected.to_not change { Organization.count } + expected.to_not change(Organization, :count) end it 'redirects to root' do @@ -60,23 +60,23 @@ describe Admin::OrganizationsController do end end - describe 'DELETE #destroy' do - context 'for a valid organization' do - it 'does not destroy a resource' do - expected = expect do - delete :destroy, id: organization.id - end - expected.to_not change { Organization.count } - end + # describe 'DELETE #destroy' do + # context 'for a valid organization' do + # it 'does not destroy a resource' do + # expected = expect do + # delete :destroy, id: organization.id + # end + # expected.to_not change { Organization.count } + # end - it 'redirects to root' do - delete :destroy, id: organization.id + # it 'redirects to root' do + # delete :destroy, id: organization.id - expect(flash[:alert]).to eq('You are not authorized to access this area!') - expect(response).to redirect_to(root_path) - end - end - end + # expect(flash[:alert]).to eq('You are not authorized to access this area!') + # expect(response).to redirect_to(root_path) + # end + # end + # end end context 'logged in as admin' do @@ -120,7 +120,7 @@ describe Admin::OrganizationsController do expected = expect do post :create, organization: attributes_for(:organization, name: '') end - expected.to_not change { Organization.count } + expected.to_not change(Organization, :count) end it 'redirects to new' do @@ -150,22 +150,22 @@ describe Admin::OrganizationsController do end end - describe 'DELETE #destroy' do - context 'for a valid organization' do - it 'should successfully destroy a resource' do - expected = expect do - delete :destroy, id: organization.id - end - expected.to change { Organization.count }.by(-1) - end + # describe 'DELETE #destroy' do + # context 'for a valid organization' do + # it 'should successfully destroy a resource' do + # expected = expect do + # delete :destroy, id: organization.id + # end + # expected.to change { Organization.count }.by(-1) + # end - it 'redirects to index' do - delete :destroy, id: organization.id + # it 'redirects to index' do + # delete :destroy, id: organization.id - expect(flash[:notice]).to eq('Organization successfully destroyed') - expect(response).to redirect_to(admin_organizations_path) - end - end - end + # expect(flash[:notice]).to eq('Organization successfully destroyed') + # expect(response).to redirect_to(admin_organizations_path) + # end + # end + # end end end From 6cf9ddbdea7c54f901a3b10382ca81f9da82f94b Mon Sep 17 00:00:00 2001 From: shlok007 Date: Sat, 10 Jun 2017 19:17:50 +0530 Subject: [PATCH 104/185] fix failing test --- .../admin/organizations_controller_spec.rb | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/spec/controllers/admin/organizations_controller_spec.rb b/spec/controllers/admin/organizations_controller_spec.rb index 14423cbd..a4afc994 100644 --- a/spec/controllers/admin/organizations_controller_spec.rb +++ b/spec/controllers/admin/organizations_controller_spec.rb @@ -1,9 +1,9 @@ require 'spec_helper' describe Admin::OrganizationsController do - let(:admin) { create(:admin) } - let(:organization) { create(:organization) } - let(:user) { create(:user) } + let!(:admin) { create(:admin) } + let!(:organization) { create(:organization) } + let!(:user) { create(:user) } context 'logged in as user with no role' do before :each do @@ -60,23 +60,23 @@ describe Admin::OrganizationsController do end end - # describe 'DELETE #destroy' do - # context 'for a valid organization' do - # it 'does not destroy a resource' do - # expected = expect do - # delete :destroy, id: organization.id - # end - # expected.to_not change { Organization.count } - # end + describe 'DELETE #destroy' do + context 'for a valid organization' do + it 'does not destroy a resource' do + expected = expect do + delete :destroy, id: organization.id + end + expected.to_not change(Organization, :count) + end - # it 'redirects to root' do - # delete :destroy, id: organization.id + it 'redirects to root' do + delete :destroy, id: organization.id - # expect(flash[:alert]).to eq('You are not authorized to access this area!') - # expect(response).to redirect_to(root_path) - # end - # end - # end + expect(flash[:alert]).to eq('You are not authorized to access this area!') + expect(response).to redirect_to(root_path) + end + end + end end context 'logged in as admin' do @@ -150,22 +150,22 @@ describe Admin::OrganizationsController do end end - # describe 'DELETE #destroy' do - # context 'for a valid organization' do - # it 'should successfully destroy a resource' do - # expected = expect do - # delete :destroy, id: organization.id - # end - # expected.to change { Organization.count }.by(-1) - # end + describe 'DELETE #destroy' do + context 'for a valid organization' do + it 'should successfully destroy a resource' do + expected = expect do + delete :destroy, id: organization.id + end + expected.to change { Organization.count }.by(-1) + end - # it 'redirects to index' do - # delete :destroy, id: organization.id + it 'redirects to index' do + delete :destroy, id: organization.id - # expect(flash[:notice]).to eq('Organization successfully destroyed') - # expect(response).to redirect_to(admin_organizations_path) - # end - # end - # end + expect(flash[:notice]).to eq('Organization successfully destroyed') + expect(response).to redirect_to(admin_organizations_path) + end + end + end end end From cc5d47e6de5812eb3c5bf4339e75f5f8620f089f Mon Sep 17 00:00:00 2001 From: shlok007 Date: Sat, 10 Jun 2017 19:36:50 +0530 Subject: [PATCH 105/185] suggested changes --- app/controllers/admin/conferences_controller.rb | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/app/controllers/admin/conferences_controller.rb b/app/controllers/admin/conferences_controller.rb index 0ff0289d..f8c9ea19 100644 --- a/app/controllers/admin/conferences_controller.rb +++ b/app/controllers/admin/conferences_controller.rb @@ -72,16 +72,11 @@ module Admin def new @conference = Conference.new - @organizations = {} - Organization.all.each do |organization| - @organizations.store(organization.name, organization.id) if can? :create, Conference.new(organization: organization) - end end def create - org = Organization.find_or_create_by(name: 'organization') @conference = Conference.new(conference_params) - @conference.organization = org + @conference.organization = Organization.find_or_create_by(name: 'organization') if @conference.save # user that creates the conference becomes organizer of that conference current_user.add_role :organizer, @conference From be72b9d02ebde2bc02f63d5187e66597c75f6992 Mon Sep 17 00:00:00 2001 From: Dimitris Date: Sat, 10 Jun 2017 19:36:12 +0300 Subject: [PATCH 106/185] Allow user to remove openid --- app/controllers/openids_controller.rb | 9 +++++++++ app/models/ability.rb | 2 ++ app/views/devise/registrations/edit.html.haml | 6 +++++- config/routes.rb | 4 +++- 4 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 app/controllers/openids_controller.rb diff --git a/app/controllers/openids_controller.rb b/app/controllers/openids_controller.rb new file mode 100644 index 00000000..35bc0bae --- /dev/null +++ b/app/controllers/openids_controller.rb @@ -0,0 +1,9 @@ +class OpenidsController < ApplicationController + load_and_authorize_resource :user + load_and_authorize_resource through: :user + + def destroy + @openid.destroy + redirect_to :back + end +end diff --git a/app/models/ability.rb b/app/models/ability.rb index dba29fa7..cc23a631 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -100,6 +100,8 @@ class Ability # can manage the commercials of their own events can :manage, Commercial, commercialable_type: 'Event', commercialable_id: user.events.pluck(:id) + + can [:destroy], Openid end # Abilities for signed in users with roles diff --git a/app/views/devise/registrations/edit.html.haml b/app/views/devise/registrations/edit.html.haml index d97b4867..c884a194 100644 --- a/app/views/devise/registrations/edit.html.haml +++ b/app/views/devise/registrations/edit.html.haml @@ -15,7 +15,11 @@ %h4 Currently the following openIDs are associated with your account - @openids.each do |openid| - %li= "#{openid.provider}:#{openid.email}" + %li{ style: "list-style: none; margin-left: 20px;" } + = link_to user_openid_path(openid, user_id: current_user.id), method: :delete, + data: { confirm: "Remove association with #{openid.provider} account?" } do + %span.fa.fa-times{ style: "color: red;" } + %span #{openid.provider}:#{openid.email} %br %h4 To add an openID with a different email address to your account, sign in with your diff --git a/config/routes.rb b/config/routes.rb index b10d5d9c..ccca3511 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -15,7 +15,9 @@ Osem::Application.routes.draw do mount LetterOpenerWeb::Engine, at: "/letter_opener" end - resources :users, except: [:new, :index, :create, :destroy] + resources :users, except: [:new, :index, :create, :destroy] do + resources :openids, only: :destroy + end namespace :admin do resources :organizations From cdf794ecbf21e0709c102d8f5e54ae16270e4664 Mon Sep 17 00:00:00 2001 From: divyanshumehta Date: Mon, 12 Jun 2017 22:37:45 +0530 Subject: [PATCH 107/185] Add Style/SelfAssignment Rubocop cop The cop enforces use of self assignment operator E.g. a=a+2 gets written as a+=2. Also the offenses listed in rubocop.todo.yml have been corrected automatically with the --auto-correct option. Fixes issue #1531 --- .rubocop.yml | 4 ++++ .rubocop_todo.yml | 8 -------- app/models/event.rb | 2 +- db/migrate/20141104131625_generate_username.rb | 4 +--- spec/support/save_feature_failures.rb | 2 +- 5 files changed, 7 insertions(+), 13 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 9f7f0d00..5cc5d541 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -92,6 +92,10 @@ Style/SpaceAroundOperators: Style/SpaceInsideBrackets: Enabled: true +# This cop enforces the use the shorthand for self-assignment. +Style/SelfAssignment: + Enabled: true + # Use single quotes unless there's string interpolation Style/StringLiterals: Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 1544c6f2..928205b0 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -721,14 +721,6 @@ Style/RegexpLiteral: Exclude: - 'Guardfile' -# Offense count: 3 -# Cop supports --auto-correct. -Style/SelfAssignment: - Exclude: - - 'app/models/event.rb' - - 'db/migrate/20141104131625_generate_username.rb' - - 'spec/support/save_feature_failures.rb' - # Offense count: 3 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. diff --git a/app/models/event.rb b/app/models/event.rb index 0c786066..f8f9c2d8 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -115,7 +115,7 @@ class Event < ActiveRecord::Base def average_rating @total_rating = 0 votes.each do |vote| - @total_rating = @total_rating + vote.rating + @total_rating += vote.rating end @total = votes.size @total_rating > 0 ? number_with_precision(@total_rating / @total.to_f, precision: 2, strip_insignificant_zeros: true) : 0 diff --git a/db/migrate/20141104131625_generate_username.rb b/db/migrate/20141104131625_generate_username.rb index d7f4bdda..e1ddf111 100644 --- a/db/migrate/20141104131625_generate_username.rb +++ b/db/migrate/20141104131625_generate_username.rb @@ -7,9 +7,7 @@ class GenerateUsername < ActiveRecord::Migration TempUser.all.each do |user| if user.username.blank? username = user.email.split('@')[0] - if TempUser.find_by(username: username) - username = username + user.id.to_s - end + username += user.id.to_s if TempUser.find_by(username: username) user.update_attributes(username: username) end end diff --git a/spec/support/save_feature_failures.rb b/spec/support/save_feature_failures.rb index fe6edf66..2e0d33a9 100644 --- a/spec/support/save_feature_failures.rb +++ b/spec/support/save_feature_failures.rb @@ -5,7 +5,7 @@ RSpec.configure do |config| config.after(:each, type: :feature) do example_filename = RSpec.current_example.full_description example_filename = example_filename.tr(' ', '_') - example_filename = example_filename + '.html' + example_filename += '.html' example_filename = File.expand_path(example_filename, Capybara.save_and_open_page_path) if RSpec.current_example.exception.present? save_page(example_filename) From 58c80f1447c1c1db332aa02fec8ca448555409b8 Mon Sep 17 00:00:00 2001 From: shlok007 Date: Wed, 14 Jun 2017 22:12:10 +0530 Subject: [PATCH 108/185] update nokogiri to 1.8.0 --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index e1c8218f..9dbc51e9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -273,7 +273,7 @@ GEM open4 (~> 1.3.4) rake mini_magick (4.5.1) - mini_portile2 (2.1.0) + mini_portile2 (2.2.0) minitest (5.10.1) momentjs-rails (2.8.1) railties (>= 3.1) @@ -293,8 +293,8 @@ GEM mysql2 (0.4.2) netrc (0.11.0) nio4r (1.2.1) - nokogiri (1.7.1) - mini_portile2 (~> 2.1.0) + nokogiri (1.8.0) + mini_portile2 (~> 2.2.0) oauth2 (0.9.4) faraday (>= 0.8, < 0.10) jwt (~> 1.0) From 0496ed23e5a3564313e6c7521f0c234a38763979 Mon Sep 17 00:00:00 2001 From: siddhantbajaj Date: Wed, 14 Jun 2017 02:46:39 +0530 Subject: [PATCH 109/185] Improves test speed --- spec/support/database_cleaner.rb | 12 +++++++++++- spec/support/factory_girl.rb | 12 +++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/spec/support/database_cleaner.rb b/spec/support/database_cleaner.rb index 3e6c8404..25bf528a 100644 --- a/spec/support/database_cleaner.rb +++ b/spec/support/database_cleaner.rb @@ -1,6 +1,16 @@ RSpec.configure do |config| - config.before(:each) do + config.before(:suite) do DatabaseCleaner.clean_with(:truncation) Rails.application.load_seed end + + config.before(:each) do |example| + DatabaseCleaner.strategy = example.metadata[:js] == true ? :truncation : :transaction + DatabaseCleaner.start + end + + config.after(:each) do |example| + DatabaseCleaner.clean + Rails.application.load_seed if example.metadata[:js] == true + end end diff --git a/spec/support/factory_girl.rb b/spec/support/factory_girl.rb index c46a5105..d745aece 100644 --- a/spec/support/factory_girl.rb +++ b/spec/support/factory_girl.rb @@ -4,9 +4,15 @@ RSpec.configure do |config| config.before(:suite) do if ENV['OSEM_FACTORY_LINT'] != 'false' - mock_commercial_request - FactoryGirl.lint + DatabaseCleaner.strategy = :transaction + DatabaseCleaner.clean_with(:truncation) + begin + DatabaseCleaner.start + mock_commercial_request + FactoryGirl.lint + ensure + DatabaseCleaner.clean + end end end - end From 2f70a1ddd114604c423393ddee3ae26b9e8a41be Mon Sep 17 00:00:00 2001 From: Stella Rouzi Date: Tue, 13 Jun 2017 10:22:23 +0300 Subject: [PATCH 110/185] Avoid horizontal scroll bar --- app/views/admin/organizations/index.html.haml | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/app/views/admin/organizations/index.html.haml b/app/views/admin/organizations/index.html.haml index 03bf11f9..52e2877a 100644 --- a/app/views/admin/organizations/index.html.haml +++ b/app/views/admin/organizations/index.html.haml @@ -6,26 +6,26 @@ = link_to 'Create Organization', new_admin_organization_path, class: 'btn btn-success pull-right' %p.text-muted Manage organizations in OSEM - .row - .col-md-12 - %table.table.table-hover.datatable - %thead - %th Name - %th Upcoming Conferences - %th Past Conferences - %th Actions - %tbody - - @organizations.each do |organization| - %tr - %td - = organization.name - %td - = organization.conferences.count - %td - = organization.conferences.count - %td - .btn-group - = link_to 'Edit', edit_admin_organization_path(organization), - method: :get, class: 'btn btn-primary' - = link_to 'Delete', admin_organization_path(organization), - method: :delete, class: 'btn btn-danger', data: { confirm: "Warning: This will delete #{organization.name} and all its data which includes data for all conferences within #{organization.name}. Do you really want to continue?" } +.row + .col-md-12 + %table.table.table-hover.datatable + %thead + %th Name + %th Upcoming Conferences + %th Past Conferences + %th Actions + %tbody + - @organizations.each do |organization| + %tr + %td + = organization.name + %td + = organization.conferences.count + %td + = organization.conferences.count + %td + .btn-group + = link_to 'Edit', edit_admin_organization_path(organization), + method: :get, class: 'btn btn-primary' + = link_to 'Delete', admin_organization_path(organization), + method: :delete, class: 'btn btn-danger', data: { confirm: "Warning: This will delete #{organization.name} and all its data which includes data for all conferences within #{organization.name}. Do you really want to continue?" } From d160c22a0b995a14e1e6cebbeb8344d295f6ad0b Mon Sep 17 00:00:00 2001 From: Dimitris Date: Thu, 15 Jun 2017 23:04:28 +0300 Subject: [PATCH 111/185] Enable rails/findEach Rubocop cop This cop enforce the use of `find_each` instead of `each`. Closes #1535 --- .rubocop.yml | 4 ++++ .rubocop_todo.yml | 8 -------- app/models/conference.rb | 2 +- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 5cc5d541..f722ba55 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -196,6 +196,10 @@ Lint/DuplicatedKey: Rails: Enabled: true +# Use `find_each` instead of `each`. +Rails/FindEach: + Enabled: true + # Avoid use of old-style attribute validation Rails/Validation: Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 928205b0..ef9bcd98 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -154,14 +154,6 @@ Rails/FindBy: - 'app/models/ticket_purchase.rb' - 'app/models/user.rb' -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: Include. -# Include: app/models/**/*.rb -Rails/FindEach: - Exclude: - - 'app/models/conference.rb' - # Offense count: 7 # Configuration parameters: Include. # Include: app/models/**/*.rb diff --git a/app/models/conference.rb b/app/models/conference.rb index f58c50ed..04fe1b52 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -643,7 +643,7 @@ class Conference < ActiveRecord::Base def self.write_event_distribution_to_db week = DateTime.now.end_of_week - Conference.where('end_date > ?', Date.today).each do |conference| + Conference.where('end_date > ?', Date.today).find_each do |conference| result = {} Event.state_machine.states.each do |state| count = conference.program.events.where('state = ?', state.name).count From 1c38b091cc3e3093a9f34bd1f06a51178f461722 Mon Sep 17 00:00:00 2001 From: Eugene Dubinin Date: Thu, 15 Jun 2017 18:11:43 +0300 Subject: [PATCH 112/185] Fixes for PostreSQL support --- Gemfile | 2 + app/models/conference.rb | 15 +++--- .../admin/reports/_missing_speakers.html.haml | 2 +- app/views/admin/reports/index.html.haml | 2 +- db/schema.rb | 51 ++++++++++--------- 5 files changed, 39 insertions(+), 33 deletions(-) diff --git a/Gemfile b/Gemfile index 76c49ce3..15b295fa 100644 --- a/Gemfile +++ b/Gemfile @@ -18,7 +18,9 @@ gem 'rails_12factor', group: :production gem 'responders', '~> 2.0' # as the database for Active Record +# choose only one gem 'mysql2' +#gem 'pg' # for observing records gem 'rails-observers' diff --git a/app/models/conference.rb b/app/models/conference.rb index 04fe1b52..0cf16de6 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -131,7 +131,7 @@ class Conference < ActiveRecord::Base result = [] if program && program.cfp && program.events - submissions = program.events.group(:week).count + submissions = program.events.select(:week).group(:week).order(:week).count start_week = program.cfp.start_week weeks = program.cfp.weeks result = calculate_items_per_week(start_week, weeks, submissions) @@ -179,7 +179,7 @@ class Conference < ActiveRecord::Base registration_period.start_date && registration_period.end_date - reg = registrations.group(:week).count + reg = registrations.group(:week).order(:week).count start_week = get_registration_start_week weeks = registration_weeks result = calculate_items_per_week(start_week, weeks, reg) @@ -337,8 +337,8 @@ class Conference < ActiveRecord::Base # ====Returns # * +hash+ -> user: submissions def self.get_top_submitter(limit = 5) - submitter = EventUser.where('event_role = ?', 'submitter').limit(limit).group(:user_id) - counter = submitter.order('count_all desc').count + submitter = EventUser.select(:user_id).where('event_role = ?', 'submitter').limit(limit).group(:user_id) + counter = submitter.order('count_all desc').count(:all) calculate_user_submission_hash(submitter, counter) end @@ -348,10 +348,10 @@ class Conference < ActiveRecord::Base # ====Returns # * +hash+ -> user: submissions def get_top_submitter(limit = 5) - submitter = EventUser.joins(:event) + submitter = EventUser.joins(:event).select(:user_id) .where('event_role = ? and program_id = ?', 'submitter', Conference.find(id).program.id) .limit(limit).group(:user_id) - counter = submitter.order('count_all desc').count + counter = submitter.order('count_all desc').count(:all) Conference.calculate_user_submission_hash(submitter, counter) end @@ -1100,7 +1100,8 @@ class Conference < ActiveRecord::Base def self.calculate_user_submission_hash(submitters, counter) result = ActiveSupport::OrderedHash.new counter.each do |key, value| - submitter = submitters.where(user_id: key).first + # make PG happy by including the user_id in ORDER + submitter = submitters.where(user_id: key).order(:user_id).first if submitter result[submitter.user] = value end diff --git a/app/views/admin/reports/_missing_speakers.html.haml b/app/views/admin/reports/_missing_speakers.html.haml index b269eef6..bc1769ae 100644 --- a/app/views/admin/reports/_missing_speakers.html.haml +++ b/app/views/admin/reports/_missing_speakers.html.haml @@ -3,7 +3,7 @@ .page-header %h1 Missing Speakers - = "(#{@missing_event_speakers.group(:user_id).length})" + = "(#{@missing_event_speakers.distinct(:user_id).length})" %p.text-muted All event speakers who haven't checked in .col-md-12 diff --git a/app/views/admin/reports/index.html.haml b/app/views/admin/reports/index.html.haml index 704ffdaa..6bbb8886 100644 --- a/app/views/admin/reports/index.html.haml +++ b/app/views/admin/reports/index.html.haml @@ -17,7 +17,7 @@ %a{href: '#missing-speakers', 'data-toggle' => 'tab'} Missing Speakers %span.label.label-danger{style: 'border-radius: 1em;'} - = @missing_event_speakers.group(:user_id).length + = @missing_event_speakers.distinct(:user_id).length .tab-content #all.tab-pane.active diff --git a/db/schema.rb b/db/schema.rb index 9772066a..547d5858 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -13,17 +13,20 @@ ActiveRecord::Schema.define(version: 20170531094819) do + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + create_table "ahoy_events", force: :cascade do |t| - t.uuid "visit_id", limit: 16 + t.integer "visit_id" t.integer "user_id" t.string "name" t.text "properties" t.datetime "time" end - add_index "ahoy_events", ["time"], name: "index_ahoy_events_on_time" - add_index "ahoy_events", ["user_id"], name: "index_ahoy_events_on_user_id" - add_index "ahoy_events", ["visit_id"], name: "index_ahoy_events_on_visit_id" + add_index "ahoy_events", ["time"], name: "index_ahoy_events_on_time", using: :btree + add_index "ahoy_events", ["user_id"], name: "index_ahoy_events_on_user_id", using: :btree + add_index "ahoy_events", ["visit_id"], name: "index_ahoy_events_on_visit_id", using: :btree create_table "answers", force: :cascade do |t| t.string "title" @@ -65,9 +68,9 @@ ActiveRecord::Schema.define(version: 20170531094819) do t.integer "rgt" end - add_index "comments", ["commentable_id"], name: "index_comments_on_commentable_id" - add_index "comments", ["commentable_type"], name: "index_comments_on_commentable_type" - add_index "comments", ["user_id"], name: "index_comments_on_user_id" + add_index "comments", ["commentable_id"], name: "index_comments_on_commentable_id", using: :btree + add_index "comments", ["commentable_type"], name: "index_comments_on_commentable_type", using: :btree + add_index "comments", ["user_id"], name: "index_comments_on_user_id", using: :btree create_table "commercials", force: :cascade do |t| t.string "commercial_id" @@ -137,7 +140,7 @@ ActiveRecord::Schema.define(version: 20170531094819) do t.datetime "updated_at" end - add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority" + add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority", using: :btree create_table "difficulty_levels", force: :cascade do |t| t.string "title" @@ -190,10 +193,10 @@ ActiveRecord::Schema.define(version: 20170531094819) do t.datetime "updated_at", null: false end - add_index "event_schedules", ["event_id", "schedule_id"], name: "index_event_schedules_on_event_id_and_schedule_id", unique: true - add_index "event_schedules", ["event_id"], name: "index_event_schedules_on_event_id" - add_index "event_schedules", ["room_id"], name: "index_event_schedules_on_room_id" - add_index "event_schedules", ["schedule_id"], name: "index_event_schedules_on_schedule_id" + add_index "event_schedules", ["event_id", "schedule_id"], name: "index_event_schedules_on_event_id_and_schedule_id", unique: true, using: :btree + add_index "event_schedules", ["event_id"], name: "index_event_schedules_on_event_id", using: :btree + add_index "event_schedules", ["room_id"], name: "index_event_schedules_on_room_id", using: :btree + add_index "event_schedules", ["schedule_id"], name: "index_event_schedules_on_schedule_id", using: :btree create_table "event_types", force: :cascade do |t| t.string "title", null: false @@ -301,7 +304,7 @@ ActiveRecord::Schema.define(version: 20170531094819) do t.integer "schedule_interval", default: 15, null: false end - add_index "programs", ["selected_schedule_id"], name: "index_programs_on_selected_schedule_id" + add_index "programs", ["selected_schedule_id"], name: "index_programs_on_selected_schedule_id", using: :btree create_table "qanswers", force: :cascade do |t| t.integer "question_id" @@ -373,8 +376,8 @@ ActiveRecord::Schema.define(version: 20170531094819) do t.string "resource_type" end - add_index "roles", ["name", "resource_type", "resource_id"], name: "index_roles_on_name_and_resource_type_and_resource_id" - add_index "roles", ["name"], name: "index_roles_on_name" + add_index "roles", ["name", "resource_type", "resource_id"], name: "index_roles_on_name_and_resource_type_and_resource_id", using: :btree + add_index "roles", ["name"], name: "index_roles_on_name", using: :btree create_table "rooms", force: :cascade do |t| t.string "guid", null: false @@ -389,7 +392,7 @@ ActiveRecord::Schema.define(version: 20170531094819) do t.datetime "updated_at", null: false end - add_index "schedules", ["program_id"], name: "index_schedules_on_program_id" + add_index "schedules", ["program_id"], name: "index_schedules_on_program_id", using: :btree create_table "splashpages", force: :cascade do |t| t.integer "conference_id" @@ -512,17 +515,17 @@ ActiveRecord::Schema.define(version: 20170531094819) do t.boolean "is_disabled", default: false end - add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true - add_index "users", ["email"], name: "index_users_on_email", unique: true - add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true - add_index "users", ["username"], name: "index_users_on_username", unique: true + add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree + add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree + add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree + add_index "users", ["username"], name: "index_users_on_username", unique: true, using: :btree create_table "users_roles", force: :cascade do |t| t.integer "role_id" t.integer "user_id" end - add_index "users_roles", ["user_id", "role_id"], name: "index_users_roles_on_user_id_and_role_id" + add_index "users_roles", ["user_id", "role_id"], name: "index_users_roles_on_user_id_and_role_id", using: :btree create_table "vchoices", force: :cascade do |t| t.integer "vday_id" @@ -566,10 +569,10 @@ ActiveRecord::Schema.define(version: 20170531094819) do t.integer "conference_id" end - add_index "versions", ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id" + add_index "versions", ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id", using: :btree create_table "visits", force: :cascade do |t| - t.uuid "visitor_id", limit: 16 + t.uuid "visitor_id" t.string "ip" t.text "user_agent" t.text "referrer" @@ -591,7 +594,7 @@ ActiveRecord::Schema.define(version: 20170531094819) do t.datetime "started_at" end - add_index "visits", ["user_id"], name: "index_visits_on_user_id" + add_index "visits", ["user_id"], name: "index_visits_on_user_id", using: :btree create_table "votes", force: :cascade do |t| t.integer "event_id" From 5c56683ae8b7a66e47b6f7f5d9dbe587e73fa936 Mon Sep 17 00:00:00 2001 From: Siddhant Bajaj Date: Sat, 3 Jun 2017 16:05:59 +0530 Subject: [PATCH 113/185] Introduced Physical Ticket Added PhysicalTicket model and controller. It holds the information about each physical ticket bought at the purchase. Physical Tickets are created after every successfull payment. --- Gemfile | 2 +- app/controllers/payments_controller.rb | 6 ++-- app/controllers/physical_ticket_controller.rb | 12 +++++++ .../ticket_purchases_controller.rb | 2 +- app/models/ability.rb | 1 + app/models/conference.rb | 1 + app/models/physical_ticket.rb | 6 ++++ app/models/ticket_purchase.rb | 13 +++++-- app/models/user.rb | 5 +++ .../conferences/_conference_details.html.haml | 2 ++ app/views/physical_ticket/index.html.haml | 35 +++++++++++++++++++ app/views/physical_ticket/show.html.haml | 0 config/routes.rb | 1 + .../20170603095900_create_physical_tickets.rb | 9 +++++ db/schema.rb | 8 ++++- spec/features/ticket_purchases_spec.rb | 4 +-- spec/models/ticket_purchase_spec.rb | 20 +++++++++-- 17 files changed, 115 insertions(+), 12 deletions(-) create mode 100644 app/controllers/physical_ticket_controller.rb create mode 100644 app/models/physical_ticket.rb create mode 100644 app/views/physical_ticket/index.html.haml create mode 100644 app/views/physical_ticket/show.html.haml create mode 100644 db/migrate/20170603095900_create_physical_tickets.rb diff --git a/Gemfile b/Gemfile index 15b295fa..245080c3 100644 --- a/Gemfile +++ b/Gemfile @@ -20,7 +20,7 @@ gem 'responders', '~> 2.0' # as the database for Active Record # choose only one gem 'mysql2' -#gem 'pg' +# gem 'pg' # for observing records gem 'rails-observers' diff --git a/app/controllers/payments_controller.rb b/app/controllers/payments_controller.rb index e8766548..b5e2c193 100644 --- a/app/controllers/payments_controller.rb +++ b/app/controllers/payments_controller.rb @@ -18,7 +18,7 @@ class PaymentsController < ApplicationController if @payment.purchase && @payment.save update_purchased_ticket_purchases - redirect_to conference_conference_registration_path(@conference.short_title), + redirect_to conference_physical_ticket_index_path, notice: 'Thanks! Your ticket is booked successfully.' else @total_amount_to_pay = Ticket.total_price(@conference, current_user, paid: false) @@ -38,6 +38,8 @@ class PaymentsController < ApplicationController end def update_purchased_ticket_purchases - current_user.ticket_purchases.by_conference(@conference).unpaid.update_all(paid: true, payment_id: @payment.id) + current_user.ticket_purchases.by_conference(@conference).unpaid.each do |ticket_purchase| + ticket_purchase.pay(@payment) + end end end diff --git a/app/controllers/physical_ticket_controller.rb b/app/controllers/physical_ticket_controller.rb new file mode 100644 index 00000000..2354f279 --- /dev/null +++ b/app/controllers/physical_ticket_controller.rb @@ -0,0 +1,12 @@ +class PhysicalTicketController < ApplicationController + before_action :authenticate_user! + load_resource :conference, find_by: :short_title + load_and_authorize_resource + authorize_resource :conference_registrations, class: Registration + + def index + @physical_tickets = current_user.physical_tickets.by_conference(@conference) + end + + def show; end +end diff --git a/app/controllers/ticket_purchases_controller.rb b/app/controllers/ticket_purchases_controller.rb index 1c672d69..3945e154 100644 --- a/app/controllers/ticket_purchases_controller.rb +++ b/app/controllers/ticket_purchases_controller.rb @@ -11,7 +11,7 @@ class TicketPurchasesController < ApplicationController redirect_to new_conference_payment_path, notice: 'Please pay here to get tickets.' elsif current_user.ticket_purchases.by_conference(@conference).paid.any? - redirect_to conference_conference_registration_path(@conference.short_title), + redirect_to conference_physical_ticket_index_path, notice: 'You have free tickets for the conference.' else redirect_to conference_tickets_path(@conference.short_title), diff --git a/app/models/ability.rb b/app/models/ability.rb index cc23a631..bdf554cc 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -87,6 +87,7 @@ class Ability can :index, Ticket can :manage, TicketPurchase, user_id: user.id can [:new, :create], Payment, user_id: user.id + can [:index, :show], PhysicalTicket, user_id: user.id can [:create, :destroy], Subscription, user_id: user.id diff --git a/app/models/conference.rb b/app/models/conference.rb index 0cf16de6..11fab753 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -19,6 +19,7 @@ class Conference < ActiveRecord::Base has_one :email_settings, dependent: :destroy has_one :program, dependent: :destroy has_one :venue, dependent: :destroy + has_many :physical_tickets, through: :ticket_purchases has_many :ticket_purchases, dependent: :destroy has_many :payments, dependent: :destroy has_many :supporters, through: :ticket_purchases, source: :user diff --git a/app/models/physical_ticket.rb b/app/models/physical_ticket.rb new file mode 100644 index 00000000..a0874a6e --- /dev/null +++ b/app/models/physical_ticket.rb @@ -0,0 +1,6 @@ +class PhysicalTicket < ActiveRecord::Base + belongs_to :ticket_purchase + has_one :ticket, through: :ticket_purchase + has_one :conference, through: :ticket_purchase + has_one :user, through: :ticket_purchase +end diff --git a/app/models/ticket_purchase.rb b/app/models/ticket_purchase.rb index d1c370c4..675527ae 100644 --- a/app/models/ticket_purchase.rb +++ b/app/models/ticket_purchase.rb @@ -13,6 +13,8 @@ class TicketPurchase < ActiveRecord::Base delegate :price_cents, to: :ticket delegate :price_currency, to: :ticket + has_many :physical_tickets + scope :paid, -> { where(paid: true) } scope :unpaid, -> { where(paid: false) } scope :by_conference, ->(conference) { where(conference_id: conference.id) } @@ -45,8 +47,8 @@ class TicketPurchase < ActiveRecord::Base purchase = new(ticket_id: ticket.id, conference_id: conference.id, user_id: user.id, - quantity: quantity, - paid: ticket.price_cents.zero?) + quantity: quantity) + purchase.pay(nil) if ticket.price_cents.zero? end purchase end @@ -60,6 +62,13 @@ class TicketPurchase < ActiveRecord::Base purchase.quantity = quantity if quantity > 0 purchase end + + def pay(payment) + update_attributes(paid: true, payment: payment) + PhysicalTicket.transaction do + quantity.times { physical_tickets.create } + end + end end private diff --git a/app/models/user.rb b/app/models/user.rb index 4be77fe8..6ffb739f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -6,6 +6,11 @@ end class User < ActiveRecord::Base rolify + has_many :physical_tickets, through: :ticket_purchases do + def by_conference(conference) + where('ticket_purchases.conference_id = ?', conference) + end + end has_many :users_roles has_many :roles, through: :users_roles, dependent: :destroy diff --git a/app/views/conferences/_conference_details.html.haml b/app/views/conferences/_conference_details.html.haml index bdbd5fc6..d5bafad4 100644 --- a/app/views/conferences/_conference_details.html.haml +++ b/app/views/conferences/_conference_details.html.haml @@ -38,3 +38,5 @@ = link_to 'Subscribe', conference_subscriptions_path(conference.short_title), method: :post, class: 'btn btn-default' - else = link_to 'Unsubscribe', conference_subscriptions_path(conference.short_title), method: :delete, class: 'btn btn-default' + - if current_user && current_user.physical_tickets.by_conference(conference).any? + = link_to "My Tickets", conference_physical_ticket_index_path(conference.short_title), class: 'btn btn-default' diff --git a/app/views/physical_ticket/index.html.haml b/app/views/physical_ticket/index.html.haml new file mode 100644 index 00000000..ce741c39 --- /dev/null +++ b/app/views/physical_ticket/index.html.haml @@ -0,0 +1,35 @@ +.container + .row + .col-md-12.page-header + %h2 + Tickets + .text-muted + Your tickets for the conference + + .col-md-12 + - if @physical_tickets.present? + %table.table.table-bordered.table-striped.table-hover#roles + %thead + %th ID + %th Type + %th User + %th Actions + %tbody + - @physical_tickets.each do |physical_ticket| + %tr + %td= physical_ticket.id + %td= physical_ticket.ticket.title + %td= physical_ticket.user.name + %td + .btn-group + = link_to 'Show', + conference_physical_ticket_path(@conference.short_title, + physical_ticket.id), + class: 'btn btn-primary' + = link_to 'Generate PDF', + conference_physical_ticket_path(@conference.short_title, + physical_ticket.id, + format: :pdf), + class: 'button btn btn-default btn-info' + - else + %h5 No Tickets found! diff --git a/app/views/physical_ticket/show.html.haml b/app/views/physical_ticket/show.html.haml new file mode 100644 index 00000000..e69de29b diff --git a/config/routes.rb b/config/routes.rb index ccca3511..60b03f54 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -126,6 +126,7 @@ Osem::Application.routes.draw do resources :tickets, only: [:index] resources :ticket_purchases, only: [:create, :destroy] resources :payments, only: [:index, :new, :create] + resources :physical_ticket, only: [:index, :show] resource :subscriptions, only: [:create, :destroy] resource :schedule, only: [:show] do member do diff --git a/db/migrate/20170603095900_create_physical_tickets.rb b/db/migrate/20170603095900_create_physical_tickets.rb new file mode 100644 index 00000000..5e0c1d98 --- /dev/null +++ b/db/migrate/20170603095900_create_physical_tickets.rb @@ -0,0 +1,9 @@ +class CreatePhysicalTickets < ActiveRecord::Migration + def change + create_table :physical_tickets do |t| + t.integer :ticket_purchase_id, null: false + + t.timestamps null: false + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 547d5858..19a3df19 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170531094819) do +ActiveRecord::Schema.define(version: 20170603095900) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -289,6 +289,12 @@ ActiveRecord::Schema.define(version: 20170531094819) do t.datetime "updated_at", null: false end + create_table "physical_tickets", force: :cascade do |t| + t.integer "ticket_purchase_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "programs", force: :cascade do |t| t.integer "conference_id" t.integer "rating", default: 0 diff --git a/spec/features/ticket_purchases_spec.rb b/spec/features/ticket_purchases_spec.rb index f8c755a3..958ae645 100644 --- a/spec/features/ticket_purchases_spec.rb +++ b/spec/features/ticket_purchases_spec.rb @@ -101,12 +101,10 @@ feature Registration do click_button 'Continue' - expect(current_path).to eq(conference_conference_registration_path(conference.short_title)) + expect(current_path).to eq(conference_physical_ticket_index_path(conference.short_title)) purchase = TicketPurchase.where(user_id: participant.id, ticket_id: free_ticket.id).first expect(purchase.quantity).to eq(5) expect(purchase.paid).to be true - - expect(page.has_content?("5 #{free_ticket.title} Tickets for $ 0")).to be true end end diff --git a/spec/models/ticket_purchase_spec.rb b/spec/models/ticket_purchase_spec.rb index 0bb33f8e..f11a8187 100644 --- a/spec/models/ticket_purchase_spec.rb +++ b/spec/models/ticket_purchase_spec.rb @@ -34,7 +34,6 @@ describe TicketPurchase do it 'is valid with a quantity greater than zero' do should allow_value(1).for(:quantity) end - end describe 'self#purchase' do @@ -54,7 +53,6 @@ describe TicketPurchase do expect(TicketPurchase.count).to eq(1) expect(purchase.quantity).to eq(10) expect(message.blank?).to be true - end it 'creates a purchase for one ticket' do @@ -116,4 +114,22 @@ describe TicketPurchase do expect(message.blank?).to be true end end + + describe 'after_create' do + let(:ticket_purchase) { create(:ticket_purchase, quantity: 4, paid: true) } + + it 'creates physical tickets equal to the quantity of purchase' do + expect(ticket_purchase.physical_tickets.count).to eq(4) + end + end + + describe 'after_update' do + let(:ticket_purchase) { create(:ticket_purchase, quantity: 5) } + + it 'creates physical tickets if the payment is made successfully' do + ticket_purchase + ticket_purchase.paid = true + expect{ ticket_purchase.save }.to change{ ticket_purchase.physical_tickets.count }.from(0).to(5) + end + end end From d7678b2fa08dfdfc281d694c75d18dc4e1481850 Mon Sep 17 00:00:00 2001 From: Siddhant Bajaj Date: Thu, 8 Jun 2017 03:45:08 +0530 Subject: [PATCH 114/185] Added model test Added test for physical ticket model. --- spec/factories/physical_ticket.rb | 5 +++++ spec/factories/ticket_purchases.rb | 6 ++++++ spec/models/physical_ticket_spec.rb | 14 ++++++++++++++ spec/models/ticket_purchase_spec.rb | 18 ------------------ 4 files changed, 25 insertions(+), 18 deletions(-) create mode 100644 spec/factories/physical_ticket.rb create mode 100644 spec/models/physical_ticket_spec.rb diff --git a/spec/factories/physical_ticket.rb b/spec/factories/physical_ticket.rb new file mode 100644 index 00000000..8b4f2a0e --- /dev/null +++ b/spec/factories/physical_ticket.rb @@ -0,0 +1,5 @@ +FactoryGirl.define do + factory :physical_ticket do + ticket_purchase + end +end diff --git a/spec/factories/ticket_purchases.rb b/spec/factories/ticket_purchases.rb index 82103db3..bee365cf 100644 --- a/spec/factories/ticket_purchases.rb +++ b/spec/factories/ticket_purchases.rb @@ -4,5 +4,11 @@ FactoryGirl.define do conference ticket quantity 10 + factory :paid_ticket_purchase do + after(:build) do |ticket_purchase| + payment = create(:payment) + ticket_purchase.pay(payment) + end + end end end diff --git a/spec/models/physical_ticket_spec.rb b/spec/models/physical_ticket_spec.rb new file mode 100644 index 00000000..9910a4a3 --- /dev/null +++ b/spec/models/physical_ticket_spec.rb @@ -0,0 +1,14 @@ +require 'spec_helper' + +describe PhysicalTicket do + + describe 'association' do + it { is_expected.to belong_to :ticket_purchase } + end + + describe 'validations' do + it 'has a valid factory' do + expect(build(:physical_ticket)).to be_valid + end + end +end diff --git a/spec/models/ticket_purchase_spec.rb b/spec/models/ticket_purchase_spec.rb index f11a8187..3ef9a861 100644 --- a/spec/models/ticket_purchase_spec.rb +++ b/spec/models/ticket_purchase_spec.rb @@ -114,22 +114,4 @@ describe TicketPurchase do expect(message.blank?).to be true end end - - describe 'after_create' do - let(:ticket_purchase) { create(:ticket_purchase, quantity: 4, paid: true) } - - it 'creates physical tickets equal to the quantity of purchase' do - expect(ticket_purchase.physical_tickets.count).to eq(4) - end - end - - describe 'after_update' do - let(:ticket_purchase) { create(:ticket_purchase, quantity: 5) } - - it 'creates physical tickets if the payment is made successfully' do - ticket_purchase - ticket_purchase.paid = true - expect{ ticket_purchase.save }.to change{ ticket_purchase.physical_tickets.count }.from(0).to(5) - end - end end From 02f27dd4bc1cb72267a88bd344eb033d3f38b92f Mon Sep 17 00:00:00 2001 From: siddhantbajaj Date: Thu, 22 Jun 2017 18:14:13 +0530 Subject: [PATCH 115/185] Fixed association between TicketPurchase and Payment Model. One to many association between TicketPurchase model and Payment Model wasn't properly set up. --- app/models/ticket_purchase.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/ticket_purchase.rb b/app/models/ticket_purchase.rb index 675527ae..88e1f4de 100644 --- a/app/models/ticket_purchase.rb +++ b/app/models/ticket_purchase.rb @@ -2,6 +2,7 @@ class TicketPurchase < ActiveRecord::Base belongs_to :ticket belongs_to :user belongs_to :conference + belongs_to :payment validates :ticket_id, :user_id, :conference_id, :quantity, presence: true From 6469ea7da5236562c69642625dfd87f16bb2466f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ana=20Mar=C3=ADa=20Mart=C3=ADnez=20G=C3=B3mez?= Date: Thu, 22 Jun 2017 16:49:52 +0200 Subject: [PATCH 116/185] Remove default configuration from `.rubocop.yml` We had part of the default Rubocop configuration in the `.rubocop.yml` file. It is not needed as it is the default and it also don't make sense, because we only have part of it. That was caused because when enabling a cop we were moving it from `.rubocop_todo.yml` to `.rubocop.yml`, but this is only needed if we overwrite the default configuration. --- .rubocop.yml | 184 --------------------------------------------------- 1 file changed, 184 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index f722ba55..cff7046b 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -13,112 +13,6 @@ AllCops: - 'config/**/*' - 'bin/*' -#################### Style ############################### - -# Align the elements of a hash literal if they span more than one line -Style/AlignHash: - Enabled: true - -# Align the parameters of a method call if they span more than one line -Style/AlignParameters: - Enabled: true - -# Use && instead of and, use || instead of or -Style/AndOr: - Enabled: true - -# Avoid redundunt curly braces when it is obvious that hash is used -Style/BracesAroundHashParameters: - Enabled: true - -# Avoid the use of the case equality operator `===` -Style/CaseEquality: - Enabled: true - -# Use nested module/class definitions instead of compact style -Style/ClassAndModuleChildren: - Enabled: true - -# Checks the . position in multi-line method calls. -Style/DotPosition: - Enabled: true - -# Checks for uses of double negation (!!) to convert something to a boolean value. -Style/DoubleNegation: - Enabled: true - -# Use one empty line between method definitions -Style/EmptyLineBetweenDefs: - Enabled: true - -# There should be only one empty line in designated place -Style/EmptyLines: - Enabled: true - -# Keep a blank line before and after private. -Style/EmptyLinesAroundAccessModifier: - Enabled: true - -# Use hash literal {} instead of Hash.new -Style/EmptyLiteral: - Enabled: true - -# Prefer `each` over `for i` -Style/For: - Enabled: true - -# Use the new Ruby 1.9 hash syntax -Style/HashSyntax: - Enabled: true - EnforcedStyle: ruby19 - -# Checks for uses of if with negated condition. Use unless instead -Style/NegatedIf: - Enabled: true - -# Do not compare with nil. Use .nil? instead -Style/NilComparison: - Enabled: true - -# Checks for redundant uses of self. -Style/RedundantSelf: - Enabled: true - -# Checks that operators have space around them, except for ** which should not have surrounding space. -Style/SpaceAroundOperators: - Enabled: true - -# Checks for spaces inside square brackets. -Style/SpaceInsideBrackets: - Enabled: true - -# This cop enforces the use the shorthand for self-assignment. -Style/SelfAssignment: - Enabled: true - -# Use single quotes unless there's string interpolation -Style/StringLiterals: - Enabled: true - -# This cop checks for tabs where spaces should be used. -Style/Tab: - Enabled: true - -# Avoid trailing blank lines -Style/TrailingBlankLines: - Enabled: true - -# Avoid trailing whitespace -Style/TrailingWhitespace: - Enabled: true - -# Check for array literals made up of word-like strings, that are not using the %w() syntax -Style/WordArray: - Enabled: true - -# This cop checks for numeric comparisons that can be replaced by a predicate method. -Style/ZeroLengthPredicate: - Enabled: true #################### Metrics ############################### @@ -135,81 +29,3 @@ Metrics/ClassLength: Metrics/BlockLength: Exclude: - 'spec/models/conference_spec.rb' - -#################### Lint ############################### - -# Wrap your assignment in condition if you mean it, otherwise it is most likely equality check -Lint/AssignmentInCondition: - Enabled: true - -# Align blocks of code properly -Lint/BlockAlignment: - Enabled: true - -# Things deprecated in current ruby API -Lint/DeprecatedClassMethods: - Enabled: true - -# Do not use literal in conditions. We have it enabled for now -Lint/LiteralInCondition: - Enabled: false - -# Prefer `Kernel#loop -> break` over `begin -> while` -Lint/Loop: - Enabled: true - -# Do not put space before arguments when they are in parentheses -Lint/ParenthesesAsGroupedExpression: - Enabled: true - -# Do not rescue Exceptions class itself -Lint/RescueException: - Enabled: true - -# Do not shadow local variables in blocks, choose other name -Lint/ShadowingOuterLocalVariable: - Enabled: true - -# Use _ or variable_name to explicitly mark variable as unused -Lint/UnusedBlockArgument: - Enabled: true - -# Use _ or _argument_name to explicitly mark argument as unused -Lint/UnusedMethodArgument: - Enabled: true - -# Avoid useless assignment -Lint/UselessAssignment: - Enabled: true - -# Do not use variables in void context -Lint/Void: - Enabled: true - -# Do not use duplicated keys in hash literals. -Lint/DuplicatedKey: - Enabled: true - -#################### Rails ############################### - -# Enforce Rails specific style -Rails: - Enabled: true - -# Use `find_each` instead of `each`. -Rails/FindEach: - Enabled: true - -# Avoid use of old-style attribute validation -Rails/Validation: - Enabled: true - -# Looks for delegations, that could have been created automatically with delegate method -Rails/Delegate: - Enabled: true - -#################### Performance ############################### - -# Identifies places where gsub can be replaced by tr or delete. -Performance/StringReplacement: - Enabled: true From 5378b7524bf9ce0a022354982dc345d231aa2988 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ana=20Mar=C3=ADa=20Mart=C3=ADnez=20G=C3=B3mez?= Date: Thu, 22 Jun 2017 16:55:00 +0200 Subject: [PATCH 117/185] Fix Style/LeadingCommentSpace Rubocop offense Fix Rubocop offense introduced in: https://github.com/openSUSE/osem/pull/1229 --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 15b295fa..245080c3 100644 --- a/Gemfile +++ b/Gemfile @@ -20,7 +20,7 @@ gem 'responders', '~> 2.0' # as the database for Active Record # choose only one gem 'mysql2' -#gem 'pg' +# gem 'pg' # for observing records gem 'rails-observers' From ed1f219b814184a93c2edcf53d9e385995ce9961 Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Sun, 18 Jun 2017 02:57:39 +0300 Subject: [PATCH 118/185] Update Ruby to 2.2 Force development environment to use ruby 2.2 in preparation for the update to Rails 5 --- bootstrap.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bootstrap.sh b/bootstrap.sh index 42766366..8b5e848a 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 ruby-devel make gcc gcc-c++ \ +zypper -q -n install update-alternatives ruby2.2-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 install bundler +gem.ruby2.2 install bundler echo -e "\ninstalling your bundle...\n" su - vagrant -c "cd /vagrant/; bundle install --quiet" From bf7e890739faad7f42b86ec0de9ecb29c7c1a8b4 Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Sun, 18 Jun 2017 02:59:28 +0300 Subject: [PATCH 119/185] Update vagrant box image to openSUSE 42.2 And fix dependencies --- Vagrantfile | 2 +- bootstrap.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Vagrantfile b/Vagrantfile index e2faad9d..bf3622e4 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -12,7 +12,7 @@ Vagrant.configure(2) do |config| # Every Vagrant development environment requires a box. You can search for # boxes at https://atlas.hashicorp.com/search. - config.vm.box = "opensuse/openSUSE-42.1-x86_64" + config.vm.box = "opensuse/openSUSE-42.2-x86_64" # Disable automatic box update checking. If you disable this, then # boxes will only be checked for updates when the user runs diff --git a/bootstrap.sh b/bootstrap.sh index 8b5e848a..503d1bbf 100644 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -4,7 +4,7 @@ pushd /vagrant echo -e "\ninstalling required software packages...\n" zypper -q -n install update-alternatives ruby2.2-devel make gcc gcc-c++ \ libxml2-devel libxslt-devel nodejs screen mariadb \ - libmysqld-devel sqlite3-devel imagemagick + libmysqld-devel sqlite3-devel ImageMagick echo -e "\ndisabling versioned gem binary names...\n" echo 'install: --no-format-executable' >> /etc/gemrc From a925ceac3589a0e8d1a65f53c1bca52c04463897 Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Mon, 19 Jun 2017 14:41:52 +0300 Subject: [PATCH 120/185] Fix typo in bootstrap.sh --- bootstrap.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap.sh b/bootstrap.sh index 503d1bbf..197b6be2 100644 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -26,7 +26,7 @@ if [ ! -f /vagrant/config/database.yml ] && [ -f /vagrant/config/database.yml.ex echo -e "WARNING: Please make sure this database works in this vagrant box!\n\n" fi else - echo -e "\nnWARNING: You have already configured your database in config/database.yml." + echo -e "\n\nWARNING: You have already configured your database in config/database.yml." echo -e "WARNING: Please make sure this configuration works in this vagrant box!\n\n" fi From 905f8954d05b344cf885990fd4009ae6e0ca1d85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ana=20Mar=C3=ADa=20Mart=C3=ADnez=20G=C3=B3mez?= Date: Sat, 17 Jun 2017 20:32:57 +0200 Subject: [PATCH 121/185] Fix broken test in Admin::EventsController We are using `paper_trail` gem, which saves data in database table versions. It has a native way to search in the versions records, using `where_object()` and `where_object_changes()`. They are broken, under certain conditions. We changed them to a manual `where()`. To test this case we need: an Event with ID 1, an Event with ID 2, and a commercial with ID 1, for event with ID 2 - obviously the numbers could be different as long as there is this matching of IDs. Before this was made wit ha expect, which would make the test fail if this is not the case. But this is actually the test case, not what we want to test, so I moved to the `let`. This was also the case why one of the test was broken after we change how the database is cleaned in: https://github.com/openSUSE/osem/pull/1541 I also remove the feature test, as this should be tested in a controller test. --- spec/controllers/admin/events_controller_spec.rb | 12 +++++++----- spec/features/versions_spec.rb | 2 -- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/spec/controllers/admin/events_controller_spec.rb b/spec/controllers/admin/events_controller_spec.rb index a413ba7a..682defce 100644 --- a/spec/controllers/admin/events_controller_spec.rb +++ b/spec/controllers/admin/events_controller_spec.rb @@ -4,9 +4,13 @@ describe Admin::EventsController do let(:conference) { create(:conference) } let(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let(:organizer) { create(:user, role_ids: organizer_role.id) } - let!(:event_without_commercial) { create(:event, program: conference.program) } - let!(:event_with_commercial) { create(:event, program: conference.program) } - let!(:event_commercial) { create(:event_commercial, commercialable: event_with_commercial, url: 'https://www.youtube.com/watch?v=M9bq_alk-sw') } + # The where_object() and where_object_changes() methods of paper_trail gem are broken when having: + # an Event with ID 1, an Event with ID 2, and a commercial with ID 1, for event with ID 2 + # (the numbers could be different as long as there is this matching of IDs). + # We implemented or own where method to solve this and those ids are for testing this case. + let!(:event_without_commercial) { create(:event, id: 1, program: conference.program) } + let!(:event_with_commercial) { create(:event, id: 2, program: conference.program) } + let!(:event_commercial) { create(:event_commercial, id: 1, commercialable: event_with_commercial, url: 'https://www.youtube.com/watch?v=M9bq_alk-sw') } with_versioning do describe 'GET #show' do @@ -17,8 +21,6 @@ describe Admin::EventsController do it 'assigns versions' do versions = event_without_commercial.versions - expect(event_without_commercial.id).to eq event_commercial.id - expect(event_commercial.id).not_to eq event_commercial.commercialable_id expect(assigns(:versions)).to eq versions end end diff --git a/spec/features/versions_spec.rb b/spec/features/versions_spec.rb index ff73eee0..90c0fa35 100644 --- a/spec/features/versions_spec.rb +++ b/spec/features/versions_spec.rb @@ -286,8 +286,6 @@ feature 'Version' do expect(page).to have_text('Someone (probably via the console) created new commercial') visit admin_conference_program_event_path(conference.short_title, event_without_commercial) click_link 'History' - expect(event_commercial.id).not_to eq event_commercial.commercialable_id - expect(event_without_commercial.id).to eq event_commercial.id expect(page).to have_no_text('Someone (probably via the console) created new commercial') end From 267f080ac77e6df04092676df1e148baffffa6f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ana=20Mar=C3=ADa=20Mart=C3=ADnez=20G=C3=B3mez?= Date: Mon, 26 Jun 2017 16:47:07 +0200 Subject: [PATCH 122/185] Enable Style/CommentAnnotation Rubocop cop This cop checks that comment annotation keywords are written according to guidelines. The offense was automatically corrected. --- .rubocop_todo.yml | 8 -------- app/models/event_user.rb | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index ef9bcd98..56ff7885 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -288,14 +288,6 @@ Style/ColonMethodCall: - 'app/models/commercial.rb' - 'app/models/contact.rb' -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: Keywords. -# Keywords: TODO, FIXME, OPTIMIZE, HACK, REVIEW -Style/CommentAnnotation: - Exclude: - - 'app/models/event_user.rb' - # Offense count: 14 # Cop supports --auto-correct. Style/CommentIndentation: diff --git a/app/models/event_user.rb b/app/models/event_user.rb index 58adadad..70d9ca91 100644 --- a/app/models/event_user.rb +++ b/app/models/event_user.rb @@ -1,5 +1,5 @@ class EventUser < ActiveRecord::Base - # TODO Do we need these roles? + # TODO: Do we need these roles? ROLES = [%w[Speaker speaker], %w[Submitter submitter], %w[Moderator moderator]] belongs_to :event From 7fd738bc7d7bd5d2667b9163c78472a7486310fb Mon Sep 17 00:00:00 2001 From: Dimitris Date: Fri, 16 Jun 2017 02:51:01 +0300 Subject: [PATCH 123/185] Add option to render html at format_helper --- app/helpers/format_helper.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/helpers/format_helper.rb b/app/helpers/format_helper.rb index bd64e3ac..472edc38 100644 --- a/app/helpers/format_helper.rb +++ b/app/helpers/format_helper.rb @@ -176,7 +176,7 @@ module FormatHelper (schedule == @selected_schedule) ? 'Yes' : 'No' end - def markdown(text) + def markdown(text, escape_html=true) return '' if text.nil? options = { @@ -184,12 +184,12 @@ module FormatHelper space_after_headers: true, no_intra_emphasis: true } - markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new(escape_html: true), options) + markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new(escape_html: escape_html), options) markdown.render(text).html_safe end def markdown_hint(text='') - markdown("#{text} Please look at #{link_to '**Markdown Syntax**', 'https://daringfireball.net/projects/markdown/syntax', target: '_blank'} to format your text") + markdown("#{text} Please look at #{link_to '**Markdown Syntax**', 'https://daringfireball.net/projects/markdown/syntax', target: '_blank'} to format your text", false) end def quantity_left_of(resource) From c3eb178546fe341b1fa1ad62b9362d79296cb06b Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Tue, 30 May 2017 20:54:48 +0300 Subject: [PATCH 124/185] Modify CFP to accept proposals for other things Add field cfp_type and relevant validations Add Program#cfp to preserve backwards compatibility Add 'for_events' scope to the cfp, in order for it to be used like program.cfps.events Add useful methods Add rspec test for the new code The supported cfp types can be viewed via Cfp::TYPES --- .rubocop_todo.yml | 1 + app/controllers/admin/cfps_controller.rb | 3 +- app/models/cfp.rb | 23 ++++++++++ app/models/program.rb | 21 +++++++++- db/migrate/20170530072155_add_type_to_cfps.rb | 15 +++++++ db/schema.rb | 1 + spec/models/cfp_spec.rb | 42 ++++++++++++++++++- spec/models/program_spec.rb | 19 +++++++++ 8 files changed, 120 insertions(+), 5 deletions(-) create mode 100644 db/migrate/20170530072155_add_type_to_cfps.rb diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 56ff7885..68360907 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -645,6 +645,7 @@ Style/PercentLiteralDelimiters: - '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' diff --git a/app/controllers/admin/cfps_controller.rb b/app/controllers/admin/cfps_controller.rb index 42d10218..81fd78a9 100644 --- a/app/controllers/admin/cfps_controller.rb +++ b/app/controllers/admin/cfps_controller.rb @@ -2,7 +2,7 @@ module Admin class CfpsController < Admin::BaseController load_and_authorize_resource :conference, find_by: :short_title load_and_authorize_resource :program, through: :conference, singleton: true - load_and_authorize_resource through: :program, singleton: true + load_and_authorize_resource through: :program def show; end @@ -27,7 +27,6 @@ module Admin end def update - @cfp = @program.cfp @cfp.assign_attributes(cfp_params) send_mail_on_cfp_dates_updates = @cfp.notify_on_cfp_date_update? diff --git a/app/models/cfp.rb b/app/models/cfp.rb index affcc408..92058e87 100644 --- a/app/models/cfp.rb +++ b/app/models/cfp.rb @@ -1,6 +1,10 @@ # cannot delete program if there are events submitted class Cfp < ActiveRecord::Base + TYPES = %w(events).freeze + + scope :for_events, (-> { find_by(cfp_type: 'events') }) + has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id } belongs_to :program @@ -8,6 +12,15 @@ class Cfp < ActiveRecord::Base validates :start_date, :end_date, presence: true validate :before_end_of_conference validate :start_after_end_date + validates :cfp_type, + presence: true, + inclusion: { + in: TYPES + }, + uniqueness: { + scope: :program, + case_sensitive: false + } ## # Checks whether cfp date is updated @@ -55,6 +68,16 @@ class Cfp < ActiveRecord::Base result > 0 ? result : 0 end + ## + # Checks if the call for papers is currently open + # + # ====Returns + # * +false+ -> If the CFP is not set or today isn't in the CFP period. + # * +true+ -> If today is in the CFP period. + def open? + (start_date..end_date).cover?(Date.current) + end + private def before_end_of_conference diff --git a/app/models/program.rb b/app/models/program.rb index e36d65bf..09bb3627 100644 --- a/app/models/program.rb +++ b/app/models/program.rb @@ -5,7 +5,7 @@ class Program < ActiveRecord::Base belongs_to :conference - has_one :cfp, dependent: :destroy + has_many :cfps, dependent: :destroy has_many :event_types, dependent: :destroy has_many :tracks, dependent: :destroy has_many :difficulty_levels, dependent: :destroy @@ -135,7 +135,7 @@ class Program < ActiveRecord::Base # * +false+ -> If the CFP is not set or today isn't in the CFP period. # * +true+ -> If today is in the CFP period. def cfp_open? - cfp = self.cfp + cfp = cfps.events cfp.present? && (cfp.start_date..cfp.end_date).cover?(Date.current) end @@ -163,6 +163,23 @@ class Program < ActiveRecord::Base EventSchedule.where(schedule: selected_schedule).where(start_time: parsed_date..(parsed_date + 1)).any? end + ## + # Provides backwards compatibility for when the program had one cfp + # + # ====Returns + # * +ActiveRecord+ -> The program's cfp with cfp_type == 'events' + def cfp + return nil if cfps.for_events.blank? + cfps.for_events + end + + ## + # ====Returns + # * +Array+ -> The types of cfps for which a cfp doesn't exist yet + def remaining_cfp_types + Cfp::TYPES - cfps.pluck(:cfp_type) + end + private ## diff --git a/db/migrate/20170530072155_add_type_to_cfps.rb b/db/migrate/20170530072155_add_type_to_cfps.rb new file mode 100644 index 00000000..50423281 --- /dev/null +++ b/db/migrate/20170530072155_add_type_to_cfps.rb @@ -0,0 +1,15 @@ +class AddTypeToCfps < ActiveRecord::Migration + class TmpCfp < ActiveRecord::Base + self.table_name = 'cfps' + end + + def change + add_column :cfps, :cfp_type, :string + + TmpCfp.reset_column_information + TmpCfp.find_each do |cfp| + cfp.cfp_type = 'events' + cfp.save! + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 19a3df19..348f6170 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -52,6 +52,7 @@ ActiveRecord::Schema.define(version: 20170603095900) do t.datetime "created_at" t.datetime "updated_at" t.integer "program_id" + t.string "cfp_type" end create_table "comments", force: :cascade do |t| diff --git a/spec/models/cfp_spec.rb b/spec/models/cfp_spec.rb index 3f8e7a0f..606f5f9f 100644 --- a/spec/models/cfp_spec.rb +++ b/spec/models/cfp_spec.rb @@ -1,8 +1,24 @@ require 'spec_helper' describe Cfp do + subject { create(:cfp) } let!(:conference) { create(:conference, end_date: Date.today) } - let!(:cfp) { build(:cfp, start_date: Date.today - 2, end_date: Date.today - 1, program_id: conference.program.id) } + let!(:cfp) { create(:cfp, start_date: Date.today - 2, end_date: Date.today - 1, program_id: conference.program.id) } + + describe 'scope' do + describe '#for_events' do + it 'returns the cfp for events' do + expect(conference.program.cfps.for_events).to be_a Cfp + expect(conference.program.cfps.for_events.cfp_type).to eq('events') + end + end + end + + describe 'validations' do + it { is_expected.to validate_presence_of(:cfp_type) } + it { is_expected.to validate_inclusion_of(:cfp_type).in_array(Cfp::TYPES) } + it { is_expected.to validate_uniqueness_of(:cfp_type).scoped_to(:program_id).case_insensitive } + end describe '#before_end_of_conference' do describe 'fails to save cfp' do @@ -97,4 +113,28 @@ describe Cfp do end end end + + describe '#open?' do + context 'returns false' do + it 'when start and end dates are in the past' do + cfp.start_date = Date.current - 3 + cfp.end_date = Date.current - 1 + expect(cfp.open?).to eq(false) + end + + it 'when start and end dates are in the future' do + cfp.start_date = Date.current + 1 + cfp.end_date = Date.current + 3 + expect(cfp.open?).to eq(false) + end + end + + context 'returns true' do + it 'when start date is in the past and end date is in the future' do + cfp.start_date = Date.current - 1 + cfp.end_date = Date.current + 1 + expect(cfp.open?).to eq(true) + end + end + end end diff --git a/spec/models/program_spec.rb b/spec/models/program_spec.rb index a2106791..6ea62cf0 100644 --- a/spec/models/program_spec.rb +++ b/spec/models/program_spec.rb @@ -240,4 +240,23 @@ describe Program do end end + describe '#cfp' do + it 'returns the cfp for events' do + create(:cfp, cfp_type: 'events', program: program, end_date: Date.current + 1) + expect(program.cfp).to be_a Cfp + expect(program.cfp.cfp_type).to eq('events') + end + + it 'returns nil if the program doesn\'t have a cfp' do + expect(program.cfp).to eq(nil) + end + end + + describe '#remaining_cfp_types' do + it 'returns an array with the types for which a cfp doesn\'t exist' do + expect(program.remaining_cfp_types).to eq(Cfp::TYPES) + create(:cfp, cfp_type: 'events', program: program, end_date: Date.current + 1) + expect(program.remaining_cfp_types).to eq([]) + end + end end From 2bff9185563c7f174f5b59be91d87ceca4a4db9f Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Wed, 31 May 2017 21:03:15 +0300 Subject: [PATCH 125/185] Add index view for the cfp and modify existing ones Add cfp_type to the form partial Refactor Cfps#show to use partials for the different cfp types Modify the rest of the view, where the cfp was used --- .haml-lint_todo.yml | 5 +- app/controllers/admin/cfps_controller.rb | 16 ++--- app/views/admin/cfps/_events_cfp.html.haml | 38 ++++++++++++ app/views/admin/cfps/_form.html.haml | 3 +- app/views/admin/cfps/index.html.haml | 36 +++++++++++ app/views/admin/cfps/show.html.haml | 62 +++---------------- .../admin/conferences/_todo_list.html.haml | 2 +- .../versions/_object_desc_and_link.html.haml | 6 +- app/views/layouts/_admin_sidebar.html.haml | 4 +- config/routes.rb | 2 +- 10 files changed, 107 insertions(+), 67 deletions(-) create mode 100644 app/views/admin/cfps/_events_cfp.html.haml create mode 100644 app/views/admin/cfps/index.html.haml diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index 918178e2..0f6f5408 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -171,6 +171,7 @@ linters: - "app/views/tickets/index.html.haml" - "app/views/users/edit.html.haml" - "app/views/users/show.html.haml" + - "app/views/admin/cfps/index.html.haml" # Offense count: 223 InstanceVariables: @@ -229,6 +230,7 @@ linters: - "app/views/schedules/_schedule.html.haml" - "app/views/schedules/_schedule_item.html.haml" - "app/views/schedules/_schedule_tabs.html.haml" + - "app/views/admin/cfps/_events_cfp.html.haml" # Offense count: 32 IdNames: @@ -247,6 +249,7 @@ linters: - "app/views/admin/users/_event_registrations.html.haml" - "app/views/admin/users/show.html.haml" - "app/views/users/edit.html.haml" + - "app/views/admin/cfps/_events_cfp.html.haml" # Offense count: 4 UnnecessaryInterpolation: @@ -423,4 +426,4 @@ linters: exclude: - "app/views/conferences/_gallery.html.haml" - "app/views/layouts/_navigation.html.haml" - - "app/views/schedules/events.html.haml" \ No newline at end of file + - "app/views/schedules/events.html.haml" diff --git a/app/controllers/admin/cfps_controller.rb b/app/controllers/admin/cfps_controller.rb index 81fd78a9..da2723b7 100644 --- a/app/controllers/admin/cfps_controller.rb +++ b/app/controllers/admin/cfps_controller.rb @@ -4,21 +4,23 @@ module Admin load_and_authorize_resource :program, through: :conference, singleton: true load_and_authorize_resource through: :program + def index; end + def show; end def new - @cfp = @program.build_cfp + @cfp = @program.cfps.new end def edit; end def create - @cfp = @program.build_cfp(cfp_params) + @cfp = @program.cfps.new(cfp_params) send_mail_on_cfp_dates_updates = @cfp.notify_on_cfp_date_update? if @cfp.save ConferenceCfpUpdateMailJob.perform_later(@conference) if send_mail_on_cfp_dates_updates - redirect_to admin_conference_program_cfp_path, + redirect_to admin_conference_program_cfps_path, notice: 'Call for papers successfully created.' else flash.now[:error] = "Creating the call for papers failed. #{@cfp.errors.full_messages.join('. ')}." @@ -33,7 +35,7 @@ module Admin if @cfp.update_attributes(cfp_params) ConferenceCfpUpdateMailJob.perform_later(@conference) if send_mail_on_cfp_dates_updates - redirect_to admin_conference_program_cfp_path(@conference.short_title), + redirect_to admin_conference_program_cfps_path(@conference.short_title), notice: 'Call for papers successfully updated.' else flash.now[:error] = "Updating call for papers failed. #{@cfp.errors.to_a.join('. ')}." @@ -43,9 +45,9 @@ module Admin def destroy if @cfp.destroy - redirect_to admin_conference_program_cfp_path, notice: 'Call for Papers was successfully deleted.' + redirect_to admin_conference_program_cfps_path, notice: 'Call for Papers was successfully deleted.' else - redirect_to admin_conference_program_cfp_path, error: 'An error prohibited this Call for Papers from being destroyed: '\ + redirect_to admin_conference_program_cfps_path, error: 'An error prohibited this Call for Papers from being destroyed: '\ "#{@cfp.errors.full_messages.join('. ')}." end end @@ -53,7 +55,7 @@ module Admin private def cfp_params - params.require(:cfp).permit(:start_date, :end_date) + params.require(:cfp).permit(:start_date, :end_date, :cfp_type) end end end diff --git a/app/views/admin/cfps/_events_cfp.html.haml b/app/views/admin/cfps/_events_cfp.html.haml new file mode 100644 index 00000000..51bc2079 --- /dev/null +++ b/app/views/admin/cfps/_events_cfp.html.haml @@ -0,0 +1,38 @@ +%dt + Start Date: +%dd#start_date + = @cfp.start_date.strftime('%A, %B %-d. %Y') +%dt + End Date: +%dd#end_date + = @cfp.end_date.strftime('%A, %B %-d. %Y') +%dt + Days Left: +%dd + = pluralize(@cfp.remaining_days, 'day') +%dt + Event types: +%dd + = event_types(@conference) +%dt + Tracks: +%dd + = tracks(@conference) +%dt + Public Schedule +%dd#schedule_public + - if @program.schedule_public + Yes + - else + No +%dt + Schedule changeable? +%dd#schedule_changes + - if @program.schedule_fluid + Yes + - else + No +%dt + Rating Levels +%dd#rating + = @program.rating diff --git a/app/views/admin/cfps/_form.html.haml b/app/views/admin/cfps/_form.html.haml index e8110406..a02f3a02 100644 --- a/app/views/admin/cfps/_form.html.haml +++ b/app/views/admin/cfps/_form.html.haml @@ -4,8 +4,9 @@ %h1 Call for Papers .row .col-md-8 - = semantic_form_for(@cfp, url: admin_conference_program_cfp_path(@conference.short_title), html: {multipart: true}) do |f| + = semantic_form_for(@cfp, url: (@cfp.new_record? ? admin_conference_program_cfps_path : admin_conference_program_cfp_path(@conference.short_title, @cfp)), html: {multipart: true}) do |f| = f.input :start_date, as: :string, input_html: { id: 'registration-period-start-datepicker', start_date: @conference.start_date, end_date: @conference.end_date, readonly: 'readonly' } = f.input :end_date, as: :string, input_html: { id: 'registration-period-end-datepicker', readonly: 'readonly' } + = f.input :cfp_type, as: :select, collection: (@cfp.new_record? ? @program.remaining_cfp_types : [@cfp.cfp_type] + @program.remaining_cfp_types).map {|type| ["#{type.capitalize}", type]}, include_blank: false, label: 'Type', input_html: { class: 'select-help-toggle' } %p.text-right = f.action :submit, as: :button, button_html: { class: 'btn btn-primary' } diff --git a/app/views/admin/cfps/index.html.haml b/app/views/admin/cfps/index.html.haml new file mode 100644 index 00000000..16ab8e84 --- /dev/null +++ b/app/views/admin/cfps/index.html.haml @@ -0,0 +1,36 @@ +.row + .col-md-12 + .page-header + %h1 Call for Papers + %p.text-muted + Call for people to submit events to your conference +- if @program.cfps + .row + .col-md-12 + %table.table.table-hover.datatable#tickets + %thead + %th Type + %th Start Date + %th End Date + %th Days Left + %th Actions + %tbody + - @program.cfps.each do |cfp| + %tr + %td + = link_to(admin_conference_program_cfp_path(@conference.short_title, cfp.id)) do + = cfp.cfp_type.capitalize + %td + = cfp.start_date.strftime('%A, %B %-d. %Y') + %td + = cfp.end_date.strftime('%A, %B %-d. %Y') + %td + = pluralize(cfp.remaining_days, 'day') + %td + .btn-group + = link_to 'Edit', edit_admin_conference_program_cfp_path(@conference.short_title, cfp.id), method: :get, class: 'btn btn-primary' + = link_to 'Delete', admin_conference_program_cfp_path(@conference.short_title, cfp.id), method: 'delete', class: 'btn btn-danger', data: { confirm: 'Are you sure you want to delete the CfP?' } +- if @program.remaining_cfp_types.length > 0 + .row + .col-md-12.text-right + = link_to 'Create Call for Papers', new_admin_conference_program_cfp_path(@conference.short_title), class: 'btn btn-primary' diff --git a/app/views/admin/cfps/show.html.haml b/app/views/admin/cfps/show.html.haml index 09441508..e2a043ea 100644 --- a/app/views/admin/cfps/show.html.haml +++ b/app/views/admin/cfps/show.html.haml @@ -4,55 +4,13 @@ %h1 Call for Papers %p.text-muted Call for people to submit events to your conference -- if @cfp - .row - .col-md-8 - %dl.dl-horizontal - %dt - Start Date: - %dd#start_date - = @cfp.start_date.strftime('%A, %B %-d. %Y') - %dt - End Date: - %dd#end_date - = @cfp.end_date.strftime('%A, %B %-d. %Y') - %dt - Days Left: - %dd - = pluralize(@cfp.remaining_days, 'day') - %dt - Event types: - %dd - = event_types(@conference) - %dt - Tracks: - %dd - = tracks(@conference) - %dt - Public Schedule - %dd#schedule_public - - if @program.schedule_public - Yes - - else - No - %dt - Schedule changeable? - %dd#schedule_changes - - if @program.schedule_fluid - Yes - - else - No - %dt - Rating Levels - %dd#rating - = @program.rating - .row - .col-md-12.text-right - = link_to(edit_admin_conference_program_cfp_path(@conference.short_title), class: 'btn btn-primary') do - Edit - = link_to(admin_conference_program_cfp_path(@conference.short_title), method: 'delete', class: 'btn btn-danger', data: { confirm: 'Are you sure you want to delete the CfP?' }) do - Delete -- else - .row - .col-md-12.text-right - = link_to 'Create Call for Papers', new_admin_conference_program_cfp_path(@conference.short_title), class: 'btn btn-primary' +.row + .col-md-8 + %dl.dl-horizontal + = render "#{@cfp.cfp_type}_cfp" +.row + .col-md-12.text-right + = link_to(edit_admin_conference_program_cfp_path(@conference.short_title, @cfp.id), class: 'btn btn-primary') do + Edit + = link_to(admin_conference_program_cfp_path(@conference.short_title, @cfp.id), method: 'delete', class: 'btn btn-danger', data: { confirm: 'Are you sure you want to delete the CfP?' }) do + Delete diff --git a/app/views/admin/conferences/_todo_list.html.haml b/app/views/admin/conferences/_todo_list.html.haml index 63f4e3aa..88bb7c36 100644 --- a/app/views/admin/conferences/_todo_list.html.haml +++ b/app/views/admin/conferences/_todo_list.html.haml @@ -18,7 +18,7 @@ %li{ 'class' => "list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['cfp'])}" } %span{ 'class' => icon_for_todo(conference_progress['cfp']) } - if can? :update, Cfp.new(program_id: @program.id) - = link_to 'Set up call for papers', admin_conference_program_cfp_path(conference_progress['short_title']) + = link_to 'Set up call for papers', admin_conference_program_cfps_path(conference_progress['short_title']) - else Set up call for papers %li{'class'=>"list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['venue'])}"} diff --git a/app/views/admin/versions/_object_desc_and_link.html.haml b/app/views/admin/versions/_object_desc_and_link.html.haml index 44eedf82..1c7ed154 100644 --- a/app/views/admin/versions/_object_desc_and_link.html.haml +++ b/app/views/admin/versions/_object_desc_and_link.html.haml @@ -85,8 +85,10 @@ admin_conference_program_path(conference_id: Conference.find(version.conference_id).short_title) - when 'Cfp' - = link_if_alive version, 'cfp', - admin_conference_program_cfp_path(conference_id: Conference.find(version.conference_id).short_title) + = 'cfp' + - cfp = current_or_last_object_state(version.item_type, version.item_id) + = link_if_alive version, cfp.cfp_type, + admin_conference_program_cfp_path(conference_id: Conference.find(version.conference_id).short_title, id: version.item_id) - when 'Track' = 'track' diff --git a/app/views/layouts/_admin_sidebar.html.haml b/app/views/layouts/_admin_sidebar.html.haml index a9a2a99a..2c3eaf52 100644 --- a/app/views/layouts/_admin_sidebar.html.haml +++ b/app/views/layouts/_admin_sidebar.html.haml @@ -67,8 +67,8 @@ - if @conference.program %ul - if can? :update, Cfp.new(program_id: @conference.program.id) - %li{class: active_nav_li(admin_conference_program_cfp_path(@conference.short_title))} - = link_to 'Call for Papers', admin_conference_program_cfp_path(@conference.short_title) + %li{class: active_nav_li(admin_conference_program_cfps_path(@conference.short_title))} + = link_to 'Call for Papers', admin_conference_program_cfps_path(@conference.short_title) - if can? :update, @conference.program.events.build %li{class: active_nav_li(admin_conference_program_events_path(@conference.short_title))} = link_to 'Events', admin_conference_program_events_path(@conference.short_title) diff --git a/config/routes.rb b/config/routes.rb index 60b03f54..8fa4b857 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -53,7 +53,7 @@ Osem::Application.routes.draw do end resource :registration_period resource :program do - resource :cfp + resources :cfps resources :tracks resources :event_types resources :difficulty_levels From a1124546f1fa5e9b98596845e0d9525dd4162009 Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Thu, 1 Jun 2017 01:11:28 +0300 Subject: [PATCH 126/185] Fix rspec tests because of the changes to the cfp Remove redundant association Note: a conference created with :full_conference already has a cfp --- app/models/cfp.rb | 4 +- app/models/program.rb | 2 +- app/models/registration.rb | 1 - .../versions/_object_desc_and_link.html.haml | 2 +- .../admin/conferences_controller_spec.rb | 8 +- spec/controllers/proposals_controller_spec.rb | 8 +- spec/factories/cfps.rb | 1 + spec/factories/programs.rb | 4 + spec/features/ability_spec.rb | 14 ++-- spec/features/cfp_spec.rb | 8 +- spec/features/versions_spec.rb | 6 +- spec/models/ability_spec.rb | 4 +- spec/models/conference_spec.rb | 80 +++++++++---------- spec/models/email_settings_spec.rb | 7 +- spec/models/program_spec.rb | 2 +- spec/models/registration_spec.rb | 1 - 16 files changed, 78 insertions(+), 74 deletions(-) diff --git a/app/models/cfp.rb b/app/models/cfp.rb index 92058e87..f06bec7b 100644 --- a/app/models/cfp.rb +++ b/app/models/cfp.rb @@ -81,12 +81,12 @@ class Cfp < ActiveRecord::Base private def before_end_of_conference - if program.conference && program.conference.end_date && end_date && (end_date > program.conference.end_date) + if program && program.conference && program.conference.end_date && end_date && (end_date > program.conference.end_date) errors .add(:end_date, "can't be after the conference end date (#{program.conference.end_date})") end - if program.conference && program.conference.end_date && start_date && (start_date > program.conference.end_date) + if program && program.conference && program.conference.end_date && start_date && (start_date > program.conference.end_date) errors .add(:start_date, "can't be after the conference end date (#{program.conference.end_date})") end diff --git a/app/models/program.rb b/app/models/program.rb index 09bb3627..49894cbd 100644 --- a/app/models/program.rb +++ b/app/models/program.rb @@ -135,7 +135,7 @@ class Program < ActiveRecord::Base # * +false+ -> If the CFP is not set or today isn't in the CFP period. # * +true+ -> If today is in the CFP period. def cfp_open? - cfp = cfps.events + cfp = self.cfp cfp.present? && (cfp.start_date..cfp.end_date).cover?(Date.current) end diff --git a/app/models/registration.rb b/app/models/registration.rb index 5d2555f2..7003dfd7 100644 --- a/app/models/registration.rb +++ b/app/models/registration.rb @@ -2,7 +2,6 @@ class Registration < ActiveRecord::Base belongs_to :user belongs_to :conference - has_and_belongs_to_many :events has_and_belongs_to_many :qanswers has_and_belongs_to_many :vchoices diff --git a/app/views/admin/versions/_object_desc_and_link.html.haml b/app/views/admin/versions/_object_desc_and_link.html.haml index 1c7ed154..14b1f2fc 100644 --- a/app/views/admin/versions/_object_desc_and_link.html.haml +++ b/app/views/admin/versions/_object_desc_and_link.html.haml @@ -85,7 +85,7 @@ admin_conference_program_path(conference_id: Conference.find(version.conference_id).short_title) - when 'Cfp' - = 'cfp' + = 'cfp for' - cfp = current_or_last_object_state(version.item_type, version.item_id) = link_if_alive version, cfp.cfp_type, admin_conference_program_cfp_path(conference_id: Conference.find(version.conference_id).short_title, id: version.item_id) diff --git a/spec/controllers/admin/conferences_controller_spec.rb b/spec/controllers/admin/conferences_controller_spec.rb index 3964996f..74acbb3f 100644 --- a/spec/controllers/admin/conferences_controller_spec.rb +++ b/spec/controllers/admin/conferences_controller_spec.rb @@ -177,10 +177,10 @@ describe Admin::ConferencesController do it 'assigns cfp_max an array with maximum weeks' do conference date = Date.new(2014, 05, 26) - conference.program.cfp = create(:cfp, - program: conference.program, - start_date: date, - end_date: date + 14) + create(:cfp, + program: conference.program, + start_date: date, + end_date: date + 14) get :index expect(assigns(:cfp_weeks)).to match_array([1, 2, 3]) end diff --git a/spec/controllers/proposals_controller_spec.rb b/spec/controllers/proposals_controller_spec.rb index 8f033973..9b01e55f 100644 --- a/spec/controllers/proposals_controller_spec.rb +++ b/spec/controllers/proposals_controller_spec.rb @@ -10,7 +10,7 @@ describe ProposalsController do describe 'GET #new' do before do # We allow new proposal only if program has open cfp - conference.program.update_attributes(cfp: create(:cfp)) + create(:cfp, program: conference.program) get :new, conference_id: conference.short_title end @@ -26,7 +26,7 @@ describe ProposalsController do describe 'POST #create' do # We allow proposal create only if program has open cfp - before { conference.program.update_attributes(cfp: create(:cfp)) } + before { create(:cfp, program: conference.program) } it 'assigns url variables' do post :create, event: attributes_for(:event, event_type_id: event_type.id), @@ -192,7 +192,7 @@ describe ProposalsController do describe 'GET #new' do before do # We allow new proposal only if program has open cfp - conference.program.update_attributes(cfp: create(:cfp)) + create(:cfp, program: conference.program) get :new, conference_id: conference.short_title end @@ -223,7 +223,7 @@ describe ProposalsController do describe 'POST #create' do # We allow proposal create only if program has open cfp - before { conference.program.update_attributes(cfp: create(:cfp)) } + before { create(:cfp, program: conference.program) } it 'assigns url variables' do post :create, event: attributes_for(:event, event_type_id: event_type.id), diff --git a/spec/factories/cfps.rb b/spec/factories/cfps.rb index 1ff58b9d..6a8e96ed 100644 --- a/spec/factories/cfps.rb +++ b/spec/factories/cfps.rb @@ -4,6 +4,7 @@ FactoryGirl.define do factory :cfp do start_date { 1.day.ago } end_date { 6.days.from_now } + cfp_type 'events' program end diff --git a/spec/factories/programs.rb b/spec/factories/programs.rb index a1a6e1f7..e3c20153 100644 --- a/spec/factories/programs.rb +++ b/spec/factories/programs.rb @@ -5,5 +5,9 @@ FactoryGirl.define do schedule_public false schedule_fluid false conference + + trait :with_cfp do + after(:create) { |program| create(:cfp, program: program) } + end end end diff --git a/spec/features/ability_spec.rb b/spec/features/ability_spec.rb index 80e968bd..162123f4 100644 --- a/spec/features/ability_spec.rb +++ b/spec/features/ability_spec.rb @@ -40,7 +40,7 @@ feature 'Has correct abilities' do expect(page).to have_link('Rooms', href: "/admin/conferences/#{conference1.short_title}/venue/rooms") expect(page).to have_link('Lodgings', href: "/admin/conferences/#{conference1.short_title}/lodgings") expect(page).to have_link('Program', href: "/admin/conferences/#{conference1.short_title}/program") - expect(page).to have_link('Call for Papers', href: "/admin/conferences/#{conference1.short_title}/program/cfp") + expect(page).to have_link('Call for Papers', href: "/admin/conferences/#{conference1.short_title}/program/cfps") expect(page).to have_link('Events', href: "/admin/conferences/#{conference1.short_title}/program/events") expect(page).to have_link('Tracks', href: "/admin/conferences/#{conference1.short_title}/program/tracks") expect(page).to have_link('Event Types', href: "/admin/conferences/#{conference1.short_title}/program/event_types") @@ -112,8 +112,8 @@ feature 'Has correct abilities' do visit new_admin_conference_program_cfp_path(conference1.short_title) expect(current_path).to eq(new_admin_conference_program_cfp_path(conference1.short_title)) - visit edit_admin_conference_program_cfp_path(conference1.short_title) - expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference1.short_title)) + visit edit_admin_conference_program_cfp_path(conference1.short_title, conference1.program.cfp) + expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference1.short_title, conference1.program.cfp)) visit admin_conference_program_events_path(conference1.short_title) expect(current_path).to eq(admin_conference_program_events_path(conference1.short_title)) @@ -256,7 +256,7 @@ feature 'Has correct abilities' do expect(page).to have_link('Rooms', href: "/admin/conferences/#{conference2.short_title}/venue/rooms") expect(page).to_not have_link('Lodgings', href: "/admin/conferences/#{conference2.short_title}/lodgings") expect(page).to have_link('Program', href: "/admin/conferences/#{conference2.short_title}/program") - expect(page).to have_link('Call for Papers', href: "/admin/conferences/#{conference2.short_title}/program/cfp") + expect(page).to have_link('Call for Papers', href: "/admin/conferences/#{conference2.short_title}/program/cfps") expect(page).to have_link('Events', href: "/admin/conferences/#{conference2.short_title}/program/events") expect(page).to have_link('Tracks', href: "/admin/conferences/#{conference2.short_title}/program/tracks") expect(page).to have_link('Event Types', href: "/admin/conferences/#{conference2.short_title}/program/event_types") @@ -324,8 +324,8 @@ feature 'Has correct abilities' do visit new_admin_conference_program_cfp_path(conference2.short_title) expect(current_path).to eq(new_admin_conference_program_cfp_path(conference2.short_title)) - visit edit_admin_conference_program_cfp_path(conference2.short_title) - expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference2.short_title)) + visit edit_admin_conference_program_cfp_path(conference2.short_title, conference2.program.cfp) + expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference2.short_title, conference2.program.cfp)) visit admin_conference_program_events_path(conference2.short_title) expect(current_path).to eq(admin_conference_program_events_path(conference2.short_title)) @@ -537,7 +537,7 @@ feature 'Has correct abilities' do visit new_admin_conference_program_cfp_path(conference3.short_title) expect(current_path).to eq(root_path) - visit edit_admin_conference_program_cfp_path(conference3.short_title) + visit edit_admin_conference_program_cfp_path(conference3.short_title, conference3.program.cfp) expect(current_path).to eq(root_path) visit admin_conference_program_events_path(conference3.short_title) diff --git a/spec/features/cfp_spec.rb b/spec/features/cfp_spec.rb index 8869de1f..7ecfb1e6 100644 --- a/spec/features/cfp_spec.rb +++ b/spec/features/cfp_spec.rb @@ -31,6 +31,8 @@ feature Conference do # Validations expect(flash) .to eq('Call for papers successfully created.') + + visit admin_conference_program_cfp_path(conference.short_title, conference.program.cfp) expect(find('#start_date').text).to eq(today.strftime('%A, %B %-d. %Y')) expect(find('#end_date').text).to eq((today + 6).strftime('%A, %B %-d. %Y')) @@ -38,11 +40,11 @@ feature Conference do end scenario 'update cfp', feature: true, js: true do - conference.program.cfp = create(:cfp) + create(:cfp, program: conference.program) expected_count = Cfp.count sign_in organizer - visit admin_conference_program_cfp_path(conference.short_title) + visit admin_conference_program_cfp_path(conference.short_title, conference.program.cfp) click_link 'Edit' # Validate update with empty start date will not saved @@ -65,6 +67,8 @@ feature Conference do # Validations expect(flash) .to eq('Call for papers successfully updated.') + + visit admin_conference_program_cfp_path(conference.short_title, conference.program.cfp) expect(find('#start_date').text).to eq(today.strftime('%A, %B %-d. %Y')) expect(find('#end_date').text).to eq((today + 14).strftime('%A, %B %-d. %Y')) expect(Cfp.count).to eq(expected_count) diff --git a/spec/features/versions_spec.rb b/spec/features/versions_spec.rb index 90c0fa35..11afa1d2 100644 --- a/spec/features/versions_spec.rb +++ b/spec/features/versions_spec.rb @@ -38,9 +38,9 @@ feature 'Version' do cfp.destroy visit admin_revision_history_path - expect(page).to have_text("Someone (probably via the console) created new cfp in conference #{conference.short_title}") - expect(page).to have_text("Someone (probably via the console) updated start date and end date of cfp in conference #{conference.short_title}") - expect(page).to have_text("Someone (probably via the console) deleted cfp in conference #{conference.short_title}") + expect(page).to have_text("Someone (probably via the console) created new cfp for events in conference #{conference.short_title}") + expect(page).to have_text("Someone (probably via the console) updated start date and end date of cfp for events in conference #{conference.short_title}") + expect(page).to have_text("Someone (probably via the console) deleted cfp for events in conference #{conference.short_title}") end scenario 'display changes in registration_period', feature: true, versioning: true, js: true do diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index 6ddc44e6..001c7365 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -10,7 +10,6 @@ describe 'User' do let(:user){ nil } let!(:my_conference) { create(:full_conference) } - let!(:my_cfp) { create(:cfp, program: my_conference.program) } let(:my_venue) { my_conference.venue || create(:venue, conference: my_conference) } let(:my_registration) { create(:registration, conference: my_conference, user: admin) } @@ -22,7 +21,6 @@ describe 'User' do let(:conference_not_public) { create(:conference, splashpage: create(:splashpage, public: false)) } let(:conference_public) { create(:full_conference, splashpage: create(:splashpage, public: true)) } - let!(:conference_public_cfp) { create(:cfp, program: conference_public.program) } let(:event_confirmed) { create(:event, state: 'confirmed') } let(:event_unconfirmed) { create(:event) } @@ -32,7 +30,7 @@ describe 'User' do let(:resource) { create(:resource, conference: my_conference)} let(:registration) { create(:registration) } - let(:program_with_cfp) { create(:program, cfp: create(:cfp)) } + 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) } diff --git a/spec/models/conference_spec.rb b/spec/models/conference_spec.rb index 9bdbea83..d6e4f485 100755 --- a/spec/models/conference_spec.rb +++ b/spec/models/conference_spec.rb @@ -48,7 +48,7 @@ describe Conference do subject.start_date = Date.today + 6.weeks subject.end_date = Date.today + 7.weeks subject.save - subject.program.cfp = create(:cfp, start_date: Date.today - 3.weeks) + create(:cfp, start_date: Date.today - 3.weeks, program: subject.program) create(:event, program: subject.program, created_at: Date.today) options = {} @@ -115,7 +115,7 @@ describe Conference do } subject.events_per_week = db_data subject.save - subject.program.cfp = create(:cfp, start_date: Date.today - 3.weeks) + create(:cfp, start_date: Date.today - 3.weeks, program: subject.program) create(:event, program: subject.program, created_at: Date.today) unconfirmed = create(:event, program: subject.program) @@ -186,7 +186,7 @@ describe Conference do subject.events_per_week = db_data subject.save - subject.program.cfp = create(:cfp, start_date: Date.today - 2.weeks) + create(:cfp, start_date: Date.today - 2.weeks, program: subject.program) create(:event, program: subject.program, created_at: Date.today - 2.weeks) @@ -203,7 +203,7 @@ describe Conference do subject.start_date = Date.today + 6.weeks subject.end_date = Date.today + 7.weeks subject.save - subject.program.cfp = create(:cfp, start_date: Date.today) + create(:cfp, start_date: Date.today, program: subject.program) create(:event, program: subject.program) result = { @@ -220,7 +220,7 @@ describe Conference do subject.start_date = Date.today + 6.weeks subject.end_date = Date.today + 7.weeks subject.save - subject.program.cfp = create(:cfp, start_date: Date.today - 3.weeks) + create(:cfp, start_date: Date.today - 3.weeks, program: subject.program) create(:event, program: subject.program, created_at: Date.today) unconfirmed = create(:event, program: subject.program) @@ -258,7 +258,7 @@ describe Conference do subject.events_per_week = db_data subject.save - subject.program.cfp = create(:cfp, start_date: Date.today - 3.weeks) + create(:cfp, start_date: Date.today - 3.weeks, program: subject.program) create(:event, program: subject.program, created_at: Date.today - 3.weeks) @@ -992,7 +992,6 @@ describe Conference do end it 'calculates correct for new conference' do - subject.program.cfp = nil subject.venue = nil subject.program.tracks = [] subject.program.event_types = [] @@ -1006,7 +1005,6 @@ describe Conference do subject.registration_period = create(:registration_period, start_date: subject.end_date - 14, end_date: subject.end_date, conference: subject) - subject.program.cfp = nil subject.venue = nil subject.program.event_types = [] subject.program.tracks = [] @@ -1024,7 +1022,7 @@ describe Conference do subject.registration_period = create(:registration_period, start_date: subject.end_date - 14, end_date: subject.end_date, conference: subject) - subject.program.cfp = create(:cfp) + create(:cfp, program: subject.program) subject.venue = nil subject.program.tracks = [] subject.program.event_types = [] @@ -1043,7 +1041,7 @@ describe Conference do subject.registration_period = create(:registration_period, start_date: subject.end_date - 14, end_date: subject.end_date, conference: subject) - subject.program.cfp = create(:cfp) + create(:cfp, program: subject.program) subject.venue = create(:venue, conference: subject) subject.venue.rooms = [] subject.program.tracks = [] @@ -1063,7 +1061,7 @@ describe Conference do subject.registration_period = create(:registration_period, start_date: Date.today, end_date: Date.today + 14, conference: subject) - subject.program.cfp = create(:cfp) + create(:cfp, program: subject.program) subject.venue = create(:venue, conference: subject) subject.venue.rooms = [create(:room, venue: subject.venue)] subject.program.tracks = [] @@ -1087,7 +1085,7 @@ describe Conference do subject.registration_period = create(:registration_period, start_date: Date.today, end_date: Date.today + 14, conference: subject) - subject.program.cfp = create(:cfp) + create(:cfp, program: subject.program) subject.program.event_types = [] subject.program.difficulty_levels = [] subject.splashpage = create(:splashpage, public: false) @@ -1109,7 +1107,7 @@ describe Conference do subject.registration_period = create(:registration_period, start_date: Date.today, end_date: Date.today + 14, conference: subject) - subject.program.cfp = create(:cfp) + create(:cfp, program: subject.program) subject.venue = create(:venue, conference: subject) subject.venue.rooms = [create(:room, venue: subject.venue)] subject.program.difficulty_levels = [] @@ -1133,7 +1131,7 @@ describe Conference do subject.registration_period = create(:registration_period, start_date: Date.today, end_date: Date.today + 14, conference: subject) - subject.program.cfp = create(:cfp) + create(:cfp, program: subject.program) subject.venue = create(:venue, conference: subject) subject.venue.rooms = [create(:room, venue: subject.venue)] subject.splashpage = create(:splashpage, public: true) @@ -1176,34 +1174,34 @@ describe Conference do describe '#cfp_weeks' do it 'calculates new year' do - cfp = create(:cfp) + cfp = create(:cfp, program: subject.program) cfp.start_date = Date.new(2013, 12, 30) cfp.end_date = Date.new(2013, 12, 30) + 6 - subject.program.cfp = cfp + cfp.save! expect(subject.cfp_weeks).to eq(1) end it 'is one if start and end are 6 days apart' do - cfp = create(:cfp) + cfp = create(:cfp, program: subject.program) cfp.start_date = Date.new(2014, 05, 26) cfp.end_date = Date.new(2014, 05, 26) + 6 - subject.program.cfp = cfp + cfp.save! expect(subject.cfp_weeks).to eq(1) end it 'is one if start and end are the same date' do - cfp = create(:cfp) + cfp = create(:cfp, program: subject.program) cfp.start_date = Date.new(2014, 05, 26) cfp.end_date = Date.new(2014, 05, 26) - subject.program.cfp = cfp + cfp.save! expect(subject.cfp_weeks).to eq(1) end it 'is two if start and end are 10 days apart' do - cfp = create(:cfp) + cfp = create(:cfp, program: subject.program) cfp.start_date = Date.new(2014, 05, 26) cfp.end_date = Date.new(2014, 05, 26) + 10 - subject.program.cfp = cfp + cfp.save! expect(subject.cfp_weeks).to eq(2) end end @@ -1211,36 +1209,36 @@ describe Conference do describe '#get_submissions_per_week' do it 'does calculate correct if cfp start date is altered' do - cfp = create(:cfp) + cfp = create(:cfp, program: subject.program) cfp.start_date = Date.new(2014, 05, 26) cfp.end_date = Date.new(2014, 05, 26) + 21 - subject.program.cfp = cfp + cfp.save! subject.program.events += [create(:event, created_at: Date.new(2014, 05, 26) - 7)] expect(subject.get_submissions_per_week).to eq([1, 1, 1, 1, 1]) end it 'does calculate correct if cfp end date is altered' do - cfp = create(:cfp) + cfp = create(:cfp, program: subject.program) cfp.start_date = Date.new(2014, 05, 26) cfp.end_date = Date.new(2014, 05, 26) + 21 - subject.program.cfp = cfp + cfp.save! subject.program.events += [create(:event, created_at: Date.new(2014, 05, 26) + 28)] expect(subject.get_submissions_per_week).to eq([0, 0, 0, 0, 1]) end it 'pads with zeros if there are no submissions' do - cfp = create(:cfp) + cfp = create(:cfp, program: subject.program) cfp.start_date = Date.new(2014, 05, 26) cfp.end_date = Date.new(2014, 05, 26) + 21 - subject.program.cfp = cfp + cfp.save! expect(subject.get_submissions_per_week).to eq([0, 0, 0, 0]) end it 'summarized correct if there are no submissions in one week' do - cfp = create(:cfp) + cfp = create(:cfp, program: subject.program) cfp.start_date = Date.new(2014, 05, 26) cfp.end_date = Date.new(2014, 05, 26) + 28 - subject.program.cfp = cfp + cfp.save! subject.program.events += [create(:event, created_at: Date.new(2014, 05, 26) + 7)] subject.program.events += [create(:event, created_at: Date.new(2014, 05, 26) + 14)] subject.program.events += [create(:event, created_at: Date.new(2014, 05, 26) + 28)] @@ -1248,20 +1246,20 @@ describe Conference do end it 'summarized correct if there are submissions every week except the first' do - cfp = create(:cfp) + cfp = create(:cfp, program: subject.program) cfp.start_date = Date.new(2014, 05, 26) cfp.end_date = Date.new(2014, 05, 26) + 21 - subject.program.cfp = cfp + cfp.save! subject.program.events += [create(:event, created_at: Date.new(2014, 05, 26) + 7)] subject.program.events += [create(:event, created_at: Date.new(2014, 05, 26) + 14)] expect(subject.get_submissions_per_week).to eq([0, 1, 2, 2]) end it 'summarized correct if there are submissions every week' do - cfp = create(:cfp) + cfp = create(:cfp, program: subject.program) cfp.start_date = Date.new(2014, 05, 26) cfp.end_date = Date.new(2014, 05, 26) + 21 - subject.program.cfp = cfp + cfp.save! subject.program.events += [create(:event, created_at: Date.new(2014, 05, 26))] subject.program.events += [create(:event, created_at: Date.new(2014, 05, 26) + 7)] subject.program.events += [create(:event, created_at: Date.new(2014, 05, 26) + 14)] @@ -1269,29 +1267,29 @@ describe Conference do end it 'pads left' do - cfp = create(:cfp) + cfp = create(:cfp, program: subject.program) cfp.start_date = Date.new(2014, 05, 26) cfp.end_date = Date.new(2014, 05, 26) + 21 - subject.program.cfp = cfp + cfp.save! subject.program.events += [create(:event, created_at: Date.new(2014, 05, 26) + 21)] expect(subject.get_submissions_per_week).to eq([0, 0, 0, 1]) end it 'pads middle' do - cfp = create(:cfp) + cfp = create(:cfp, program: subject.program) cfp.start_date = Date.new(2014, 05, 26) cfp.end_date = Date.new(2014, 05, 26) + 21 - subject.program.cfp = cfp + cfp.save! subject.program.events += [create(:event, created_at: Date.new(2014, 05, 26))] subject.program.events += [create(:event, created_at: Date.new(2014, 05, 26) + 21)] expect(subject.get_submissions_per_week).to eq([1, 1, 1, 2]) end it 'pads right' do - cfp = create(:cfp) + cfp = create(:cfp, program: subject.program) cfp.start_date = Date.new(2014, 05, 26) cfp.end_date = Date.new(2014, 05, 26) + 21 - subject.program.cfp = cfp + cfp.save! subject.program.events += [create(:event, created_at: Date.new(2014, 05, 26))] expect(subject.get_submissions_per_week).to eq([1, 1, 1, 1]) end @@ -1460,7 +1458,7 @@ describe Conference do context 'open cfp' do before do - subject.program.cfp = create(:cfp) + create(:cfp, program: subject.program) end it '#registration_open? is true' do diff --git a/spec/models/email_settings_spec.rb b/spec/models/email_settings_spec.rb index 949f5762..c4ab7830 100644 --- a/spec/models/email_settings_spec.rb +++ b/spec/models/email_settings_spec.rb @@ -46,9 +46,10 @@ describe EmailSettings do context 'conference has cfp' do before do - conference.program.update_attributes(cfp: create(:cfp, - start_date: Date.new(2014, 04, 29), - end_date: Date.new(2014, 05, 06))) + create(:cfp, + start_date: Date.new(2014, 04, 29), + end_date: Date.new(2014, 05, 06), + program: conference.program) cfp_dates_hash = { 'cfp_start_date' => Date.new(2014, 04, 29), 'cfp_end_date' => Date.new(2014, 05, 06) } expected_hash.merge!(cfp_dates_hash) end diff --git a/spec/models/program_spec.rb b/spec/models/program_spec.rb index 6ea62cf0..208ca386 100644 --- a/spec/models/program_spec.rb +++ b/spec/models/program_spec.rb @@ -7,7 +7,7 @@ describe Program do describe 'association' do it { is_expected.to belong_to :conference } - it { is_expected.to have_one(:cfp).dependent(:destroy) } + it { is_expected.to have_many(:cfps).dependent(:destroy) } it { is_expected.to have_many(:schedules).dependent(:destroy) } it { is_expected.to have_many(:event_types).dependent(:destroy) } it { is_expected.to have_many(:tracks).dependent(:destroy) } diff --git a/spec/models/registration_spec.rb b/spec/models/registration_spec.rb index 772ccda1..25ec9888 100644 --- a/spec/models/registration_spec.rb +++ b/spec/models/registration_spec.rb @@ -29,7 +29,6 @@ describe 'Registration' do describe 'association' do it { is_expected.to belong_to(:user) } it { is_expected.to belong_to(:conference) } - it { is_expected.to have_and_belong_to_many(:events) } it { is_expected.to have_and_belong_to_many(:qanswers) } it { is_expected.to have_and_belong_to_many(:vchoices) } it { is_expected.to have_many(:events_registrations) } From 5f3b48c9f7083891ce365ea02e372bdc2097b902 Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Thu, 15 Jun 2017 11:34:58 +0300 Subject: [PATCH 127/185] Update shoulda-matchers to 2.8 --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 9dbc51e9..74e8ce84 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -471,7 +471,7 @@ GEM sprockets (~> 2.8, < 2.12) sprockets-rails (~> 2.0) selectize-rails (0.12.4) - shoulda-matchers (2.6.1) + shoulda-matchers (2.8.0) activesupport (>= 3.0.0) simplecov (0.11.2) docile (~> 1.1.0) @@ -653,4 +653,4 @@ DEPENDENCIES whenever BUNDLED WITH - 1.14.5 + 1.15.1 From f37d3095e1bc3a991f66c1cf2edcddb13f01b8cc Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Mon, 19 Jun 2017 17:35:46 +0300 Subject: [PATCH 128/185] Rework cfp abilities --- .rubocop.yml | 1 + app/models/ability.rb | 7 ++++++- app/views/admin/cfps/index.html.haml | 2 +- spec/features/ability_spec.rb | 14 ++++++++++++-- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index cff7046b..22e17db0 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -29,3 +29,4 @@ Metrics/ClassLength: Metrics/BlockLength: Exclude: - 'spec/models/conference_spec.rb' + - 'spec/features/ability_spec.rb' diff --git a/app/models/ability.rb b/app/models/ability.rb index bdf554cc..6fa8c12f 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -139,6 +139,11 @@ class Ability 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_organizer_role(user) @@ -166,7 +171,7 @@ class Ability can :manage, Program, conference_id: conf_ids_for_organizer can :manage, Schedule, program: { conference_id: conf_ids_for_organizer } can :manage, EventSchedule, schedule: { program: { conference_id: conf_ids_for_organizer } } - can :manage, Cfp, program: { conference_id: conf_ids_for_organizer} + can :manage, Cfp, program: { conference_id: conf_ids_for_organizer } can :manage, Event, program: { conference_id: conf_ids_for_organizer} can :manage, EventType, program: { conference_id: conf_ids_for_organizer} can :manage, Track, program: { conference_id: conf_ids_for_organizer} diff --git a/app/views/admin/cfps/index.html.haml b/app/views/admin/cfps/index.html.haml index 16ab8e84..0067229c 100644 --- a/app/views/admin/cfps/index.html.haml +++ b/app/views/admin/cfps/index.html.haml @@ -30,7 +30,7 @@ .btn-group = link_to 'Edit', edit_admin_conference_program_cfp_path(@conference.short_title, cfp.id), method: :get, class: 'btn btn-primary' = link_to 'Delete', admin_conference_program_cfp_path(@conference.short_title, cfp.id), method: 'delete', class: 'btn btn-danger', data: { confirm: 'Are you sure you want to delete the CfP?' } -- if @program.remaining_cfp_types.length > 0 +- if can? :new, @program.cfps.new .row .col-md-12.text-right = link_to 'Create Call for Papers', new_admin_conference_program_cfp_path(@conference.short_title), class: 'btn btn-primary' diff --git a/spec/features/ability_spec.rb b/spec/features/ability_spec.rb index 162123f4..fe3a3c36 100644 --- a/spec/features/ability_spec.rb +++ b/spec/features/ability_spec.rb @@ -110,7 +110,12 @@ feature 'Has correct abilities' do expect(current_path).to eq(edit_admin_conference_program_path(conference1.short_title)) visit new_admin_conference_program_cfp_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_program_cfp_path(conference1.short_title)) + expect(current_path).to eq root_path + + conference1.program.cfp.destroy! + visit new_admin_conference_program_cfp_path(conference1.short_title) + expect(current_path).to eq new_admin_conference_program_cfp_path(conference1.short_title) + create(:cfp, program: conference1.program) visit edit_admin_conference_program_cfp_path(conference1.short_title, conference1.program.cfp) expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference1.short_title, conference1.program.cfp)) @@ -322,7 +327,12 @@ feature 'Has correct abilities' do expect(current_path).to eq(edit_admin_conference_program_path(conference2.short_title)) visit new_admin_conference_program_cfp_path(conference2.short_title) - expect(current_path).to eq(new_admin_conference_program_cfp_path(conference2.short_title)) + expect(current_path).to eq root_path + + conference2.program.cfp.destroy! + visit new_admin_conference_program_cfp_path(conference2.short_title) + expect(current_path).to eq new_admin_conference_program_cfp_path(conference2.short_title) + create(:cfp, program: conference2.program) visit edit_admin_conference_program_cfp_path(conference2.short_title, conference2.program.cfp) expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference2.short_title, conference2.program.cfp)) From b72e64b2385767f2b1634322ac2cf97c9a3a3638 Mon Sep 17 00:00:00 2001 From: shlok007 Date: Tue, 13 Jun 2017 04:39:47 +0530 Subject: [PATCH 129/185] Introduce organization admins --- app/controllers/admin/base_controller.rb | 2 +- .../admin/organizations_controller.rb | 5 + app/models/ability.rb | 95 +++++++++++-------- app/models/organization.rb | 10 ++ lib/tasks/roles.rake | 4 + spec/models/ability_spec.rb | 21 +++- 6 files changed, 96 insertions(+), 41 deletions(-) diff --git a/app/controllers/admin/base_controller.rb b/app/controllers/admin/base_controller.rb index 638d2ab6..5c71ffdc 100644 --- a/app/controllers/admin/base_controller.rb +++ b/app/controllers/admin/base_controller.rb @@ -8,7 +8,7 @@ module Admin return false 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? :info_desk, :any) || (current_user.has_role? :organization_admin, :any) || (current_user.has_role? :volunteers_coordinator, :any) || current_user.is_admin raise CanCan::AccessDenied.new('You are not authorized to access this area!') end diff --git a/app/controllers/admin/organizations_controller.rb b/app/controllers/admin/organizations_controller.rb index 087bf7f8..9d0dc78b 100644 --- a/app/controllers/admin/organizations_controller.rb +++ b/app/controllers/admin/organizations_controller.rb @@ -1,6 +1,7 @@ module Admin class OrganizationsController < Admin::BaseController load_and_authorize_resource :organization + after_action :assign_role, only: :create def index @organizations = Organization.all @@ -45,6 +46,10 @@ module Admin private + def assign_role + current_user.add_role :organization_admin, @organization + end + def organization_params params.require(:organization).permit(:name, :description, :picture) end diff --git a/app/models/ability.rb b/app/models/ability.rb index 6fa8c12f..7d1cf868 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -110,6 +110,7 @@ class Ability # 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 @@ -146,57 +147,73 @@ class Ability end end - def signed_in_with_organizer_role(user) - # ids of all the conferences for which the user has the 'organizer' role - conf_ids_for_organizer = Conference.with_role(:organizer, user).pluck(:id) + def signed_in_with_organization_admin_role(user) + org_ids_for_organization_admin = Organization.with_role(:organization_admin, user).pluck(:id) - can :manage, Resource, conference_id: conf_ids_for_organizer - can [:new, :create], Conference if user.has_role?(:organizer, :any) - can :manage, Conference, id: conf_ids_for_organizer - can :manage, Splashpage, conference_id: conf_ids_for_organizer - can :manage, Contact, conference_id: conf_ids_for_organizer - can :manage, EmailSettings, conference_id: conf_ids_for_organizer - can :manage, Campaign, conference_id: conf_ids_for_organizer - can :manage, Target, conference_id: conf_ids_for_organizer - can :manage, Commercial, commercialable_type: 'Conference', - commercialable_id: conf_ids_for_organizer - can :manage, Registration, conference_id: conf_ids_for_organizer - can :manage, RegistrationPeriod, conference_id: conf_ids_for_organizer - can :manage, Question, conference_id: conf_ids_for_organizer - can :manage, Question do |question| - !(question.conferences.pluck(:id) & conf_ids_for_organizer).empty? + can :manage, Organization, id: org_ids_for_organization_admin + can :manage, Conference, organization_id: org_ids_for_organization_admin + conf_ids_for_organization_admin = [] + org_ids_for_organization_admin.each do |org_id| + conf_ids_for_organization_admin += Organization.find(org_id).conferences.pluck(:id) end - can :manage, Vposition, conference_id: conf_ids_for_organizer - can :manage, Vday, conference_id: conf_ids_for_organizer - can :manage, Program, conference_id: conf_ids_for_organizer - can :manage, Schedule, program: { conference_id: conf_ids_for_organizer } - can :manage, EventSchedule, schedule: { program: { conference_id: conf_ids_for_organizer } } - can :manage, Cfp, program: { conference_id: conf_ids_for_organizer } - can :manage, Event, program: { conference_id: conf_ids_for_organizer} - can :manage, EventType, program: { conference_id: conf_ids_for_organizer} - can :manage, Track, program: { conference_id: conf_ids_for_organizer} - can :manage, DifficultyLevel, program: { conference_id: conf_ids_for_organizer} + 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_for_organization_admin_and_organizer = conf_ids_for_organization_admin.concat(Conference.with_role(:organizer, user).pluck(:id)).uniq + can :manage, Resource, conference_id: conf_ids_for_organization_admin_and_organizer + can [:new, :create], Conference if user.has_role?(:organizer, :any) + can :manage, Conference, id: conf_ids_for_organization_admin_and_organizer + can :manage, Splashpage, conference_id: conf_ids_for_organization_admin_and_organizer + can :manage, Contact, conference_id: conf_ids_for_organization_admin_and_organizer + can :manage, EmailSettings, conference_id: conf_ids_for_organization_admin_and_organizer + can :manage, Campaign, conference_id: conf_ids_for_organization_admin_and_organizer + can :manage, Target, conference_id: conf_ids_for_organization_admin_and_organizer + can :manage, Commercial, commercialable_type: 'Conference', + commercialable_id: conf_ids_for_organization_admin_and_organizer + can :manage, Registration, conference_id: conf_ids_for_organization_admin_and_organizer + can :manage, RegistrationPeriod, conference_id: conf_ids_for_organization_admin_and_organizer + can :manage, Question, conference_id: conf_ids_for_organization_admin_and_organizer + can :manage, Question do |question| + !(question.conferences.pluck(:id) & conf_ids_for_organization_admin_and_organizer).empty? + end + can :manage, Vposition, conference_id: conf_ids_for_organization_admin_and_organizer + can :manage, Vday, conference_id: conf_ids_for_organization_admin_and_organizer + can :manage, Program, conference_id: conf_ids_for_organization_admin_and_organizer + can :manage, Schedule, program: { conference_id: conf_ids_for_organization_admin_and_organizer } + can :manage, EventSchedule, schedule: { program: { conference_id: conf_ids_for_organization_admin_and_organizer } } + can :manage, Cfp, program: { conference_id: conf_ids_for_organization_admin_and_organizer} + can :manage, Event, program: { conference_id: conf_ids_for_organization_admin_and_organizer} + can :manage, EventType, program: { conference_id: conf_ids_for_organization_admin_and_organizer} + can :manage, Track, program: { conference_id: conf_ids_for_organization_admin_and_organizer} + can :manage, DifficultyLevel, program: { conference_id: conf_ids_for_organization_admin_and_organizer} can :manage, Commercial, commercialable_type: 'Event', - commercialable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_organizer).pluck(:id)).pluck(:id) - can :manage, Venue, conference_id: conf_ids_for_organizer + commercialable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_organization_admin_and_organizer).pluck(:id)).pluck(:id) + can :manage, Venue, conference_id: conf_ids_for_organization_admin_and_organizer can :manage, Commercial, commercialable_type: 'Venue', - commercialable_id: Venue.where(conference_id: conf_ids_for_organizer).pluck(:id) - can :manage, Lodging, conference_id: conf_ids_for_organizer - can :manage, Room, venue: { conference_id: conf_ids_for_organizer} - can :manage, Sponsor, conference_id: conf_ids_for_organizer - can :manage, SponsorshipLevel, conference_id: conf_ids_for_organizer - can :manage, Ticket, conference_id: conf_ids_for_organizer + commercialable_id: Venue.where(conference_id: conf_ids_for_organization_admin_and_organizer).pluck(:id) + can :manage, Lodging, conference_id: conf_ids_for_organization_admin_and_organizer + can :manage, Room, venue: { conference_id: conf_ids_for_organization_admin_and_organizer} + can :manage, Sponsor, conference_id: conf_ids_for_organization_admin_and_organizer + can :manage, SponsorshipLevel, conference_id: conf_ids_for_organization_admin_and_organizer + can :manage, Ticket, conference_id: conf_ids_for_organization_admin_and_organizer can :index, Comment, commentable_type: 'Event', - commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_organizer).pluck(:id)).pluck(:id) + commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_organization_admin_and_organizer).pluck(:id)).pluck(:id) # Abilities for Role (Conference resource) can [:index, :show], Role can [:edit, :update, :toggle_user], Role do |role| - role.resource_type == 'Conference' && (conf_ids_for_organizer.include? role.resource_id) + role.resource_type == 'Conference' && (conf_ids_for_organization_admin_and_organizer.include? role.resource_id) end can [:index, :revert_object, :revert_attribute], PaperTrail::Version do |version| - version.item_type == 'User' || (conf_ids_for_organizer.include? version.conference_id) + version.item_type == 'User' || (conf_ids_for_organization_admin_and_organizer.include? version.conference_id) end end diff --git a/app/models/organization.rb b/app/models/organization.rb index 60a83fef..0fdbe5f9 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -1,7 +1,17 @@ class Organization < ActiveRecord::Base + resourcify :roles, dependent: :delete_all + has_many :conferences, dependent: :destroy + after_create :create_roles + validates :name, presence: true mount_uploader :picture, PictureUploader, mount_on: :picture + + private + + def create_roles + Role.where(name: 'organization_admin', resource: self).first_or_create(description: "For the administrators of an organization (who shall have full access to the organization and it's conferences)") + end end diff --git a/lib/tasks/roles.rake b/lib/tasks/roles.rake index 8c817db0..227f9642 100644 --- a/lib/tasks/roles.rake +++ b/lib/tasks/roles.rake @@ -2,6 +2,10 @@ namespace :roles do desc 'Adds back deleted roles to all conferences' task add: :environment do + Organization.all.each do |org| + Role.where(name: 'organization_admin', resource: org).first_or_create(description: "For the administrators of an organization (who shall have full access to the organization and it's conferences)") + end + Conference.all.each do |c| Role.where(name: 'organizer', resource: c).first_or_create(description: 'For the organizers of the conference (who shall have full access)') Role.where(name: 'cfp', resource: c).first_or_create(description: 'For the members of the CfP team') diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index 001c7365..980cc194 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -9,7 +9,8 @@ describe 'User' do subject(:ability){ Ability.new(user) } let(:user){ nil } - let!(:my_conference) { create(:full_conference) } + 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) } @@ -44,6 +45,7 @@ describe 'User' do 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)} it{ should be_able_to(:index, Conference)} it{ should be_able_to(:show, conference_public)} @@ -138,9 +140,14 @@ describe 'User' do shared_examples 'user with any role' do before do + @other_organization = create(:organization) @other_conference = create(:conference) end + 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)) } @@ -164,6 +171,18 @@ describe 'User' do 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_conference) { create(:conference) } + + it{ should_not be_able_to(:manage, other_conference) } + it{ should be_able_to(:manage, my_conference) } + it{ should be_able_to(:manage, organization) } + + it_behaves_like 'user with any role' + 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]) } From aa3df0243eff061502050fa0d346f47fc9569789 Mon Sep 17 00:00:00 2001 From: shlok007 Date: Tue, 13 Jun 2017 20:57:55 +0530 Subject: [PATCH 130/185] mending permissions and test --- app/models/ability.rb | 22 ++++++++++++++-------- spec/models/ability_spec.rb | 10 +++++----- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/app/models/ability.rb b/app/models/ability.rb index 7d1cf868..00a0b291 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -29,6 +29,7 @@ class Ability # Abilities for not signed in users (guests) def not_signed_in + can [:index], Organization can [:index], Conference can [:show], Conference do |conference| conference.splashpage && conference.splashpage.public == true @@ -168,7 +169,6 @@ class Ability # conferences that belong to organizations for which user is 'organization_admin' conf_ids_for_organization_admin_and_organizer = conf_ids_for_organization_admin.concat(Conference.with_role(:organizer, user).pluck(:id)).uniq can :manage, Resource, conference_id: conf_ids_for_organization_admin_and_organizer - can [:new, :create], Conference if user.has_role?(:organizer, :any) can :manage, Conference, id: conf_ids_for_organization_admin_and_organizer can :manage, Splashpage, conference_id: conf_ids_for_organization_admin_and_organizer can :manage, Contact, conference_id: conf_ids_for_organization_admin_and_organizer @@ -207,7 +207,10 @@ class Ability commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_organization_admin_and_organizer).pluck(:id)).pluck(:id) # Abilities for Role (Conference resource) - can [:index, :show], Role + 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_for_organization_admin_and_organizer.include? role.resource_id) end @@ -239,8 +242,9 @@ class Ability 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 - + 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| @@ -268,8 +272,9 @@ class Ability end # Abilities for Role (Conference resource) - can [:index, :show], Role - + 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| @@ -287,8 +292,9 @@ class Ability can :manage, Vday, conference_id: conf_ids_for_volunteers_coordinator # Abilities for Role (Conference resource) - can [:index, :show], Role - + 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| diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index 980cc194..fcf9b384 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -141,7 +141,7 @@ describe 'User' do shared_examples 'user with any role' do before do @other_organization = create(:organization) - @other_conference = create(:conference) + @other_conference = create(:conference, organization: @other_organization) end it{ should_not be_able_to(:update, Role.find_by(name: 'organization_admin', resource: @other_organization)) } @@ -179,8 +179,6 @@ describe 'User' do it{ should_not be_able_to(:manage, other_conference) } it{ should be_able_to(:manage, my_conference) } it{ should be_able_to(:manage, organization) } - - it_behaves_like 'user with any role' end context 'when user has the role organizer' do @@ -199,8 +197,10 @@ describe 'User' do should be_able_to(:destroy, my_venue) end - it{ should be_able_to(:new, Conference) } - it{ should be_able_to(:create, Conference) } + it{ should_not be_able_to(:new, Organization)} + it{ should_not be_able_to(:create, Organization)} + it{ should_not be_able_to(:new, Conference.new) } + it{ should_not be_able_to(:create, Conference.new) } it{ should be_able_to(:manage, my_conference) } it{ should_not be_able_to(:manage, conference_public) } it{ should be_able_to(:manage, my_conference.splashpage) } From ad3d6f2f95bc5d6af98a3056747b63c3ed14bc37 Mon Sep 17 00:00:00 2001 From: shlok007 Date: Wed, 14 Jun 2017 20:42:50 +0530 Subject: [PATCH 131/185] modify admin/conference_controller_spec and not authorized error messages --- app/controllers/admin/base_controller.rb | 2 +- .../admin/conferences_controller.rb | 5 +- app/models/ability.rb | 1 + app/views/admin/conferences/new.html.haml | 1 + .../admin/comments_controller_spec.rb | 2 +- .../admin/conferences_controller_spec.rb | 210 +++++++++--------- spec/features/ability_spec.rb | 2 +- spec/features/base_controller_spec.rb | 2 +- 8 files changed, 120 insertions(+), 105 deletions(-) diff --git a/app/controllers/admin/base_controller.rb b/app/controllers/admin/base_controller.rb index 5c71ffdc..85dba43d 100644 --- a/app/controllers/admin/base_controller.rb +++ b/app/controllers/admin/base_controller.rb @@ -10,7 +10,7 @@ module Admin 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 - raise CanCan::AccessDenied.new('You are not authorized to access this area!') + raise CanCan::AccessDenied.new('You are not authorized to access this page.') end end end diff --git a/app/controllers/admin/conferences_controller.rb b/app/controllers/admin/conferences_controller.rb index f8c9ea19..bf1dfdb5 100644 --- a/app/controllers/admin/conferences_controller.rb +++ b/app/controllers/admin/conferences_controller.rb @@ -72,11 +72,14 @@ module Admin def new @conference = Conference.new + @organizations = {} + Organization.all.each do |organization| + @organizations.store(organization.name, organization.id) if can? :create, Conference.new(organization: organization) + end end def create @conference = Conference.new(conference_params) - @conference.organization = Organization.find_or_create_by(name: 'organization') if @conference.save # user that creates the conference becomes organizer of that conference current_user.add_role :organizer, @conference diff --git a/app/models/ability.rb b/app/models/ability.rb index 00a0b291..6e560a63 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -152,6 +152,7 @@ class Ability org_ids_for_organization_admin = Organization.with_role(:organization_admin, user).pluck(:id) can :manage, Organization, id: org_ids_for_organization_admin + can [:new], Conference can :manage, Conference, organization_id: org_ids_for_organization_admin conf_ids_for_organization_admin = [] org_ids_for_organization_admin.each do |org_id| diff --git a/app/views/admin/conferences/new.html.haml b/app/views/admin/conferences/new.html.haml index 014758de..0d2eb4b3 100644 --- a/app/views/admin/conferences/new.html.haml +++ b/app/views/admin/conferences/new.html.haml @@ -6,6 +6,7 @@ input_html: { required: 'required' } = f.input :short_title, hint: "A short and unique handle for your conference, using only letters, numbers, underscores, and dashes. This will be used to identify your conference in URLs etc. Example: 'froscon2011'", input_html: { required: 'required', pattern: '[a-zA-Z0-9_-]+', title: 'Only letters, numbers, underscores, and dashes.' }, prepend: conferences_url + '/' + = f.input :organization, as: :select, collection: @organizations = f.inputs 'Scheduling' do = f.input :timezone, as: :time_zone, default: Time.zone.name, hint: 'Please select in what time zone your conference will take place.' = f.input :start_date, as: :string, input_html: { id: 'conference-start-datepicker', required: 'required' } diff --git a/spec/controllers/admin/comments_controller_spec.rb b/spec/controllers/admin/comments_controller_spec.rb index 5429dabd..23b6b88a 100644 --- a/spec/controllers/admin/comments_controller_spec.rb +++ b/spec/controllers/admin/comments_controller_spec.rb @@ -51,7 +51,7 @@ describe Admin::CommentsController, type: :controller do comment get :index expect(response).to redirect_to(root_path) - expect(flash[:alert]).to match('You are not authorized to access this area!') + expect(flash[:alert]).to match('You are not authorized to access this page.') end end end diff --git a/spec/controllers/admin/conferences_controller_spec.rb b/spec/controllers/admin/conferences_controller_spec.rb index 74acbb3f..d6133c65 100644 --- a/spec/controllers/admin/conferences_controller_spec.rb +++ b/spec/controllers/admin/conferences_controller_spec.rb @@ -3,19 +3,18 @@ require 'spec_helper' describe Admin::ConferencesController do # It is necessary to use bang version of let to build roles before user - let(:conference) { create(:conference, end_date: Date.new(2014, 05, 26) + 15) } + let(:organization) { create(:organization) } + let(:conference) { create(:conference, organization: organization, end_date: Date.new(2014, 05, 26) + 15) } let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } - + let!(:organization_admin_role) { Role.find_by(name: 'organization_admin', resource: organization) } + let(:organization_admin) { create(:user, role_ids: organization_admin_role.id) } let(:organizer) { create(:user, role_ids: organizer_role.id) } let(:organizer2) { create(:user, email: 'organizer2@email.osem', role_ids: organizer_role.id) } let(:participant) { create(:user) } - shared_examples 'access as organizer' do - + shared_examples 'access as organizer or organization_admin' do describe 'PATCH #update' do - context 'valid attributes' do - it 'locates the requested conference' do patch :update, id: conference.short_title, conference: attributes_for(:conference, title: 'Example Con') expect(assigns(:conference)).to eq(conference) @@ -25,7 +24,6 @@ describe Admin::ConferencesController do patch :update, id: conference.short_title, conference: attributes_for(:conference, title: 'Example Con', short_title: 'ExCon') - conference.reload expect(conference.title).to eq('Example Con') expect(conference.short_title).to eq('ExCon') @@ -75,72 +73,6 @@ describe Admin::ConferencesController do end end - describe 'POST #create' do - context 'with valid attributes' do - it 'saves the conference to the database' do - expected = expect do - post :create, conference: - attributes_for(:conference, short_title: 'dps15') - end - expected.to change { Conference.count }.by 1 - end - - it 'redirects to conference#show' do - post :create, conference: - attributes_for(:conference, short_title: 'dps15') - - expect(response).to redirect_to admin_conference_path( - assigns[:conference].short_title) - end - - it 'creates roles for the conference' do - cfp_role = Role.find_by(name: 'cfp', resource: conference) - info_desk_role = Role.find_by(name: 'info_desk', resource: conference) - volunteers_coordinator_role = Role.find_by(name: 'volunteers_coordinator', resource: conference) - - post :create, conference: - attributes_for(:conference, short_title: 'dps15') - - expect(conference.roles.count).to eq 4 - - expect(conference.roles).to eq [organizer_role, cfp_role, info_desk_role, volunteers_coordinator_role] - end - end - - context 'with invalid attributes' do - it 'does not save the conference to the database' do - expected = expect do - post :create, conference: - attributes_for(:conference, short_title: nil) - end - expected.to_not change { Conference.count } - end - - it 're-renders the new template' do - post :create, conference: - attributes_for(:conference, short_title: nil) - expect(response).to be_success - end - end - - context 'with duplicate conference short title' do - it 'does not save the conference to the database' do - conference - expected = expect do - post :create, conference: - attributes_for(:conference, short_title: conference.short_title) - end - expected.to_not change { Conference.count } - end - - it 're-renders the new template' do - conference - post :create, conference: attributes_for(:conference, short_title: conference.short_title) - expect(response).to be_success - end - end - end - describe 'GET #edit' do it 'assigns the requested conference to conference' do get :edit, id: conference.short_title @@ -203,6 +135,74 @@ describe Admin::ConferencesController do end end end + end + + shared_examples 'access as organization_admin' do + describe 'POST #create' do + context 'with valid attributes' do + it 'saves the conference to the database' do + expected = expect do + post :create, conference: + attributes_for(:conference, short_title: 'dps15', organization: organization) + end + expected.to change { Conference.count }.by 1 + end + + it 'redirects to conference#show' do + post :create, conference: + attributes_for(:conference, short_title: 'dps15', organization: organization) + + expect(response).to redirect_to admin_conference_path( + assigns[:conference].short_title) + end + + it 'creates roles for the conference' do + cfp_role = Role.find_by(name: 'cfp', resource: conference) + info_desk_role = Role.find_by(name: 'info_desk', resource: conference) + volunteers_coordinator_role = Role.find_by(name: 'volunteers_coordinator', resource: conference) + + post :create, conference: + attributes_for(:conference, short_title: 'dps15') + + expect(conference.roles.count).to eq 4 + + expect(conference.roles).to eq [organizer_role, cfp_role, info_desk_role, volunteers_coordinator_role] + end + end + + context 'with invalid attributes' do + it 'does not save the conference to the database' do + expected = expect do + post :create, conference: + attributes_for(:conference, short_title: nil, organization: organization) + end + expected.to_not change { Conference.count } + end + + it 're-renders the new template' do + post :create, conference: + attributes_for(:conference, short_title: nil, organization: organization) + expect(response).to be_success + end + end + + context 'with duplicate conference short title' do + it 'does not save the conference to the database' do + conference + expected = expect do + post :create, conference: + attributes_for(:conference, short_title: conference.short_title, organization: organization) + end + expected.to_not change { Conference.count } + end + + it 're-renders the new template' do + conference + post :create, conference: attributes_for(:conference, short_title: conference.short_title, organization: organization) + expect(response).to be_success + end + end + end describe 'GET #new' do it 'assigns a new conference to conference' do @@ -217,14 +217,45 @@ describe Admin::ConferencesController do end end - describe 'organizer access' do + describe 'organization admin access' do + before do + sign_in(organization_admin) + end + it_behaves_like 'access as organizer or organization_admin' + it_behaves_like 'access as organization_admin' + end + + shared_examples 'access as organizer, participant or guest' do |path, message| + describe 'GET #new' do + it 'requires organizer privileges' do + get :new + expect(response).to redirect_to(send(path)) + if message + expect(flash[:alert]).to match(/#{message}/) + end + end + end + + describe 'POST #create' do + it 'requires organizer privileges' do + post :create, conference: attributes_for(:conference, + short_title: 'ExCon') + expect(response).to redirect_to(send(path)) + if message + expect(flash[:alert]).to match(/#{message}/) + end + end + end + end + + describe 'organizer access' do before do sign_in(organizer) end - it_behaves_like 'access as organizer' - + it_behaves_like 'access as organizer or organization_admin' + it_behaves_like 'access as organizer, participant or guest', :root_path, 'You are not authorized to access this page.' end shared_examples 'access as participant or guest' do |path, message| @@ -248,27 +279,6 @@ describe Admin::ConferencesController do end end - describe 'GET #new' do - it 'requires organizer privileges' do - get :new - expect(response).to redirect_to(send(path)) - if message - expect(flash[:alert]).to match(/#{message}/) - end - end - end - - describe 'POST #create' do - it 'requires organizer privileges' do - post :create, conference: attributes_for(:conference, - short_title: 'ExCon') - expect(response).to redirect_to(send(path)) - if message - expect(flash[:alert]).to match(/#{message}/) - end - end - end - describe 'PATCH #update' do it 'requires organizer privileges' do patch :update, id: conference.short_title, @@ -287,13 +297,13 @@ describe Admin::ConferencesController do sign_in(participant) end - it_behaves_like 'access as participant or guest', :root_path, 'You are not authorized to access this area!' - + it_behaves_like 'access as participant or guest', :root_path, 'You are not authorized to access this page.' + it_behaves_like 'access as organizer, participant or guest', :root_path, 'You are not authorized to access this page.' end describe 'guest access' do it_behaves_like 'access as participant or guest', :new_user_session_path - + it_behaves_like 'access as organizer, participant or guest', :new_user_session_path end end diff --git a/spec/features/ability_spec.rb b/spec/features/ability_spec.rb index fe3a3c36..8ddcb001 100644 --- a/spec/features/ability_spec.rb +++ b/spec/features/ability_spec.rb @@ -22,7 +22,7 @@ feature 'Has correct abilities' do visit admin_conference_path(conference1.short_title) expect(current_path).to eq root_path - expect(flash).to eq 'You are not authorized to access this area!' + expect(flash).to eq 'You are not authorized to access this page.' end scenario 'when user is organizer' do diff --git a/spec/features/base_controller_spec.rb b/spec/features/base_controller_spec.rb index be52c3a9..1f75f81b 100644 --- a/spec/features/base_controller_spec.rb +++ b/spec/features/base_controller_spec.rb @@ -25,7 +25,7 @@ feature 'BaseController' do it 'not an admin it redirects to root_path' do visit admin_conferences_path expect(current_path).to eq root_path - expect(flash).to eq 'You are not authorized to access this area!' + expect(flash).to eq 'You are not authorized to access this page.' end it 'an admin he can access the admin area' do From 8839a928ed83a0fca8b90f9c5a6871f9c7bc946e Mon Sep 17 00:00:00 2001 From: shlok007 Date: Wed, 14 Jun 2017 21:59:58 +0530 Subject: [PATCH 132/185] mending failing tests --- .../admin/conferences_controller.rb | 5 +---- app/models/ability.rb | 2 +- app/views/admin/conferences/new.html.haml | 1 - .../admin/conferences_controller_spec.rb | 18 +++++++++--------- .../admin/organizations_controller_spec.rb | 10 +++++----- 5 files changed, 16 insertions(+), 20 deletions(-) diff --git a/app/controllers/admin/conferences_controller.rb b/app/controllers/admin/conferences_controller.rb index bf1dfdb5..f8c9ea19 100644 --- a/app/controllers/admin/conferences_controller.rb +++ b/app/controllers/admin/conferences_controller.rb @@ -72,14 +72,11 @@ module Admin def new @conference = Conference.new - @organizations = {} - Organization.all.each do |organization| - @organizations.store(organization.name, organization.id) if can? :create, Conference.new(organization: organization) - end end def create @conference = Conference.new(conference_params) + @conference.organization = Organization.find_or_create_by(name: 'organization') if @conference.save # user that creates the conference becomes organizer of that conference current_user.add_role :organizer, @conference diff --git a/app/models/ability.rb b/app/models/ability.rb index 6e560a63..37090a49 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -152,7 +152,7 @@ class Ability org_ids_for_organization_admin = Organization.with_role(:organization_admin, user).pluck(:id) can :manage, Organization, id: org_ids_for_organization_admin - can [:new], Conference + can :new, Conference can :manage, Conference, organization_id: org_ids_for_organization_admin conf_ids_for_organization_admin = [] org_ids_for_organization_admin.each do |org_id| diff --git a/app/views/admin/conferences/new.html.haml b/app/views/admin/conferences/new.html.haml index 0d2eb4b3..014758de 100644 --- a/app/views/admin/conferences/new.html.haml +++ b/app/views/admin/conferences/new.html.haml @@ -6,7 +6,6 @@ input_html: { required: 'required' } = f.input :short_title, hint: "A short and unique handle for your conference, using only letters, numbers, underscores, and dashes. This will be used to identify your conference in URLs etc. Example: 'froscon2011'", input_html: { required: 'required', pattern: '[a-zA-Z0-9_-]+', title: 'Only letters, numbers, underscores, and dashes.' }, prepend: conferences_url + '/' - = f.input :organization, as: :select, collection: @organizations = f.inputs 'Scheduling' do = f.input :timezone, as: :time_zone, default: Time.zone.name, hint: 'Please select in what time zone your conference will take place.' = f.input :start_date, as: :string, input_html: { id: 'conference-start-datepicker', required: 'required' } diff --git a/spec/controllers/admin/conferences_controller_spec.rb b/spec/controllers/admin/conferences_controller_spec.rb index d6133c65..009e40ba 100644 --- a/spec/controllers/admin/conferences_controller_spec.rb +++ b/spec/controllers/admin/conferences_controller_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' describe Admin::ConferencesController do # It is necessary to use bang version of let to build roles before user - let(:organization) { create(:organization) } - let(:conference) { create(:conference, organization: organization, end_date: Date.new(2014, 05, 26) + 15) } + let!(:organization) { create(:organization, name: 'organization') } + let!(:conference) { create(:conference, organization: organization, end_date: Date.new(2014, 05, 26) + 15) } let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organization_admin_role) { Role.find_by(name: 'organization_admin', resource: organization) } let(:organization_admin) { create(:user, role_ids: organization_admin_role.id) } @@ -143,14 +143,14 @@ describe Admin::ConferencesController do it 'saves the conference to the database' do expected = expect do post :create, conference: - attributes_for(:conference, short_title: 'dps15', organization: organization) + attributes_for(:conference, short_title: 'dps15', organization_id: organization.id) end expected.to change { Conference.count }.by 1 end it 'redirects to conference#show' do post :create, conference: - attributes_for(:conference, short_title: 'dps15', organization: organization) + attributes_for(:conference, short_title: 'dps15', organization_id: organization.id) expect(response).to redirect_to admin_conference_path( assigns[:conference].short_title) @@ -174,14 +174,14 @@ describe Admin::ConferencesController do it 'does not save the conference to the database' do expected = expect do post :create, conference: - attributes_for(:conference, short_title: nil, organization: organization) + attributes_for(:conference, short_title: nil, organization_id: organization.id) end expected.to_not change { Conference.count } end it 're-renders the new template' do post :create, conference: - attributes_for(:conference, short_title: nil, organization: organization) + attributes_for(:conference, short_title: nil, organization_id: organization.id) expect(response).to be_success end end @@ -191,14 +191,14 @@ describe Admin::ConferencesController do conference expected = expect do post :create, conference: - attributes_for(:conference, short_title: conference.short_title, organization: organization) + attributes_for(:conference, short_title: conference.short_title, organization_id: organization.id) end expected.to_not change { Conference.count } end it 're-renders the new template' do conference - post :create, conference: attributes_for(:conference, short_title: conference.short_title, organization: organization) + post :create, conference: attributes_for(:conference, short_title: conference.short_title, organization_id: organization.id) expect(response).to be_success end end @@ -240,7 +240,7 @@ describe Admin::ConferencesController do describe 'POST #create' do it 'requires organizer privileges' do post :create, conference: attributes_for(:conference, - short_title: 'ExCon') + short_title: 'ExCon', organization_id: organization.id) expect(response).to redirect_to(send(path)) if message expect(flash[:alert]).to match(/#{message}/) diff --git a/spec/controllers/admin/organizations_controller_spec.rb b/spec/controllers/admin/organizations_controller_spec.rb index a4afc994..abe5005b 100644 --- a/spec/controllers/admin/organizations_controller_spec.rb +++ b/spec/controllers/admin/organizations_controller_spec.rb @@ -16,7 +16,7 @@ describe Admin::OrganizationsController do end it 'redirects to root' do - expect(flash[:alert]).to eq('You are not authorized to access this area!') + expect(flash[:alert]).to eq('You are not authorized to access this page.') expect(response).to redirect_to(root_path) end end @@ -27,7 +27,7 @@ describe Admin::OrganizationsController do end it 'redirects to root' do - expect(flash[:alert]).to eq('You are not authorized to access this area!') + expect(flash[:alert]).to eq('You are not authorized to access this page.') expect(response).to redirect_to(root_path) end end @@ -43,7 +43,7 @@ describe Admin::OrganizationsController do it 'redirects to root' do post :create, organization: attributes_for(:organization) - expect(flash[:alert]).to eq('You are not authorized to access this area!') + expect(flash[:alert]).to eq('You are not authorized to access this page.') expect(response).to redirect_to(root_path) end end @@ -55,7 +55,7 @@ describe Admin::OrganizationsController do organization.reload expect(organization.name).to eq(old_name) - expect(flash[:alert]).to eq('You are not authorized to access this area!') + expect(flash[:alert]).to eq('You are not authorized to access this page.') expect(response).to redirect_to(root_path) end end @@ -72,7 +72,7 @@ describe Admin::OrganizationsController do it 'redirects to root' do delete :destroy, id: organization.id - expect(flash[:alert]).to eq('You are not authorized to access this area!') + expect(flash[:alert]).to eq('You are not authorized to access this page.') expect(response).to redirect_to(root_path) end end From 7d408ee33cfdac2b35410ac2c78e8c222de7f131 Mon Sep 17 00:00:00 2001 From: shlok007 Date: Wed, 14 Jun 2017 22:51:26 +0530 Subject: [PATCH 133/185] suggested changes change description of organization_admin remove assign_role callback --- app/controllers/admin/organizations_controller.rb | 5 ----- app/models/organization.rb | 2 +- lib/tasks/roles.rake | 2 +- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/app/controllers/admin/organizations_controller.rb b/app/controllers/admin/organizations_controller.rb index 9d0dc78b..087bf7f8 100644 --- a/app/controllers/admin/organizations_controller.rb +++ b/app/controllers/admin/organizations_controller.rb @@ -1,7 +1,6 @@ module Admin class OrganizationsController < Admin::BaseController load_and_authorize_resource :organization - after_action :assign_role, only: :create def index @organizations = Organization.all @@ -46,10 +45,6 @@ module Admin private - def assign_role - current_user.add_role :organization_admin, @organization - end - def organization_params params.require(:organization).permit(:name, :description, :picture) end diff --git a/app/models/organization.rb b/app/models/organization.rb index 0fdbe5f9..de3d4f94 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -12,6 +12,6 @@ class Organization < ActiveRecord::Base private def create_roles - Role.where(name: 'organization_admin', resource: self).first_or_create(description: "For the administrators of an organization (who shall have full access to the organization and it's conferences)") + roles.where(name: 'organization_admin').first_or_create(description: 'For the administrators of an organization and its conferences') end end diff --git a/lib/tasks/roles.rake b/lib/tasks/roles.rake index 227f9642..c29d0e24 100644 --- a/lib/tasks/roles.rake +++ b/lib/tasks/roles.rake @@ -3,7 +3,7 @@ namespace :roles do task add: :environment do Organization.all.each do |org| - Role.where(name: 'organization_admin', resource: org).first_or_create(description: "For the administrators of an organization (who shall have full access to the organization and it's conferences)") + Role.where(name: 'organization_admin', resource: org).first_or_create(description: 'For the administrators of an organization and its conferences') end Conference.all.each do |c| From 21b2e5466f3ed49e0ee78da08ca4ddcb822691f3 Mon Sep 17 00:00:00 2001 From: shlok007 Date: Fri, 16 Jun 2017 03:47:34 +0530 Subject: [PATCH 134/185] refactor features/ability_spec and increase test coverage for organization --- spec/features/ability_spec.rb | 1045 ++++++++++++++-------------- spec/features/organization_spec.rb | 51 ++ 2 files changed, 562 insertions(+), 534 deletions(-) create mode 100644 spec/features/organization_spec.rb diff --git a/spec/features/ability_spec.rb b/spec/features/ability_spec.rb index 8ddcb001..41775de4 100644 --- a/spec/features/ability_spec.rb +++ b/spec/features/ability_spec.rb @@ -1,18 +1,22 @@ require 'spec_helper' feature 'Has correct abilities' do - # It is necessary to use bang version of let to build roles before user - let(:conference1) { create(:full_conference) } # user is organizer - let(:conference2) { create(:full_conference) } # user is cfp - let(:conference3) { create(:full_conference) } # user is info_desk - let(:conference6) { create(:conference) } # user is organizer, venue is not set by default + let(:organization) { create(:organization) } + # It is necessary to use bang version of let to build roles before user + let(:conference1) { create(:full_conference, organization: organization) } # user is organizer + let(:conference2) { create(:full_conference, organization: organization) } # user is cfp + let(:conference3) { create(:full_conference, organization: organization) } # user is info_desk + let(:conference6) { create(:conference, organization: organization) } # user is organizer, venue is not set by default + + let(:role_organization_admin) { Role.find_by(name: 'organization_admin', resource: organization) } let(:role_organizer_conf1) { Role.find_by(name: 'organizer', resource: conference1) } let(:role_organizer_conf6) { Role.find_by(name: 'organizer', resource: conference6) } let(:role_cfp) { Role.find_by(name: 'cfp', resource: conference2) } let(:role_info_desk) { Role.find_by(name: 'info_desk', resource: conference3) } let(:user) { create(:user) } + let(:user_organization_admin) { create(:user, role_ids: [role_organization_admin.id]) } let(:user_organizer) { create(:user, role_ids: [role_organizer_conf1.id, role_organizer_conf6.id]) } let(:user_cfp) { create(:user, role_ids: [role_cfp.id]) } let(:user_info_desk) { create(:user, role_ids: [role_info_desk.id]) } @@ -25,653 +29,626 @@ feature 'Has correct abilities' do expect(flash).to eq 'You are not authorized to access this page.' end - scenario 'when user is organizer' do - sign_in user_organizer + shared_examples 'correct abilities for organizers and organization_admin' do + scenario 'for conference attributes' do + visit admin_conference_path(conference1.short_title) + expect(current_path).to eq(admin_conference_path(conference1.short_title)) - visit admin_conference_path(conference1.short_title) - expect(current_path).to eq(admin_conference_path(conference1.short_title)) + expect(page).to have_selector('li.nav-header.nav-header-bigger a', text: 'Dashboard') + expect(page).to have_link('Basics', href: "/admin/conferences/#{conference1.short_title}/edit") + expect(page).to have_link('Contact', href: "/admin/conferences/#{conference1.short_title}/contact/edit") + expect(page).to have_link('Commercials', href: "/admin/conferences/#{conference1.short_title}/commercials") + expect(page).to have_link('Splashpage', href: "/admin/conferences/#{conference1.short_title}/splashpage") + expect(page).to have_link('Venue', href: "/admin/conferences/#{conference1.short_title}/venue") + expect(page).to have_link('Rooms', href: "/admin/conferences/#{conference1.short_title}/venue/rooms") + expect(page).to have_link('Lodgings', href: "/admin/conferences/#{conference1.short_title}/lodgings") + expect(page).to have_link('Program', href: "/admin/conferences/#{conference1.short_title}/program") + expect(page).to have_link('Call for Papers', href: "/admin/conferences/#{conference1.short_title}/program/cfps") + expect(page).to have_link('Events', href: "/admin/conferences/#{conference1.short_title}/program/events") + expect(page).to have_link('Tracks', href: "/admin/conferences/#{conference1.short_title}/program/tracks") + expect(page).to have_link('Event Types', href: "/admin/conferences/#{conference1.short_title}/program/event_types") + expect(page).to have_link('Difficulty Levels', href: "/admin/conferences/#{conference1.short_title}/program/difficulty_levels") + expect(page).to have_link('Schedules', href: "/admin/conferences/#{conference1.short_title}/schedules") + expect(page).to have_link('Reports', href: "/admin/conferences/#{conference1.short_title}/program/reports") + expect(page).to have_link('Registrations', href: "/admin/conferences/#{conference1.short_title}/registrations") + expect(page).to have_link('Registration Period', href: "/admin/conferences/#{conference1.short_title}/registration_period") + expect(page).to have_link('Questions', href: "/admin/conferences/#{conference1.short_title}/questions") + expect(page).to have_text('Donations') + expect(page).to have_link('Sponsorship Levels', href: "/admin/conferences/#{conference1.short_title}/sponsorship_levels") + expect(page).to have_link('Sponsors', href: "/admin/conferences/#{conference1.short_title}/sponsors") + expect(page).to have_link('Tickets', href: "/admin/conferences/#{conference1.short_title}/tickets") + expect(page).to have_text('Objectives') + expect(page).to have_link('Campaigns', href: "/admin/conferences/#{conference1.short_title}/campaigns") + expect(page).to have_link('Goals', href: "/admin/conferences/#{conference1.short_title}/targets") + expect(page).to have_link('E-Mails', href: "/admin/conferences/#{conference1.short_title}/emails") + expect(page).to have_link('Roles', href: "/admin/conferences/#{conference1.short_title}/roles") + expect(page).to have_link('Resources', href: "/admin/conferences/#{conference1.short_title}/resources") - expect(page).to have_selector('li.nav-header.nav-header-bigger a', text: 'Dashboard') - expect(page).to have_link('Basics', href: "/admin/conferences/#{conference1.short_title}/edit") - expect(page).to have_link('Contact', href: "/admin/conferences/#{conference1.short_title}/contact/edit") - expect(page).to have_link('Commercials', href: "/admin/conferences/#{conference1.short_title}/commercials") - expect(page).to have_link('Splashpage', href: "/admin/conferences/#{conference1.short_title}/splashpage") - expect(page).to have_link('Venue', href: "/admin/conferences/#{conference1.short_title}/venue") - expect(page).to have_link('Rooms', href: "/admin/conferences/#{conference1.short_title}/venue/rooms") - expect(page).to have_link('Lodgings', href: "/admin/conferences/#{conference1.short_title}/lodgings") - expect(page).to have_link('Program', href: "/admin/conferences/#{conference1.short_title}/program") - expect(page).to have_link('Call for Papers', href: "/admin/conferences/#{conference1.short_title}/program/cfps") - expect(page).to have_link('Events', href: "/admin/conferences/#{conference1.short_title}/program/events") - expect(page).to have_link('Tracks', href: "/admin/conferences/#{conference1.short_title}/program/tracks") - expect(page).to have_link('Event Types', href: "/admin/conferences/#{conference1.short_title}/program/event_types") - expect(page).to have_link('Difficulty Levels', href: "/admin/conferences/#{conference1.short_title}/program/difficulty_levels") - expect(page).to have_link('Schedules', href: "/admin/conferences/#{conference1.short_title}/schedules") - expect(page).to have_link('Reports', href: "/admin/conferences/#{conference1.short_title}/program/reports") - expect(page).to have_link('Registrations', href: "/admin/conferences/#{conference1.short_title}/registrations") - expect(page).to have_link('Registration Period', href: "/admin/conferences/#{conference1.short_title}/registration_period") - expect(page).to have_link('Questions', href: "/admin/conferences/#{conference1.short_title}/questions") - expect(page).to have_text('Donations') - expect(page).to have_link('Sponsorship Levels', href: "/admin/conferences/#{conference1.short_title}/sponsorship_levels") - expect(page).to have_link('Sponsors', href: "/admin/conferences/#{conference1.short_title}/sponsors") - expect(page).to have_link('Tickets', href: "/admin/conferences/#{conference1.short_title}/tickets") - expect(page).to have_text('Objectives') - expect(page).to have_link('Campaigns', href: "/admin/conferences/#{conference1.short_title}/campaigns") - expect(page).to have_link('Goals', href: "/admin/conferences/#{conference1.short_title}/targets") - expect(page).to have_link('E-Mails', href: "/admin/conferences/#{conference1.short_title}/emails") - expect(page).to have_link('Roles', href: "/admin/conferences/#{conference1.short_title}/roles") - expect(page).to have_link('Resources', href: "/admin/conferences/#{conference1.short_title}/resources") + visit admin_conference_path(conference6.short_title) + expect(page).to have_link('Add venue', href: "/admin/conferences/#{conference6.short_title}/venue/new") - visit admin_conference_path(conference6.short_title) - expect(page).to have_link('Add venue', href: "/admin/conferences/#{conference6.short_title}/venue/new") + visit edit_admin_conference_path(conference1.short_title) + expect(current_path).to eq(edit_admin_conference_path(conference1.short_title)) - visit edit_admin_conference_path(conference1.short_title) - expect(current_path).to eq(edit_admin_conference_path(conference1.short_title)) + visit edit_admin_conference_contact_path(conference1.short_title) + expect(current_path).to eq(edit_admin_conference_contact_path(conference1.short_title)) - visit edit_admin_conference_contact_path(conference1.short_title) - expect(current_path).to eq(edit_admin_conference_contact_path(conference1.short_title)) + visit admin_conference_commercials_path(conference1.short_title) + expect(current_path).to eq(admin_conference_commercials_path(conference1.short_title)) - visit admin_conference_commercials_path(conference1.short_title) - expect(current_path).to eq(admin_conference_commercials_path(conference1.short_title)) + visit new_admin_conference_splashpage_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_splashpage_path(conference1.short_title)) - visit new_admin_conference_splashpage_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_splashpage_path(conference1.short_title)) + visit edit_admin_conference_splashpage_path(conference1.short_title) + expect(current_path).to eq(edit_admin_conference_splashpage_path(conference1.short_title)) - visit edit_admin_conference_splashpage_path(conference1.short_title) - expect(current_path).to eq(edit_admin_conference_splashpage_path(conference1.short_title)) + visit new_admin_conference_venue_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_venue_path(conference1.short_title)) - visit new_admin_conference_venue_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_venue_path(conference1.short_title)) + conference1.venue = create(:venue) + visit edit_admin_conference_venue_path(conference1.short_title) + expect(current_path).to eq(edit_admin_conference_venue_path(conference1.short_title)) - conference1.venue = create(:venue) - visit edit_admin_conference_venue_path(conference1.short_title) - expect(current_path).to eq(edit_admin_conference_venue_path(conference1.short_title)) + visit admin_conference_venue_rooms_path(conference1.short_title) + expect(current_path).to eq(admin_conference_venue_rooms_path(conference1.short_title)) - visit admin_conference_venue_rooms_path(conference1.short_title) - expect(current_path).to eq(admin_conference_venue_rooms_path(conference1.short_title)) + create(:room, venue: conference1.venue) + visit edit_admin_conference_venue_room_path(conference1.short_title, conference1.venue.rooms.first) + expect(current_path).to eq(edit_admin_conference_venue_room_path(conference1.short_title, conference1.venue.rooms.first)) - create(:room, venue: conference1.venue) - visit edit_admin_conference_venue_room_path(conference1.short_title, conference1.venue.rooms.first) - expect(current_path).to eq(edit_admin_conference_venue_room_path(conference1.short_title, conference1.venue.rooms.first)) + visit admin_conference_lodgings_path(conference1.short_title) + expect(current_path).to eq(admin_conference_lodgings_path(conference1.short_title)) - visit admin_conference_lodgings_path(conference1.short_title) - expect(current_path).to eq(admin_conference_lodgings_path(conference1.short_title)) + visit new_admin_conference_lodging_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_lodging_path(conference1.short_title)) - visit new_admin_conference_lodging_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_lodging_path(conference1.short_title)) + create(:lodging, conference: conference1) + visit edit_admin_conference_lodging_path(conference1.short_title, conference1.lodgings.first) + expect(current_path).to eq(edit_admin_conference_lodging_path(conference1.short_title, conference1.lodgings.first)) - create(:lodging, conference: conference1) - visit edit_admin_conference_lodging_path(conference1.short_title, conference1.lodgings.first) - expect(current_path).to eq(edit_admin_conference_lodging_path(conference1.short_title, conference1.lodgings.first)) + visit new_admin_conference_program_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_program_path(conference1.short_title)) - visit new_admin_conference_program_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_program_path(conference1.short_title)) + visit edit_admin_conference_program_path(conference1.short_title) + expect(current_path).to eq(edit_admin_conference_program_path(conference1.short_title)) - visit edit_admin_conference_program_path(conference1.short_title) - expect(current_path).to eq(edit_admin_conference_program_path(conference1.short_title)) + visit new_admin_conference_program_cfp_path(conference1.short_title) + expect(current_path).to eq root_path + + conference1.program.cfp.destroy! + visit new_admin_conference_program_cfp_path(conference1.short_title) + expect(current_path).to eq new_admin_conference_program_cfp_path(conference1.short_title) + create(:cfp, program: conference1.program) + + visit edit_admin_conference_program_cfp_path(conference1.short_title, conference1.program.cfp) + expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference1.short_title, conference1.program.cfp)) - visit new_admin_conference_program_cfp_path(conference1.short_title) - expect(current_path).to eq root_path + visit admin_conference_program_events_path(conference1.short_title) + expect(current_path).to eq(admin_conference_program_events_path(conference1.short_title)) - conference1.program.cfp.destroy! - visit new_admin_conference_program_cfp_path(conference1.short_title) - expect(current_path).to eq new_admin_conference_program_cfp_path(conference1.short_title) - create(:cfp, program: conference1.program) + create(:event, program: conference1.program) + visit edit_admin_conference_program_event_path(conference1.short_title, conference1.program.events.first) + expect(current_path).to eq(edit_admin_conference_program_event_path(conference1.short_title, conference1.program.events.first)) - visit edit_admin_conference_program_cfp_path(conference1.short_title, conference1.program.cfp) - expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference1.short_title, conference1.program.cfp)) + visit admin_conference_program_event_types_path(conference1.short_title) + expect(current_path).to eq(admin_conference_program_event_types_path(conference1.short_title)) - visit admin_conference_program_events_path(conference1.short_title) - expect(current_path).to eq(admin_conference_program_events_path(conference1.short_title)) + visit new_admin_conference_program_event_type_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_program_event_type_path(conference1.short_title)) - create(:event, program: conference1.program) - visit edit_admin_conference_program_event_path(conference1.short_title, conference1.program.events.first) - expect(current_path).to eq(edit_admin_conference_program_event_path(conference1.short_title, conference1.program.events.first)) + visit edit_admin_conference_program_event_type_path(conference1.short_title, conference1.program.event_types.first) + expect(current_path).to eq(edit_admin_conference_program_event_type_path(conference1.short_title, conference1.program.event_types.first)) - visit admin_conference_program_event_types_path(conference1.short_title) - expect(current_path).to eq(admin_conference_program_event_types_path(conference1.short_title)) + visit admin_conference_program_difficulty_levels_path(conference1.short_title) + expect(current_path).to eq(admin_conference_program_difficulty_levels_path(conference1.short_title)) - visit new_admin_conference_program_event_type_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_program_event_type_path(conference1.short_title)) + visit new_admin_conference_program_difficulty_level_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_program_difficulty_level_path(conference1.short_title)) - visit edit_admin_conference_program_event_type_path(conference1.short_title, conference1.program.event_types.first) - expect(current_path).to eq(edit_admin_conference_program_event_type_path(conference1.short_title, conference1.program.event_types.first)) + visit edit_admin_conference_program_difficulty_level_path(conference1.short_title, conference1.program.difficulty_levels.first) + expect(current_path).to eq(edit_admin_conference_program_difficulty_level_path(conference1.short_title, conference1.program.difficulty_levels.first)) - visit admin_conference_program_difficulty_levels_path(conference1.short_title) - expect(current_path).to eq(admin_conference_program_difficulty_levels_path(conference1.short_title)) + visit admin_conference_schedules_path(conference1.short_title) + expect(current_path).to eq(admin_conference_schedules_path(conference1.short_title)) - visit new_admin_conference_program_difficulty_level_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_program_difficulty_level_path(conference1.short_title)) + create(:schedule, program: conference1.program) + visit admin_conference_schedule_path(conference1.short_title, conference1.program.schedules.first) + expect(current_path).to eq(admin_conference_schedule_path(conference1.short_title, conference1.program.schedules.first)) - visit edit_admin_conference_program_difficulty_level_path(conference1.short_title, conference1.program.difficulty_levels.first) - expect(current_path).to eq(edit_admin_conference_program_difficulty_level_path(conference1.short_title, conference1.program.difficulty_levels.first)) + visit admin_conference_program_reports_path(conference1.short_title) + expect(current_path).to eq(admin_conference_program_reports_path(conference1.short_title)) - visit admin_conference_schedules_path(conference1.short_title) - expect(current_path).to eq(admin_conference_schedules_path(conference1.short_title)) + visit admin_conference_registrations_path(conference1.short_title) + expect(current_path).to eq(admin_conference_registrations_path(conference1.short_title)) - create(:schedule, program: conference1.program) - visit admin_conference_schedule_path(conference1.short_title, conference1.program.schedules.first) - expect(current_path).to eq(admin_conference_schedule_path(conference1.short_title, conference1.program.schedules.first)) + create(:registration, user: create(:user), conference: conference1) + visit edit_admin_conference_registration_path(conference1.short_title, conference1.registrations.first) + expect(current_path).to eq(edit_admin_conference_registration_path(conference1.short_title, conference1.registrations.first)) - visit admin_conference_program_reports_path(conference1.short_title) - expect(current_path).to eq(admin_conference_program_reports_path(conference1.short_title)) + visit new_admin_conference_registration_period_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_registration_period_path(conference1.short_title)) - visit admin_conference_registrations_path(conference1.short_title) - expect(current_path).to eq(admin_conference_registrations_path(conference1.short_title)) + create(:registration_period, conference: conference1) + visit edit_admin_conference_registration_period_path(conference1.short_title) + expect(current_path).to eq(edit_admin_conference_registration_period_path(conference1.short_title)) - create(:registration, user: create(:user), conference: conference1) - visit edit_admin_conference_registration_path(conference1.short_title, conference1.registrations.first) - expect(current_path).to eq(edit_admin_conference_registration_path(conference1.short_title, conference1.registrations.first)) + visit admin_conference_questions_path(conference1.short_title) + expect(current_path).to eq(admin_conference_questions_path(conference1.short_title)) - visit new_admin_conference_registration_period_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_registration_period_path(conference1.short_title)) + visit admin_conference_sponsorship_levels_path(conference1.short_title) + expect(current_path).to eq(admin_conference_sponsorship_levels_path(conference1.short_title)) - create(:registration_period, conference: conference1) - visit edit_admin_conference_registration_period_path(conference1.short_title) - expect(current_path).to eq(edit_admin_conference_registration_period_path(conference1.short_title)) + visit new_admin_conference_sponsorship_level_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_sponsorship_level_path(conference1.short_title)) - visit admin_conference_questions_path(conference1.short_title) - expect(current_path).to eq(admin_conference_questions_path(conference1.short_title)) + create(:sponsorship_level, conference: conference1) + visit edit_admin_conference_sponsorship_level_path(conference1.short_title, conference1.sponsorship_levels.first) + expect(current_path).to eq(edit_admin_conference_sponsorship_level_path(conference1.short_title, conference1.sponsorship_levels.first)) - visit admin_conference_sponsorship_levels_path(conference1.short_title) - expect(current_path).to eq(admin_conference_sponsorship_levels_path(conference1.short_title)) + visit admin_conference_sponsors_path(conference1.short_title) + expect(current_path).to eq(admin_conference_sponsors_path(conference1.short_title)) - visit new_admin_conference_sponsorship_level_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_sponsorship_level_path(conference1.short_title)) + visit new_admin_conference_sponsor_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_sponsor_path(conference1.short_title)) - create(:sponsorship_level, conference: conference1) - visit edit_admin_conference_sponsorship_level_path(conference1.short_title, conference1.sponsorship_levels.first) - expect(current_path).to eq(edit_admin_conference_sponsorship_level_path(conference1.short_title, conference1.sponsorship_levels.first)) + create(:sponsor, conference: conference1, sponsorship_level: conference1.sponsorship_levels.first) + visit edit_admin_conference_sponsor_path(conference1.short_title, conference1.sponsors.first) + expect(current_path).to eq(edit_admin_conference_sponsor_path(conference1.short_title, conference1.sponsors.first)) - visit admin_conference_sponsors_path(conference1.short_title) - expect(current_path).to eq(admin_conference_sponsors_path(conference1.short_title)) + visit admin_conference_tickets_path(conference1.short_title) + expect(current_path).to eq(admin_conference_tickets_path(conference1.short_title)) - visit new_admin_conference_sponsor_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_sponsor_path(conference1.short_title)) + visit new_admin_conference_ticket_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_ticket_path(conference1.short_title)) - create(:sponsor, conference: conference1, sponsorship_level: conference1.sponsorship_levels.first) - visit edit_admin_conference_sponsor_path(conference1.short_title, conference1.sponsors.first) - expect(current_path).to eq(edit_admin_conference_sponsor_path(conference1.short_title, conference1.sponsors.first)) + create(:ticket, conference: conference1) + visit edit_admin_conference_ticket_path(conference1.short_title, conference1.tickets.first) + expect(current_path).to eq(edit_admin_conference_ticket_path(conference1.short_title, conference1.tickets.first)) - visit admin_conference_tickets_path(conference1.short_title) - expect(current_path).to eq(admin_conference_tickets_path(conference1.short_title)) + visit admin_conference_campaigns_path(conference1.short_title) + expect(current_path).to eq(admin_conference_campaigns_path(conference1.short_title)) - visit new_admin_conference_ticket_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_ticket_path(conference1.short_title)) + visit new_admin_conference_campaign_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_campaign_path(conference1.short_title)) - create(:ticket, conference: conference1) - visit edit_admin_conference_ticket_path(conference1.short_title, conference1.tickets.first) - expect(current_path).to eq(edit_admin_conference_ticket_path(conference1.short_title, conference1.tickets.first)) + create(:campaign, conference: conference1) + visit edit_admin_conference_campaign_path(conference1.short_title, conference1.campaigns.first) + expect(current_path).to eq(edit_admin_conference_campaign_path(conference1.short_title, conference1.campaigns.first)) - visit admin_conference_campaigns_path(conference1.short_title) - expect(current_path).to eq(admin_conference_campaigns_path(conference1.short_title)) + visit admin_conference_targets_path(conference1.short_title) + expect(current_path).to eq(admin_conference_targets_path(conference1.short_title)) - visit new_admin_conference_campaign_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_campaign_path(conference1.short_title)) + visit new_admin_conference_target_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_target_path(conference1.short_title)) - create(:campaign, conference: conference1) - visit edit_admin_conference_campaign_path(conference1.short_title, conference1.campaigns.first) - expect(current_path).to eq(edit_admin_conference_campaign_path(conference1.short_title, conference1.campaigns.first)) + create(:target, conference: conference1) + visit edit_admin_conference_target_path(conference1.short_title, conference1.targets.first) + expect(current_path).to eq(edit_admin_conference_target_path(conference1.short_title, conference1.targets.first)) - visit admin_conference_targets_path(conference1.short_title) - expect(current_path).to eq(admin_conference_targets_path(conference1.short_title)) + visit admin_conference_program_tracks_path(conference1.short_title) + expect(current_path).to eq(admin_conference_program_tracks_path(conference1.short_title)) - visit new_admin_conference_target_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_target_path(conference1.short_title)) + visit admin_conference_roles_path(conference1.short_title) + expect(current_path).to eq(admin_conference_roles_path(conference1.short_title)) - create(:target, conference: conference1) - visit edit_admin_conference_target_path(conference1.short_title, conference1.targets.first) - expect(current_path).to eq(edit_admin_conference_target_path(conference1.short_title, conference1.targets.first)) + visit admin_conference_emails_path(conference1.short_title) + expect(current_path).to eq(admin_conference_emails_path(conference1.short_title)) - visit admin_conference_program_tracks_path(conference1.short_title) - expect(current_path).to eq(admin_conference_program_tracks_path(conference1.short_title)) + visit admin_conference_resources_path(conference1.short_title) + expect(current_path).to eq(admin_conference_resources_path(conference1.short_title)) - visit admin_conference_roles_path(conference1.short_title) - expect(current_path).to eq(admin_conference_roles_path(conference1.short_title)) + visit new_admin_conference_resource_path(conference1.short_title) + expect(current_path).to eq(new_admin_conference_resource_path(conference1.short_title)) - visit admin_conference_emails_path(conference1.short_title) - expect(current_path).to eq(admin_conference_emails_path(conference1.short_title)) + create(:resource, conference: conference1) + visit edit_admin_conference_resource_path(conference1.short_title, conference1.resources.first) + expect(current_path).to eq(edit_admin_conference_resource_path(conference1.short_title, conference1.resources.first)) - visit admin_conference_resources_path(conference1.short_title) - expect(current_path).to eq(admin_conference_resources_path(conference1.short_title)) - - visit new_admin_conference_resource_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_resource_path(conference1.short_title)) - - create(:resource, conference: conference1) - visit edit_admin_conference_resource_path(conference1.short_title, conference1.resources.first) - expect(current_path).to eq(edit_admin_conference_resource_path(conference1.short_title, conference1.resources.first)) - - visit admin_revision_history_path - expect(current_path).to eq(admin_revision_history_path) + visit admin_revision_history_path + expect(current_path).to eq(admin_revision_history_path) + end end - scenario 'when user is cfp' do - sign_in user_cfp + context 'when user is organization_admin' do + before do + sign_in user_organization_admin + end - visit admin_conference_path(conference2.short_title) - expect(current_path).to eq(admin_conference_path(conference2.short_title)) + scenario 'can manage organization' do + visit admin_organizations_path + expect(current_path).to eq(admin_organizations_path) - expect(page).to have_selector('li.nav-header.nav-header-bigger a', text: 'Dashboard') - expect(page).to_not have_link('Basics', href: "/admin/conferences/#{conference2.short_title}/edit") - expect(page).to have_text('Basics') - expect(page).to_not have_link('Contact', href: "/admin/conferences/#{conference2.short_title}/contact/edit") - expect(page).to have_link('Commercials', href: "/admin/conferences/#{conference2.short_title}/commercials") - expect(page).to_not have_link('Splashpage', href: "/admin/conferences/#{conference2.short_title}/splashpage") - expect(page).to have_link('Venue', href: "/admin/conferences/#{conference2.short_title}/venue") - expect(page).to have_link('Rooms', href: "/admin/conferences/#{conference2.short_title}/venue/rooms") - expect(page).to_not have_link('Lodgings', href: "/admin/conferences/#{conference2.short_title}/lodgings") - expect(page).to have_link('Program', href: "/admin/conferences/#{conference2.short_title}/program") - expect(page).to have_link('Call for Papers', href: "/admin/conferences/#{conference2.short_title}/program/cfps") - expect(page).to have_link('Events', href: "/admin/conferences/#{conference2.short_title}/program/events") - expect(page).to have_link('Tracks', href: "/admin/conferences/#{conference2.short_title}/program/tracks") - expect(page).to have_link('Event Types', href: "/admin/conferences/#{conference2.short_title}/program/event_types") - expect(page).to have_link('Difficulty Levels', href: "/admin/conferences/#{conference2.short_title}/program/difficulty_levels") - expect(page).to have_link('Schedules', href: "/admin/conferences/#{conference2.short_title}/schedules") - expect(page).to have_link('Reports', href: "/admin/conferences/#{conference2.short_title}/program/reports") - expect(page).to_not have_link('Registrations', href: "/admin/conferences/#{conference2.short_title}/registrations") - expect(page).to_not have_link('Registration Period', href: "/admin/conferences/#{conference2.short_title}/registration_period") - expect(page).to_not have_link('Questions', href: "/admin/conferences/#{conference2.short_title}/questions") - expect(page).to_not have_text('Donations') - expect(page).to_not have_link('Sponsorship Levels', href: "/admin/conferences/#{conference2.short_title}/supporter_levels") - expect(page).to_not have_link('Sponsors', href: "/admin/conferences/#{conference2.short_title}/sponsors") - expect(page).to_not have_link('Tickets', href: "/admin/conferences/#{conference2.short_title}/tickets") - expect(page).to_not have_text('Objectives') - expect(page).to_not have_link('Campaigns', href: "/admin/conferences/#{conference2.short_title}/campaigns") - expect(page).to_not have_link('Goals', href: "/admin/conferences/#{conference2.short_title}/targets") - expect(page).to have_link('E-Mails', href: "/admin/conferences/#{conference2.short_title}/emails") - expect(page).to have_link('Roles', href: "/admin/conferences/#{conference2.short_title}/roles") - expect(page).to have_link('Resources', href: "/admin/conferences/#{conference2.short_title}/resources") + visit edit_admin_organization_path(organization) + expect(current_path).to eq(edit_admin_organization_path(organization)) - visit edit_admin_conference_path(conference2.short_title) - expect(current_path).to eq(root_path) + visit new_admin_organization_path + expect(current_path).to eq(root_path) + end - visit edit_admin_conference_contact_path(conference2.short_title) - expect(current_path).to eq(root_path) - - visit admin_conference_commercials_path(conference2.short_title) - expect(current_path).to eq(admin_conference_commercials_path(conference2.short_title)) - - visit new_admin_conference_splashpage_path(conference2.short_title) - expect(current_path).to eq(root_path) - - visit edit_admin_conference_splashpage_path(conference2.short_title) - expect(current_path).to eq(root_path) - - visit new_admin_conference_venue_path(conference2.short_title) - expect(current_path).to eq(root_path) - - conference2.venue = create(:venue) - visit edit_admin_conference_venue_path(conference2.short_title) - expect(current_path).to eq(root_path) - - visit admin_conference_venue_rooms_path(conference2.short_title) - expect(current_path).to eq(admin_conference_venue_rooms_path(conference2.short_title)) - create(:room, venue: conference2.venue) - visit edit_admin_conference_venue_room_path(conference2.short_title, conference2.venue.rooms.first) - expect(current_path).to eq(edit_admin_conference_venue_room_path(conference2.short_title, conference2.venue.rooms.first)) - - visit admin_conference_lodgings_path(conference2.short_title) - expect(current_path).to eq(root_path) - - visit new_admin_conference_lodging_path(conference2.short_title) - expect(current_path).to eq(root_path) - - create(:lodging, conference: conference2) - visit edit_admin_conference_lodging_path(conference2.short_title, conference2.lodgings.first) - expect(current_path).to eq(root_path) - - visit new_admin_conference_program_path(conference2.short_title) - expect(current_path).to eq(new_admin_conference_program_path(conference2.short_title)) - - visit edit_admin_conference_program_path(conference2.short_title) - expect(current_path).to eq(edit_admin_conference_program_path(conference2.short_title)) - - visit new_admin_conference_program_cfp_path(conference2.short_title) - expect(current_path).to eq root_path - - conference2.program.cfp.destroy! - visit new_admin_conference_program_cfp_path(conference2.short_title) - expect(current_path).to eq new_admin_conference_program_cfp_path(conference2.short_title) - create(:cfp, program: conference2.program) - - visit edit_admin_conference_program_cfp_path(conference2.short_title, conference2.program.cfp) - expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference2.short_title, conference2.program.cfp)) - - visit admin_conference_program_events_path(conference2.short_title) - expect(current_path).to eq(admin_conference_program_events_path(conference2.short_title)) - - create(:event, program: conference2.program) - visit edit_admin_conference_program_event_path(conference2.short_title, conference2.program.events.first) - expect(current_path).to eq(edit_admin_conference_program_event_path(conference2.short_title, conference2.program.events.first)) - - visit admin_conference_program_event_types_path(conference2.short_title) - expect(current_path).to eq(admin_conference_program_event_types_path(conference2.short_title)) - - visit new_admin_conference_program_event_type_path(conference2.short_title) - expect(current_path).to eq(new_admin_conference_program_event_type_path(conference2.short_title)) - - visit edit_admin_conference_program_event_type_path(conference2.short_title, conference2.program.event_types.first) - expect(current_path).to eq(edit_admin_conference_program_event_type_path(conference2.short_title, conference2.program.event_types.first)) - - visit admin_conference_program_difficulty_levels_path(conference2.short_title) - expect(current_path).to eq(admin_conference_program_difficulty_levels_path(conference2.short_title)) - - visit new_admin_conference_program_difficulty_level_path(conference2.short_title) - expect(current_path).to eq(new_admin_conference_program_difficulty_level_path(conference2.short_title)) - - visit edit_admin_conference_program_difficulty_level_path(conference2.short_title, conference2.program.difficulty_levels.first) - expect(current_path).to eq(edit_admin_conference_program_difficulty_level_path(conference2.short_title, conference2.program.difficulty_levels.first)) - - visit admin_conference_schedules_path(conference2.short_title) - expect(current_path).to eq(admin_conference_schedules_path(conference2.short_title)) - - create(:schedule, program: conference2.program) - visit admin_conference_schedule_path(conference2.short_title, conference2.program.schedules.first) - expect(current_path).to eq(admin_conference_schedule_path(conference2.short_title, conference2.program.schedules.first)) - - visit admin_conference_program_reports_path(conference2.short_title) - expect(current_path).to eq(admin_conference_program_reports_path(conference2.short_title)) - - visit admin_conference_registrations_path(conference2.short_title) - expect(current_path).to eq(admin_conference_registrations_path(conference2.short_title)) - - create(:registration, user: create(:user), conference: conference2) - visit edit_admin_conference_registration_path(conference2.short_title, conference2.registrations.first) - expect(current_path).to eq(root_path) - - visit new_admin_conference_registration_period_path(conference2.short_title) - expect(current_path).to eq(root_path) - - create(:registration_period, conference: conference2) - visit edit_admin_conference_registration_period_path(conference2.short_title) - expect(current_path).to eq(root_path) - - visit admin_conference_questions_path(conference2.short_title) - expect(current_path).to eq(root_path) - - visit admin_conference_sponsorship_levels_path(conference2.short_title) - expect(current_path).to eq(root_path) - - visit new_admin_conference_sponsorship_level_path(conference2.short_title) - expect(current_path).to eq(root_path) - - create(:sponsorship_level, conference: conference2) - visit edit_admin_conference_sponsorship_level_path(conference2.short_title, conference2.sponsorship_levels.first) - expect(current_path).to eq(root_path) - - visit admin_conference_sponsors_path(conference2.short_title) - expect(current_path).to eq(root_path) - - visit new_admin_conference_sponsor_path(conference2.short_title) - expect(current_path).to eq(root_path) - - create(:sponsor, conference: conference2, sponsorship_level: conference2.sponsorship_levels.first) - visit edit_admin_conference_sponsor_path(conference2.short_title, conference2.sponsors.first) - expect(current_path).to eq(root_path) - - visit admin_conference_tickets_path(conference2.short_title) - expect(current_path).to eq(root_path) - - visit new_admin_conference_ticket_path(conference2.short_title) - expect(current_path).to eq(root_path) - - create(:ticket, conference: conference2) - visit edit_admin_conference_ticket_path(conference2.short_title, conference2.tickets.first) - expect(current_path).to eq(root_path) - - visit admin_conference_campaigns_path(conference2.short_title) - expect(current_path).to eq(root_path) - - visit new_admin_conference_campaign_path(conference2.short_title) - expect(current_path).to eq(root_path) - - create(:campaign, conference: conference2) - visit edit_admin_conference_campaign_path(conference2.short_title, conference2.campaigns.first) - expect(current_path).to eq(root_path) - - visit admin_conference_targets_path(conference2.short_title) - expect(current_path).to eq(root_path) - - visit new_admin_conference_target_path(conference2.short_title) - expect(current_path).to eq(root_path) - - create(:target, conference: conference2) - visit edit_admin_conference_target_path(conference2.short_title, conference2.targets.first) - expect(current_path).to eq(root_path) - - visit admin_conference_program_tracks_path(conference2.short_title) - expect(current_path).to eq(admin_conference_program_tracks_path(conference2.short_title)) - - visit admin_conference_roles_path(conference2.short_title) - expect(current_path).to eq(admin_conference_roles_path(conference2.short_title)) - - visit admin_conference_emails_path(conference2.short_title) - expect(current_path).to eq(admin_conference_emails_path(conference2.short_title)) - - visit admin_conference_resources_path(conference2.short_title) - expect(current_path).to eq(admin_conference_resources_path(conference2.short_title)) - - visit new_admin_conference_resource_path(conference2.short_title) - expect(current_path).to eq(new_admin_conference_resource_path(conference2.short_title)) - - create(:resource, conference: conference2) - visit edit_admin_conference_resource_path(conference2.short_title, conference2.resources.first) - expect(current_path).to eq(edit_admin_conference_resource_path(conference2.short_title, conference2.resources.first)) - - visit admin_revision_history_path - expect(current_path).to eq(root_path) + it_behaves_like 'correct abilities for organizers and organization_admin' end - scenario 'when user is info desk' do - sign_in user_info_desk + context 'when user is organizer' do + before do + sign_in user_organizer + end - visit admin_conference_path(conference3.short_title) - expect(current_path).to eq(admin_conference_path(conference3.short_title)) + scenario 'cannot manage organization' do + visit admin_organizations_path + expect(current_path).to eq(admin_organizations_path) - expect(page).to have_selector('li.nav-header.nav-header-bigger a', text: 'Dashboard') - expect(page).to_not have_link('Basics', href: "/admin/conferences/#{conference3.short_title}/edit") - expect(page).to have_text('Basics') - expect(page).to_not have_link('Contact', href: "/admin/conferences/#{conference3.short_title}/contact/edit") - expect(page).to have_link('Commercials', href: "/admin/conferences/#{conference3.short_title}/commercials") - expect(page).to_not have_link('Splashpage', href: "/admin/conferences/#{conference3.short_title}/splashpage") - expect(page).to_not have_link('Venue', href: "/admin/conferences/#{conference3.short_title}/venue") - expect(page).to_not have_link('Rooms', href: "/admin/conferences/#{conference3.short_title}/venue/rooms") - expect(page).to_not have_link('Lodgings', href: "/admin/conferences/#{conference3.short_title}/lodgings") - expect(page).to_not have_link('Program', href: "/admin/conferences/#{conference3.short_title}/program") - expect(page).to_not have_link('Call for Papers', href: "/admin/conferences/#{conference2.short_title}/program/cfp") - expect(page).to_not have_link('Events', href: "/admin/conferences/#{conference3.short_title}/program/events") - expect(page).to_not have_link('Tracks', href: "/admin/conferences/#{conference3.short_title}/program/tracks") - expect(page).to_not have_link('Event Types', href: "/admin/conferences/#{conference3.short_title}/program/event_types") - expect(page).to_not have_link('Difficulty Levels', href: "/admin/conferences/#{conference3.short_title}/program/difficulty_levels") - expect(page).to_not have_link('Schedules', href: "/admin/conferences/#{conference3.short_title}/schedules") - expect(page).to_not have_link('Reports', href: "/admin/conferences/#{conference3.short_title}/program/reports") - expect(page).to have_link('Registrations', href: "/admin/conferences/#{conference3.short_title}/registrations") - expect(page).to_not have_link('Registration Period', href: "/admin/conferences/#{conference3.short_title}/registration_period") - expect(page).to have_link('Questions', href: "/admin/conferences/#{conference3.short_title}/questions") - expect(page).to_not have_text('Donations') - expect(page).to_not have_link('Sponsorship Levels', href: "/admin/conferences/#{conference3.short_title}/sponsorship_levels") - expect(page).to_not have_link('Sponsors', href: "/admin/conferences/#{conference3.short_title}/sponsors") - expect(page).to_not have_link('Tickets', href: "/admin/conferences/#{conference3.short_title}/tickets") - expect(page).to_not have_text('Objectives') - expect(page).to_not have_link('Campaigns', href: "/admin/conferences/#{conference3.short_title}/campaigns") - expect(page).to_not have_link('Goals', href: "/admin/conferences/#{conference3.short_title}/targets") - expect(page).to_not have_link('E-Mails', href: "/admin/conferences/#{conference3.short_title}/emails") - expect(page).to have_link('Roles', href: "/admin/conferences/#{conference3.short_title}/roles") - expect(page).to have_link('Resources', href: "/admin/conferences/#{conference3.short_title}/resources") + visit edit_admin_organization_path(organization) + expect(current_path).to eq(root_path) - visit edit_admin_conference_path(conference3.short_title) - expect(current_path).to eq(root_path) + visit new_admin_organization_path + expect(current_path).to eq(root_path) + end - visit edit_admin_conference_contact_path(conference3.short_title) - expect(current_path).to eq(root_path) + it_behaves_like 'correct abilities for organizers and organization_admin' + end - visit admin_conference_commercials_path(conference3.short_title) - expect(current_path).to eq(admin_conference_commercials_path(conference3.short_title)) + shared_examples 'correct abilities for cfps and info_desk' do |role| + scenario 'correct ability' do + if role == 'cfp' + conference = conference2 + elsif role == 'info_desk' + conference = conference3 + end - visit new_admin_conference_splashpage_path(conference3.short_title) - expect(current_path).to eq(root_path) + visit admin_conference_path(conference.short_title) + expect(current_path).to eq(admin_conference_path(conference.short_title)) - visit edit_admin_conference_splashpage_path(conference3.short_title) - expect(current_path).to eq(root_path) + 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('Lodgings', href: "/admin/conferences/#{conference.short_title}/lodgings") + expect(page).to_not have_link('Registration Period', href: "/admin/conferences/#{conference.short_title}/registration_period") + 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 have_link('Roles', href: "/admin/conferences/#{conference.short_title}/roles") + expect(page).to have_link('Resources', href: "/admin/conferences/#{conference.short_title}/resources") - visit new_admin_conference_venue_path(conference3.short_title) - expect(current_path).to eq(root_path) + visit admin_organizations_path + expect(current_path).to eq(admin_organizations_path) - conference3.venue = create(:venue) - visit edit_admin_conference_venue_path(conference3.short_title) - expect(current_path).to eq(root_path) + visit edit_admin_organization_path(organization) + expect(current_path).to eq(root_path) - visit admin_conference_venue_rooms_path(conference3.short_title) - expect(current_path).to eq(root_path) + visit new_admin_organization_path + expect(current_path).to eq(root_path) - create(:room, venue: conference3.venue) - visit edit_admin_conference_venue_room_path(conference3.short_title, conference3.venue.rooms.first) - expect(current_path).to eq(root_path) + visit edit_admin_conference_path(conference.short_title) + expect(current_path).to eq(root_path) - visit admin_conference_lodgings_path(conference3.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 new_admin_conference_lodging_path(conference3.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)) - create(:lodging, conference: conference3) - visit edit_admin_conference_lodging_path(conference3.short_title, conference3.lodgings.first) - expect(current_path).to eq(root_path) + visit new_admin_conference_splashpage_path(conference.short_title) + expect(current_path).to eq(root_path) - visit new_admin_conference_program_path(conference3.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 edit_admin_conference_program_path(conference3.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) - visit new_admin_conference_program_cfp_path(conference3.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 edit_admin_conference_program_cfp_path(conference3.short_title, conference3.program.cfp) - expect(current_path).to eq(root_path) + visit admin_conference_lodgings_path(conference.short_title) + expect(current_path).to eq(root_path) - visit admin_conference_program_events_path(conference3.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(:event, program: conference3.program) - visit edit_admin_conference_program_event_path(conference3.short_title, conference3.program.events.first) - 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 admin_conference_program_event_types_path(conference3.short_title) - expect(current_path).to eq(root_path) + visit new_admin_conference_registration_period_path(conference.short_title) + expect(current_path).to eq(root_path) - visit new_admin_conference_program_event_type_path(conference3.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 edit_admin_conference_program_event_type_path(conference3.short_title, conference3.program.event_types.first) - expect(current_path).to eq(root_path) + visit admin_conference_sponsorship_levels_path(conference.short_title) + expect(current_path).to eq(root_path) - visit admin_conference_program_difficulty_levels_path(conference3.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) - visit new_admin_conference_program_difficulty_level_path(conference3.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 edit_admin_conference_program_difficulty_level_path(conference3.short_title, conference3.program.difficulty_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 admin_conference_schedules_path(conference3.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(:schedule, program: conference3.program) - visit admin_conference_schedule_path(conference3.short_title, conference3.program.schedules.first) - 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_program_reports_path(conference3.short_title) - expect(current_path).to eq(root_path) + visit admin_conference_tickets_path(conference.short_title) + expect(current_path).to eq(root_path) - visit admin_conference_registrations_path(conference3.short_title) - expect(current_path).to eq(admin_conference_registrations_path(conference3.short_title)) + visit new_admin_conference_ticket_path(conference.short_title) + expect(current_path).to eq(root_path) - create(:registration, user: create(:user), conference: conference3) - visit edit_admin_conference_registration_path(conference3.short_title, conference3.registrations.first) - expect(current_path).to eq(edit_admin_conference_registration_path(conference3.short_title, conference3.registrations.first)) + create(:ticket, conference: conference) + visit edit_admin_conference_ticket_path(conference.short_title, conference.tickets.first) + expect(current_path).to eq(root_path) - visit new_admin_conference_registration_period_path(conference3.short_title) - expect(current_path).to eq(root_path) + visit admin_conference_campaigns_path(conference.short_title) + expect(current_path).to eq(root_path) - create(:registration_period, conference: conference3) - visit edit_admin_conference_registration_period_path(conference3.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) - visit admin_conference_questions_path(conference3.short_title) - expect(current_path).to eq(admin_conference_questions_path(conference3.short_title)) + 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_sponsorship_levels_path(conference3.short_title) - 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_sponsorship_level_path(conference3.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(:sponsorship_level, conference: conference3) - visit edit_admin_conference_sponsorship_level_path(conference3.short_title, conference3.sponsorship_levels.first) - 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_sponsors_path(conference3.short_title) - expect(current_path).to eq(root_path) + visit admin_conference_roles_path(conference.short_title) + expect(current_path).to eq(admin_conference_roles_path(conference.short_title)) - visit new_admin_conference_sponsor_path(conference3.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)) - create(:sponsor, conference: conference3, sponsorship_level: conference3.sponsorship_levels.first) - visit edit_admin_conference_sponsor_path(conference3.short_title, conference3.sponsors.first) - expect(current_path).to eq(root_path) + visit new_admin_conference_resource_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_resource_path(conference.short_title)) - visit admin_conference_tickets_path(conference3.short_title) - expect(current_path).to eq(root_path) + create(:resource, conference: conference) + visit edit_admin_conference_resource_path(conference.short_title, conference.resources.first) + expect(current_path).to eq(edit_admin_conference_resource_path(conference.short_title, conference.resources.first)) - visit new_admin_conference_ticket_path(conference3.short_title) - expect(current_path).to eq(root_path) + visit admin_revision_history_path + expect(current_path).to eq(root_path) + end + end - create(:ticket, conference: conference3) - visit edit_admin_conference_ticket_path(conference3.short_title, conference3.tickets.first) - expect(current_path).to eq(root_path) + context 'when user is cfp' do + before do + sign_in user_cfp + @conference = conference2 + end + scenario 'has correct abilities' do + visit admin_conference_path(conference2.short_title) + expect(current_path).to eq(admin_conference_path(conference2.short_title)) - visit admin_conference_campaigns_path(conference3.short_title) - expect(current_path).to eq(root_path) + expect(page).to have_selector('li.nav-header.nav-header-bigger a', text: 'Dashboard') + expect(page).to_not have_link('Basics', href: "/admin/conferences/#{conference2.short_title}/edit") + expect(page).to have_text('Basics') + expect(page).to_not have_link('Contact', href: "/admin/conferences/#{conference2.short_title}/contact/edit") + expect(page).to have_link('Commercials', href: "/admin/conferences/#{conference2.short_title}/commercials") + expect(page).to_not have_link('Splashpage', href: "/admin/conferences/#{conference2.short_title}/splashpage") + expect(page).to have_link('Venue', href: "/admin/conferences/#{conference2.short_title}/venue") + expect(page).to have_link('Rooms', href: "/admin/conferences/#{conference2.short_title}/venue/rooms") + expect(page).to_not have_link('Lodgings', href: "/admin/conferences/#{conference2.short_title}/lodgings") + expect(page).to have_link('Program', href: "/admin/conferences/#{conference2.short_title}/program") + expect(page).to have_link('Call for Papers', href: "/admin/conferences/#{conference2.short_title}/program/cfps") + expect(page).to have_link('Events', href: "/admin/conferences/#{conference2.short_title}/program/events") + expect(page).to have_link('Tracks', href: "/admin/conferences/#{conference2.short_title}/program/tracks") + expect(page).to have_link('Event Types', href: "/admin/conferences/#{conference2.short_title}/program/event_types") + expect(page).to have_link('Difficulty Levels', href: "/admin/conferences/#{conference2.short_title}/program/difficulty_levels") + expect(page).to have_link('Schedules', href: "/admin/conferences/#{conference2.short_title}/schedules") + expect(page).to have_link('Reports', href: "/admin/conferences/#{conference2.short_title}/program/reports") + expect(page).to_not have_link('Registrations', href: "/admin/conferences/#{conference2.short_title}/registrations") + expect(page).to_not have_link('Registration Period', href: "/admin/conferences/#{conference2.short_title}/registration_period") + expect(page).to_not have_link('Questions', href: "/admin/conferences/#{conference2.short_title}/questions") + expect(page).to_not have_text('Donations') + expect(page).to_not have_link('Sponsorship Levels', href: "/admin/conferences/#{conference2.short_title}/supporter_levels") + expect(page).to_not have_link('Sponsors', href: "/admin/conferences/#{conference2.short_title}/sponsors") + expect(page).to_not have_link('Tickets', href: "/admin/conferences/#{conference2.short_title}/tickets") + expect(page).to_not have_text('Objectives') + expect(page).to_not have_link('Campaigns', href: "/admin/conferences/#{conference2.short_title}/campaigns") + expect(page).to_not have_link('Goals', href: "/admin/conferences/#{conference2.short_title}/targets") + expect(page).to have_link('E-Mails', href: "/admin/conferences/#{conference2.short_title}/emails") + expect(page).to have_link('Roles', href: "/admin/conferences/#{conference2.short_title}/roles") + expect(page).to have_link('Resources', href: "/admin/conferences/#{conference2.short_title}/resources") - visit new_admin_conference_campaign_path(conference3.short_title) - expect(current_path).to eq(root_path) + visit admin_conference_venue_rooms_path(conference2.short_title) + expect(current_path).to eq(admin_conference_venue_rooms_path(conference2.short_title)) + create(:room, venue: conference2.venue) + visit edit_admin_conference_venue_room_path(conference2.short_title, conference2.venue.rooms.first) + expect(current_path).to eq(edit_admin_conference_venue_room_path(conference2.short_title, conference2.venue.rooms.first)) - create(:campaign, conference: conference3) - visit edit_admin_conference_campaign_path(conference3.short_title, conference3.campaigns.first) - expect(current_path).to eq(root_path) + visit new_admin_conference_program_path(conference2.short_title) + expect(current_path).to eq(new_admin_conference_program_path(conference2.short_title)) - visit admin_conference_targets_path(conference3.short_title) - expect(current_path).to eq(root_path) + visit edit_admin_conference_program_path(conference2.short_title) + expect(current_path).to eq(edit_admin_conference_program_path(conference2.short_title)) - visit new_admin_conference_target_path(conference3.short_title) - expect(current_path).to eq(root_path) + visit new_admin_conference_program_cfp_path(conference2.short_title) + expect(current_path).to eq(new_admin_conference_program_cfp_path(conference2.short_title)) - create(:target, conference: conference3) - visit edit_admin_conference_target_path(conference3.short_title, conference3.targets.first) - expect(current_path).to eq(root_path) + visit edit_admin_conference_program_cfp_path(conference2.short_title) + expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference2.short_title)) - visit admin_conference_program_tracks_path(conference3.short_title) - expect(current_path).to eq(root_path) + visit admin_conference_program_events_path(conference2.short_title) + expect(current_path).to eq(admin_conference_program_events_path(conference2.short_title)) - visit admin_conference_roles_path(conference3.short_title) - expect(current_path).to eq(admin_conference_roles_path(conference3.short_title)) + create(:event, program: conference2.program) + visit edit_admin_conference_program_event_path(conference2.short_title, conference2.program.events.first) + expect(current_path).to eq(edit_admin_conference_program_event_path(conference2.short_title, conference2.program.events.first)) - visit admin_conference_emails_path(conference3.short_title) - expect(current_path).to eq(root_path) + visit admin_conference_program_event_types_path(conference2.short_title) + expect(current_path).to eq(admin_conference_program_event_types_path(conference2.short_title)) - visit admin_conference_resources_path(conference3.short_title) - expect(current_path).to eq(admin_conference_resources_path(conference3.short_title)) + visit new_admin_conference_program_event_type_path(conference2.short_title) + expect(current_path).to eq(new_admin_conference_program_event_type_path(conference2.short_title)) - visit new_admin_conference_resource_path(conference3.short_title) - expect(current_path).to eq(new_admin_conference_resource_path(conference3.short_title)) + visit edit_admin_conference_program_event_type_path(conference2.short_title, conference2.program.event_types.first) + expect(current_path).to eq(edit_admin_conference_program_event_type_path(conference2.short_title, conference2.program.event_types.first)) - create(:resource, conference: conference3) - visit edit_admin_conference_resource_path(conference3.short_title, conference3.resources.first) - expect(current_path).to eq(edit_admin_conference_resource_path(conference3.short_title, conference3.resources.first)) + visit admin_conference_program_difficulty_levels_path(conference2.short_title) + expect(current_path).to eq(admin_conference_program_difficulty_levels_path(conference2.short_title)) - visit admin_revision_history_path - expect(current_path).to eq(root_path) + visit new_admin_conference_program_difficulty_level_path(conference2.short_title) + expect(current_path).to eq(new_admin_conference_program_difficulty_level_path(conference2.short_title)) + + visit edit_admin_conference_program_difficulty_level_path(conference2.short_title, conference2.program.difficulty_levels.first) + expect(current_path).to eq(edit_admin_conference_program_difficulty_level_path(conference2.short_title, conference2.program.difficulty_levels.first)) + + visit admin_conference_schedules_path(conference2.short_title) + expect(current_path).to eq(admin_conference_schedules_path(conference2.short_title)) + + create(:schedule, program: conference2.program) + visit admin_conference_schedule_path(conference2.short_title, conference2.program.schedules.first) + expect(current_path).to eq(admin_conference_schedule_path(conference2.short_title, conference2.program.schedules.first)) + + visit admin_conference_program_reports_path(conference2.short_title) + expect(current_path).to eq(admin_conference_program_reports_path(conference2.short_title)) + + visit admin_conference_registrations_path(conference2.short_title) + expect(current_path).to eq(admin_conference_registrations_path(conference2.short_title)) + + create(:registration, user: create(:user), conference: conference2) + visit edit_admin_conference_registration_path(conference2.short_title, conference2.registrations.first) + expect(current_path).to eq(root_path) + + visit new_admin_conference_registration_period_path(conference2.short_title) + expect(current_path).to eq(root_path) + + create(:registration_period, conference: conference2) + visit edit_admin_conference_registration_period_path(conference2.short_title) + expect(current_path).to eq(root_path) + + visit admin_conference_questions_path(conference2.short_title) + expect(current_path).to eq(root_path) + + visit admin_conference_program_tracks_path(conference2.short_title) + expect(current_path).to eq(admin_conference_program_tracks_path(conference2.short_title)) + + visit admin_conference_roles_path(conference2.short_title) + expect(current_path).to eq(admin_conference_roles_path(conference2.short_title)) + + visit admin_conference_emails_path(conference2.short_title) + expect(current_path).to eq(admin_conference_emails_path(conference2.short_title)) + end + + it_behaves_like 'correct abilities for cfps and info_desk', 'cfp' + end + + context 'when user is info desk' do + before do + sign_in user_info_desk + end + + scenario 'has correct abilities' do + visit admin_conference_path(conference3.short_title) + expect(current_path).to eq(admin_conference_path(conference3.short_title)) + + expect(page).to have_selector('li.nav-header.nav-header-bigger a', text: 'Dashboard') + expect(page).to_not have_link('Venue', href: "/admin/conferences/#{conference3.short_title}/venue") + expect(page).to_not have_link('Rooms', href: "/admin/conferences/#{conference3.short_title}/venue/rooms") + expect(page).to_not have_link('Program', href: "/admin/conferences/#{conference3.short_title}/program") + expect(page).to_not have_link('Call for Papers', href: "/admin/conferences/#{conference2.short_title}/program/cfps") + expect(page).to_not have_link('Events', href: "/admin/conferences/#{conference3.short_title}/program/events") + expect(page).to_not have_link('Tracks', href: "/admin/conferences/#{conference3.short_title}/program/tracks") + expect(page).to_not have_link('Event Types', href: "/admin/conferences/#{conference3.short_title}/program/event_types") + expect(page).to_not have_link('Difficulty Levels', href: "/admin/conferences/#{conference3.short_title}/program/difficulty_levels") + expect(page).to_not have_link('Schedules', href: "/admin/conferences/#{conference3.short_title}/schedules") + expect(page).to_not have_link('Reports', href: "/admin/conferences/#{conference3.short_title}/program/reports") + expect(page).to have_link('Registrations', href: "/admin/conferences/#{conference3.short_title}/registrations") + expect(page).to have_link('Questions', href: "/admin/conferences/#{conference3.short_title}/questions") + expect(page).to_not have_link('E-Mails', href: "/admin/conferences/#{conference3.short_title}/emails") + + visit admin_conference_venue_rooms_path(conference3.short_title) + expect(current_path).to eq(root_path) + + create(:room, venue: conference3.venue) + visit edit_admin_conference_venue_room_path(conference3.short_title, conference3.venue.rooms.first) + expect(current_path).to eq(root_path) + + visit new_admin_conference_program_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit edit_admin_conference_program_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit new_admin_conference_program_cfp_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit edit_admin_conference_program_cfp_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit admin_conference_program_events_path(conference3.short_title) + expect(current_path).to eq(root_path) + + create(:event, program: conference3.program) + visit edit_admin_conference_program_event_path(conference3.short_title, conference3.program.events.first) + expect(current_path).to eq(root_path) + + visit admin_conference_program_event_types_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit new_admin_conference_program_event_type_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit edit_admin_conference_program_event_type_path(conference3.short_title, conference3.program.event_types.first) + expect(current_path).to eq(root_path) + + visit admin_conference_program_difficulty_levels_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit new_admin_conference_program_difficulty_level_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit edit_admin_conference_program_difficulty_level_path(conference3.short_title, conference3.program.difficulty_levels.first) + expect(current_path).to eq(root_path) + + visit admin_conference_schedules_path(conference3.short_title) + expect(current_path).to eq(root_path) + + create(:schedule, program: conference3.program) + visit admin_conference_schedule_path(conference3.short_title, conference3.program.schedules.first) + expect(current_path).to eq(root_path) + + visit admin_conference_program_reports_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit admin_conference_registrations_path(conference3.short_title) + expect(current_path).to eq(admin_conference_registrations_path(conference3.short_title)) + + create(:registration, user: create(:user), conference: conference3) + visit edit_admin_conference_registration_path(conference3.short_title, conference3.registrations.first) + expect(current_path).to eq(edit_admin_conference_registration_path(conference3.short_title, conference3.registrations.first)) + + visit admin_conference_questions_path(conference3.short_title) + expect(current_path).to eq(admin_conference_questions_path(conference3.short_title)) + + visit admin_conference_program_tracks_path(conference3.short_title) + expect(current_path).to eq(root_path) + + visit admin_conference_emails_path(conference3.short_title) + expect(current_path).to eq(root_path) + end + + it_behaves_like 'correct abilities for cfps and info_desk', 'info_desk' end end diff --git a/spec/features/organization_spec.rb b/spec/features/organization_spec.rb new file mode 100644 index 00000000..72fee466 --- /dev/null +++ b/spec/features/organization_spec.rb @@ -0,0 +1,51 @@ +require 'spec_helper' + +feature Organization do + let!(:organization) { create(:organization) } + let!(:organization_admin_role) { Role.find_by(name: 'organization_admin', resource: organization) } + let(:organization_admin) { create(:user, role_ids: [organization_admin_role.id]) } + let(:admin_user) { create(:admin) } + + shared_examples 'successfully updates a organization' do + scenario 'updates a exsisting organization', feature: true, js: true do + visit edit_admin_organization_path(organization) + fill_in 'organization_name', with: 'changed name' + + click_button 'Update Organization' + + organization.reload + expect(flash).to eq('Organization successfully updated') + expect(organization.name).to eq('changed name') + end + end + + context 'signed in as site admin' do + before do + sign_in admin_user + end + scenario 'creates a new organization', feature: true, js: true do + visit new_admin_organization_path + fill_in 'organization_name', with: 'Organization name' + + click_button 'Create Organization' + + expect(flash).to eq('Organization successfully created') + expect(Organization.last.name).to eq('Organization name') + end + + it_behaves_like 'successfully updates a organization' + end + + context 'signed in as organization admin' do + before do + sign_in organization_admin + end + scenario "can't create new organization", feature: true, js: true do + visit new_admin_organization_path + + expect(flash).to eq('You are not authorized to access this page.') + end + + it_behaves_like 'successfully updates a organization' + end +end From 3daa12f83fdbc9a44ea6c14d7843501262478721 Mon Sep 17 00:00:00 2001 From: shlok007 Date: Wed, 28 Jun 2017 08:05:04 +0530 Subject: [PATCH 135/185] fix tests for cfps after rebase --- spec/features/ability_spec.rb | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/spec/features/ability_spec.rb b/spec/features/ability_spec.rb index 41775de4..915ce401 100644 --- a/spec/features/ability_spec.rb +++ b/spec/features/ability_spec.rb @@ -114,12 +114,12 @@ feature 'Has correct abilities' do visit new_admin_conference_program_cfp_path(conference1.short_title) expect(current_path).to eq root_path - + conference1.program.cfp.destroy! visit new_admin_conference_program_cfp_path(conference1.short_title) expect(current_path).to eq new_admin_conference_program_cfp_path(conference1.short_title) create(:cfp, program: conference1.program) - + visit edit_admin_conference_program_cfp_path(conference1.short_title, conference1.program.cfp) expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference1.short_title, conference1.program.cfp)) @@ -484,13 +484,15 @@ feature 'Has correct abilities' do expect(current_path).to eq(edit_admin_conference_program_path(conference2.short_title)) visit new_admin_conference_program_cfp_path(conference2.short_title) - expect(current_path).to eq(new_admin_conference_program_cfp_path(conference2.short_title)) + expect(current_path).to eq root_path - visit edit_admin_conference_program_cfp_path(conference2.short_title) - expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference2.short_title)) + conference2.program.cfp.destroy! + visit new_admin_conference_program_cfp_path(conference2.short_title) + expect(current_path).to eq new_admin_conference_program_cfp_path(conference2.short_title) + create(:cfp, program: conference2.program) - visit admin_conference_program_events_path(conference2.short_title) - expect(current_path).to eq(admin_conference_program_events_path(conference2.short_title)) + visit edit_admin_conference_program_cfp_path(conference2.short_title, conference2.program.cfp) + expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference2.short_title, conference2.program.cfp)) create(:event, program: conference2.program) visit edit_admin_conference_program_event_path(conference2.short_title, conference2.program.events.first) @@ -592,9 +594,14 @@ feature 'Has correct abilities' do expect(current_path).to eq(root_path) visit new_admin_conference_program_cfp_path(conference3.short_title) - expect(current_path).to eq(root_path) + expect(current_path).to eq root_path - visit edit_admin_conference_program_cfp_path(conference3.short_title) + conference1.program.cfp.destroy! + visit new_admin_conference_program_cfp_path(conference3.short_title) + expect(current_path).to eq root_path + create(:cfp, program: conference1.program) + + visit edit_admin_conference_program_cfp_path(conference3.short_title, conference3.program.cfp) expect(current_path).to eq(root_path) visit admin_conference_program_events_path(conference3.short_title) From 651abcab87cf1699fba41f9c31eb1a314046059b Mon Sep 17 00:00:00 2001 From: shlok007 Date: Fri, 30 Jun 2017 09:18:17 +0530 Subject: [PATCH 136/185] split feature tests for abilities and suggested changes --- app/models/ability.rb | 73 +- spec/features/ability_spec.rb | 661 ------------------ spec/features/cfp_ability_spec.rb | 250 +++++++ spec/features/info_desk_ability_spec.rb | 246 +++++++ .../organization_admin_ability_spec.rb | 240 +++++++ spec/features/organizer_ability_spec.rb | 247 +++++++ spec/features/user_ability_spec.rb | 21 + spec/models/ability_spec.rb | 42 +- 8 files changed, 1059 insertions(+), 721 deletions(-) delete mode 100644 spec/features/ability_spec.rb create mode 100644 spec/features/cfp_ability_spec.rb create mode 100644 spec/features/info_desk_ability_spec.rb create mode 100644 spec/features/organization_admin_ability_spec.rb create mode 100644 spec/features/organizer_ability_spec.rb create mode 100644 spec/features/user_ability_spec.rb diff --git a/app/models/ability.rb b/app/models/ability.rb index 37090a49..8185fadd 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -154,10 +154,7 @@ class Ability can :manage, Organization, id: org_ids_for_organization_admin can :new, Conference can :manage, Conference, organization_id: org_ids_for_organization_admin - conf_ids_for_organization_admin = [] - org_ids_for_organization_admin.each do |org_id| - conf_ids_for_organization_admin += Organization.find(org_id).conferences.pluck(:id) - end + conf_ids_for_organization_admin = Conference.where(organization_id: org_ids_for_organization_admin).pluck(:id) can [:index, :show], Role can [:edit, :update], Role do |role| role.resource_type == 'Organization' && (org_ids_for_organization_admin.include? role.resource_id) @@ -168,44 +165,44 @@ class Ability 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_for_organization_admin_and_organizer = conf_ids_for_organization_admin.concat(Conference.with_role(:organizer, user).pluck(:id)).uniq - can :manage, Resource, conference_id: conf_ids_for_organization_admin_and_organizer - can :manage, Conference, id: conf_ids_for_organization_admin_and_organizer - can :manage, Splashpage, conference_id: conf_ids_for_organization_admin_and_organizer - can :manage, Contact, conference_id: conf_ids_for_organization_admin_and_organizer - can :manage, EmailSettings, conference_id: conf_ids_for_organization_admin_and_organizer - can :manage, Campaign, conference_id: conf_ids_for_organization_admin_and_organizer - can :manage, Target, conference_id: conf_ids_for_organization_admin_and_organizer + conf_ids = conf_ids_for_organization_admin.concat(Conference.with_role(:organizer, user).pluck(:id)).uniq + can :manage, Resource, conference_id: conf_ids + can :manage, 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_for_organization_admin_and_organizer - can :manage, Registration, conference_id: conf_ids_for_organization_admin_and_organizer - can :manage, RegistrationPeriod, conference_id: conf_ids_for_organization_admin_and_organizer - can :manage, Question, conference_id: conf_ids_for_organization_admin_and_organizer + 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_for_organization_admin_and_organizer).empty? + !(question.conferences.pluck(:id) & conf_ids).empty? end - can :manage, Vposition, conference_id: conf_ids_for_organization_admin_and_organizer - can :manage, Vday, conference_id: conf_ids_for_organization_admin_and_organizer - can :manage, Program, conference_id: conf_ids_for_organization_admin_and_organizer - can :manage, Schedule, program: { conference_id: conf_ids_for_organization_admin_and_organizer } - can :manage, EventSchedule, schedule: { program: { conference_id: conf_ids_for_organization_admin_and_organizer } } - can :manage, Cfp, program: { conference_id: conf_ids_for_organization_admin_and_organizer} - can :manage, Event, program: { conference_id: conf_ids_for_organization_admin_and_organizer} - can :manage, EventType, program: { conference_id: conf_ids_for_organization_admin_and_organizer} - can :manage, Track, program: { conference_id: conf_ids_for_organization_admin_and_organizer} - can :manage, DifficultyLevel, program: { conference_id: conf_ids_for_organization_admin_and_organizer} + 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_for_organization_admin_and_organizer).pluck(:id)).pluck(:id) - can :manage, Venue, conference_id: conf_ids_for_organization_admin_and_organizer + 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_for_organization_admin_and_organizer).pluck(:id) - can :manage, Lodging, conference_id: conf_ids_for_organization_admin_and_organizer - can :manage, Room, venue: { conference_id: conf_ids_for_organization_admin_and_organizer} - can :manage, Sponsor, conference_id: conf_ids_for_organization_admin_and_organizer - can :manage, SponsorshipLevel, conference_id: conf_ids_for_organization_admin_and_organizer - can :manage, Ticket, conference_id: conf_ids_for_organization_admin_and_organizer + 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_for_organization_admin_and_organizer).pluck(:id)).pluck(:id) + 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| @@ -213,11 +210,11 @@ class Ability end can [:edit, :update, :toggle_user], Role do |role| - role.resource_type == 'Conference' && (conf_ids_for_organization_admin_and_organizer.include? role.resource_id) + 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_for_organization_admin_and_organizer.include? version.conference_id) + version.item_type == 'User' || (conf_ids.include? version.conference_id) end end diff --git a/spec/features/ability_spec.rb b/spec/features/ability_spec.rb deleted file mode 100644 index 915ce401..00000000 --- a/spec/features/ability_spec.rb +++ /dev/null @@ -1,661 +0,0 @@ -require 'spec_helper' - -feature 'Has correct abilities' do - - let(:organization) { create(:organization) } - # It is necessary to use bang version of let to build roles before user - let(:conference1) { create(:full_conference, organization: organization) } # user is organizer - let(:conference2) { create(:full_conference, organization: organization) } # user is cfp - let(:conference3) { create(:full_conference, organization: organization) } # user is info_desk - let(:conference6) { create(:conference, organization: organization) } # user is organizer, venue is not set by default - - let(:role_organization_admin) { Role.find_by(name: 'organization_admin', resource: organization) } - let(:role_organizer_conf1) { Role.find_by(name: 'organizer', resource: conference1) } - let(:role_organizer_conf6) { Role.find_by(name: 'organizer', resource: conference6) } - let(:role_cfp) { Role.find_by(name: 'cfp', resource: conference2) } - let(:role_info_desk) { Role.find_by(name: 'info_desk', resource: conference3) } - - let(:user) { create(:user) } - let(:user_organization_admin) { create(:user, role_ids: [role_organization_admin.id]) } - let(:user_organizer) { create(:user, role_ids: [role_organizer_conf1.id, role_organizer_conf6.id]) } - let(:user_cfp) { create(:user, role_ids: [role_cfp.id]) } - let(:user_info_desk) { create(:user, role_ids: [role_info_desk.id]) } - - scenario 'when user has no role' do - sign_in user - - visit admin_conference_path(conference1.short_title) - expect(current_path).to eq root_path - expect(flash).to eq 'You are not authorized to access this page.' - end - - shared_examples 'correct abilities for organizers and organization_admin' do - scenario 'for conference attributes' do - visit admin_conference_path(conference1.short_title) - expect(current_path).to eq(admin_conference_path(conference1.short_title)) - - expect(page).to have_selector('li.nav-header.nav-header-bigger a', text: 'Dashboard') - expect(page).to have_link('Basics', href: "/admin/conferences/#{conference1.short_title}/edit") - expect(page).to have_link('Contact', href: "/admin/conferences/#{conference1.short_title}/contact/edit") - expect(page).to have_link('Commercials', href: "/admin/conferences/#{conference1.short_title}/commercials") - expect(page).to have_link('Splashpage', href: "/admin/conferences/#{conference1.short_title}/splashpage") - expect(page).to have_link('Venue', href: "/admin/conferences/#{conference1.short_title}/venue") - expect(page).to have_link('Rooms', href: "/admin/conferences/#{conference1.short_title}/venue/rooms") - expect(page).to have_link('Lodgings', href: "/admin/conferences/#{conference1.short_title}/lodgings") - expect(page).to have_link('Program', href: "/admin/conferences/#{conference1.short_title}/program") - expect(page).to have_link('Call for Papers', href: "/admin/conferences/#{conference1.short_title}/program/cfps") - expect(page).to have_link('Events', href: "/admin/conferences/#{conference1.short_title}/program/events") - expect(page).to have_link('Tracks', href: "/admin/conferences/#{conference1.short_title}/program/tracks") - expect(page).to have_link('Event Types', href: "/admin/conferences/#{conference1.short_title}/program/event_types") - expect(page).to have_link('Difficulty Levels', href: "/admin/conferences/#{conference1.short_title}/program/difficulty_levels") - expect(page).to have_link('Schedules', href: "/admin/conferences/#{conference1.short_title}/schedules") - expect(page).to have_link('Reports', href: "/admin/conferences/#{conference1.short_title}/program/reports") - expect(page).to have_link('Registrations', href: "/admin/conferences/#{conference1.short_title}/registrations") - expect(page).to have_link('Registration Period', href: "/admin/conferences/#{conference1.short_title}/registration_period") - expect(page).to have_link('Questions', href: "/admin/conferences/#{conference1.short_title}/questions") - expect(page).to have_text('Donations') - expect(page).to have_link('Sponsorship Levels', href: "/admin/conferences/#{conference1.short_title}/sponsorship_levels") - expect(page).to have_link('Sponsors', href: "/admin/conferences/#{conference1.short_title}/sponsors") - expect(page).to have_link('Tickets', href: "/admin/conferences/#{conference1.short_title}/tickets") - expect(page).to have_text('Objectives') - expect(page).to have_link('Campaigns', href: "/admin/conferences/#{conference1.short_title}/campaigns") - expect(page).to have_link('Goals', href: "/admin/conferences/#{conference1.short_title}/targets") - expect(page).to have_link('E-Mails', href: "/admin/conferences/#{conference1.short_title}/emails") - expect(page).to have_link('Roles', href: "/admin/conferences/#{conference1.short_title}/roles") - expect(page).to have_link('Resources', href: "/admin/conferences/#{conference1.short_title}/resources") - - visit admin_conference_path(conference6.short_title) - expect(page).to have_link('Add venue', href: "/admin/conferences/#{conference6.short_title}/venue/new") - - visit edit_admin_conference_path(conference1.short_title) - expect(current_path).to eq(edit_admin_conference_path(conference1.short_title)) - - visit edit_admin_conference_contact_path(conference1.short_title) - expect(current_path).to eq(edit_admin_conference_contact_path(conference1.short_title)) - - visit admin_conference_commercials_path(conference1.short_title) - expect(current_path).to eq(admin_conference_commercials_path(conference1.short_title)) - - visit new_admin_conference_splashpage_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_splashpage_path(conference1.short_title)) - - visit edit_admin_conference_splashpage_path(conference1.short_title) - expect(current_path).to eq(edit_admin_conference_splashpage_path(conference1.short_title)) - - visit new_admin_conference_venue_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_venue_path(conference1.short_title)) - - conference1.venue = create(:venue) - visit edit_admin_conference_venue_path(conference1.short_title) - expect(current_path).to eq(edit_admin_conference_venue_path(conference1.short_title)) - - visit admin_conference_venue_rooms_path(conference1.short_title) - expect(current_path).to eq(admin_conference_venue_rooms_path(conference1.short_title)) - - create(:room, venue: conference1.venue) - visit edit_admin_conference_venue_room_path(conference1.short_title, conference1.venue.rooms.first) - expect(current_path).to eq(edit_admin_conference_venue_room_path(conference1.short_title, conference1.venue.rooms.first)) - - visit admin_conference_lodgings_path(conference1.short_title) - expect(current_path).to eq(admin_conference_lodgings_path(conference1.short_title)) - - visit new_admin_conference_lodging_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_lodging_path(conference1.short_title)) - - create(:lodging, conference: conference1) - visit edit_admin_conference_lodging_path(conference1.short_title, conference1.lodgings.first) - expect(current_path).to eq(edit_admin_conference_lodging_path(conference1.short_title, conference1.lodgings.first)) - - visit new_admin_conference_program_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_program_path(conference1.short_title)) - - visit edit_admin_conference_program_path(conference1.short_title) - expect(current_path).to eq(edit_admin_conference_program_path(conference1.short_title)) - - visit new_admin_conference_program_cfp_path(conference1.short_title) - expect(current_path).to eq root_path - - conference1.program.cfp.destroy! - visit new_admin_conference_program_cfp_path(conference1.short_title) - expect(current_path).to eq new_admin_conference_program_cfp_path(conference1.short_title) - create(:cfp, program: conference1.program) - - visit edit_admin_conference_program_cfp_path(conference1.short_title, conference1.program.cfp) - expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference1.short_title, conference1.program.cfp)) - - visit admin_conference_program_events_path(conference1.short_title) - expect(current_path).to eq(admin_conference_program_events_path(conference1.short_title)) - - create(:event, program: conference1.program) - visit edit_admin_conference_program_event_path(conference1.short_title, conference1.program.events.first) - expect(current_path).to eq(edit_admin_conference_program_event_path(conference1.short_title, conference1.program.events.first)) - - visit admin_conference_program_event_types_path(conference1.short_title) - expect(current_path).to eq(admin_conference_program_event_types_path(conference1.short_title)) - - visit new_admin_conference_program_event_type_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_program_event_type_path(conference1.short_title)) - - visit edit_admin_conference_program_event_type_path(conference1.short_title, conference1.program.event_types.first) - expect(current_path).to eq(edit_admin_conference_program_event_type_path(conference1.short_title, conference1.program.event_types.first)) - - visit admin_conference_program_difficulty_levels_path(conference1.short_title) - expect(current_path).to eq(admin_conference_program_difficulty_levels_path(conference1.short_title)) - - visit new_admin_conference_program_difficulty_level_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_program_difficulty_level_path(conference1.short_title)) - - visit edit_admin_conference_program_difficulty_level_path(conference1.short_title, conference1.program.difficulty_levels.first) - expect(current_path).to eq(edit_admin_conference_program_difficulty_level_path(conference1.short_title, conference1.program.difficulty_levels.first)) - - visit admin_conference_schedules_path(conference1.short_title) - expect(current_path).to eq(admin_conference_schedules_path(conference1.short_title)) - - create(:schedule, program: conference1.program) - visit admin_conference_schedule_path(conference1.short_title, conference1.program.schedules.first) - expect(current_path).to eq(admin_conference_schedule_path(conference1.short_title, conference1.program.schedules.first)) - - visit admin_conference_program_reports_path(conference1.short_title) - expect(current_path).to eq(admin_conference_program_reports_path(conference1.short_title)) - - visit admin_conference_registrations_path(conference1.short_title) - expect(current_path).to eq(admin_conference_registrations_path(conference1.short_title)) - - create(:registration, user: create(:user), conference: conference1) - visit edit_admin_conference_registration_path(conference1.short_title, conference1.registrations.first) - expect(current_path).to eq(edit_admin_conference_registration_path(conference1.short_title, conference1.registrations.first)) - - visit new_admin_conference_registration_period_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_registration_period_path(conference1.short_title)) - - create(:registration_period, conference: conference1) - visit edit_admin_conference_registration_period_path(conference1.short_title) - expect(current_path).to eq(edit_admin_conference_registration_period_path(conference1.short_title)) - - visit admin_conference_questions_path(conference1.short_title) - expect(current_path).to eq(admin_conference_questions_path(conference1.short_title)) - - visit admin_conference_sponsorship_levels_path(conference1.short_title) - expect(current_path).to eq(admin_conference_sponsorship_levels_path(conference1.short_title)) - - visit new_admin_conference_sponsorship_level_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_sponsorship_level_path(conference1.short_title)) - - create(:sponsorship_level, conference: conference1) - visit edit_admin_conference_sponsorship_level_path(conference1.short_title, conference1.sponsorship_levels.first) - expect(current_path).to eq(edit_admin_conference_sponsorship_level_path(conference1.short_title, conference1.sponsorship_levels.first)) - - visit admin_conference_sponsors_path(conference1.short_title) - expect(current_path).to eq(admin_conference_sponsors_path(conference1.short_title)) - - visit new_admin_conference_sponsor_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_sponsor_path(conference1.short_title)) - - create(:sponsor, conference: conference1, sponsorship_level: conference1.sponsorship_levels.first) - visit edit_admin_conference_sponsor_path(conference1.short_title, conference1.sponsors.first) - expect(current_path).to eq(edit_admin_conference_sponsor_path(conference1.short_title, conference1.sponsors.first)) - - visit admin_conference_tickets_path(conference1.short_title) - expect(current_path).to eq(admin_conference_tickets_path(conference1.short_title)) - - visit new_admin_conference_ticket_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_ticket_path(conference1.short_title)) - - create(:ticket, conference: conference1) - visit edit_admin_conference_ticket_path(conference1.short_title, conference1.tickets.first) - expect(current_path).to eq(edit_admin_conference_ticket_path(conference1.short_title, conference1.tickets.first)) - - visit admin_conference_campaigns_path(conference1.short_title) - expect(current_path).to eq(admin_conference_campaigns_path(conference1.short_title)) - - visit new_admin_conference_campaign_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_campaign_path(conference1.short_title)) - - create(:campaign, conference: conference1) - visit edit_admin_conference_campaign_path(conference1.short_title, conference1.campaigns.first) - expect(current_path).to eq(edit_admin_conference_campaign_path(conference1.short_title, conference1.campaigns.first)) - - visit admin_conference_targets_path(conference1.short_title) - expect(current_path).to eq(admin_conference_targets_path(conference1.short_title)) - - visit new_admin_conference_target_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_target_path(conference1.short_title)) - - create(:target, conference: conference1) - visit edit_admin_conference_target_path(conference1.short_title, conference1.targets.first) - expect(current_path).to eq(edit_admin_conference_target_path(conference1.short_title, conference1.targets.first)) - - visit admin_conference_program_tracks_path(conference1.short_title) - expect(current_path).to eq(admin_conference_program_tracks_path(conference1.short_title)) - - visit admin_conference_roles_path(conference1.short_title) - expect(current_path).to eq(admin_conference_roles_path(conference1.short_title)) - - visit admin_conference_emails_path(conference1.short_title) - expect(current_path).to eq(admin_conference_emails_path(conference1.short_title)) - - visit admin_conference_resources_path(conference1.short_title) - expect(current_path).to eq(admin_conference_resources_path(conference1.short_title)) - - visit new_admin_conference_resource_path(conference1.short_title) - expect(current_path).to eq(new_admin_conference_resource_path(conference1.short_title)) - - create(:resource, conference: conference1) - visit edit_admin_conference_resource_path(conference1.short_title, conference1.resources.first) - expect(current_path).to eq(edit_admin_conference_resource_path(conference1.short_title, conference1.resources.first)) - - visit admin_revision_history_path - expect(current_path).to eq(admin_revision_history_path) - end - end - - context 'when user is organization_admin' do - before do - sign_in user_organization_admin - end - - scenario 'can manage organization' do - visit admin_organizations_path - expect(current_path).to eq(admin_organizations_path) - - visit edit_admin_organization_path(organization) - expect(current_path).to eq(edit_admin_organization_path(organization)) - - visit new_admin_organization_path - expect(current_path).to eq(root_path) - end - - it_behaves_like 'correct abilities for organizers and organization_admin' - end - - context 'when user is organizer' do - before do - sign_in user_organizer - end - - scenario 'cannot manage organization' do - visit admin_organizations_path - expect(current_path).to eq(admin_organizations_path) - - visit edit_admin_organization_path(organization) - expect(current_path).to eq(root_path) - - visit new_admin_organization_path - expect(current_path).to eq(root_path) - end - - it_behaves_like 'correct abilities for organizers and organization_admin' - end - - shared_examples 'correct abilities for cfps and info_desk' do |role| - scenario 'correct ability' do - if role == 'cfp' - conference = conference2 - elsif role == 'info_desk' - conference = conference3 - end - - visit admin_conference_path(conference.short_title) - expect(current_path).to eq(admin_conference_path(conference.short_title)) - - 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('Lodgings', href: "/admin/conferences/#{conference.short_title}/lodgings") - expect(page).to_not have_link('Registration Period', href: "/admin/conferences/#{conference.short_title}/registration_period") - 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 have_link('Roles', href: "/admin/conferences/#{conference.short_title}/roles") - expect(page).to have_link('Resources', href: "/admin/conferences/#{conference.short_title}/resources") - - visit admin_organizations_path - expect(current_path).to eq(admin_organizations_path) - - visit edit_admin_organization_path(organization) - expect(current_path).to eq(root_path) - - visit new_admin_organization_path - expect(current_path).to eq(root_path) - - 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_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_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_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_roles_path(conference.short_title) - expect(current_path).to eq(admin_conference_roles_path(conference.short_title)) - - 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(edit_admin_conference_resource_path(conference.short_title, conference.resources.first)) - - visit admin_revision_history_path - expect(current_path).to eq(root_path) - end - end - - context 'when user is cfp' do - before do - sign_in user_cfp - @conference = conference2 - end - scenario 'has correct abilities' do - visit admin_conference_path(conference2.short_title) - expect(current_path).to eq(admin_conference_path(conference2.short_title)) - - expect(page).to have_selector('li.nav-header.nav-header-bigger a', text: 'Dashboard') - expect(page).to_not have_link('Basics', href: "/admin/conferences/#{conference2.short_title}/edit") - expect(page).to have_text('Basics') - expect(page).to_not have_link('Contact', href: "/admin/conferences/#{conference2.short_title}/contact/edit") - expect(page).to have_link('Commercials', href: "/admin/conferences/#{conference2.short_title}/commercials") - expect(page).to_not have_link('Splashpage', href: "/admin/conferences/#{conference2.short_title}/splashpage") - expect(page).to have_link('Venue', href: "/admin/conferences/#{conference2.short_title}/venue") - expect(page).to have_link('Rooms', href: "/admin/conferences/#{conference2.short_title}/venue/rooms") - expect(page).to_not have_link('Lodgings', href: "/admin/conferences/#{conference2.short_title}/lodgings") - expect(page).to have_link('Program', href: "/admin/conferences/#{conference2.short_title}/program") - expect(page).to have_link('Call for Papers', href: "/admin/conferences/#{conference2.short_title}/program/cfps") - expect(page).to have_link('Events', href: "/admin/conferences/#{conference2.short_title}/program/events") - expect(page).to have_link('Tracks', href: "/admin/conferences/#{conference2.short_title}/program/tracks") - expect(page).to have_link('Event Types', href: "/admin/conferences/#{conference2.short_title}/program/event_types") - expect(page).to have_link('Difficulty Levels', href: "/admin/conferences/#{conference2.short_title}/program/difficulty_levels") - expect(page).to have_link('Schedules', href: "/admin/conferences/#{conference2.short_title}/schedules") - expect(page).to have_link('Reports', href: "/admin/conferences/#{conference2.short_title}/program/reports") - expect(page).to_not have_link('Registrations', href: "/admin/conferences/#{conference2.short_title}/registrations") - expect(page).to_not have_link('Registration Period', href: "/admin/conferences/#{conference2.short_title}/registration_period") - expect(page).to_not have_link('Questions', href: "/admin/conferences/#{conference2.short_title}/questions") - expect(page).to_not have_text('Donations') - expect(page).to_not have_link('Sponsorship Levels', href: "/admin/conferences/#{conference2.short_title}/supporter_levels") - expect(page).to_not have_link('Sponsors', href: "/admin/conferences/#{conference2.short_title}/sponsors") - expect(page).to_not have_link('Tickets', href: "/admin/conferences/#{conference2.short_title}/tickets") - expect(page).to_not have_text('Objectives') - expect(page).to_not have_link('Campaigns', href: "/admin/conferences/#{conference2.short_title}/campaigns") - expect(page).to_not have_link('Goals', href: "/admin/conferences/#{conference2.short_title}/targets") - expect(page).to have_link('E-Mails', href: "/admin/conferences/#{conference2.short_title}/emails") - expect(page).to have_link('Roles', href: "/admin/conferences/#{conference2.short_title}/roles") - expect(page).to have_link('Resources', href: "/admin/conferences/#{conference2.short_title}/resources") - - visit admin_conference_venue_rooms_path(conference2.short_title) - expect(current_path).to eq(admin_conference_venue_rooms_path(conference2.short_title)) - create(:room, venue: conference2.venue) - visit edit_admin_conference_venue_room_path(conference2.short_title, conference2.venue.rooms.first) - expect(current_path).to eq(edit_admin_conference_venue_room_path(conference2.short_title, conference2.venue.rooms.first)) - - visit new_admin_conference_program_path(conference2.short_title) - expect(current_path).to eq(new_admin_conference_program_path(conference2.short_title)) - - visit edit_admin_conference_program_path(conference2.short_title) - expect(current_path).to eq(edit_admin_conference_program_path(conference2.short_title)) - - visit new_admin_conference_program_cfp_path(conference2.short_title) - expect(current_path).to eq root_path - - conference2.program.cfp.destroy! - visit new_admin_conference_program_cfp_path(conference2.short_title) - expect(current_path).to eq new_admin_conference_program_cfp_path(conference2.short_title) - create(:cfp, program: conference2.program) - - visit edit_admin_conference_program_cfp_path(conference2.short_title, conference2.program.cfp) - expect(current_path).to eq(edit_admin_conference_program_cfp_path(conference2.short_title, conference2.program.cfp)) - - create(:event, program: conference2.program) - visit edit_admin_conference_program_event_path(conference2.short_title, conference2.program.events.first) - expect(current_path).to eq(edit_admin_conference_program_event_path(conference2.short_title, conference2.program.events.first)) - - visit admin_conference_program_event_types_path(conference2.short_title) - expect(current_path).to eq(admin_conference_program_event_types_path(conference2.short_title)) - - visit new_admin_conference_program_event_type_path(conference2.short_title) - expect(current_path).to eq(new_admin_conference_program_event_type_path(conference2.short_title)) - - visit edit_admin_conference_program_event_type_path(conference2.short_title, conference2.program.event_types.first) - expect(current_path).to eq(edit_admin_conference_program_event_type_path(conference2.short_title, conference2.program.event_types.first)) - - visit admin_conference_program_difficulty_levels_path(conference2.short_title) - expect(current_path).to eq(admin_conference_program_difficulty_levels_path(conference2.short_title)) - - visit new_admin_conference_program_difficulty_level_path(conference2.short_title) - expect(current_path).to eq(new_admin_conference_program_difficulty_level_path(conference2.short_title)) - - visit edit_admin_conference_program_difficulty_level_path(conference2.short_title, conference2.program.difficulty_levels.first) - expect(current_path).to eq(edit_admin_conference_program_difficulty_level_path(conference2.short_title, conference2.program.difficulty_levels.first)) - - visit admin_conference_schedules_path(conference2.short_title) - expect(current_path).to eq(admin_conference_schedules_path(conference2.short_title)) - - create(:schedule, program: conference2.program) - visit admin_conference_schedule_path(conference2.short_title, conference2.program.schedules.first) - expect(current_path).to eq(admin_conference_schedule_path(conference2.short_title, conference2.program.schedules.first)) - - visit admin_conference_program_reports_path(conference2.short_title) - expect(current_path).to eq(admin_conference_program_reports_path(conference2.short_title)) - - visit admin_conference_registrations_path(conference2.short_title) - expect(current_path).to eq(admin_conference_registrations_path(conference2.short_title)) - - create(:registration, user: create(:user), conference: conference2) - visit edit_admin_conference_registration_path(conference2.short_title, conference2.registrations.first) - expect(current_path).to eq(root_path) - - visit new_admin_conference_registration_period_path(conference2.short_title) - expect(current_path).to eq(root_path) - - create(:registration_period, conference: conference2) - visit edit_admin_conference_registration_period_path(conference2.short_title) - expect(current_path).to eq(root_path) - - visit admin_conference_questions_path(conference2.short_title) - expect(current_path).to eq(root_path) - - visit admin_conference_program_tracks_path(conference2.short_title) - expect(current_path).to eq(admin_conference_program_tracks_path(conference2.short_title)) - - visit admin_conference_roles_path(conference2.short_title) - expect(current_path).to eq(admin_conference_roles_path(conference2.short_title)) - - visit admin_conference_emails_path(conference2.short_title) - expect(current_path).to eq(admin_conference_emails_path(conference2.short_title)) - end - - it_behaves_like 'correct abilities for cfps and info_desk', 'cfp' - end - - context 'when user is info desk' do - before do - sign_in user_info_desk - end - - scenario 'has correct abilities' do - visit admin_conference_path(conference3.short_title) - expect(current_path).to eq(admin_conference_path(conference3.short_title)) - - expect(page).to have_selector('li.nav-header.nav-header-bigger a', text: 'Dashboard') - expect(page).to_not have_link('Venue', href: "/admin/conferences/#{conference3.short_title}/venue") - expect(page).to_not have_link('Rooms', href: "/admin/conferences/#{conference3.short_title}/venue/rooms") - expect(page).to_not have_link('Program', href: "/admin/conferences/#{conference3.short_title}/program") - expect(page).to_not have_link('Call for Papers', href: "/admin/conferences/#{conference2.short_title}/program/cfps") - expect(page).to_not have_link('Events', href: "/admin/conferences/#{conference3.short_title}/program/events") - expect(page).to_not have_link('Tracks', href: "/admin/conferences/#{conference3.short_title}/program/tracks") - expect(page).to_not have_link('Event Types', href: "/admin/conferences/#{conference3.short_title}/program/event_types") - expect(page).to_not have_link('Difficulty Levels', href: "/admin/conferences/#{conference3.short_title}/program/difficulty_levels") - expect(page).to_not have_link('Schedules', href: "/admin/conferences/#{conference3.short_title}/schedules") - expect(page).to_not have_link('Reports', href: "/admin/conferences/#{conference3.short_title}/program/reports") - expect(page).to have_link('Registrations', href: "/admin/conferences/#{conference3.short_title}/registrations") - expect(page).to have_link('Questions', href: "/admin/conferences/#{conference3.short_title}/questions") - expect(page).to_not have_link('E-Mails', href: "/admin/conferences/#{conference3.short_title}/emails") - - visit admin_conference_venue_rooms_path(conference3.short_title) - expect(current_path).to eq(root_path) - - create(:room, venue: conference3.venue) - visit edit_admin_conference_venue_room_path(conference3.short_title, conference3.venue.rooms.first) - expect(current_path).to eq(root_path) - - visit new_admin_conference_program_path(conference3.short_title) - expect(current_path).to eq(root_path) - - visit edit_admin_conference_program_path(conference3.short_title) - expect(current_path).to eq(root_path) - - visit new_admin_conference_program_cfp_path(conference3.short_title) - expect(current_path).to eq root_path - - conference1.program.cfp.destroy! - visit new_admin_conference_program_cfp_path(conference3.short_title) - expect(current_path).to eq root_path - create(:cfp, program: conference1.program) - - visit edit_admin_conference_program_cfp_path(conference3.short_title, conference3.program.cfp) - expect(current_path).to eq(root_path) - - visit admin_conference_program_events_path(conference3.short_title) - expect(current_path).to eq(root_path) - - create(:event, program: conference3.program) - visit edit_admin_conference_program_event_path(conference3.short_title, conference3.program.events.first) - expect(current_path).to eq(root_path) - - visit admin_conference_program_event_types_path(conference3.short_title) - expect(current_path).to eq(root_path) - - visit new_admin_conference_program_event_type_path(conference3.short_title) - expect(current_path).to eq(root_path) - - visit edit_admin_conference_program_event_type_path(conference3.short_title, conference3.program.event_types.first) - expect(current_path).to eq(root_path) - - visit admin_conference_program_difficulty_levels_path(conference3.short_title) - expect(current_path).to eq(root_path) - - visit new_admin_conference_program_difficulty_level_path(conference3.short_title) - expect(current_path).to eq(root_path) - - visit edit_admin_conference_program_difficulty_level_path(conference3.short_title, conference3.program.difficulty_levels.first) - expect(current_path).to eq(root_path) - - visit admin_conference_schedules_path(conference3.short_title) - expect(current_path).to eq(root_path) - - create(:schedule, program: conference3.program) - visit admin_conference_schedule_path(conference3.short_title, conference3.program.schedules.first) - expect(current_path).to eq(root_path) - - visit admin_conference_program_reports_path(conference3.short_title) - expect(current_path).to eq(root_path) - - visit admin_conference_registrations_path(conference3.short_title) - expect(current_path).to eq(admin_conference_registrations_path(conference3.short_title)) - - create(:registration, user: create(:user), conference: conference3) - visit edit_admin_conference_registration_path(conference3.short_title, conference3.registrations.first) - expect(current_path).to eq(edit_admin_conference_registration_path(conference3.short_title, conference3.registrations.first)) - - visit admin_conference_questions_path(conference3.short_title) - expect(current_path).to eq(admin_conference_questions_path(conference3.short_title)) - - visit admin_conference_program_tracks_path(conference3.short_title) - expect(current_path).to eq(root_path) - - visit admin_conference_emails_path(conference3.short_title) - expect(current_path).to eq(root_path) - end - - it_behaves_like 'correct abilities for cfps and info_desk', 'info_desk' - end -end diff --git a/spec/features/cfp_ability_spec.rb b/spec/features/cfp_ability_spec.rb new file mode 100644 index 00000000..52725527 --- /dev/null +++ b/spec/features/cfp_ability_spec.rb @@ -0,0 +1,250 @@ +require 'spec_helper' + +feature 'Has correct abilities' do + + let(:organization) { create(:organization) } + # It is necessary to use bang version of let to build roles before user + let(:conference) { create(:full_conference, organization: organization) } # user is cfp + let(:role_cfp) { Role.find_by(name: 'cfp', resource: conference) } + let(:user_cfp) { create(:user, role_ids: [role_cfp.id]) } + + context 'when user is cfp' do + before do + sign_in user_cfp + 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 have_link('Venue', href: "/admin/conferences/#{conference.short_title}/venue") + expect(page).to have_link('Rooms', href: "/admin/conferences/#{conference.short_title}/venue/rooms") + expect(page).to have_link('Program', href: "/admin/conferences/#{conference.short_title}/program") + expect(page).to have_link('Call for Papers', href: "/admin/conferences/#{conference.short_title}/program/cfps") + expect(page).to 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 have_link('Event Types', href: "/admin/conferences/#{conference.short_title}/program/event_types") + expect(page).to have_link('Difficulty Levels', href: "/admin/conferences/#{conference.short_title}/program/difficulty_levels") + expect(page).to have_link('Schedules', href: "/admin/conferences/#{conference.short_title}/schedules") + expect(page).to 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('Questions', href: "/admin/conferences/#{conference.short_title}/questions") + expect(page).to have_link('E-Mails', href: "/admin/conferences/#{conference.short_title}/emails") + expect(page).to_not have_link('Lodgings', href: "/admin/conferences/#{conference.short_title}/lodgings") + expect(page).to_not have_link('Registration Period', href: "/admin/conferences/#{conference.short_title}/registration_period") + 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 have_link('Roles', href: "/admin/conferences/#{conference.short_title}/roles") + expect(page).to have_link('Resources', href: "/admin/conferences/#{conference.short_title}/resources") + + visit admin_conference_venue_rooms_path(conference.short_title) + expect(current_path).to eq(admin_conference_venue_rooms_path(conference.short_title)) + create(:room, venue: conference.venue) + visit edit_admin_conference_venue_room_path(conference.short_title, conference.venue.rooms.first) + expect(current_path).to eq(edit_admin_conference_venue_room_path(conference.short_title, conference.venue.rooms.first)) + + visit new_admin_conference_program_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_program_path(conference.short_title)) + + visit edit_admin_conference_program_path(conference.short_title) + expect(current_path).to eq(edit_admin_conference_program_path(conference.short_title)) + + visit new_admin_conference_program_cfp_path(conference.short_title) + expect(current_path).to eq root_path + + 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)) + + create(:event, program: conference.program) + visit edit_admin_conference_program_event_path(conference.short_title, conference.program.events.first) + expect(current_path).to eq(edit_admin_conference_program_event_path(conference.short_title, conference.program.events.first)) + + visit admin_conference_program_event_types_path(conference.short_title) + expect(current_path).to eq(admin_conference_program_event_types_path(conference.short_title)) + + visit new_admin_conference_program_event_type_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_program_event_type_path(conference.short_title)) + + visit edit_admin_conference_program_event_type_path(conference.short_title, conference.program.event_types.first) + expect(current_path).to eq(edit_admin_conference_program_event_type_path(conference.short_title, conference.program.event_types.first)) + + visit admin_conference_program_difficulty_levels_path(conference.short_title) + expect(current_path).to eq(admin_conference_program_difficulty_levels_path(conference.short_title)) + + visit new_admin_conference_program_difficulty_level_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_program_difficulty_level_path(conference.short_title)) + + visit edit_admin_conference_program_difficulty_level_path(conference.short_title, conference.program.difficulty_levels.first) + expect(current_path).to eq(edit_admin_conference_program_difficulty_level_path(conference.short_title, conference.program.difficulty_levels.first)) + + visit admin_conference_schedules_path(conference.short_title) + expect(current_path).to eq(admin_conference_schedules_path(conference.short_title)) + + create(:schedule, program: conference.program) + visit admin_conference_schedule_path(conference.short_title, conference.program.schedules.first) + expect(current_path).to eq(admin_conference_schedule_path(conference.short_title, conference.program.schedules.first)) + + 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_program_tracks_path(conference.short_title) + expect(current_path).to eq(admin_conference_program_tracks_path(conference.short_title)) + + 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(admin_conference_emails_path(conference.short_title)) + + visit admin_conference_path(conference.short_title) + expect(current_path).to eq(admin_conference_path(conference.short_title)) + + visit admin_organizations_path + expect(current_path).to eq(admin_organizations_path) + + visit edit_admin_organization_path(organization) + expect(current_path).to eq(root_path) + + visit new_admin_organization_path + expect(current_path).to eq(root_path) + + 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_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_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_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_roles_path(conference.short_title) + expect(current_path).to eq(admin_conference_roles_path(conference.short_title)) + + 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(edit_admin_conference_resource_path(conference.short_title, conference.resources.first)) + + visit admin_revision_history_path + expect(current_path).to eq(root_path) + end + end +end diff --git a/spec/features/info_desk_ability_spec.rb b/spec/features/info_desk_ability_spec.rb new file mode 100644 index 00000000..d7b0b909 --- /dev/null +++ b/spec/features/info_desk_ability_spec.rb @@ -0,0 +1,246 @@ +require 'spec_helper' + +feature 'Has correct abilities' do + + let(:organization) { create(:organization) } + # It is necessary to use bang version of let to build roles before user + let(:conference) { create(:full_conference, organization: organization) } # user is info_desk + + let(:role_info_desk) { Role.find_by(name: 'info_desk', resource: conference) } + + let(:user_info_desk) { create(:user, role_ids: [role_info_desk.id]) } + + context 'when user is info desk' do + before do + sign_in user_info_desk + 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_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('Lodgings', href: "/admin/conferences/#{conference.short_title}/lodgings") + expect(page).to_not have_link('Registration Period', href: "/admin/conferences/#{conference.short_title}/registration_period") + 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 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_selector('li.nav-header.nav-header-bigger a', text: 'Dashboard') + 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('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_not 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 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") + + visit admin_organizations_path + expect(current_path).to eq(admin_organizations_path) + + visit edit_admin_organization_path(organization) + expect(current_path).to eq(root_path) + + visit new_admin_organization_path + expect(current_path).to eq(root_path) + + 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_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_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_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_roles_path(conference.short_title) + expect(current_path).to eq(admin_conference_roles_path(conference.short_title)) + + 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(edit_admin_conference_resource_path(conference.short_title, conference.resources.first)) + + visit admin_revision_history_path + expect(current_path).to eq(root_path) + + visit admin_conference_path(conference.short_title) + expect(current_path).to eq(admin_conference_path(conference.short_title)) + + 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 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 + + conference.program.cfp.destroy! + visit new_admin_conference_program_cfp_path(conference.short_title) + expect(current_path).to eq root_path + create(:cfp, program: conference.program) + + 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(root_path) + + 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(root_path) + + 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(edit_admin_conference_registration_path(conference.short_title, conference.registrations.first)) + + visit admin_conference_questions_path(conference.short_title) + expect(current_path).to eq(admin_conference_questions_path(conference.short_title)) + + visit admin_conference_program_tracks_path(conference.short_title) + expect(current_path).to eq(root_path) + + visit admin_conference_emails_path(conference.short_title) + expect(current_path).to eq(root_path) + end + end +end diff --git a/spec/features/organization_admin_ability_spec.rb b/spec/features/organization_admin_ability_spec.rb new file mode 100644 index 00000000..5a247dd8 --- /dev/null +++ b/spec/features/organization_admin_ability_spec.rb @@ -0,0 +1,240 @@ +require 'spec_helper' + +feature 'Has correct abilities' do + let(:organization) { create(:organization) } + let(:conference) { create(:full_conference, organization: organization) } # user is organization_admin + let(:role_organization_admin) { Role.find_by(name: 'organization_admin', resource: organization) } + let(:user_organization_admin) { create(:user, role_ids: [role_organization_admin.id]) } + + context 'when user is organization_admin' do + before do + sign_in user_organization_admin + end + + scenario 'for organization attributes' do + visit admin_organizations_path + expect(current_path).to eq(admin_organizations_path) + + visit edit_admin_organization_path(organization) + expect(current_path).to eq(edit_admin_organization_path(organization)) + + visit new_admin_organization_path + expect(current_path).to eq(root_path) + end + + scenario 'for 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 have_link('Basics', href: "/admin/conferences/#{conference.short_title}/edit") + expect(page).to 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 have_link('Splashpage', href: "/admin/conferences/#{conference.short_title}/splashpage") + expect(page).to have_link('Venue', href: "/admin/conferences/#{conference.short_title}/venue") + expect(page).to have_link('Rooms', href: "/admin/conferences/#{conference.short_title}/venue/rooms") + expect(page).to 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 have_link('Call for Papers', href: "/admin/conferences/#{conference.short_title}/program/cfps") + expect(page).to 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 have_link('Event Types', href: "/admin/conferences/#{conference.short_title}/program/event_types") + expect(page).to have_link('Difficulty Levels', href: "/admin/conferences/#{conference.short_title}/program/difficulty_levels") + expect(page).to have_link('Schedules', href: "/admin/conferences/#{conference.short_title}/schedules") + expect(page).to have_link('Reports', href: "/admin/conferences/#{conference.short_title}/program/reports") + expect(page).to have_link('Registrations', href: "/admin/conferences/#{conference.short_title}/registrations") + expect(page).to have_link('Registration Period', href: "/admin/conferences/#{conference.short_title}/registration_period") + expect(page).to have_link('Questions', href: "/admin/conferences/#{conference.short_title}/questions") + expect(page).to have_text('Donations') + expect(page).to have_link('Sponsorship Levels', href: "/admin/conferences/#{conference.short_title}/sponsorship_levels") + expect(page).to have_link('Sponsors', href: "/admin/conferences/#{conference.short_title}/sponsors") + expect(page).to have_link('Tickets', href: "/admin/conferences/#{conference.short_title}/tickets") + expect(page).to have_text('Objectives') + expect(page).to have_link('Campaigns', href: "/admin/conferences/#{conference.short_title}/campaigns") + expect(page).to have_link('Goals', href: "/admin/conferences/#{conference.short_title}/targets") + 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") + + visit edit_admin_conference_path(conference.short_title) + expect(current_path).to eq(edit_admin_conference_path(conference.short_title)) + + visit edit_admin_conference_contact_path(conference.short_title) + expect(current_path).to eq(edit_admin_conference_contact_path(conference.short_title)) + + 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(new_admin_conference_splashpage_path(conference.short_title)) + + visit edit_admin_conference_splashpage_path(conference.short_title) + expect(current_path).to eq(edit_admin_conference_splashpage_path(conference.short_title)) + + visit new_admin_conference_venue_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_venue_path(conference.short_title)) + + conference.venue = create(:venue) + visit edit_admin_conference_venue_path(conference.short_title) + expect(current_path).to eq(edit_admin_conference_venue_path(conference.short_title)) + + visit admin_conference_venue_rooms_path(conference.short_title) + expect(current_path).to eq(admin_conference_venue_rooms_path(conference.short_title)) + + create(:room, venue: conference.venue) + visit edit_admin_conference_venue_room_path(conference.short_title, conference.venue.rooms.first) + expect(current_path).to eq(edit_admin_conference_venue_room_path(conference.short_title, conference.venue.rooms.first)) + + visit admin_conference_lodgings_path(conference.short_title) + expect(current_path).to eq(admin_conference_lodgings_path(conference.short_title)) + + visit new_admin_conference_lodging_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_lodging_path(conference.short_title)) + + create(:lodging, conference: conference) + visit edit_admin_conference_lodging_path(conference.short_title, conference.lodgings.first) + expect(current_path).to eq(edit_admin_conference_lodging_path(conference.short_title, conference.lodgings.first)) + + visit new_admin_conference_program_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_program_path(conference.short_title)) + + visit edit_admin_conference_program_path(conference.short_title) + expect(current_path).to eq(edit_admin_conference_program_path(conference.short_title)) + + visit new_admin_conference_program_cfp_path(conference.short_title) + expect(current_path).to eq root_path + + 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)) + + 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(edit_admin_conference_program_event_path(conference.short_title, conference.program.events.first)) + + visit admin_conference_program_event_types_path(conference.short_title) + expect(current_path).to eq(admin_conference_program_event_types_path(conference.short_title)) + + visit new_admin_conference_program_event_type_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_program_event_type_path(conference.short_title)) + + visit edit_admin_conference_program_event_type_path(conference.short_title, conference.program.event_types.first) + expect(current_path).to eq(edit_admin_conference_program_event_type_path(conference.short_title, conference.program.event_types.first)) + + visit admin_conference_program_difficulty_levels_path(conference.short_title) + expect(current_path).to eq(admin_conference_program_difficulty_levels_path(conference.short_title)) + + visit new_admin_conference_program_difficulty_level_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_program_difficulty_level_path(conference.short_title)) + + visit edit_admin_conference_program_difficulty_level_path(conference.short_title, conference.program.difficulty_levels.first) + expect(current_path).to eq(edit_admin_conference_program_difficulty_level_path(conference.short_title, conference.program.difficulty_levels.first)) + + visit admin_conference_schedules_path(conference.short_title) + expect(current_path).to eq(admin_conference_schedules_path(conference.short_title)) + + create(:schedule, program: conference.program) + visit admin_conference_schedule_path(conference.short_title, conference.program.schedules.first) + expect(current_path).to eq(admin_conference_schedule_path(conference.short_title, conference.program.schedules.first)) + + 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(edit_admin_conference_registration_path(conference.short_title, conference.registrations.first)) + + visit new_admin_conference_registration_period_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_registration_period_path(conference.short_title)) + + create(:registration_period, conference: conference) + visit edit_admin_conference_registration_period_path(conference.short_title) + expect(current_path).to eq(edit_admin_conference_registration_period_path(conference.short_title)) + + visit admin_conference_questions_path(conference.short_title) + expect(current_path).to eq(admin_conference_questions_path(conference.short_title)) + + visit admin_conference_sponsorship_levels_path(conference.short_title) + expect(current_path).to eq(admin_conference_sponsorship_levels_path(conference.short_title)) + + visit new_admin_conference_sponsorship_level_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_sponsorship_level_path(conference.short_title)) + + create(:sponsorship_level, conference: conference) + visit edit_admin_conference_sponsorship_level_path(conference.short_title, conference.sponsorship_levels.first) + expect(current_path).to eq(edit_admin_conference_sponsorship_level_path(conference.short_title, conference.sponsorship_levels.first)) + + visit admin_conference_sponsors_path(conference.short_title) + expect(current_path).to eq(admin_conference_sponsors_path(conference.short_title)) + + visit new_admin_conference_sponsor_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_sponsor_path(conference.short_title)) + + 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(edit_admin_conference_sponsor_path(conference.short_title, conference.sponsors.first)) + + visit admin_conference_tickets_path(conference.short_title) + expect(current_path).to eq(admin_conference_tickets_path(conference.short_title)) + + visit new_admin_conference_ticket_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_ticket_path(conference.short_title)) + + create(:ticket, conference: conference) + visit edit_admin_conference_ticket_path(conference.short_title, conference.tickets.first) + expect(current_path).to eq(edit_admin_conference_ticket_path(conference.short_title, conference.tickets.first)) + + visit admin_conference_campaigns_path(conference.short_title) + expect(current_path).to eq(admin_conference_campaigns_path(conference.short_title)) + + visit new_admin_conference_campaign_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_campaign_path(conference.short_title)) + + create(:campaign, conference: conference) + visit edit_admin_conference_campaign_path(conference.short_title, conference.campaigns.first) + expect(current_path).to eq(edit_admin_conference_campaign_path(conference.short_title, conference.campaigns.first)) + + visit admin_conference_targets_path(conference.short_title) + expect(current_path).to eq(admin_conference_targets_path(conference.short_title)) + + visit new_admin_conference_target_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_target_path(conference.short_title)) + + create(:target, conference: conference) + visit edit_admin_conference_target_path(conference.short_title, conference.targets.first) + expect(current_path).to eq(edit_admin_conference_target_path(conference.short_title, conference.targets.first)) + + visit admin_conference_program_tracks_path(conference.short_title) + expect(current_path).to eq(admin_conference_program_tracks_path(conference.short_title)) + + 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(admin_conference_emails_path(conference.short_title)) + + 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(edit_admin_conference_resource_path(conference.short_title, conference.resources.first)) + + visit admin_revision_history_path + expect(current_path).to eq(admin_revision_history_path) + end + end +end diff --git a/spec/features/organizer_ability_spec.rb b/spec/features/organizer_ability_spec.rb new file mode 100644 index 00000000..9604fad6 --- /dev/null +++ b/spec/features/organizer_ability_spec.rb @@ -0,0 +1,247 @@ +require 'spec_helper' + +feature 'Has correct abilities' do + + let(:organization) { create(:organization) } + # It is necessary to use bang version of let to build roles before user + let(:conference) { create(:full_conference, organization: organization) } # user is organizer + let(:other_conference) { create(:conference, organization: organization) } # user is organizer, venue is not set by default + let(:role_organizer_conf) { Role.find_by(name: 'organizer', resource: conference) } + let(:role_organizer_other_conf) { Role.find_by(name: 'organizer', resource: other_conference) } + let(:user_organizer) { create(:user, role_ids: [role_organizer_conf.id, role_organizer_other_conf.id]) } + + context 'when user is organizer' do + before do + sign_in user_organizer + end + + scenario 'for organization attributes' do + visit admin_organizations_path + expect(current_path).to eq(admin_organizations_path) + + visit edit_admin_organization_path(organization) + expect(current_path).to eq(root_path) + + visit new_admin_organization_path + expect(current_path).to eq(root_path) + end + + scenario 'for 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 have_link('Basics', href: "/admin/conferences/#{conference.short_title}/edit") + expect(page).to 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 have_link('Splashpage', href: "/admin/conferences/#{conference.short_title}/splashpage") + expect(page).to have_link('Venue', href: "/admin/conferences/#{conference.short_title}/venue") + expect(page).to have_link('Rooms', href: "/admin/conferences/#{conference.short_title}/venue/rooms") + expect(page).to 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 have_link('Call for Papers', href: "/admin/conferences/#{conference.short_title}/program/cfps") + expect(page).to 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 have_link('Event Types', href: "/admin/conferences/#{conference.short_title}/program/event_types") + expect(page).to have_link('Difficulty Levels', href: "/admin/conferences/#{conference.short_title}/program/difficulty_levels") + expect(page).to have_link('Schedules', href: "/admin/conferences/#{conference.short_title}/schedules") + expect(page).to have_link('Reports', href: "/admin/conferences/#{conference.short_title}/program/reports") + expect(page).to have_link('Registrations', href: "/admin/conferences/#{conference.short_title}/registrations") + expect(page).to have_link('Registration Period', href: "/admin/conferences/#{conference.short_title}/registration_period") + expect(page).to have_link('Questions', href: "/admin/conferences/#{conference.short_title}/questions") + expect(page).to have_text('Donations') + expect(page).to have_link('Sponsorship Levels', href: "/admin/conferences/#{conference.short_title}/sponsorship_levels") + expect(page).to have_link('Sponsors', href: "/admin/conferences/#{conference.short_title}/sponsors") + expect(page).to have_link('Tickets', href: "/admin/conferences/#{conference.short_title}/tickets") + expect(page).to have_text('Objectives') + expect(page).to have_link('Campaigns', href: "/admin/conferences/#{conference.short_title}/campaigns") + expect(page).to have_link('Goals', href: "/admin/conferences/#{conference.short_title}/targets") + 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") + + visit admin_conference_path(other_conference.short_title) + expect(page).to have_link('Add venue', href: "/admin/conferences/#{other_conference.short_title}/venue/new") + + visit edit_admin_conference_path(conference.short_title) + expect(current_path).to eq(edit_admin_conference_path(conference.short_title)) + + visit edit_admin_conference_contact_path(conference.short_title) + expect(current_path).to eq(edit_admin_conference_contact_path(conference.short_title)) + + 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(new_admin_conference_splashpage_path(conference.short_title)) + + visit edit_admin_conference_splashpage_path(conference.short_title) + expect(current_path).to eq(edit_admin_conference_splashpage_path(conference.short_title)) + + visit new_admin_conference_venue_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_venue_path(conference.short_title)) + + conference.venue = create(:venue) + visit edit_admin_conference_venue_path(conference.short_title) + expect(current_path).to eq(edit_admin_conference_venue_path(conference.short_title)) + + visit admin_conference_venue_rooms_path(conference.short_title) + expect(current_path).to eq(admin_conference_venue_rooms_path(conference.short_title)) + + create(:room, venue: conference.venue) + visit edit_admin_conference_venue_room_path(conference.short_title, conference.venue.rooms.first) + expect(current_path).to eq(edit_admin_conference_venue_room_path(conference.short_title, conference.venue.rooms.first)) + + visit admin_conference_lodgings_path(conference.short_title) + expect(current_path).to eq(admin_conference_lodgings_path(conference.short_title)) + + visit new_admin_conference_lodging_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_lodging_path(conference.short_title)) + + create(:lodging, conference: conference) + visit edit_admin_conference_lodging_path(conference.short_title, conference.lodgings.first) + expect(current_path).to eq(edit_admin_conference_lodging_path(conference.short_title, conference.lodgings.first)) + + visit new_admin_conference_program_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_program_path(conference.short_title)) + + visit edit_admin_conference_program_path(conference.short_title) + expect(current_path).to eq(edit_admin_conference_program_path(conference.short_title)) + + visit new_admin_conference_program_cfp_path(conference.short_title) + expect(current_path).to eq root_path + + 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)) + + 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(edit_admin_conference_program_event_path(conference.short_title, conference.program.events.first)) + + visit admin_conference_program_event_types_path(conference.short_title) + expect(current_path).to eq(admin_conference_program_event_types_path(conference.short_title)) + + visit new_admin_conference_program_event_type_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_program_event_type_path(conference.short_title)) + + visit edit_admin_conference_program_event_type_path(conference.short_title, conference.program.event_types.first) + expect(current_path).to eq(edit_admin_conference_program_event_type_path(conference.short_title, conference.program.event_types.first)) + + visit admin_conference_program_difficulty_levels_path(conference.short_title) + expect(current_path).to eq(admin_conference_program_difficulty_levels_path(conference.short_title)) + + visit new_admin_conference_program_difficulty_level_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_program_difficulty_level_path(conference.short_title)) + + visit edit_admin_conference_program_difficulty_level_path(conference.short_title, conference.program.difficulty_levels.first) + expect(current_path).to eq(edit_admin_conference_program_difficulty_level_path(conference.short_title, conference.program.difficulty_levels.first)) + + visit admin_conference_schedules_path(conference.short_title) + expect(current_path).to eq(admin_conference_schedules_path(conference.short_title)) + + create(:schedule, program: conference.program) + visit admin_conference_schedule_path(conference.short_title, conference.program.schedules.first) + expect(current_path).to eq(admin_conference_schedule_path(conference.short_title, conference.program.schedules.first)) + + 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(edit_admin_conference_registration_path(conference.short_title, conference.registrations.first)) + + visit new_admin_conference_registration_period_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_registration_period_path(conference.short_title)) + + create(:registration_period, conference: conference) + visit edit_admin_conference_registration_period_path(conference.short_title) + expect(current_path).to eq(edit_admin_conference_registration_period_path(conference.short_title)) + + visit admin_conference_questions_path(conference.short_title) + expect(current_path).to eq(admin_conference_questions_path(conference.short_title)) + + visit admin_conference_sponsorship_levels_path(conference.short_title) + expect(current_path).to eq(admin_conference_sponsorship_levels_path(conference.short_title)) + + visit new_admin_conference_sponsorship_level_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_sponsorship_level_path(conference.short_title)) + + create(:sponsorship_level, conference: conference) + visit edit_admin_conference_sponsorship_level_path(conference.short_title, conference.sponsorship_levels.first) + expect(current_path).to eq(edit_admin_conference_sponsorship_level_path(conference.short_title, conference.sponsorship_levels.first)) + + visit admin_conference_sponsors_path(conference.short_title) + expect(current_path).to eq(admin_conference_sponsors_path(conference.short_title)) + + visit new_admin_conference_sponsor_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_sponsor_path(conference.short_title)) + + 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(edit_admin_conference_sponsor_path(conference.short_title, conference.sponsors.first)) + + visit admin_conference_tickets_path(conference.short_title) + expect(current_path).to eq(admin_conference_tickets_path(conference.short_title)) + + visit new_admin_conference_ticket_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_ticket_path(conference.short_title)) + + create(:ticket, conference: conference) + visit edit_admin_conference_ticket_path(conference.short_title, conference.tickets.first) + expect(current_path).to eq(edit_admin_conference_ticket_path(conference.short_title, conference.tickets.first)) + + visit admin_conference_campaigns_path(conference.short_title) + expect(current_path).to eq(admin_conference_campaigns_path(conference.short_title)) + + visit new_admin_conference_campaign_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_campaign_path(conference.short_title)) + + create(:campaign, conference: conference) + visit edit_admin_conference_campaign_path(conference.short_title, conference.campaigns.first) + expect(current_path).to eq(edit_admin_conference_campaign_path(conference.short_title, conference.campaigns.first)) + + visit admin_conference_targets_path(conference.short_title) + expect(current_path).to eq(admin_conference_targets_path(conference.short_title)) + + visit new_admin_conference_target_path(conference.short_title) + expect(current_path).to eq(new_admin_conference_target_path(conference.short_title)) + + create(:target, conference: conference) + visit edit_admin_conference_target_path(conference.short_title, conference.targets.first) + expect(current_path).to eq(edit_admin_conference_target_path(conference.short_title, conference.targets.first)) + + visit admin_conference_program_tracks_path(conference.short_title) + expect(current_path).to eq(admin_conference_program_tracks_path(conference.short_title)) + + 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(admin_conference_emails_path(conference.short_title)) + + 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(edit_admin_conference_resource_path(conference.short_title, conference.resources.first)) + + visit admin_revision_history_path + expect(current_path).to eq(admin_revision_history_path) + end + end +end diff --git a/spec/features/user_ability_spec.rb b/spec/features/user_ability_spec.rb new file mode 100644 index 00000000..d56e7441 --- /dev/null +++ b/spec/features/user_ability_spec.rb @@ -0,0 +1,21 @@ +require 'spec_helper' + +feature 'Has correct abilities' do + + let(:organization) { create(:organization) } + let(:conference) { create(:full_conference, organization: organization) } # user is cfp + let(:user) { create(:user) } + + context 'when user has no role' do + before do + sign_in user + end + + scenario 'for administration views' do + visit admin_conference_path(conference.short_title) + + expect(current_path).to eq root_path + expect(flash).to eq 'You are not authorized to access this page.' + end + end +end diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index fcf9b384..6803ffc5 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -139,22 +139,20 @@ describe 'User' do end shared_examples 'user with any role' do - before do - @other_organization = create(:organization) - @other_conference = create(:conference, organization: @other_organization) - end + 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)) } + 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 + %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| @@ -199,8 +197,8 @@ describe 'User' do it{ should_not be_able_to(:new, Organization)} it{ should_not be_able_to(:create, Organization)} - it{ should_not be_able_to(:new, Conference.new) } - it{ should_not be_able_to(:create, Conference.new) } + it{ should_not be_able_to(:new, Conference)} + it{ should_not be_able_to(:create, Conference) } it{ should be_able_to(:manage, my_conference) } it{ should_not be_able_to(:manage, conference_public) } it{ should be_able_to(:manage, my_conference.splashpage) } @@ -269,8 +267,8 @@ describe 'User' 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(:new, Conference) } + it{ should_not be_able_to(:create, Conference) } 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) } @@ -336,8 +334,8 @@ describe 'User' 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(:new, Conference) } + it{ should_not be_able_to(:create, Conference) } 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) } @@ -403,8 +401,8 @@ describe 'User' 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(:new, Conference) } + it{ should_not be_able_to(:create, Conference) } 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) } From d59a036cf17b405df38bbdf13aafce6dcef838df Mon Sep 17 00:00:00 2001 From: shlok007 Date: Fri, 30 Jun 2017 09:27:19 +0530 Subject: [PATCH 137/185] removed unnecessary comments and fixed grammatical errors --- spec/features/cfp_ability_spec.rb | 3 +-- spec/features/info_desk_ability_spec.rb | 5 +---- spec/features/organization_admin_ability_spec.rb | 2 +- spec/features/organization_spec.rb | 6 +++--- spec/features/organizer_ability_spec.rb | 3 +-- 5 files changed, 7 insertions(+), 12 deletions(-) diff --git a/spec/features/cfp_ability_spec.rb b/spec/features/cfp_ability_spec.rb index 52725527..235dedea 100644 --- a/spec/features/cfp_ability_spec.rb +++ b/spec/features/cfp_ability_spec.rb @@ -3,8 +3,7 @@ require 'spec_helper' feature 'Has correct abilities' do let(:organization) { create(:organization) } - # It is necessary to use bang version of let to build roles before user - let(:conference) { create(:full_conference, organization: organization) } # user is cfp + let(:conference) { create(:full_conference, organization: organization) } let(:role_cfp) { Role.find_by(name: 'cfp', resource: conference) } let(:user_cfp) { create(:user, role_ids: [role_cfp.id]) } diff --git a/spec/features/info_desk_ability_spec.rb b/spec/features/info_desk_ability_spec.rb index d7b0b909..7d0039fe 100644 --- a/spec/features/info_desk_ability_spec.rb +++ b/spec/features/info_desk_ability_spec.rb @@ -3,11 +3,8 @@ require 'spec_helper' feature 'Has correct abilities' do let(:organization) { create(:organization) } - # It is necessary to use bang version of let to build roles before user - let(:conference) { create(:full_conference, organization: organization) } # user is info_desk - + let(:conference) { create(:full_conference, organization: organization) } let(:role_info_desk) { Role.find_by(name: 'info_desk', resource: conference) } - let(:user_info_desk) { create(:user, role_ids: [role_info_desk.id]) } context 'when user is info desk' do diff --git a/spec/features/organization_admin_ability_spec.rb b/spec/features/organization_admin_ability_spec.rb index 5a247dd8..3a5ffcd3 100644 --- a/spec/features/organization_admin_ability_spec.rb +++ b/spec/features/organization_admin_ability_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' feature 'Has correct abilities' do let(:organization) { create(:organization) } - let(:conference) { create(:full_conference, organization: organization) } # user is organization_admin + let(:conference) { create(:full_conference, organization: organization) } let(:role_organization_admin) { Role.find_by(name: 'organization_admin', resource: organization) } let(:user_organization_admin) { create(:user, role_ids: [role_organization_admin.id]) } diff --git a/spec/features/organization_spec.rb b/spec/features/organization_spec.rb index 72fee466..6fcf590b 100644 --- a/spec/features/organization_spec.rb +++ b/spec/features/organization_spec.rb @@ -6,7 +6,7 @@ feature Organization do let(:organization_admin) { create(:user, role_ids: [organization_admin_role.id]) } let(:admin_user) { create(:admin) } - shared_examples 'successfully updates a organization' do + shared_examples 'successfully updates an organization' do scenario 'updates a exsisting organization', feature: true, js: true do visit edit_admin_organization_path(organization) fill_in 'organization_name', with: 'changed name' @@ -33,7 +33,7 @@ feature Organization do expect(Organization.last.name).to eq('Organization name') end - it_behaves_like 'successfully updates a organization' + it_behaves_like 'successfully updates an organization' end context 'signed in as organization admin' do @@ -46,6 +46,6 @@ feature Organization do expect(flash).to eq('You are not authorized to access this page.') end - it_behaves_like 'successfully updates a organization' + it_behaves_like 'successfully updates an organization' end end diff --git a/spec/features/organizer_ability_spec.rb b/spec/features/organizer_ability_spec.rb index 9604fad6..7617bc0a 100644 --- a/spec/features/organizer_ability_spec.rb +++ b/spec/features/organizer_ability_spec.rb @@ -3,8 +3,7 @@ require 'spec_helper' feature 'Has correct abilities' do let(:organization) { create(:organization) } - # It is necessary to use bang version of let to build roles before user - let(:conference) { create(:full_conference, organization: organization) } # user is organizer + let(:conference) { create(:full_conference, organization: organization) } let(:other_conference) { create(:conference, organization: organization) } # user is organizer, venue is not set by default let(:role_organizer_conf) { Role.find_by(name: 'organizer', resource: conference) } let(:role_organizer_other_conf) { Role.find_by(name: 'organizer', resource: other_conference) } From f68fd39095915bcfda29a41b1ddc2abc19aa8695 Mon Sep 17 00:00:00 2001 From: shlok007 Date: Mon, 3 Jul 2017 04:17:06 +0530 Subject: [PATCH 138/185] fixed abilities for conference#new and organization#new --- app/models/ability.rb | 6 +++--- spec/models/ability_spec.rb | 38 +++++++++++++++++++++++-------------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/app/models/ability.rb b/app/models/ability.rb index 8185fadd..5001278a 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -150,11 +150,11 @@ class Ability 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 :manage, Organization, id: org_ids_for_organization_admin + can [:read, :update, :destroy], Organization, id: org_ids_for_organization_admin can :new, Conference can :manage, Conference, organization_id: org_ids_for_organization_admin - conf_ids_for_organization_admin = Conference.where(organization_id: org_ids_for_organization_admin).pluck(:id) can [:index, :show], Role can [:edit, :update], Role do |role| role.resource_type == 'Organization' && (org_ids_for_organization_admin.include? role.resource_id) @@ -167,7 +167,7 @@ class Ability # 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 :manage, 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 diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index 6803ffc5..02aa4882 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -172,11 +172,19 @@ describe 'User' do 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_conference) { create(:conference) } + let(:other_organization) { create(:organization) } + let(:other_conference) { create(:conference, organization: other_organization) } - it{ should_not be_able_to(:manage, other_conference) } it{ should be_able_to(:manage, my_conference) } - it{ should be_able_to(:manage, organization) } + 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 @@ -195,11 +203,13 @@ describe 'User' do should be_able_to(:destroy, my_venue) end - it{ should_not be_able_to(:new, Organization)} - it{ should_not be_able_to(:create, Organization)} - it{ should_not be_able_to(:new, Conference)} - it{ should_not be_able_to(:create, Conference) } - it{ should be_able_to(:manage, my_conference) } + 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) } @@ -267,8 +277,8 @@ describe 'User' 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) } - it{ should_not be_able_to(:create, Conference) } + 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) } @@ -334,8 +344,8 @@ describe 'User' 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) } - it{ should_not be_able_to(:create, Conference) } + 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) } @@ -401,8 +411,8 @@ describe 'User' 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) } - it{ should_not be_able_to(:create, Conference) } + 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) } From 3d4adb568379d3de50dc6069aad273142c8aa3ee Mon Sep 17 00:00:00 2001 From: siddhantbajaj Date: Mon, 26 Jun 2017 04:04:36 +0530 Subject: [PATCH 139/185] Allow admin to show/generate ticket Created physical ticket controller and views for admin. --- .../admin/physical_ticket_controller.rb | 14 ++++++ .../admin/physical_ticket/index.html.haml | 43 +++++++++++++++++++ app/views/admin/tickets/index.html.haml | 6 +-- config/routes.rb | 1 + 4 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 app/controllers/admin/physical_ticket_controller.rb create mode 100644 app/views/admin/physical_ticket/index.html.haml diff --git a/app/controllers/admin/physical_ticket_controller.rb b/app/controllers/admin/physical_ticket_controller.rb new file mode 100644 index 00000000..d43c5c33 --- /dev/null +++ b/app/controllers/admin/physical_ticket_controller.rb @@ -0,0 +1,14 @@ +module Admin + class PhysicalTicketController < Admin::BaseController + before_action :authenticate_user! + load_resource :conference, find_by: :short_title + load_and_authorize_resource + authorize_resource :conference_registrations, class: Registration + + def index + @physical_tickets = @conference.physical_tickets + @tickets_sold_distribution = @conference.tickets_sold_distribution + @tickets_turnover_distribution = @conference.tickets_turnover_distribution + end + end +end diff --git a/app/views/admin/physical_ticket/index.html.haml b/app/views/admin/physical_ticket/index.html.haml new file mode 100644 index 00000000..fe128932 --- /dev/null +++ b/app/views/admin/physical_ticket/index.html.haml @@ -0,0 +1,43 @@ +.container + .row + .col-md-12.page-header + %h2 + Tickets Sold + .text-muted + Tickets sold for the conference + .row + .col-md-4 + = render partial: 'admin/conferences/doughnut_chart', + locals: { title: 'Tickets sold', data: @tickets_sold_distribution } + .col-md-4 + = render partial: 'admin/conferences/doughnut_chart', + locals: {title: 'Tickets turnover', data: @tickets_turnover_distribution} + %br + - if @physical_tickets.any? + .row + .col-md-12 + %table.table.table-hover.datatable#tickets + %thead + %th ID + %th Type + %th User + %th Actions + %tbody + - @physical_tickets.each do |physical_ticket| + %tr + %td= physical_ticket.id + %td= physical_ticket.ticket.title + %td= physical_ticket.user.email + %td + .btn-group + = link_to 'Show', + conference_physical_ticket_path(@conference.short_title, + physical_ticket.id), + class: 'btn btn-primary' + = link_to 'Generate PDF', + conference_physical_ticket_path(@conference.short_title, + physical_ticket.id, + format: :pdf), + class: 'button btn btn-default btn-info' + - else + %h5 No Tickets sold! diff --git a/app/views/admin/tickets/index.html.haml b/app/views/admin/tickets/index.html.haml index 6a0c7dca..bb2804bf 100644 --- a/app/views/admin/tickets/index.html.haml +++ b/app/views/admin/tickets/index.html.haml @@ -4,11 +4,6 @@ %h1 Tickets %p.text-muted Tickets to get during registration -.row - .col-md-4 - = render partial: 'admin/conferences/doughnut_chart', locals: { title: 'Tickets sold', data: @tickets_sold_distribution,} - .col-md-4 - = render partial: 'admin/conferences/doughnut_chart', locals: { title: 'Tickets turnover', data: @tickets_turnover_distribution } %br - if @conference.tickets.any? .row @@ -42,3 +37,4 @@ .row .col-md-12 = link_to 'Add Ticket', new_admin_conference_ticket_path, class: 'btn btn-success pull-right' + = link_to 'Tickets Sold', admin_conference_physical_ticket_index_path, class: 'button btn btn-default btn-info pull-right' diff --git a/config/routes.rb b/config/routes.rb index 8fa4b857..ae67a820 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -81,6 +81,7 @@ Osem::Application.routes.draw do resources :targets, except: [:show] resources :campaigns, except: [:show] resources :emails, only: [:show, :update, :index] + resources :physical_ticket, only: [:index] resources :roles, except: [ :new, :create ] do member do post :toggle_user From 6b3a6fa967ade39bf01b42798013fb14e5dab155 Mon Sep 17 00:00:00 2001 From: siddhantbajaj Date: Thu, 29 Jun 2017 20:58:22 +0530 Subject: [PATCH 140/185] Fixed ticket_sold method of ticket model --- app/models/ticket.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/ticket.rb b/app/models/ticket.rb index 7bac9462..ce527472 100644 --- a/app/models/ticket.rb +++ b/app/models/ticket.rb @@ -56,7 +56,7 @@ class Ticket < ActiveRecord::Base end def tickets_sold - ticket_purchases.sum(:quantity) + ticket_purchases.paid.sum(:quantity) end def tickets_turnover From 7d472f2ad5670fd754eb44d56358a8cd50c75e94 Mon Sep 17 00:00:00 2001 From: shlok007 Date: Tue, 4 Jul 2017 05:55:41 +0530 Subject: [PATCH 141/185] fix failing tests --- app/views/admin/registration_periods/show.html.haml | 2 +- app/views/admin/splashpages/show.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/admin/registration_periods/show.html.haml b/app/views/admin/registration_periods/show.html.haml index 9ef02e37..057a7a37 100644 --- a/app/views/admin/registration_periods/show.html.haml +++ b/app/views/admin/registration_periods/show.html.haml @@ -25,5 +25,5 @@ = link_to 'Delete', admin_conference_registration_period_path, method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-danger' - else - - if can? :create, @conference + - if can? :create, @conference.build_registration_period = link_to 'New Registration Period', new_admin_conference_registration_period_path, class: 'btn btn-primary' diff --git a/app/views/admin/splashpages/show.html.haml b/app/views/admin/splashpages/show.html.haml index 0c6be8a8..b4e5f24c 100644 --- a/app/views/admin/splashpages/show.html.haml +++ b/app/views/admin/splashpages/show.html.haml @@ -90,5 +90,5 @@ - else .row .col-md-12.text-right - - if can? :create, @conference + - if can? :create, @conference.build_splashpage = link_to 'Create Splashpage', new_admin_conference_splashpage_path, class: 'btn btn-primary' From 95fbd10153035043318fcc08b92988c817fc3301 Mon Sep 17 00:00:00 2001 From: AEtherC0r3 Date: Thu, 29 Jun 2017 23:39:56 +0300 Subject: [PATCH 142/185] Friendly urls for tracks Don't use tracks ids in urls Add short_name to tracks and use that in urls as the identifier --- app/controllers/admin/tracks_controller.rb | 4 +- app/models/track.rb | 6 +++ app/views/admin/tracks/_form.html.haml | 3 +- app/views/admin/tracks/index.html.haml | 9 +++-- .../versions/_object_desc_and_link.html.haml | 2 +- ...20170629162450_add_short_name_to_tracks.rb | 39 +++++++++++++++++++ db/schema.rb | 3 +- spec/factories/tracks.rb | 1 + spec/features/tracks_spec.rb | 2 + 9 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 db/migrate/20170629162450_add_short_name_to_tracks.rb diff --git a/app/controllers/admin/tracks_controller.rb b/app/controllers/admin/tracks_controller.rb index 2df7db67..4fc9d9c7 100644 --- a/app/controllers/admin/tracks_controller.rb +++ b/app/controllers/admin/tracks_controller.rb @@ -2,7 +2,7 @@ module Admin class TracksController < Admin::BaseController load_and_authorize_resource :conference, find_by: :short_title load_and_authorize_resource :program, through: :conference, singleton: true - load_and_authorize_resource through: :program + load_and_authorize_resource through: :program, find_by: :short_name def index; end @@ -53,7 +53,7 @@ module Admin private def track_params - params.require(:track).permit(:name, :description, :color) + params.require(:track).permit(:name, :description, :color, :short_name) end end end diff --git a/app/models/track.rb b/app/models/track.rb index 1d94f7d5..d3502bb0 100644 --- a/app/models/track.rb +++ b/app/models/track.rb @@ -7,6 +7,12 @@ class Track < ActiveRecord::Base before_create :generate_guid validates :name, presence: true validates :color, format: /\A#[0-9A-F]{6}\z/ + validates :short_name, + presence: true, + format: /\A[a-zA-Z0-9_-]*\z/, + uniqueness: { + scope: :program + } before_validation :capitalize_color diff --git a/app/views/admin/tracks/_form.html.haml b/app/views/admin/tracks/_form.html.haml index 579d263d..c3c7cf26 100644 --- a/app/views/admin/tracks/_form.html.haml +++ b/app/views/admin/tracks/_form.html.haml @@ -8,8 +8,9 @@ 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))) do |f| + = 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| = 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' } }, hint: markdown_hint = 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 f2de8a38..f9ed9036 100644 --- a/app/views/admin/tracks/index.html.haml +++ b/app/views/admin/tracks/index.html.haml @@ -9,6 +9,7 @@ %table.table.table-hover#tracks %thead %th Name + %th Short name %th Description %th Color %th Actions @@ -16,8 +17,10 @@ - @tracks.each do |track| %tr %td - = link_to(admin_conference_program_track_path(@conference.short_title, track)) do + = link_to(admin_conference_program_track_path(@conference.short_title, track.short_name)) do = track.name + %td + = track.short_name %td %p = truncate(track.description) @@ -26,9 +29,9 @@ = track.color %td .btn-group{role: "group"} - = link_to 'Edit', edit_admin_conference_program_track_path(@conference.short_title, track.id), + = link_to 'Edit', edit_admin_conference_program_track_path(@conference.short_title, track.short_name), method: :get, class: 'btn btn-primary' - = link_to 'Delete', admin_conference_program_track_path(@conference.short_title, track.id), + = 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" } .row diff --git a/app/views/admin/versions/_object_desc_and_link.html.haml b/app/views/admin/versions/_object_desc_and_link.html.haml index 14b1f2fc..83542ef1 100644 --- a/app/views/admin/versions/_object_desc_and_link.html.haml +++ b/app/views/admin/versions/_object_desc_and_link.html.haml @@ -94,7 +94,7 @@ = 'track' - track = current_or_last_object_state(version.item_type, version.item_id) = link_if_alive version, track.name, - admin_conference_program_track_path(conference_id: Conference.find(version.conference_id).short_title, id: version.item_id) + admin_conference_program_track_path(conference_id: Conference.find(version.conference_id).short_title, id: track.try(:short_name)) - when 'EventType' = 'event type' diff --git a/db/migrate/20170629162450_add_short_name_to_tracks.rb b/db/migrate/20170629162450_add_short_name_to_tracks.rb new file mode 100644 index 00000000..cbc6b431 --- /dev/null +++ b/db/migrate/20170629162450_add_short_name_to_tracks.rb @@ -0,0 +1,39 @@ +class AddShortNameToTracks < ActiveRecord::Migration + class TmpProgram < ActiveRecord::Base + self.table_name = 'programs' + end + + class TmpTrack < ActiveRecord::Base + self.table_name = 'tracks' + end + + def change + add_column :tracks, :short_name, :string + + TmpTrack.reset_column_information + + TmpProgram.find_each do |program| + # Keeps count of how many times we've encountered a short_name + track_name_counter = {} + + TmpTrack.where(program_id: program.id).find_each do |track| + # Replace spaces with undercores and remove the non alphanumeric characters that aren't underscores or dashes + short_name = track.name.tr(' ', '_').tr('^a-zA-Z0-9_-', '') + + # If we've seen that short_name before then add the counter in the end to avoid collisions + if track_name_counter[short_name] + track_name_counter[short_name] += 1 + short_name += "_#{track_name_counter[short_name]}" + else + # Initialize the counter + track_name_counter[short_name] = 0 unless track_name_counter[short_name] + end + + track.short_name = short_name + track.save! + end + end + + change_column_null :tracks, :short_name, false + end +end diff --git a/db/schema.rb b/db/schema.rb index 348f6170..2e2fb088 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170603095900) do +ActiveRecord::Schema.define(version: 20170629162450) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -485,6 +485,7 @@ ActiveRecord::Schema.define(version: 20170603095900) do t.datetime "created_at" t.datetime "updated_at" t.integer "program_id" + t.string "short_name", null: false end create_table "users", force: :cascade do |t| diff --git a/spec/factories/tracks.rb b/spec/factories/tracks.rb index 1b7f8083..4334cb4c 100644 --- a/spec/factories/tracks.rb +++ b/spec/factories/tracks.rb @@ -3,6 +3,7 @@ FactoryGirl.define do name { Faker::Commerce.department(2, true) } description { Faker::Lorem.sentence } color { Faker::Color.hex_color } + short_name { SecureRandom.urlsafe_base64(5) } program end end diff --git a/spec/features/tracks_spec.rb b/spec/features/tracks_spec.rb index d1972075..3538a6d7 100644 --- a/spec/features/tracks_spec.rb +++ b/spec/features/tracks_spec.rb @@ -14,6 +14,7 @@ feature Track do click_link 'New Track' fill_in 'track_name', with: 'Distribution' + fill_in 'track_short_name', with: 'Distribution' page.find('#track_color').set('#B94D4D') fill_in 'track_description', with: 'Events about our Linux distribution' click_button 'Create Track' @@ -50,6 +51,7 @@ feature Track do click_link 'Edit' fill_in 'track_name', with: 'Distribution' + fill_in 'track_short_name', with: 'Distribution' page.find('#track_color').set('#B94D4D') fill_in 'track_description', with: 'Events about our Linux distribution' click_button 'Update Track' From b9a540f4e2bba612f44f848589a3f1c0c1dd7ac7 Mon Sep 17 00:00:00 2001 From: siddhantbajaj Date: Tue, 13 Jun 2017 07:20:43 +0530 Subject: [PATCH 143/185] Sample prototype for ticket pdf Added verticl layout of ticket pdf without QR code. --- Gemfile | 2 + Gemfile.lock | 8 +++ app/controllers/physical_ticket_controller.rb | 5 +- app/uploaders/picture_uploader.rb | 4 ++ app/views/physical_ticket/show.pdf.prawn | 62 +++++++++++++++++++ 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 app/views/physical_ticket/show.pdf.prawn diff --git a/Gemfile b/Gemfile index 245080c3..e6245e78 100644 --- a/Gemfile +++ b/Gemfile @@ -128,6 +128,8 @@ gem 'country_select' # as PDF generator gem 'prawn_rails' +gem 'rqrcode' +gem 'prawn-qrcode', '~> 0.2.2.1' # to render XLS spreadsheets gem 'axlsx', git: 'https://github.com/randym/axlsx.git' diff --git a/Gemfile.lock b/Gemfile.lock index 74e8ce84..a493c113 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -117,6 +117,7 @@ GEM chart-js-rails (0.0.6) railties (> 3.1) chronic (0.10.2) + chunky_png (1.3.8) cliver (0.3.2) cloudinary (1.1.6) aws_cf_signer @@ -343,6 +344,9 @@ GEM prawn (1.0.0) pdf-core (~> 0.2.2) ttfunk (~> 1.1.1) + prawn-qrcode (0.2.2.1) + prawn (>= 0.11.1) + rqrcode (>= 0.4.1) prawn_rails (0.0.11) prawn (>= 0.11.1) railties (>= 3.0.0) @@ -429,6 +433,8 @@ GEM mime-types (>= 1.16, < 3.0) netrc (~> 0.7) 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) @@ -611,6 +617,7 @@ DEPENDENCIES phantomjs piwik_analytics (~> 1.0.1) poltergeist + prawn-qrcode (~> 0.2.2.1) prawn_rails rails (~> 4.2) rails-assets-bootstrap-markdown! @@ -631,6 +638,7 @@ DEPENDENCIES redcarpet responders (~> 2.0) rolify + rqrcode rspec-activemodel-mocks rspec-rails rubocop (~> 0.48.1) diff --git a/app/controllers/physical_ticket_controller.rb b/app/controllers/physical_ticket_controller.rb index 2354f279..20d335d7 100644 --- a/app/controllers/physical_ticket_controller.rb +++ b/app/controllers/physical_ticket_controller.rb @@ -8,5 +8,8 @@ class PhysicalTicketController < ApplicationController @physical_tickets = current_user.physical_tickets.by_conference(@conference) end - def show; end + def show + @file_name = "ticket_for_#{@conference.short_title}" + @user = @physical_ticket.user + end end diff --git a/app/uploaders/picture_uploader.rb b/app/uploaders/picture_uploader.rb index af3c2227..b17f0d76 100644 --- a/app/uploaders/picture_uploader.rb +++ b/app/uploaders/picture_uploader.rb @@ -52,6 +52,10 @@ class PictureUploader < CarrierWave::Uploader::Base "system/#{object_class_name}/#{mounted_as}/#{model.id}" end + def image + @image ||= MiniMagick::Image.open(file.file) + end + # Create different versions of your uploaded files: version :large do process resize_to_fit: [300, 300] diff --git a/app/views/physical_ticket/show.pdf.prawn b/app/views/physical_ticket/show.pdf.prawn new file mode 100644 index 00000000..90f11fd5 --- /dev/null +++ b/app/views/physical_ticket/show.pdf.prawn @@ -0,0 +1,62 @@ +prawn_document(filename: @file_name, page_layout: :portrait, :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 72537ba2a8e590877e12edae767efcc0f2b147f0 Mon Sep 17 00:00:00 2001 From: siddhantbajaj Date: Thu, 29 Jun 2017 19:25:10 +0530 Subject: [PATCH 144/185] Fixed user abilities in Physical Ticket --- app/models/ability.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/ability.rb b/app/models/ability.rb index 5001278a..40965719 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -88,7 +88,7 @@ class Ability can :index, Ticket can :manage, TicketPurchase, user_id: user.id can [:new, :create], Payment, user_id: user.id - can [:index, :show], PhysicalTicket, user_id: user.id + can [:index, :show], PhysicalTicket, user: user can [:create, :destroy], Subscription, user_id: user.id From 2cc97a92f5b42877946c4a29f3df87cd4da84a5b Mon Sep 17 00:00:00 2001 From: L11 Date: Sat, 1 Jul 2017 13:39:22 +0530 Subject: [PATCH 145/185] Remove duplicated label - target/form --- app/views/admin/targets/_form.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/targets/_form.html.haml b/app/views/admin/targets/_form.html.haml index b0462249..1e81989b 100644 --- a/app/views/admin/targets/_form.html.haml +++ b/app/views/admin/targets/_form.html.haml @@ -10,6 +10,6 @@ = semantic_form_for(@target, url: (@target.new_record? ? admin_conference_targets_path : admin_conference_target_path(@conference.short_title, @target))) do |f| = f.input :due_date, as: :string, input_html: { class: 'target-due-date-datepicker'}, label: 'Until when do you want to have ' = f.input :target_count, label: 'this amount of ' - = f.input :unit, as: :select, label: 'Unit', class: 'form-control', collection: Target.units.values, include_blank: false, label: 'units ' + = f.input :unit, as: :select, label: 'Unit', class: 'form-control', collection: Target.units.values, include_blank: false %p.text-right = f.action :submit, as: :button, button_html: { class: 'btn btn-primary' } From a327d2cbd2e41c728f001f5204eabde1e8a26276 Mon Sep 17 00:00:00 2001 From: siddhantbajaj Date: Mon, 26 Jun 2017 06:07:52 +0530 Subject: [PATCH 146/185] Ticket Purchase Index Page List all the unpaid ticket purchases of the user for that conference and allow user to pay for them. --- app/controllers/physical_ticket_controller.rb | 1 + .../ticket_purchases_controller.rb | 4 +++ app/views/physical_ticket/index.html.haml | 7 +++++ app/views/ticket_purchases/index.html.haml | 30 +++++++++++++++++++ config/routes.rb | 2 +- 5 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 app/views/ticket_purchases/index.html.haml diff --git a/app/controllers/physical_ticket_controller.rb b/app/controllers/physical_ticket_controller.rb index 2354f279..59c248d1 100644 --- a/app/controllers/physical_ticket_controller.rb +++ b/app/controllers/physical_ticket_controller.rb @@ -6,6 +6,7 @@ class PhysicalTicketController < ApplicationController def index @physical_tickets = current_user.physical_tickets.by_conference(@conference) + @unpaid_ticket_purchases = current_user.ticket_purchases.by_conference(@conference).unpaid end def show; end diff --git a/app/controllers/ticket_purchases_controller.rb b/app/controllers/ticket_purchases_controller.rb index 3945e154..792122e2 100644 --- a/app/controllers/ticket_purchases_controller.rb +++ b/app/controllers/ticket_purchases_controller.rb @@ -23,6 +23,10 @@ class TicketPurchasesController < ApplicationController end end + def index + @unpaid_ticket_purchases = current_user.ticket_purchases.by_conference(@conference).unpaid + end + private def ticket_purchase_params diff --git a/app/views/physical_ticket/index.html.haml b/app/views/physical_ticket/index.html.haml index ce741c39..b077400b 100644 --- a/app/views/physical_ticket/index.html.haml +++ b/app/views/physical_ticket/index.html.haml @@ -33,3 +33,10 @@ class: 'button btn btn-default btn-info' - else %h5 No Tickets found! + .row + .col-md-12 + - if @unpaid_ticket_purchases.any? + .h3 + You have unpaid tickets! + %small + = link_to "Pay them here", conference_ticket_purchases_path diff --git a/app/views/ticket_purchases/index.html.haml b/app/views/ticket_purchases/index.html.haml new file mode 100644 index 00000000..c9255c37 --- /dev/null +++ b/app/views/ticket_purchases/index.html.haml @@ -0,0 +1,30 @@ +.container + .row + .col-md-12.page-header + %h2 + Ticket Purchases + .text-muted + Your unpaid ticket purchases for the conference + + .col-md-12 + - if @unpaid_ticket_purchases.present? + %table.table.table-bordered.table-striped.table-hover#roles + %thead + %th ID + %th Type + %th Quantity + %th Date + %th Actions + %tbody + - @unpaid_ticket_purchases.each do |ticket_purchase| + %tr + %td= ticket_purchase.id + %td= ticket_purchase.ticket.title + %td= ticket_purchase.quantity + %td= ticket_purchase.created_at.strftime('%B %d, %Y') + %td + .btn-group + = link_to 'Pay', new_conference_payment_path, + class: 'btn btn-primary' + - else + %h5 You don't have any unpaid ticket purchase! diff --git a/config/routes.rb b/config/routes.rb index ae67a820..db88613f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -125,7 +125,7 @@ Osem::Application.routes.draw do # TODO: change conference_registrations to singular resource resource :conference_registration, path: 'register' resources :tickets, only: [:index] - resources :ticket_purchases, only: [:create, :destroy] + resources :ticket_purchases, only: [:create, :destroy, :index] resources :payments, only: [:index, :new, :create] resources :physical_ticket, only: [:index, :show] resource :subscriptions, only: [:create, :destroy] From dd52a9b2ab0b78708a7b23fba061a0fc0f730b38 Mon Sep 17 00:00:00 2001 From: siddhantbajaj Date: Fri, 30 Jun 2017 05:26:21 +0530 Subject: [PATCH 147/185] Make ticket layout configurable Added option for conference organizer to switch between ticket layouts (horizontal or vertical). Added test for the same. --- .../admin/conferences_controller.rb | 2 +- app/controllers/physical_ticket_controller.rb | 1 + app/models/conference.rb | 3 +++ app/views/admin/conferences/edit.html.haml | 1 + app/views/physical_ticket/show.pdf.prawn | 2 +- ...232817_add_ticket_layout_to_conferences.rb | 5 +++++ db/schema.rb | 1 + .../physical_ticket_controller_spec.rb | 20 +++++++++++++++++++ spec/factories/conferences.rb | 1 + spec/models/conference_spec.rb | 4 ++++ 10 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20170629232817_add_ticket_layout_to_conferences.rb create mode 100644 spec/controllers/physical_ticket_controller_spec.rb diff --git a/app/controllers/admin/conferences_controller.rb b/app/controllers/admin/conferences_controller.rb index f8c9ea19..6716a253 100644 --- a/app/controllers/admin/conferences_controller.rb +++ b/app/controllers/admin/conferences_controller.rb @@ -211,7 +211,7 @@ module Admin :vpositions_attributes, :use_volunteers, :color, :sponsorship_levels_attributes, :sponsors_attributes, :targets, :targets_attributes, - :campaigns, :campaigns_attributes, :registration_limit, :organization_id) + :campaigns, :campaigns_attributes, :registration_limit, :organization_id, :ticket_layout) end end end diff --git a/app/controllers/physical_ticket_controller.rb b/app/controllers/physical_ticket_controller.rb index 09b38ff2..8617e0d9 100644 --- a/app/controllers/physical_ticket_controller.rb +++ b/app/controllers/physical_ticket_controller.rb @@ -12,5 +12,6 @@ class PhysicalTicketController < ApplicationController def show @file_name = "ticket_for_#{@conference.short_title}" @user = @physical_ticket.user + @ticket_layout = @conference.ticket_layout.to_sym end end diff --git a/app/models/conference.rb b/app/models/conference.rb index 11fab753..cf94b334 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -57,6 +57,7 @@ class Conference < ActiveRecord::Base :end_date, :start_hour, :end_hour, + :ticket_layout, :organization, presence: true validates :short_title, uniqueness: true @@ -73,6 +74,8 @@ class Conference < ActiveRecord::Base after_create :create_free_ticket after_update :delete_event_schedules + enum ticket_layout: [:portrait, :landscape] + ## # Checks if the user is registered to the conference # diff --git a/app/views/admin/conferences/edit.html.haml b/app/views/admin/conferences/edit.html.haml index 5aa717ea..2d5df126 100644 --- a/app/views/admin/conferences/edit.html.haml +++ b/app/views/admin/conferences/edit.html.haml @@ -17,6 +17,7 @@ = image_tag @conference.picture.thumb.url = f.input :picture, label: false, hint: 'This will be displayed on the front page.' = f.hidden_field :picture_cache + = f.input :ticket_layout, as: :select, collection: Conference.ticket_layouts.keys, hint: "Layout type for tickets of the conference." = f.inputs name: 'Scheduling' do = f.input :timezone, as: :time_zone, hint: 'The conference time zone' = f.input :start_date, as: :string, input_html: { id: 'conference-start-datepicker', readonly: 'readonly' } diff --git a/app/views/physical_ticket/show.pdf.prawn b/app/views/physical_ticket/show.pdf.prawn index 90f11fd5..92206baf 100644 --- a/app/views/physical_ticket/show.pdf.prawn +++ b/app/views/physical_ticket/show.pdf.prawn @@ -1,4 +1,4 @@ -prawn_document(filename: @file_name, page_layout: :portrait, :page_size =>'A4' ) do |pdf| +prawn_document(filename: @file_name, page_layout: @ticket_layout, :page_size =>'A4' ) do |pdf| # Vertical Layout top = pdf.bounds.top bottom = pdf.bounds.bottom diff --git a/db/migrate/20170629232817_add_ticket_layout_to_conferences.rb b/db/migrate/20170629232817_add_ticket_layout_to_conferences.rb new file mode 100644 index 00000000..c07f85c3 --- /dev/null +++ b/db/migrate/20170629232817_add_ticket_layout_to_conferences.rb @@ -0,0 +1,5 @@ +class AddTicketLayoutToConferences < ActiveRecord::Migration + def change + add_column :conferences, :ticket_layout, :integer, default: 0 + end +end diff --git a/db/schema.rb b/db/schema.rb index 2e2fb088..4a9cc724 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -105,6 +105,7 @@ ActiveRecord::Schema.define(version: 20170629162450) do t.integer "start_hour", default: 9 t.integer "end_hour", default: 20 t.integer "organization_id" + t.integer "ticket_layout", default: 0 end add_index "conferences", ["organization_id"], name: "index_conferences_on_organization_id" diff --git a/spec/controllers/physical_ticket_controller_spec.rb b/spec/controllers/physical_ticket_controller_spec.rb new file mode 100644 index 00000000..7a430479 --- /dev/null +++ b/spec/controllers/physical_ticket_controller_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +describe PhysicalTicketController do + let(:conference) { create(:conference) } + let(:user) { create(:user) } + let(:paid_ticket_purchase) { create(:ticket_purchase, conference: conference, user: user) } + let(:physical_ticket) { create(:physical_ticket, ticket_purchase: paid_ticket_purchase) } + + describe 'GET #show' do + before :each do + sign_in user + get :show, id: physical_ticket.id, conference_id: conference.short_title + end + + it 'assigns ticket_layout' do + ticket_layout = conference.ticket_layout.to_sym + expect(assigns(:ticket_layout)).to eq ticket_layout + end + end +end diff --git a/spec/factories/conferences.rb b/spec/factories/conferences.rb index e1ef7d84..1e4d8551 100644 --- a/spec/factories/conferences.rb +++ b/spec/factories/conferences.rb @@ -10,6 +10,7 @@ FactoryGirl.define do start_hour 9 end_hour 20 registration_limit 0 + ticket_layout 'portrait' description { Faker::Hipster.paragraph } organization after(:create) do |conference| diff --git a/spec/models/conference_spec.rb b/spec/models/conference_spec.rb index d6e4f485..eaef9293 100755 --- a/spec/models/conference_spec.rb +++ b/spec/models/conference_spec.rb @@ -1573,6 +1573,10 @@ describe Conference do should validate_presence_of(:end_hour) end + it 'is not valid without a ticket_layout' do + should validate_presence_of(:ticket_layout) + end + it 'is not valid with a duplicate short title' do should validate_uniqueness_of(:short_title) end From 4c957a8b17d9822291f5fe854dd9a2f15e147988 Mon Sep 17 00:00:00 2001 From: siddhantbajaj Date: Fri, 7 Jul 2017 02:35:40 +0530 Subject: [PATCH 148/185] Updated Paper Trail --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index a493c113..89d52471 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -323,7 +323,7 @@ GEM rack-openid (~> 1.3.1) open4 (1.3.4) orm_adapter (0.5.0) - paper_trail (5.0.1) + paper_trail (5.2.1) activerecord (>= 3.0, < 6.0) activesupport (>= 3.0, < 6.0) request_store (~> 1.1) From 1ba797bead3bd3c9daaad7fd1f69d9601428d38a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A1n=20Schmidt?= Date: Sat, 8 Jul 2017 18:45:38 +0200 Subject: [PATCH 149/185] Fix schema.rb In #1570, db/schema.rb got broken, as the version was not updated. --- db/schema.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index 4a9cc724..6608495b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170629162450) do +ActiveRecord::Schema.define(version: 20170629232817) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" From 9c6286182ef8c9b33f6a170e2b2cf989eb71f4ef Mon Sep 17 00:00:00 2001 From: shlok007 Date: Thu, 29 Dec 2016 03:17:33 -0500 Subject: [PATCH 150/185] caching comment counts --- app/models/comment.rb | 2 +- app/views/admin/events/index.html.haml | 2 +- ...1229080315_add_comments_count_to_events.rb | 10 ++++++++ db/schema.rb | 1 + spec/models/event_spec.rb | 23 +++++++++++++++++++ 5 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20161229080315_add_comments_count_to_events.rb diff --git a/app/models/comment.rb b/app/models/comment.rb index 947b2f54..4bb90719 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -8,7 +8,7 @@ class Comment < ActiveRecord::Base # want user to vote on the quality of comments. #acts_as_votable - belongs_to :commentable, polymorphic: true + belongs_to :commentable, counter_cache: true, polymorphic: true # NOTE: Comments belong to a user belongs_to :user diff --git a/app/views/admin/events/index.html.haml b/app/views/admin/events/index.html.haml index 0e204c87..50d7acd5 100644 --- a/app/views/admin/events/index.html.haml +++ b/app/views/admin/events/index.html.haml @@ -184,4 +184,4 @@ %ul.dropdown-menu{ role: 'menu' } = render 'change_state_dropdown', event: event %td.text-center - = link_to "#{event.comment_threads.count}", admin_conference_program_event_path(@conference.short_title, event), anchor: 'comments-div' + = link_to "#{event.comments_count}", admin_conference_program_event_path(@conference.short_title, event), anchor: 'comments-div' diff --git a/db/migrate/20161229080315_add_comments_count_to_events.rb b/db/migrate/20161229080315_add_comments_count_to_events.rb new file mode 100644 index 00000000..e1d6ebec --- /dev/null +++ b/db/migrate/20161229080315_add_comments_count_to_events.rb @@ -0,0 +1,10 @@ +class AddCommentsCountToEvents < ActiveRecord::Migration + def change + add_column :events, :comments_count, :integer, default: 0, null: false + + Event.find_each do |event| + comments_count = event.comment_threads.count + event.update_attribute(:comments_count, comments_count) unless comments_count.zero? + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 6608495b..9f0f9ff5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -242,6 +242,7 @@ ActiveRecord::Schema.define(version: 20170629232817) do t.boolean "is_highlight", default: false t.integer "program_id" t.integer "max_attendees" + t.integer "comments_count", default: 0, null: false end create_table "events_registrations", force: :cascade do |t| diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index e1c2297c..b723d151 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -98,6 +98,29 @@ describe Event do end end + describe '#comments_count' do + context 'has a valid counter cache' do + before do + create(:comment, commentable: event) + end + + it 'successfully increments comments_count' do + expected = expect do + create(:comment, commentable: event) + end + expected.to change { event.comments_count }.by(1) + end + + it 'successfully decrements comments_count' do + expected = expect do + event.comment_threads.last.destroy + event.reload + end + expected.to change { event.comments_count }.by(-1) + end + end + end + describe 'scope ' do context 'confirmed' do it 'returns only confirmed events' do From 518ecc3d4ef53a95a8ac52e66f0e5f9879f0579f Mon Sep 17 00:00:00 2001 From: shlok007 Date: Sun, 9 Jul 2017 01:29:15 +0530 Subject: [PATCH 151/185] rebuild schema.rb for sqlite3 --- db/schema.rb | 51 ++++++++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 9f0f9ff5..7a640259 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -13,20 +13,17 @@ ActiveRecord::Schema.define(version: 20170629232817) do - # These are extensions that must be enabled in order to support this database - enable_extension "plpgsql" - create_table "ahoy_events", force: :cascade do |t| - t.integer "visit_id" + t.uuid "visit_id", limit: 16 t.integer "user_id" t.string "name" t.text "properties" t.datetime "time" end - add_index "ahoy_events", ["time"], name: "index_ahoy_events_on_time", using: :btree - add_index "ahoy_events", ["user_id"], name: "index_ahoy_events_on_user_id", using: :btree - add_index "ahoy_events", ["visit_id"], name: "index_ahoy_events_on_visit_id", using: :btree + add_index "ahoy_events", ["time"], name: "index_ahoy_events_on_time" + add_index "ahoy_events", ["user_id"], name: "index_ahoy_events_on_user_id" + add_index "ahoy_events", ["visit_id"], name: "index_ahoy_events_on_visit_id" create_table "answers", force: :cascade do |t| t.string "title" @@ -69,9 +66,9 @@ ActiveRecord::Schema.define(version: 20170629232817) do t.integer "rgt" end - add_index "comments", ["commentable_id"], name: "index_comments_on_commentable_id", using: :btree - add_index "comments", ["commentable_type"], name: "index_comments_on_commentable_type", using: :btree - add_index "comments", ["user_id"], name: "index_comments_on_user_id", using: :btree + add_index "comments", ["commentable_id"], name: "index_comments_on_commentable_id" + add_index "comments", ["commentable_type"], name: "index_comments_on_commentable_type" + add_index "comments", ["user_id"], name: "index_comments_on_user_id" create_table "commercials", force: :cascade do |t| t.string "commercial_id" @@ -142,7 +139,7 @@ ActiveRecord::Schema.define(version: 20170629232817) do t.datetime "updated_at" end - add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority", using: :btree + add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority" create_table "difficulty_levels", force: :cascade do |t| t.string "title" @@ -195,10 +192,10 @@ ActiveRecord::Schema.define(version: 20170629232817) do t.datetime "updated_at", null: false end - add_index "event_schedules", ["event_id", "schedule_id"], name: "index_event_schedules_on_event_id_and_schedule_id", unique: true, using: :btree - add_index "event_schedules", ["event_id"], name: "index_event_schedules_on_event_id", using: :btree - add_index "event_schedules", ["room_id"], name: "index_event_schedules_on_room_id", using: :btree - add_index "event_schedules", ["schedule_id"], name: "index_event_schedules_on_schedule_id", using: :btree + add_index "event_schedules", ["event_id", "schedule_id"], name: "index_event_schedules_on_event_id_and_schedule_id", unique: true + add_index "event_schedules", ["event_id"], name: "index_event_schedules_on_event_id" + add_index "event_schedules", ["room_id"], name: "index_event_schedules_on_room_id" + add_index "event_schedules", ["schedule_id"], name: "index_event_schedules_on_schedule_id" create_table "event_types", force: :cascade do |t| t.string "title", null: false @@ -313,7 +310,7 @@ ActiveRecord::Schema.define(version: 20170629232817) do t.integer "schedule_interval", default: 15, null: false end - add_index "programs", ["selected_schedule_id"], name: "index_programs_on_selected_schedule_id", using: :btree + add_index "programs", ["selected_schedule_id"], name: "index_programs_on_selected_schedule_id" create_table "qanswers", force: :cascade do |t| t.integer "question_id" @@ -385,8 +382,8 @@ ActiveRecord::Schema.define(version: 20170629232817) do t.string "resource_type" end - add_index "roles", ["name", "resource_type", "resource_id"], name: "index_roles_on_name_and_resource_type_and_resource_id", using: :btree - add_index "roles", ["name"], name: "index_roles_on_name", using: :btree + add_index "roles", ["name", "resource_type", "resource_id"], name: "index_roles_on_name_and_resource_type_and_resource_id" + add_index "roles", ["name"], name: "index_roles_on_name" create_table "rooms", force: :cascade do |t| t.string "guid", null: false @@ -401,7 +398,7 @@ ActiveRecord::Schema.define(version: 20170629232817) do t.datetime "updated_at", null: false end - add_index "schedules", ["program_id"], name: "index_schedules_on_program_id", using: :btree + add_index "schedules", ["program_id"], name: "index_schedules_on_program_id" create_table "splashpages", force: :cascade do |t| t.integer "conference_id" @@ -525,17 +522,17 @@ ActiveRecord::Schema.define(version: 20170629232817) do t.boolean "is_disabled", default: false end - add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree - add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree - add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree - add_index "users", ["username"], name: "index_users_on_username", unique: true, using: :btree + add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true + add_index "users", ["email"], name: "index_users_on_email", unique: true + add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true + add_index "users", ["username"], name: "index_users_on_username", unique: true create_table "users_roles", force: :cascade do |t| t.integer "role_id" t.integer "user_id" end - add_index "users_roles", ["user_id", "role_id"], name: "index_users_roles_on_user_id_and_role_id", using: :btree + add_index "users_roles", ["user_id", "role_id"], name: "index_users_roles_on_user_id_and_role_id" create_table "vchoices", force: :cascade do |t| t.integer "vday_id" @@ -579,10 +576,10 @@ ActiveRecord::Schema.define(version: 20170629232817) do t.integer "conference_id" end - add_index "versions", ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id", using: :btree + add_index "versions", ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id" create_table "visits", force: :cascade do |t| - t.uuid "visitor_id" + t.uuid "visitor_id", limit: 16 t.string "ip" t.text "user_agent" t.text "referrer" @@ -604,7 +601,7 @@ ActiveRecord::Schema.define(version: 20170629232817) do t.datetime "started_at" end - add_index "visits", ["user_id"], name: "index_visits_on_user_id", using: :btree + add_index "visits", ["user_id"], name: "index_visits_on_user_id" create_table "votes", force: :cascade do |t| t.integer "event_id" From b33e9ed28ee444f45e5bac2f9e1761fe896784ea Mon Sep 17 00:00:00 2001 From: shlok007 Date: Wed, 4 Jan 2017 22:27:46 -0500 Subject: [PATCH 152/185] fix revision count and drop observers --- Gemfile | 3 --- Gemfile.lock | 3 --- app/models/concerns/revision_count.rb | 11 ++++++++ app/models/conference.rb | 10 +++++++ app/models/event.rb | 5 ++++ app/models/revision_observer.rb | 26 ------------------ app/models/room.rb | 5 ++++ app/models/track.rb | 5 ++++ config/application.rb | 1 - ...1_add_default_to_revision_in_conference.rb | 5 ++++ db/schema.rb | 2 +- spec/models/conference_spec.rb | 27 +++++++++++++++++++ 12 files changed, 69 insertions(+), 34 deletions(-) create mode 100644 app/models/concerns/revision_count.rb delete mode 100644 app/models/revision_observer.rb create mode 100644 db/migrate/20170108053041_add_default_to_revision_in_conference.rb diff --git a/Gemfile b/Gemfile index e6245e78..1af89f34 100644 --- a/Gemfile +++ b/Gemfile @@ -22,9 +22,6 @@ gem 'responders', '~> 2.0' gem 'mysql2' # gem 'pg' -# for observing records -gem 'rails-observers' - # for tracking data changes gem 'paper_trail' diff --git a/Gemfile.lock b/Gemfile.lock index 89d52471..9ea214c2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -399,8 +399,6 @@ GEM rails-i18n (4.0.8) i18n (~> 0.7) railties (~> 4.0) - rails-observers (0.1.2) - activemodel (~> 4.0) rails_12factor (0.0.3) rails_serve_static_assets rails_stdout_logging @@ -632,7 +630,6 @@ DEPENDENCIES rails-assets-trianglify! rails-assets-waypoints! rails-i18n (~> 4.0.0) - rails-observers rails_12factor rdoc-generator-fivefish redcarpet diff --git a/app/models/concerns/revision_count.rb b/app/models/concerns/revision_count.rb new file mode 100644 index 00000000..71789f34 --- /dev/null +++ b/app/models/concerns/revision_count.rb @@ -0,0 +1,11 @@ +module RevisionCount + extend ActiveSupport::Concern + + included do + after_update :increment_revision + end + + def increment_revision + conference.update_column(:revision, conference.revision + 1) + end +end diff --git a/app/models/conference.rb b/app/models/conference.rb index cf94b334..69571dc9 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -1,4 +1,5 @@ class Conference < ActiveRecord::Base + include RevisionCount require 'uri' serialize :events_per_week, Hash # Needed to call 'Conference.with_role' in /models/ability.rb @@ -734,6 +735,15 @@ class Conference < ActiveRecord::Base (start_hour..(end_hour - 1)).cover?(current_hour) ? current_hour - start_hour : 0 end + ## + # Return the current conference object to be used in RevisionCount + # + # ====Returns + # * +ActiveRecord+ + def conference + self + end + private # Returns a different html colour for every i and consecutive colors are diff --git a/app/models/event.rb b/app/models/event.rb index f8f9c2d8..8436aac9 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -1,5 +1,6 @@ class Event < ActiveRecord::Base include ActiveRecord::Transitions + include RevisionCount has_paper_trail on: [:create, :update], ignore: [:updated_at, :guid, :week], meta: { conference_id: :conference_id } acts_as_commentable @@ -251,6 +252,10 @@ class Event < ActiveRecord::Base event_schedules.find_by(schedule_id: program.selected_schedule_id).try(:start_time) end + def conference + program.conference + end + private ## diff --git a/app/models/revision_observer.rb b/app/models/revision_observer.rb deleted file mode 100644 index 4d2784f4..00000000 --- a/app/models/revision_observer.rb +++ /dev/null @@ -1,26 +0,0 @@ -# -# suseconferenceclient relies on a 'revision' attribute for caching and -# doing some calculations. -# -# It should be incremented after any change in the conference or in any -# associated models -# -# This observer updates the revision column in a non-intrusive way, -# preventing validations, callbacks or exceptions to be triggered -# -# Relying on paper_trail could also be an option, but a 'revision' column -# in table 'conferences' looks like a more simple and straightforward solution -# -class RevisionObserver < ActiveRecord::Observer - observe :conference, :event, :room, :track - - def after_save(model) - begin - conference = model.kind_of?(Conference) ? model : model.conference - conference.reload.increment(:revision) - conference.update_column(:revision, conference.revision) - rescue - nil - end - end -end diff --git a/app/models/room.rb b/app/models/room.rb index 1477a2c6..f8150f78 100644 --- a/app/models/room.rb +++ b/app/models/room.rb @@ -1,4 +1,5 @@ class Room < ActiveRecord::Base + include RevisionCount belongs_to :venue has_many :event_schedules, dependent: :destroy @@ -10,6 +11,10 @@ class Room < ActiveRecord::Base validates :size, numericality: { only_integer: true, greater_than: 0 }, allow_nil: true + def conference + venue.conference + end + private def generate_guid diff --git a/app/models/track.rb b/app/models/track.rb index d3502bb0..f65506d8 100644 --- a/app/models/track.rb +++ b/app/models/track.rb @@ -1,4 +1,5 @@ class Track < ActiveRecord::Base + include RevisionCount belongs_to :program has_many :events, dependent: :nullify @@ -16,6 +17,10 @@ class Track < ActiveRecord::Base before_validation :capitalize_color + def conference + program.conference + end + private def generate_guid diff --git a/config/application.rb b/config/application.rb index 9123e5bb..07ba40f3 100644 --- a/config/application.rb +++ b/config/application.rb @@ -25,7 +25,6 @@ module Osem # Activate observers that should always be running. # config.active_record.observers = :cacher, :garbage_collector, :forum_observer - config.active_record.observers = :revision_observer # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. diff --git a/db/migrate/20170108053041_add_default_to_revision_in_conference.rb b/db/migrate/20170108053041_add_default_to_revision_in_conference.rb new file mode 100644 index 00000000..1c3571de --- /dev/null +++ b/db/migrate/20170108053041_add_default_to_revision_in_conference.rb @@ -0,0 +1,5 @@ +class AddDefaultToRevisionInConference < ActiveRecord::Migration + def change + change_column :conferences, :revision, :integer, default: 0, null: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 7a640259..af227946 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -90,7 +90,7 @@ ActiveRecord::Schema.define(version: 20170629232817) do t.datetime "created_at" t.datetime "updated_at" t.string "logo_file_name" - t.integer "revision" + t.integer "revision", default: 0, null: false t.boolean "use_vpositions", default: false t.boolean "use_vdays", default: false t.boolean "use_volunteers" diff --git a/spec/models/conference_spec.rb b/spec/models/conference_spec.rb index eaef9293..89863412 100755 --- a/spec/models/conference_spec.rb +++ b/spec/models/conference_spec.rb @@ -1660,4 +1660,31 @@ describe Conference do expect{ conference.save }.to change{ EventSchedule.count }.from(2).to(1) end end + + describe '#revision' do + let(:track) { create(:track, program: subject.program) } + let(:event) { create(:event, program: subject.program, track: track) } + let(:venue) { create(:venue, conference: subject) } + let(:room) { create(:room, venue: venue) } + + it 'for change in conference' do + subject.title = 'changed' + expect{ subject.save }.to change { subject.revision }.by(1) + end + + it 'for change in event' do + event.title = 'changed' + expect{ event.save }.to change { subject.revision }.by(1) + end + + it 'for change in track' do + track.name = 'changed' + expect{ track.save }.to change { subject.revision }.by(1) + end + + it 'for change in room' do + room.name = 'changed' + expect{ room.save }.to change { subject.revision }.by(1) + end + end end From f15fe9ddb0cc5422b777d4ef299b043af7e6a75f Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Sat, 25 Mar 2017 22:51:21 +0100 Subject: [PATCH 153/185] Docker support for production use This commit adds a Docker infrastructure that is ready for production use. It is meant to simplify the deployment of OSEM for everyone who wants to host their own instances. It includes many features like data persistence, automatic secret key generation and persistence and automatic database initialization and upgrading. This should make updating the Docker container as easy as possible. --- .dockerignore | 2 ++ Dockerfile | 46 ++++++++++++++++++++++++++++++++++++++ config/database.yml.docker | 7 ++++++ docker-compose.env.example | 38 +++++++++++++++++++++++++++++++ docker-compose.yml.example | 29 ++++++++++++++++++++++++ docker/init.sh | 45 +++++++++++++++++++++++++++++++++++++ 6 files changed, 167 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 config/database.yml.docker create mode 100644 docker-compose.env.example create mode 100644 docker-compose.yml.example create mode 100644 docker/init.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..e235b236 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +Dockerfile +docker-compose.* diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..86a6d4d1 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,46 @@ +FROM ruby:2.3 + +MAINTAINER TheAssassin + +# required for compiling assets +RUN apt-get update && \ + apt-get install -y nodejs nodejs-legacy mariadb-client + +# used to run the container without root permissions +RUN adduser --home /osem/ --system --group --disabled-login --disabled-password osem + +# required to detect when the database is up and running in init.sh +RUN cd /usr/bin && \ + wget https://github.com/jwilder/dockerize/releases/download/v0.3.0/dockerize-linux-amd64-v0.3.0.tar.gz -O dockerize.tar.gz && \ + echo "36e8319cdf9d2b07340f456ec61cfa0f495ec6c130b02ad9c116fd55a5c43fa1 dockerize.tar.gz" | sha256sum -c && \ + tar -xf dockerize.tar.gz && \ + rm dockerize.tar.gz + +# explicitly add Gemfile and install dependencies using bundler to make use of +# Docker's caching +WORKDIR /osem/ +RUN gem install puma +COPY Gemfile /osem/ +COPY Gemfile.lock /osem/ +RUN bundle install --without test development + +# add OSEM files and prepare them for use inside a Docker container +COPY . /osem/ +RUN chown osem.osem /osem/ -R && \ + mv /osem/config/database.yml.docker /osem/config/database.yml + +# data directory is used to cache the secret key in a file +ENV DATA_DIR /data +RUN install -d -m 0700 -o osem $DATA_DIR +VOLUME ["$DATA_DIR"] + +USER osem +EXPOSE 9292 + +COPY docker/init.sh /init.sh + +# a user could override this if they wanted to serve the static files directly +# from a webserver +ENV RAILS_SERVE_STATIC_FILES 1 + +CMD ["bash", "/init.sh"] diff --git a/config/database.yml.docker b/config/database.yml.docker new file mode 100644 index 00000000..60ef8947 --- /dev/null +++ b/config/database.yml.docker @@ -0,0 +1,7 @@ +production: + adapter: mysql2 + host: <%= ENV['DATABASE_HOST'] %> + port: <%= ENV['DATABASE_PORT'] %> + username: <%= ENV['MYSQL_USER'] %> + password: <%= ENV['MYSQL_PASSWORD'] %> + database: <%= ENV['MYSQL_DATABASE'] %> diff --git a/docker-compose.env.example b/docker-compose.env.example new file mode 100644 index 00000000..911b8062 --- /dev/null +++ b/docker-compose.env.example @@ -0,0 +1,38 @@ +## database related variables ## + +# variables prefixed with MYSQL_ are used by both database and web containers +# variables prefixed with DATABASE_ are used exlusively by the web container + +MYSQL_DATABASE=osem +MYSQL_USER=osem +MYSQL_PASSWORD=changemeimmediately +MYSQL_ROOT_PASSWORD=changemeevenmoreimmediately + +# the following settings should not be modified unless the database service +# is renamed in docker-compose.yml or you plan to use an external database +DATABASE_HOST=database +DATABASE_PORT=3306 + + +## OSEM options ## +# you can configure any option described in this document here instead of +# having to create a .env file: +# https://github.com/openSUSE/osem/blob/master/dotenv.example + +OSEM_NAME=Dockerized OSEM +OSEM_HOSTNAME=http://localhost:9292 +OSEM_ERRBIT_HOST=localhost +SECRET_KEY_BASE=changemechangemechangeme + +# these settings work for the MailHog server that is enabled by default in +# docker-compose.yml +# if you do not plan to use MailHog (you most likely don't want to), you need +# to change these settings to use an external working mailserver, otherwise +# your users are going to see the HTTP status 500 page +# you should comment out or remove the mailhog service from docker-compose.yml, +# too +OSEM_EMAIL_ADDRESS=osem@mailhog +OSEM_SMTP_ADDRESS=mailhog +OSEM_SMTP_PORT=1025 +OSEM_SMTP_USERNAME=mailhog +OSEM_SMTP_PASSWORD=mailhog diff --git a/docker-compose.yml.example b/docker-compose.yml.example new file mode 100644 index 00000000..0959523c --- /dev/null +++ b/docker-compose.yml.example @@ -0,0 +1,29 @@ +version: "2" + +services: + database: + image: mariadb:10.1 + env_file: docker-compose.env + volumes: + - database:/var/lib/mysql + + mailhog: + image: mailhog/mailhog:latest + ports: + - "127.0.0.1:8025:8025" + + web: + build: . + env_file: docker-compose.env + depends_on: + - database + - mailhog + ports: + - "127.0.0.1:9292:9292" + volumes: + - "web:/data" + +# these named volumes are used to persist data +volumes: + database: + web: diff --git a/docker/init.sh b/docker/init.sh new file mode 100644 index 00000000..36601e6c --- /dev/null +++ b/docker/init.sh @@ -0,0 +1,45 @@ +#! /bin/bash + +set -e + +# data directory is required for caching the secret key in a file +if [ "$DATA_DIR" == "" ]; then + echo -n "Error: DATA_DIR environment variable not set!" + echo "Are you sure you are running this script in a Docker container?" + exit 1 +fi + +SECRET_KEY_FILE="$DATA_DIR/secret_key" + +if [ ! -f "$SECRET_KEY_FILE" ]; then + install -m 0600 /dev/null "$SECRET_KEY_FILE" + SECRET_KEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 100 | head -n 1) + echo "$key" > "$SECRET_KEY_FILE" + chmod -w "$SECRET_KEY_FILE" +else + SECRET_KEY=$(cat "$SECRET_KEY_FILE") +fi + +export SECRET_KEY +export RAILS_ENV=production + +install -m 0600 /dev/null .my.cnf +cat > .my.cnf <>> Initializing database..." + dockerize -wait tcp://$DATABASE_HOST:$DATABASE_PORT -timeout 60s bundle exec rake db:schema:load +fi + +echo ">>> Upgrading database..." +dockerize -wait tcp://$DATABASE_HOST:$DATABASE_PORT -timeout 60s bundle exec rake db:migrate + +echo ">>> Precompiling assets..." +bundle exec rake assets:precompile + +echo ">>> Starting application server..." +exec puma -e production From 8229cca1e83ec5222ab3c44beccd169adbaeb0e3 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Fri, 31 Mar 2017 13:33:03 +0200 Subject: [PATCH 154/185] Add missing dependency to Dockerfile --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 86a6d4d1..0e7a70aa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ MAINTAINER TheAssassin # required for compiling assets RUN apt-get update && \ - apt-get install -y nodejs nodejs-legacy mariadb-client + apt-get install -y nodejs nodejs-legacy mariadb-client imagemagick # used to run the container without root permissions RUN adduser --home /osem/ --system --group --disabled-login --disabled-password osem From 9402eb36d85530b3c1f4da3d7a53b8283fb48e04 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Fri, 31 Mar 2017 13:33:24 +0200 Subject: [PATCH 155/185] Add beginner guide for deploying OSEM with Docker --- INSTALL.md | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/INSTALL.md b/INSTALL.md index 9cbfafcc..6307b7ae 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -11,7 +11,9 @@ OSEM is an [semantic versioned](http://semver.org/) app. That means given a vers ## Download You can find the latest OSEM releases on our [release page](https://github.com/openSUSE/osem/releases/latest) ([older release here](https://github.com/openSUSE/osem/releases)) + ## Deploy + OSEM is a *Ruby on Rails* application. We recommend to run OSEM in production with [mod_passenger](https://www.phusionpassenger.com/download/#open_source) and the [apache web-server](https://www.apache.org/). There are tons of guides on how to deploy rails apps on various base operating systems. [Check Google](https://encrypted.google.com/search?hl=en&q=ruby%20on%20rails%20apache%20passenger) ;-) @@ -24,6 +26,53 @@ If you have an heroku account you can also Deploy +### Deploy with Docker + +You can deploy OSEM using [Docker](https://docker.com/) and [Docker-Compose](https://docs.docker.com/compose/overview/). + +*This is just a short guide and does not explain how to use Docker and/or Docker-Compose. You need some experience with these tools to be able to deploy OSEM with Docker properly.* + +First of all, copy `docker-compose.yml.example` to `docker-compose.yml` and `docker-compose.env.example` to `docker-compose.env`. + +There are two configurations to deploy OSEM with Docker: *evaluation mode* and *production mode*. + +#### Evaluation mode + +If you want to evaluate OSEM to see if it fits your needs, the default configuration in `docker-compose.env` will work perfectly fine for you. +For convenience reasons, `docker-compose.yml` already contains a [MailHog](https://github.com/mailhog/MailHog) service configuration. MailHog +is going to catch every email sent by OSEM and displays them on a special web service. Thus, it eliminitates the need to set up an SMTP server just to try out OSEM. +Just point your browser to http://localhost:8025 to get access to registration confirmation links etc. + +Run `docker-compose up --build` to start the services. On first run, it will take a few minutes to initialize the database. Thus, wait a few minutes before you open up +http://localhost:9292 in your browser. + +#### Production mode + +To deploy OSEM for production, you have to make a few changes to `docker-compose.yml`. First, remove (or comment) the `mailhog` service, as it is only useful for evaluation and +cannot be used for production. +You can change the forwarded port from port `9292` to any other value if this port is already in use or you just want to use another one. + +Next, you have to modify `docker-compose.env`. This file works as a Docker-like replacement for the regular Rails `.env` files described below. +You can configure any of the configuration values shown in the **Configure** section below in it. The most essential variables are already configured to standard +values in `docker-compose.env` which you most likely want to change. + +First, you need to modify the email related settings. You need a working SMTP server for OSEM to send out registration confirmation mails etc. + +For security reasons, the following variables have to be changed, too: + + - `MYSQL_PASSWORD` + - `MYSQL_ROOT_PASSWORD` + - `SECRET_KEY_BASE` + +These variables need to be set to the correct values at first, as they are used to initialize everything. Modification of these variables after installation and initialization is more +complicated and out of this document's scope. + +As with any other Docker-Compose configuration, run `docker-compose up --build` (or `docker-compose up --build -d` to run in background) to start the services. During the first +start, the database has to be initialized which can take several minutes. The web service is by default exposed on localhost only as it is intended to be served by a reverse proxy (for SSL +termination, caching etc.). +You should not directly expose the web server port unless you have a good reason to do so. + + ## Configure There are a couple of environment variables you can set to configure OSEM. Check out the *dotenv.example* file. From 2c3c070f7e20bea9d932a99c783ccc5beba56e1f Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Sat, 1 Apr 2017 00:48:22 +0200 Subject: [PATCH 156/185] Update Docker docs --- INSTALL.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/INSTALL.md b/INSTALL.md index 6307b7ae..29dc5cec 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -32,7 +32,9 @@ You can deploy OSEM using [Docker](https://docker.com/) and [Docker-Compose](htt *This is just a short guide and does not explain how to use Docker and/or Docker-Compose. You need some experience with these tools to be able to deploy OSEM with Docker properly.* -First of all, copy `docker-compose.yml.example` to `docker-compose.yml` and `docker-compose.env.example` to `docker-compose.env`. +First of all, copy `docker-compose.yml.example` to `docker-compose.yml` and `docker-compose.env.example` to `docker-compose.env`. You should immediately change +`docker-compose.env`'s permissions to `0600` to make sure all the passphrases in it are kept secret. +(Tip: the easiest and most secure way to do it is to do it with a single command, for example `install -m 0600 docker-compose.env.example docker-compose.env`). There are two configurations to deploy OSEM with Docker: *evaluation mode* and *production mode*. From 28d9ac9b1fb37400133cad675ab3b822e66a02a8 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Sat, 1 Apr 2017 01:13:39 +0200 Subject: [PATCH 157/185] Switch to built in rails server --- Dockerfile | 1 - docker/init.sh | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0e7a70aa..dab432ca 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,7 +19,6 @@ RUN cd /usr/bin && \ # explicitly add Gemfile and install dependencies using bundler to make use of # Docker's caching WORKDIR /osem/ -RUN gem install puma COPY Gemfile /osem/ COPY Gemfile.lock /osem/ RUN bundle install --without test development diff --git a/docker/init.sh b/docker/init.sh index 36601e6c..4d71ec77 100644 --- a/docker/init.sh +++ b/docker/init.sh @@ -42,4 +42,4 @@ echo ">>> Precompiling assets..." bundle exec rake assets:precompile echo ">>> Starting application server..." -exec puma -e production +exec bundle exec rails server -e production -p 9292 From 769643a642c6161c72459cbdbdf5f687a54181af Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Sat, 1 Apr 2017 01:16:30 +0200 Subject: [PATCH 158/185] Remove MySQL config file again as soon as possible --- docker/init.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker/init.sh b/docker/init.sh index 4d71ec77..be418b9e 100644 --- a/docker/init.sh +++ b/docker/init.sh @@ -38,6 +38,8 @@ fi echo ">>> Upgrading database..." dockerize -wait tcp://$DATABASE_HOST:$DATABASE_PORT -timeout 60s bundle exec rake db:migrate +rm .my.cnf + echo ">>> Precompiling assets..." bundle exec rake assets:precompile From d7765bf4fdaa33f9db3ece41d65e761ccef26ace Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Sat, 1 Apr 2017 01:16:51 +0200 Subject: [PATCH 159/185] Update ignores --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 4d5fd427..37bd6b81 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,4 @@ pickle-email-*.html .env.development .env.test .env.local +docker-compose.{env,yml} From c592a19f2deb8b7ec25f6bf2ba13370595c728a8 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Tue, 4 Apr 2017 07:32:33 +0200 Subject: [PATCH 160/185] Use rails secret to generate the secret key --- docker/init.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker/init.sh b/docker/init.sh index be418b9e..81ab11b5 100644 --- a/docker/init.sh +++ b/docker/init.sh @@ -12,8 +12,9 @@ fi SECRET_KEY_FILE="$DATA_DIR/secret_key" if [ ! -f "$SECRET_KEY_FILE" ]; then + echo ">>> Creating a new secret key file..." install -m 0600 /dev/null "$SECRET_KEY_FILE" - SECRET_KEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 100 | head -n 1) + SECRET_KEY=$(bundle exec rails secret) echo "$key" > "$SECRET_KEY_FILE" chmod -w "$SECRET_KEY_FILE" else From dd993b74481e158bee3a7105ca85bdb01e5f61fe Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Tue, 16 May 2017 22:16:46 +0200 Subject: [PATCH 161/185] Fix issue mentioned in osem/pull/1407 After the rebase (to update the PR with the latest changes), I had the same issue @lguerard has had. I noticed that the rails server didn't lisen on all interfaces any more, but bound the port to the loopback device only. By adding the parameter `-b 0.0.0.0`, I restored the previous behavior, and OSEM could be reached with the browser after it started up (takes a few seconds). --- docker/init.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/init.sh b/docker/init.sh index 81ab11b5..8f1ba766 100644 --- a/docker/init.sh +++ b/docker/init.sh @@ -45,4 +45,4 @@ echo ">>> Precompiling assets..." bundle exec rake assets:precompile echo ">>> Starting application server..." -exec bundle exec rails server -e production -p 9292 +exec bundle exec rails server -e production -b 0.0.0.0 -p 9292 From b5ca626873cd6d4c95c481238b9f117203fe4de2 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Sun, 9 Jul 2017 15:47:24 +0200 Subject: [PATCH 162/185] Fix Git ignores --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 37bd6b81..75a1bdc6 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,5 @@ pickle-email-*.html .env.development .env.test .env.local -docker-compose.{env,yml} +docker-compose.env +docker-compose.yml From ad9ef4aba36710f9c032a5473e96fd782b983d8b Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Sun, 9 Jul 2017 15:48:09 +0200 Subject: [PATCH 163/185] Fix secret key generation --- docker/init.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/init.sh b/docker/init.sh index 8f1ba766..aedb0874 100644 --- a/docker/init.sh +++ b/docker/init.sh @@ -14,7 +14,7 @@ SECRET_KEY_FILE="$DATA_DIR/secret_key" if [ ! -f "$SECRET_KEY_FILE" ]; then echo ">>> Creating a new secret key file..." install -m 0600 /dev/null "$SECRET_KEY_FILE" - SECRET_KEY=$(bundle exec rails secret) + SECRET_KEY=$(bundle exec rake secret) echo "$key" > "$SECRET_KEY_FILE" chmod -w "$SECRET_KEY_FILE" else From 13d6bf471da363a2901009aa60781c0a5339e13e Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Sun, 9 Jul 2017 15:54:51 +0200 Subject: [PATCH 164/185] Wait for database to be started before running MySQL client command --- docker/init.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/init.sh b/docker/init.sh index aedb0874..16a55231 100644 --- a/docker/init.sh +++ b/docker/init.sh @@ -31,7 +31,7 @@ user=$MYSQL_USER password=$MYSQL_PASSWORD ABC -if [ $(echo "show tables;" | mysql --host $DATABASE_HOST --port $DATABASE_PORT $MYSQL_DATABASE | wc -l) -le 1 ]; then +if [ $(echo "show tables;" | dockerize -wait tcp://$DATABASE_HOST:$DATABASE_PORT -timeout 60s mysql --host $DATABASE_HOST --port $DATABASE_PORT $MYSQL_DATABASE | wc -l) -le 1 ]; then echo ">>> Initializing database..." dockerize -wait tcp://$DATABASE_HOST:$DATABASE_PORT -timeout 60s bundle exec rake db:schema:load fi From 6dea37ec413630ad45dace2891294942eccd9061 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Sun, 9 Jul 2017 19:57:29 +0200 Subject: [PATCH 165/185] Add missing environment variable --- docker-compose.env.example | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.env.example b/docker-compose.env.example index 911b8062..2aedbe73 100644 --- a/docker-compose.env.example +++ b/docker-compose.env.example @@ -32,6 +32,7 @@ SECRET_KEY_BASE=changemechangemechangeme # you should comment out or remove the mailhog service from docker-compose.yml, # too OSEM_EMAIL_ADDRESS=osem@mailhog +OSEM_SMTP_AUTHENTICATION=login OSEM_SMTP_ADDRESS=mailhog OSEM_SMTP_PORT=1025 OSEM_SMTP_USERNAME=mailhog From 93d5e360ca0fbf42dba804e1bf3c71ad936f2cc9 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Sun, 9 Jul 2017 20:55:09 +0200 Subject: [PATCH 166/185] Merge dockerize commands --- docker/init.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docker/init.sh b/docker/init.sh index 16a55231..3a2031f3 100644 --- a/docker/init.sh +++ b/docker/init.sh @@ -31,13 +31,16 @@ user=$MYSQL_USER password=$MYSQL_PASSWORD ABC -if [ $(echo "show tables;" | dockerize -wait tcp://$DATABASE_HOST:$DATABASE_PORT -timeout 60s mysql --host $DATABASE_HOST --port $DATABASE_PORT $MYSQL_DATABASE | wc -l) -le 1 ]; then +echo ">>> Waiting for database to get ready to connect..." +dockerize -wait tcp://$DATABASE_HOST:$DATABASE_PORT -timeout 60s true + +if [ $(echo "show tables;" | mysql --host $DATABASE_HOST --port $DATABASE_PORT $MYSQL_DATABASE | wc -l) -le 1 ]; then echo ">>> Initializing database..." - dockerize -wait tcp://$DATABASE_HOST:$DATABASE_PORT -timeout 60s bundle exec rake db:schema:load + bundle exec rake db:schema:load fi echo ">>> Upgrading database..." -dockerize -wait tcp://$DATABASE_HOST:$DATABASE_PORT -timeout 60s bundle exec rake db:migrate +bundle exec rake db:migrate rm .my.cnf From fbd4be3503131022fb3d037576239a8f3c64d954 Mon Sep 17 00:00:00 2001 From: siddhantbajaj Date: Mon, 10 Jul 2017 17:45:05 +0530 Subject: [PATCH 167/185] Ticket show page --- app/views/physical_ticket/show.html.haml | 51 ++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/app/views/physical_ticket/show.html.haml b/app/views/physical_ticket/show.html.haml index e69de29b..19b89473 100644 --- a/app/views/physical_ticket/show.html.haml +++ b/app/views/physical_ticket/show.html.haml @@ -0,0 +1,51 @@ +.container + .row + .col-md-12 + .page-header + %h1 + Ticket for + = @conference.title + %p.text-muted + - if @conference.venue + at + %strong + #{@conference.venue.name}, + #{@conference.venue.street}, + #{@conference.venue.city} / #{@conference.venue.country_name}. + %small + = date_string(@conference.start_date, @conference.end_date) + .row + .col-md-6 + - if @conference.picture? + = image_tag(@conference.picture_url, class: 'img-responsive') + - else + = image_tag('/img/osem-logo.png', class: 'img-responsive') + .col-md-6 + %address + %strong + Ticket Type + %br + = @physical_ticket.ticket.title + %br + %strong + Ticket REF. + %br + = @physical_ticket.ticket_purchase.id + %br + %strong + Organization + %br + = @conference.organization.name + %br + %strong + Transaction Date + %br + = @physical_ticket.created_at.strftime('%B %d, %Y') + .row + .col-md-12 + %p.text-right + = link_to 'Generate PDF', + conference_physical_ticket_path(@conference.short_title, + @physical_ticket.id, + format: :pdf), + class: 'button btn btn-default btn-info' From c066aadae2138961952a1495d2afa7953ef2e539 Mon Sep 17 00:00:00 2001 From: siddhantbajaj Date: Tue, 11 Jul 2017 17:05:07 +0530 Subject: [PATCH 168/185] Added TicketScanning Model --- app/models/physical_ticket.rb | 1 + app/models/ticket_scanning.rb | 3 +++ db/migrate/20170711102511_create_ticket_scannings.rb | 9 +++++++++ db/schema.rb | 8 +++++++- 4 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 app/models/ticket_scanning.rb create mode 100644 db/migrate/20170711102511_create_ticket_scannings.rb diff --git a/app/models/physical_ticket.rb b/app/models/physical_ticket.rb index a0874a6e..6142c875 100644 --- a/app/models/physical_ticket.rb +++ b/app/models/physical_ticket.rb @@ -3,4 +3,5 @@ class PhysicalTicket < ActiveRecord::Base has_one :ticket, through: :ticket_purchase has_one :conference, through: :ticket_purchase has_one :user, through: :ticket_purchase + has_many :ticket_scannings end diff --git a/app/models/ticket_scanning.rb b/app/models/ticket_scanning.rb new file mode 100644 index 00000000..6ce9d00c --- /dev/null +++ b/app/models/ticket_scanning.rb @@ -0,0 +1,3 @@ +class TicketScanning < ActiveRecord::Base + belongs_to :physical_ticket +end diff --git a/db/migrate/20170711102511_create_ticket_scannings.rb b/db/migrate/20170711102511_create_ticket_scannings.rb new file mode 100644 index 00000000..d1879f68 --- /dev/null +++ b/db/migrate/20170711102511_create_ticket_scannings.rb @@ -0,0 +1,9 @@ +class CreateTicketScannings < ActiveRecord::Migration + def change + create_table :ticket_scannings do |t| + t.integer :physical_ticket_id, null: false + + t.timestamps null: false + end + end +end diff --git a/db/schema.rb b/db/schema.rb index af227946..b9f8e3f4 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170629232817) do +ActiveRecord::Schema.define(version: 20170711102511) do create_table "ahoy_events", force: :cascade do |t| t.uuid "visit_id", limit: 16 @@ -468,6 +468,12 @@ ActiveRecord::Schema.define(version: 20170629232817) do t.integer "week" end + create_table "ticket_scannings", force: :cascade do |t| + t.integer "physical_ticket_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "tickets", force: :cascade do |t| t.integer "conference_id" t.string "title", null: false From 43b4204e308ffa7ffafd808d4d8a391214ae3cd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mois=C3=A9s=20D=C3=A9niz=20Alem=C3=A1n?= Date: Wed, 12 Jul 2017 10:33:16 +0200 Subject: [PATCH 169/185] Revert "Ticket show page" --- app/views/physical_ticket/show.html.haml | 51 ------------------------ 1 file changed, 51 deletions(-) diff --git a/app/views/physical_ticket/show.html.haml b/app/views/physical_ticket/show.html.haml index 19b89473..e69de29b 100644 --- a/app/views/physical_ticket/show.html.haml +++ b/app/views/physical_ticket/show.html.haml @@ -1,51 +0,0 @@ -.container - .row - .col-md-12 - .page-header - %h1 - Ticket for - = @conference.title - %p.text-muted - - if @conference.venue - at - %strong - #{@conference.venue.name}, - #{@conference.venue.street}, - #{@conference.venue.city} / #{@conference.venue.country_name}. - %small - = date_string(@conference.start_date, @conference.end_date) - .row - .col-md-6 - - if @conference.picture? - = image_tag(@conference.picture_url, class: 'img-responsive') - - else - = image_tag('/img/osem-logo.png', class: 'img-responsive') - .col-md-6 - %address - %strong - Ticket Type - %br - = @physical_ticket.ticket.title - %br - %strong - Ticket REF. - %br - = @physical_ticket.ticket_purchase.id - %br - %strong - Organization - %br - = @conference.organization.name - %br - %strong - Transaction Date - %br - = @physical_ticket.created_at.strftime('%B %d, %Y') - .row - .col-md-12 - %p.text-right - = link_to 'Generate PDF', - conference_physical_ticket_path(@conference.short_title, - @physical_ticket.id, - format: :pdf), - class: 'button btn btn-default btn-info' From eb23d838b53ce0dc61e333206a2fa24b1eb80440 Mon Sep 17 00:00:00 2001 From: shlok007 Date: Tue, 11 Jul 2017 04:59:03 +0530 Subject: [PATCH 170/185] 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 171/185] 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 172/185] 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 173/185] 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 174/185] 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 175/185] 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 176/185] 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 177/185] 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 178/185] 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 179/185] 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 180/185] 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 181/185] 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 182/185] 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 183/185] 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 184/185] 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 185/185] 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)