diff --git a/.gitignore b/.gitignore index c8dc8863..8331c5c8 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ pickle-email-*.html .env.development .env.test .env.local +.envrc docker-compose.override.yml .DS_Store .byebug_history diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index acefafb1..7bcb33d4 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -83,7 +83,6 @@ linters: - "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/_questions.html.haml" - "app/views/admin/registrations/edit.html.haml" - "app/views/admin/registrations/index.csv.haml" @@ -209,7 +208,7 @@ linters: - "app/views/layouts/_messages.html.haml" - "app/views/layouts/_navigation.html.haml" - "app/views/layouts/_user_menu.html.haml" - - "app/views/layouts/application.haml" + - "app/views/layouts/application.html.haml" - "app/views/organizations/index.html.haml" - "app/views/payments/_payment.html.haml" - "app/views/payments/new.html.haml" @@ -229,6 +228,7 @@ linters: - "app/views/schedules/_schedule.html.haml" - "app/views/schedules/_schedule_item.html.haml" - "app/views/schedules/_schedule_tabs.html.haml" + - "app/views/schedules/app.html.haml" - "app/views/schedules/events.html.haml" - "app/views/schedules/show.html.haml" - "app/views/schedules/show.xml.haml" @@ -242,8 +242,6 @@ linters: - "app/views/surveys/index.html.haml" - "app/views/surveys/show.html.haml" - "app/views/ticket_purchases/index.html.haml" - - "app/views/tickets/_ticket.html.haml" - - "app/views/tickets/index.html.haml" - "app/views/tracks/_form.html.haml" - "app/views/tracks/index.html.haml" - "app/views/tracks/show.html.haml" @@ -313,6 +311,7 @@ linters: # Offense count: 1074 LineLength: + max: 150 exclude: - "app/views/admin/booths/_change_state_dropdown.html.haml" - "app/views/admin/booths/index.html.haml" @@ -359,7 +358,6 @@ linters: - "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" @@ -441,7 +439,7 @@ linters: - "app/views/layouts/_messages.html.haml" - "app/views/layouts/_navigation.html.haml" - "app/views/layouts/_user_menu.html.haml" - - "app/views/layouts/application.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" @@ -467,8 +465,6 @@ linters: - "app/views/surveys/_list.html.haml" - "app/views/surveys/index.html.haml" - "app/views/surveys/show.html.haml" - - "app/views/tickets/_ticket.html.haml" - - "app/views/tickets/index.html.haml" - "app/views/tracks/_form.html.haml" - "app/views/tracks/index.html.haml" - "app/views/tracks/show.html.haml" @@ -546,7 +542,7 @@ linters: - "app/views/layouts/_admin_sidebar_index.html.haml" - "app/views/layouts/_messages.html.haml" - "app/views/layouts/_navigation.html.haml" - - "app/views/layouts/application.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" @@ -560,7 +556,6 @@ linters: - "app/views/shared/_media_item.html.haml" - "app/views/shared/_media_items.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" @@ -596,14 +591,13 @@ linters: - "app/views/layouts/_admin.html.haml" - "app/views/layouts/_navigation.html.haml" - "app/views/layouts/_user_menu.html.haml" - - "app/views/layouts/application.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: 2 FinalNewline: @@ -642,7 +636,6 @@ linters: - "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: 13 diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 31258088..0dc492c9 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,12 +1,13 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2018-09-08 03:47:39 +0200 using RuboCop version 0.58.2. +# on 2019-10-16 20:30:53 -0700 using RuboCop version 0.75.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: 381 +# Offense count: 351 +# Cop supports --auto-correct. Capybara/CurrentPathExpectation: Exclude: - 'spec/features/base_controller_spec.rb' @@ -23,25 +24,12 @@ Capybara/CurrentPathExpectation: - 'spec/features/track_organizer_ability_spec.rb' - 'spec/features/user_ability_spec.rb' -# Offense count: 170 +# Offense count: 161 # Cop supports --auto-correct. # Configuration parameters: EnabledMethods. Capybara/FeatureMethods: Enabled: false -# Offense count: 140 -# Cop supports --auto-correct. -FactoryBot/AttributeDefinedStatically: - Enabled: false - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: with_first_parameter, with_fixed_indentation -Layout/AlignParameters: - Exclude: - - 'Vagrantfile' - # Offense count: 4 # Cop supports --auto-correct. Layout/ClosingParenthesisIndentation: @@ -75,7 +63,7 @@ Layout/EmptyLineAfterMagicComment: Exclude: - 'spec/models/conference_spec.rb' -# Offense count: 121 +# Offense count: 118 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: empty_lines, no_empty_lines @@ -88,9 +76,9 @@ Layout/EmptyLinesAroundExceptionHandlingKeywords: Exclude: - 'app/models/payment.rb' -# Offense count: 51 +# Offense count: 14 # Cop supports --auto-correct. -# Configuration parameters: AllowForAlignment, ForceEqualSignAlignment. +# Configuration parameters: AllowForAlignment, AllowBeforeTrailingComments, ForceEqualSignAlignment. Layout/ExtraSpacing: Exclude: - 'Guardfile' @@ -103,52 +91,49 @@ Layout/ExtraSpacing: - 'db/migrate/20140623101032_create_ahoy_events.rb' - 'db/migrate/20140701123203_add_events_per_week_to_conference.rb' - 'db/migrate/20140719160903_create_delayed_jobs.rb' - - 'db/schema.rb' - 'spec/models/conference_spec.rb' -# Offense count: 47 +# Offense count: 5 +# Cop supports --auto-correct. +# Configuration parameters: IndentationWidth. +Layout/IndentAssignment: + Exclude: + - 'app/helpers/format_helper.rb' + - 'config/environments/development.rb' + +# Offense count: 43 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, IndentationWidth. # SupportedStyles: consistent, consistent_relative_to_receiver, special_for_inner_method_call, special_for_inner_method_call_in_parentheses -Layout/FirstParameterIndentation: +Layout/IndentFirstArgument: Enabled: false # Offense count: 2 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, IndentationWidth. # SupportedStyles: special_inside_parentheses, consistent, align_brackets -Layout/IndentArray: +Layout/IndentFirstArrayElement: Exclude: - 'app/models/conference.rb' -# Offense count: 6 -# Cop supports --auto-correct. -# Configuration parameters: IndentationWidth. -Layout/IndentAssignment: - Exclude: - - 'app/helpers/format_helper.rb' - - 'app/models/conference.rb' - - 'config/environments/development.rb' - # Offense count: 4 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, IndentationWidth. # SupportedStyles: special_inside_parentheses, consistent, align_braces -Layout/IndentHash: +Layout/IndentFirstHashElement: Exclude: - 'app/models/user.rb' - 'config/routes.rb' - 'db/migrate/20140701123203_add_events_per_week_to_conference.rb' -# Offense count: 3 +# Offense count: 2 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. -# SupportedStyles: normal, rails +# SupportedStyles: normal, indented_internal_methods Layout/IndentationConsistency: Exclude: - 'app/controllers/users_controller.rb' - 'app/models/event.rb' - - 'spec/controllers/subscriptions_controller_spec.rb' # Offense count: 1 # Cop supports --auto-correct. @@ -157,13 +142,13 @@ Layout/IndentationWidth: Exclude: - 'app/controllers/users_controller.rb' -# Offense count: 5 +# Offense count: 4 # Cop supports --auto-correct. +# Configuration parameters: AllowDoxygenCommentStyle. Layout/LeadingCommentSpace: Exclude: - 'Guardfile' - 'app/models/comment.rb' - - 'config/deploy.rb' # Offense count: 1 # Cop supports --auto-correct. @@ -189,7 +174,7 @@ Layout/MultilineHashBraceLayout: - 'config/routes.rb' - 'spec/models/event_spec.rb' -# Offense count: 40 +# Offense count: 36 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: symmetrical, new_line, same_line @@ -252,7 +237,7 @@ Layout/SpaceAroundOperators: - 'config/initializers/airbrake.rb' - 'lib/tasks/data.rake' -# Offense count: 487 +# Offense count: 138 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. # SupportedStyles: space, no_space @@ -302,20 +287,19 @@ Layout/SpaceInsideBlockBraces: - 'app/models/ticket.rb' - 'app/models/user.rb' - 'lib/tasks/events_registrations.rake' + - 'spec/ability/ability_spec.rb' - 'spec/controllers/admin/event_schedules_controller_spec.rb' - 'spec/controllers/admin/schedules_controller_spec.rb' - 'spec/features/splashpage_spec.rb' - - 'spec/ability/ability_spec.rb' - 'spec/models/user_spec.rb' -# Offense count: 39 +# Offense count: 37 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. # 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' @@ -339,15 +323,13 @@ Layout/SpaceInsideParens: Exclude: - 'app/views/admin/registrations/index.xlsx.axlsx' -# Offense count: 5 +# Offense count: 2 # Cop supports --auto-correct. Layout/SpaceInsidePercentLiteralDelimiters: Exclude: - 'Gemfile' - - 'config/deploy.rb' - - 'config/initializers/assets.rb' -# Offense count: 2 +# Offense count: 4 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: space, no_space @@ -355,6 +337,13 @@ Layout/SpaceInsideStringInterpolation: Exclude: - 'config/initializers/active_record_log_subscriber.rb' +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: IndentationWidth. +Layout/Tab: + Exclude: + - 'app/controllers/admin/resources_controller.rb' + # Offense count: 3 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. @@ -389,6 +378,7 @@ Lint/DuplicatedKey: - 'db/migrate/20140801170430_move_event_media_to_commercial.rb' # Offense count: 1 +# Configuration parameters: AllowComments. Lint/HandleExceptions: Exclude: - 'bin/rspec' @@ -406,6 +396,12 @@ Lint/ScriptPermission: - 'Guardfile' - 'Rakefile' +# Offense count: 1 +# Cop supports --auto-correct. +Lint/SendWithMixinArgument: + Exclude: + - 'config/initializers/active_record_log_subscriber.rb' + # Offense count: 1 # Cop supports --auto-correct. # Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments. @@ -420,15 +416,15 @@ Lint/UnusedMethodArgument: Exclude: - 'config/initializers/fuckups.rb' -# Offense count: 142 +# Offense count: 139 Metrics/AbcSize: - Max: 94 + Max: 70 -# Offense count: 331 +# Offense count: 314 # Configuration parameters: CountComments, ExcludedMethods. # ExcludedMethods: refine Metrics/BlockLength: - Max: 1419 + Max: 1344 # Offense count: 1 # Configuration parameters: CountBlocks. @@ -438,16 +434,16 @@ Metrics/BlockNesting: # Offense count: 13 # Configuration parameters: CountComments. Metrics/ClassLength: - Max: 684 + Max: 650 -# Offense count: 32 +# Offense count: 33 Metrics/CyclomaticComplexity: Max: 14 -# Offense count: 146 -# Configuration parameters: CountComments. +# Offense count: 147 +# Configuration parameters: CountComments, ExcludedMethods. Metrics/MethodLength: - Max: 60 + Max: 56 # Offense count: 5 # Configuration parameters: CountComments. @@ -458,7 +454,7 @@ Metrics/ModuleLength: Metrics/PerceivedComplexity: Max: 16 -# Offense count: 17 +# Offense count: 13 Naming/AccessorMethodName: Exclude: - 'app/models/conference.rb' @@ -484,9 +480,17 @@ Naming/PredicateName: - 'app/models/comment.rb' - 'app/models/contact.rb' +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: PreferredName. +Naming/RescuedExceptionsVariableName: + Exclude: + - 'app/models/commercial.rb' + - 'app/models/payment.rb' + # Offense count: 2 # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. -# AllowedNames: io, id, to, by, on, in, at, ip +# AllowedNames: io, id, to, by, on, in, at, ip, db Naming/UncommunicativeMethodParamName: Exclude: - 'app/models/conference.rb' @@ -498,14 +502,7 @@ Naming/VariableNumber: Exclude: - 'spec/models/ticket_purchase_spec.rb' -# Offense count: 4 -# Cop supports --auto-correct. -Performance/InefficientHashSearch: - Exclude: - - 'app/controllers/admin/versions_controller.rb' - - 'app/helpers/versions_helper.rb' - -# Offense count: 31 +# Offense count: 28 RSpec/AnyInstance: Exclude: - 'spec/controllers/admin/rooms_controller_spec.rb' @@ -517,7 +514,7 @@ RSpec/AnyInstance: - 'spec/controllers/proposals_controller_spec.rb' - 'spec/controllers/tracks_controller_spec.rb' -# Offense count: 327 +# Offense count: 317 # Configuration parameters: Prefixes. # Prefixes: when, with, without RSpec/ContextWording: @@ -538,6 +535,24 @@ RSpec/DescribedClass: - 'spec/models/ticket_purchase_spec.rb' - 'spec/models/ticket_spec.rb' - 'spec/models/user_spec.rb' + - 'spec/serializers/conference_serializer_spec.rb' + - 'spec/serializers/event_serializer_spec.rb' + - 'spec/serializers/room_serializer_spec.rb' + - 'spec/serializers/speaker_serializer_spec.rb' + - 'spec/serializers/track_serializer_spec.rb' + +# Offense count: 13 +# Cop supports --auto-correct. +# Configuration parameters: AllowConsecutiveOneLiners. +RSpec/EmptyLineAfterExample: + Exclude: + - 'spec/ability/ability_spec.rb' + - 'spec/controllers/admin/comments_controller_spec.rb' + - 'spec/controllers/admin/registration_periods_controller_spec.rb' + - 'spec/controllers/admin/users_controller_spec.rb' + - 'spec/helpers/events_helper_spec.rb' + - 'spec/models/event_spec.rb' + - 'spec/models/survey_spec.rb' # Offense count: 3 # Cop supports --auto-correct. @@ -545,7 +560,7 @@ RSpec/EmptyLineAfterExampleGroup: Exclude: - 'spec/controllers/admin/users_controller_spec.rb' -# Offense count: 12 +# Offense count: 11 # Cop supports --auto-correct. RSpec/EmptyLineAfterFinalLet: Exclude: @@ -553,7 +568,6 @@ RSpec/EmptyLineAfterFinalLet: - 'spec/controllers/admin/users_controller_spec.rb' - 'spec/controllers/application_controller_spec.rb' - 'spec/features/conference_spec.rb' - - 'spec/models/admin_ability_spec.rb' - 'spec/models/conference_spec.rb' - 'spec/models/payment_spec.rb' - 'spec/models/ticket_spec.rb' @@ -573,12 +587,11 @@ RSpec/EmptyLineAfterHook: - 'spec/models/payment_spec.rb' - 'spec/models/program_spec.rb' -# Offense count: 9 +# Offense count: 8 # Cop supports --auto-correct. RSpec/EmptyLineAfterSubject: Exclude: - 'spec/ability/ability_spec.rb' - - 'spec/models/admin_ability_spec.rb' - 'spec/models/booth_spec.rb' - 'spec/models/cfp_spec.rb' - 'spec/models/event_spec.rb' @@ -587,7 +600,7 @@ RSpec/EmptyLineAfterSubject: - 'spec/models/survey_spec.rb' - 'spec/models/track_spec.rb' -# Offense count: 230 +# Offense count: 220 # Configuration parameters: Max. RSpec/ExampleLength: Enabled: false @@ -608,7 +621,7 @@ RSpec/ExampleWording: - 'spec/models/ticket_purchase_spec.rb' - 'spec/models/ticket_spec.rb' -# Offense count: 38 +# Offense count: 37 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: method_call, block @@ -638,28 +651,41 @@ RSpec/FilePath: - 'spec/models/comment_spec.rb' - 'spec/models/openid.rb' -# Offense count: 174 +# Offense count: 171 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: implicit, each, example RSpec/HookArgument: Enabled: false -# Offense count: 499 +# Offense count: 140 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: is_expected, should RSpec/ImplicitExpect: - Enabled: false + Exclude: + - 'spec/ability/ability_spec.rb' + - 'spec/models/commercial_spec.rb' + - 'spec/models/conference_spec.rb' + - 'spec/models/event_schedule_spec.rb' + - 'spec/models/event_type_spec.rb' + - 'spec/models/organization_spec.rb' + - 'spec/models/registration_period_spec.rb' + - 'spec/models/room_spec.rb' + - 'spec/models/schedule_spec.rb' + - 'spec/models/sponsor_spec.rb' + - 'spec/models/sponsorship_level_spec.rb' + - 'spec/models/ticket_purchase_spec.rb' + - 'spec/models/ticket_spec.rb' + - 'spec/models/user_spec.rb' -# Offense count: 48 +# Offense count: 39 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. -# SupportedStyles: single_line_only, disallow +# SupportedStyles: single_line_only, single_statement_only, disallow RSpec/ImplicitSubject: Exclude: - 'spec/ability/ability_spec.rb' - - 'spec/models/admin_ability_spec.rb' - 'spec/models/booth_spec.rb' - 'spec/models/conference_spec.rb' - 'spec/models/event_type_spec.rb' @@ -670,21 +696,35 @@ RSpec/ImplicitSubject: - 'spec/models/ticket_purchase_spec.rb' - 'spec/models/ticket_spec.rb' -# Offense count: 347 +# Offense count: 321 # Configuration parameters: AssignmentOnly. RSpec/InstanceVariable: - Enabled: false + Exclude: + - 'spec/controllers/admin/sponsorship_levels_controller_spec.rb' + - 'spec/controllers/admin/versions_controller_spec.rb' + - 'spec/controllers/api/v1/conferences_controller_spec.rb' + - 'spec/controllers/application_controller_spec.rb' + - 'spec/controllers/conference_registration_controller_spec.rb' + - 'spec/controllers/conferences_controller_spec.rb' + - 'spec/controllers/confirmations_controller_spec.rb' + - 'spec/controllers/proposals_controller_spec.rb' + - 'spec/features/proposals_spec.rb' + - 'spec/helpers/application_helper_spec.rb' + - 'spec/models/conference_spec.rb' + - 'spec/models/event_schedule_spec.rb' + - 'spec/models/sponsorship_level_spec.rb' + - 'spec/models/track_spec.rb' + - 'spec/models/user_spec.rb' -# Offense count: 5 +# Offense count: 4 # Cop supports --auto-correct. RSpec/LeadingSubject: Exclude: - 'spec/ability/ability_spec.rb' - - 'spec/models/admin_ability_spec.rb' - 'spec/models/conference_spec.rb' - 'spec/models/ticket_spec.rb' -# Offense count: 51 +# Offense count: 55 RSpec/LetSetup: Enabled: false @@ -699,12 +739,13 @@ RSpec/MultipleDescribes: Exclude: - 'spec/controllers/application_controller_spec.rb' -# Offense count: 283 +# Offense count: 278 # Configuration parameters: AggregateFailuresByDefault. RSpec/MultipleExpectations: - Max: 106 + Max: 97 -# Offense count: 403 +# Offense count: 387 +# Configuration parameters: IgnoreSharedExamples. RSpec/NamedSubject: Exclude: - 'spec/models/conference_spec.rb' @@ -712,11 +753,11 @@ RSpec/NamedSubject: - 'spec/models/room_spec.rb' - 'spec/models/track_spec.rb' -# Offense count: 213 +# Offense count: 206 RSpec/NestedGroups: Max: 7 -# Offense count: 93 +# Offense count: 85 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: not_to, to_not @@ -746,7 +787,7 @@ RSpec/RepeatedExample: Exclude: - 'spec/models/conference_spec.rb' -# Offense count: 13 +# Offense count: 10 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: and_return, block @@ -754,11 +795,10 @@ RSpec/ReturnFromStub: Exclude: - 'spec/helpers/events_helper_spec.rb' -# Offense count: 49 +# Offense count: 19 RSpec/ScatteredLet: Exclude: - 'spec/ability/ability_spec.rb' - - 'spec/models/admin_ability_spec.rb' - 'spec/models/payment_spec.rb' # Offense count: 2 @@ -773,8 +813,8 @@ RSpec/SubjectStub: - 'spec/models/room_spec.rb' - 'spec/models/track_spec.rb' -# Offense count: 1 -# Configuration parameters: IgnoreSymbolicNames. +# Offense count: 3 +# Configuration parameters: IgnoreNameless, IgnoreSymbolicNames. RSpec/VerifiedDoubles: Exclude: - 'spec/datatables/user_datatable_spec.rb' @@ -785,247 +825,11 @@ RSpec/VoidExpect: Exclude: - 'spec/models/conference_spec.rb' -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, Include. -# SupportedStyles: action, filter -# Include: app/controllers/**/*.rb -Rails/ActionFilter: - Exclude: - - 'app/controllers/users/omniauth_callbacks_controller.rb' - -# Offense count: 107 -# Cop supports --auto-correct. -Rails/ActiveRecordAliases: - Enabled: false - -# Offense count: 128 -# Cop supports --auto-correct. -Rails/ApplicationRecord: - Enabled: false - -# Offense count: 10 -# Cop supports --auto-correct. -# Configuration parameters: NilOrEmpty, NotPresent, UnlessPresent. -Rails/Blank: - Exclude: - - 'app/controllers/conferences_controller.rb' - - 'app/controllers/users/omniauth_callbacks_controller.rb' - - 'app/models/program.rb' - - 'app/models/user.rb' - - 'spec/factories/event_schedule.rb' - -# Offense count: 20 -# Configuration parameters: Include. -# Include: db/migrate/*.rb -Rails/CreateTableWithTimestamps: - Enabled: false - -# Offense count: 126 -# Configuration parameters: EnforcedStyle. -# SupportedStyles: strict, flexible -Rails/Date: - Enabled: false - # Offense count: 3 -# Cop supports --auto-correct. -# Configuration parameters: EnforceForPrefixed. -Rails/Delegate: - Exclude: - - 'app/models/event.rb' - - 'app/models/room.rb' - - 'app/models/track.rb' - -# 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: 8 -# Configuration parameters: EnforcedStyle. -# SupportedStyles: slashes, arguments -Rails/FilePath: - Exclude: - - 'app/pdfs/ticket_pdf.rb' - - 'config/initializers/active_record_log_subscriber.rb' - - 'config/initializers/carrierwave.rb' - - 'spec/features/lodgings_spec.rb' - - 'spec/features/sponsor_spec.rb' - - 'spec/spec_helper.rb' - -# Offense count: 7 -# Cop supports --auto-correct. -# Configuration parameters: Include. -# Include: app/models/**/*.rb -Rails/FindBy: - Exclude: - - 'app/models/event.rb' - - 'app/models/openid.rb' - - 'app/models/ticket_purchase.rb' - - 'app/models/user.rb' - -# Offense count: 6 -# 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: 20 -# Configuration parameters: Include. -# Include: app/models/**/*.rb -Rails/HasManyOrHasOneDependent: - Exclude: - - 'app/models/answer.rb' - - 'app/models/event.rb' - - 'app/models/payment.rb' - - 'app/models/physical_ticket.rb' - - 'app/models/question_type.rb' - - 'app/models/registration.rb' - - 'app/models/role.rb' - - 'app/models/room.rb' - - 'app/models/sponsorship_level.rb' - - 'app/models/ticket_purchase.rb' - - 'app/models/track.rb' - - 'app/models/user.rb' - - 'app/models/vday.rb' - - 'app/models/vposition.rb' - -# Offense count: 256 -# Cop supports --auto-correct. -# Configuration parameters: Include. -# Include: spec/**/*, test/**/* -Rails/HttpPositionalArguments: - Enabled: false - -# Offense count: 12 -# Configuration parameters: Include. -# Include: app/models/**/*.rb -Rails/InverseOf: - Exclude: - - 'app/models/booth.rb' - - 'app/models/conference.rb' - - 'app/models/event.rb' - - 'app/models/user.rb' - - 'app/models/venue.rb' - -# Offense count: 1 -# Configuration parameters: Include. -# Include: app/controllers/**/*.rb -Rails/LexicallyScopedActionFilter: - Exclude: - - 'app/controllers/registrations_controller.rb' - -# Offense count: 1 -# Configuration parameters: Include. -# Include: app/**/*.rb, config/**/*.rb, db/**/*.rb, lib/**/*.rb -Rails/Output: - Exclude: - - 'config/environment.rb' - -# Offense count: 4 -Rails/OutputSafety: - Exclude: - - 'app/helpers/events_helper.rb' - - 'app/helpers/format_helper.rb' - - 'app/models/commercial.rb' - -# Offense count: 15 -# Cop supports --auto-correct. -Rails/PluralizationGrammar: - Exclude: - - 'spec/models/conference_spec.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -Rails/Presence: - Exclude: - - 'app/controllers/schedules_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/models/user.rb' - -# Offense count: 23 -# Cop supports --auto-correct. -# Configuration parameters: NotNilAndNotEmpty, NotBlank, UnlessBlank. -Rails/Present: - Exclude: - - 'app/helpers/users_helper.rb' - - 'app/models/cfp.rb' - - 'app/models/email_settings.rb' - - 'app/models/event.rb' - - 'app/models/program.rb' - - 'app/models/venue.rb' - - 'config/routes.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: 8 -# 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/models/concerns/revision_count.rb' - - 'db/migrate/20140730104658_migrate_roles_for_cancancan.rb' - - 'db/migrate/20161229080315_add_comments_count_to_events.rb' - - 'db/migrate/20180226032958_add_created_at_and_updated_at_to_event_types.rb' - - 'db/migrate/20180313012253_add_timestamps_to_tickets.rb' - - 'lib/tasks/user.rake' - - 'spec/controllers/conferences_controller_spec.rb' - -# Offense count: 51 -# Configuration parameters: EnforcedStyle. -# SupportedStyles: strict, flexible -Rails/TimeZone: - Exclude: - - 'app/models/comment.rb' - - 'app/models/conference.rb' - - 'config/environments/test.rb' - - 'db/migrate/20180226032958_add_created_at_and_updated_at_to_event_types.rb' - - 'db/migrate/20180313012253_add_timestamps_to_tickets.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/conference_spec.rb' - -# Offense count: 2 Security/Open: Exclude: - 'app/pdfs/ticket_pdf.rb' -# Offense count: 2 -# Configuration parameters: EnforcedStyle. -# SupportedStyles: inline, group -Style/AccessModifierDeclarations: - Exclude: - - 'spec/factories/splashpages.rb' - # Offense count: 1 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. @@ -1046,27 +850,18 @@ Style/ColonMethodCall: - 'app/models/commercial.rb' - 'app/models/contact.rb' -# Offense count: 5 +# Offense count: 4 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SingleLineConditionsOnly, IncludeTernaryExpressions. # SupportedStyles: assign_to_condition, assign_inside_condition Style/ConditionalAssignment: Exclude: - 'app/helpers/format_helper.rb' - - 'config/environments/production.rb' - 'config/initializers/airbrake.rb' - 'db/migrate/20140610165551_migrate_data_person_to_user.rb' - 'db/migrate/20140820124117_undo_wrong_migration20140801080705_add_users_to_events.rb' -# Offense count: 11 -Style/DateTime: - Exclude: - - 'app/models/conference.rb' - - 'app/models/program.rb' - - 'spec/models/conference_spec.rb' - - 'spec/models/program_spec.rb' - -# Offense count: 514 +# Offense count: 516 Style/Documentation: Enabled: false @@ -1088,14 +883,13 @@ Style/EmptyLiteral: Exclude: - 'spec/models/conference_spec.rb' -# Offense count: 9 +# Offense count: 7 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # 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' @@ -1126,19 +920,26 @@ Style/ExpandPathArguments: - 'config/environment.rb' - 'spec/spec_helper.rb' -# Offense count: 44 +# Offense count: 1 +# Configuration parameters: EnforcedStyle. +# SupportedStyles: annotated, template, unannotated +Style/FormatStringToken: + Exclude: + - 'app/uploaders/picture_uploader.rb' + +# Offense count: 49 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. -# SupportedStyles: when_needed, always, never +# SupportedStyles: always, never Style/FrozenStringLiteralComment: Enabled: false -# Offense count: 30 +# Offense count: 29 # Configuration parameters: MinBodyLength. Style/GuardClause: Enabled: false -# Offense count: 8 +# Offense count: 7 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols. # SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys @@ -1149,16 +950,15 @@ Style/HashSyntax: - 'app/views/admin/registrations/index.xlsx.axlsx' - 'lib/tasks/user.rake' -# Offense count: 61 +# Offense count: 58 # Cop supports --auto-correct. Style/IfUnlessModifier: Enabled: false -# Offense count: 8 +# Offense count: 10 # Cop supports --auto-correct. Style/LineEndConcatenation: Exclude: - - 'spec/features/cfp_spec.rb' - 'spec/features/conference_spec.rb' - 'spec/features/registration_periods_spec.rb' @@ -1192,6 +992,8 @@ Style/MultilineIfModifier: # Offense count: 2 # Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. +# SupportedStyles: literals, strict Style/MutableConstant: Exclude: - 'app/models/event_user.rb' @@ -1213,7 +1015,7 @@ Style/NestedParenthesizedCalls: Style/Next: Enabled: false -# Offense count: 121 +# Offense count: 120 # Cop supports --auto-correct. # Configuration parameters: EnforcedOctalStyle. # SupportedOctalStyles: zero_with_o, zero_only @@ -1234,9 +1036,9 @@ Style/NumericLiteralPrefix: Style/NumericLiterals: MinDigits: 15 -# Offense count: 41 +# Offense count: 36 # Cop supports --auto-correct. -# Configuration parameters: AutoCorrect, EnforcedStyle. +# Configuration parameters: AutoCorrect, EnforcedStyle, IgnoredMethods. # SupportedStyles: predicate, comparison Style/NumericPredicate: Exclude: @@ -1274,7 +1076,7 @@ Style/ParenthesesAroundCondition: - 'app/controllers/application_controller.rb' - 'app/helpers/format_helper.rb' -# Offense count: 28 +# Offense count: 22 # Cop supports --auto-correct. # Configuration parameters: PreferredDelimiters. Style/PercentLiteralDelimiters: @@ -1307,15 +1109,15 @@ Style/RedundantParentheses: Exclude: - 'app/controllers/admin/base_controller.rb' -# Offense count: 3 +# Offense count: 4 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, AllowInnerSlashes. # SupportedStyles: slashes, percent_r, mixed Style/RegexpLiteral: Exclude: - 'Guardfile' - - 'config/initializers/airbrake.rb' - 'app/uploaders/picture_uploader.rb' + - 'config/initializers/airbrake.rb' # Offense count: 2 # Cop supports --auto-correct. @@ -1342,21 +1144,18 @@ Style/SingleLineMethods: Exclude: - 'Guardfile' -# Offense count: 672 +# Offense count: 611 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline. # SupportedStyles: single_quotes, double_quotes Style/StringLiterals: Exclude: - 'Gemfile' - - 'Vagrantfile' - 'bin/rspec' - 'bin/spring' - 'config/deploy.rb' - 'config/environments/production.rb' - - 'config/initializers/devise.rb' - 'config/puma.rb' - - 'config/routes.rb' - 'db/schema.rb' - 'lib/tasks/dump_db.rake' - 'lib/tasks/events_registrations.rake' @@ -1374,19 +1173,13 @@ Style/StringLiteralsInInterpolation: - 'app/views/admin/events/_confirmed_events.xlsx.axlsx' - 'lib/tasks/dump_db.rake' -# Offense count: 109 +# Offense count: 110 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, MinSize. # SupportedStyles: percent, brackets Style/SymbolArray: Enabled: false -# Offense count: 1 -# Cop supports --auto-correct. -Style/SymbolLiteral: - Exclude: - - 'config/deploy.rb' - # Offense count: 10 # Cop supports --auto-correct. # Configuration parameters: IgnoredMethods. @@ -1439,7 +1232,7 @@ Style/UnneededCondition: - 'app/helpers/versions_helper.rb' - 'app/models/ticket.rb' -# Offense count: 8 +# Offense count: 9 # Cop supports --auto-correct. # Configuration parameters: WordRegex. # SupportedStyles: percent, brackets @@ -1447,8 +1240,9 @@ Style/WordArray: EnforcedStyle: percent MinSize: 8 -# Offense count: 3041 -# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. +# Offense count: 2915 +# Cop supports --auto-correct. +# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. # URISchemes: http, https Metrics/LineLength: Max: 619 diff --git a/.travis.yml b/.travis.yml index d17395af..4c73dd49 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,19 @@ sudo: required -dist: trusty +dist: xenial +addons: + apt: + packages: + - chromium-browser language: ruby cache: bundler rvm: - - 2.5.0@osem --ignore-gemsets branches: - only: - - master + except: + - /^depfu/.*$/ before_install: - "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" - - "echo `phantomjs -v`" -addons: - chrome: stable + - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true + - gem install bundler -v $(tail -n 1 Gemfile.lock) notifications: email: on_success: change @@ -23,6 +25,7 @@ notifications: on_failure: change before_script: - RAILS_ENV=test bundle exec rake db:bootstrap --trace + - RAILS_ENV=test bundle exec bin/rails webdrivers:chromedriver:update script: - "./travis_script.sh $TEST_SUITE" env: diff --git a/CHANGES.md b/CHANGES.md new file mode 100644 index 00000000..db20a234 --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,70 @@ +# Changes in OSEM 2.0 + +Not release yet... + +## Update from 1.0 + +### Multiple Schedules +A conference can have multiple schedules now so it's easier for organizers to +test schedules and collaborate on different versions. + +For this some of the existing data needs to be changed. If you update +from 1.0 please run this rake task to move your old schedules to the +new system. + +``` +bundle exec rake data:move_events_attributes RAILS_ENV=production +``` + +### Dropped visit/campaign tracking +We have dropped the feature to track visits and campaigns (utm parameters) +inside OSEM. We recommend you use [matomo](https://matomo.org/) for things +like that. Before you update to OSEM 1.1 you should drop all the data we +have collected. + +``` +bundle exec rake data:drop_all_ahoy_events RAILS_ENV=production +``` + +### Conference wide revision history +There is now a conference wide revision history that will show organizers +everything that is happening. To be able to do this we need to change old +data. + +``` +bundle exec rake data:set_conference_in_versions RAILS_ENV=production +``` + +### Organization admins + +We have a new role `organization admins` which allow a user to manage his the +organization and create and manage conference within the organization. This +needs the role to exist in the database, otherwise the application crashes +as it is assumed to exist. For that, run the following rake task: + +``` +bundle exec rake roles:add RAILS_ENV=production +``` + + +# Changes in OSEM 1.0 + +[Released May 24, 2016](https://osem.io/1.0) + +Our first release after developing and using this app in production for +many years. Too many changes to list, see the release announcement to +learn what OSEM is about. + +https://osem.io/1.0 + +## Update from master + +### Configuration through the environment +If you have deployed OSEM from master before there is one thing you need to do +manually. OSEM is now configured through environment variables and not through +the config/options.yml anymore. There is a rake task to migrate your existing +data to a .env file that OSEM will use: + +``` +bundle exec rake data:migrate:config2dotenv RAILS_ENV=production +``` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5f321f29..5c90f739 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,5 @@ # Contributing to OSEM + We here at OSEM are open for all types of contributions from anyone. Tell us about our [issues/ideas](https://github.com/openSUSE/osem/issues/new), propose code changes via [pull requests](https://help.github.com/articles/using-pull-requests) or contribute artwork and documentation. We welcome all new developers and are also prepared to mentor you through your first contributions! All OSEM maintainers are seasoned developers and have participated in mentoring programs, such as [GSoC](https://summerofcode.withgoogle.com/) and [RGSoC](https://railsgirlssummerofcode.org/). @@ -8,10 +9,12 @@ We need your input and contributions to OSEM. In particular we seek the followin * **code**: contribute your expertise in an area by helping us expand OSEM with features/bugfixes/UX * **code editing**: fix typos, clarify language, and generally improve the quality of the content of OSEM * **ideas**: participate in an issues thread or start your own to have your voice heard +* **translations**: translate OSEM into other languages than English Read this guide on how to do that. ## How to contribute code + 1. Fork the repository and make a pull-request with your changes 1. Make sure that the test suite passes and that you comply to our code style 1. Please increase code coverage with your pull request @@ -19,10 +22,59 @@ Read this guide on how to do that. 1. If you are already a contributor and you get a positive review, you can merge your pull-request yourself 1. If you are not already a contributor, one of the existing contributors will merge your pull-request +**However, please bear in mind the following things:** + +### Discuss Large Changes in Advance + +If you see a glaring flaw within OSEM, resist the urge to jump into the +code and make sweeping changes right away. We know it can be tempting, but +especially for large, structural changes it's a wiser choice to first discuss +them in the [issue list](https://github.com/openSUSE/osem/issues). + +A good rule of thumb, of what a *structural change* is, is to estimate how much +time would be wasted if the pull request was rejected. If it's a couple of minutes +then you can probably dive head first and eat the loss in the worst case. Otherwise, +making a quick check with the other developers could save you lots of time down the line. + +Why? It may turn out that someone is already working on this or that someone already +has tried to solve this and hit a roadblock, maybe there even is a good reason +why this particular flaw exists? If nothing else, a discussion of the change will +usually familiarize the reviewer with your proposed changes and streamline the +review process when you finally create a pull request. + +### Small Commits & Pull Request Scope + +A commit should contain a single logical change, the scope should be as small +as possible. And a pull request should only consist of the commits that you +need for your change. If it's possible for you to split larger changes into +smaller blocks please do so. + +Why? Limiting the scope of commits/pull requests makes reviewing much easier. +Because it will usually mean each commit can be evaluated independently and a +smaller amount of commits per pull request usually also means a smaller amount +of code to be reviewed. + +### Proper Commit Messages + +We are keen on proper commit messages because they will help us to maintain +this code in the future. We define proper commit messages like this: + +* The title of your commit message summarizes **what** has been done +* The body of your commit message explains **why** you have done this + +If the title is to small to explain **what** you have done, then you can of course +elaborate about it in the body. Please avoid explaining *how* you have done this, +we are developers too and we see the diff, if we do not understand something we will +ask you in the review. + +Additional to **what** and **why** you should explain potential **side-effects** of +this change, if you are aware of any. + +The content is most important, but please also use a [proper style](https://github.com/openSUSE/osem/wiki/Commit-message-guidelines). + ## Development Environment -### with docker-compose -To isolate you host system from OSEM development we have prepared a container +To isolate your host system from OSEM development we have prepared a container based development environment, based on [docker](https://www.docker.com/) and [docker-compose](https://docs.docker.com/compose/). Here's a step by step guide how to set it up. @@ -50,7 +102,7 @@ sed "s/13042/`id -u`/" docker-compose.override.yml.example > docker-compose.over 1. Check out your OSEM rails app. You can access the app at http://localhost:3000. Whatever you change in your cloned repository will have effect in the development environment. Sign up, the first user will be automatically assigned the admin role. -1. Changed something? Test your changes! +1. Changed something? Run the tests to verify your changes! ```bash docker-compose run --rm osem bundle exec rspec spec ``` @@ -62,65 +114,28 @@ sed "s/13042/`id -u`/" docker-compose.override.yml.example > docker-compose.over 1. Or explore the development environment: ```bash - docker-compose exec osem_1 /bin/bash -l + docker-compose exec osem /bin/bash -l ``` -### with Vagrant -Another option is using [Vagrant](https://www.vagrantup.com/) and [VirtualBox 5.0.10](https://www.virtualbox.org/wiki/Download_Old_Builds_5_0) to create your development environment. +1. Want to know more? + In our wiki you can find more information about what is possible in our development environment, + how we work with each other on github or other topics of interest for OSEM developers. -1. Install [vagrant-exec](https://github.com/p0deje/vagrant-exec): + https://github.com/openSUSE/osem/wiki - ```bash - vagrant plugin install vagrant-exec - ``` +## How to contribute translations -1. Start the development environment - - ``` - vagrant up - ``` - -1. Start OSEM inside the development environment - - ``` - vagrant exec /vagrant/bin/rails server -b 0.0.0.0 - ``` - -6. Check out your OSEM rails app: -You can access the app [localhost:3000](http://localhost:3000). Whatever you change in your cloned repository will have effect in the development environment. Sign up, the first user will be automatically assigned the admin role. - -7. Changed something? Test your changes!: - - ``` - vagrant exec bundle exec rspec spec - ``` - -9. Issue any standard `rails`/`rake`/`bundler` command - - ``` - vagrant exec bundle exec rake db:migrate - ``` - -8. Or explore the development environment: - - ``` - vagrant ssh - ``` - -## Want to know more? -In our wiki you can find more information about what is possible in our development environment, -how we work with each other on github or other topics of interest for developers. Visit us at ->>>>>>> Introduces docker-compose to the contribution guide - -https://github.com/openSUSE/osem/wiki +Please refer to our [translation guide](https://github.com/openSUSE/osem/wiki/Translation) in the wiki. ## 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 or address your concerns to the [openSUSE Board](https://en.opensuse.org/openSUSE:Board). ## Contact + GitHub issues and pull requests are the primary way for communicating about specific proposed changes to this project. If you have other questions feel free to subscribe to the [opensuse-web@opensuse.org](http://lists.opensuse.org/opensuse-web/) diff --git a/Dockerfile.base b/Dockerfile.base index 37741c72..9e274751 100644 --- a/Dockerfile.base +++ b/Dockerfile.base @@ -1,10 +1,5 @@ FROM opensuse/leap:15 -# Enable/Disable the repositories we need/don't need -RUN zypper rr openSUSE-Leap-15.0-Non-Oss openSUSE-Leap-15.0-Update-Non-Oss \ - zypper ar -f https://download.opensuse.org/repositories/devel:/tools/openSUSE_Leap_15.0/devel:tools.repo \ - zypper --gpg-auto-import-keys refresh - # Install our requirements RUN zypper -n install --no-recommends \ # for compiling assets/gems @@ -18,11 +13,11 @@ RUN zypper -n install --no-recommends \ # for nokogiri libxml2-devel libxslt-devel \ # for the interactive shell - ack curl wget w3m \ - # for running our tests - phantomjs which \ + ack curl wget w3m vim which \ # as ruby - ruby2.5-devel + ruby2.5-devel \ + # as browser for feature tests + chromium # Setup sudo RUN echo 'osem ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers @@ -31,7 +26,7 @@ RUN echo 'osem ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers RUN echo 'install: --no-format-executable' >> /etc/gemrc # Install bundler & foreman -RUN gem install bundler foreman +RUN gem install bundler:1.17.3 foreman # Create our user RUN useradd -m --user-group osem diff --git a/Dockerfile.production b/Dockerfile.production index 75b3dfc7..12582dd9 100644 --- a/Dockerfile.production +++ b/Dockerfile.production @@ -1,23 +1,16 @@ FROM osem/base -# We copy the Gemfiles into this intermediate build stage so it's checksum -# changes and all the subsequent stages (a.k.a. the bundle install call below) -# have to be rebuild. Otherwise, after the first build of this image, -# docker would use it's cache for this and the following stages. -COPY Gemfile /osem/ -COPY Gemfile.lock /osem/ -RUN chown -R osem /osem - # Add our files +COPY --chown=1000:1000 . /osem/ + USER osem WORKDIR /osem/ -COPY --chown=osem:osem . /osem/ # Install our bundle RUN export NOKOGIRI_USE_SYSTEM_LIBRARIES=1; bundle install --jobs=3 --retry=3 --without test development -# Configure OSEM -RUN mv config/database.yml.example config/database.yml +# Generate assets +RUN export RAILS_ENV=production; bundle exec rake assets:clobber assets:precompile ENV RAILS_ENV=production diff --git a/Gemfile b/Gemfile index 9469d2ab..b281e1aa 100644 --- a/Gemfile +++ b/Gemfile @@ -10,16 +10,11 @@ if Gem::Version.new(Bundler::VERSION) < Gem::Version.new('1.8.4') end # as web framework -gem 'rails', '~> 5.0.7' +gem 'rails', '~> 5.2.3' # Use Puma as the app server gem 'puma', '~> 3.0' -# enables serving assets in production and setting your logger to standard out -# both of which are required to run an application on a twelve-factor provider -# like heroku.com -gem 'rails_12factor', group: :production - # respond_to methods have been extracted to the responders gem # http://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html#responders gem 'responders', '~> 2.0' @@ -37,7 +32,7 @@ gem 'carrierwave-bombshelter' gem 'mini_magick' # for internationalizing -gem 'rails-i18n', '~> 5.0.0' +gem 'rails-i18n' # as authentification framework gem 'devise' @@ -54,7 +49,7 @@ gem 'omniauth-openid' gem 'recaptcha', require: 'recaptcha/rails' # as authorization framework -gem 'cancancan', '~> 2.0' +gem 'cancancan' # for roles gem 'rolify' @@ -67,7 +62,7 @@ gem 'transitions', :require => %w( transitions active_record/transitions ) # for comments gem 'acts_as_commentable_with_threading' -gem 'awesome_nested_set', '~> 3.1.3' +gem 'awesome_nested_set' # as templating language gem 'haml-rails' @@ -80,7 +75,7 @@ gem 'uglifier', '>= 1.3.0' # as the front-end framework gem 'autoprefixer-rails' -gem 'bootstrap-sass', '~> 3.3.4.1' +gem 'bootstrap-sass', '~> 3.4.0' gem 'cocoon' gem 'formtastic', '~> 3.1.5' gem 'formtastic-bootstrap' @@ -92,8 +87,6 @@ gem 'jquery-ui-rails', '~> 4.2.1' # for languages validation gem 'iso-639' -gem 'thor', '~> 0.19' - # frontend javascripts source 'https://rails-assets.org' do # for placeholder images @@ -117,18 +110,17 @@ source 'https://rails-assets.org' do # for select with icon gem 'rails-assets-bootstrap-select' gem 'rails-assets-markdown' - gem 'rails-assets-to-markdown' + gem 'rails-assets-to-markdown', '~> 3' end # as date picker -gem 'bootstrap3-datetimepicker-rails', '~> 3.0.2' +gem 'bootstrap3-datetimepicker-rails', '~> 4.17.47' # data tables gem 'ajax-datatables-rails' gem 'jquery-datatables-rails' # for charts -gem 'chart-js-rails' gem 'chartkick' # for displaying maps @@ -141,8 +133,10 @@ gem 'gravtastic' gem 'country_select' # as PDF generator -gem 'prawn-qrcode', '~> 0.2.2.1' -gem 'prawn_rails' +gem 'prawn-qrcode' +gem 'prawn-rails' + +# for QR code generation gem 'rqrcode' # to render XLS spreadsheets @@ -150,7 +144,7 @@ gem 'axlsx', git: 'https://github.com/randym/axlsx.git' gem 'axlsx_rails' # as error catcher -gem 'airbrake', '~> 7.1' +gem 'airbrake' # to make links faster gem 'turbolinks' @@ -187,7 +181,7 @@ gem 'acts_as_list' gem 'bootstrap-switch-rails', '~> 3.0.0' # for parsing OEmbed data -gem 'ruby-oembed', '~>0.12.0' +gem 'ruby-oembed' # for uploading images to the cloud gem 'cloudinary' @@ -200,7 +194,7 @@ gem 'dotenv-rails' gem 'feature' # For countable.js -gem "countable-rails", "~> 0.0.1" +gem "countable-rails" # Both are not in a group as we use it also for rake data:demo # for fake data @@ -239,12 +233,10 @@ group :development do gem 'rubocop-rspec' # to open mails gem 'letter_opener' - # to open mails in browser - gem 'letter_opener_web' # as deployment system gem 'mina' # as debugger on error pages - gem 'web-console', '~> 2.0' + gem 'web-console' # as development database gem 'sqlite3' end @@ -252,12 +244,11 @@ end group :test do # as test framework gem 'capybara' - gem 'chromedriver-helper' gem 'database_cleaner' gem 'geckodriver-helper' gem 'rspec-rails' - gem 'selenium-webdriver' gem 'transactional_capybara' + gem 'webdrivers' # for measuring test coverage gem 'codecov', require: false # for describing models diff --git a/Gemfile.lock b/Gemfile.lock index 9f3cdf48..2e1da283 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -13,44 +13,48 @@ GEM remote: https://rails-assets.org/ specs: Ascii85 (1.0.3) - actioncable (5.0.7.1) - actionpack (= 5.0.7.1) - nio4r (>= 1.2, < 3.0) - websocket-driver (~> 0.6.1) - actionmailer (5.0.7.1) - actionpack (= 5.0.7.1) - actionview (= 5.0.7.1) - activejob (= 5.0.7.1) + actioncable (5.2.3) + actionpack (= 5.2.3) + nio4r (~> 2.0) + websocket-driver (>= 0.6.1) + actionmailer (5.2.3) + actionpack (= 5.2.3) + actionview (= 5.2.3) + activejob (= 5.2.3) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (5.0.7.1) - actionview (= 5.0.7.1) - activesupport (= 5.0.7.1) + actionpack (5.2.3) + actionview (= 5.2.3) + activesupport (= 5.2.3) rack (~> 2.0) - rack-test (~> 0.6.3) + rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (5.0.7.1) - activesupport (= 5.0.7.1) + actionview (5.2.3) + activesupport (= 5.2.3) builder (~> 3.1) - erubis (~> 2.7.0) + erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.3) - active_model_serializers (0.10.8) - actionpack (>= 4.1, < 6) - activemodel (>= 4.1, < 6) + active_model_serializers (0.10.10) + actionpack (>= 4.1, < 6.1) + activemodel (>= 4.1, < 6.1) case_transform (>= 0.2) jsonapi-renderer (>= 0.1.1.beta1, < 0.3) - activejob (5.0.7.1) - activesupport (= 5.0.7.1) + activejob (5.2.3) + activesupport (= 5.2.3) globalid (>= 0.3.6) - activemodel (5.0.7.1) - activesupport (= 5.0.7.1) - activerecord (5.0.7.1) - activemodel (= 5.0.7.1) - activesupport (= 5.0.7.1) - arel (~> 7.0) - activesupport (5.0.7.1) + activemodel (5.2.3) + activesupport (= 5.2.3) + activerecord (5.2.3) + activemodel (= 5.2.3) + activesupport (= 5.2.3) + arel (>= 9.0) + activestorage (5.2.3) + actionpack (= 5.2.3) + activerecord (= 5.2.3) + marcel (~> 0.3.1) + activesupport (5.2.3) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) @@ -59,21 +63,22 @@ GEM activerecord (>= 4.0) activesupport (>= 4.0) awesome_nested_set (>= 3.0) - acts_as_list (0.9.17) + acts_as_list (0.9.19) activerecord (>= 3.0) - addressable (2.5.2) + addressable (2.6.0) public_suffix (>= 2.0.2, < 4.0) afm (0.2.2) - airbrake (7.4.0) - airbrake-ruby (~> 2.12) - airbrake-ruby (2.12.0) + airbrake (9.2.2) + airbrake-ruby (~> 4.4) + airbrake-ruby (4.4.0) + rbtree3 (~> 0.5) ajax-datatables-rails (0.4.3) railties (>= 4.0) - archive-zip (0.11.0) + archive-zip (0.12.0) io-like (~> 0.3.0) - arel (7.1.4) + arel (9.0.0) ast (2.4.0) - autoprefixer-rails (9.4.3) + autoprefixer-rails (9.6.4) execjs awesome_nested_set (3.1.4) activerecord (>= 4.0.0, < 5.3) @@ -81,27 +86,26 @@ GEM axlsx_rails (0.5.2) actionpack (>= 3.1) axlsx (>= 2.0.1) - bcrypt (3.1.12) - binding_of_caller (0.7.2) - debug_inspector (>= 0.0.1) - bootstrap-sass (3.3.4.1) - autoprefixer-rails (>= 5.0.0.1) - sass (>= 3.2.19) + bcrypt (3.1.13) + bindex (0.6.0) + bootstrap-sass (3.4.1) + autoprefixer-rails (>= 5.2.1) + sassc (>= 2.0.0) bootstrap-switch-rails (3.0.2) - bootstrap3-datetimepicker-rails (3.0.3) + bootstrap3-datetimepicker-rails (4.17.47) momentjs-rails (>= 2.8.1) builder (3.2.3) - byebug (10.0.2) + byebug (11.0.1) cancancan (2.3.0) - capybara (3.12.0) + capybara (3.26.0) addressable mini_mime (>= 0.1.3) nokogiri (~> 1.8) rack (>= 1.6.0) rack-test (>= 0.6.3) - regexp_parser (~> 1.2) + regexp_parser (~> 1.5) xpath (~> 3.2) - carrierwave (1.3.0) + carrierwave (1.3.1) activemodel (>= 4.0.0) activesupport (>= 4.0.0) mime-types (>= 1.16) @@ -111,67 +115,60 @@ GEM fastimage case_transform (0.2) activesupport - chart-js-rails (0.1.6) - railties (> 3.1) - chartkick (3.0.1) - childprocess (0.9.0) - ffi (~> 1.0, >= 1.0.11) - chromedriver-helper (2.1.0) - archive-zip (~> 0.10) - nokogiri (~> 1.8) + chartkick (3.3.0) + childprocess (3.0.0) chronic (0.10.2) - chunky_png (1.3.8) + chunky_png (1.3.11) climate_control (0.2.0) cloudinary (1.11.1) aws_cf_signer rest-client - cocoon (1.2.12) + cocoon (1.2.14) codecov (0.1.14) json simplecov url coderay (1.1.1) - concurrent-ruby (1.1.4) + concurrent-ruby (1.1.5) connection_pool (2.2.2) countable-rails (0.0.1) railties (>= 3.1) - countries (2.1.4) + countries (3.0.0) i18n_data (~> 0.8.0) - money (~> 6.9) sixarm_ruby_unaccent (~> 1.1) unicode_utils (~> 1.4) - country_select (3.1.1) - countries (~> 2.0) + country_select (4.0.0) + countries (~> 3.0) sort_alphabetical (~> 1.0) crack (0.4.3) safe_yaml (~> 1.0.0) - crass (1.0.4) + crass (1.0.5) daemons (1.3.1) - dalli (2.7.9) + dalli (2.7.10) dante (0.2.0) database_cleaner (1.7.0) - debug_inspector (0.0.3) - delayed_job (4.1.5) - activesupport (>= 3.0, < 5.3) - delayed_job_active_record (4.1.3) - activerecord (>= 3.0, < 5.3) + delayed_job (4.1.8) + activesupport (>= 3.0, < 6.1) + delayed_job_active_record (4.1.4) + activerecord (>= 3.0, < 6.1) delayed_job (>= 3.0, < 5) - devise (4.5.0) + devise (4.7.1) bcrypt (~> 3.0) orm_adapter (~> 0.1) - railties (>= 4.1.0, < 6.0) + railties (>= 4.1.0) responders warden (~> 1.2.3) - devise_ichain_authenticatable (0.3.1) + devise_ichain_authenticatable (0.3.2) devise (>= 2.2) diff-lcs (1.3) docile (1.3.1) domain_name (0.5.20180417) unf (>= 0.0.5, < 1.0.0) - dotenv (2.5.0) - dotenv-rails (2.5.0) - dotenv (= 2.5.0) - railties (>= 3.2, < 6.0) + dotenv (2.7.5) + dotenv-rails (2.7.5) + dotenv (= 2.7.5) + railties (>= 3.2, < 6.1) + erubi (1.9.0) erubis (2.7.0) execjs (2.7.0) factory_bot (4.11.1) @@ -179,15 +176,15 @@ GEM factory_bot_rails (4.11.1) factory_bot (~> 4.11.1) railties (>= 3.0.0) - faker (1.9.1) + faker (1.9.3) i18n (>= 0.7) faraday (0.15.4) multipart-post (>= 1.2, < 3) fastimage (2.1.4) feature (1.4.0) - ffi (1.9.25) - font-awesome-rails (4.7.0.4) - railties (>= 3.2, < 6.0) + ffi (1.10.0) + font-awesome-rails (4.7.0.5) + railties (>= 3.2, < 6.1) formatador (0.2.5) formtastic (3.1.5) actionpack (>= 3.2.13) @@ -195,7 +192,7 @@ GEM formtastic (>= 3.0) geckodriver-helper (0.23.0) archive-zip (~> 0.7) - globalid (0.4.1) + globalid (0.4.2) activesupport (>= 4.2.0) gravtastic (3.2.6) guard (2.14.1) @@ -238,84 +235,82 @@ GEM htmlentities (4.3.4) http-cookie (1.0.3) domain_name (~> 0.5) - i18n (0.9.5) + i18n (1.7.0) concurrent-ruby (~> 1.0) i18n_data (0.8.0) inversion (1.1.1) loggability (~> 0.12) io-like (0.3.0) iso-639 (0.2.8) - jaro_winkler (1.5.1) + jaro_winkler (1.5.3) jquery-datatables-rails (3.4.0) actionpack (>= 3.1) jquery-rails railties (>= 3.1) sass-rails - jquery-rails (4.3.3) + jquery-rails (4.3.5) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) jquery-ui-rails (4.2.1) railties (>= 3.2.16) - json (2.1.0) + json (2.2.0) json-schema (2.8.1) addressable (>= 2.4) - jsonapi-renderer (0.2.0) + jsonapi-renderer (0.2.2) jwt (2.1.0) launchy (2.4.3) addressable (~> 2.3) - leaflet-rails (1.3.1) + leaflet-rails (1.5.1) rails (>= 4.2.0) letter_opener (1.7.0) launchy (~> 2.2) - letter_opener_web (1.3.0) - actionmailer (>= 3.2) - letter_opener (~> 1.0) - railties (>= 3.2) listen (3.1.5) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) ruby_dep (~> 1.2) loggability (0.14.0) - loofah (2.2.3) + loofah (2.4.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) lumberjack (1.0.12) mail (2.7.1) mini_mime (>= 0.1.1) + marcel (0.3.3) + mimemagic (~> 0.3.2) method_source (0.8.2) mime-types (3.2.2) mime-types-data (~> 3.2015) mime-types-data (3.2018.0812) - mimemagic (0.3.2) - mina (0.3.8) + mimemagic (0.3.3) + mina (1.2.3) open4 (~> 1.3.4) rake - mini_magick (4.9.2) - mini_mime (1.0.1) + mini_magick (4.9.5) + mini_mime (1.0.2) mini_portile2 (2.4.0) - minitest (5.11.3) - momentjs-rails (2.8.1) + minitest (5.13.0) + momentjs-rails (2.20.1) railties (>= 3.1) - monetize (1.9.0) + monetize (1.9.2) money (~> 6.12) - money (6.13.1) + money (6.13.4) i18n (>= 0.6.4, <= 2) - money-rails (1.13.0) + money-rails (1.13.3) activesupport (>= 3.0) monetize (~> 1.9.0) - money (~> 6.13.0) + money (~> 6.13.2) railties (>= 3.0) multi_json (1.13.1) multi_xml (0.6.0) - multipart-post (2.0.0) + multipart-post (2.1.1) mysql2 (0.5.2) nenv (0.3.0) - net-http-persistent (3.0.0) + net-http-persistent (3.0.1) connection_pool (~> 2.2) netrc (0.11.0) - nio4r (2.3.1) - nokogiri (1.9.1) + nio4r (2.5.2) + nokogiri (1.10.5) mini_portile2 (~> 2.4.0) notiffany (0.1.1) nenv (~> 0.1) @@ -334,8 +329,8 @@ GEM omniauth-github (1.3.0) omniauth (~> 1.5) omniauth-oauth2 (>= 1.4.0, < 2.0) - omniauth-google-oauth2 (0.5.4) - jwt (>= 1.5) + omniauth-google-oauth2 (0.6.1) + jwt (>= 2.0) omniauth (>= 1.1.1) omniauth-oauth2 (>= 1.5) omniauth-oauth2 (1.6.0) @@ -346,13 +341,13 @@ GEM rack-openid (~> 1.3.1) open4 (1.3.4) orm_adapter (0.5.0) - paper_trail (10.1.0) - activerecord (>= 4.2, < 6.0) + paper_trail (10.3.1) + activerecord (>= 4.2) request_store (~> 1.1) - parallel (1.12.1) - parser (2.5.3.0) + parallel (1.18.0) + parser (2.6.5.0) ast (~> 2.4.0) - pdf-core (0.2.5) + pdf-core (0.7.0) pdf-inspector (1.3.0) pdf-reader (>= 1.0, < 3.0.a) pdf-reader (2.2.0) @@ -361,44 +356,47 @@ GEM hashery (~> 2.0) ruby-rc4 ttfunk - pg (1.1.3) + pg (1.1.4) piwik_analytics (1.0.2) actionpack activesupport rails (>= 3.0.0) - powerpack (0.1.2) - prawn (1.0.0) - pdf-core (~> 0.2.2) - ttfunk (~> 1.1.1) - prawn-qrcode (0.2.2.1) - prawn (>= 0.11.1) + prawn (2.2.2) + pdf-core (~> 0.7.0) + ttfunk (~> 1.5) + prawn-qrcode (0.3.1) + prawn (>= 1) rqrcode (>= 0.4.1) - prawn_rails (0.0.11) - prawn (>= 0.11.1) - railties (>= 3.0.0) + prawn-rails (1.2.0) + prawn + prawn-table + rails (>= 3.1.0) + prawn-table (0.2.2) + prawn (>= 1.3.0, < 3.0.0) pry (0.10.4) coderay (~> 1.1.0) method_source (~> 0.8.1) slop (~> 3.4) - public_suffix (3.0.3) - puma (3.12.0) - rack (2.0.6) + public_suffix (3.1.1) + puma (3.12.2) + rack (2.0.8) rack-openid (1.3.1) rack (>= 1.1.0) ruby-openid (>= 2.1.8) - rack-test (0.6.3) - rack (>= 1.0) - rails (5.0.7.1) - actioncable (= 5.0.7.1) - actionmailer (= 5.0.7.1) - actionpack (= 5.0.7.1) - actionview (= 5.0.7.1) - activejob (= 5.0.7.1) - activemodel (= 5.0.7.1) - activerecord (= 5.0.7.1) - activesupport (= 5.0.7.1) + rack-test (1.1.0) + rack (>= 1.0, < 3) + rails (5.2.3) + actioncable (= 5.2.3) + actionmailer (= 5.2.3) + actionpack (= 5.2.3) + actionview (= 5.2.3) + activejob (= 5.2.3) + activemodel (= 5.2.3) + activerecord (= 5.2.3) + activestorage (= 5.2.3) + activesupport (= 5.2.3) bundler (>= 1.3.0) - railties (= 5.0.7.1) + railties (= 5.2.3) sprockets-rails (>= 2.0.0) rails-assets-bootstrap (3.3.6) rails-assets-jquery (>= 1.9.1, < 3) @@ -417,7 +415,7 @@ GEM rails-assets-spectrum (1.8.0) rails-assets-jquery (>= 1.7.2) rails-assets-tinycolor (1.4.1) - rails-assets-to-markdown (3.0.0) + rails-assets-to-markdown (3.1.1) rails-assets-trianglify (1.2.0) rails-assets-waypoints (4.0.0) rails-controller-testing (1.0.4) @@ -427,42 +425,38 @@ GEM rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) - rails-html-sanitizer (1.0.4) - loofah (~> 2.2, >= 2.2.2) - rails-i18n (5.0.4) - i18n (~> 0.7) - railties (~> 5.0) - rails_12factor (0.0.3) - rails_serve_static_assets - rails_stdout_logging - rails_serve_static_assets (0.0.4) - rails_stdout_logging (0.0.3) - railties (5.0.7.1) - actionpack (= 5.0.7.1) - activesupport (= 5.0.7.1) + rails-html-sanitizer (1.3.0) + loofah (~> 2.3) + rails-i18n (5.1.3) + i18n (>= 0.7, < 2) + railties (>= 5.0, < 6) + railties (5.2.3) + actionpack (= 5.2.3) + activesupport (= 5.2.3) method_source rake (>= 0.8.7) - thor (>= 0.18.1, < 2.0) + thor (>= 0.19.0, < 2.0) rainbow (3.0.0) - rake (12.3.1) - rb-fsevent (0.10.2) - rb-inotify (0.9.10) - ffi (>= 0.5.0, < 2) + rake (12.3.3) + rb-fsevent (0.10.3) + rb-inotify (0.10.0) + ffi (~> 1.0) + rbtree3 (0.5.0) rdoc (6.0.4) rdoc-generator-fivefish (0.4.0) inversion (~> 1.1) loggability (~> 0.12) rdoc (~> 6.0) yajl-ruby (~> 1.3) - recaptcha (4.13.1) + recaptcha (4.14.0) json - redcarpet (3.4.0) - regexp_parser (1.3.0) + redcarpet (3.5.0) + regexp_parser (1.6.0) request_store (1.4.1) rack (>= 1.4) - responders (2.4.0) - actionpack (>= 4.2.0, < 5.3) - railties (>= 4.2.0, < 5.3) + responders (2.4.1) + actionpack (>= 4.2.0, < 6.0) + railties (>= 4.2.0, < 6.0) rest-client (2.0.2) http-cookie (>= 1.0.2, < 2.0) mime-types (>= 1.16, < 4.0) @@ -495,26 +489,25 @@ GEM rspec-mocks (~> 3.6.0) rspec-support (~> 3.6.0) rspec-support (3.6.0) - rubocop (0.61.1) + rubocop (0.75.1) jaro_winkler (~> 1.5.1) parallel (~> 1.10) - parser (>= 2.5, != 2.5.1.1) - powerpack (~> 0.1) + parser (>= 2.6) rainbow (>= 2.2.2, < 4.0) ruby-progressbar (~> 1.7) - unicode-display_width (~> 1.4.0) - rubocop-rspec (1.30.1) - rubocop (>= 0.60.0) + unicode-display_width (>= 1.4.0, < 1.7) + rubocop-rspec (1.36.0) + rubocop (>= 0.68.1) ruby-oembed (0.12.0) - ruby-openid (2.5.0) - ruby-progressbar (1.10.0) + ruby-openid (2.9.2) + ruby-progressbar (1.10.1) ruby-rc4 (0.1.5) ruby_dep (1.5.0) ruby_parser (3.11.0) sexp_processor (~> 4.9) - rubyzip (1.2.2) + rubyzip (1.3.0) safe_yaml (1.0.4) - sass (3.5.7) + sass (3.7.2) sass-listen (~> 4.0.0) sass-listen (4.0.0) rb-fsevent (~> 0.9, >= 0.9.4) @@ -525,23 +518,26 @@ GEM sprockets (>= 2.8, < 4.0) sprockets-rails (>= 2.0, < 4.0) tilt (>= 1.1, < 3) + sassc (2.0.1) + ffi (~> 1.9) + rake selectize-rails (0.12.6) - selenium-webdriver (3.141.0) - childprocess (~> 0.5) - rubyzip (~> 1.2, >= 1.2.2) + selenium-webdriver (3.142.6) + childprocess (>= 0.5, < 4.0) + rubyzip (>= 1.2.2) sexp_processor (4.11.0) shellany (0.0.1) - shoulda-matchers (2.8.0) - activesupport (>= 3.0.0) + shoulda-matchers (4.1.2) + activesupport (>= 4.2.0) simplecov (0.16.1) docile (~> 1.1) json (>= 1.8, < 3) simplecov-html (~> 0.10.0) simplecov-html (0.10.2) sixarm_ruby_unaccent (1.2.0) - skylight (3.1.2) - skylight-core (= 3.1.2) - skylight-core (3.1.2) + skylight (3.1.5) + skylight-core (= 3.1.5) + skylight-core (3.1.5) activesupport (>= 4.2.0) slop (3.6.0) sort_alphabetical (1.1.0) @@ -556,11 +552,11 @@ GEM actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) - sqlite3 (1.3.13) - stripe (4.4.0) + sqlite3 (1.4.1) + stripe (4.21.3) faraday (~> 0.13) net-http-persistent (~> 3.0) - stripe-ruby-mock (2.5.6) + stripe-ruby-mock (2.5.8) dante (>= 0.2.0) multi_json (~> 1.0) stripe (>= 2.0.3) @@ -572,9 +568,9 @@ GEM timecop (0.9.1) transactional_capybara (0.2.0) capybara - transitions (0.1.12) - ttfunk (1.1.1) - turbolinks (5.2.0) + transitions (1.2.1) + ttfunk (1.5.1) + turbolinks (5.2.1) turbolinks-source (~> 5.2) turbolinks-source (5.2.0) tzinfo (1.2.5) @@ -584,25 +580,29 @@ GEM unf (0.1.4) unf_ext unf_ext (0.0.7.5) - unicode-display_width (1.4.0) + unicode-display_width (1.6.0) unicode_utils (1.4.0) unobtrusive_flash (3.3.1) railties url (0.3.2) - warden (1.2.7) - rack (>= 1.0) - web-console (2.3.0) - activemodel (>= 4.0) - binding_of_caller (>= 0.7.2) - railties (>= 4.0) - sprockets-rails (>= 2.0, < 4.0) - webmock (3.4.2) + warden (1.2.8) + rack (>= 2.0.6) + web-console (3.7.0) + actionview (>= 5.0) + activemodel (>= 5.0) + bindex (>= 0.4.0) + railties (>= 5.0) + webdrivers (4.1.3) + nokogiri (~> 1.6) + rubyzip (>= 1.3.0) + selenium-webdriver (>= 3.0, < 4.0) + webmock (3.5.1) addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff - websocket-driver (0.6.5) + websocket-driver (0.7.1) websocket-extensions (>= 0.1.0) - websocket-extensions (0.1.3) + websocket-extensions (0.1.4) whenever (0.10.0) chronic (>= 0.6.3) xpath (3.2.0) @@ -616,28 +616,26 @@ DEPENDENCIES active_model_serializers acts_as_commentable_with_threading acts_as_list - airbrake (~> 7.1) + airbrake ajax-datatables-rails autoprefixer-rails - awesome_nested_set (~> 3.1.3) + awesome_nested_set axlsx! axlsx_rails - bootstrap-sass (~> 3.3.4.1) + bootstrap-sass (~> 3.4.0) bootstrap-switch-rails (~> 3.0.0) - bootstrap3-datetimepicker-rails (~> 3.0.2) + bootstrap3-datetimepicker-rails (~> 4.17.47) byebug - cancancan (~> 2.0) + cancancan capybara carrierwave carrierwave-bombshelter - chart-js-rails chartkick - chromedriver-helper climate_control cloudinary cocoon codecov - countable-rails (~> 0.0.1) + countable-rails country_select daemons dalli @@ -664,7 +662,6 @@ DEPENDENCIES json-schema leaflet-rails letter_opener - letter_opener_web mina mini_magick money-rails @@ -679,10 +676,10 @@ DEPENDENCIES pdf-inspector pg piwik_analytics (~> 1.0.1) - prawn-qrcode (~> 0.2.2.1) - prawn_rails + prawn-qrcode + prawn-rails puma (~> 3.0) - rails (~> 5.0.7) + rails (~> 5.2.3) rails-assets-bootstrap-markdown! rails-assets-bootstrap-select! rails-assets-date.format! @@ -692,12 +689,11 @@ DEPENDENCIES rails-assets-momentjs! rails-assets-spectrum! rails-assets-tinycolor! - rails-assets-to-markdown! + rails-assets-to-markdown (~> 3)! rails-assets-trianglify! rails-assets-waypoints! rails-controller-testing - rails-i18n (~> 5.0.0) - rails_12factor + rails-i18n rdoc-generator-fivefish recaptcha redcarpet @@ -708,10 +704,9 @@ DEPENDENCIES rspec-rails rubocop rubocop-rspec - ruby-oembed (~> 0.12.0) + ruby-oembed sass-rails (>= 4.0.2) selectize-rails - selenium-webdriver shoulda-matchers skylight spring-commands-rspec @@ -719,14 +714,14 @@ DEPENDENCIES sqlite3 stripe stripe-ruby-mock - thor (~> 0.19) timecop transactional_capybara transitions turbolinks uglifier (>= 1.3.0) unobtrusive_flash (>= 3) - web-console (~> 2.0) + web-console + webdrivers webmock whenever @@ -734,4 +729,4 @@ RUBY VERSION ruby 2.5.0p0 BUNDLED WITH - 1.16.5 + 1.17.3 diff --git a/INSTALL.md b/INSTALL.md index 52741ad9..39f9ce4c 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,5 +1,14 @@ # Install Open Source Event Manager -All the information that you need to install OSEM. If you have any problems with installing don't hesitate to [contact us](https://github.com/openSUSE/osem#contact) +Here is what you need to install OSEM. + +# 💥💥💥 WARNING 💥💥💥 +![explosions](https://media.giphy.com/media/Yl5aO3gdVfsQ0/giphy.gif) + +OSEM is a Ruby on Rails server application for professional use, not some desktop app you run for yourself. If you deploy it, **YOU** are responsible for the data that users enter into it, this data includes personal information like email addresses and/or passwords that most likely can be used to harm them in some form (cracking, doxing, social engineering). + +If you never deployed a Ruby on Rails app before we **strongly** suggest you seek help from someone who has. That someone is **NOT** the OSEM team so please do **NOT** open an issue expecting us to explain how to do this. + +*You should know what you do and you have been warned*. ## Versions OSEM is an [semantic versioned](http://semver.org/) app. That means given a version number MAJOR.MINOR.PATCH we increment the: @@ -9,102 +18,65 @@ OSEM is an [semantic versioned](http://semver.org/) app. That means given a vers 3. PATCH version when we make backwards-compatible bug fixes ## 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)) +You can find the latest OSEM releases on our [release page](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) ;-) - -For more information about rails and what it can do, see the [rails guides.](http://guides.rubyonrails.org/getting_started.html) - -If you have an heroku account you can also +## Deploy to the cloud +The easiest way to deploy OSEM is to use one of the many platform as a service providers that support ruby on rails. We have prepared OSEM to be used with [heroku](https://heroku.com). So if you have an account there, you can deploy OSEM by pressing this button: Deploy -### Deploy with Docker +## Deploy to your own server +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). Of course there are also other options for the application server and reverse proxy, pick your poison. -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`. 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*. - -#### 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 eliminates 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. +## Deploy via docker/docker-compose +There is a rudimentary docker-compose configuration for production usage (`docker-compose.yml.production-example`). It brings [OSEM up](http://0.0.0.0:8080) on port 8080. It uses persistent storage volumes for all the data users might create. You can start it with -## Configure -There are a couple of environment variables you can set to configure OSEM. Check out the *dotenv.example* file. +1. Configure OSEM + You have at least to set `SECRET_KEY_BASE` + ``` + cp dotenv.example .env.production + vim .env.production + ``` +1. Build the docker image (only once) + ``` + docker-compose -f docker-compose.yml.production-example build + ``` +1. Start the services + ``` + docker-compose -f docker-compose.yml.production-example up + ``` -### Online Ticket Payments -We use [Stripe](https://stripe.com) for accepting your ticket payments securely over the web. -Our application uses iFrame for accepting your user's payment details without storing them, making the application PCI SAQ-A Compliant. -Please refer to [PAYMENTS](PAYMENTS.md) documentation file for setting up your stripe account and start accepting payments from your users. +## Configuration +OSEM is configured through environment variables and falls back to sensible defaults. See the [dotenv.example](https://github.com/openSUSE/osem/blob/master/dotenv.example) for all possible configuration options. However here is a list of things you most likey want to configure because otherwise things will not work as expected. -## Dependencies +### `SECRET_KEY_BASE` +A [random string](https://www.randomlists.com/string?base=16&length=64&qty=1) to encrypt sessions/cookies. -### ImageMagick -We use [ImageMagick](http://imagemagick.org/) for image manipulation so it needs to be available in your installation. -If you would like to resize exisiting logos in your OSEM installation you can do so by running the following rake task: +### `OSEM_NAME` +The name of your OSEM installation -```shell -$ bundle exec rake logo:reprocess -``` -### Ruby -OSEM is using Ruby version 2.5 +### How to send emails +By default OSEM tries to send emails over localhost. -## 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 in the environment variables found in your *.env* file(s). +#### `OSEM_HOSTNAME` +The host this OSEM instance runs on. This is used for generating urls in emails sent. -## 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. -``` -bundle exec rake jobs:work -``` +#### `OSEM_EMAIL_ADDRESS` +The address OSEM uses to sending mails from. -## Performance -If you are experiencing performance issues (or just curious), you may be able to [apply a free Skylight account](https://www.skylight.io/oss). -Once you have your account setup, simply set `SKYLIGHT_AUTHENTICATION` and `SKYLIGHT_PUBLIC_DASHBOARD_URL` in your `.env` file. -If you are reporting a performance issue or submiting a performance patch, it would be helpful (but not required) to link to the relevant Skylight data. +#### `OSEM_SMTP_ADDRESS` +The mail server we send mail over. (*default*: localhost) + +#### `OSEM_SMTP_AUTHENTICATION` +If your mail server requires authentication, you need to specify the authentication type here. This is a symbol and one of :plain (will send the password in the clear), :login (will send password Base64 encoded) or :cram_md5 (combines a Challenge/Response mechanism to exchange information and a cryptographic Message Digest 5 algorithm to hash important information) + +#### `OSEM_SMTP_USERNAME` +If your mail server requires authentication, set the username in this setting. + +#### `OSEM_SMTP_PASSWORD` +If your mail server requires authentication, set the password in this setting. diff --git a/PAYMENTS.md b/PAYMENTS.md deleted file mode 100644 index 2222e3c9..00000000 --- a/PAYMENTS.md +++ /dev/null @@ -1,46 +0,0 @@ -# Payments through Stripe -Here you will find all the information that you need to setup your Stripe account and integrate it into OSEM. -If you experience any problems, don't hesitate to [contact us](https://github.com/openSUSE/osem#contact) - -**To enable payments, you need to add the API keys, provided by Stripe, in OSEM.** - -## Add Stripe credentials -To integrate Stripe into OSEM, all you need to do is add the *publishable* and *secret* keys into the Rails environment. - -1. Register with Stripe [here](https://dashboard.stripe.com/register) and get your API keys for free - -2. Add your Stripe API keys in the following variables of your `.env` file: - - * For **development** - * `STRIPE_PUBLISHABLE_KEY = 'pk_**test**_random123example456'` - * `STRIPE_SECRET_KEY = 'sk_**test**_random123example456'` - - In development mode, the Stripe integration is useful for feature testing purposes. However, if you wish to enable payments for users, you need to use the live API keys. - - * For **production** - - * `STRIPE_PUBLISHABLE_KEY = 'pk_**live**_random123example456'` - - * `STRIPE_SECRET_KEY = 'sk_**live**_random123example456'` - -3. You are ready to start accepting payments from users - -## Feature tests in development mode -You can test the payment feature in development mode using test credit cards; check out the list [here](https://stripe.com/docs/testing#cards). - -### PCI Self Assessment Questionnaire(SAQ) -> As long as you serve your payment pages over TLS, and use either Checkout or Stripe.js -> as the only way of handling card information, Stripe automatically creates a prefilled SAQ A questionnaire for you, -> and you won’t need to undergo a PCI audit. If card data is stored or transferred through your servers, -> you are responsible for following PCI DSS guidelines for handling card data, and periodic audits by a PCI-certified auditor. - -As we are using Stripe Checkout for accepting payments, Stripe will help you for filling SAQ for your application. -You can read the full security documentation [here](https://stripe.com/docs/security). - -## Configure Stripe to send emails for successful transactions -Stripe can send email reciepts for every successful payment done through its gateway. -Please refer [here](https://dashboard.stripe.com/account/emails) to enable invoice emails for your users. - -## Customize Stripe invoice emails for your application -You can customise your payment reciepts by adding your personalisation like organisation name, logo etc. -Please see the options for invoice personalisation [here](https://dashboard.stripe.com/account/public). diff --git a/Procfile b/Procfile index 84cab0c9..8b9e764c 100644 --- a/Procfile +++ b/Procfile @@ -1,2 +1,2 @@ -web: bundle exec puma -C config/puma.rb +web: bundle exec rails server -b 0.0.0.0 worker: bundle exec rails jobs:work diff --git a/README.md b/README.md index 8c3ab6c6..2fe87dcf 100644 --- a/README.md +++ b/README.md @@ -6,21 +6,16 @@ Deploy -# Open Source Event Manager +# Open Source Event Manager - [osem.io](https://osem.io) ![OSEM Logo](doc/osem-logo.png) An event management tool tailored to Free and Open Source Software conferences. -OSEM actively participates in [GSoC](https://summerofcode.withgoogle.com/) and [RGSoC](https://railsgirlssummerofcode.org/). - ## Installation -Please refer to [INSTALL](INSTALL.md) documentation file +Please refer to our [installation guide](INSTALL.md). ## How to contribute to OSEM -Please refer to our [CONTRIBUTING guide](CONTRIBUTING.md) - -## How to translate OSEM into your language -Please refer to our [TRANSLATION guide](TRANSLATION.md) +Please refer to our [contributing guide](CONTRIBUTING.md). ## Contact GitHub issues are the primary way for communicating about specific proposed changes to this project. If you have other questions feel free to subscribe to the [opensuse-web@opensuse.org](http://lists.opensuse.org/opensuse-web/) mailinglist, all OSEM contributors are on that list! Additionally you can use #osem channel on freenode IRC. diff --git a/TRANSLATION.md b/TRANSLATION.md deleted file mode 100644 index 3923584c..00000000 --- a/TRANSLATION.md +++ /dev/null @@ -1,52 +0,0 @@ -# Translation -We are using [Transifex](https://www.transifex.com/opensuse-community/osem/) to manage our translations. - -We are also using the _Live_ feature of Transifex. That means that all strings from OSEM instances are automatically collected and are available for translating. ->Automated collection only works if you use the API key (See at the end of this file) - -## 1. Translate - * Start translating: - - 1. Navigate to the [project's page](https://www.transifex.com/opensuse-community/osem) - 2. Click **translation** button - 3. Select **language** - 4. Select **resource** (events.opensuse.org) - -Eg. Assuming you have signed up yourself as a translator for OSEM, to translate in German, for example, you go to: https://www.transifex.com/projects/p/osem/translate/#de_DE/eventsopensuseorg/31056760 - - * Request a new language - - If you want to translate OSEM into a language that does not already exist, you can request a new language from the Transifex interface. Your request will have to be approved by an admin of the OSEM project in Transifex. - -## 2. Publish translations - * How to make translations visible (if you have the proper access): - 1. Visit https://www.transifex.com/projects/p/osem/live/#en/events.opensuse.org - 2. Click **Publish** (from right sidebar menu) - 3. Select the language(s) - 4. Click **Publish** - - * How to request to publish translated strings - - After you make sure that you have properly reviewed the newly translated strings (they need to be marked as **reviewed** otherwise they won't go live), you can open a [new issue](https://github.com/openSUSE/osem/issues/new) with the following information: - - Title: [Transifex] Publish translation for EN - - Content: Publish new reviewed strings for language EN - - (You substitute EN with the initials of the language you want to publish) - -> Note: We only publish **reviewed** translated strings - -## 3. Use translations -You can view OSEM in other languages by selecting the language you want from the language selector icon (bottom right corner). - -## 4. API key -When you run your own instance of OSEM, if you want to have the translations available you need to add the api key in the `.env.development` file: - -`OSEM_TRANSIFEX_APIKEY="cf866a61277842b39c897c5a0b5ec075"` - -## 5. Strings with dynamic contents - -Strings containing dynamic content should be tagged in the haml file with "notranslate" classes as described in: - -http://docs.transifex.com/live/webmasters/#how-to-handle-inline-block-variables diff --git a/Vagrantfile b/Vagrantfile deleted file mode 100644 index 92f8e4ca..00000000 --- a/Vagrantfile +++ /dev/null @@ -1,85 +0,0 @@ -# frozen_string_literal: true - -# -*- mode: ruby -*- -# vi: set ft=ruby : - -# All Vagrant configuration is done below. The "2" in Vagrant.configure -# configures the configuration version (we support older styles for -# backwards compatibility). Please don't change it unless you know what -# you're doing. -Vagrant.configure(2) do |config| - # The most common configuration options are documented and commented below. - # For a complete reference, please see the online documentation at - # https://docs.vagrantup.com. - - # Every Vagrant development environment requires a box. You can search for - # boxes at https://atlas.hashicorp.com/search. - 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 - # `vagrant box outdated`. This is not recommended. - # config.vm.box_check_update = false - - # Create a forwarded port mapping which allows access to a specific port - # within the machine from a port on the host machine. In the example below, - # accessing "localhost:8080" will access port 80 on the guest machine. - config.vm.network "forwarded_port", guest: 3000, host: 3000 - - # Create a private network, which allows host-only access to the machine - # using a specific IP. - # config.vm.network "private_network", ip: "192.168.33.10" - - # Create a public network, which generally matched to bridged network. - # Bridged networks make the machine appear as another physical device on - # your network. - # config.vm.network "public_network" - - # Share an additional folder to the guest VM. The first argument is - # the path on the host to the actual folder. The second argument is - # the path on the guest to mount the folder. And the optional third - # argument is a set of non-required options. - # config.vm.synced_folder "../data", "/vagrant_data" - - # When using the default settings, we will attempt to mount this share - # as the vagrant user and the vagrant group. Alas, box opensuse/openSUSE-42.1-x86_64 - # does not have the vagrant group created, so this share fails and - # requires manual mounting for the vagrant setup to continue. Setting - # to the hardcoded numbers will allow the mount to successfully - # mount without working about the group mismatch - VAGRANT_UID = 1000 # User vagrant - VAGRANT_GID = 100 # Group users - config.vm.synced_folder ".", "/vagrant", - owner: VAGRANT_UID, group: VAGRANT_GID - - # Provider-specific configuration so you can fine-tune various - # backing providers for Vagrant. These expose provider-specific options. - # Example for VirtualBox: - # - # config.vm.provider "virtualbox" do |vb| - # # Display the VirtualBox GUI when booting the machine - # vb.gui = true - # - # # Customize the amount of memory on the VM: - # vb.memory = "1024" - # end - # - # View the documentation for the provider you are using for more - # information on available options. - - # Define a Vagrant Push strategy for pushing to Atlas. Other push strategies - # such as FTP and Heroku are also available. See the documentation at - # https://docs.vagrantup.com/v2/push/atlas.html for more information. - # config.push.define "atlas" do |push| - # push.app = "YOUR_ATLAS_USERNAME/YOUR_APPLICATION_NAME" - # end - - # Enable provisioning with a shell script. Additional provisioners such as - # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the - # documentation for more information about their specific syntax and use. - config.vm.provision :shell, path: "bootstrap.sh" - # config.vm.provision "shell", inline: <<-SHELL - # sudo apt-get update - # sudo apt-get install -y apache2 - # SHELL -end diff --git a/app.json b/app.json index 9d6acc52..74f21ee4 100644 --- a/app.json +++ b/app.json @@ -1,67 +1,21 @@ { "name": "osem", "description": "Open Source Event Manager", + "repository": "https://github.com/openSUSE/osem", "env": { "CLOUDINARY_URL": { - "description": "Configure your cloudinary.com cloud name and api key/secret", - "required": true - }, - "DATABASE_URL": { - "description": "Configure your database connection", - "required": false + "description": "Create a https://cloudinary.com account and set the cloud url here. It starts with cloudinary://" }, "SECRET_KEY_BASE": { - "description": "a key which allows sessions to be verified against a known secure key to prevent tampering", - "required": true + "description": "A key to verify sessions. At least 40 characters. For instance: https://www.randomlists.com/string?base=16&length=64&qty=1", + "generator": "secret" }, - "LANG": { - "required": false - }, - "OSEM_EMAIL_ADDRESS": { - "description": "The address OSEM uses for sending mails", - "required": false - }, - "OSEM_HOSTNAME": { - "description": "The host this OSEM instance runs on", - "required": false - }, - "OSEM_NAME": { - "description": "The name of your page", - "required": false - }, - "OSEM_SMTP_ADDRESS": { - "description": "The smtp server to use", - "required": false - }, - "OSEM_SMTP_AUTHENTICATION": { - "description": "The auth method for the smtp server", - "required": false - }, - "OSEM_SMTP_DOMAIN": { - "description": "The HELO domain for the smtp server", - "required": false - }, - "OSEM_SMTP_PASSWORD": { - "description": "The password for the smtp server", - "required": false - }, - "OSEM_SMTP_PORT": { - "description": "The port on the smtp server", - "required": false - }, - "OSEM_SMTP_USERNAME": { - "description": "The user for the smtp server", - "required": false - }, - "RACK_ENV": { - "required": false - }, - "RAILS_ENV": { - "required": false - } + "NOKOGIRI_USE_SYSTEM_LIBRARIES": "1", + "RAILS_ENV": "production", + "RACK_ENV": "production" }, "scripts": { - "postdeploy": "bundle exec rake db:reset data:demo" + "postdeploy": "bundle exec rake db:schema:load db:seed" }, "formation": { "web": { @@ -72,12 +26,11 @@ } }, "addons": [ - "heroku-postgresql", - "sendgrid" - ], - "buildpacks": [ { - "url": "heroku/ruby" + "plan": "heroku-postgresql" + }, + { + "plan": "sendgrid" } ] } diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 0697566f..da958dc3 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -20,8 +20,9 @@ //= require dataTables/bootstrap/3/jquery.dataTables.bootstrap //= require cocoon //= require bootstrap +//= require Chart.bundle +//= require chartkick //= require osem -//= require osem-dashboard //= require jquery-smooth-scroll //= require trianglify //= require tinycolor diff --git a/app/assets/javascripts/osem-dashboard.js b/app/assets/javascripts/osem-dashboard.js deleted file mode 100644 index 83d2b468..00000000 --- a/app/assets/javascripts/osem-dashboard.js +++ /dev/null @@ -1,146 +0,0 @@ -$(function() { - var t; - function size(animate){ - if (animate == undefined){ - animate = false; - } - clearTimeout(t); - t = setTimeout(function(){ - $("canvas").each(function(i,el){ - $(el).attr({ - "width":$(el).parent().width() - }); - }); - - $(".line_chart").each(function(){ - draw_line_chart(animate, $(this)); - }); - - $(".doughnut_chart").each(function(){ - if($(this).is(":visible")){ - draw_doughnut_chart(animate, $(this)); - } - }); - - }, 30); - } - - function draw_doughnut_chart(animation, $this){ - var options = get_animation({}, animation); - var tmp = $this.data('chart'); - - if(jQuery.isEmptyObject(tmp)){ - // Append error message if there is no data - $this.parent().append("

No data!

"); - // Remove canvas - $this.remove(); - }else{ - var data = []; - for (var key in tmp) { - data.push(tmp[key]); - } - - var ctx = $this.get(0).getContext("2d"); - new Chart(ctx).Doughnut(data, options); - } - } - - function get_animation(options, animation){ - if (!animation){ - options.animation = false; - } else { - options.animation = true; - } - return options; - } - - function draw_line_chart(animation, $canvas){ - var chart_data = create_dataset($canvas); - var weeks = $canvas.parent().data('weeks'); - var data = { - labels : weeks, - datasets : chart_data - } - - var options = get_animation(wholeNumberAxisFix(data), animation); - var ctx = $canvas.get(0).getContext("2d"); - new Chart(ctx).Line(data, options); - } - - function wholeNumberAxisFix(data){ - var maxValue = false; - for(datasetIndex = 0; datasetIndex < data.datasets.length; ++datasetIndex){ - var setMax = Math.max.apply(null, data.datasets[datasetIndex].data); - if (maxValue === false || setMax > maxValue) maxValue = setMax; - } - - var steps = maxValue; - var stepWidth = 1; - if (maxValue > 10) { - stepWidth = Math.floor(maxValue / 10); - steps = Math.ceil(maxValue / stepWidth); - } - return { scaleOverride: true, scaleSteps: steps, scaleStepWidth: stepWidth, scaleStartValue: 0 }; - } - - function create_dataset($canvas){ - var selected = getSelectedConferences($canvas); - var chart_data = $canvas.parent().data('chart'); - var conferences = $canvas.parent().data('conferences'); - var result = []; - - for(var i in conferences){ - if(selected.indexOf(conferences[i].short_title) >= 0){ - var options = {}; - options.fillColor = "rgba(255,255,255,0.0)"; - options.strokeColor = conferences[i].color; - options.data = chart_data[conferences[i].short_title]; - if(options.data == null || options.data.length == 0){ - options.data = [0]; - } - result.push(options) - } - } - return result - } - - function getSelectedConferences($canvas){ - var name = $canvas.data('name'); - var id = '#' + name + 'Checkboxes' - var selected = []; - var $checkboxes = $(id + ' input'); - // If there are checkboxes -> get selected - // Else -> use the active conference - if($checkboxes.length){ - $(id + ' input').each(function(){ - if($(this).is(":checked")) { - selected.push($(this).attr('name')); - } - }); - }else{ - var active = $canvas.parent().data('active'); - for(i in active){ - selected.push(active[i].short_title) - } - } - return selected; - } - - $('.conferenceCheckboxes input').change(function(){ - var chart_name = $(this).parent().data('chart'); - var $canvas = $('#line_chart_' + chart_name); - draw_line_chart(false, $canvas); - }); - - $(window).on('resize', function(){ - size(false); - }); - - $('#doughnut_tabs a').click(function (e) { - e.preventDefault(); - $(this).tab('show'); - size(false); - }); - - size(true); -}); diff --git a/app/assets/javascripts/osem-datepickers.js b/app/assets/javascripts/osem-datepickers.js index ed1db596..b907aa0c 100644 --- a/app/assets/javascripts/osem-datepickers.js +++ b/app/assets/javascripts/osem-datepickers.js @@ -2,114 +2,104 @@ var today = new Date().toISOString().slice(0, 10); $(function () { $("input[id^='datetimepicker']").datetimepicker({ - pickTime: true, useCurrent: false, sideBySide: true, - autoclose: true, format: 'YYYY-MM-DD HH:mm' }); $('.datetimepicker').datetimepicker({ - pickTime: true, useCurrent: false, sideBySide: true, format: 'YYYY-MM-DD HH:mm' }); $("#registration-arrival-datepicker").datetimepicker({ - pickTime: true, useCurrent: false, - minuteStepping: 15, + stepping: 15, sideBySide: true, format: "YYYY-MM-DD HH:mm", // current_date <= arrival_date <= end_date maxDate : $("#registration-arrival-datepicker").attr('end_date'), - minDate : today, + minDate : today }); $("#registration-departure-datepicker").datetimepicker({ - pickTime: true, useCurrent: false, - minuteStepping: 15, + stepping: 15, sideBySide: true, format: "YYYY-MM-DD HH:mm", // departure_date > start_date - minDate : $("#registration-arrival-datepicker").attr('start_date'), + minDate : $("#registration-arrival-datepicker").attr('start_date') }); $("#registration-arrival-datepicker").on("dp.change",function (e) { // departure_date > start_date,arrival_date if ((new Date(e.date).getTime()) > (new Date($("#registration-arrival-datepicker").attr('start_date')).getTime())){ - $('#registration-departure-datepicker').data("DateTimePicker").setMinDate(e.date); + $('#registration-departure-datepicker').data("DateTimePicker").minDate(e.date); } else{ - $('#registration-departure-datepicker').data("DateTimePicker").setMinDate($("#registration-arrival-datepicker").attr('start_date')); + $('#registration-departure-datepicker').data("DateTimePicker").minDate($("#registration-arrival-datepicker").attr('start_date')); } }); // departure_date >= arrival_date $("#registration-departure-datepicker").on("dp.change",function (e) { - $('#registration-arrival-datepicker').data("DateTimePicker").setMaxDate(e.date); + $('#registration-arrival-datepicker').data("DateTimePicker").maxDate(e.date); }); $("#conference-start-datepicker").datetimepicker({ - pickTime: false, useCurrent: false, format: "YYYY-MM-DD", // conference-start-day >= Current_date - minDate : today , + minDate : today }); $("#conference-end-datepicker").datetimepicker({ - pickTime: false, useCurrent: false, - format: "YYYY-MM-DD", + format: "YYYY-MM-DD" }); - // end_date_conference >= registration-period-Start_date >= Current_date - // registration-period-Start_date <= registration-period-End_date <= End_date (of conference) - $("#registration-period-start-datepicker").datetimepicker({ - pickTime: false, - useCurrent: false, - format: "YYYY-MM-DD", + // today <= start_registration <= end_registration <= end_conference + var end_conference = $('form').data('end-conference'); + + $('#registration-period-start-datepicker').datetimepicker({ + format: 'YYYY-MM-DD', minDate : today, - maxDate : $("#registration-period-start-datepicker").attr('end_date'), + maxDate : end_conference }); - $("#registration-period-end-datepicker").datetimepicker({ - pickTime: false, - useCurrent: false, - format: "YYYY-MM-DD", - minDate: today, - maxDate : $("#registration-period-start-datepicker").attr('end_date'), + $('#registration-period-end-datepicker').datetimepicker({ + format: 'YYYY-MM-DD', + minDate : today, + maxDate : end_conference }); $("#conference-start-datepicker").on("dp.change",function (e) { - $('#conference-end-datepicker').data("DateTimePicker").setMinDate(e.date); + $('#conference-end-datepicker').data("DateTimePicker").minDate(e.date); if (!$('#conference-end-datepicker').val()) { - $('#conference-end-datepicker').data("DateTimePicker").setDate(e.date); + $('#conference-end-datepicker').data("DateTimePicker").date(e.date); } }); $("#conference-start-datepicker").change(function (e) { - $('#conference-start-datepicker').val()?$('#conference-end-datepicker').data("DateTimePicker").setMinDate(e.date):$('#conference-end-datepicker').data("DateTimePicker").setMinDate(null); + $('#conference-start-datepicker').val()?$('#conference-end-datepicker').data("DateTimePicker").minDate(e.date):$('#conference-end-datepicker').data("DateTimePicker").minDate(null); }); $("#conference-end-datepicker").on("dp.change",function (e) { - $('#conference-start-datepicker').data("DateTimePicker").setMaxDate(e.date); + $('#conference-start-datepicker').data("DateTimePicker").maxDate(e.date); }); $("#conference-end-datepicker").change(function (e) { - $('#conference-end-datepicker').val()?$('#conference-start-datepicker').data("DateTimePicker").setMaxDate(e.date):$('#conference-start-datepicker').data("DateTimePicker").setMaxDate(null); + $('#conference-end-datepicker').val()?$('#conference-start-datepicker').data("DateTimePicker").maxDate(e.date):$('#conference-start-datepicker').data("DateTimePicker").maxDate(null); }); $("#registration-period-start-datepicker").on("dp.change",function (e) { - $('#registration-period-end-datepicker').data("DateTimePicker").setMinDate(e.date); + $('#registration-period-end-datepicker').data("DateTimePicker").minDate(e.date); if (!$('#registration-period-end-datepicker').val()) { - $('#registration-period-end-datepicker').data("DateTimePicker").setDate(e.date); + $('#registration-period-end-datepicker').data("DateTimePicker").date(e.date); } }); $("#registration-period-end-datepicker").on("dp.change",function (e) { - $('#registration-period-start-datepicker').data("DateTimePicker").setMaxDate(e.date); + $('#registration-period-start-datepicker').data("DateTimePicker").maxDate(e.date); }); } ); diff --git a/app/assets/javascripts/osem-schedule.js b/app/assets/javascripts/osem-schedule.js index 39e33922..aeb76ae3 100644 --- a/app/assets/javascripts/osem-schedule.js +++ b/app/assets/javascripts/osem-schedule.js @@ -18,13 +18,11 @@ var Schedule = { if(event_schedule_id != null){ var my_url = url + '/' + event_schedule_id; var success_callback = function(data) { - console.log(data); e.attr("event_schedule_id", null); e.appendTo($(".unscheduled-events")); e.find(".schedule-event-delete-button").hide(); } var error_callback = function(data) { - console.log(data); showError($.parseJSON(data.responseText).errors); } $.ajax({ @@ -57,12 +55,10 @@ var Schedule = { params['event_schedule']['schedule_id'] = schedule_id; } var success_callback = function(data) { - console.log(data); event.attr("event_schedule_id", data.event_schedule_id); event.find(".schedule-event-delete-button").show(); } var error_callback = function(data) { - console.log(data); showError($.parseJSON(data.responseText).errors); event.appendTo(previous_parent); } @@ -87,7 +83,6 @@ $(document).ready( function() { snap: '.schedule-room-slot', revertDuration: 200, revert: function (event, ui) { - console.log(event.attr); return !event; }, stop: function(event, ui) { @@ -96,7 +91,8 @@ $(document).ready( function() { }, opacity: 0.7, snapMode: "inner", - zIndex: 2 + zIndex: 2, + scroll: true }); // set room cells as droppable diff --git a/app/assets/stylesheets/osem-schedule.scss b/app/assets/stylesheets/osem-schedule.scss index 4d1989aa..1cf1efec 100644 --- a/app/assets/stylesheets/osem-schedule.scss +++ b/app/assets/stylesheets/osem-schedule.scss @@ -1,3 +1,12 @@ +#schedule-content .carousel-control{ + width: 12%; +} + +@media (min-width: 768px){ + #schedule-content .carousel-control{ + width: 5%; + } +} .room-name{ font-weight: bold; diff --git a/app/controllers/admin/booths_controller.rb b/app/controllers/admin/booths_controller.rb index 7f46c2bd..b33ec103 100644 --- a/app/controllers/admin/booths_controller.rb +++ b/app/controllers/admin/booths_controller.rb @@ -6,7 +6,7 @@ module Admin load_and_authorize_resource through: :conference def index - @file_name = "booths_for_#{@conference.short_title}" + @file_name = "#{(t 'booth').pluralize}_for_#{@conference.short_title}" @booth_export_option = params[:booth_export_option] respond_to do |format| format.html @@ -14,12 +14,12 @@ module Admin format.json { render json: Booth.where(state: :confirmed, program: @program).to_json } format.xlsx do response.headers['Content-Disposition'] = "attachment; filename=\"#{@file_name}.xlsx\"" - render 'booths' + render 'booths', layout: false end - format.pdf { render 'booths' } + format.pdf { render 'booths', layout: false } format.csv do response.headers['Content-Disposition'] = "attachment; filename=\"#{@file_name}.csv\"" - render 'booths' + render 'booths', layout: false end end end @@ -39,9 +39,9 @@ module Admin if @booth.save redirect_to admin_conference_booths_path, - notice: 'Booth successfully created.' + notice: "#{(t 'booth').capitalize} successfully created." else - flash.now[:error] = "Creating booth failed. #{@booth.errors.full_messages.to_sentence}." + flash.now[:error] = "Creating #{t 'booth'} failed. #{@booth.errors.full_messages.to_sentence}." render :new end end @@ -57,9 +57,9 @@ module Admin if @booth.save redirect_to admin_conference_booths_path, - notice: "Successfully updated booth for #{@booth.title}." + notice: "Successfully updated #{t 'booth'} for #{@booth.title}." else - flash.now[:error] = "An error prohibited the Booth for #{@booth.title} "\ + flash.now[:error] = "An error prohibited the #{t'booth'} for #{@booth.title} "\ "#{@booth.errors.full_messages.join('. ')}." render :edit end @@ -70,47 +70,49 @@ module Admin if @booth.save if @conference.email_settings.send_on_booths_acceptance - Mailbot.conference_booths_acceptance_mail(@booth).deliver + Mailbot.conference_booths_acceptance_mail(@booth).deliver_later end redirect_to admin_conference_booths_path(conference_id: @conference.short_title), - notice: 'Booth successfully accepted!' + notice: "#{(t'booth').capitalize} successfully accepted!" else redirect_to admin_conference_booths_path(conference_id: @conference.short_title) - flash[:error] = "Booth could not be accepted. #{@booth.errors.full_messages.to_sentence}." + flash[:error] = "#{(t 'booth').capitalize} could not be accepted. #{@booth.errors.full_messages.to_sentence}." end end def to_accept - update_state(:to_accept, 'Booth to accept') + update_state(:to_accept, "#{(t'booth').capitalize} to accept") end def to_reject - update_state(:to_reject, 'Booth to reject') + update_state(:to_reject, "#{(t'booth').capitalize} to reject") end def reject @booth.reject! if @booth.save - Mailbot.conference_booths_rejection_mail(@booth).deliver + if @conference.email_settings.send_on_booths_rejection + Mailbot.conference_booths_rejection_mail(@booth).deliver_later + end redirect_to admin_conference_booths_path(conference_id: @conference.short_title), - notice: 'Booth successfully rejected.' + notice: "#{(t'booth').capitalize} successfully rejected." else redirect_to admin_conference_booths_path(conference_id: @conference.short_title) - flash[:error] = "Booth could not be rejected. #{@booth.errors.full_messages.to_sentence}." + flash[:error] = "#{(t 'booth').capitalize} could not be rejected. #{@booth.errors.full_messages.to_sentence}." end end def restart - update_state(:restart, 'Booth is submitted') + update_state(:restart, "#{(t 'booth').capitalize} is submitted") end def cancel - update_state(:cancel, 'Booth is canceled') + update_state(:cancel, "#{(t 'booth').capitalize} is canceled") end def confirm - update_state(:confirm, 'Booth successfully confirmed') + update_state(:confirm, "#{(t 'booth').capitalize} successfully confirmed") end private diff --git a/app/controllers/admin/commercials_controller.rb b/app/controllers/admin/commercials_controller.rb index 003e04bf..e361086d 100644 --- a/app/controllers/admin/commercials_controller.rb +++ b/app/controllers/admin/commercials_controller.rb @@ -45,9 +45,9 @@ module Admin def render_commercial result = Commercial.render_from_url(params[:url]) if result[:error] - render text: result[:error], status: 400 + render plain: result[:error], status: 400 else - render text: result[:html] + render plain: result[:html] end end @@ -70,7 +70,7 @@ module Admin flash[:error] = errors_text end - redirect_to :back + redirect_back(fallback_location: root_path) end private diff --git a/app/controllers/admin/conferences_controller.rb b/app/controllers/admin/conferences_controller.rb index 8b06efeb..f25f2cfe 100644 --- a/app/controllers/admin/conferences_controller.rb +++ b/app/controllers/admin/conferences_controller.rb @@ -37,43 +37,33 @@ module Admin @top_submitter = Conference.get_top_submitter - @submissions = {} - @cfp_weeks = [0] - - @registrations = {} - @registration_weeks = [0] - - @tickets = {} - @ticket_weeks = [0] + @registrations = [] + @submissions = [] + @tickets = [] @conferences.each do |c| - # Event submissions over time chart - @submissions[c.short_title] = c.get_submissions_per_week - @cfp_weeks.push(@submissions[c.short_title].length) - # Conference registrations over time chart - @registrations[c.short_title] = c.get_registrations_per_week - @registration_weeks.push(@registrations[c.short_title].length) - + @registrations << { + name: c.short_title, + data: c.get_registrations_per_week + } + # Event submissions over time chart + @submissions << { + name: c.short_title, + data: c.get_submissions_per_week + } # Tickets sold over time chart - @tickets[c.short_title] = c.get_tickets_sold_per_week - @ticket_weeks.push(@tickets[c.short_title].length) + @tickets << { + name: c.short_title, + data: c.get_tickets_sold_per_week + } end - @cfp_weeks = @cfp_weeks.max - @submissions = normalize_array_length(@submissions, @cfp_weeks) - @cfp_weeks = @cfp_weeks > 0 ? (1..@cfp_weeks).to_a : 1 - - @registration_weeks = @registration_weeks.max - @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 + @event_distribution_colors = Event::COLORS.values + + @user_distribution = User.distribution + @user_distribution_colors = User::DISTRIBUTION_COLORS.values end def new @@ -138,35 +128,9 @@ module Admin @conference_progress = @conference.get_status # Line charts - @registrations = {@conference.short_title => @conference.get_registrations_per_week} - @registration_weeks = [0] - @registration_weeks.push(@registrations[@conference.short_title].length) - - @registration_weeks = @registration_weeks.max - @registrations = normalize_array_length(@registrations, @registration_weeks) - @registration_weeks = @registration_weeks > 0 ? (1..@registration_weeks).to_a : 1 - - @submissions = Conference.get_event_state_line_colors - - @submissions_data = @conference.get_submissions_data - @cfp_weeks = 0 - if @submissions_data['Weeks'] - @cfp_weeks = @submissions_data['Weeks'] - @submissions_data = @submissions_data.except('Weeks') - end - - @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.each_key do |title| - @tickets.append(short_title: title, color: "\##{Digest::MD5.hexdigest(title)[0..5]}") - end + @registrations = @conference.get_registrations_per_week + @submissions = @conference.get_submissions_data + @tickets = @conference.get_tickets_data # Doughnut charts @event_type_distribution = @conference.event_type_distribution diff --git a/app/controllers/admin/event_schedules_controller.rb b/app/controllers/admin/event_schedules_controller.rb index 117ea238..8068b41e 100644 --- a/app/controllers/admin/event_schedules_controller.rb +++ b/app/controllers/admin/event_schedules_controller.rb @@ -3,6 +3,7 @@ module Admin class EventSchedulesController < Admin::BaseController load_and_authorize_resource :event_schedule + skip_before_action :verify_authenticity_token def create if @event_schedule.save diff --git a/app/controllers/admin/events_controller.rb b/app/controllers/admin/events_controller.rb index 3db9321f..d8e9c1c9 100644 --- a/app/controllers/admin/events_controller.rb +++ b/app/controllers/admin/events_controller.rb @@ -16,6 +16,7 @@ module Admin @event_types = @program.event_types @tracks_distribution_confirmed = @conference.tracks_distribution(:confirmed) @event_distribution = @conference.event_distribution + @event_distribution_colors = Event::COLORS.values @scheduled_event_distribution = @conference.scheduled_event_distribution @file_name = "events_for_#{@conference.short_title}" @event_export_option = params[:event_export_option] @@ -27,12 +28,12 @@ module Admin format.json { render json: Event.where(state: :confirmed, program: @program).to_json } format.xlsx do response.headers['Content-Disposition'] = "attachment; filename=\"#{@file_name}.xlsx\"" - render 'events' + render 'events', layout: false end - format.pdf { render 'events' } + format.pdf { render 'events', layout: false } format.csv do response.headers['Content-Disposition'] = "attachment; filename=\"#{@file_name}.csv\"" - render 'events' + render 'events', layout: false end end end diff --git a/app/controllers/admin/registration_periods_controller.rb b/app/controllers/admin/registration_periods_controller.rb index 962c1027..d0884719 100644 --- a/app/controllers/admin/registration_periods_controller.rb +++ b/app/controllers/admin/registration_periods_controller.rb @@ -23,12 +23,6 @@ module Admin end end - def edit - end - - def show - end - def update @registration_period.assign_attributes(registration_period_params) send_mail_on_reg_update = @conference.notify_on_registration_dates_changed? diff --git a/app/controllers/admin/registrations_controller.rb b/app/controllers/admin/registrations_controller.rb index 3f19ed39..89c4d069 100644 --- a/app/controllers/admin/registrations_controller.rb +++ b/app/controllers/admin/registrations_controller.rb @@ -15,12 +15,22 @@ module Admin @registration_distribution = @conference.registration_distribution @affiliation_distribution = @conference.affiliation_distribution @code_of_conduct = @conference.code_of_conduct.present? + @file_name = "registrations_for_#{@conference.short_title}" respond_to do |format| format.html format.json do render json: RegistrationDatatable.new(view_context, conference: @conference) end + format.pdf { render 'index', layout: false } + format.xlsx do + response.headers['Content-Disposition'] = "attachment; filename=\"#{@file_name}.xlsx\"" + render 'index', layout: false + end + format.csv do + response.headers['Content-Disposition'] = "attachment; filename=\"#{@file_name}.csv\"" + render 'index', layout: false + end end end diff --git a/app/controllers/admin/reports_controller.rb b/app/controllers/admin/reports_controller.rb index b2b0f41c..28f4f94f 100644 --- a/app/controllers/admin/reports_controller.rb +++ b/app/controllers/admin/reports_controller.rb @@ -15,8 +15,9 @@ module Admin 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('event_role = ? and program_id = ?', 'speaker', @program.id) .where.not(user_id: attended_registrants_ids) + .where(event_id: @events.pluck(:id)) .includes(:user, :event) end end diff --git a/app/controllers/admin/surveys_controller.rb b/app/controllers/admin/surveys_controller.rb index 591a5ddc..0cef238f 100644 --- a/app/controllers/admin/surveys_controller.rb +++ b/app/controllers/admin/surveys_controller.rb @@ -19,7 +19,7 @@ module Admin if @survey.save redirect_to new_admin_conference_survey_survey_question_path(@conference.short_title, @survey), notice: 'Successfully created survey' else - redirect_to new_admin_conference_survey_survey_question_path(@conference.short_title, @survey), error: 'Could not create survey.' + @survey.errors.full_messages.to_sentence + redirect_to new_admin_conference_survey_path(@conference.short_title, survey: { surveyable_type: survey_params['surveyable_type'], surveyable_id: survey_params['surveyable_id'] }), error: 'Could not create survey.' + @survey.errors.full_messages.to_sentence end end diff --git a/app/controllers/admin/tracks_controller.rb b/app/controllers/admin/tracks_controller.rb index 7d24e4a3..a4f4c69e 100644 --- a/app/controllers/admin/tracks_controller.rb +++ b/app/controllers/admin/tracks_controller.rb @@ -19,12 +19,12 @@ module Admin format.json { render json: Track.where(state: :confirmed, program: @program).to_json } format.xlsx do response.headers['Content-Disposition'] = "attachment; filename=\"#{@file_name}.xlsx\"" - render 'tracks' + render 'tracks', layout: false end - format.pdf { render 'tracks' } + format.pdf { render 'tracks', layout: false } format.csv do response.headers['Content-Disposition'] = "attachment; filename=\"#{@file_name}.csv\"" - render 'tracks' + render 'tracks', layout: false end end end diff --git a/app/controllers/admin/venue_commercials_controller.rb b/app/controllers/admin/venue_commercials_controller.rb index 3be0ec47..ddd13aa9 100644 --- a/app/controllers/admin/venue_commercials_controller.rb +++ b/app/controllers/admin/venue_commercials_controller.rb @@ -40,9 +40,9 @@ module Admin def render_commercial result = Commercial.render_from_url(params[:url]) if result[:error] - render text: result[:error], status: 400 + render plain: result[:error], status: 400 else - render text: result[:html] + render plain: result[:html] end end diff --git a/app/controllers/booths_controller.rb b/app/controllers/booths_controller.rb index df535459..959c9d5d 100644 --- a/app/controllers/booths_controller.rb +++ b/app/controllers/booths_controller.rb @@ -23,9 +23,9 @@ class BoothsController < ApplicationController if @booth.save redirect_to conference_booths_path, - notice: 'Booth successfully created.' + notice: "#{(t 'booth').capitalize} successfully created." else - flash.now[:error] = "Creating booth failed. #{@booth.errors.full_messages.to_sentence}." + flash.now[:error] = "Creating #{t 'booth'} failed. #{@booth.errors.full_messages.to_sentence}." render :new end end @@ -43,6 +43,7 @@ class BoothsController < ApplicationController notice: 'Booth successfully updated!' else flash.now[:error] = "Booth could not be updated. #{@booth.errors.full_messages.to_sentence}." + render :edit end end diff --git a/app/controllers/commercials_controller.rb b/app/controllers/commercials_controller.rb index 13b9b2d4..aa48a406 100644 --- a/app/controllers/commercials_controller.rb +++ b/app/controllers/commercials_controller.rb @@ -4,6 +4,7 @@ class CommercialsController < ApplicationController load_resource :conference, find_by: :short_title before_action :set_event load_and_authorize_resource through: :event + skip_before_action :verify_authenticity_token def create @commercial = @event.commercials.build(commercial_params) @@ -37,9 +38,9 @@ class CommercialsController < ApplicationController def render_commercial result = Commercial.render_from_url(params[:url]) if result[:error] - render text: result[:error], status: 400 + render plain: result[:error], status: 400 else - render text: result[:html] + render plain: result[:html] end end diff --git a/app/controllers/conferences_controller.rb b/app/controllers/conferences_controller.rb index 28309f46..005fe4ad 100644 --- a/app/controllers/conferences_controller.rb +++ b/app/controllers/conferences_controller.rb @@ -6,9 +6,8 @@ class ConferencesController < ApplicationController load_and_authorize_resource find_by: :short_title, except: :show def index - @current, @antiquated = Conference.reorder(start_date: :asc).all.partition do |conference| - conference.end_date >= Date.current - end + @current = Conference.where('end_date >= ?', Date.current).reorder(start_date: :asc) + @antiquated = Conference.where('end_date < ?', Date.current) end def show diff --git a/app/controllers/openids_controller.rb b/app/controllers/openids_controller.rb index 3bccba2f..82af86d0 100644 --- a/app/controllers/openids_controller.rb +++ b/app/controllers/openids_controller.rb @@ -6,6 +6,6 @@ class OpenidsController < ApplicationController def destroy @openid.destroy - redirect_to :back + redirect_back(fallback_location: root_path) end end diff --git a/app/controllers/proposals_controller.rb b/app/controllers/proposals_controller.rb index d59cc2d8..692b4db0 100644 --- a/app/controllers/proposals_controller.rb +++ b/app/controllers/proposals_controller.rb @@ -104,7 +104,7 @@ class ProposalsController < ApplicationController @event.event_schedules.destroy_all end rescue Transitions::InvalidTransition - redirect_to :back, error: "Event can't be withdrawn" + redirect_back(fallback_location: root_path, error: "Event can't be withdrawn") return end @@ -124,7 +124,7 @@ class ProposalsController < ApplicationController begin @event.confirm rescue Transitions::InvalidTransition - redirect_to :back, error: "Event can't be confirmed" + redirect_back(fallback_location: root_path, error: "Event can't be confirmed") return end diff --git a/app/controllers/schedules_controller.rb b/app/controllers/schedules_controller.rb index 453e38c9..2d3f22ef 100644 --- a/app/controllers/schedules_controller.rb +++ b/app/controllers/schedules_controller.rb @@ -2,7 +2,6 @@ class SchedulesController < ApplicationController load_and_authorize_resource - protect_from_forgery with: :null_session before_action :respond_to_options load_resource :conference, find_by: :short_title load_resource :program, through: :conference, singleton: true, except: :index @@ -61,6 +60,10 @@ class SchedulesController < ApplicationController @tag = day.strftime('%Y-%m-%d') if day end + def app + @qr_code = RQRCode::QRCode.new(conference_schedule_url).as_svg(offset: 20, color: '000', shape_rendering: 'crispEdges', module_size: 11) + end + private def respond_to_options diff --git a/app/controllers/surveys_controller.rb b/app/controllers/surveys_controller.rb index 5c0af57e..349bc34b 100644 --- a/app/controllers/surveys_controller.rb +++ b/app/controllers/surveys_controller.rb @@ -40,6 +40,6 @@ class SurveysController < ApplicationController end end - redirect_to :back + redirect_back(fallback_location: root_path) end end diff --git a/app/controllers/ticket_purchases_controller.rb b/app/controllers/ticket_purchases_controller.rb index dac4e34f..632a7289 100644 --- a/app/controllers/ticket_purchases_controller.rb +++ b/app/controllers/ticket_purchases_controller.rb @@ -16,9 +16,11 @@ class TicketPurchasesController < ApplicationController elsif current_user.ticket_purchases.by_conference(@conference).paid.any? redirect_to conference_physical_tickets_path, notice: 'You have free tickets for the conference.' - else + elsif @conference.tickets.for_registration.any? redirect_to conference_tickets_path(@conference.short_title), error: 'Please get at least one ticket to continue.' + else + redirect_to conference_conference_registration_path(@conference.short_title) end else redirect_to conference_tickets_path(@conference.short_title), diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb index 03ae4044..3cc3c621 100644 --- a/app/controllers/users/omniauth_callbacks_controller.rb +++ b/app/controllers/users/omniauth_callbacks_controller.rb @@ -2,7 +2,7 @@ module Users class OmniauthCallbacksController < Devise::OmniauthCallbacksController - skip_before_filter :verify_authenticity_token + skip_before_action :verify_authenticity_token skip_authorization_check User.omniauth_providers.each do |provider| @@ -35,8 +35,7 @@ module Users openid.save! sign_in user - redirect_to request.env['omniauth.origin'] || root_path, - notice: "#{user.email} signed in successfully with #{provider}" + redirect_to root_path, notice: "#{user.email} signed in successfully with #{provider}" rescue => e flash[:error] = e.message redirect_back_or_to new_user_registration_path diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 83275adf..9e27c1a5 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -88,10 +88,9 @@ module ApplicationHelper 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 + redirect_back(fallback_location: root_path) else redirect_to options, response_status end @@ -121,19 +120,19 @@ module ApplicationHelper end def speaker_selector_input(form) - user_selector_input(:speakers, form, '', false) + user_selector_input(:speakers, form, '', true) end def responsibles_selector_input(form) user_selector_input( :responsibles, form, - 'The people responsible for the booth. You can only select existing users.' + "The people responsible for the #{t 'booth'}. You can only select existing users." ) end def user_selector_input(field, form, hint = '', multiple = true) - 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 } + users = User.where(is_disabled: false).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( field, as: :select, diff --git a/app/helpers/chart_helper.rb b/app/helpers/chart_helper.rb new file mode 100644 index 00000000..7503e55b --- /dev/null +++ b/app/helpers/chart_helper.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module ChartHelper + def chart_values(distribution_hash) + Hash[ + distribution_hash.collect do |key, data| + [key, data['value']] + end + ] + end + + def chart_colors(distribution_hash) + distribution_hash.collect do |_key, data| + data['color'] + end + end +end diff --git a/app/models/.lodging.rb.swp b/app/models/.lodging.rb.swp new file mode 100644 index 00000000..70c3567d Binary files /dev/null and b/app/models/.lodging.rb.swp differ diff --git a/app/models/ability.rb b/app/models/ability.rb index 9a0fa2fd..e4d30311 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -31,10 +31,23 @@ class Ability event.state == 'confirmed' end + can [:show, :events, :app], Schedule do |schedule| + schedule.program.schedule_public + end + # can view Commercials of confirmed Events - can :show, Commercial, commercialable_type: 'Event', commercialable_id: Event.where(state: 'confirmed').pluck(:id) + can :show, Commercial, commercialable: Event.where(state: 'confirmed') can [:show, :create], User - unless ENV['OSEM_ICHAIN_ENABLED'] == 'true' + + can [:index, :show], Survey, surveyable_type: 'Conference' + + # Things that are possible without ichain enabled that are **not*+ possible with ichain mode enabled. + if ENV['OSEM_ICHAIN_ENABLED'] != 'true' + # There is no reliable way for this workflow (enable not logged in users to fill out a form, then telling + # them to sign up once they submit) in ichain. So enable it only without ichain. + + # FIXME: The following abilities need to be checked. Are they about the type of workflow mentioned above? Or are + # they just here because they worked in development mode (without ichain). We are suspicious that it's the latter! can :show, Registration do |registration| registration.new_record? end @@ -51,12 +64,6 @@ 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 - - can [:index, :show], Survey, surveyable_type: 'Conference' end end diff --git a/app/models/admin_ability.rb b/app/models/admin_ability.rb index c0328212..19d6c4d3 100644 --- a/app/models/admin_ability.rb +++ b/app/models/admin_ability.rb @@ -117,10 +117,7 @@ class AdminAbility can :manage, Commercial, commercialable_type: 'Conference', commercialable_id: conf_ids can :manage, Registration, conference_id: conf_ids - can :manage, RegistrationPeriod do |registration_period| - conference = registration_period.conference - conf_ids.include?(conference.id) && conference.tickets.for_registration.any? - end + can :manage, RegistrationPeriod, conference_id: conf_ids can :manage, Booth, conference_id: conf_ids can :manage, Question, conference_id: conf_ids can :manage, Question do |question| diff --git a/app/models/cfp.rb b/app/models/cfp.rb index 052e45ce..6571e701 100644 --- a/app/models/cfp.rb +++ b/app/models/cfp.rb @@ -18,7 +18,7 @@ class Cfp < ApplicationRecord in: TYPES }, uniqueness: { - scope: :program, + scope: :program_id, case_sensitive: false } diff --git a/app/models/conference.rb b/app/models/conference.rb index 8ffedb78..be3c36ad 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -29,11 +29,7 @@ class Conference < ApplicationRecord has_many :ticket_purchases, dependent: :destroy has_many :payments, dependent: :destroy has_many :supporters, through: :ticket_purchases, source: :user - has_many :tickets, dependent: :destroy do - def for_registration - where(registration_ticket: true) - end - end + has_many :tickets, dependent: :destroy has_many :resources, dependent: :destroy has_many :booths, dependent: :destroy has_many :confirmed_booths, -> { where(state: 'confirmed') }, class_name: 'Booth' @@ -84,7 +80,8 @@ class Conference < ApplicationRecord :start_hour, :end_hour, :ticket_layout, - :organization, presence: true + :organization, + :timezone, presence: true validates :short_title, uniqueness: true validates :short_title, format: { with: /\A[a-zA-Z0-9_-]*\z/ } @@ -118,7 +115,7 @@ class Conference < ApplicationRecord # 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? + if saved_change_to_start_hour? || saved_change_to_end_hour? event_schedules = program.event_schedules.select do |event_schedule| event_schedule.start_time.hour < start_hour || event_schedule.end_time.hour > end_hour || @@ -176,24 +173,22 @@ class Conference < ApplicationRecord # ====Returns # * +Array+ -> e.g. 'Submitted' => [0, 3, 3, 5] -> first week 0 events, second week 3 events. def get_submissions_data - result = {} - if program&.cfp && program&.events - result = get_events_per_week_by_state + return [] unless program&.cfp && program&.events - start_week = program.cfp.start_week - end_week = end_date.strftime('%W').to_i - weeks = weeks(start_week, end_week) - - result.each do |state, values| - if state == 'Submitted' - result['Submitted'] = pad_array_left_kumulative(start_week, values) - else - result[state] = pad_array_left_not_kumulative(start_week, values) - end + start_week = program.cfp.start_week + get_events_per_week_by_state.collect do |state, values| + if state == 'Submitted' + { + name: 'Submitted', + data: add_week_indices(pad_array_left_kumulative(start_week, values)) + } + else + { + name: state, + data: add_week_indices(pad_array_left_not_kumulative(start_week, values)) + } end - result['Weeks'] = weeks > 0 ? (1..weeks).to_a : 0 end - result end ## @@ -202,19 +197,15 @@ class Conference < ApplicationRecord # ====Returns # * +Array+ -> e.g. [0, 3, 3, 5] -> first week 0, second week 3 registrations def get_registrations_per_week - result = [] + return [] unless registrations && + registration_period && + registration_period.start_date && + registration_period.end_date - if registrations && - registration_period && - registration_period.start_date && - registration_period.end_date - - 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) - end - result + reg = registrations.group(:week).order(:week).count + start_week = get_registration_start_week + weeks = registration_weeks + calculate_items_per_week(start_week, weeks, reg) end ## @@ -223,15 +214,12 @@ class Conference < ApplicationRecord # ====Returns # * +Array+ -> e.g. [0, 3, 3, 5] -> first week 0, second week 3 tickets sold def get_tickets_sold_per_week - result = [] + return [] unless tickets && ticket_purchases && registration_period - 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 + tickets_sold = ticket_purchases.paid.group(:week).sum(:quantity) + start_week = get_registration_start_week + weeks = registration_weeks + calculate_items_per_week(start_week, weeks, tickets_sold) end ## @@ -241,33 +229,32 @@ class Conference < ApplicationRecord # ====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) + return [] unless tickets && ticket_purchases && registration_period - start_week = get_registration_start_week - weeks = registration_weeks + tickets_per_ticket_id_and_week = ticket_purchases.paid.group(:ticket_id, :week).sum(:quantity) - tickets_by_id_per_week = {} + start_week = get_registration_start_week + weeks = registration_weeks - 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 + 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 - - 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 + + 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.collect do |ticket, values| + { + name: Ticket.find(ticket).title, + data: add_week_indices(pad_array_left_not_kumulative(start_week, values)) + } + end end ## @@ -400,7 +387,9 @@ class Conference < ApplicationRecord # ====Returns # * +hash+ -> hash def event_distribution - Conference.calculate_event_distribution_hash(program.events.select(:state).group(:state).count) + Conference.calculate_event_distribution_hash( + program.events.select(:state).group(:state).count + ) end ## @@ -465,22 +454,6 @@ class Conference < ApplicationRecord result end - ## - # Returns a hash with user distribution => {value: count of user state, color: color} - # active: signed in during the last 3 months - # unconfirmed: registered but not confirmed - # dead: not signed in during the last year - # - # ====Returns - # * +hash+ -> hash - def self.user_distribution - active_user = User.where('last_sign_in_at > ?', Date.today - 3.months).count - unconfirmed_user = User.where('confirmed_at IS NULL').count - dead_user = User.where('last_sign_in_at < ?', Date.today - 1.year).count - - 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 }, ...} @@ -669,7 +642,7 @@ class Conference < ApplicationRecord def notify_on_dates_changed? return false unless email_settings.send_on_conference_dates_updated # do not notify unless one of the dates changed - return false unless start_date_changed? || end_date_changed? + return false unless saved_change_to_start_date? || saved_change_to_end_date? # do not notify unless the mail content is set up (email_settings.conference_dates_updated_subject.present? && email_settings.conference_dates_updated_body.present?) @@ -686,7 +659,7 @@ class Conference < ApplicationRecord # do not notify unless we allow a registration 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? + return false unless registration_period.saved_change_to_start_date? || registration_period.saved_change_to_end_date? # do not notify unless the mail content is set up (email_settings.conference_registration_dates_updated_subject.present? && email_settings.conference_registration_dates_updated_body.present?) @@ -1110,20 +1083,19 @@ class Conference < ApplicationRecord end ## - # Helper method. Calculates hash with corresponding colors of event state distribution. + # Helper method. Calculates hash of all event states in a consistent order. # # ====Returns # * +hash+ -> hash - def self.calculate_event_distribution_hash(states) - result = {} - states.each do |key, value| - result[key.capitalize] = - { - 'value' => value, - 'color' => Event.get_state_color(key) - } - end - result + def self.calculate_event_distribution_hash(counts) + return {} if counts.values.sum == 0 + + Hash[ + Event.state_machine.states.collect do |state| + state_name = state.name.to_s + [state_name.capitalize, counts[state_name] || 0] + end + ] end ## @@ -1148,7 +1120,6 @@ class Conference < ApplicationRecord # def create_email_settings build_email_settings - true end ## @@ -1211,6 +1182,12 @@ class Conference < ApplicationRecord result += Array.new(weeks - result.length, sum) end - result + add_week_indices(result) + end + + def add_week_indices(values) + Hash[ + values.collect.with_index { |value, index| ["Wk #{index + 1}", value] } + ] end end diff --git a/app/models/event.rb b/app/models/event.rb index 0b78ebf7..3c9fe4f1 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -44,7 +44,6 @@ class Event < ApplicationRecord 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 @@ -83,6 +82,15 @@ class Event < ApplicationRecord end end + COLORS = { + new: '#0000FF', # blue + withdrawn: '#FF8000', # orange + unconfirmed: '#FFFF00', # yellow + confirmed: '#00FF00', # green + canceled: '#848484', # grey + rejected: '#FF0000' # red + }.freeze + ## # Checkes if the event has a start_time and a room for the selected schedule if there is any # ====Returns @@ -176,16 +184,7 @@ class Event < ApplicationRecord end def self.get_state_color(state) - color = { - new: '#0000FF', # blue - withdrawn: '#FF8000', # orange - confirmed: '#00FF00', # green - unconfirmed: '#FFFF00', # yellow - rejected: '#FF0000', # red - canceled: '#848484' # grey - }[state.to_sym] - - color || '#00FFFF' # azure + COLORS[state.to_sym] || '#00FFFF' # azure end def update_state(transition, mail = false, subject = false, send_mail = false, send_mail_param) diff --git a/app/models/program.rb b/app/models/program.rb index 6c3a3b4a..8db24c6c 100644 --- a/app/models/program.rb +++ b/app/models/program.rb @@ -72,8 +72,8 @@ class Program < ApplicationRecord 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? + after_save :unschedule_unfit_events, if: :saved_change_to_schedule_interval? + after_save :normalize_event_types_length, if: :saved_change_to_schedule_interval? validate :check_languages_format # Returns all event_schedules for the selected schedule ordered by start_time @@ -211,7 +211,6 @@ class Program < ApplicationRecord EventType.create(title: 'Workshop', length: 60, color: '#0000FF', description: 'Interactive hands-on practice', minimum_abstract_length: 0, maximum_abstract_length: 500, program_id: id) - true end ## @@ -227,7 +226,6 @@ class Program < ApplicationRecord DifficultyLevel.create(title: 'Hard', description: 'Events require expert knowledge of the topic.', color: '#EF6E69', program_id: id) - true end ## diff --git a/app/models/registration.rb b/app/models/registration.rb index f7c032ea..84a9aba0 100644 --- a/app/models/registration.rb +++ b/app/models/registration.rb @@ -31,7 +31,7 @@ class Registration < ApplicationRecord validate :registration_to_events_only_if_present validates :accepted_code_of_conduct, acceptance: { - if: -> { conference.code_of_conduct.present? } + if: -> { conference.try(:code_of_conduct).present? } } after_create :set_week, :subscribe_to_conference, :send_registration_mail @@ -76,7 +76,7 @@ class Registration < ApplicationRecord end def registration_limit_not_exceed - if conference.registration_limit > 0 && conference.registrations(:reload).count >= conference.registration_limit + if conference.registration_limit > 0 && conference.registrations.count >= conference.registration_limit errors.add(:base, 'Registration limit exceeded') end end diff --git a/app/models/role.rb b/app/models/role.rb index d759f47d..2be87d7b 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -18,6 +18,6 @@ class Role < ApplicationRecord # Needed to ensure that removing all user from role doesn't remove role. def cancel - false + throw(:abort) end end diff --git a/app/models/survey_question.rb b/app/models/survey_question.rb index 7f3f7750..e1cb0427 100644 --- a/app/models/survey_question.rb +++ b/app/models/survey_question.rb @@ -10,7 +10,7 @@ class SurveyQuestion < ActiveRecord::Base ICONS = { boolean: 'dot-circle-o', choice: 'check-square-o', string: 'edit', text: 'align-left', datetime: 'clock-o', numeric: 'slack' }.freeze validates :title, presence: true - validates :possible_answers, :max_choices, :min_choices, presence: true, if: 'choice?' + validates :possible_answers, :max_choices, :min_choices, presence: true, if: :choice? validates :min_choices, numericality: { greater_than_or_equal_to: 1 }, allow_blank: true validates :max_choices, numericality: { greater_than_or_equal_to: 1 }, allow_blank: true diff --git a/app/models/ticket.rb b/app/models/ticket.rb index d69739ab..ca686115 100644 --- a/app/models/ticket.rb +++ b/app/models/ticket.rb @@ -10,6 +10,8 @@ class Ticket < ApplicationRecord monetize :price_cents, with_model_currency: :price_currency + scope :for_registration, -> { where(registration_ticket: true) } + # This validation is for the sake of simplicity. # If we would allow different currencies per conference we also have to handle convertions between currencies! validate :tickets_of_conference_have_same_currency diff --git a/app/models/track.rb b/app/models/track.rb index 96ad9593..d34bfbef 100644 --- a/app/models/track.rb +++ b/app/models/track.rb @@ -45,7 +45,7 @@ class Track < ApplicationRecord scope :cfp_active, -> { where(cfp_active: true) } scope :self_organized, -> { where.not(submitter: nil) } - state_machine initial: :pending do + state_machine initial: :new do state :new state :to_accept state :accepted diff --git a/app/models/user.rb b/app/models/user.rb index e69cff5c..7c764fa1 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -11,6 +11,7 @@ class User < ApplicationRecord # prevent N+1 queries with has_cached_role? by preloading roles *always* default_scope { preload(:roles) } + has_many :ticket_purchases, dependent: :destroy has_many :physical_tickets, through: :ticket_purchases do def by_conference(conference) where('ticket_purchases.conference_id = ?', conference) @@ -32,6 +33,13 @@ class User < ApplicationRecord # add scope scope :comment_notifiable, ->(conference) {joins(:roles).where('roles.name IN (?)', [:organizer, :cfp]).where('roles.resource_type = ? AND roles.resource_id = ?', 'Conference', conference.id)} + # scopes for user distributions + scope :recent, lambda { + where('last_sign_in_at > ?', Date.today - 3.months).where(is_disabled: false) + } + scope :unconfirmed, -> { where('confirmed_at IS NULL') } + scope :dead, -> { where('last_sign_in_at < ?', Date.today - 1.year) } + # Include default devise modules. Others available are: # :token_authenticatable, :confirmable, # :lockable, :timeoutable and :omniauthable @@ -60,7 +68,6 @@ class User < ApplicationRecord end end has_many :events_registrations, through: :registrations - has_many :ticket_purchases, dependent: :destroy has_many :payments, dependent: :destroy has_many :tickets, through: :ticket_purchases, source: :ticket do def for_registration conference @@ -79,7 +86,9 @@ class User < ApplicationRecord accepts_nested_attributes_for :roles scope :admin, -> { where(is_admin: true) } - scope :active, -> { where(is_disabled: false) } + scope :active, lambda { + where(is_disabled: false) + } validates :email, presence: true @@ -91,6 +100,12 @@ class User < ApplicationRecord validate :biography_limit + DISTRIBUTION_COLORS = { + 'Active' => 'green', + 'Unconfirmed' => 'red', + 'Dead' => 'black' + }.freeze + ## # Checkes if the user attended the event # This is used for events that require registration @@ -152,6 +167,22 @@ class User < ApplicationRecord user end + ## + # Returns a hash with user distribution => {value: count of user state, color: color} + # active: signed in during the last 3 months + # unconfirmed: registered but not confirmed + # dead: not signed in during the last year + # + # ====Returns + # * +hash+ -> hash + def self.distribution + { + 'Active' => User.recent.count, + 'Unconfirmed' => User.unconfirmed.count, + 'Dead' => User.dead.count + } + end + def self.find_for_database_authentication(warden_conditions) conditions = warden_conditions.dup login = conditions.delete(:login) @@ -237,12 +268,14 @@ class User < ApplicationRecord proposals(conference).count end + def self.empty? + User.count == 1 && User.first.email == 'deleted@localhost.osem' + end + private def setup_role - if User.count == 1 && User.first.email == 'deleted@localhost.osem' - self.is_admin = true - end + self.is_admin = true if User.empty? end def touch_events @@ -257,4 +290,8 @@ class User < ApplicationRecord errors.add(:biography, 'is limited to 150 words.') if biography.split.length > 150 end end + + def send_devise_notification(notification, *args) + devise_mailer.send(notification, self, *args).deliver_later + end end diff --git a/app/models/venue.rb b/app/models/venue.rb index 592279ad..5abdcf96 100644 --- a/app/models/venue.rb +++ b/app/models/venue.rb @@ -37,7 +37,7 @@ class Venue < ApplicationRecord 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 name_changed? || street_changed? || city_changed? || country_changed? + return false unless saved_change_to_name? || saved_change_to_street? || saved_change_to_city? || saved_change_to_country? # do not notify unless the mail content is set up (!conference.email_settings.venue_updated_subject.blank? && !conference.email_settings.venue_updated_body.blank?) diff --git a/app/views/admin/booths/_all_booths.csv.haml b/app/views/admin/booths/_all_booths.csv.haml index 7a6f10fd..334918ac 100644 --- a/app/views/admin/booths/_all_booths.csv.haml +++ b/app/views/admin/booths/_all_booths.csv.haml @@ -1,4 +1,4 @@ -- headers = ['Booth ID', +- headers = ["#{(t'booth').capitalize } ID", 'Title', 'Description', 'Reasoning', @@ -6,7 +6,7 @@ 'Submitter Relationship', 'Website Url', 'State'] -= CSV.generate_line ['All booths'] += CSV.generate_line ["All #{(t'booth').pluralize}"] = CSV.generate_line headers - @booths.each do |booth| = CSV.generate_line([booth.id, diff --git a/app/views/admin/booths/_all_booths.pdf.prawn b/app/views/admin/booths/_all_booths.pdf.prawn index 168397e8..df034b79 100644 --- a/app/views/admin/booths/_all_booths.pdf.prawn +++ b/app/views/admin/booths/_all_booths.pdf.prawn @@ -1,6 +1,6 @@ prawn_document(force_download: true, filename: "#{@file_name}.pdf", page_layout: :landscape) do |pdf| booths_array = [] - header_array = ['Booth ID', + header_array = ["#{(t'booth').capitalize } ID", 'Title', 'Description', 'Reasoning', @@ -21,6 +21,6 @@ prawn_document(force_download: true, filename: "#{@file_name}.pdf", page_layout: row << booth.state booths_array << row end - pdf.text "#{@conference.short_title} booths", font_size: 25, align: :center + pdf.text "#{@conference.short_title} #{(t'booth').pluralize}", font_size: 25, align: :center pdf.table booths_array, header: true, cell_style: {size: 8, border_width: 1},column_widths: [45,70,153,152,70,80,105,45] end diff --git a/app/views/admin/booths/_all_booths.xlsx.axlsx b/app/views/admin/booths/_all_booths.xlsx.axlsx index 43f77b49..5a0a1d48 100644 --- a/app/views/admin/booths/_all_booths.xlsx.axlsx +++ b/app/views/admin/booths/_all_booths.xlsx.axlsx @@ -1,9 +1,9 @@ # frozen_string_literal: true -wb.add_worksheet(name: 'all booths') do |sheet| +wb.add_worksheet(name: "all #{(t 'booth').pluralize}") do |sheet| bold_style = wb.styles.add_style(b: true) wrap_text = wb.styles.add_style alignment: {wrap_text: true} - row = ['Booth ID', + row = ["#{(t 'booth').capitalize} ID", 'Title', 'Description', 'Reasoning', diff --git a/app/views/admin/booths/_change_state_dropdown.html.haml b/app/views/admin/booths/_change_state_dropdown.html.haml index 338e43f7..e55fdc35 100644 --- a/app/views/admin/booths/_change_state_dropdown.html.haml +++ b/app/views/admin/booths/_change_state_dropdown.html.haml @@ -2,12 +2,12 @@ - if booth.transition_possible? :accept - if can? :accept, booth - if @conference.booth_limit > 0 - - confirm_message = ' You are able to accept '+ pluralize(@conference.booth_limit - (@conference.booths.accepted.count + @conference.booths.confirmed.count), 'more booth') + " (booth limit set to #{@conference.booth_limit}). Are you sure you want to accept this one?" + - confirm_message = ' You are able to accept '+ pluralize(@conference.booth_limit - (@conference.booths.accepted.count + @conference.booths.confirmed.count), "more #{t'booth'}") + " (#{t'booth'} limit set to #{@conference.booth_limit}). Are you sure you want to accept this one?" - if @conference.email_settings.send_on_booths_acceptance - link = 'Accept with email' - - confirm_message = "By accepting this booth, an email will be sent informing the submitter for the acceptance. You may change the state to \'To accept\' until you are completely sure." + confirm_message + - confirm_message = "By accepting this #{t'booth'}, an email will be sent informing the submitter for the acceptance. You may change the state to \'To accept\' until you are completely sure." + confirm_message - else - - link = 'Accept booth' + - link = "Accept #{t'booth'}" %li= link_to link, accept_admin_conference_booth_path(@conference.short_title, booth), method: :patch ,id: "accept_booth_#{booth.id}", @@ -24,7 +24,7 @@ data: (@conference.email_settings.send_on_booths_rejection ? { confirm: 'By rejecting this booth, an email will be sent informing the submitter about the rejection. You may change the state to \'To reject\' until you are completely sure.'} : nil) - if booth.transition_possible? :to_reject - %li= link_to 'To reject booth', + %li= link_to "To reject #{t'booth'}", to_reject_admin_conference_booth_path(@conference.short_title, booth), method: :patch, id: "to_reject_booth_#{booth.id}" @@ -34,16 +34,16 @@ method: :patch, id: "restart_booth_#{booth.id}" - if booth.transition_possible? :to_accept - %li= link_to 'To accept booth', + %li= link_to "To accept #{t'booth'}", to_accept_admin_conference_booth_path(@conference.short_title, booth), method: :patch, id: "to_accept_booth_#{booth.id}" - if booth.transition_possible? :cancel - %li= link_to 'Cancel booth', + %li= link_to "Cancel #{t'booth'}", cancel_admin_conference_booth_path(@conference.short_title, booth), method: :patch, id: "cancel_booth_#{booth.id}" - if booth.transition_possible? :confirm - %li= link_to 'Confirm booth', + %li= link_to "Confirm #{t'booth'}", confirm_admin_conference_booth_path(@conference.short_title, booth), method: :patch, id: "confirm_booth_#{booth.id}" diff --git a/app/views/admin/booths/_confirmed_booths.csv.haml b/app/views/admin/booths/_confirmed_booths.csv.haml index b5d17eb4..acf7dcc0 100644 --- a/app/views/admin/booths/_confirmed_booths.csv.haml +++ b/app/views/admin/booths/_confirmed_booths.csv.haml @@ -1,4 +1,4 @@ -- headers = ['Booth ID', +- headers = ["#{(t'booth').capitalize } ID", 'Title', 'Description', 'Reasoning', @@ -6,7 +6,7 @@ 'Submitter Relationship', 'Website Url', 'State'] -= CSV.generate_line ['All booths'] += CSV.generate_line ["All #{(t'booth').pluralize}"] = CSV.generate_line headers - @booths.confirmed.each do |booth| = CSV.generate_line([booth.id, diff --git a/app/views/admin/booths/_confirmed_booths.pdf.prawn b/app/views/admin/booths/_confirmed_booths.pdf.prawn index a9750ab9..b3902ff7 100644 --- a/app/views/admin/booths/_confirmed_booths.pdf.prawn +++ b/app/views/admin/booths/_confirmed_booths.pdf.prawn @@ -1,6 +1,6 @@ prawn_document(force_download: true, filename: "#{@file_name}.pdf", page_layout: :landscape) do |pdf| booths_array = [] - header_array = ['Booth ID', + header_array = ["#{(t'booth').capitalize } ID", 'Title', 'Description', 'Reasoning', diff --git a/app/views/admin/booths/_confirmed_booths.xlsx.axlsx b/app/views/admin/booths/_confirmed_booths.xlsx.axlsx index 4d119fae..a6016703 100644 --- a/app/views/admin/booths/_confirmed_booths.xlsx.axlsx +++ b/app/views/admin/booths/_confirmed_booths.xlsx.axlsx @@ -1,9 +1,9 @@ # frozen_string_literal: true -wb.add_worksheet(name: 'all booths') do |sheet| +wb.add_worksheet(name: "all #{(t 'booth').pluralize}") do |sheet| bold_style = wb.styles.add_style(b: true) wrap_text = wb.styles.add_style alignment: {wrap_text: true} - row = ['Booth ID', + row = ["#{(t 'booth').capitalize} ID", 'Title', 'Description', 'Reasoning', diff --git a/app/views/admin/booths/index.html.haml b/app/views/admin/booths/index.html.haml index e135be56..d5c02bdc 100644 --- a/app/views/admin/booths/index.html.haml +++ b/app/views/admin/booths/index.html.haml @@ -2,7 +2,7 @@ .col-md-12 .page-header %h1 - Booths + #{(t'booth').pluralize.capitalize } .pull-right - if can? :read, Booth .btn-group @@ -11,8 +11,8 @@ Export PDF %span.caret %ul.dropdown-menu{ role: 'menu' } - %li= link_to 'All Booths', admin_conference_booths_path(@conference.short_title, format: :pdf, booth_export_option: 'all') - %li= link_to 'Confirmed Booths', admin_conference_booths_path(@conference.short_title, format: :pdf, booth_export_option: 'confirmed') + %li= link_to "All #{(t'booth').pluralize.capitalize }", admin_conference_booths_path(@conference.short_title, format: :pdf, booth_export_option: 'all') + %li= link_to "Confirmed #{(t'booth').pluralize.capitalize }", admin_conference_booths_path(@conference.short_title, format: :pdf, booth_export_option: 'confirmed') .btn-group %button.btn.btn-default.dropdown-toggle{ 'data-toggle' => 'dropdown', type: 'button', class: 'btn btn-success' } Export CSV @@ -29,7 +29,7 @@ %li= link_to 'Confirmed', admin_conference_booths_path(@conference.short_title, format: :xlsx, booth_export_option: 'confirmed') = "(#{@booths.length})" if @booths.any? %p.text-muted - All the booth requests + All the #{t'booth'} requests .row .col-md-12 @@ -37,21 +37,21 @@ - if @conference.booth_limit == 0 %p Set the - = link_to 'Booth limit', edit_admin_conference_path(@conference.short_title) - to make sure you are not accepting more booths than you can accommodate. + = link_to "#{(t'booth').capitalize } limit", edit_admin_conference_path(@conference.short_title) + to make sure you are not accepting more #{(t'booth').pluralize} than you can accommodate. - elsif !@conference.maximum_accepted_booths? %p You cannot accept more than %b - = pluralize(@conference.booth_limit, 'booth') + = pluralize(@conference.booth_limit, "#{t'booth'}") ( - = pluralize(@conference.booths.accepted.count + @conference.booths.confirmed.count, 'accepted booth') + = pluralize(@conference.booths.accepted.count + @conference.booths.confirmed.count, "accepted #{t'booth'}") so far) - else %p - You have reached the maximum number of accepted booths. + You have reached the maximum number of accepted #{(t'booth').pluralize}. ( - = link_to "#{@conference.booth_limit} booths", edit_admin_conference_path(@conference.short_title) + = link_to "#{@conference.booth_limit} #{(t'booth').pluralize}", edit_admin_conference_path(@conference.short_title) ) - if @booths.any? %table.datatable diff --git a/app/views/admin/booths/new.html.haml b/app/views/admin/booths/new.html.haml index 99ec9b20..0cf6adb5 100644 --- a/app/views/admin/booths/new.html.haml +++ b/app/views/admin/booths/new.html.haml @@ -1,3 +1,3 @@ -%h1 New booth +%h1 New #{t'booth'} = render 'booths/form' diff --git a/app/views/admin/cfps/_form.html.haml b/app/views/admin/cfps/_form.html.haml index 178b9033..1cff0645 100644 --- a/app/views/admin/cfps/_form.html.haml +++ b/app/views/admin/cfps/_form.html.haml @@ -7,15 +7,15 @@ .row .col-md-8 = semantic_form_for(cfp, url: cfp_form_url(cfp, conference), - html: { multipart: true }) do |f| + html: { multipart: true, + data: { end_conference: conference.end_date.to_s } }) do |f| = f.input :cfp_type, as: :hidden = 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' } + input_html: { class: 'form-control', + id: 'registration-period-start-datepicker' } = f.input :end_date, as: :string, - input_html: { id: 'registration-period-end-datepicker', - readonly: 'readonly' } + input_html: { class: 'form-control', + id: 'registration-period-end-datepicker' } = f.input :description, hint: markdown_hint, input_html: { rows: 2, data: { provide: 'markdown-editable' } } - if cfp.cfp_type == 'events' diff --git a/app/views/admin/conferences/_doughnut_chart.html.haml b/app/views/admin/conferences/_doughnut_chart.html.haml deleted file mode 100644 index 6ad75cef..00000000 --- a/app/views/admin/conferences/_doughnut_chart.html.haml +++ /dev/null @@ -1,23 +0,0 @@ -.text-center - %h4 #{title} - %canvas.doughnut_chart{ id: "dough_#{title.parameterize.underscore}", 'data-chart' => data.to_json } -- if data - - data.each do |key, value| - %span{ 'style' => "border-bottom: 3px solid #{value['color']}" } #{key}: #{value['value']} - -:javascript - $(document).ready( function(){ - - var d = $("#dough_#{title.parameterize.underscore}"); - var dt = d.get(0).getContext('2d'); - - $(window).resize( respondCanvas ); - - function respondCanvas(){ - dt.canvas.width = 150; - dt.canvas.height = 150; - } - - respondCanvas(); - - }); diff --git a/app/views/admin/conferences/_line_chart.html.haml b/app/views/admin/conferences/_line_chart.html.haml deleted file mode 100644 index 12d825e7..00000000 --- a/app/views/admin/conferences/_line_chart.html.haml +++ /dev/null @@ -1,47 +0,0 @@ -.row - .col-md-12 - .text-center - %h4 - = title -.row - .col-md-12 - .chart_data{ 'data-chart' => "#{y.to_json}", 'data-conferences' => "#{conferences.to_json}", - 'data-deactive' => "#{deactive_conferences.to_json}", 'data-weeks' => "#{x.to_json}", - 'data-active' => "#{active_conferences.to_json}" } - %canvas.line_chart{ id: "line_chart_#{name}", 'data-name' => "#{name}" } -.row - .col-md-12 - .text-center - = unit -.row - .col-md-12 - .conferenceCheckboxes{ id: "#{name}Checkboxes", 'data-name' => "#{name}" } - - if active_conferences && deactive_conferences && conferences && conferences.length > 1 - - active_conferences.each do |conference| - %div - %span{ 'style' => "border-bottom: 3px solid #{conference[:color]};", 'data-chart' => "#{name}" } - %input{ 'type' => 'checkbox', 'name' => "#{conference[:short_title]}", 'checked' => 'checked' } - #{conference[:short_title]} - - deactive_conferences.each do |conference| - %div - %span{ 'style' => "border-bottom: 3px solid #{conference[:color]};", 'data-chart' => "#{name}" } - %input{ 'type' => 'checkbox', 'name' => "#{conference[:short_title]}" } - #{conference[:short_title]} - -:javascript - $(document).ready( function(){ - - var c = $("#line_chart_#{name}"); - var ct = c.get(0).getContext('2d'); - var container = $(c).parent(); - - $(window).resize( respondCanvas ); - - function respondCanvas(){ - c.attr('width', $(container).width() ); - c.attr('height', $(container).height() ); - } - - respondCanvas(); - - }); diff --git a/app/views/admin/conferences/_recent_users.html.haml b/app/views/admin/conferences/_recent_users.html.haml index 83234afa..790e386b 100644 --- a/app/views/admin/conferences/_recent_users.html.haml +++ b/app/views/admin/conferences/_recent_users.html.haml @@ -14,10 +14,7 @@ %td= link_to user.email, admin_user_path(user.id) %td= user.created_at.strftime('%m/%d/%Y') %td - = check_box_tag user.id, user.id, user.confirmed?, - url: "/admin/users/#{user.id}/toggle_confirmation?user[to_confirm]=", - class: 'switch-checkbox', - readonly: true + = user.confirmed? ? 'Yes' : 'No' - else %h5.text-warning.text-center No sign ups! diff --git a/app/views/admin/conferences/edit.html.haml b/app/views/admin/conferences/edit.html.haml index ac90610d..edb8f12b 100644 --- a/app/views/admin/conferences/edit.html.haml +++ b/app/views/admin/conferences/edit.html.haml @@ -28,5 +28,5 @@ = 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.inputs name: 'Booths' do = f.input :booth_limit, as: :number, in: 0..9999, - hint: 'Booth limit is the maximum number of booths that you can accept for this conference. By setting this number (0 no limit) you can be sure that you are not going to accept more booths than the conference can accommodate. You currently have ' + pluralize(@conference.booths.accepted.count, 'accepted booth') +'.' + hint: "#{(t'booth').capitalize } limit is the maximum number of #{(t'booth').pluralize} that you can accept for this conference. By setting this number (0 no limit) you can be sure that you are not going to accept more #{(t'booth').pluralize} than the conference can accommodate. You currently have " + pluralize(@conference.booths.accepted.count, "accepted #{t'booth'}") +'.' = f.action :submit, as: :button, button_html: { class: 'btn btn-primary', data: { confirm: 'Are you sure you want to proceed?' } } diff --git a/app/views/admin/conferences/index.html.haml b/app/views/admin/conferences/index.html.haml index 72d6179d..800e612e 100644 --- a/app/views/admin/conferences/index.html.haml +++ b/app/views/admin/conferences/index.html.haml @@ -1,52 +1,32 @@ -= javascript_include_tag 'Chart.min' .row .col-sm-3.col-xs-3 - = render "shared/big_statistic", + = render "big_statistic", icon: "user", subtitle: "User", value: @total_user, delta: @new_user .col-sm-3.col-xs-3 - = render "shared/big_statistic", + = render "big_statistic", icon: "check-square", subtitle: "Registration", value: @total_reg, delta: @new_reg .col-sm-3.col-xs-3 - = render "shared/big_statistic", + = render "big_statistic", icon: "file-text", subtitle: "Submission", value: @total_submissions, delta: @new_submissions .col-sm-3.col-xs-3 - = render "shared/big_statistic", + = render "big_statistic", icon: "archive", subtitle: "Withdrawn", value: @total_withdrawn, delta: @new_withdrawn, reverse: true .row#registrations .col-md-8 - = render partial: 'line_chart', locals: { title: 'Registrations over time', - name: 'registrations', - conferences: @conferences, - active_conferences: @active_conferences, - deactive_conferences: @deactive_conferences, - y: @registrations, - x: @registration_weeks, - unit: 'weeks' } + = render 'line_chart', title: 'Registrations per week', data: @registrations .col-md-4 - = render partial: 'doughnut_chart', locals: { title: 'Events', data: @event_distribution } + = render 'donut_chart', title: 'Events', + data: @event_distribution, colors: @event_distribution_colors .row#submissions .col-md-8 - = render partial: 'line_chart', locals: { title: 'Submissions over time', - name: 'submissions', - conferences: @conferences, - active_conferences: @active_conferences, - deactive_conferences: @deactive_conferences, - y: @submissions, - x: @cfp_weeks, - unit: 'weeks' } + = render 'line_chart', title: 'Submissions per week', data: @submissions .col-md-4 - = render partial: 'doughnut_chart', locals: { title: 'User', data: @user_distribution } + = render 'donut_chart', title: 'Users', + data: @user_distribution, colors: @user_distribution_colors .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' } + = render 'line_chart', title: 'Tickets sold per week', data: @tickets %br .row .col-md-8 diff --git a/app/views/admin/conferences/show.html.haml b/app/views/admin/conferences/show.html.haml index ed4d0cd1..89daeff5 100644 --- a/app/views/admin/conferences/show.html.haml +++ b/app/views/admin/conferences/show.html.haml @@ -1,21 +1,19 @@ -= javascript_include_tag 'Chart.min' - %h1 %span.fa.fa-tachometer Dashboard for #{@conference.title} %hr .row .col-sm-3.col-xs-3 - = render "shared/big_statistic", + = render "big_statistic", icon: "user", subtitle: "Registration", value: @total_reg, delta: @new_reg .col-sm-3.col-xs-3 - = render "shared/big_statistic", + = render "big_statistic", icon: "check-square", subtitle: "Submission", value: @total_submissions, delta: @new_submissions .col-sm-3.col-xs-3 - = render "shared/big_statistic", + = render "big_statistic", icon: "file-text", subtitle: "Hour", value: @program_length, delta: @new_program_length .col-sm-3.col-xs-3 - = render "shared/big_statistic", + = render "big_statistic", icon: "archive", subtitle: "Withdrawn", value: @total_withdrawn, delta: @new_withdrawn .row @@ -24,37 +22,19 @@ .col-md-8 .row#registrations .col-md-12 - = render partial: 'line_chart', locals: { title: 'Registrations over time', - name: 'registrations', - conferences: [@conference], - active_conferences: [@conference], - deactive_conferences: [], - y: @registrations, - x: @registration_weeks, - unit: 'weeks' } + = render 'line_chart', + title: 'Registrations per week', data: @registrations .row#submissions .col-md-12 - = render partial: 'line_chart', locals: { title: 'Submissions over time', - name: 'submissions', - conferences: @submissions, - active_conferences: @submissions, - deactive_conferences: [], - y: @submissions_data, - x: @cfp_weeks, - unit: 'weeks' } + = render 'line_chart', + title: 'Submissions per week', data: @submissions .col-md-4 - = render partial: 'todo_list', locals: { conference_progress: @conference_progress, - conference: @conference } + = render 'todo_list', + 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' } + = render 'line_chart', + title: 'Tickets sold per week', data: @tickets %br .row .col-md-12#doughnut @@ -75,27 +55,36 @@ .tab-pane.active#distribution_all .row .col-md-4 - = render partial: 'doughnut_chart', locals: {title: 'Event types', data: @event_type_distribution} + = render 'donut_chart', title: 'Event types', + combined_data: @event_type_distribution .col-md-4 - = render partial: 'doughnut_chart', locals: {title: 'Difficulty levels', data: @difficulty_levels_distribution} + = render 'donut_chart', title: 'Difficulty levels', + combined_data: @difficulty_levels_distribution .col-md-4 - = render partial: 'doughnut_chart', locals: {title: 'Tracks', data: @tracks_distribution} + = render 'donut_chart', title: 'Tracks', + combined_data: @tracks_distribution .tab-pane#distribution_confirmed .row .col-md-4 - = render partial: 'doughnut_chart', locals: {title: 'Event types', data: @event_type_distribution_confirmed} + = render 'donut_chart', title: 'Event types', + combined_data: @event_type_distribution_confirmed .col-md-4 - = render partial: 'doughnut_chart', locals: {title: 'Difficulty levels', data: @difficulty_levels_distribution_confirmed} + = render 'donut_chart', title: 'Difficulty levels', + combined_data: @difficulty_levels_distribution_confirmed .col-md-4 - = render partial: 'doughnut_chart', locals: {title: 'Tracks', data: @tracks_distribution_confirmed} + = render 'donut_chart', title: 'Tracks', + combined_data: @tracks_distribution_confirmed .tab-pane#distribution_withdrawn .row .col-md-4 - = render partial: 'doughnut_chart', locals: {title: 'Event types', data: @event_type_distribution_withdrawn} + = render 'donut_chart', title: 'Event types', + combined_data: @event_type_distribution_withdrawn .col-md-4 - = render partial: 'doughnut_chart', locals: {title: 'Difficulty levels', data: @difficulty_levels_distribution_withdrawn} + = render 'donut_chart', title: 'Difficulty levels', + combined_data: @difficulty_levels_distribution_withdrawn .col-md-4 - = render partial: 'doughnut_chart', locals: {title: 'Tracks', data: @tracks_distribution_withdrawn} + = render 'donut_chart', title: 'Tracks', + combined_data: @tracks_distribution_withdrawn .row .col-md-8 diff --git a/app/views/admin/emails/index.html.haml b/app/views/admin/emails/index.html.haml index 7e3b195d..97946a75 100644 --- a/app/views/admin/emails/index.html.haml +++ b/app/views/admin/emails/index.html.haml @@ -114,18 +114,18 @@ = f.input :booths_acceptance_subject = f.input :booths_acceptance_body, input_html: { rows:10, cols: 20 } %a.btn.btn-link.control_label.load_template{ 'data-subject-input-id' => 'email_settings_booths_acceptance_subject', - 'data-subject-text' => 'Your booth has been accepted!', + 'data-subject-text' => "Your #{t'booth'} has been accepted!", 'data-body-input-id' => 'email_settings_booths_acceptance_body', - 'data-body-text' => "Dear {name},\n\nWe are pleased to inform you that your booth request {booth_title} has been accepted for the conference {conference}.\nPlease click the confirm button to let us know you can make it as soon as possible!\n\nFeel free to contact us with any questions or concerns.\n\nWe are looking forward to seeing you there.\n\nBest wishes\n\n{conference} Team"} Load Template + 'data-body-text' => "Dear {name},\n\nWe are pleased to inform you that your #{t'booth'} request {booth_title} has been accepted for the conference {conference}.\nPlease click the confirm button to let us know you can make it as soon as possible!\n\nFeel free to contact us with any questions or concerns.\n\nWe are looking forward to seeing you there.\n\nBest wishes\n\n{conference} Team"} Load Template %a.btn.btn-link.control_label.template_help_link{ 'data-name' => 'booth_acceptance_help' } Show help = render partial: 'help', locals: {id: 'booth_acceptance_help', show_event_variables: false} = f.input :send_on_booths_rejection = f.input :booths_rejection_subject = f.input :booths_rejection_body, input_html: { rows:10, cols:20 } %a.btn.btn-link.control_label.load_template{ 'data-subject-input-id' => 'email_settings_booths_rejection_subject', - 'data-subject-text' => 'Your booth request has been rejected', + 'data-subject-text' => "Your #{t'booth'} request has been rejected", 'data-body-input-id' => 'email_settings_booths_rejection_body', - 'data-body-text' => "Dear {name},\n\nThank you for your booth request {booth_title} for the conference {conference}.\n\nUnfortunately, we are sorry to inform you that your request has been rejected.\n\n\nBest wishes\n\n{conference} Team" } Load Template + 'data-body-text' => "Dear {name},\n\nThank you for your #{t'booth'} request {booth_title} for the conference {conference}.\n\nUnfortunately, we are sorry to inform you that your request has been rejected.\n\n\nBest wishes\n\n{conference} Team" } Load Template %a.btn.btn-link.control_label.template_help_link{ 'data-name' => 'booth_rejection_help' } Show help = render partial: 'help', locals: {id: 'booth_rejection_help', show_event_variables: false} diff --git a/app/views/admin/events/_datatable_row.haml b/app/views/admin/events/_datatable_row.haml index 93f43d77..74a8ccb4 100644 --- a/app/views/admin/events/_datatable_row.haml +++ b/app/views/admin/events/_datatable_row.haml @@ -24,11 +24,15 @@ Unknown submitter %td - - event.speakers_ordered.each do |speaker| - .speaker - = link_to speaker.name, admin_user_path(speaker) - - unless speaker.registrations.for_conference(event.conference) - %span.label.label-danger Unregistered + - if event.speakers.any? + - event.speakers_ordered.each do |speaker| + .speaker + = link_to speaker.name, admin_user_path(speaker) + - unless speaker.registrations.for_conference(event.conference) + %span.label.label-danger Unregistered + - else + .small + No Speaker - if @program.languages.present? %td diff --git a/app/views/admin/events/index.html.haml b/app/views/admin/events/index.html.haml index d547c66b..4944d946 100644 --- a/app/views/admin/events/index.html.haml +++ b/app/views/admin/events/index.html.haml @@ -1,5 +1,3 @@ -= javascript_include_tag 'Chart.min' - .row .col-md-12 .page-header @@ -47,17 +45,14 @@ = f.submit 'Add', class: 'btn btn-primary' .row .col-md-4 - = render 'admin/conferences/doughnut_chart', - title: 'Events state', - data: @event_distribution + = render 'donut_chart', title: 'Events state', + data: @event_distribution, colors: @event_distribution_colors .col-md-4 - = render 'admin/conferences/doughnut_chart', - title: 'Confirmed events scheduled', - data: @scheduled_event_distribution + = render 'donut_chart', title: 'Confirmed events scheduled', + combined_data: @scheduled_event_distribution .col-md-4 - = render 'admin/conferences/doughnut_chart', - title: 'Tracks of confirmed events', - data: @tracks_distribution_confirmed + = render 'donut_chart', title: 'Tracks of confirmed events', + combined_data: @tracks_distribution_confirmed .row .col-md-12 .margin-event-table diff --git a/app/views/admin/events/registrations.html.haml b/app/views/admin/events/registrations.html.haml index 227c0138..70204369 100644 --- a/app/views/admin/events/registrations.html.haml +++ b/app/views/admin/events/registrations.html.haml @@ -11,7 +11,7 @@ for = @event.title - - if @event.room && (@event_registrations.length > @event.room.size) + - if @event.room.try(:size) && (@event_registrations.length > @event.room.size) %b Attention: You have more registrations than the capacity of the room! @@ -32,7 +32,7 @@ %td= event_registration.email %td= event_registration.created_at %td - = check_box_tag @conference.short_title, @event.id, event_registration.attended, class: 'switch-checkbox', url: "/admin/conferences/#{@conference.short_title}/program/events/#{@event.id}/toggle_attendance?events_registration_id=#{event_registration.id}&&event_registration[attended]=" + = check_box_tag @conference.short_title, @event.id, event_registration.attended, class: 'switch-checkbox', url: "#{toggle_attendance_admin_conference_program_event_path(@conference, @event, events_registration_id: event_registration)}&&event_registration[attended]=" %td - if event_registration.registration.attended %i.fa.fa-check.text-success diff --git a/app/views/admin/events/show.html.haml b/app/views/admin/events/show.html.haml index ecf45c2a..4b764838 100644 --- a/app/views/admin/events/show.html.haml +++ b/app/views/admin/events/show.html.haml @@ -69,9 +69,10 @@ %span{ 'class' => [icon_for_todo(progress_status['registered']), 'fa-lg'] } %tr %td - - if @event.speakers.count == 1 + - speakers_count = @event.speakers.count + - if speakers_count == 1 = link_to 'Fill out speaker\'s biography', edit_admin_user_path(@event.speakers.first) - - else + - elsif speakers_count > 1 Fill out speaker's biography: = speaker_links(@event) %td{ 'class' => class_for_todo(progress_status['biographies']) } diff --git a/app/views/admin/lodgings/index.html.haml b/app/views/admin/lodgings/index.html.haml index c2e011f9..67b5e3df 100644 --- a/app/views/admin/lodgings/index.html.haml +++ b/app/views/admin/lodgings/index.html.haml @@ -16,9 +16,9 @@ - else - if lodging.website_link.present? = link_to(lodging.website_link, class: 'thumbnail') do - = image_tag lodging.picture.thumb, class: 'img-responsive img-lodging' + = image_tag lodging.picture.thumb.url, class: 'img-responsive img-lodging' - else - = image_tag lodging.picture.thumb, class: 'img-responsive img-lodging' + = image_tag lodging.picture.thumb.url, class: 'img-responsive img-lodging' .caption %h3.text-center = lodging.name diff --git a/app/views/admin/physical_tickets/index.html.haml b/app/views/admin/physical_tickets/index.html.haml index 88303a50..a1d14cd3 100644 --- a/app/views/admin/physical_tickets/index.html.haml +++ b/app/views/admin/physical_tickets/index.html.haml @@ -1,5 +1,3 @@ -= javascript_include_tag 'Chart.min' - .container .row .col-md-12.page-header @@ -9,11 +7,11 @@ Tickets sold for the conference .row .col-md-4 - = render partial: 'admin/conferences/doughnut_chart', - locals: { title: 'Tickets sold', data: @tickets_sold_distribution } + = render 'donut_chart', title: 'Tickets sold', + combined_data: @tickets_sold_distribution .col-md-4 - = render partial: 'admin/conferences/doughnut_chart', - locals: {title: 'Tickets turnover', data: @tickets_turnover_distribution} + = render 'donut_chart', title: 'Tickets turnover', + combined_data: @tickets_turnover_distribution %br - if @physical_tickets.any? .row diff --git a/app/views/admin/programs/_form.html.haml b/app/views/admin/programs/_form.html.haml index 9b42e2b0..c158453a 100644 --- a/app/views/admin/programs/_form.html.haml +++ b/app/views/admin/programs/_form.html.haml @@ -11,7 +11,7 @@ = 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, input_html: { autofocus: true }, 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?) } + = f.input :voting_start_date, as: :string, input_html: { id: 'datetimepicker-voting_start_date', 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_end_date', value: (f.object.voting_end_date.to_formatted_s(:db_without_seconds) unless f.object.voting_end_date.nil?) } %p.text-right = f.action :submit, as: :button, button_html: {class: 'btn btn-primary'} diff --git a/app/views/admin/registration_periods/_form.html.haml b/app/views/admin/registration_periods/_form.html.haml index 2fe9af8b..c3d3c86c 100644 --- a/app/views/admin/registration_periods/_form.html.haml +++ b/app/views/admin/registration_periods/_form.html.haml @@ -5,7 +5,7 @@ .row .col-md-8 = semantic_form_for(@registration_period, url: admin_conference_registration_period_path(@conference.short_title)) 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 :start_date, as: :string, input_html: { id: 'registration-period-start-datepicker', start_date: @conference.start_date, end_date: @conference.end_date } + = f.input :end_date, as: :string, input_html: { id: 'registration-period-end-datepicker' } %p.text-right = f.submit 'Save Registration Period', class: 'btn btn-primary' diff --git a/app/views/admin/registration_periods/show.html.haml b/app/views/admin/registration_periods/show.html.haml index 243220ec..51bc8d37 100644 --- a/app/views/admin/registration_periods/show.html.haml +++ b/app/views/admin/registration_periods/show.html.haml @@ -8,29 +8,38 @@ .row .col-md-8 %dl.dl-horizontal - %dt - Start Date - %dd - = @registration_period.start_date - %dt - End Date - %dd - = @registration_period.end_date + %dt Start Date + %dd= @registration_period.start_date + %dt End Date + %dd= @registration_period.end_date + %dt Ticket required? + %dd= @conference.tickets.for_registration.any? ? 'Yes' : 'No' + +.row + .col-md-12 + %p + If you would like to require a ticket purchase for registration, at least + one + = link_to 'ticket', admin_conference_tickets_path(@conference) + must be set as a registration ticket, and the registration process + will not proceed without the purchase (or selection of a free) single + registration ticket. + %p + To make ticketing optional, do not mark any + = link_to 'tickets', admin_conference_tickets_path(@conference) + as registration tickets, and registration can proceed without them. .row .col-md-12.text-right - - if @registration_period - - if can? :update, @registration_period - = link_to 'Edit', edit_admin_conference_registration_period_path, class: 'btn btn-primary' - - if can? :destroy, @registration_period - = link_to 'Delete', admin_conference_registration_period_path, - method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-danger' - - else - - if @conference.tickets.for_registration.empty? - .h3.text-left - No Registration Tickets! - %small - = link_to 'Create registration tickets', new_admin_conference_ticket_path - before creating the registration period. - - else - - if can? :create, @conference.build_registration_period - = link_to 'New Registration Period', new_admin_conference_registration_period_path, class: 'btn btn-primary' + .btn-group{ role: 'group' } + - if @registration_period + - if can? :update, @registration_period + = link_to 'Edit', edit_admin_conference_registration_period_path, + class: 'btn btn-primary' + - if can? :destroy, @registration_period + = link_to 'Delete', admin_conference_registration_period_path, + method: :delete, data: { confirm: 'Are you sure?' }, + class: 'btn btn-danger' + - elsif 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/registrations/index.csv.haml b/app/views/admin/registrations/index.csv.haml index eace3122..76f01211 100644 --- a/app/views/admin/registrations/index.csv.haml +++ b/app/views/admin/registrations/index.csv.haml @@ -1,4 +1,16 @@ -- headers = ['Name', 'Email'] +- headers = ['Attended', + 'Name', + 'Nickname', + 'Affilιation', + 'Email', + 'Arrival', + 'Departure'] = CSV.generate_line headers - @registrations.each do |registration| - = CSV.generate_line([registration.name, registration.email]) \ No newline at end of file + = CSV.generate_line([registration.attended ? 'X' : '', + registration.name, + registration.nickname, + registration.affiliation, + registration.email, + registration.arrival.to_s, + registration.departure.to_s]) diff --git a/app/views/admin/registrations/index.html.haml b/app/views/admin/registrations/index.html.haml index 699d5a9f..8ea544d8 100644 --- a/app/views/admin/registrations/index.html.haml +++ b/app/views/admin/registrations/index.html.haml @@ -1,5 +1,3 @@ -= javascript_include_tag 'Chart.min' - .row .col-md-12 .page-header @@ -14,10 +12,12 @@ %p.text-muted All the people who registered to your event .col-md-4 - = render partial: 'admin/conferences/doughnut_chart', locals: {title: 'Affiliation', data: @affiliation_distribution} + = render 'donut_chart', title: 'Affiliation', + combined_data: @affiliation_distribution - unless @conference.pending? .col-md-4 - = render partial: 'admin/conferences/doughnut_chart', locals: {title: 'Attended registrations', data: @registration_distribution} + = render 'donut_chart', title: 'Attended registrations', + combined_data: @registration_distribution .row .col-md-12 %div.margin-event-table diff --git a/app/views/admin/reports/_all_events.html.haml b/app/views/admin/reports/_all_events.html.haml index 87ed9817..712d4ad7 100644 --- a/app/views/admin/reports/_all_events.html.haml +++ b/app/views/admin/reports/_all_events.html.haml @@ -27,10 +27,14 @@ %td = link_to event.title, edit_admin_conference_program_event_path(@conference.short_title, event) %br - .small - (Presented by - = speaker_links(event) - ) + - if(event.speakers.any?) + .small + (Presented by + = speaker_links(event) + ) + - else + .small + (No speaker) - %w(registered biographies commercials subtitle difficulty_level).each do |info| %td{'data-order' => "#{progress_status[info]}"} diff --git a/app/views/admin/reports/_events_without_commercials.html.haml b/app/views/admin/reports/_events_without_commercials.html.haml index a9447f1d..8f26cb99 100644 --- a/app/views/admin/reports/_events_without_commercials.html.haml +++ b/app/views/admin/reports/_events_without_commercials.html.haml @@ -18,4 +18,8 @@ %td= event.id %td= link_to event.title, edit_admin_conference_program_event_path(@conference.short_title, event) %td - = speaker_links(event) + - if(event.speakers.any?) + = speaker_links(event) + - else + .small + (No speaker) diff --git a/app/views/admin/schedules/_event.html.haml b/app/views/admin/schedules/_event.html.haml index 20158689..9df56a39 100644 --- a/app/views/admin/schedules/_event.html.haml +++ b/app/views/admin/schedules/_event.html.haml @@ -1,30 +1,29 @@ -- cache [:admin, @conference, @program, :schedule, event] do - - cells_length = event.event_type.length / @program.schedule_interval - / this height fits the room cells - - compact_grid = @program.schedule_interval < 15 - - single_cell_height = compact_grid ? 32 : 58 - - height = (cells_length * single_cell_height) - - height -= 23 unless compact_grid - / subtracting the padding before calculate the number of lines - - lines = (height - 7) / 23 - - color = event.track.try(:color).present? ? event.track.try(:color) : 'FFFFFF' - - non_schedulable = event_schedule_id && (EventSchedule.find(event_schedule_id).schedule != @schedule) - .schedule-event{ style: "height: #{height}px; background-color: #{color}; color: #{contrast_color(color)}", | - id: "event-#{event.id}", | - event_id: event.id, | - length: cells_length, | - event_schedule_id: event_schedule_id, | - class: "#{'compact' if compact_grid} #{'non_schedulable' if non_schedulable}" } - .schedule-event-text{ style: "-webkit-line-clamp: #{lines}; height: #{lines * 23}px;"} - %span.schedule-event-delete-button{ onclick: "Schedule.remove(\'event-#{event.id}\');" } X - %b - = link_to(event.id, admin_conference_program_event_path(@conference, event)) - = event.speakers.collect(&:name).to_sentence - = ':' - = event.title - - if event.difficulty_level - %span.label.label-default= event.difficulty_level.title - - if event.event_type - %span.label.label-default= event.event_type.title - - if event.track - %span.label.label-default= event.track.short_name +- cells_length = event.event_type.length / @program.schedule_interval +/ this height fits the room cells +- compact_grid = @program.schedule_interval < 15 +- single_cell_height = compact_grid ? 32 : 58 +- height = (cells_length * single_cell_height) +- height -= 23 unless compact_grid +/ subtracting the padding before calculate the number of lines +- lines = (height - 7) / 23 +- color = event.track.try(:color).present? ? event.track.try(:color) : 'FFFFFF' +- non_schedulable = event_schedule_id && (EventSchedule.find(event_schedule_id).schedule != @schedule) +.schedule-event{ style: "height: #{height}px; background-color: #{color}; color: #{contrast_color(color)}", | + id: "event-#{event.id}", | + event_id: event.id, | + length: cells_length, | + event_schedule_id: event_schedule_id, | + class: "#{'compact' if compact_grid} #{'non_schedulable' if non_schedulable}" } + .schedule-event-text{ style: "-webkit-line-clamp: #{lines}; height: #{lines * 23}px;"} + %span.schedule-event-delete-button{ onclick: "Schedule.remove(\'event-#{event.id}\');" } X + %b + = link_to(event.id, admin_conference_program_event_path(@conference, event)) + = event.speakers.collect(&:name).to_sentence + = ':' + = event.title + - if event.difficulty_level + %span.label.label-default= event.difficulty_level.title + - if event.event_type + %span.label.label-default= event.event_type.title + - if event.track + %span.label.label-default= event.track.short_name diff --git a/app/views/admin/splashpages/_form.html.haml b/app/views/admin/splashpages/_form.html.haml index 1d15b38c..3db1e9ea 100644 --- a/app/views/admin/splashpages/_form.html.haml +++ b/app/views/admin/splashpages/_form.html.haml @@ -8,6 +8,13 @@ .col-md-12 = f.inputs name: 'Components' do %ul.fa-ul + %li + %th + %button.btn.btn-default#select-all{ type: "button" } + Select All + %th + %button.btn.btn-default#unselect-all{ type: "button" } + Unselect All %li = f.input :include_cfp, label: 'Display call for papers and call for tracks, while open', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_cfp) } %li @@ -17,7 +24,7 @@ %li = f.input :include_tracks, label: 'Include confirmed tracks', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_tracks) } %li - = f.input :include_booths, label: 'Include confirmed booths', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_booths) } + = f.input :include_booths, label: "Include confirmed #{(t'booth').pluralize}", input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_booths) } %li = f.input :include_registrations, label: 'Display the registration period', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_registrations) } @@ -45,3 +52,15 @@ .col-md-12 %p.text-right = f.submit 'Save Changes', class: 'btn btn-primary' + +:javascript + $(document).ready(function(){ + $('#select-all').click(function(event) { + var parent = $(this).parents('.inputs:last'); + parent.find('.input.checkbox input[type=checkbox]').prop('checked',true); + }); + $('#unselect-all').click(function(event) { + var parent = $(this).parents('.inputs:last'); + parent.find('.input.checkbox input[type=checkbox]').prop('checked',false); + }); + }); diff --git a/app/views/admin/splashpages/show.html.haml b/app/views/admin/splashpages/show.html.haml index aedd4aff..a9046fdc 100644 --- a/app/views/admin/splashpages/show.html.haml +++ b/app/views/admin/splashpages/show.html.haml @@ -26,7 +26,7 @@ Include confirmed tracks %li %i{ class: "fa-li #{icon_for_todo @splashpage.include_booths?}" } - Include confirmed booths + Include confirmed #{(t'booth').pluralize} %li %i{ class: "fa-li #{icon_for_todo @splashpage.include_registrations?}" } Display the registration period diff --git a/app/views/admin/sponsors/_form.html.haml b/app/views/admin/sponsors/_form.html.haml index c465fc48..5e475714 100644 --- a/app/views/admin/sponsors/_form.html.haml +++ b/app/views/admin/sponsors/_form.html.haml @@ -10,7 +10,7 @@ .col-md-8 = semantic_form_for(@sponsor, url: (@sponsor.new_record? ? admin_conference_sponsors_path : admin_conference_sponsor_path(@conference.short_title, @sponsor))) do |f| = f.input :name, input_html: { autofocus: true } - = f.input :description + = f.input :description, input_html: { rows: 5, cols: 20, data: { provide: 'markdown-editable' } }, hint: markdown_hint = image_tag f.object.picture.thumb.url if f.object.picture? = f.input :picture = f.input :website_url diff --git a/app/views/admin/sponsors/index.html.haml b/app/views/admin/sponsors/index.html.haml index d2fc512c..95643ada 100644 --- a/app/views/admin/sponsors/index.html.haml +++ b/app/views/admin/sponsors/index.html.haml @@ -24,7 +24,7 @@ %td = sponsor.name %td - = truncate(sponsor.description) + = truncate(markdown(sponsor.description)) %td = sponsor.website_url %td diff --git a/app/views/admin/surveys/_survey_stats.html.haml b/app/views/admin/surveys/_survey_stats.html.haml index b9336f4a..e551a7d1 100644 --- a/app/views/admin/surveys/_survey_stats.html.haml +++ b/app/views/admin/surveys/_survey_stats.html.haml @@ -1,6 +1,3 @@ -= javascript_include_tag "//www.google.com/jsapi", "chartkick" -= javascript_include_tag 'chartkick' - = bar_chart @survey.survey_questions.map{ |q| [q.title, q.survey_replies.count] } - @survey.survey_questions.each.with_index(1) do |survey_question, question_index| diff --git a/app/views/admin/tracks/_form.html.haml b/app/views/admin/tracks/_form.html.haml index 36ff5734..cfdd9bf3 100644 --- a/app/views/admin/tracks/_form.html.haml +++ b/app/views/admin/tracks/_form.html.haml @@ -12,8 +12,8 @@ = f.input :name, input_html: { autofocus: true } = 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 :start_date, as: :string, input_html: { id: 'registration-period-start-datepicker', start_date: @conference.start_date, end_date: @conference.end_date, readonly: 'readonly', required: @track.self_organized_and_accepted_or_confirmed? } - = f.input :end_date, as: :string, input_html: { id: 'registration-period-end-datepicker', readonly: 'readonly', required: @track.self_organized_and_accepted_or_confirmed? } + = f.input :start_date, as: :string, input_html: { id: 'registration-period-start-datepicker', start_date: @conference.start_date, end_date: @conference.end_date, required: @track.self_organized_and_accepted_or_confirmed? } + = f.input :end_date, as: :string, input_html: { id: 'registration-period-end-datepicker', required: @track.self_organized_and_accepted_or_confirmed? } - if @conference.venue.try(:rooms).present? = f.input :room, as: :select, collection: (@conference.venue.rooms).map {|room| ["#{room.name}", room.id]}, include_blank: true, label: 'Room', input_html: { class: 'select-help-toggle', required: @track.self_organized_and_accepted_or_confirmed? } - else diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml index 9de061d4..40ec8a7a 100644 --- a/app/views/admin/users/_form.html.haml +++ b/app/views/admin/users/_form.html.haml @@ -6,12 +6,12 @@ Confirmed? - if can? :toggle_confirmation, @user = check_box_tag @user.id, @user.id, @user.confirmed?, - url: "/admin/users/#{@user.id}/toggle_confirmation?user[to_confirm]=", + url: "#{toggle_confirmation_admin_user_path(@user.id)}?user[to_confirm]=", class: 'switch-checkbox', readonly: false - else = check_box_tag @user.id, @user.id, @user.confirmed?, - url: "/admin/users/#{@user.id}/toggle_confirmation?user[to_confirm]=", + url: "#{toggle_confirmation_admin_user_path(@user.id)}?user[to_confirm]=", class: 'switch-checkbox', readonly: true = f.input :is_admin, hint: 'An admin can create a new conference, manage users and make other users admins.' diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index 11933454..c9048be4 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -36,12 +36,12 @@ %td - if can? :toggle_confirmation, @user = check_box_tag @user.id, @user.id, @user.confirmed?, - url: "/admin/users/#{@user.id}/toggle_confirmation?user[to_confirm]=", + url: "#{toggle_confirmation_admin_user_path(@user)}?user[to_confirm]=", class: 'switch-checkbox', readonly: false - else = check_box_tag @user.id, @user.id, @user.confirmed?, - url: "/admin/users/#{@user.id}/toggle_confirmation?user[to_confirm]=", + url: "#{toggle_confirmation_admin_user_path(@user)}?user[to_confirm]=", class: 'switch-checkbox', readonly: true - else 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 bd06c92a..1728b999 100644 --- a/app/views/admin/versions/_object_desc_and_link.html.haml +++ b/app/views/admin/versions/_object_desc_and_link.html.haml @@ -79,8 +79,8 @@ = link_to (current_or_last_object_state('Event', object.event_id).try(:title) || 'deleted'), admin_conference_program_event_path(conference_short_title, object.event_id) in - = link_to "Schedule #{event_schedule.schedule_id}", - admin_conference_schedule_path(conference_short_title, event_schedule.schedule_id) + = link_to "Schedule #{version.item.schedule_id}", + admin_conference_schedule_path(conference_short_title, version.item.schedule_id) - when 'Schedule' = link_if_alive version, "Schedule #{version.item_id}", @@ -102,7 +102,7 @@ conference - when 'Booth' - = 'booth' + = t 'booth' = link_if_alive version, object.title, admin_conference_booth_path(conference_id: Conference.find(version.conference_id).short_title, id: version.item_id ), conference diff --git a/app/views/shared/_big_statistic.haml b/app/views/application/_big_statistic.haml similarity index 100% rename from app/views/shared/_big_statistic.haml rename to app/views/application/_big_statistic.haml diff --git a/app/views/application/_donut_chart.haml b/app/views/application/_donut_chart.haml new file mode 100644 index 00000000..351ff216 --- /dev/null +++ b/app/views/application/_donut_chart.haml @@ -0,0 +1,16 @@ +:ruby + combined_data ||= {} + data ||= chart_values(combined_data) + colors ||= chart_colors(combined_data) + + options = { + donut: true, + legend: 'bottom', + download: true, + messages: { empty: 'No data' } + } + options[:colors] = colors if colors.present? + +.text-center + %h4= title + = pie_chart data, options diff --git a/app/views/application/_line_chart.html.haml b/app/views/application/_line_chart.html.haml new file mode 100644 index 00000000..b3dbf7be --- /dev/null +++ b/app/views/application/_line_chart.html.haml @@ -0,0 +1,15 @@ +:ruby + options = { + legend: 'bottom', + download: true, + messages: { empty: 'No data' } + } + +.row + .col-md-12 + .text-center + %h4 + = title +.row + .col-md-12 + = line_chart data, options diff --git a/app/views/booths/_form.html.haml b/app/views/booths/_form.html.haml index 4f5b6018..583db3d9 100644 --- a/app/views/booths/_form.html.haml +++ b/app/views/booths/_form.html.haml @@ -17,9 +17,9 @@ %p.text-right - if @booth.new_record? - = f.submit 'Create Booth Request', class: 'btn btn-success' + = f.submit "Create #{(t'booth').capitalize } Request", class: 'btn btn-success' - else - = f.submit 'Update Booth Request', class: 'btn btn-success' + = f.submit "Update #{(t'booth').capitalize } Request", class: 'btn btn-success' :javascript $(document).ready(function() { diff --git a/app/views/booths/index.html.haml b/app/views/booths/index.html.haml index 3ec4c222..a1b37cc1 100644 --- a/app/views/booths/index.html.haml +++ b/app/views/booths/index.html.haml @@ -2,7 +2,7 @@ .row .col-md-12.page-header %h1 - Your booth requests for + Your #{t'booth'} requests for = @conference.title .row .col-md-12 @@ -48,4 +48,4 @@ restart_conference_booth_path(@conference.short_title, booth), method: :patch, class: 'btn btn-mini btn-success', id: "restart_booth_#{booth.id}" .pull-right - = link_to 'Add Booth', new_conference_booth_path(@conference.short_title), class: 'button btn btn-primary' + = link_to "Add #{(t'booth').capitalize }", new_conference_booth_path(@conference.short_title), class: 'button btn btn-primary' diff --git a/app/views/booths/new.html.haml b/app/views/booths/new.html.haml index 169efd17..6713d312 100644 --- a/app/views/booths/new.html.haml +++ b/app/views/booths/new.html.haml @@ -1,4 +1,4 @@ .container - %h1 Request a booth + %h1 Request a #{t'booth'} = render 'form' diff --git a/app/views/conference_registrations/_registration_info.html.haml b/app/views/conference_registrations/_registration_info.html.haml index 2945a16e..a81f385d 100644 --- a/app/views/conference_registrations/_registration_info.html.haml +++ b/app/views/conference_registrations/_registration_info.html.haml @@ -27,7 +27,7 @@ = f.inputs 'Your Travel Info' do - = f.input :arrival, as: :string, label: 'Your arrival time', hint: "Leave blank if not sure", input_html: { value: (f.object.arrival.to_formatted_s(:db_without_seconds) unless f.object.arrival.nil?), id: 'registration-arrival-datepicker',start_date: @conference.start_date,end_date: @conference.end_date} - = f.input :departure, as: :string, label: 'Your departure time', hint: "Leave blank if not sure", input_html: { value: (f.object.departure.to_formatted_s(:db_without_seconds) unless f.object.departure.nil?), id: 'registration-departure-datepicker'} + = f.input :arrival, as: :string, label: 'Your arrival time', hint: "Leave blank if not sure", input_html: { value: (f.object.arrival.to_formatted_s(:db_without_seconds) unless f.object.arrival.nil?), id: 'registration-arrival-datepicker',start_date: @conference.start_date,end_date: @conference.end_date } + = f.input :departure, as: :string, label: 'Your departure time', hint: "Leave blank if not sure", input_html: { value: (f.object.departure.to_formatted_s(:db_without_seconds) unless f.object.departure.nil?), id: 'registration-departure-datepicker' } = render 'conferences/code_of_conduct', organization: @conference.organization diff --git a/app/views/conference_registrations/show.html.haml b/app/views/conference_registrations/show.html.haml index 8ed24d0d..4bde4a41 100644 --- a/app/views/conference_registrations/show.html.haml +++ b/app/views/conference_registrations/show.html.haml @@ -97,37 +97,48 @@ - if @conference.tickets.visible.any? .row .col-md-12 - -if @tickets.any? - %h4 - %span.fa-stack - %i.fa.fa-square-o.fa-stack-2x - %i.fa.fa-ticket.fa-stack-1x - Ticket Purchases - = "(#{@tickets.first.price.symbol}#{humanized_money @total_price})" - %ul - .col-md-12 - - @ticket_payments.each_pair do |ticket_id, tickets| - %li - = @total_quantity[ticket_id] - = tickets.first.title - = word_pluralize(@total_quantity[ticket_id], 'Ticket') - for - = tickets.first.price.symbol - = humanized_money @total_price_per_ticket[ticket_id] - %br + %h4 + %span.fa-stack + %i.fa.fa-square-o.fa-stack-2x + %i.fa.fa-ticket.fa-stack-1x + Tickets - if @tickets.any? - .btn-group - = link_to 'View all tickets', conference_physical_tickets_path(@conference.short_title), class: "btn btn-success" - = link_to 'Get more tickets', conference_tickets_path(@conference.short_title), class: "btn btn-default" + Total Purchased: + = "(#{@tickets.first.price.symbol}#{humanized_money @total_price})" + %ul + .col-md-12 + - @ticket_payments.each_pair do |ticket_id, tickets| + %li + = @total_quantity[ticket_id] + = tickets.first.title + = word_pluralize(@total_quantity[ticket_id], 'Ticket') + for + = tickets.first.price.symbol + = humanized_money @total_price_per_ticket[ticket_id] + %br + .btn-group{ role: 'group' } + = link_to 'View all tickets', + conference_physical_tickets_path(@conference.short_title), + class: 'btn btn-success' + = link_to 'Get more tickets', + conference_tickets_path(@conference.short_title), + class: 'btn btn-default' - else - You haven't bought any tickets. - = link_to 'Please get some tickets to support us!', conference_tickets_path(@conference.short_title) %p - (Your participation won't be valid without getting a registration ticket) + You haven't bought any tickets. + = link_to 'Please get some tickets to support us!', conference_tickets_path(@conference.short_title) + - if @conference.tickets.for_registration.any? + %p + %em + Your participation won't be valid without getting a + registration ticket. + = link_to 'Get tickets', + conference_tickets_path(@conference.short_title), + class: 'btn btn-default' .row .col-md-12 - -if @registration + - if @registration .btn-group-vertical.pull-right = link_to 'Edit your Registration', edit_conference_conference_registration_path(@conference.short_title), class: 'btn btn-success', disabled: @conference.end_date < Date.today - if @tickets.any? diff --git a/app/views/conferences/_booths.haml b/app/views/conferences/_booths.haml index da14526e..026af2fc 100644 --- a/app/views/conferences/_booths.haml +++ b/app/views/conferences/_booths.haml @@ -1,6 +1,6 @@ .row .col-md-12 - %h3.text-center Booths + %h3.text-center "#{(t'booth').pluralize.capitalize }" .row.row-centered - booths.each do |booth| .col-md-2.col-sm-2.col-centered.col-top.booth diff --git a/app/views/conferences/_call_for_booths.haml b/app/views/conferences/_call_for_booths.haml index 7738fad7..5e81e7e8 100644 --- a/app/views/conferences/_call_for_booths.haml +++ b/app/views/conferences/_call_for_booths.haml @@ -1,12 +1,12 @@ - cache [conference_id, call, '#splash#callforbooths'] do .col-md-4.col-sm-4.text-center %h2 - Call for Booths + Call for #{(t'booth').pluralize.capitalize } %p.lead - We are now accepting custom booth requests! + We are now accepting custom #{t'booth'} requests! %p - Would you like to request a new booth? - The submission period for booth requests is open + Would you like to request a new #{t'booth'}? + The submission period for #{t'booth'} requests is open %em = date_string(call.start_date, call.end_date) + '.' %b @@ -14,6 +14,6 @@ = pluralize(call.remaining_days, 'day') left! %p.cta-button - = link_to("Submit your request for booth", + = link_to("Submit your request for #{t'booth'}", new_conference_booth_path(conference_id), class: 'btn btn-success btn-lg text-center') diff --git a/app/views/conferences/_conference_details.html.haml b/app/views/conferences/_conference_details.html.haml index 1de55697..08b73023 100644 --- a/app/views/conferences/_conference_details.html.haml +++ b/app/views/conferences/_conference_details.html.haml @@ -41,11 +41,12 @@ - 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' - elsif can? :new, conference.program.events.new - = link_to "Submit Proposal", new_conference_program_proposal_path(conference.short_title), class: 'btn btn-default' + - if conference.program.cfp_open? + = link_to "Submit Proposal", new_conference_program_proposal_path(conference.short_title), class: 'btn btn-default' - if current_user && current_user.booths.where(conference_id: conference.id).count > 0 - = link_to 'My Booth Requests', conference_booths_path(conference.short_title), class: 'btn btn-default' + = link_to "My #{(t'booth').capitalize } Requests", conference_booths_path(conference.short_title), class: 'btn btn-default' - elsif can? :new, conference.booths.new - = link_to 'Request Booth', new_conference_booth_path(conference.short_title), class: 'btn btn-default' + = link_to "Request #{(t'booth').capitalize }", new_conference_booth_path(conference.short_title), class: 'btn btn-default' - if current_user.nil? || !current_user.subscribed?(conference) = link_to 'Subscribe', conference_subscriptions_path(conference.short_title), method: :post, class: 'btn btn-default' - else diff --git a/app/views/conferences/_modal_description.haml b/app/views/conferences/_modal_description.haml index 7fe4173b..1c66b67d 100644 --- a/app/views/conferences/_modal_description.haml +++ b/app/views/conferences/_modal_description.haml @@ -18,6 +18,6 @@ - if object.picture? = image_tag get_logo(object), class: img_classes %p.description - = object.description + = markdown(object.description) .modal-footer = link_to nil, object.website_url, target: '_blank' diff --git a/app/views/conferences/_new_install.html.haml b/app/views/conferences/_new_install.html.haml new file mode 100644 index 00000000..1ec2bd02 --- /dev/null +++ b/app/views/conferences/_new_install.html.haml @@ -0,0 +1,21 @@ +.row + .col-md-12 + .well + %h1 + Welcome to your new + = link_to('https://osem.io') do + Open Source Event Manager + installation! + %p + The first user to + - if ENV['OSEM_ICHAIN_ENABLED'] == 'true' + = link_to(new_ichain_registration_path('user')) do + sign up + - else + = link_to(new_registration_path('user')) do + sign up + will the be administrator of it. + %p + We hope you enjoy using OSEM, if you have any question don't hesitate to + = link_to('http://osem.io/#contact') do + contact us! diff --git a/app/views/conferences/index.html.haml b/app/views/conferences/index.html.haml index a3735478..5382989c 100644 --- a/app/views/conferences/index.html.haml +++ b/app/views/conferences/index.html.haml @@ -5,7 +5,7 @@ %h2 Upcoming Conferences - @current.each do |conference| = render '/conferences/conference_details', conference: conference - -if @antiquated and @antiquated.any? + - if @antiquated and @antiquated.any? .row .col-md-12 %p.text-right @@ -18,6 +18,8 @@ #antiquated.collapse - @antiquated.each do |conference| = render '/conferences/conference_details', conference: conference + - if @antiquated.empty? && @current.empty? && User.empty? + = render partial: 'new_install' -content_for :script_body do :javascript diff --git a/app/views/conferences/show.html.haml b/app/views/conferences/show.html.haml index 65db8bbc..e8f64db3 100644 --- a/app/views/conferences/show.html.haml +++ b/app/views/conferences/show.html.haml @@ -64,22 +64,21 @@ = render 'social_media', contact: @conference.contact = render 'footer' -- cache [@conference.color, '#splash#inlinejs'] do - - content_for :script_head do - :javascript - var triangle_tcs = tinycolor("#{h(@conference.color)}").monochromatic(); - var triangle_colors = triangle_tcs.map(function(t) { - return t.toHexString(); - }); - $(function () { - $(document).ready(function() { - var triangle_width = document.body.clientWidth; - var triangle_height = ($( "#banner" ).height() + 200 ); - var pattern = Trianglify({ width: triangle_width, - height: triangle_height, - cell_size: 100, - x_colors: triangle_colors - }); - $('#banner').css('background-image', 'url("' + pattern.png() + '")'); - }); +- content_for :script_head do + :javascript + var triangle_tcs = tinycolor("#{h(@conference.color)}").monochromatic(); + var triangle_colors = triangle_tcs.map(function(t) { + return t.toHexString(); + }); + $(function () { + $(document).ready(function() { + var triangle_width = document.body.clientWidth; + var triangle_height = ($( "#banner" ).height() + 200 ); + var pattern = Trianglify({ width: triangle_width, + height: triangle_height, + cell_size: 100, + x_colors: triangle_colors + }); + $('#banner').css('background-image', 'url("' + pattern.png() + '")'); }); + }); diff --git a/app/views/devise/registrations/edit.html.haml b/app/views/devise/registrations/edit.html.haml index e3100b6c..928c292f 100644 --- a/app/views/devise/registrations/edit.html.haml +++ b/app/views/devise/registrations/edit.html.haml @@ -9,7 +9,7 @@ = f.input :username, required: false, input_html: { autocomplete: 'off' } = f.input :email, required: false, input_html: { autocomplete: 'off' } = f.input :email_public, - hint: "Do you want to your email address publicly? (On sessions, registration lists, etc.)" + hint: "Do you want your email address to appear publicly? (e.g. on sessions, registration lists, etc.)" = f.input :password, hint: "(Leave blank if you don't want to change it)", input_html: { autocomplete: 'off' } = f.input :password_confirmation, input_html: { autocomplete: 'off' } = f.inputs name: 'OpenID' do diff --git a/app/views/layouts/_admin_sidebar.html.haml b/app/views/layouts/_admin_sidebar.html.haml index c6da29b0..78523bc7 100644 --- a/app/views/layouts/_admin_sidebar.html.haml +++ b/app/views/layouts/_admin_sidebar.html.haml @@ -120,7 +120,7 @@ %li = link_to admin_conference_booths_path(@conference.short_title) do %span.fa.fa-shopping-bag - Booths + = (t'booth').pluralize.capitalize - if can? :update, @conference.email_settings %li{class: active_nav_li(admin_conference_emails_path(@conference.short_title))} = link_to(admin_conference_emails_path(@conference.short_title)) do diff --git a/app/views/layouts/_user_menu.html.haml b/app/views/layouts/_user_menu.html.haml index 30e1d27f..5465a66a 100644 --- a/app/views/layouts/_user_menu.html.haml +++ b/app/views/layouts/_user_menu.html.haml @@ -38,7 +38,7 @@ %li = link_to (conference_booths_path(@conference.short_title)) do %span.fa.fa-shopping-bag - My Booth Requests + My #{(t'booth').capitalize } Requests %li - if ENV['OSEM_ICHAIN_ENABLED'] == 'true' = link_to(destroy_user_ichain_session_path, method: 'delete') do diff --git a/app/views/layouts/application.haml b/app/views/layouts/application.html.haml similarity index 98% rename from app/views/layouts/application.haml rename to app/views/layouts/application.html.haml index 0c8f6201..d4c194b9 100644 --- a/app/views/layouts/application.haml +++ b/app/views/layouts/application.html.haml @@ -50,4 +50,5 @@ Performance data is available on #{link_to "Skylight", ENV["SKYLIGHT_PUBLIC_DASHBOARD_URL"]}. = yield :script_body + = yield :charts_js = piwik_tracking_tag diff --git a/app/views/proposals/_proposal_form.html.haml b/app/views/proposals/_proposal_form.html.haml index 9629e82d..e4d72ae3 100644 --- a/app/views/proposals/_proposal_form.html.haml +++ b/app/views/proposals/_proposal_form.html.haml @@ -43,7 +43,7 @@ 250 words. - - if @program.cfp.enable_registrations? + - if current_user.is_admin? or @program.cfp.enable_registrations? = f.inputs 'Enable pre-registration' do = f.input :require_registration, label: 'Require participants to register to your event' - message = @event.room ? "Value must be between 1 and #{@event.room.size}" : 'Check room capacity after scheduling.' diff --git a/app/views/proposals/show.html.haml b/app/views/proposals/show.html.haml index ae2a93cc..a7a155bb 100644 --- a/app/views/proposals/show.html.haml +++ b/app/views/proposals/show.html.haml @@ -27,27 +27,28 @@ .row .col-md-3 %h3 + - if @event.speakers.any? 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) - %br - - if speaker.email_public? - = mail_to "#{ speaker.email }" do - %i.fa.fa-envelope-o.fa-2x - - if speaker.affiliation? - .text-muted - from - = speaker.affiliation - -if speaker.biography? - .row.speakerbio - .col-md-12 - = markdown(speaker.biography) + - @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) + %br + - if speaker.email_public? + = mail_to "#{ speaker.email }" do + %i.fa.fa-envelope-o.fa-2x + - 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 @@ -83,7 +84,7 @@ = @event.room.name .col-md-12 %dt Conference: - %dd= @event.program.conference.title + %dd= link_to @event.program.conference.title, conference_path(@conference) .col-md-12 %dt Language: %dd= @event.language if @event.language diff --git a/app/views/schedules/_event.html.haml b/app/views/schedules/_event.html.haml index a19d01cd..99ced63b 100644 --- a/app/views/schedules/_event.html.haml +++ b/app/views/schedules/_event.html.haml @@ -15,7 +15,8 @@ %small = event.subtitle %h4 - presented by #{event.speaker_names} + - if(event.speakers.any?) + 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 diff --git a/app/views/schedules/app.html.haml b/app/views/schedules/app.html.haml new file mode 100644 index 00000000..75e7c07c --- /dev/null +++ b/app/views/schedules/app.html.haml @@ -0,0 +1,19 @@ +.container + .page-header + %h1 + Get the schedule on your mobile with Giggity! + = link_to 'https://f-droid.org/packages/net.gaast.giggity' do + %img.img-responsive.center-block{ alt: 'Get it on F-Droid', src: 'https://fdroid.gitlab.io/artwork/badge/get-it-on.png' } + %p + The schedule URL: + %p.lead.text-center + = link_to conference_schedule_url(format: :xml) do + = conference_schedule_url(format: :xml) + %p + Or point your phone at the QR code: + .img-responsive.text-center + = raw @qr_code + %p.text-muted + Not free of surveilance capitalism yet? Use the + = link_to 'https://play.google.com/store/apps/details?id=net.gaast.giggity' do + google play store... diff --git a/app/views/schedules/show.html.haml b/app/views/schedules/show.html.haml index bd0f9976..355cafad 100644 --- a/app/views/schedules/show.html.haml +++ b/app/views/schedules/show.html.haml @@ -26,6 +26,9 @@ .visible-md-inline.visible-lg-inline = render partial: 'carousel', locals: { date: date, hrs_per_slide: 3 } + %p.pull-right + = link_to app_conference_schedule_path do + Get the mobile app! :javascript // change of active tab and the button title when a date is clicked diff --git a/app/views/schedules/show.xml.haml b/app/views/schedules/show.xml.haml index f42ad801..21bbbcea 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= time_with_timezone(event.time) + %date= event.time.in_time_zone(@conference.timezone).iso8601 %start= event.time.strftime('%H:%M') %duration= length_timestamp(event.event_type.length) %room= event.room.name diff --git a/app/views/shared/_media_items.html.haml b/app/views/shared/_media_items.html.haml index afc954d9..e4ef3c0d 100644 --- a/app/views/shared/_media_items.html.haml +++ b/app/views/shared/_media_items.html.haml @@ -5,7 +5,7 @@ - else %ul.nav.nav-tabs{ 'role'=>'tablist' } - commercials.each.with_index(1) do |commercial, index| - %li{class: "#{active if (index == 1)}"} + %li{class: "#{'active' if (index == 1)}"} %a{ 'href'=>"##{index}", 'role'=>'tab', 'data-toggle'=>'tab' } = index .tab-content diff --git a/app/views/tickets/_ticket.html.haml b/app/views/tickets/_ticket.html.haml index 726d836e..501e4151 100644 --- a/app/views/tickets/_ticket.html.haml +++ b/app/views/tickets/_ticket.html.haml @@ -2,18 +2,26 @@ %td.col-sm-8.col-md-4 .media .media-body - %h4.media-heading - = ticket.title - %h5.media-heading - - unless ticket.description.blank? - = markdown(ticket.description) - %td.col-sm-1.col-md-2.text-center - = ticket.registration_ticket? ? 'Yes' : 'No' + %h4.media-heading= ticket.title + %h5.media-heading= markdown(ticket.description) + - if @conference.tickets.for_registration.any? + %td.col-sm-1.col-md-2.text-center + = ticket.registration_ticket? ? 'Yes' : 'No' %td.col-sm-1.col-md-1 - - options = { type: 'number', min: 0, max: 99, class: "form-control quantity", 'data-id' => ticket.id } - - if ticket.registration_ticket? - - options[:max] = 1 - - options[:disabled] = current_user.tickets.for_registration(ticket.conference).present? + :ruby + options = { + type: 'number', + min: 0, + max: 99, + class: 'form-control quantity', + 'data-id' => ticket.id + } + if ticket.registration_ticket? + options[:max] = 1 + options[:disabled] = current_user.tickets.for_registration( + ticket.conference + ).present? + end = text_field_tag("tickets[][#{ticket.id}]", 0, options) %td.col-sm-1.col-md-1.text-center = ticket.price.symbol diff --git a/app/views/tickets/index.html.haml b/app/views/tickets/index.html.haml index 2f3569a2..e877845f 100644 --- a/app/views/tickets/index.html.haml +++ b/app/views/tickets/index.html.haml @@ -8,22 +8,23 @@ Please choose your tickets for %strong = @conference.title - here* - =form_tag(conference_ticket_purchases_path, method: :post) do |f| + = form_tag(conference_ticket_purchases_path, method: :post) do |f| %table.table.table-hover %thead %tr %th Ticket - %th Registration Ticket + - if @conference.tickets.for_registration.any? + %th Registration Ticket %th Quantity %th Price %th Total %tbody - @conference.tickets.visible.each do |ticket| - = render partial: 'ticket', f: f, locals: {ticket: ticket} + = render 'ticket', f: f, ticket: ticket %tr %td - %td + - if @conference.tickets.for_registration.any? + %td %td %td.col-sm-1.col-md-1.text-center %h4 @@ -32,20 +33,20 @@ %h4 %strong = @conference.tickets.first.price.symbol - %span{id: 'total_price'} + %span{ id: 'total_price' } 0 .pull-right .btn-group-vertical = button_tag(type: 'submit', class: 'btn btn-success btn-lg') do Continue %i.fa.fa-shopping-cart - - if current_user.ticket_purchases.by_conference(@conference).any? - = link_to 'Back to registration', conference_conference_registration_path(@conference.short_title), class: 'btn btn-default btn-sm' - - else - = link_to 'Cancel registration', conference_conference_registration_path(@conference.short_title), method: :delete, class: 'btn btn-danger btn-sm', - data: { confirm: 'Are you sure you want to unregister?' } - .row - .col-md-13 - %p.text-muted.text-center - %small - * Getting a registration ticket is mandatory. Your participation will not be valid until you get a registration ticket. + = link_to 'Back to registration', + conference_conference_registration_path(@conference.short_title), + class: 'btn btn-default btn-sm' + - if @conference.tickets.for_registration.any? + .row + .col-md-13 + %p.text-muted.text-center + %small + Getting a registration ticket is mandatory. Your participation + will not be valid until you get a registration ticket. diff --git a/bootstrap.sh b/bootstrap.sh deleted file mode 100644 index 3b331c23..00000000 --- a/bootstrap.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash - -pushd /vagrant - -echo -e "\ninstalling required software packages...\n" -zypper -q ar -f http://download.opensuse.org/repositories/devel:/languages:/ruby/openSUSE_Leap_42.2/devel:languages:ruby.repo -zypper -q --gpg-auto-import-keys --non-interactive ref -zypper -q -n install update-alternatives ruby2.4-devel make gcc gcc-c++ \ - libxml2-devel libxslt-devel nodejs screen mariadb \ - libmysqld-devel sqlite3-devel ImageMagick - -echo -e "\ndisabling versioned gem binary names...\n" -echo 'install: --no-format-executable' >> /etc/gemrc - -echo -e "\ninstalling bundler...\n" -gem.ruby2.4 install bundler - -echo -e "\ninstalling your bundle...\n" -su - vagrant -c "cd /vagrant/; bundle install --quiet" - -echo -e "\nConfiguring the app...\n" -su - vagrant -c "cd /vagrant/; bundle exec rake db:bootstrap" - -echo -e "\nProvisioning of your OSEM rails app done!" -echo -e "To start your development OSEM run: vagrant exec bundle exec rails server -b 0.0.0.0\n" diff --git a/config/deploy.rb b/config/deploy.rb index 9b76c176..8519deb5 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -1,63 +1,49 @@ -require 'mina/bundler' require 'mina/rails' require 'mina/git' -set :domain, 'proxy-opensuse.suse.de' -set :port, 2252 -set :user, 'osem' -set :deploy_to, '/srv/www/vhosts/opensuse.org/events' -set :repository, 'https://github.com/openSUSE/osem.git' +OSEM_DEPLOY_DOMAIN = ENV.fetch('OSEM_DEPLOY_DOMAIN', 'dale.infra.opensuse.org') +OSEM_DEPLOY_PORT = ENV.fetch('OSEM_DEPLOY_PORT', '22') +OSEM_DEPLOY_USER = ENV.fetch('OSEM_DEPLOY_USER', 'osem') +OSEM_DEPLOY_DIR = ENV.fetch('OSEM_DEPLOY_DIR', '/home/osem/events') +OSEM_DEPLOY_REPO = ENV.fetch('OSEM_DEPLOY_REPO', 'https://github.com/openSUSE/osem.git') +OSEM_DEPLOY_BRANCH = ENV.fetch('OSEM_DEPLOY_BRANCH', 'master') -# Manually create these paths in shared/ (eg: shared/config/database.yml) in your server. -# They will be linked in the 'deploy:link_shared_paths' step. -set :shared_paths, %w{ config/database.yml log public/system config/secrets.yml config/piwik.yml tmp .env.production} +set :application_name, 'osem' +set :domain, OSEM_DEPLOY_DOMAIN +set :user, OSEM_DEPLOY_USER +set :port, OSEM_DEPLOY_PORT +set :deploy_to, OSEM_DEPLOY_DIR +set :repository, OSEM_DEPLOY_REPO +set :branch, OSEM_DEPLOY_BRANCH -task setup: :environment do - queue! %[mkdir -p "#{deploy_to}/shared/log"] - queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/log"] - - queue! %[mkdir -p "#{deploy_to}/shared/config"] - queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/config"] - - queue! %[touch "#{deploy_to}/shared/config/database.yml"] - - queue! %[touch "#{deploy_to}/shared/system"] - queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/system"] - queue %[echo "-----> Be sure to edit 'shared/config/database.yml'."] -end - -desc 'Deploys the current version to the server.' -task deploy: :environment do - to :prepare do - queue "cd #{deploy_to}/current && RAILS_ENV=production bin/delayed_job stop" - end +# Shared dirs and files will be symlinked into the app-folder by the 'deploy:link_shared_paths' step. +# Some plugins already add folders to shared_dirs like `mina/rails` add `public/assets`, `vendor/bundle` and many more +# run `mina -d` to see all folders and files already included in `shared_dirs` and `shared_files` +set :shared_dirs, fetch(:shared_dirs, []).push('public/system') +set :shared_files, fetch(:shared_files, []).push('.env.production') +desc "Deploys the current version to the server." +task :deploy do deploy do + # Put things that will set up an empty directory into a fully set-up + # instance of your project. invoke :'git:clone' invoke :'deploy:link_shared_paths' invoke :'bundle:install' - invoke :'dump_db' invoke :'rails:db_migrate' invoke :'rails:assets_precompile' - #invoke :notify_errbit - - to :launch do - queue "sudo /usr/bin/systemctl restart apache2" - queue "cd #{deploy_to}/current && RAILS_ENV=production bin/delayed_job start" - end - invoke :'deploy:cleanup' + + on :launch do + in_path(fetch(:current_path)) do + command %{mkdir -p tmp/} + command %{touch tmp/restart.txt} + command %{sudo systemctl restart osem-dj} + end + end end end -desc 'Notifies the exception handler of the deploy.' -task :notify_errbit do - revision = `git rev-parse HEAD`.strip - user = ENV['USER'] - queue "cd #{deploy_to}/current && RAILS_ENV=production bundle exec rake hoptoad:deploy TO=#{rails_env} REVISION=#{revision} REPO=#{repository} USER=#{user}" -end - -desc 'Back ups the database' -task :dump_db do - queue "bundle exec rake dump_db" -end +# For help in making your deploy script, see the Mina documentation: +# +# - https://github.com/mina-deploy/mina/tree/master/docs diff --git a/config/environments/development.rb b/config/environments/development.rb index 3b3ae15e..c3dcac54 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -1,11 +1,7 @@ Osem::Application.configure do # Settings specified here will take precedence over those in config/application.rb - # Allow the web console from the vagrant host ip - config.web_console.whitelisted_ips = '10.0.2.2' - - # Use letter_opener_web for Vagrant (launchy won't work) - config.action_mailer.delivery_method = ENV['USER'] == 'vagrant' ? :letter_opener_web : :letter_opener + config.action_mailer.delivery_method = :letter_opener # In the development environment your application's code is reloaded on # every request. This slows down response time but is perfect for development diff --git a/config/environments/production.rb b/config/environments/production.rb index 357dcb55..60e023a0 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -33,7 +33,7 @@ Osem::Application.configure do # config.assets.manifest = YOUR_PATH # Specifies the header that your server uses for sending files - config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for apache + # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for apache # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. @@ -43,20 +43,25 @@ Osem::Application.configure do config.log_level = ENV['OSEM_LOG_LEVEL'].try(:to_sym) || :info # Prepend all log lines with the following tags - # config.log_tags = [ :subdomain, :uuid ] + config.log_tags = [:uuid] - # Use a different logger for distributed setups - # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) + # Disable serving static files from the `/public` folder by default since + # Apache or NGINX already handles this. + config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? + + if ENV["RAILS_LOG_TO_STDOUT"].present? + logger = ActiveSupport::Logger.new(STDOUT) + logger.formatter = config.log_formatter + config.logger = ActiveSupport::TaggedLogging.new(logger) + end # Use a different cache store in production # config.cache_store = :mem_cache_store - if ENV["MEMCACHEDCLOUD_SERVERS"] - config.cache_store = :dalli_store, ENV["MEMCACHEDCLOUD_SERVERS"].split(','), { - username: ENV["MEMCACHEDCLOUD_USERNAME"], - password: ENV["MEMCACHEDCLOUD_PASSWORD"] + if ENV["OSEM_MEMCACHED_SERVERS"] + config.cache_store = :mem_cache_store, ENV["OSEM_MEMCACHED_SERVERS"].split(','), { + username: ENV["OSEM_MEMCACHED_USERNAME"], + password: ENV["OSEM_MEMCACHED_PASSWORD"] } - else - config.cache_store = :memory_store, { size: 64.megabytes } end # Enable serving of images, stylesheets, and JavaScripts from an asset server diff --git a/config/initializers/airbrake.rb b/config/initializers/airbrake.rb index 44cac749..e3c96dfc 100644 --- a/config/initializers/airbrake.rb +++ b/config/initializers/airbrake.rb @@ -1,7 +1,7 @@ Airbrake.configure do |config| # Change this to some sensible data for your errbit instance - config.project_id = ENV['OSEM_ERRBIT_APIKEY'] || Rails.application.secrets.errbit_key || '' - config.project_key = ENV['OSEM_ERRBIT_APIKEY'] || Rails.application.secrets.errbit_key || '' + config.project_id = ENV['OSEM_ERRBIT_ID'] || Rails.application.secrets.errbit_id || '' + config.project_key = ENV['OSEM_ERRBIT_KEY'] || Rails.application.secrets.errbit_key || '' config.host = ENV['OSEM_ERRBIT_HOST'] config.environment = Rails.env if config.project_key.blank? || config.host.blank? diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index 1d25cea1..01ef3e66 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -9,4 +9,3 @@ Rails.application.config.assets.version = '1.0' # Precompile additional assets. # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. # Rails.application.config.assets.precompile += %w( search.js ) -Rails.application.config.assets.precompile += %w( Chart.min.js ) diff --git a/config/initializers/chartkick.rb b/config/initializers/chartkick.rb new file mode 100644 index 00000000..23fa3574 --- /dev/null +++ b/config/initializers/chartkick.rb @@ -0,0 +1,4 @@ +Chartkick.options = { + height: '150px', + content_for: :charts_js +} diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index f10f4349..a533ffe2 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -243,7 +243,7 @@ Devise.setup do |config| # config.omniauth_path_prefix = "/my_engine/users/auth" # You will always need to set this parameter. - config.ichain_base_url = "https://events.opensuse.org" + config.ichain_base_url = ENV.fetch('OSEM_ICHAIN_BASE_URL', 'https://events.opensuse.org') # Paths (relative to ichain_base_url) used by your proxy # config.ichain_login_path = "ICSLogin/" diff --git a/config/initializers/new_framework_defaults.rb b/config/initializers/new_framework_defaults.rb index cbf423a8..534a2396 100644 --- a/config/initializers/new_framework_defaults.rb +++ b/config/initializers/new_framework_defaults.rb @@ -20,6 +20,3 @@ ActiveSupport.to_time_preserves_timezone = false # Require `belongs_to` associations by default. Previous versions had false. Rails.application.config.active_record.belongs_to_required_by_default = false - -# Do not halt callback chains when a callback returns false. Previous versions had true. -ActiveSupport.halt_callback_chains_on_return_false = true diff --git a/config/locales/alias.en.yml b/config/locales/alias.en.yml new file mode 100644 index 00000000..fc66d6cb --- /dev/null +++ b/config/locales/alias.en.yml @@ -0,0 +1,3 @@ +en: + booth: 'booth' + booth_responsible: 'booth responsible' diff --git a/config/puma.rb b/config/puma.rb index fa11fb8f..9886e1e5 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -21,7 +21,7 @@ environment ENV.fetch("RAILS_ENV") { "development" } # Workers do not work on JRuby or Windows (both of which do not support # processes). # -workers ENV.fetch("WEB_CONCURRENCY") { 2 } +workers ENV.fetch("WEB_CONCURRENCY") { 1 } # Use the `preload_app!` method when specifying a `workers` number. # This directive tells Puma to first boot the application and load code diff --git a/config/routes.rb b/config/routes.rb index 33cda6dc..8849e0b2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -14,11 +14,6 @@ Osem::Application.routes.draw do path: 'accounts' end - # Use letter_opener_web to open mails in browser (e.g. necessary for Vagrant) - if Rails.env.development? - mount LetterOpenerWeb::Engine, at: "/letter_opener" - end - resources :users, except: [:new, :index, :create, :destroy] do resources :openids, only: :destroy end @@ -174,6 +169,7 @@ Osem::Application.routes.draw do end end resource :program, only: [] do + get 'proposal/:id', to: 'proposals#show' # For backward compatibility resources :proposals, except: :destroy do get 'commercials/render_commercial' => 'commercials#render_commercial' resources :commercials, only: [:create, :update, :destroy] @@ -201,6 +197,9 @@ Osem::Application.routes.draw do resources :physical_tickets, only: [:index, :show] resource :subscriptions, only: [:create, :destroy] resource :schedule, only: [:show] do + collection do + get 'app' + end member do get :events end diff --git a/db/schema.rb b/db/schema.rb index 5fde0696..8168dfbe 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -13,15 +13,15 @@ ActiveRecord::Schema.define(version: 20181113195810) do create_table "answers", force: :cascade do |t| - t.string "title" + t.string "title" t.datetime "created_at" t.datetime "updated_at" end create_table "booth_requests", force: :cascade do |t| - t.integer "booth_id" - t.integer "user_id" - t.string "role" + t.integer "booth_id" + t.integer "user_id" + t.string "role" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["booth_id"], name: "index_booth_requests_on_booth_id" @@ -29,81 +29,81 @@ ActiveRecord::Schema.define(version: 20181113195810) do end create_table "booths", force: :cascade do |t| - t.string "title" - t.text "description" - t.text "reasoning" - t.string "state" - t.string "logo_link" - t.string "website_url" - t.text "submitter_relationship" - t.integer "conference_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.string "title" + t.text "description" + t.text "reasoning" + t.string "state" + t.string "logo_link" + t.string "website_url" + t.text "submitter_relationship" + t.integer "conference_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "cfps", force: :cascade do |t| - t.date "start_date", null: false - t.date "end_date", null: false + t.date "start_date", null: false + t.date "end_date", null: false t.datetime "created_at" t.datetime "updated_at" - t.integer "program_id" - t.string "cfp_type" - t.text "description" - t.boolean "enable_registrations", default: false + t.integer "program_id" + t.string "cfp_type" + t.text "description" + t.boolean "enable_registrations", default: false end create_table "comments", force: :cascade do |t| - t.string "title", limit: 50, default: "" - t.text "body" - t.integer "commentable_id" - t.string "commentable_type" - t.integer "user_id" + t.string "title", limit: 50, default: "" + t.text "body" + t.integer "commentable_id" + t.string "commentable_type" + t.integer "user_id" t.datetime "created_at" t.datetime "updated_at" - t.string "subject" - t.integer "parent_id" - t.integer "lft" - t.integer "rgt" + t.string "subject" + t.integer "parent_id" + t.integer "lft" + t.integer "rgt" t.index ["commentable_id"], name: "index_comments_on_commentable_id" t.index ["commentable_type"], name: "index_comments_on_commentable_type" t.index ["user_id"], name: "index_comments_on_user_id" end create_table "commercials", force: :cascade do |t| - t.string "commercial_id" - t.string "commercial_type" - t.integer "commercialable_id" - t.string "commercialable_type" + t.string "commercial_id" + t.string "commercial_type" + t.integer "commercialable_id" + t.string "commercialable_type" t.datetime "created_at" t.datetime "updated_at" - t.string "url" + t.string "url" end create_table "conferences", force: :cascade do |t| - t.string "guid", null: false - t.string "title", null: false - t.string "short_title", null: false - t.string "timezone", null: false - t.date "start_date", null: false - t.date "end_date", null: false + t.string "guid", null: false + t.string "title", null: false + t.string "short_title", null: false + t.string "timezone", null: false + t.date "start_date", null: false + t.date "end_date", null: false t.datetime "created_at" t.datetime "updated_at" - t.string "logo_file_name" - t.integer "revision", default: 0, null: false - t.boolean "use_vpositions", default: false - t.boolean "use_vdays", default: false - t.boolean "use_volunteers" - t.string "color" - t.text "events_per_week" - t.text "description" - t.integer "registration_limit", default: 0 - t.string "picture" - t.integer "start_hour", default: 9 - t.integer "end_hour", default: 20 - t.integer "organization_id" - t.integer "ticket_layout", default: 0 - t.string "custom_domain" - t.integer "booth_limit", default: 0 + t.string "logo_file_name" + t.integer "revision", default: 0, null: false + t.boolean "use_vpositions", default: false + t.boolean "use_vdays", default: false + t.boolean "use_volunteers" + t.string "color" + t.text "events_per_week" + t.text "description" + t.integer "registration_limit", default: 0 + t.string "picture" + t.integer "start_hour", default: 9 + t.integer "end_hour", default: 20 + t.integer "organization_id" + t.integer "ticket_layout", default: 0 + t.string "custom_domain" + t.integer "booth_limit", default: 0 t.index ["organization_id"], name: "index_conferences_on_organization_id" end @@ -113,95 +113,95 @@ ActiveRecord::Schema.define(version: 20181113195810) do end create_table "contacts", force: :cascade do |t| - t.string "social_tag" - t.string "email" - t.string "facebook" - t.string "googleplus" - t.string "twitter" - t.string "instagram" - t.integer "conference_id" + t.string "social_tag" + t.string "email" + t.string "facebook" + t.string "googleplus" + t.string "twitter" + t.string "instagram" + t.integer "conference_id" t.datetime "created_at" t.datetime "updated_at" - t.string "sponsor_email" - t.string "mastodon" - t.string "youtube" - t.string "blog" + t.string "sponsor_email" + t.string "mastodon" + t.string "youtube" + t.string "blog" end create_table "delayed_jobs", force: :cascade do |t| - t.integer "priority", default: 0, null: false - t.integer "attempts", default: 0, null: false - t.text "handler", null: false - t.text "last_error" + t.integer "priority", default: 0, null: false + t.integer "attempts", default: 0, null: false + t.text "handler", null: false + t.text "last_error" t.datetime "run_at" t.datetime "locked_at" t.datetime "failed_at" - t.string "locked_by" - t.string "queue" + t.string "locked_by" + t.string "queue" t.datetime "created_at" t.datetime "updated_at" t.index ["priority", "run_at"], name: "delayed_jobs_priority" end create_table "difficulty_levels", force: :cascade do |t| - t.string "title" - t.text "description" - t.string "color" + t.string "title" + t.text "description" + t.string "color" t.datetime "created_at" t.datetime "updated_at" - t.integer "program_id" + t.integer "program_id" end create_table "email_settings", force: :cascade do |t| - t.integer "conference_id" - t.boolean "send_on_registration", default: false - t.boolean "send_on_accepted", default: false - t.boolean "send_on_rejected", default: false - t.boolean "send_on_confirmed_without_registration", default: false - t.text "registration_body" - t.text "accepted_body" - t.text "rejected_body" - t.text "confirmed_without_registration_body" + t.integer "conference_id" + t.boolean "send_on_registration", default: false + t.boolean "send_on_accepted", default: false + t.boolean "send_on_rejected", default: false + t.boolean "send_on_confirmed_without_registration", default: false + t.text "registration_body" + t.text "accepted_body" + t.text "rejected_body" + t.text "confirmed_without_registration_body" t.datetime "created_at" t.datetime "updated_at" - t.string "registration_subject" - t.string "accepted_subject" - t.string "rejected_subject" - t.string "confirmed_without_registration_subject" - t.boolean "send_on_conference_dates_updated", default: false - t.string "conference_dates_updated_subject" - t.text "conference_dates_updated_body" - t.boolean "send_on_conference_registration_dates_updated", default: false - t.string "conference_registration_dates_updated_subject" - t.text "conference_registration_dates_updated_body" - t.boolean "send_on_venue_updated", default: false - t.string "venue_updated_subject" - t.text "venue_updated_body" - t.boolean "send_on_cfp_dates_updated", default: false - t.boolean "send_on_program_schedule_public", default: false - t.string "program_schedule_public_subject" - t.string "cfp_dates_updated_subject" - t.text "program_schedule_public_body" - t.text "cfp_dates_updated_body" - t.boolean "send_on_booths_acceptance", default: false - t.string "booths_acceptance_subject" - t.text "booths_acceptance_body" - t.boolean "send_on_booths_rejection", default: false - t.string "booths_rejection_subject" - t.text "booths_rejection_body" - t.boolean "send_on_submitted_proposal", default: false - t.string "submitted_proposal_subject" - t.text "submitted_proposal_body" + t.string "registration_subject" + t.string "accepted_subject" + t.string "rejected_subject" + t.string "confirmed_without_registration_subject" + t.boolean "send_on_conference_dates_updated", default: false + t.string "conference_dates_updated_subject" + t.text "conference_dates_updated_body" + t.boolean "send_on_conference_registration_dates_updated", default: false + t.string "conference_registration_dates_updated_subject" + t.text "conference_registration_dates_updated_body" + t.boolean "send_on_venue_updated", default: false + t.string "venue_updated_subject" + t.text "venue_updated_body" + t.boolean "send_on_cfp_dates_updated", default: false + t.boolean "send_on_program_schedule_public", default: false + t.string "program_schedule_public_subject" + t.string "cfp_dates_updated_subject" + t.text "program_schedule_public_body" + t.text "cfp_dates_updated_body" + t.boolean "send_on_booths_acceptance", default: false + t.string "booths_acceptance_subject" + t.text "booths_acceptance_body" + t.boolean "send_on_booths_rejection", default: false + t.string "booths_rejection_subject" + t.text "booths_rejection_body" + t.boolean "send_on_submitted_proposal", default: false + t.string "submitted_proposal_subject" + t.text "submitted_proposal_body" end create_table "event_schedules", force: :cascade do |t| - t.integer "event_id" - t.integer "schedule_id" - t.integer "room_id" + t.integer "event_id" + t.integer "schedule_id" + t.integer "room_id" t.datetime "start_time" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.boolean "enabled", default: true + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "enabled", default: true t.index ["event_id", "schedule_id"], name: "index_event_schedules_on_event_id_and_schedule_id", unique: true t.index ["event_id"], name: "index_event_schedules_on_event_id" t.index ["room_id"], name: "index_event_schedules_on_room_id" @@ -209,171 +209,171 @@ ActiveRecord::Schema.define(version: 20181113195810) do end create_table "event_types", force: :cascade do |t| - t.string "title", null: false - t.integer "length", default: 30 - t.integer "minimum_abstract_length", default: 0 - t.integer "maximum_abstract_length", default: 500 - t.string "color" - t.string "description" - t.integer "program_id" + t.string "title", null: false + t.integer "length", default: 30 + t.integer "minimum_abstract_length", default: 0 + t.integer "maximum_abstract_length", default: 500 + t.string "color" + t.string "description" + t.integer "program_id" t.datetime "created_at" t.datetime "updated_at" end create_table "event_users", force: :cascade do |t| - t.integer "user_id" - t.integer "event_id" - t.string "event_role", default: "participant", null: false - t.string "comment" + t.integer "user_id" + t.integer "event_id" + t.string "event_role", default: "participant", null: false + t.string "comment" t.datetime "created_at" t.datetime "updated_at" end create_table "events", force: :cascade do |t| - t.string "guid", null: false - t.integer "event_type_id" - t.string "title", null: false - t.string "subtitle" - t.string "state", default: "new", null: false - t.string "progress", default: "new", null: false - t.string "language" + t.string "guid", null: false + t.integer "event_type_id" + t.string "title", null: false + t.string "subtitle" + t.string "state", default: "new", null: false + t.string "progress", default: "new", null: false + t.string "language" t.datetime "start_time" - t.text "abstract" - t.text "description" - t.boolean "public", default: true - t.text "proposal_additional_speakers" - t.integer "track_id" - t.integer "room_id" + t.text "abstract" + t.text "description" + t.boolean "public", default: true + t.text "proposal_additional_speakers" + t.integer "track_id" + t.integer "room_id" t.datetime "created_at" t.datetime "updated_at" - t.boolean "require_registration" - t.integer "difficulty_level_id" - t.integer "week" - t.boolean "is_highlight", default: false - t.integer "program_id" - t.integer "max_attendees" - t.integer "comments_count", default: 0, null: false + t.boolean "require_registration" + t.integer "difficulty_level_id" + t.integer "week" + 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| - t.integer "registration_id" - t.integer "event_id" - t.boolean "attended", default: false, null: false + t.integer "registration_id" + t.integer "event_id" + t.boolean "attended", default: false, null: false t.datetime "created_at" end create_table "lodgings", force: :cascade do |t| - t.string "name" - t.text "description" - t.string "photo_file_name" - t.string "photo_content_type" - t.integer "photo_file_size" + t.string "name" + t.text "description" + t.string "photo_file_name" + t.string "photo_content_type" + t.integer "photo_file_size" t.datetime "photo_updated_at" t.datetime "created_at" t.datetime "updated_at" - t.string "website_link" - t.integer "conference_id" - t.string "picture" + t.string "website_link" + t.integer "conference_id" + t.string "picture" end create_table "openids", force: :cascade do |t| - t.string "provider" - t.string "email" - t.string "uid" - t.integer "user_id" + t.string "provider" + t.string "email" + t.string "uid" + t.integer "user_id" t.datetime "created_at" t.datetime "updated_at" end create_table "organizations", force: :cascade do |t| - t.string "name", null: false - t.text "description" + t.string "name", null: false + t.text "description" t.string "picture" - t.text "code_of_conduct" + t.text "code_of_conduct" end create_table "payments", force: :cascade do |t| - t.string "last4" - t.integer "amount" - t.string "authorization_code" - t.integer "status", default: 0, null: false - t.integer "user_id", null: false - t.integer "conference_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.string "last4" + t.integer "amount" + t.string "authorization_code" + t.integer "status", default: 0, null: false + t.integer "user_id", null: false + t.integer "conference_id", null: false + t.datetime "created_at", null: false + 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 - t.string "token" + t.integer "ticket_purchase_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "token" t.index ["token"], name: "index_physical_tickets_on_token", unique: true end create_table "programs", force: :cascade do |t| - t.integer "conference_id" - t.integer "rating", default: 0 - t.boolean "schedule_public", default: false - t.boolean "schedule_fluid", default: false + t.integer "conference_id" + t.integer "rating", default: 0 + t.boolean "schedule_public", default: false + t.boolean "schedule_fluid", default: false t.datetime "created_at" t.datetime "updated_at" - t.string "languages" - t.boolean "blind_voting", default: false + t.string "languages" + t.boolean "blind_voting", default: false t.datetime "voting_start_date" t.datetime "voting_end_date" - t.integer "selected_schedule_id" - t.integer "schedule_interval", default: 15, null: false + t.integer "selected_schedule_id" + t.integer "schedule_interval", default: 15, null: false t.index ["selected_schedule_id"], name: "index_programs_on_selected_schedule_id" end create_table "qanswers", force: :cascade do |t| - t.integer "question_id" - t.integer "answer_id" + t.integer "question_id" + t.integer "answer_id" t.datetime "created_at" t.datetime "updated_at" end create_table "qanswers_registrations", id: false, force: :cascade do |t| t.integer "registration_id", null: false - t.integer "qanswer_id", null: false + t.integer "qanswer_id", null: false end create_table "question_types", force: :cascade do |t| - t.string "title" + t.string "title" t.datetime "created_at" t.datetime "updated_at" end create_table "questions", force: :cascade do |t| - t.string "title" - t.integer "question_type_id" - t.integer "conference_id" - t.boolean "global" + t.string "title" + t.integer "question_type_id" + t.integer "conference_id" + t.boolean "global" t.datetime "created_at" t.datetime "updated_at" end create_table "registration_periods", force: :cascade do |t| - t.integer "conference_id" - t.date "start_date" - t.date "end_date" + t.integer "conference_id" + t.date "start_date" + t.date "end_date" t.datetime "created_at" t.datetime "updated_at" end create_table "registrations", force: :cascade do |t| - t.integer "conference_id" + t.integer "conference_id" t.datetime "arrival" t.datetime "departure" t.datetime "created_at" t.datetime "updated_at" - t.text "other_special_needs" - t.boolean "attended", default: false - t.boolean "volunteer" - t.integer "user_id" - t.integer "week" - t.boolean "accepted_code_of_conduct" + t.text "other_special_needs" + t.boolean "attended", default: false + t.boolean "volunteer" + t.integer "user_id" + t.integer "week" + t.boolean "accepted_code_of_conduct" end create_table "registrations_vchoices", id: false, force: :cascade do |t| @@ -382,109 +382,110 @@ ActiveRecord::Schema.define(version: 20181113195810) do end create_table "resources", force: :cascade do |t| - t.string "name" - t.text "description" + t.string "name" + t.text "description" t.integer "quantity" - t.integer "used", default: 0 + t.integer "used", default: 0 t.integer "conference_id" end create_table "roles", force: :cascade do |t| - t.string "name" + t.string "name" t.datetime "created_at" t.datetime "updated_at" - t.string "description" - t.integer "resource_id" - t.string "resource_type" + t.string "description" + t.integer "resource_id" + t.string "resource_type" t.index ["name", "resource_type", "resource_id"], name: "index_roles_on_name_and_resource_type_and_resource_id" t.index ["name"], name: "index_roles_on_name" end create_table "rooms", 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.integer "size" t.integer "venue_id", null: false end create_table "schedules", force: :cascade do |t| - t.integer "program_id" + t.integer "program_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.integer "track_id" + t.integer "track_id" t.index ["program_id"], name: "index_schedules_on_program_id" t.index ["track_id"], name: "index_schedules_on_track_id" end create_table "splashpages", force: :cascade do |t| - t.integer "conference_id" - t.boolean "public" - t.boolean "include_tracks" - t.boolean "include_program" - t.boolean "include_social_media" - t.boolean "include_venue" - t.boolean "include_tickets" - t.boolean "include_registrations" - t.boolean "include_sponsors" - t.boolean "include_lodgings" - t.string "banner_photo_file_name" - t.string "banner_photo_content_type" - t.integer "banner_photo_file_size" + t.integer "conference_id" + t.boolean "public" + t.boolean "include_tracks" + t.boolean "include_program" + t.boolean "include_social_media" + t.boolean "include_venue" + t.boolean "include_tickets" + t.boolean "include_registrations" + t.boolean "include_sponsors" + t.boolean "include_lodgings" + t.string "banner_photo_file_name" + t.string "banner_photo_content_type" + t.integer "banner_photo_file_size" t.datetime "banner_photo_updated_at" t.datetime "created_at" t.datetime "updated_at" - t.boolean "include_cfp", default: false - t.boolean "include_booths" + t.boolean "include_cfp", default: false + t.boolean "include_booths" + t.boolean "shuffle_highlights", default: false, null: false end create_table "sponsors", force: :cascade do |t| - t.string "name" - t.text "description" - t.string "website_url" - t.string "logo_file_name" - t.integer "sponsorship_level_id" - t.integer "conference_id" + t.string "name" + t.text "description" + t.string "website_url" + t.string "logo_file_name" + t.integer "sponsorship_level_id" + t.integer "conference_id" t.datetime "created_at" t.datetime "updated_at" - t.string "picture" + t.string "picture" end create_table "sponsorship_levels", force: :cascade do |t| - t.string "title" - t.integer "conference_id" + t.string "title" + t.integer "conference_id" t.datetime "created_at" t.datetime "updated_at" - t.integer "position" + t.integer "position" end create_table "subscriptions", force: :cascade do |t| - t.integer "user_id" - t.integer "conference_id" + t.integer "user_id" + t.integer "conference_id" t.datetime "created_at" t.datetime "updated_at" end create_table "survey_questions", force: :cascade do |t| t.integer "survey_id" - t.string "title" - t.integer "kind", default: 0 + t.string "title" + t.integer "kind", default: 0 t.integer "min_choices" t.integer "max_choices" - t.text "possible_answers" - t.boolean "mandatory", default: false + t.text "possible_answers" + t.boolean "mandatory", default: false end create_table "survey_replies", force: :cascade do |t| - t.integer "survey_question_id" - t.integer "user_id" - t.text "text" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.integer "survey_question_id" + t.integer "user_id" + t.text "text" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "survey_submissions", force: :cascade do |t| - t.integer "user_id" - t.integer "survey_id" + t.integer "user_id" + t.integer "survey_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false end @@ -492,101 +493,101 @@ ActiveRecord::Schema.define(version: 20181113195810) do create_table "surveys", force: :cascade do |t| t.datetime "start_date" t.datetime "end_date" - t.string "title" - t.text "description" - t.integer "surveyable_id" - t.string "surveyable_type" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.integer "target", default: 0 + t.string "title" + t.text "description" + t.integer "surveyable_id" + t.string "surveyable_type" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "target", default: 0 t.index ["surveyable_type", "surveyable_id"], name: "index_surveys_on_surveyable_type_and_surveyable_id" end create_table "ticket_purchases", force: :cascade do |t| - t.integer "ticket_id" - t.integer "conference_id" - t.boolean "paid", default: false + t.integer "ticket_id" + t.integer "conference_id" + t.boolean "paid", default: false t.datetime "created_at" - t.integer "quantity", default: 1 - t.integer "user_id" - t.integer "payment_id" - t.integer "week" - t.float "amount_paid", default: 0.0 + t.integer "quantity", default: 1 + t.integer "user_id" + t.integer "payment_id" + t.integer "week" + t.float "amount_paid", default: 0.0 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 + 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 - t.text "description" - t.integer "price_cents", default: 0, null: false - t.string "price_currency", default: "USD", null: false - t.boolean "registration_ticket", default: false + t.integer "conference_id" + t.string "title", null: false + t.text "description" + t.integer "price_cents", default: 0, null: false + t.string "price_currency", default: "USD", null: false + t.boolean "registration_ticket", default: false t.datetime "created_at" t.datetime "updated_at" t.boolean "visible", default: true end create_table "tracks", force: :cascade do |t| - t.string "guid", null: false - t.string "name", null: false - t.text "description" - t.string "color" + 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 "state", default: "new", null: false - t.boolean "cfp_active", null: false - t.integer "submitter_id" - t.integer "room_id" - t.date "start_date" - t.date "end_date" - t.text "relevance" - t.integer "selected_schedule_id" + t.integer "program_id" + t.string "short_name", null: false + t.string "state", default: "new", null: false + t.boolean "cfp_active", null: false + t.integer "submitter_id" + t.integer "room_id" + t.date "start_date" + t.date "end_date" + t.text "relevance" + t.integer "selected_schedule_id" t.index ["room_id"], name: "index_tracks_on_room_id" t.index ["selected_schedule_id"], name: "index_tracks_on_selected_schedule_id" t.index ["submitter_id"], name: "index_tracks_on_submitter_id" end create_table "users", force: :cascade do |t| - t.string "email", default: "", null: false - t.string "encrypted_password", default: "", null: false - t.string "reset_password_token" + t.string "email", default: "", null: false + t.string "encrypted_password", default: "", null: false + t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" - t.integer "sign_in_count", default: 0 + t.integer "sign_in_count", default: 0 t.datetime "current_sign_in_at" t.datetime "last_sign_in_at" - t.string "current_sign_in_ip" - t.string "last_sign_in_ip" - t.string "confirmation_token" + t.string "current_sign_in_ip" + t.string "last_sign_in_ip" + t.string "confirmation_token" t.datetime "confirmed_at" t.datetime "confirmation_sent_at" - t.string "unconfirmed_email" + t.string "unconfirmed_email" t.datetime "created_at" t.datetime "updated_at" - t.string "name" - t.boolean "email_public", default: false - t.text "biography" - t.string "nickname" - t.string "affiliation" - t.string "avatar_file_name" - t.string "avatar_content_type" - t.integer "avatar_file_size" + t.string "name" + t.boolean "email_public", default: false + t.text "biography" + t.string "nickname" + t.string "affiliation" + t.string "avatar_file_name" + t.string "avatar_content_type" + t.integer "avatar_file_size" t.datetime "avatar_updated_at" - t.string "mobile" - t.string "tshirt" - t.string "languages" - t.text "volunteer_experience" - t.boolean "is_admin", default: false - t.string "username" - t.boolean "is_disabled", default: false + t.string "mobile" + t.string "tshirt" + t.string "languages" + t.text "volunteer_experience" + t.boolean "is_admin", default: false + t.string "username" + t.boolean "is_disabled", default: false t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true t.index ["email"], name: "index_users_on_email", unique: true t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true @@ -605,55 +606,55 @@ ActiveRecord::Schema.define(version: 20181113195810) do end create_table "vdays", force: :cascade do |t| - t.integer "conference_id" - t.date "day" - t.text "description" + t.integer "conference_id" + t.date "day" + t.text "description" t.datetime "created_at" t.datetime "updated_at" end create_table "venues", force: :cascade do |t| - t.string "guid" - t.string "name" - t.string "website" - t.text "description" + t.string "guid" + t.string "name" + t.string "website" + t.text "description" t.datetime "created_at" t.datetime "updated_at" - t.string "photo_file_name" - t.string "street" - t.string "postalcode" - t.string "city" - t.string "country" - t.string "latitude" - t.string "longitude" - t.integer "conference_id" - t.string "picture" + t.string "photo_file_name" + t.string "street" + t.string "postalcode" + t.string "city" + t.string "country" + t.string "latitude" + t.string "longitude" + t.integer "conference_id" + t.string "picture" end create_table "versions", force: :cascade do |t| - t.string "item_type", null: false - t.integer "item_id", null: false - t.string "event", null: false - t.string "whodunnit" - t.text "object" - t.text "object_changes" + t.string "item_type", null: false + t.integer "item_id", null: false + t.string "event", null: false + t.string "whodunnit" + t.text "object" + t.text "object_changes" t.datetime "created_at" - t.integer "conference_id" + t.integer "conference_id" t.index ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id" end create_table "votes", force: :cascade do |t| - t.integer "event_id" - t.integer "rating" + t.integer "event_id" + t.integer "rating" t.datetime "created_at" t.datetime "updated_at" - t.integer "user_id" + t.integer "user_id" end create_table "vpositions", force: :cascade do |t| - t.integer "conference_id" - t.string "title", null: false - t.text "description" + t.integer "conference_id" + t.string "title", null: false + t.text "description" t.datetime "created_at" t.datetime "updated_at" end diff --git a/dist/apache-vhost.conf b/dist/apache-vhost.conf new file mode 100644 index 00000000..994593bf --- /dev/null +++ b/dist/apache-vhost.conf @@ -0,0 +1,45 @@ + + ServerAdmin admin@opensuse.org + ServerName events.opensuse.org + ServerAlias conference.opensuse.org + ServerAlias summit.opensuse.org + + DocumentRoot /home/osem/events/current/public + + CustomLog /home/osem/events/current/log/access.log combined + ErrorLog /home/osem/events/current/log/error.log + + RewriteEngine on + RewriteRule "^/conference/(.+)" "https://events.opensuse.org/conferences/$1" [R,L] + + # Serve assets and uploads directly + + ProxyPass ! + + + ProxyPass ! + + + # Pass the rest on to puma + ProxyPass / http://127.0.0.1:3000/ + ProxyPassReverse / http://127.0.0.1:3000/ + + # don't loose time with IP address lookups + HostnameLookups Off + UseCanonicalName Off + + # enable the footer on server-generated documents + ServerSignature On + + + Options FollowSymLinks + + + + Options FollowSymLinks + AllowOverride All + Options -MultiViews + Require all granted + + + diff --git a/dist/osem-dj.service b/dist/osem-dj.service new file mode 100644 index 00000000..53702769 --- /dev/null +++ b/dist/osem-dj.service @@ -0,0 +1,17 @@ +[Unit] +Description=Open Source Event Manager Delayed Jobs +Wants=osem.service +Before=osem.service + +[Service] +User=osem +EnvironmentFile=/home/osem/events/current/.env.production +WorkingDirectory=/home/osem/events/current +ExecStart = /usr/bin/bundle exec bin/delayed_job -e production start +ExecStop = /usr/bin/bundle exec bin/delayed_job -e production stop +Type = forking +PIDFile = /home/osem/events/current/tmp/pids/delayed_job.pid + +[Install] +WantedBy=multi-user.target + diff --git a/dist/osem.logrotate b/dist/osem.logrotate new file mode 100644 index 00000000..d46c9e73 --- /dev/null +++ b/dist/osem.logrotate @@ -0,0 +1,13 @@ +/home/osem/events/shared/log/*.log { + compress + dateext + maxage 31 + rotate 99 + size=+4096k + missingok + notifempty + create 644 osem osem + postrotate + /usr/bin/touch /home/osem/events/current/tmp/restart.txt + endscript +} diff --git a/dist/osem.service b/dist/osem.service new file mode 100644 index 00000000..0c6ec304 --- /dev/null +++ b/dist/osem.service @@ -0,0 +1,13 @@ +[Unit] +Description=Open Source Event Manager +Wants=apache2.service +Before=apache2.service + +[Service] +User=osem +EnvironmentFile=/home/osem/events/current/.env.production +WorkingDirectory=/home/osem/events/current +ExecStart=/usr/bin/bundle exec puma -e production + +[Install] +WantedBy=multi-user.target diff --git a/docker-compose.override.yml.example b/docker-compose.override.yml.example index 3de3f9a6..f5dca21d 100644 --- a/docker-compose.override.yml.example +++ b/docker-compose.override.yml.example @@ -1,7 +1,6 @@ -# This file is generated by our Rakefile. Do not change it! version: '2' services: - web: + osem: build: args: CONTAINER_USERID: 13042 diff --git a/docker-compose.yml b/docker-compose.yml index 3d6fa7b2..8f31749c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,7 +10,7 @@ services: context: . args: CONTAINER_USERID: 1000 - command: /osem/bin/osem-init.sh + command: /osem/bin/osem-init.sh depends_on: - database ports: diff --git a/docker-compose.yml.production-example b/docker-compose.yml.production-example index e15206d8..73fa1ad1 100644 --- a/docker-compose.yml.production-example +++ b/docker-compose.yml.production-example @@ -1,29 +1,32 @@ version: "2" services: - database: + production_database: image: postgres environment: PGDATA: /var/lib/postgresql/data/pgdata volumes: - - database:/var/lib/postgresql/data/pgdata - osem: - build: . - dockerfile: Dockerfile.production - env_file: .env.production # see dotenv.example file + - osem_production_database:/var/lib/postgresql/data/pgdata + production_web: + build: + context: . + dockerfile: Dockerfile.production depends_on: - - database + - production_database ports: - - 3000:3000 + - 8080:3000 + env_file: .env.production # see dotenv.example file + environment: + OSEM_DB_HOST: production_database + command: /osem/bin/osem-init.sh volumes: - - .:/osem - - web-data:/osem/public/system - - web-assets:/osem/public/assets - - web-logs:/osem/log + - osem_production_web_data:/osem/public/system + - osem_production_web_assets:/osem/public/assets + - osem_production_web_logs:/osem/log # named volumes to persist data volumes: - database: - web-data: - web-assets: - web-logs: + osem_production_database: + osem_production_web_data: + osem_production_web_assets: + osem_production_web_logs: diff --git a/dotenv.example b/dotenv.example index e2b5c93b..ca6bbfa8 100644 --- a/dotenv.example +++ b/dotenv.example @@ -27,6 +27,11 @@ # The name of the database # OSEM_DB_NAME=osem_production +# The memached servers to use, default is a file based cache +# OSEM_MEMCACHED_SERVERS='cache-1.example.com,cache-2.example.com' +# OSEM_MEMCACHED_USERNAME='root' +# OSEM_MEMCACHED_PASSWORD='1234' + # The ruby version to use # OSEM_RUBY_VERSION=2.5.0 @@ -44,13 +49,15 @@ # OSEM_EMAIL_ADDRESS="no-reply@example.com" # The api key for transifex.com. -# See TRANSLATION.md for details +# See https://github.com/openSUSE/osem/wiki/Translation # OSEM_TRANSIFEX_APIKEY=1234 # The errbit host to post exceptions to # OSEM_ERRBIT_HOST=errbit.example.com -# The api key for the errbit host -# OSEM_ERRBIT_APIKEY=1234 +# The project to use on the errbit host +# OSEM_ERRBIT_ID=1234 +# The key for this project +# OSEM_ERRBIT_KEY=5678 # OMNIAUTH Developer Key/Secret for GOOGLE # OSEM_GOOGLE_KEY=1234 @@ -69,7 +76,7 @@ # OSEM_SUSE_SECRET=5678 # STRIPE Publishable/Secret keys -# test keys for development mode, live for production mode +# -> https://github.com/openSUSE/osem/wiki/Stripe # STRIPE_PUBLISHABLE_KEY=1234 # STRIPE_SECRET_KEY=5678 @@ -93,6 +100,7 @@ # Enable the usage of the devise ichain plugin # OSEM_ICHAIN_ENABLED=false +# OSEM_ICHAIN_BASE_URL=https://example.com # ReCAPTCHA keys # RECAPTCHA_SITE_KEY=1234 diff --git a/google-packaging.key b/google-packaging.key new file mode 100644 index 00000000..04298f55 --- /dev/null +++ b/google-packaging.key @@ -0,0 +1,235 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBFcMjNMBEAC6Wr5QuLIFgz1V1EFPlg8ty2TsjQEl4VWftUAqWlMevJFWvYEx +BOsOZ6kNFfBfjAxgJNWTkxZrHzDl74R7KW/nUx6X57bpFjUyRaB8F3/NpWKSeIGS +pJT+0m2SgUNhLAn1WY/iNJGNaMl7lgUnaP+/ZsSNT9hyTBiH3Ev5VvAtMGhVI/u8 +P0EtTjXp4o2U+VqFTBGmZ6PJVhCFjZUeRByloHw8dGOshfXKgriebpioHvU8iQ2U +GV3WNIirB2Rq1wkKxXJ/9Iw+4l5m4GmXMs7n3XaYQoBj28H86YA1cYWSm5LR5iU2 +TneI1fJ3vwF2vpSXVBUUDk67PZhg6ZwGRT7GFWskC0z8PsWd5jwK20mA8EVKq0vN +BFmMK6i4fJU+ux17Rgvnc9tDSCzFZ1/4f43EZ41uTmmNXIDsaPCqwjvSS5ICadt2 +xeqTWDlzONUpOs5yBjF1cfJSdVxsfshvln2JXUwgIdKl4DLbZybuNFXnPffNLb2v +PtRJHO48O2UbeXS8n27PcuMoLRd7+r7TsqG2vBH4t/cB/1vsvWMbqnQlaJ5VsjeW +Tp8Gv9FJiKuU8PKiWsF4EGR/kAFyCB8QbJeQ6HrOT0CXLOaYHRu2TvJ4taY9doXn +98TgU03XTLcYoSp49cdkkis4K+9hd2dUqARVCG7UVd9PY60VVCKi47BVKQARAQAB +tFRHb29nbGUgSW5jLiAoTGludXggUGFja2FnZXMgU2lnbmluZyBBdXRob3JpdHkp +IDxsaW51eC1wYWNrYWdlcy1rZXltYXN0ZXJAZ29vZ2xlLmNvbT6IRgQQEQIABgUC +Vw22fwAKCRCgQIMPf6xZkbLfAJ9ZMxlayKlf7Ib9UHhDUW6ch8RUdgCeKYRcKNnc +hXLLkXXJTfo+KEMKNaqIRgQQEQIABgUCVw228QAKCRAxRyw7MbfoA+dHAJ4n9t8Z +/wUFrirlMzDynUZLWNZPkQCfaxzTbjzUcd1OZmJb8IZZeaAT44+IXgQQEQgABgUC +V8lc6gAKCRDpBtJvEQtyOR7SAP0RzDZu4kMocqufUE3Q3Kn4ivpnskU4q/ccUxdW +S0npeAD/c2ZYqpGQldtxlxpvN01oMatartxP5TIyT95FqybZOIqIdQQQEQgAHRYh +BBXBtpK3EtxL8DzBusly7/23tmqKBQJa2uHAAAoJEMly7/23tmqKkoQBAOVn29Nd +UTB5Ea78Hz8TxPDhrE1opFrIjHRpTKh3VODcAQCd3azdBrSfP6GaE4q36uKQOexT +8ZJiXhNj0wC9J5xpW4h1BBARCAAdFiEEFcG2krcS3EvwPMG6yXLv/be2aooFAlrc +6egACgkQyXLv/be2aooX0gD7BNhwKdbhlP3fR/encwJo7QIuF6U1mhoGRKEj3I7I +IyAA/jf6yYXgIoXjnDwDZksDA4A69BBRN6DR6BJwpEcipg6LiQEcBBABAgAGBQJY +cuq2AAoJEFglKuGTAoZyWUwH/jMAAUqTS6MFNXiySTNyd89vrH/IAchFEOGEd0IF ++3ODosGKXU3Gw60Mhrq/OfCXreFiHGyg6zlbAyqm0GwZbO/hTIxvsCq7/aLPB+Yo +u6VvLkfYt5My/ArxaNnIeO/O4cesC48vgJaT71vMfG0zAu7Cf/gy0ZbEGb/D3veQ +hkRIO+D9er5UgpYA0X57SMatiLc5X1/DEZFTSyX/Wcn4QzGVG/qcdUGkZP32isS+ +05xFdCtsV5A5sIVYu7/HDFqkkGLgVamWHFCv7MzT2s9w73ybiM05WJUUL3lJ4oP5 +rOa35W1Vlgus/XuJ+KMpxltJot7Vo/VkWuosV5W8Aji7ADeJARwEEAECAAYFAlm3 +75AACgkQ9XNoIMINk64/LQf/SebRAMuXUccrkF6QzS7V03AhYF8iZOnZKkQu++Mx +XbPKXgbRgDQwvCkSM2E9L3OWn+8Nvw2umENCWwE9d/3H+J3fxmYWSg50GWtWKnpt +iquixcdig8afQ224PW+YilpetHR3MSZCfjt5HXTaRoGjNE87p2wr9VYHiTw37M1I +b8xH1y/8WtMwar8ln1V90qo4pZh5ejz+33EvnaCpQZMxqs3WXo/a6D2ftxJ6GFVV +I/MwPoZ29v27X3qvLQOcZRKW7N7NAxY2/uihklnibyGjORoVR3wyx/O4WLbfkxsm +cNfQyW39O/9SH7hoNV8egQfpXW+iDlXiiyKfzfhGlbKE8IkBHAQQAQIABgUCWuC9 +XAAKCRC6YwAM2dBTy2P7B/0b69UfuHNToyfnnjUhEthbpXjuxCN/s4yYUI/Kd/HE +TkorkSSsZa4KHyXpYJoCDbh7NCI6Zg1pJLcmI0fail8Jg9A45r8lyFaHC0kfkKrh +PElZ96MxRxqtVcBChxvQHlJX1pL1wIs+8EmtRwd2r3aPta7+AYWub4ninlfAEaSQ +TgH+kl1rzh3PQKE5/yhr81pW+Ahzky/KDuthN7HnyjApxNxIz7vjSIhcLOIYQRT/ +2fsDvjVGwqQdMEBu+27dPoWbNMVgnosr3m2H8J2iZMIyxr6IfM/WiQNyvgCDuRLQ +8kiZUkyCqbJruCMdrcPniOOwmqmsQB43/FNLJkEV8WJziQEcBBABCAAGBQJatwWb +AAoJEHkYry3TdFwCUBIH/0yKSDC/5t6OSEeygmt+mEPe/iZDt81mBzMID3ybg74U +tL/uFzhrfgcBHFCxSh/MDVA7IkX3GU7wQ/5TeiEDGqsDZXNfCbmvUcr3gwCV8ynM +E0i6NWwEQOiL2T+/XFT3n2msqTTqQLKtNVqnFZwGt2vjxGyqQcgFo5vngvJ2yIo5 +YUsDyWIVL/nett7AsPOUniODxtHtKKlkMUPAw3Y18f9hQelrVNJ1U+6EeVdzsN3c +mp+PkMK1HVeDyyjfcV/4MHIWypY5P2Z/IIis/RWbJYZZlcFoQrMzvtipZqrpdL1Z +zpVJmG1biluAQT0wUwiK3hOnOHB8nEoWYo0c6swwmKKJAhwEEAECAAYFAlrfzikA +CgkQmOQX33jNeqofUQ//f4TTmjHwCiGkrbl5TgsAD1HgYBq59CcOGzVGWvoXEaTn +u3bIiOJ2H3J6wr4XQ/8H5zj0TLbGxIueBQgebpNQCv2hzkHol6fUz6St75T4Bd2Z +aeZ7xqaFNqKZYu7yfMNeOVG/P/R+LVy+FzJxvtzg/oN6Ob3d9i2vopcQBuyf09Yx +CYClKcLaUSx+h3Le4lWEd8zHQ7qhqQaY8EmZHIpwT9Mjt8GbxJ1evuZ5Rt0JDq3A +r34ULW1/96gbZprm8mvEe9igKUhREW79A2WCPdTbdYKy2Ze7Z4kdb53DLkaTtW08 +497Nm9qalNCjLa/g+eAm2nDXmSLc+qGJDBHVgo26DhllzTooeIWZ87+jv7n5fjaM +WQTT1KdFcm+ztyWGjmBekYzjXDdxEgtiHn5J9hPR08QHhofAp74malkI9WOxdu53 +0CTdO/qiA8MCE/KnvLQP0pmgKIYnTtJ/e7RYUKUu1UOXpao13wouHg0KyD8gzVs7 +ajcxJWCcrivJ/nMoM49ksA1VDwDpR5TpI47VPUMUKMN7XnBrDqhsVIBB+lHqPCiX +4MylkTUbLUy6izLQt7nfyjG9of/vu3tIif5SML0QkPXSfVvZft6kKaRd3bOLz55H +d1hdluGVaioupLvSXCScSUtiHAJDxWVtkaYQ4FZD4zvqoO34+cVQGiynCi/ns4CJ +AhwEEAEIAAYFAlq4gi4ACgkQWIStaHlntpep0Q/9HmYnei65pN3wyIMMx5EriLoD +jnib4EgB4+j8wAMhtw/RIVlzuHXE/h6AdbOsxJ+z95OZjsvmLCL0XzEO3qQRZ1Bk +GU+W2qHMzfRaBYEDOrYRuuAjnxOF0rk9OWguGyNtqrWDQ27/BGOXBU+HSmOSj98k +qbpQYeaekDfTcbKymxr69iimroBhyRxpCIP6gmlQ2fbbqPpkyqX4cDdAfj8f3ftN +3bGdWpjj65Ugb78Cf/rqU+QuEW3egHIJZ9yr6XXKu3Mk5OfBXJz/uxK8g5Tutwja +++T6b1yiuPIb3NxxmWgIRuoRbxZc0UALWHNlpm+8/we5AXfZI0V8Wf67RR9oLyxP +R2N3EKVHRZ+RcWoNRrlOT0NhjufwrYaIc05zgbBkPD92Qdm99gJ3yreTtyCdx4PH +Mizh6odnjuIyrXqVGefEeWjSIxhKkJW2hf8zzMBmXfItN9QJEH3xH6n7mp94Xlv+ +TpqT9aSPGlxFuEnEa3Z8+IjlJ4CY6YOzDKgmKNy9G94dolBPT2rxfkJXAue5XLrI ++01ApZcg8UlVFWGp4Sc1SJVy9CmP0hXEh0KOqttq+vC8xGdh9lEyWzRpxjMRfKMi +fv0rH/D+lFou/GvKa66BQaHat1W9nghTEwf4O/kbQwJdzfcuHl2+PTqxcmZlcbap +b6RTcAKw39HS4HoYH0yJAhwEEAEKAAYFAleiq/oACgkQFxAKeYnLE9JWUw//UUef +5U1bWg1JP4aPb2eJqhRleLkptX6vFN6dNfASmKTb7ChIEamn6Vgk89z1ZKdIztUo +5RZQ+2lqEsu/ZEMTBwSyBa2r4I9Ss1zaimTOzEN55d1ZPNa7Kq3XpF2J57x0QmoJ +erraR9vMVPVGdjRQpx8gjoAO05PwDDxiNgrIHWtgsVdz9/M63czDIW/sWAtpdl1Y +Kigu4iPT7ZsDBH2MVtofQdTyMOS+L4jnnG98aUgVtrifET7jphAEuP1Lq3ZSFm/S +OiVcaIXxP7GQv/nBfH1cAHAM6jLyJkXIFBzHL9hTnB8tSNWILXDFJNqk0oEpF0i/ +UcYN/Rafwd09/KOQNysbiVju2E55OcEEmIiT/aLYBdAnxtRihkw4SU6fDCAZLywB +daEjMD2+6z8SlBo7IWkSuSjMqJGJTVsS0ojRGHUVsQbxX+Zb9MWdOfehQPsGpBn9 +pxyfNScaiYoriUycelxvFCANWttmyXnaLizKG/GfUNl9bb3Z52W1zjpPMHA4AQND +fhyncFyJ47R55bfXDeND3xfzPjSkAnZ7Vs3C6BzfaKdfuUjAiN7FUR/CYlfRTIwy +oexWb2SQ3dTvyMGKkb8G09hTDc6h9zPlKKSK+2770fAFfwmZ+xGpKnabvZe6HAA5 +Tp65BN0Fq+rP6LcJOSPPPz0BzswsJ6auYnQkx12JAjMEEAEKAB0WIQQmwuJkkOHC +mZpQOiVfsetKpGZBhwUCWtre8AAKCRBfsetKpGZBh8KwD/9fXgrBEV96Z6DJs5Nq +6aA8CLXT2295bAe4h/lIPAIplr9rin1EDXbs+L+eq1hx5aW00upGoi62zfcxr2qi +xS4TT6jfF94PZUpeG32yb/ZCxD81sDg6sYFG5zj2XgN7AuaMZtL6OPd48MMkYKk3 +Za/SE4JNCpjI7xTZpOm/2N3WYR7XD3Tgv/WppA6whl36lurpTUcl+zztMIwn0vN/ +m/fOi143J//wjCL+Mk898nIz+t1X4cf0M9fWyvuoh5PKc6efw0pCDmqnr3oP21+D +EeK4nMi7dMnX4DdehvtgcXu8xu40ai32cQKkesYBTaKYchiz3QA8RvbU0PYVrtKj +5fNBxE0GH19XuxAIif2rpg/h6ZD084emFfj3xd2bxEP+SeSeZZLk1ZlWWBYZnhlF +UalgF1RUqRBWGtLJ0MPlSPd7MCnFb9Y7Sh6ulhmLA+zUMhkWjUmDQG4lpyaOoFZ7 +ESoNaeOPCscNPWLktbnmCM+BnB9bLKt4Ofci6CrP6gmOWyqFpvl+D+R5qHHaNujJ +o6kz4gqZHbKnwuce2QJO38YmGct8eorZ9UOnKnwY2Bi0O5pT6AzJ6fp+aC6zDr2W ++5Q+K9PppZWouXfJucoZekfhj/jaYhE6QtqlvaHHQnGyZjUfM9xIQOC1B52foHKy +DBkJ/o7bWblYhgKFdNaXQ8y5cokCMwQQAQoAHRYhBGXSGhgQXpf7tOdzdDh3LuD9 +zKvFBQJa4Qp0AAoJEDh3LuD9zKvFMTEP/3bjkhUsPQDvcQBqViBppc2i2OtBUs1/ +t2HW2gcbjVj9PmGw22iMWPSF9kuHBtV2d0wgregnWorg/nKWZwhpl3T6g/1cqKBQ +mea7HlS50EijtxPWtFp6FDrJXTYwt+d5vpOE2ymrtDroX22uPo89thq5XfE4hVAH +bZ2reM4rwRRXPO29O97qpDtBFCtt/SzO56tA8PN/r2ykYBILb6YRFRen6R6DFqG2 +UDTTbUXWlViRgIDM8eaW/NDd15nwvIp9dBllaFsQEVI9VKv99Lqp1d13XX6vUCcF +ZxO3zF6r/466WC0n0eXo5li8Azl3Na/j6I7DSG9pYxFuCH/miuGMtR5SmV4x8MeJ +ERVawbbmy7CUrIGakDkzL7RfHikKtKh1Gb4h1JUaDDRYPkpB5bocERe2WcNC11w6 +R4QZmiYqHtbzru1i1IHRhijT3Oc2fh1VyL2NkHRar6UBeWyFnyub5BdKBREMNu7w +jvgx66QOHBnAlG0VYszzwg8hBaXICaMWo6BmigZBvGoIkGopb/GwPjxVUe3drAnr +6HOCwVgz4L3r7PwrolHYVCFMg8+lfQ69KSMWGqhpXNn11VjIyY20HaO8xBJm4h5b +3nV5Vf/C/JeaLerT4ZiF2+zSb4wqqjnKsUaMGb2VQyOwKxmGMuFnRaU1y9zz9fQZ +DoViEwW8B1/OiQIzBBABCgAdFiEEepI875g6dg7J2cQAp0YQ1OZ6GfAFAlrg6Y0A +CgkQp0YQ1OZ6GfA77g//ZBrTRALdwM7QrImkfc+Ir1Z5N654Y7PTSz03KGU3I/Vj +MNm7koBCbqwtRHbu7UXIVmXfuW/k9cspj4Brrrl7P8RsalOiB0ygDfvxpQJQqqx9 +sXVs9bDFlkyUDH9HxDK5kaB7vKvD43tF/UkqHbpIftcBwX5kV2DP0vpZziYyemIr +BmSX2bQQa7OcBg+Eh3sFppTpWBilJy1vu7CC05ZbB6MGvML0xxYKY92X7XbvJR4w +J8efKVoyrWBqMfoG9CWNiWvznEfAghuCU0VkH9OrQ3pS7WazTQOMqjYJ4qYk9LuC +0OhTnhlbgPn+eeKFhOf2AO//YkCpOyiiCNMCggjXmn6egnMfi3A1hIkO3lbOdCtg +NFXxC7N6SnjSPJLlCrdUs/9JABGoeNX8SmDu9OIwDYu7jQDV3GrkfgbREJ1ZsKTN +7bZAnwJZl2gKQeP0kl7PswPqbPYLl6vdM1aJJkJmZFqok9sr5D3ajdkIiCBb+U3u +687Nm7RRmZIe27wT3jGSuO2GrJfq2/Rz+w07Qc/QsloRQyKPi3qpnfNNOG/Wr/p2 +1ntLmDVCKSRd/8gnuV2bJ1NEyvAdOXuiOkb785WgbdIHtnWSCHdoziCdifP8zPpP +B6gmdH7co580Lfk7u22BR3Jb09Im+tZmv2ZvDPzzJh/9/x7EE2gmYRzPhzMKFSuJ +AjMEEAEKAB0WIQTP3lhs0NlLR3oYgY4qYhaY0j2SOgUCWtrHSAAKCRAqYhaY0j2S +OhNwEACa/0peaWk1zAtMSwEtzPfDIW0ZSQsjBOeXHN37jmrZsqFcfPJ67+W4Cxhl +hy3iYBXzOQmLY48V9ZcY8ntweMLq9YsCe7+6TqRtc2J+AASloVWum7Xjny81WOgp +Jup46Jug2Vu6qmxImdaOa4qq34P6j2KcnQCXh1vTQhnhYrEQfJdeRw/nlDKiuYRL +fNyHxcrdntr3tEcV1IlocftIH/cbLg2Uj/nzJrwNhGqSvRYOncHKgyh7iM3iG0K1 +48WrXZlUVWqqFuVpyqer7M7eRqPNJXIyfiRvgK3DHfySrFpxk63fKejYGuQvmp4Q +pWiFWQ6JTjIISLNlsrVjhaLk60ms38NwM3WUw26GWgaf1/f5z2L/Udix9JoFfLJD +kCor9QLyWHZR7r0riZuZHlLWiYy7cm2PsxWI2o4DuuYU97Cb44jqjOooQTlsXoh/ +aqTn5Y8QpXxWywWanWuHCoppCEanPjhpP8ZqSZYdfx6RQAufXX2GN0t47NU/s/6d +svQbUlU0BG3qx3dr8XCo6f976+0H/oRUNEdPlUJpLT3TNMiqhY86u/KaidfZWAL0 +jbVFSn3oYim+uQ5POb9kglFmKPdMt585z1l2HVR0n+uXeEsBOlJUui2wuQghdBkO +DVTXkeq6xmrIobo50KJ6O40gcDxfque/cjc551m/3faZLvDP/IkCMwQQAQoAHRYh +BNskc+jgZQ59A+3qnON+2vHrT2C7BQJa3UzvAAoJEON+2vHrT2C7C7IQAJuh4xEh +aGwtiHIB7wgui9WzAFBV+5LcM8LDp1AsWIH3MpSnp/hD1GcMvrYp8REM631/ixI5 +evtJDbjDJsz01ul9yBSG6/f1O416iVESifY9MoCxYzW7Vj8Rg8+/gXhizlkhayBm +knNY0fDcT+Yy5DtjAq5/FiIM6tvTFzZYS9tpPfmD75Ok7K85aP3v/IksAzKn710u +UC8oS2YgWqSxtmkIUzY12OvuLHEjDh+c2FMcsL8yM9kGc7e8uuf4znQYiax9q7eD +opOf+qWcpdpoaMP3msq3XeU7JqyOOL0S8jrE4rpJUySAJOq4OkGtTWh3QA4zs2Kc +UtqQJn9SI0b1bb4dieDH45gUgquedrhPzMpWfiPPerdmXnRk4aoz8Qjtbvw3VG7b +6FOfIXww7Do7hcJK9vb/4uEmAuLNcK/oMwsXhuBA2MXEWSbRTNqghEw7YxX3TbS8 +yVZ/VwY4Iq8RGCnUPpehdPOxaIi9J/3l0AuqaDkhP26A+ukKZutnaaSxXVNMELrG +s/oH/ybeFMOR/wyof3y4wnfLldLAtTfJyEuV8mqAkxq6XYY8/GfC7B4Aj+QbFFOn +AVq3oe8p2UAF1HZ79FyyXDx5RiqvTmJtE449qJNqCWjlNtuHtggSXw3B59H627oU +++PseQ8SfLml5D3oxLRDS+2scTBHqEm56mUpiQIzBBABCgAdFiEE6jeLdZoA8VVM +NsD5zP1hBvPo86EFAlrwuaMACgkQzP1hBvPo86HNTBAAitL1/z7WK++d4nNSdx/5 +rPwNgGx1MmZSAEU87i4iAngoe7QFlUdWu/CLKa+ts+7M35zKISjvJFXpRAbcbfmv +uIUosivwc+uWl1DJQnBjg3dk5f/YZFcrazM/rqwr5DkpeI7uo7r9qOFLrMsWArIk +LiuGMtOlAogXqSdv8Y14EVy4g+LnfxMoVjR9it5pSy1yDybIMNuTiBeugWYBwx9u +Z/fD2STjOvc054FLAi6rwHgtSwE1Mwmg+TcQFPnojk8HsuPQgjiCiVQV1N6n+q8n +VPelkf5Ph75lp+oB8A3mhvXrynsrBR1O2/kSOc6XNZRQEV+lK9apIwuKhXCs58YG +9igT+9iwWhQXdAMeEFNIrKJJg7yT9QNSasNhR2knPSdu9hYXRHLxq2Zs2CksrtoQ +/XXo4AZToDCc9c4s24IflhIy1W1y7se5vUsldgeBCK8JW2vmMt/i3iZAQXdImDHW +lGgBBqWh01U8czzUD6JqnG8N2ULOHFO7+0xVC6E5tLT0lmt/FpFkd50w//E9gl8e +ibFsyOzVGTapClK42tn5QOl9XKeuJGeBsa87mQtSpuhE4WLI6d1MOdUsHZ9Gfy94 +m4OSyEGOR6c1MeOUAseU38KuA7LlGZRxuZl+jkjgCTDr9JdcMdovo/5MEW0Usaqf +cLmw43kgTzFilUz12mbj6aOJAjgEEwECACIFAlcMjNMCGwMGCwkIBwMCBhUIAgkK +CwQWAgMBAh4BAheAAAoJEHch9jvTi0eW5CAP/RELE/OAoA4o1cMBxJsljWgCgDig +2Ge91bFCN0vExLcP0iByra7qPWJowXDJ5sCjUBnCkrxGo5D15U7cW5FC0+qWU73q +0AuG3OjKDQ49ecdRkYHwcvwWQvT5Lz3DwOGW4armfEuzWXcUDeShR7AgfcTq+Pfo +o3dHqdB8TmtNySu/AdJFmVH/xTiWYWrOSibhyLuaSW/0cTkHW0GDk06MlDkcdkTz +hO5GMDO7PUxBgCysTXFR0T9TVWDo9VwvuMww2pE5foleA0X6PD/6GQpy3aX2xry8 +rhFvYplEa5zwXhqsscdKXlp1ZPZ4PMvvwe495mY9n/1Rx1TmMvIcLHKP61sURMOv +e97Gipk/iD6oaeeT8I0khexHCQy7JMROoPMrz5onVOt2rAGZScIZsm5FYGSt9eDK +BWI6qpJ/5QoVhkRWjOXOchZlJHo+kLdg6jq2vOnIlFnXo0p6Rqf/IEq5PMh70vVZ +pk4tNYNy4zRx03ZTA9qXRLW+ftxSQIYMY5eCZ31lqSH4EjqgtUG+zn2A6juKayb1 +nkt2O3F1wWOm6oTzNsAP5LdReJRlw151Jp4U4ftGtw7ygq+nvokXL7YLuu8sbFqf +FXcTPrAZa5M9gnC7GCnIQyF/WvqUnrcaC1jpqBc+pkSJhROhN12QY8Po8AT8/UaU +h/dPIiW5A4o8pOPEuQINBFcMjcgBEACrL9gHhdr6gQX4ZMA5slp628xOrHCsdLO5 +4WNdPRKeFHXJqSSJi3fs8FxBWI4FnejeKUGbF+MrOlFpKqELxaMje7bwZyap3izz +tZHszP3YmOoTBJvREGKdCkL82cLsChYD/PrgE8crvkhSnq9evcsKAnziMxg/wDCC +hUL3Evqo29BeoB81f+E9wkrUTMCT/kVxt3pGRalKX0UhrtKrpm8yRfjufJfwjkdw +gvinkRGZ2GrWHj4LzMbi9/udYaJZ66Yw0hEU4USxUB9vNtmSFrb4EB91T2rhc68d +gQ4jYBI7K4Ebb8XaWAxb+IAq31l1UkiEA32F4qUMoL6rChB4y6nHxOnTvs+XEb5T +BwXVogjLRKTQs5U/HV9l7j+HAchk5y3im2N2UKmMxHqotvPZZUZPdaCRxUedQf9g +R0yLZV+U9BcDuwjzL/zjrthNZYlEGJ6HZ/TLSTp4dDH+uXuLqMVWy5iquKtnbrnN +TQtv5twD+Ajpgy60YLOJ9YaiJ4GjifOpzSk83e1rJ3p/pX6B5NWQinVLZJzxyeOo +h3iMjdmCDSnEXLrCmYv5g6jyV/Wbd4GYFuMK8TT7+PQdWLcbZ/Lxc5w0s+c7+f5O +fmKXO5KPHnnUsrF5DBaKRPjScpwePQitxeIglUgEMDkNruBhu1PzCxd3BtXgu++K +3WdoH3VcgwARAQABiQREBBgBAgAPBQJXDI3IAhsCBQkFo5qAAikJEHch9jvTi0eW +wV0gBBkBAgAGBQJXDI3IAAoJEBOXvFNkDbVRQSYP/0Ewr3T7e0soTz8g4QJLLVqZ +DZdX8Iez04idNHuvAu0AwdZ2wl0C+tMkD7l4R2aI6BKe/9wPndk/NJe+ZYcD/uzy +iKIJQD48PrifNnwvHu9A80rE4BppQnplENehibbWaGNJQONGFJx7QTYlFjS5LNlG +1AX6mQjxvb423zOWSOmEamYXYBmYyMG6vkr/XTPzsldky8XFuPrJUZslL/Wlx31X +Q1IrtkHHOYqWwr0hTc50/2O8H0ewl/dBZLq3EminZZ+tsTugof0j4SbxYhplw99n +GwbN1uXy4L8/dWOUXnY5OgaTKZPF15zRMxXN9FeylBVYpp5kzre/rRI6mQ2lafYH +dbjvd7ryHF5JvYToSDXd0mzF2nLzm6jwsO847ZNd5GdTD6/vcef1IJta1nSwA/hh +Ltgtlz6/tNncp3lEdCjAMx29jYPDX+Lqs9JAxcJHufr82o6wM9TF24Q8ra8NbvB6 +3odVidCfiHoOsIFDUrazH8XuaQzyZkI0bbzLmgMAvMO6u1zPfe/TK6LdJg7AeAKS +cOJS38D5mmwaD1bABr67ebA/X5HdaomSDKVdUYaewfTGBIsrWmCmKpdb+WfX4odF +pNzXW/qskiBp5WSesKvN1QUkLJZDZD1kz2++Xul5B97s5LxLTLRwvgLoNaUFr3ln +ejzNLgdBpf6FnkA59syRUuIP/jiAZ2uJzXVKPeRJqMGL+Ue2HiVEe8ima3SQIceq +W8jKS7c7Nic6dMWxgnDpk5tJmVjrgfc0a9c1FY4GomUBbZFj+j73+WRk3EaVKIst +y+xz48+rlJjdYFVCJo0Jp67jjjXOt6EOHTniOA/ANtzRIzDMnWrwJZ7AxCGJ4YjL +ShkcRM9S30X0iuAkxNILX++SNOd8aqc2bFofyTCkcbk6CIc1W00vffv1QGTNjstN +pVSl9+bRmlJDqJWnDGk5Nl4Ncqd8X51V0tYEg6WEK4OM83wx5Ew/TdTRq5jJkbCu +2GYNaNNNgXW7bXSvT5VINbuP6dmbi1/8s0jKJQOEBI3RxxoB+01Dgx9YdNfjsCM3 +hvQvykaWMALeZIpzbXxV118Y9QQUIRe2L+4XZACEAhWjj2K1wP7ODGTQrrM4q4sI +w1l3l7yO9aXXN7likAAddT4WEpGV0CiorReOJ1y/sKJRJSI/npN1UK7wMazZ+yzh +xN0qzG8sqREKJQnNuuGQQ/qIGb/oe4dPO0FihAUGkWoa0bgtGVijN5fQSbMbV50k +ZYqaa9GnNQRnchmZb+pK2xLcK85hD1np37/Am5o2ggoONj3qI3JaRHsZaOs1qPQc +yd46OyIFUpHJIfk4nezDCoQYd93bWUGqDwxI/n/CsdO0365yqDO/ADscehlVqdAu +pVv2uQINBFiGv8wBEACtrmK7c12DfxkPAJSD12VanxLLvvjYW0KEWKxN6TMRQCaw +LhGwFf7FLNpab829DFMhBcNVgJ8aU0YIIu9fHroIaGi+bkBkDkSWEhSTlYa6ISfB +n6Zk9AGBWB/SIelOncuAcI/Ik6BdDzIXnDN7cXsMgV1ql7jIbdbsdX63wZEFwqba +iL1GWd4BUKhj0H46ZTEVBLl0MfHNlYl+X3ib9WpRS6iBAGOWs8Kqw5xVE7oJm9DD +XXWOdPUE8/FVti+bmOz+ICwQETY9I2EmyNXyUG3iaKs07VAf7SPHhgyBEkMngt5Z +GcH4gs1m2l/HFQ0StNFNhXuzlHvQhDzd9M1nqpstEe+f8AZMgyNnM+uGHJq9VVta +NnwtMDastvNkUOs+auMXbNwsl5y/O6ZPX5I5IvJmUhbSh0UOguGPJKUu/bl65the +ahz4HGBA0Q5nzgNLXVmU6aic143iixxMk+/qA59I6KelgWGj9QBPAHU68//J4dPF +tlsRKZ7vI0vD14wnMvaJFv6tyTSgNdWsQOCWi+n16rGfMx1LNZTO1bO6TE6+ZLuv +OchGJTYP4LbCeWLL8qDbdfz3oSKHUpyalELJljzin6r3qoA3TqvoGK5OWrFozuhW +rWt3tIto53oJ34vJCsRZ0qvKDn9PQX9r3o56hKhn8G9z/X5tNlfrzeSYikWQcQAR +AQABiQREBBgBAgAPBQJYhr/MAhsCBQkFo5qAAikJEHch9jvTi0eWwV0gBBkBAgAG +BQJYhr/MAAoJEGSUxtaZfCFeW4kP/iZq+blRDzgRzOw16x80vyBjfPOUKd++dSUk +cr4Khi5vjBygNdVSWcKZaBKVkdBmCvf+p9bYwzfL+RdxvGEv8WKNTNjdaWcJ2chU +2O4H5Am3QsduQ/sSf+jTzlnMe7NpfF9n3uo34o+xEFOOcnyF3cHrhxWOCde9rX6k +bnUQriIMXZteJY8e9Rs+Iv46DoL1eOlavAgDUJbIf/iLt219OdtWI7ZqopA0d+tc +n7FL3fwuvyvn5WZRYHIerB4EYgBI6bCwl5JQejORlhuYx1oknyPjnzPJ9Los74ch +rf7OHOJ06iIQf1zlC9V/niA2xiM9NwePtTQOCTEJVB6IEoEtH6rozpAdriprH9fR +nZkJxINNnCoYk1op9wVh3xfUHbOCvGQbB54cqN+amp9dEquCAe6Yt1WodTspL1zP +XJ5Mv43Dud76TNEwQDywuebg4NFQnBTPXZGpLQYbUVhXSuMlVZXNEUx8xSz7vECm +0S4x2h12RBKbK2RfI4oCq/wpD1dQRsZaKSYLFbZw5j2yk6nBBrtfahd7sWVX1F+Y +disbTeT5iUhESAWqW9bCyCnNRFy6V34IgW9Pe9yLu8WbVSJAFvnALxsc6hGyvs5d +bXbruWKmi5mvk6tCFWdFlBVrrhx1QgqMtcS3jv3S7GHyCA3CS1lEgsifYkeOARAg +J1hZ5BvUurUP+wb66lIhDB0U9NuFdJUTc6nO/1cy3i9mGCVoqwmTcB1BJ9E1hncM +UP1/MvrAgkBBrAWJiD2Xj9QV/uBozA7nLxrV7cf1de9OLgH4eNEfX25xj8BBPYny +VyHsyk5ZHDhjj9SaurfvlFWYi13i5ieMpyLVJV4+r2Wi1x1UgKVAlB78sHYnbDzS +oHPLBcIxtIKp30LJ0PEkat8SG7G2wgtv1RdhmcZEBV05vMnrGGO991e+pKzRNPYH +8rD3VQKJlvaFwsJuBTW42gZ3KfpUNKI2ugCcnRNpoHFWNCrzlJ0CFI48LMlmUSs+ +7i/l+QGleaLKQxRTNNpAmevLrS7ga4Iq0IEqxey6VW6RSk/Z1Z37J8B7PISSR0rZ +n6TeyQgFWf/FOLw6OtwOquGmMeGSqj2UzxybygtsvUZz0BxYymoWFd4F8sp43oL2 +TXU6Wp7QIpBaFgkSf/UQxfR6wcQ3ivafeS1lg8vUFuMfuMLto6T0JiZw8uKSuDWl +tSReF+FXVnhawz72BZMy8RIoshGdpWHn/YbN6L+JOuxZnvkMAZvSLT3c0H4XCDYt +EfK2mJMqD2ynX5tGR8Fy3GAaEjhx36TvzTjCXRmJ+FnlSW1p77x+UjFUFcpY8skv ++f0Gip30iynAb1hoAdibIDab612OWi/4vX0DaM6t68Uq8rsabeJYsZG4 +=EXOv +-----END PGP PUBLIC KEY BLOCK----- diff --git a/lib/tasks/data.rake b/lib/tasks/data.rake index 08d2b8c8..2e9863ed 100644 --- a/lib/tasks/data.rake +++ b/lib/tasks/data.rake @@ -17,6 +17,14 @@ namespace :data do nullify_attribute(events_room, 'room_id') end + desc 'Drop all ahoy events' + task drop_all_ahoy_events: :environment do + class TmpAhoy < ActiveRecord::Base + self.table_name = 'ahoy_events' + end + TmpAhoy.delete_all + end + def nullify_attribute(collection, attribute) puts "Will nullify #{attribute} in #{ActionController::Base.helpers.pluralize(collection.length, 'event')}." if collection.any? diff --git a/lib/tasks/db.rake b/lib/tasks/db.rake index 89299227..39db898f 100644 --- a/lib/tasks/db.rake +++ b/lib/tasks/db.rake @@ -3,16 +3,13 @@ namespace :db do desc 'Bootstrap the database for the current RAILS_ENV (create, setup & seed if the database does not exist)' task bootstrap: :environment do - puts 'Bootstrapping the database...' - begin - # Only do this if the database does not exist... - Rake::Task['db:version'].invoke - # rubocop:disable Style/RescueStandardError - rescue - # rubocop:enable Style/RescueStandardError - Rake::Task['db:create'].invoke + Rake::Task['db:create'].invoke + if ActiveRecord::Base.connection.tables.empty? + puts 'Bootstrapping the database...' Rake::Task['db:setup'].invoke Rake::Task['db:seed'].invoke + else + puts 'Database exists, skipping bootstrap...' end end end diff --git a/lib/tasks/rubocop.rake b/lib/tasks/rubocop.rake new file mode 100644 index 00000000..b575cd54 --- /dev/null +++ b/lib/tasks/rubocop.rake @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +unless Rails.env.production? + require 'rubocop/rake_task' + + RuboCop::RakeTask.new(:rubocop) do |task| + task.patterns = [] + task.options = ['--display-cop-names'] + end + + namespace :rubocop do + desc 'Generate .rubocop_todo.yml' + task :auto_gen_config do + sh 'rubocop --display-cop-names --auto-gen-config --auto-gen-only-exclude' + end + end +end diff --git a/lib/tasks/several_schedules.rake b/lib/tasks/several_schedules.rake index 759951f7..9c58942e 100644 --- a/lib/tasks/several_schedules.rake +++ b/lib/tasks/several_schedules.rake @@ -6,8 +6,8 @@ namespace :data do task move_events_attributes: :environment do Program.all.each do |program| schedule = Schedule.create(program: program) - program.selected_schedule = schedule - program.save + program.selected_schedule = schedule unless program.selected_schedule + program.save! program.events.each do |event| unless event.start_time.nil? && event.room_id.nil? # we can not use .room as this relation has been removed diff --git a/lib/tasks/version.rake b/lib/tasks/version.rake index 08a0b2ec..0827e6a5 100644 --- a/lib/tasks/version.rake +++ b/lib/tasks/version.rake @@ -10,8 +10,12 @@ namespace :data do version.update_attributes(conference_id: version.item_id) elsif version.item_type == 'Event' - event = (version.item || version.reify || version.next.reify) - + event = version.item + unless event || Event.find_by(id: version.item_id) + puts 'Not updating versions of deleted event...' + next + end + event ||= (version.reify || version.next.reify) conference_id = if event.try(:program) event.program.conference_id # Event had attribute conference_id before it was replaced with program_id diff --git a/spec/controllers/admin/booths_controller_spec.rb b/spec/controllers/admin/booths_controller_spec.rb index f9d5358e..f9c528a8 100644 --- a/spec/controllers/admin/booths_controller_spec.rb +++ b/spec/controllers/admin/booths_controller_spec.rb @@ -13,14 +13,14 @@ describe Admin::BoothsController do describe 'GET index' do it 'does not render admin/booths#index' do - get :index, conference_id: conference.short_title + get :index, params: { conference_id: conference.short_title } expect(response).to redirect_to(user_session_path) end end describe 'GET show' do it 'does not render admin/booths#show' do - get :show, id: booth.id, conference_id: conference.short_title + get :show, params: { id: booth.id, conference_id: conference.short_title } expect(response).to redirect_to(user_session_path) end end @@ -32,7 +32,7 @@ describe Admin::BoothsController do end describe 'GET index' do - before { get :index, conference_id: conference.short_title } + before { get :index, params: { conference_id: conference.short_title } } it 'assigns attributes for booths' do expect(assigns(:booths)).to eq([booth]) @@ -44,7 +44,7 @@ describe Admin::BoothsController do end describe 'GET new' do - before { get :new, conference_id: conference.short_title } + before { get :new, params: { conference_id: conference.short_title } } it 'assigns attributes for booths' do expect(assigns(:booth)).to be_a_new(Booth) @@ -57,11 +57,11 @@ describe Admin::BoothsController do describe 'POST #create' do context 'successfully created' do - before { post :create, booth: attributes_for(:booth), conference_id: conference.short_title } + before { post :create, params: { booth: attributes_for(:booth), conference_id: conference.short_title } } it 'creates a new booth' do expected = expect do - post :create, booth: attributes_for(:booth), conference_id: conference.short_title + post :create, params: { booth: attributes_for(:booth), conference_id: conference.short_title } end expected.to change { Booth.count }.by(1) end @@ -75,16 +75,16 @@ describe Admin::BoothsController do end it 'shows success message' do - expect(flash[:notice]).to match('Booth successfully created.') + expect(flash[:notice]).to match("#{(t 'booth').capitalize} successfully created.") end end context 'create action fails' do - before { post :create, booth: attributes_for(:booth, title: ''), conference_id: conference.short_title } + before { post :create, params: { booth: attributes_for(:booth, title: ''), conference_id: conference.short_title } } it 'does not create any record' do expected = expect do - post :create, booth: attributes_for(:booth, title: ''), conference_id: conference.short_title + post :create, params: { booth: attributes_for(:booth, title: ''), conference_id: conference.short_title } end expected.to_not change(Booth, :count) end @@ -94,13 +94,13 @@ describe Admin::BoothsController do end it 'shows flash message' do - expect(flash[:error]).to eq("Creating booth failed. Title can't be blank.") + expect(flash[:error]).to eq("Creating #{t 'booth'} failed. Title can't be blank.") end end end describe 'GET #edit' do - before { get :edit, id: booth.id, conference_id: conference.short_title } + before { get :edit, params: { id: booth.id, conference_id: conference.short_title } } it 'renders edit template' do expect(response).to render_template('edit') @@ -113,13 +113,13 @@ describe Admin::BoothsController do describe 'PATCH #update' do context 'updates suchessfully' do - before { patch :update, id: booth.id, booth: attributes_for(:booth, title: 'different'), conference_id: conference.short_title } + before { patch :update, params: { id: booth.id, booth: attributes_for(:booth, title: 'different'), conference_id: conference.short_title } } it 'redirects to admin booth index path' do expect(response).to redirect_to admin_conference_booths_path end it 'shows success message' do - expect(flash[:notice]).to match 'Successfully updated booth.' + expect(flash[:notice]).to match "Successfully updated #{t 'booth'}." end it 'updates booth' do diff --git a/spec/controllers/admin/cfps_controller_spec.rb b/spec/controllers/admin/cfps_controller_spec.rb new file mode 100644 index 00000000..617417a1 --- /dev/null +++ b/spec/controllers/admin/cfps_controller_spec.rb @@ -0,0 +1,28 @@ +require 'pry' + +# frozen_string_literal: true + +require 'spec_helper' + +describe Admin::CfpsController do + let!(:today) { Date.today } + let!(:conference) { create(:conference, start_date: today + 20.days, end_date: today + 30.days) } + let!(:organizer) { create(:organizer, resource: conference) } + let(:cfp) { create(:cfp, program: conference.program) } + + before { sign_in(organizer) } + + describe 'POST #create' do + it 'successes' do + post :create, params: { conference_id: conference.short_title, cfp: { cfp_type: 'events', start_date: today, end_date: today + 6.days, description: 'We call for papers, or tabak, or you know what!' } } + expect(flash[:notice]).to match('Call for papers successfully created.') + end + end + + describe 'POST #update' do + it 'successes' do + patch :update, params: { conference_id: conference.short_title, id: cfp.id, cfp: { end_date: today + 10.days } } + expect(flash[:notice]).to match('Call for papers successfully updated.') + end + end +end diff --git a/spec/controllers/admin/comments_controller_spec.rb b/spec/controllers/admin/comments_controller_spec.rb index 702b7396..daffa788 100644 --- a/spec/controllers/admin/comments_controller_spec.rb +++ b/spec/controllers/admin/comments_controller_spec.rb @@ -6,8 +6,7 @@ describe Admin::CommentsController, type: :controller do # It is necessary to use bang version of let to build roles before user let(:conference) { create(:conference) } - let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } - let(:organizer) { create(:user, role_ids: organizer_role.id, last_sign_in_at: Time.now - 1.day) } + let(:organizer) { create(:organizer, resource: conference, last_sign_in_at: Time.now - 1.day) } let(:participant) { create(:user) } let(:event) { create(:event, program: conference.program) } let(:comment) { create(:comment, commentable_type: 'Event', commentable_id: event.id) } diff --git a/spec/controllers/admin/conferences_controller_spec.rb b/spec/controllers/admin/conferences_controller_spec.rb index 4d8bb060..c89b646c 100644 --- a/spec/controllers/admin/conferences_controller_spec.rb +++ b/spec/controllers/admin/conferences_controller_spec.rb @@ -7,33 +7,33 @@ describe Admin::ConferencesController do # It is necessary to use bang version of let to build roles before user 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) } - let(:organizer) { create(:user, role_ids: organizer_role.id) } - let(:organizer2) { create(:user, email: 'organizer2@email.osem', role_ids: organizer_role.id) } + let(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } + let!(:organizer) { create(:organizer, resource: conference) } + let!(:organizer2) { create(:organizer, email: 'organizer2@email.osem', resource: conference) } let(:participant) { create(:user) } 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') + patch :update, params: { id: conference.short_title, conference: attributes_for(:conference, title: 'Example Con') } expect(assigns(:conference)).to eq(conference) end it 'changes conference attributes' do - patch :update, id: conference.short_title, conference: + patch :update, params: { id: conference.short_title, conference: attributes_for(:conference, title: 'Example Con', - short_title: 'ExCon') + short_title: 'ExCon') } conference.reload expect(conference.title).to eq('Example Con') expect(conference.short_title).to eq('ExCon') end it 'redirects to the updated conference' do - patch :update, id: conference.short_title, conference: - attributes_for(:conference, title: 'Example Con') + patch :update, params: { id: conference.short_title, conference: + attributes_for(:conference, title: 'Example Con') } conference.reload expect(response).to redirect_to edit_admin_conference_path( conference.short_title) @@ -43,7 +43,7 @@ describe Admin::ConferencesController do mailer = double allow(mailer).to receive(:deliver) conference.email_settings = create(:email_settings) - patch :update, id: conference.short_title, conference: attributes_for(:conference, start_date: Time.zone.today + 2.days, end_date: Time.zone.today + 4.days) + patch :update, params: { id: conference.short_title, conference: attributes_for(:conference, start_date: Time.zone.today + 2.days, end_date: Time.zone.today + 4.days) } conference.reload allow(Mailbot).to receive(:conference_date_update_mail).and_return(mailer) end @@ -51,9 +51,9 @@ describe Admin::ConferencesController do context 'invalid attributes' do it 'does not change conference attributes' do - patch :update, id: conference.short_title, conference: + patch :update, params: { id: conference.short_title, conference: attributes_for(:conference, title: 'Example Con', - short_title: nil) + short_title: nil) } conference.reload expect(flash[:error]) @@ -63,9 +63,9 @@ describe Admin::ConferencesController do end it 're-renders the #show template' do - patch :update, id: conference.short_title, conference: + patch :update, params: { id: conference.short_title, conference: attributes_for(:conference, title: 'Example Con', - short_title: nil) + short_title: nil) } expect(flash[:error]) .to eq("Updating conference failed. Short title can't be blank.") @@ -77,24 +77,24 @@ describe Admin::ConferencesController do describe 'GET #edit' do it 'assigns the requested conference to conference' do - get :edit, id: conference.short_title + get :edit, params: { id: conference.short_title } expect(assigns(:conference)).to eq conference end it 'renders the show template' do - get :edit, id: conference.short_title + get :edit, params: { id: conference.short_title } expect(response).to render_template :edit end end describe 'GET #show' do it 'assigns the requested conference to conference' do - get :show, id: conference.short_title + get :show, params: { id: conference.short_title } expect(assigns(:conference)).to eq conference end it 'renders the show template' do - get :show, id: conference.short_title + get :show, params: { id: conference.short_title } expect(response).to render_template :show end @@ -103,11 +103,11 @@ describe Admin::ConferencesController do create(:event, program: conference.program) workshop = create(:event_type, title: 'Workshop', color: '#000000', program: conference.program) lecture = create(:event_type, title: 'Lecture', color: '#ffffff', program: conference.program) - get :show, id: conference.short_title + get :show, params: { id: conference.short_title } expect(assigns(:event_type_distribution_withdrawn)).to be_empty create(:event, program: conference.program, state: 'withdrawn', event_type: lecture) create(:event, program: conference.program, state: 'withdrawn', event_type: workshop) - get :show, id: conference.short_title + get :show, params: { id: conference.short_title } expect(assigns(:event_type_distribution_withdrawn)).not_to be_empty result = {} result['Workshop'] = { @@ -124,13 +124,13 @@ describe Admin::ConferencesController do it 'assigns conference withdrawn difficulty level distribution to difficulty_levels_distribution_withdrawn' do conference create(:event, program: conference.program) - get :show, id: conference.short_title + get :show, params: { id: conference.short_title } expect(assigns(:difficulty_levels_distribution_withdrawn)).to be_empty easy = create(:difficulty_level, title: 'Easy', color: '#000000') hard = create(:difficulty_level, title: 'Hard', color: '#ffffff') create(:event, program: conference.program, state: 'withdrawn', difficulty_level: easy) create(:event, program: conference.program, state: 'withdrawn', difficulty_level: hard) - get :show, id: conference.short_title + get :show, params: { id: conference.short_title } expect(assigns(:difficulty_levels_distribution_withdrawn)).not_to be_empty result = {} result['Easy'] = { @@ -147,13 +147,13 @@ describe Admin::ConferencesController do it 'assigns conference withdrawn track distribution to tracks_distribution_withdrawn' do conference create(:event, program: conference.program) - get :show, id: conference.short_title + get :show, params: { id: conference.short_title } expect(assigns(:tracks_distribution_withdrawn)).to be_empty track_one = create(:track, name: 'Track One', color: '#000000', program: conference.program) track_two = create(:track, name: 'Track Two', color: '#FFFFFF', program: conference.program) create(:event, program: conference.program, state: 'withdrawn', track: track_one) create(:event, program: conference.program, state: 'withdrawn', track: track_two) - get :show, id: conference.short_title + get :show, params: { id: conference.short_title } expect(assigns(:tracks_distribution_withdrawn)).not_to be_empty result = {} result['Track One'] = { @@ -177,17 +177,6 @@ describe Admin::ConferencesController do expect(assigns(:conferences)).to match_array([conference, con2]) end - it 'assigns cfp_max an array with maximum weeks' do - conference - date = Date.new(2014, 05, 26) - 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 - it 'renders the index template' do conference get :index @@ -213,15 +202,15 @@ describe Admin::ConferencesController 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_id: organization.id) + post :create, params: { conference: + 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_id: organization.id) + post :create, params: { conference: + attributes_for(:conference, short_title: 'dps15', organization_id: organization.id) } expect(response).to redirect_to admin_conference_path( assigns[:conference].short_title) @@ -232,8 +221,8 @@ describe Admin::ConferencesController do 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') + post :create, params: { conference: + attributes_for(:conference, short_title: 'dps15') } expect(conference.roles.count).to eq 4 @@ -244,15 +233,15 @@ describe Admin::ConferencesController do 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_id: organization.id) + post :create, params: { conference: + 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_id: organization.id) + post :create, params: { conference: + attributes_for(:conference, short_title: nil, organization_id: organization.id) } expect(response).to be_success end end @@ -261,15 +250,15 @@ describe Admin::ConferencesController 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_id: organization.id) + post :create, params: { conference: + 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_id: organization.id) + post :create, params: { conference: attributes_for(:conference, short_title: conference.short_title, organization_id: organization.id) } expect(response).to be_success end end @@ -310,8 +299,8 @@ describe Admin::ConferencesController do describe 'POST #create' do it 'requires organizer privileges' do - post :create, conference: attributes_for(:conference, - short_title: 'ExCon', organization_id: organization.id) + post :create, params: { conference: attributes_for(:conference, + short_title: 'ExCon', organization_id: organization.id) } expect(response).to redirect_to(send(path)) if message expect(flash[:alert]).to match(/#{message}/) @@ -332,7 +321,7 @@ describe Admin::ConferencesController do shared_examples 'access as participant or guest' do |path, message| describe 'GET #show' do it 'requires organizer privileges' do - get :show, id: conference.short_title + get :show, params: { id: conference.short_title } expect(response).to redirect_to(send(path)) if message expect(flash[:alert]).to match(/#{message}/) @@ -352,9 +341,9 @@ describe Admin::ConferencesController do describe 'PATCH #update' do it 'requires organizer privileges' do - patch :update, id: conference.short_title, - conference: attributes_for(:conference, - short_title: 'ExCon') + patch :update, params: { id: conference.short_title, + conference: attributes_for(:conference, + short_title: 'ExCon') } expect(response).to redirect_to(send(path)) if message expect(flash[:alert]).to match(/#{message}/) diff --git a/spec/controllers/admin/event_schedules_controller_spec.rb b/spec/controllers/admin/event_schedules_controller_spec.rb index 96350d80..e1e31363 100644 --- a/spec/controllers/admin/event_schedules_controller_spec.rb +++ b/spec/controllers/admin/event_schedules_controller_spec.rb @@ -8,8 +8,7 @@ describe Admin::EventSchedulesController do let(:room) { create(:room, venue: venue) } let(:schedule) { create(:schedule, program: conference.program)} let(:event_schedule) { create(:event_schedule, schedule: schedule)} - let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } - let(:organizer) { create(:user, role_ids: organizer_role.id) } + let!(:organizer) { create(:organizer, resource: conference) } context 'logged in as an organizer' do before :each do @@ -20,12 +19,12 @@ describe Admin::EventSchedulesController do describe 'POST #create' do context 'with valid attributes' do let(:create_action) do - post :create, conference_id: conference.short_title, event_schedule: + post :create, params: { conference_id: conference.short_title, event_schedule: attributes_for(:event_schedule, schedule_id: schedule.id, event_id: create(:event, program: conference.program).id, room_id: create(:room, venue: venue).id, - start_time: conference.start_date + conference.start_hour.hours) + start_time: conference.start_date + conference.start_hour.hours) } end it 'saves the event schedule to the database' do @@ -41,12 +40,12 @@ describe Admin::EventSchedulesController do context 'with invalid attributes' do let(:create_action) do - post :create, conference_id: conference.short_title, event_schedule: + post :create, params: { conference_id: conference.short_title, event_schedule: attributes_for(:event_schedule, schedule_id: schedule.id, event_id: nil, room_id: nil, - start_time: nil) + start_time: nil) } end it 'does not save the event schedule to the database' do @@ -63,12 +62,12 @@ describe Admin::EventSchedulesController do describe 'POST #update' do context 'with valid attributes' do before :each do - patch :update, id: event_schedule.id, conference_id: conference.short_title, event_schedule: + patch :update, params: { id: event_schedule.id, conference_id: conference.short_title, event_schedule: attributes_for(:event_schedule, schedule_id: schedule.id, event_id: create(:event, program: conference.program).id, room_id: room.id, - start_time: conference.start_date + conference.start_hour.hours) + start_time: conference.start_date + conference.start_hour.hours) } event_schedule.reload end @@ -87,12 +86,12 @@ describe Admin::EventSchedulesController do context 'with invalid attributes' do let(:update_action) do - patch :update, id: event_schedule.id, conference_id: conference.short_title, event_schedule: + patch :update, params: { id: event_schedule.id, conference_id: conference.short_title, event_schedule: attributes_for(:event_schedule, schedule_id: schedule.id, event_id: nil, room_id: nil, - start_time: nil) + start_time: nil) } end it 'does not save the event schedule to the database' do expect{ update_action }.to_not change { event_schedule } @@ -107,7 +106,7 @@ describe Admin::EventSchedulesController do describe 'DELETE #destroy' do let(:destroy_action) do - delete :destroy, id: event_schedule.id, conference_id: conference.short_title + delete :destroy, params: { id: event_schedule.id, conference_id: conference.short_title } end it 'deletes the event schedule' do diff --git a/spec/controllers/admin/events_controller_spec.rb b/spec/controllers/admin/events_controller_spec.rb index fb91af94..18850328 100644 --- a/spec/controllers/admin/events_controller_spec.rb +++ b/spec/controllers/admin/events_controller_spec.rb @@ -4,8 +4,7 @@ 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!(:organizer) { create(:organizer, resource: conference) } # 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). @@ -18,7 +17,7 @@ describe Admin::EventsController do describe 'GET #show' do before :each do sign_in(organizer) - get :show, id: event_without_commercial.id, conference_id: conference.short_title + get :show, params: { id: event_without_commercial.id, conference_id: conference.short_title } end it 'assigns versions' do diff --git a/spec/controllers/admin/organizations_controller_spec.rb b/spec/controllers/admin/organizations_controller_spec.rb index 2b1180c6..4468bb34 100644 --- a/spec/controllers/admin/organizations_controller_spec.rb +++ b/spec/controllers/admin/organizations_controller_spec.rb @@ -37,13 +37,13 @@ describe Admin::OrganizationsController do describe 'POST #create' do it 'does not create new organization' do expected = expect do - post :create, organization: attributes_for(:organization) + post :create, params: { organization: attributes_for(:organization) } end expected.to_not change(Organization, :count) end it 'redirects to root' do - post :create, organization: attributes_for(:organization) + post :create, params: { organization: attributes_for(:organization) } expect(flash[:alert]).to eq('You are not authorized to access this page.') expect(response).to redirect_to(root_path) @@ -53,7 +53,7 @@ describe Admin::OrganizationsController do 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') + patch :update, params: { id: organization.id, organization: attributes_for(:organization, name: 'new name') } organization.reload expect(organization.name).to eq(old_name) @@ -66,13 +66,13 @@ describe Admin::OrganizationsController do context 'for a valid organization' do it 'does not destroy a resource' do expected = expect do - delete :destroy, id: organization.id + delete :destroy, params: { id: organization.id } end expected.to_not change(Organization, :count) end it 'redirects to root' do - delete :destroy, id: organization.id + delete :destroy, params: { id: organization.id } expect(flash[:alert]).to eq('You are not authorized to access this page.') expect(response).to redirect_to(root_path) @@ -104,13 +104,13 @@ describe Admin::OrganizationsController do context 'with valid attributes' do it 'creates new organization' do expected = expect do - post :create, organization: attributes_for(:organization) + post :create, params: { organization: attributes_for(:organization) } end expected.to change { Organization.count }.by(1) end it 'redirects to index' do - post :create, organization: attributes_for(:organization) + post :create, params: { organization: attributes_for(:organization) } expect(flash[:notice]).to eq('Organization successfully created') expect(response).to redirect_to(admin_organizations_path) @@ -120,13 +120,13 @@ describe Admin::OrganizationsController do context 'with invalid attributes' do it 'does not create new organization' do expected = expect do - post :create, organization: attributes_for(:organization, name: '') + post :create, params: { 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: '') + post :create, params: { organization: attributes_for(:organization, name: '') } expect(flash[:error]).to eq("Name can't be blank") expect(response).to redirect_to(new_admin_organization_path) @@ -136,7 +136,7 @@ describe Admin::OrganizationsController do 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') + patch :update, params: { id: organization.id, organization: attributes_for(:organization, name: 'changed name') } organization.reload expect(organization.name).to eq('changed name') @@ -145,7 +145,7 @@ describe Admin::OrganizationsController do end it 'redirects to edit when attributes are invalid' do - patch :update, id: organization.id, organization: attributes_for(:organization, name: '') + patch :update, params: { 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)) @@ -156,13 +156,13 @@ describe Admin::OrganizationsController do context 'for a valid organization' do it 'should successfully destroy a resource' do expected = expect do - delete :destroy, id: organization.id + delete :destroy, params: { id: organization.id } end expected.to change { Organization.count }.by(-1) end it 'redirects to index' do - delete :destroy, id: organization.id + delete :destroy, params: { id: organization.id } expect(flash[:notice]).to eq('Organization successfully destroyed') expect(response).to redirect_to(admin_organizations_path) @@ -174,8 +174,8 @@ describe Admin::OrganizationsController do let(:org_admin_role) { Role.find_by(name: 'organization_admin', resource: organization) } before do - post :assign_org_admins, id: organization.id, - user: { email: user.email } + post :assign_org_admins, params: { id: organization.id, + user: { email: user.email } } end it 'assigns organization_admin role' do @@ -188,8 +188,8 @@ describe Admin::OrganizationsController do let!(:org_admin_user) { create(:user, role_ids: [org_admin_role.id]) } before do - delete :unassign_org_admins, id: organization.id, - user: { email: org_admin_user.email } + delete :unassign_org_admins, params: { id: organization.id, + user: { email: org_admin_user.email } } end it 'unassigns organization_admin role' do diff --git a/spec/controllers/admin/programs_controller_spec.rb b/spec/controllers/admin/programs_controller_spec.rb index ee9931c1..5ee48bc0 100644 --- a/spec/controllers/admin/programs_controller_spec.rb +++ b/spec/controllers/admin/programs_controller_spec.rb @@ -6,13 +6,12 @@ describe Admin::ProgramsController, type: :controller do # It is necessary to use bang version of let to build roles before user let(:conference) { create(:conference) } - let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } - let(:organizer) { create(:user, role_ids: organizer_role.id, last_sign_in_at: Time.now - 1.day) } + let!(:organizer) { create(:organizer, resource: conference) } context 'not logged in user' do describe 'GET #show' do it 'does not render admin/programs#show' do - get :show, conference_id: conference.short_title + get :show, params: { conference_id: conference.short_title } expect(response).to redirect_to(user_session_path) end end @@ -25,7 +24,7 @@ describe Admin::ProgramsController, type: :controller do describe 'PATCH #update' do it 'redirects to admin/programs#index' do - patch :update, conference_id: conference.short_title, program: attributes_for(:program) + patch :update, params: { conference_id: conference.short_title, program: attributes_for(:program) } conference.program.reload expect(response).to redirect_to admin_conference_program_path(conference.short_title) end diff --git a/spec/controllers/admin/registration_periods_controller_spec.rb b/spec/controllers/admin/registration_periods_controller_spec.rb index d4f0823a..3d5159b5 100644 --- a/spec/controllers/admin/registration_periods_controller_spec.rb +++ b/spec/controllers/admin/registration_periods_controller_spec.rb @@ -6,10 +6,9 @@ describe Admin::RegistrationPeriodsController do # It is necessary to use bang version of let to build roles before user let(:conference) { create(:conference) } - let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:registration_ticket) { create(:registration_ticket, conference: conference) } - let(:organizer) { create(:user, role_ids: organizer_role.id) } - let(:organizer2) { create(:user, email: 'organizer2@email.osem', role_ids: organizer_role.id) } + let!(:organizer) { create(:organizer, resource: conference) } + let!(:organizer2) { create(:organizer, email: 'organizer2@email.osem', resource: conference) } let(:participant) { create(:user) } shared_examples 'access as administration or organizer' do @@ -23,22 +22,22 @@ describe Admin::RegistrationPeriodsController do context 'valid attributes' do it 'locates the requested registration period object' do - patch :update, conference_id: conference.short_title, registration_period: attributes_for(:registration_period) + patch :update, params: { conference_id: conference.short_title, registration_period: attributes_for(:registration_period) } expect(assigns(:registration_period)).to eq(conference.registration_period) end it 'changes registration period attributes' do the_date = conference.end_date - 10 - patch :update, conference_id: conference.short_title, registration_period: - attributes_for(:registration_period, start_date: the_date) + patch :update, params: { conference_id: conference.short_title, registration_period: + attributes_for(:registration_period, start_date: the_date) } conference.reload expect(conference.registration_period.start_date.to_s).to eq(the_date.to_s) end it 'redirects to the updated registration period' do - patch :update, conference_id: conference.short_title, registration_period: - attributes_for(:registration_period) + patch :update, params: { conference_id: conference.short_title, registration_period: + attributes_for(:registration_period) } conference.reload expect(response).to redirect_to admin_conference_registration_period_path( conference.short_title) @@ -52,10 +51,10 @@ describe Admin::RegistrationPeriodsController do start_date: Date.today, end_date: Date.today + 2.days) - patch :update, conference_id: conference.short_title, registration_period: - attributes_for(:registration_period, - start_date: Date.today + 2.days, - end_date: Date.today + 4.days) + patch :update, params: { conference_id: conference.short_title, registration_period: + attributes_for(:registration_period, + start_date: Date.today + 2.days, + end_date: Date.today + 4.days) } conference.reload allow(Mailbot).to receive(:conference_registration_date_update_mail).and_return(mailer) end @@ -66,17 +65,19 @@ describe Admin::RegistrationPeriodsController do context 'with valid attributes' do it 'saves the registration period to the database' do expected = expect do - post :create, - conference_id: conference.short_title, - registration_period: attributes_for(:registration_period) + post :create, params: { + conference_id: conference.short_title, + registration_period: attributes_for(:registration_period) + } end expected.to change { RegistrationPeriod.count }.by 1 end it 'redirects to registration_periods#show' do - post :create, - conference_id: conference.short_title, - registration_period: attributes_for(:registration_period) + post :create, params: { + conference_id: conference.short_title, + registration_period: attributes_for(:registration_period) + } expect(response).to redirect_to admin_conference_registration_period_path( assigns[:conference].short_title) @@ -86,21 +87,23 @@ describe Admin::RegistrationPeriodsController do context 'with invalid attributes' do it 'does not save the registration period to the database' do expected = expect do - post :create, - conference_id: conference.short_title, - registration_period: attributes_for(:registration_period, - start_date: nil, - end_date: nil) + post :create, params: { + conference_id: conference.short_title, + registration_period: attributes_for(:registration_period, + start_date: nil, + end_date: nil) + } end expected.to_not change { Conference.count } end it 're-renders the new template' do - post :create, - conference_id: conference.short_title, - registration_period: attributes_for(:registration_period, - start_date: nil, - end_date: nil) + post :create, params: { + conference_id: conference.short_title, + registration_period: attributes_for(:registration_period, + start_date: nil, + end_date: nil) + } expect(response).to be_success end end @@ -108,46 +111,46 @@ describe Admin::RegistrationPeriodsController do describe 'GET #edit' do it 'assigns the requested registration period to @registration_period' do - get :edit, conference_id: conference.short_title + get :edit, params: { conference_id: conference.short_title } expect(assigns(:registration_period)).to eq conference.registration_period end it 'renders the show template' do - get :edit, conference_id: conference.short_title + get :edit, params: { conference_id: conference.short_title } expect(response).to render_template :edit end end describe 'GET #show' do it 'assigns the requested registration period to @registration_period' do - get :show, conference_id: conference.short_title + get :show, params: { conference_id: conference.short_title } expect(assigns(:registration_period)).to eq conference.registration_period end it 'renders the show template' do - get :show, conference_id: conference.short_title + get :show, params: { conference_id: conference.short_title } expect(response).to render_template :show end end describe 'GET #new' do it 'assigns a new registration period to @registration_period' do - get :new, conference_id: conference.short_title + get :new, params: { conference_id: conference.short_title } expect(assigns(:registration_period)).to be_a_new(RegistrationPeriod) end it 'renders the :new template' do - get :new, conference_id: conference.short_title + get :new, params: { conference_id: conference.short_title } expect(response).to render_template :new end end describe 'DELETE #destroy' do it 'it deletes the registration period' do - expect { delete :destroy, conference_id: conference.short_title }.to change(RegistrationPeriod, :count).by(-1) + expect { delete :destroy, params: { conference_id: conference.short_title } }.to change(RegistrationPeriod, :count).by(-1) end it 'redirects to users#show' do - delete :destroy, conference_id: conference.short_title + delete :destroy, params: { conference_id: conference.short_title } expect(response).to redirect_to admin_conference_registration_period_path end end diff --git a/spec/controllers/admin/reports_controller_spec.rb b/spec/controllers/admin/reports_controller_spec.rb new file mode 100644 index 00000000..6d36488b --- /dev/null +++ b/spec/controllers/admin/reports_controller_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Admin::ReportsController do + + let(:conference) { create(:conference, start_date: Date.current - 1.day) } + let!(:admin) { create(:admin) } + let!(:user1) { create(:user) } + let!(:user2) { create(:user) } + let!(:venue) { create(:venue, conference: conference) } + let!(:room) { create(:room, venue: venue) } + let!(:track_submitter) { create(:user) } + let!(:self_organized_track) { create(:track, :self_organized, submitter_id: track_submitter.id, program: conference.program, name: 'My awesome track', start_date: Date.current, end_date: Date.current, room: room, state: 'confirmed') } + let!(:track) { create(:track, program: conference.program, color: '#800080') } + + let!(:event1) { create(:event, id: 1, program: conference.program, track: self_organized_track, speakers: [user1], state: 'confirmed') } + let!(:event2) { create(:event, id: 2, program: conference.program, track: track, speakers: [user2], state: 'confirmed') } + + context 'track organizer is signed in' do + before :each do + sign_in(track_submitter) + self_organized_track.assign_role_to_submitter + end + + describe 'GET #index' do + it 'renders the index template' do + get :index, params: { conference_id: conference.short_title } + expect(response).to render_template :index + end + + it 'initialises missing speakers' do + get :index, params: { conference_id: conference.short_title } + expect(assigns(:missing_event_speakers).pluck(:user_id)).to eq [user1.id] + end + end + end +end diff --git a/spec/controllers/admin/roles_controller_spec.rb b/spec/controllers/admin/roles_controller_spec.rb index 8edb1c30..6a0d7754 100644 --- a/spec/controllers/admin/roles_controller_spec.rb +++ b/spec/controllers/admin/roles_controller_spec.rb @@ -14,7 +14,7 @@ describe Admin::RolesController do describe 'GET #index' do before :each do sign_in(admin) - get :index, conference_id: conference.short_title + get :index, params: { conference_id: conference.short_title } end it 'assigns default value to selection variable' do @@ -29,8 +29,8 @@ describe Admin::RolesController do describe 'GET #show' do before :each do sign_in(admin) - xhr :get, :show, conference_id: conference.short_title, - id: 'organizer' + get :show, params: { conference_id: conference.short_title, + id: 'organizer' } end it 'assigns correct value to selection variable' do @@ -45,9 +45,9 @@ describe Admin::RolesController do describe 'PATCH #update' do before :each do sign_in admin - patch :update, conference_id: conference.short_title, - id: 'cfp', - role: { description: 'New description for cfp role!' } + patch :update, params: { conference_id: conference.short_title, + id: 'cfp', + role: { description: 'New description for cfp role!' } } end it 'changes the description of the role' do @@ -58,9 +58,9 @@ describe Admin::RolesController do describe 'POST #toggle' do before :each do sign_in admin - post :toggle_user, conference_id: conference.short_title, - user: { email: 'user1@osem.io' }, - id: 'cfp' + post :toggle_user, params: { conference_id: conference.short_title, + user: { email: 'user1@osem.io' }, + id: 'cfp' } end context 'assigns correct values to variables' do @@ -79,17 +79,17 @@ describe Admin::RolesController do context 'adds role to user' do it 'adds second user' do - post :toggle_user, conference_id: conference.short_title, - user: { email: 'user2@osem.io' }, - id: 'cfp' + post :toggle_user, params: { conference_id: conference.short_title, + user: { email: 'user2@osem.io' }, + id: 'cfp' } expect(user2.roles).to eq [cfp_role] end it 'assigns second role to user' do - post :toggle_user, conference_id: conference.short_title, - user: { email: 'user1@osem.io' }, - id: 'organizer' + post :toggle_user, params: { conference_id: conference.short_title, + user: { email: 'user1@osem.io' }, + id: 'organizer' } expect(user1.roles).to eq [organizer_role, cfp_role] end @@ -97,23 +97,23 @@ describe Admin::RolesController do context 'removes role from user' do it 'removes role from user' do - post :toggle_user, conference_id: conference.short_title, - user: { email: 'user1@osem.io', state: 'false' }, - id: 'cfp' + post :toggle_user, params: { conference_id: conference.short_title, + user: { email: 'user1@osem.io', state: 'false' }, + id: 'cfp' } expect(user1.roles).to eq [] end it 'removes second role from user' do - post :toggle_user, conference_id: conference.short_title, - user: { email: 'user1@osem.io' }, - id: 'organizer' + post :toggle_user, params: { conference_id: conference.short_title, + user: { email: 'user1@osem.io' }, + id: 'organizer' } expect(user1.roles).to eq [organizer_role, cfp_role] - post :toggle_user, conference_id: conference.short_title, - user: { email: 'user1@osem.io', state: 'false' }, - id: 'cfp' + post :toggle_user, params: { conference_id: conference.short_title, + user: { email: 'user1@osem.io', state: 'false' }, + id: 'cfp' } user1.reload expect(user1.roles).to eq [organizer_role] @@ -122,15 +122,15 @@ describe Admin::RolesController do it 'does not remove role if user is the last organizer' do # Add role organizer - post :toggle_user, conference_id: conference.short_title, - user: { email: 'user1@osem.io', state: 'true' }, - id: 'organizer' + post :toggle_user, params: { conference_id: conference.short_title, + user: { email: 'user1@osem.io', state: 'true' }, + id: 'organizer' } expect(organizer_role.users).to eq [user1] # Try to remove role organizer, when there is only 1 user as organizer - post :toggle_user, conference_id: conference.short_title, - user: { email: 'user1@osem.io', state: 'false' }, - id: 'organizer' + post :toggle_user, params: { conference_id: conference.short_title, + user: { email: 'user1@osem.io', state: 'false' }, + id: 'organizer' } expect(organizer_role.users).to eq [user1] end end diff --git a/spec/controllers/admin/rooms_controller_spec.rb b/spec/controllers/admin/rooms_controller_spec.rb index 7c5d6f7c..6272d7d5 100644 --- a/spec/controllers/admin/rooms_controller_spec.rb +++ b/spec/controllers/admin/rooms_controller_spec.rb @@ -12,7 +12,7 @@ describe Admin::RoomsController do before { sign_in admin } describe 'GET #index' do - before { get :index, conference_id: conference.short_title } + before { get :index, params: { conference_id: conference.short_title } } it 'assigns conference, venue and rooms variables' do expect(assigns(:conference)).to eq conference @@ -26,7 +26,7 @@ describe Admin::RoomsController do end describe 'GET #edit' do - before { get :edit, conference_id: conference.short_title, id: room.id } + before { get :edit, params: { conference_id: conference.short_title, id: room.id } } it 'renders edit template' do expect(response).to render_template('edit') @@ -38,7 +38,7 @@ describe Admin::RoomsController do end describe 'GET #new' do - before { get :new, conference_id: conference.short_title } + before { get :new, params: { conference_id: conference.short_title } } it 'renders new template' do expect(response).to render_template('new') @@ -52,7 +52,7 @@ describe Admin::RoomsController do describe 'POST #create' do context 'saves successfuly' do before do - post :create, room: attributes_for(:room), conference_id: conference.short_title + post :create, params: { room: attributes_for(:room), conference_id: conference.short_title } end it 'redirects to admin room index path' do @@ -71,7 +71,7 @@ describe Admin::RoomsController do context 'save fails' do before do allow_any_instance_of(Room).to receive(:save).and_return(false) - post :create, room: attributes_for(:room), conference_id: conference.short_title + post :create, params: { room: attributes_for(:room), conference_id: conference.short_title } end it 'renders new template' do @@ -91,9 +91,9 @@ describe Admin::RoomsController do describe 'PATCH #update' do context 'updates successfully' do before do - patch :update, room: attributes_for(:room, size: 2), - conference_id: conference.short_title, - id: room.id + patch :update, params: { room: attributes_for(:room, size: 2), + conference_id: conference.short_title, + id: room.id } end it 'redirects to admin room index path' do @@ -113,9 +113,9 @@ describe Admin::RoomsController do context 'update fails' do before do allow_any_instance_of(Room).to receive(:save).and_return(false) - patch :update, room: attributes_for(:room, size: 2), - conference_id: conference.short_title, - id: room.id + patch :update, params: { room: attributes_for(:room, size: 2), + conference_id: conference.short_title, + id: room.id } end it 'renders edit template' do @@ -135,7 +135,7 @@ describe Admin::RoomsController do describe 'DELETE #destroy' do context 'deletes successfully' do - before { delete :destroy, conference_id: conference.short_title, id: room.id } + before { delete :destroy, params: { conference_id: conference.short_title, id: room.id } } it 'redirects to admin room index path' do expect(response).to redirect_to admin_conference_venue_rooms_path(conference_id: conference.short_title) @@ -153,7 +153,7 @@ describe Admin::RoomsController do context 'delete fails' do before do allow_any_instance_of(Room).to receive(:destroy).and_return(false) - delete :destroy, conference_id: conference.short_title, id: room.id + delete :destroy, params: { conference_id: conference.short_title, id: room.id } end it 'redirects to admin room index path' do diff --git a/spec/controllers/admin/schedules_controller_spec.rb b/spec/controllers/admin/schedules_controller_spec.rb index 38ba33e3..76310398 100644 --- a/spec/controllers/admin/schedules_controller_spec.rb +++ b/spec/controllers/admin/schedules_controller_spec.rb @@ -5,8 +5,7 @@ require 'spec_helper' describe Admin::SchedulesController do let(:conference) { create(:conference) } let(:schedule) { create(:schedule, program: conference.program)} - let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } - let(:organizer) { create(:user, role_ids: organizer_role.id) } + let!(:organizer) { create(:organizer, resource: conference) } context 'logged in as an organizer' do before :each do @@ -16,13 +15,13 @@ describe Admin::SchedulesController do describe 'GET #index' do it 'renders the index template' do - get :index, conference_id: conference.short_title + get :index, params: { conference_id: conference.short_title } expect(response).to render_template :index end end describe 'POST #create' do - let(:create_action){ post :create, conference_id: conference.short_title } + let(:create_action){ post :create, params: { conference_id: conference.short_title } } it 'saves the schedule to the database' do expect{ create_action }.to change { Schedule.count }.by 1 @@ -36,7 +35,7 @@ describe Admin::SchedulesController do end describe 'GET #show' do - let(:show_action){ get :show, id: schedule.id, conference_id: conference.short_title } + let(:show_action){ get :show, params: { id: schedule.id, conference_id: conference.short_title } } it 'assigns the requested schedule to schedule' do show_action @@ -50,7 +49,7 @@ describe Admin::SchedulesController do end describe 'DELETE #destroy' do - let(:destroy_action){ delete :destroy, id: schedule.id, conference_id: conference.short_title } + let(:destroy_action){ delete :destroy, params: { id: schedule.id, conference_id: conference.short_title } } it 'deletes the schedule' do expect{ destroy_action }.to change { Schedule.count }.by(-1) diff --git a/spec/controllers/admin/sponsorship_levels_controller_spec.rb b/spec/controllers/admin/sponsorship_levels_controller_spec.rb index 98b9da87..d8c01681 100644 --- a/spec/controllers/admin/sponsorship_levels_controller_spec.rb +++ b/spec/controllers/admin/sponsorship_levels_controller_spec.rb @@ -11,7 +11,7 @@ describe Admin::SponsorshipLevelsController do before { sign_in admin } describe 'GET #index' do - before { get :index, conference_id: conference.short_title } + before { get :index, params: { conference_id: conference.short_title } } it 'assigns conference and sponsorship_levels variables' do expect(assigns(:conference)).to eq conference @@ -24,7 +24,7 @@ describe Admin::SponsorshipLevelsController do end describe 'GET #edit' do - before { get :edit, conference_id: conference.short_title, id: sponsorship_level.id } + before { get :edit, params: { conference_id: conference.short_title, id: sponsorship_level.id } } it 'renders edit template' do expect(response).to render_template('edit') @@ -36,7 +36,7 @@ describe Admin::SponsorshipLevelsController do end describe 'GET #new' do - before { get :new, conference_id: conference.short_title } + before { get :new, params: { conference_id: conference.short_title } } it 'renders new template' do expect(response).to render_template('new') @@ -50,8 +50,8 @@ describe Admin::SponsorshipLevelsController do describe 'POST #create' do context 'saves successfuly' do before(:each, run: true) do - post :create, sponsorship_level: attributes_for(:sponsorship_level), - conference_id: conference.short_title + post :create, params: { sponsorship_level: attributes_for(:sponsorship_level), + conference_id: conference.short_title } end it 'redirects to admin sponsorship_level index path', run: true do @@ -64,8 +64,8 @@ describe Admin::SponsorshipLevelsController do it 'creates new sponsorship_level' do expect do - post :create, sponsorship_level: attributes_for(:sponsorship_level), - conference_id: conference.short_title + post :create, params: { sponsorship_level: attributes_for(:sponsorship_level), + conference_id: conference.short_title } end.to change{ conference.sponsorship_levels.count }.from(0).to(1) end end @@ -73,8 +73,8 @@ describe Admin::SponsorshipLevelsController do context 'save fails' do before do allow_any_instance_of(SponsorshipLevel).to receive(:save).and_return(false) - post :create, sponsorship_level: attributes_for(:sponsorship_level), - conference_id: conference.short_title + post :create, params: { sponsorship_level: attributes_for(:sponsorship_level), + conference_id: conference.short_title } end it 'renders new template' do @@ -94,9 +94,9 @@ describe Admin::SponsorshipLevelsController do describe 'PATCH #update' do context 'updates successfully' do before do - patch :update, sponsorship_level: attributes_for(:sponsorship_level, title: 'Gold'), - conference_id: conference.short_title, - id: sponsorship_level.id + patch :update, params: { sponsorship_level: attributes_for(:sponsorship_level, title: 'Gold'), + conference_id: conference.short_title, + id: sponsorship_level.id } end it 'redirects to admin sponsorship_level index path' do @@ -116,9 +116,9 @@ describe Admin::SponsorshipLevelsController do context 'update fails' do before do allow_any_instance_of(SponsorshipLevel).to receive(:save).and_return(false) - patch :update, sponsorship_level: attributes_for(:sponsorship_level, title: 'Gold'), - conference_id: conference.short_title, - id: sponsorship_level.id + patch :update, params: { sponsorship_level: attributes_for(:sponsorship_level, title: 'Gold'), + conference_id: conference.short_title, + id: sponsorship_level.id } end it 'renders edit template' do @@ -139,7 +139,7 @@ describe Admin::SponsorshipLevelsController do describe 'DELETE #destroy' do context 'deletes successfully' do before(:each, run: true) do - delete :destroy, conference_id: conference.short_title, id: sponsorship_level.id + delete :destroy, params: { conference_id: conference.short_title, id: sponsorship_level.id } end it 'redirects to admin sponsorship_level index path', run: true do @@ -153,7 +153,7 @@ describe Admin::SponsorshipLevelsController do it 'deletes the sponsorship_level' do sponsorship_level expect do - delete :destroy, conference_id: conference.short_title, id: sponsorship_level.id + delete :destroy, params: { conference_id: conference.short_title, id: sponsorship_level.id } end.to change{ conference.sponsorship_levels.count }.from(1).to(0) end end @@ -161,7 +161,7 @@ describe Admin::SponsorshipLevelsController do context 'delete fails' do before do allow_any_instance_of(SponsorshipLevel).to receive(:destroy).and_return(false) - delete :destroy, conference_id: conference.short_title, id: sponsorship_level.id + delete :destroy, params: { conference_id: conference.short_title, id: sponsorship_level.id } end it 'redirects to admin sponsorship_level index path' do @@ -182,7 +182,7 @@ describe Admin::SponsorshipLevelsController do before do sponsorship_level @second_sponsorship_level = create(:sponsorship_level, conference: conference) - patch :up, conference_id: conference.short_title, id: @second_sponsorship_level.id + patch :up, params: { conference_id: conference.short_title, id: @second_sponsorship_level.id } end it 'moves sponsorship_level up by one position' do @@ -197,7 +197,7 @@ describe Admin::SponsorshipLevelsController do before do sponsorship_level @second_sponsorship_level = create(:sponsorship_level, conference: conference) - patch :down, conference_id: conference.short_title, id: sponsorship_level.id + patch :down, params: { conference_id: conference.short_title, id: sponsorship_level.id } end it 'moves sponsorship_level down by one position' do diff --git a/spec/controllers/admin/ticket_scannings_controller_spec.rb b/spec/controllers/admin/ticket_scannings_controller_spec.rb index 022800cf..83909a28 100644 --- a/spec/controllers/admin/ticket_scannings_controller_spec.rb +++ b/spec/controllers/admin/ticket_scannings_controller_spec.rb @@ -18,13 +18,13 @@ describe Admin::TicketScanningsController do describe 'POST #create' do it 'does not create new ticket scanning' do expected = expect do - post :create, physical_ticket_id: physical_ticket.token + post :create, params: { physical_ticket_id: physical_ticket.token } end expected.to_not change(TicketScanning, :count) end it 'redirects to root' do - post :create, physical_ticket_id: physical_ticket.token + post :create, params: { physical_ticket_id: physical_ticket.token } expect(flash[:alert]).to eq('You are not authorized to access this page.') expect(response).to redirect_to(root_path) end @@ -39,13 +39,13 @@ describe Admin::TicketScanningsController do context 'with valid physical_ticket' do it 'creates new ticket scanning' do expected = expect do - post :create, physical_ticket_id: physical_ticket.token + post :create, params: { physical_ticket_id: physical_ticket.token } end expected.to change { TicketScanning.count }.by(1) end it 'redirects to index' do - post :create, physical_ticket_id: physical_ticket.token + post :create, params: { physical_ticket_id: physical_ticket.token } expect(flash[:notice]).to eq("Ticket with token #{physical_ticket.token} successfully scanned.") expect(response).to redirect_to(conferences_path) end @@ -54,7 +54,7 @@ describe Admin::TicketScanningsController do context 'with Invalid physical_ticket' do it 'raises exception' do expected = expect do - post :create, physical_ticket_id: 'XXXX' + post :create, params: { physical_ticket_id: 'XXXX' } end expected.to raise_exception(ActiveRecord::RecordNotFound) end diff --git a/spec/controllers/admin/tracks_controller_spec.rb b/spec/controllers/admin/tracks_controller_spec.rb index 1b8bc231..f51f1dda 100644 --- a/spec/controllers/admin/tracks_controller_spec.rb +++ b/spec/controllers/admin/tracks_controller_spec.rb @@ -17,7 +17,7 @@ describe Admin::TracksController do describe 'GET #index' do before :each do - get :index, conference_id: conference.short_title + get :index, params: { conference_id: conference.short_title } end it 'assigns @tracks with the correct values' do @@ -33,7 +33,7 @@ describe Admin::TracksController do describe 'GET #show' do before :each do - get :show, conference_id: conference.short_title, id: track.short_name + get :show, params: { conference_id: conference.short_title, id: track.short_name } end it 'assigns the correct track' do @@ -47,7 +47,7 @@ describe Admin::TracksController do describe 'GET #new' do before :each do - get :new, conference_id: conference.short_title + get :new, params: { conference_id: conference.short_title } end it 'assigns a new track with the correct conference' do @@ -64,7 +64,7 @@ describe Admin::TracksController do describe 'POST #create' do context 'saves successfuly' do before :each do - post :create, track: attributes_for(:track), conference_id: conference.short_title + post :create, params: { track: attributes_for(:track), conference_id: conference.short_title } end it 'assigns a new track with the correct conference' do @@ -94,7 +94,7 @@ describe Admin::TracksController do 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 + post :create, params: { track: attributes_for(:track, short_name: 'my_track'), conference_id: conference.short_title } end it 'assigns a new track with the correct conference' do @@ -119,7 +119,7 @@ describe Admin::TracksController do describe 'GET #edit' do before :each do - get :edit, conference_id: conference.short_title, id: track.short_name + get :edit, params: { conference_id: conference.short_title, id: track.short_name } end it 'assigns the correct track' do @@ -134,9 +134,9 @@ describe Admin::TracksController do 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 + patch :update, params: { track: attributes_for(:track, color: '#FF0000'), + conference_id: conference.short_title, + id: track.short_name } end it 'assigns the correct track' do @@ -160,9 +160,9 @@ describe Admin::TracksController do 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 + patch :update, params: { track: attributes_for(:track, color: '#FF0000'), + conference_id: conference.short_title, + id: track.short_name } end it 'assigns the correct track' do @@ -187,7 +187,7 @@ describe Admin::TracksController do describe 'DELETE #destroy' do context 'deletes successfully' do before :each do - delete :destroy, conference_id: conference.short_title, id: track.short_name + delete :destroy, params: { conference_id: conference.short_title, id: track.short_name } end it 'redirects to admin tracks index path' do @@ -206,7 +206,7 @@ describe Admin::TracksController do 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 + delete :destroy, params: { conference_id: conference.short_title, id: track.short_name } end it 'assigns the correct track' do @@ -236,7 +236,7 @@ describe Admin::TracksController do context 'toggles successfully' do before :each do - patch :toggle_cfp_inclusion, conference_id: conference.short_title, id: self_organized_track.short_name, format: :js + patch :toggle_cfp_inclusion, params: { conference_id: conference.short_title, id: self_organized_track.short_name, format: :js } self_organized_track.reload end @@ -256,7 +256,7 @@ describe Admin::TracksController do context 'save fails' do before :each do allow_any_instance_of(Track).to receive(:save).and_return(false) - patch :toggle_cfp_inclusion, conference_id: conference.short_title, id: self_organized_track.short_name, format: :js + patch :toggle_cfp_inclusion, params: { conference_id: conference.short_title, id: self_organized_track.short_name, format: :js } self_organized_track.reload end @@ -282,7 +282,7 @@ describe Admin::TracksController do context 'toggles successfully' do before :each do - patch :toggle_cfp_inclusion, conference_id: conference.short_title, id: self_organized_track.short_name, format: :js + patch :toggle_cfp_inclusion, params: { conference_id: conference.short_title, id: self_organized_track.short_name, format: :js } self_organized_track.reload end @@ -302,7 +302,7 @@ describe Admin::TracksController do context 'save fails' do before :each do allow_any_instance_of(Track).to receive(:save).and_return(false) - patch :toggle_cfp_inclusion, conference_id: conference.short_title, id: self_organized_track.short_name, format: :js + patch :toggle_cfp_inclusion, params: { conference_id: conference.short_title, id: self_organized_track.short_name, format: :js } self_organized_track.reload end @@ -325,7 +325,7 @@ describe Admin::TracksController do before :each do self_organized_track.state = 'canceled' self_organized_track.save! - patch :restart, conference_id: conference.short_title, id: self_organized_track.short_name + patch :restart, params: { conference_id: conference.short_title, id: self_organized_track.short_name } self_organized_track.reload end @@ -344,7 +344,7 @@ describe Admin::TracksController do describe 'PATCH #to_accept' do before :each do - patch :to_accept, conference_id: conference.short_title, id: self_organized_track.short_name + patch :to_accept, params: { conference_id: conference.short_title, id: self_organized_track.short_name } self_organized_track.reload end @@ -364,7 +364,7 @@ describe Admin::TracksController do describe 'PATCH #accept' do shared_examples 'fails to accept' do before :each do - patch :accept, conference_id: conference.short_title, id: self_organized_track.short_name + patch :accept, params: { conference_id: conference.short_title, id: self_organized_track.short_name } end it 'assigns the correct track' do @@ -382,7 +382,7 @@ describe Admin::TracksController do context 'has start_date, end_date and room' do before :each do - patch :accept, conference_id: conference.short_title, id: self_organized_track.short_name + patch :accept, params: { conference_id: conference.short_title, id: self_organized_track.short_name } self_organized_track.reload end @@ -472,7 +472,7 @@ describe Admin::TracksController do before :each do self_organized_track.state = 'accepted' self_organized_track.save! - patch :confirm, conference_id: conference.short_title, id: self_organized_track.short_name + patch :confirm, params: { conference_id: conference.short_title, id: self_organized_track.short_name } self_organized_track.reload end @@ -491,7 +491,7 @@ describe Admin::TracksController do describe 'PATCH #to_reject' do before :each do - patch :to_reject, conference_id: conference.short_title, id: self_organized_track.short_name + patch :to_reject, params: { conference_id: conference.short_title, id: self_organized_track.short_name } self_organized_track.reload end @@ -510,7 +510,7 @@ describe Admin::TracksController do describe 'PATCH #reject' do before :each do - patch :reject, conference_id: conference.short_title, id: self_organized_track.short_name + patch :reject, params: { conference_id: conference.short_title, id: self_organized_track.short_name } self_organized_track.reload end @@ -531,7 +531,7 @@ describe Admin::TracksController do before :each do self_organized_track.state = 'confirmed' self_organized_track.save! - patch :cancel, conference_id: conference.short_title, id: self_organized_track.short_name + patch :cancel, params: { conference_id: conference.short_title, id: self_organized_track.short_name } self_organized_track.reload end diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb index 97c829c8..50eda9b1 100644 --- a/spec/controllers/admin/users_controller_spec.rb +++ b/spec/controllers/admin/users_controller_spec.rb @@ -23,12 +23,12 @@ describe Admin::UsersController do describe 'PATCH #toggle_confirmation' do it 'confirms user' do user_to_confirm = create(:user, email: 'unconfirmed_user@osem.io', confirmed_at: nil) - patch :toggle_confirmation, id: user_to_confirm.id, user: { to_confirm: 'true' } + patch :toggle_confirmation, params: { id: user_to_confirm.id, user: { to_confirm: 'true' } } user_to_confirm.reload expect(user_to_confirm.confirmed?).to eq true end it 'undo confirmation of user' do - patch :toggle_confirmation, id: user.id, user: { to_confirm: 'false' } + patch :toggle_confirmation, params: { id: user.id, user: { to_confirm: 'false' } } user.reload expect(user.confirmed?).to eq false end @@ -36,7 +36,7 @@ describe Admin::UsersController do describe 'PATCH #update' do context 'valid attributes' do before :each do - patch :update, id: user.id, user: { name: 'new name', email: 'new_email@osem.io' } + patch :update, params: { id: user.id, user: { name: 'new name', email: 'new_email@osem.io' } } end it 'locates requested @user' do @@ -66,7 +66,7 @@ describe Admin::UsersController do describe 'POST #create' do context 'saves successfuly' do before do - post :create, user: attributes_for(:user) + post :create, params: { user: attributes_for(:user) } end it 'redirects to admin users index path' do @@ -85,7 +85,7 @@ describe Admin::UsersController do context 'save fails' do before do allow_any_instance_of(User).to receive(:save).and_return(false) - post :create, user: attributes_for(:user) + post :create, params: { user: attributes_for(:user) } end it 'renders new template' do @@ -98,7 +98,7 @@ describe Admin::UsersController do it 'does not create new user' do expect do - post :create, user: attributes_for(:user) + post :create, params: { user: attributes_for(:user) } end.not_to change{ Event.count } end end diff --git a/spec/controllers/admin/versions_controller_spec.rb b/spec/controllers/admin/versions_controller_spec.rb index 0dede517..8c453efd 100644 --- a/spec/controllers/admin/versions_controller_spec.rb +++ b/spec/controllers/admin/versions_controller_spec.rb @@ -18,7 +18,7 @@ describe Admin::VersionsController do it 'reverts all changes for update actions' do conference.update_attributes(short_title: 'testtitle', description: 'Some random text') - get :revert_object, id: PaperTrail::Version.last.id + get :revert_object, params: { id: PaperTrail::Version.last.id } conference.reload expect(conference.short_title).to eq 'exampletitle' expect(conference.description).to eq 'Example Description' @@ -27,14 +27,14 @@ describe Admin::VersionsController do it 'shows correct flash on trying to revert create event of a deleted object' do creation_version_id = conference.program.event_types.first.versions.first.id conference.program.event_types.first.destroy - get :revert_object, id: creation_version_id + get :revert_object, params: { id: creation_version_id } expect(flash[:error]).to match('The item is already in the state that you are trying to revert it back to') end it 'reverting deletion of object creates it again' do conference.program.event_types.first.destroy event_types_count = conference.program.event_types.count - get :revert_object, id: PaperTrail::Version.last.id + get :revert_object, params: { id: PaperTrail::Version.last.id } conference.reload expect(PaperTrail::Version.last.event).to eq 'create' expect(conference.program.event_types.count).to eq(event_types_count + 1) @@ -42,14 +42,14 @@ describe Admin::VersionsController do it 'reverting creation of object deletes it ' do create(:lodging, conference: conference) - get :revert_object, id: PaperTrail::Version.last.id + get :revert_object, params: { id: PaperTrail::Version.last.id } expect(PaperTrail::Version.last.event).to eq 'destroy' expect(Lodging.count).to eq 0 end it 'reverting creation of conference is not permitted' do conference_count_before = Conference.count - get :revert_object, id: conference.versions.first.id + get :revert_object, params: { id: conference.versions.first.id } expect(flash[:alert]).to eq 'You are not authorized to access this page.' expect(Conference.count).to eq(conference_count_before) end @@ -62,7 +62,7 @@ describe Admin::VersionsController do it 'reverts specified change for update actions' do conference.update_attributes(short_title: 'testtitle', description: 'Some random text') - get :revert_attribute, id: PaperTrail::Version.last.id, attribute: 'short_title' + get :revert_attribute, params: { id: PaperTrail::Version.last.id, attribute: 'short_title' } conference.reload expect(conference.short_title).to eq 'exampletitle' expect(conference.description).to eq 'Some random text' @@ -71,7 +71,7 @@ describe Admin::VersionsController do it 'shows correct flash on trying to revert to the current state' do conference.update_attributes(short_title: 'testtitle', description: 'Some random text') conference.update_attributes(short_title: 'exampletitle') - get :revert_attribute, id: PaperTrail::Version.all[-2].id, attribute: 'short_title' + get :revert_attribute, params: { id: PaperTrail::Version.all[-2].id, attribute: 'short_title' } expect(flash[:error]).to match('The item is already in the state that you are trying to revert it back to') expect(conference.short_title).to eq 'exampletitle' end @@ -79,14 +79,14 @@ describe Admin::VersionsController do it 'fails on trying to revert deleted object' do conference.program.event_types.first.update_attributes(title: 'New Event Title') conference.program.event_types.first.destroy - get :revert_attribute, id: PaperTrail::Version.all[-2].id, attribute: 'title' + get :revert_attribute, params: { id: PaperTrail::Version.all[-2].id, attribute: 'title' } conference.reload expect(flash[:alert]).to eq 'You are not authorized to access this page.' end it 'fails on trying to revert creation event' do create(:lodging, conference: conference) - get :revert_attribute, id: PaperTrail::Version.last.id, attribute: 'name' + get :revert_attribute, params: { id: PaperTrail::Version.last.id, attribute: 'name' } expect(flash[:alert]).to eq 'You are not authorized to access this page.' end @@ -94,7 +94,7 @@ describe Admin::VersionsController do conference.update_attributes(short_title: 'testtitle', description: 'Some random text') before_conference_title = conference.title # Note: even though title is a valid attribute of conference, it was not updated in the change we are trying to revert - get :revert_attribute, id: PaperTrail::Version.last.id, attribute: 'title' + get :revert_attribute, params: { id: PaperTrail::Version.last.id, attribute: 'title' } conference.reload expect(conference.short_title).to eq 'testtitle' expect(conference.description).to eq 'Some random text' @@ -107,7 +107,7 @@ describe Admin::VersionsController do it 'raises error if user is not of any role' do user = create(:user) sign_in user - get :index, conference_id: conference.short_title + get :index, params: { conference_id: conference.short_title } expect(flash[:alert]).to match('You are not authorized to access this page.') end @@ -127,7 +127,7 @@ describe Admin::VersionsController do it 'when user has role cfp' do @user.roles = [role_cfp] sign_in @user - get :index, conference_id: conference.short_title + get :index, params: { conference_id: conference.short_title } expect(assigns(:versions).include?(@version_cfp)).to eq true expect(assigns(:versions).include?(@version_organizer)).to eq false @@ -136,7 +136,7 @@ describe Admin::VersionsController do it 'when user has role info_desk' do @user.roles = [role_info_desk] sign_in @user - get :index, conference_id: conference.short_title + get :index, params: { conference_id: conference.short_title } expect(assigns(:versions).include?(@version_info_desk)).to eq true expect(assigns(:versions).include?(@version_organizer)).to eq false @@ -146,7 +146,7 @@ describe Admin::VersionsController do it 'when user has role organizer' do @user.roles = [role_organizer] sign_in @user - get :index, conference_id: conference.short_title + get :index, params: { conference_id: conference.short_title } expect(assigns(:versions).include?(@version_organizer)).to eq true expect(assigns(:versions).include?(@version_cfp)).to eq true diff --git a/spec/controllers/api/v1/conferences_controller_spec.rb b/spec/controllers/api/v1/conferences_controller_spec.rb index 330c86d8..b126d87d 100644 --- a/spec/controllers/api/v1/conferences_controller_spec.rb +++ b/spec/controllers/api/v1/conferences_controller_spec.rb @@ -8,7 +8,7 @@ describe Api::V1::ConferencesController do describe 'GET #index' do before(:each) do - get :index, format: :json + get :index, params: { format: :json } @json = JSON.parse(response.body)['conferences'] end @@ -28,7 +28,7 @@ describe Api::V1::ConferencesController do describe 'GET #show' do before(:each) do - get :show, id: 'conf_two', format: :json + get :show, params: { id: 'conf_two', format: :json } @json = JSON.parse(response.body)['conferences'] end diff --git a/spec/controllers/api/v1/events_controller_spec.rb b/spec/controllers/api/v1/events_controller_spec.rb index 168d5d8c..1f9b2809 100644 --- a/spec/controllers/api/v1/events_controller_spec.rb +++ b/spec/controllers/api/v1/events_controller_spec.rb @@ -11,7 +11,7 @@ describe Api::V1::EventsController do context 'without conference scope' do it 'returns all confirmed events' do - get :index, format: :json + get :index, params: { format: :json } json = JSON.parse(response.body)['events'] expect(response).to be_success @@ -24,7 +24,7 @@ describe Api::V1::EventsController do context 'with conference scope' do it 'returns all confirmed events of conference' do - get :index, conference_id: conference.short_title, format: :json + get :index, params: { conference_id: conference.short_title, format: :json } json = JSON.parse(response.body)['events'] expect(response).to be_success diff --git a/spec/controllers/api/v1/rooms_controller_spec.rb b/spec/controllers/api/v1/rooms_controller_spec.rb index bb29c44c..f8262800 100644 --- a/spec/controllers/api/v1/rooms_controller_spec.rb +++ b/spec/controllers/api/v1/rooms_controller_spec.rb @@ -12,7 +12,7 @@ describe Api::V1::RoomsController do context 'without conference scope' do it 'returns all rooms' do - get :index, format: :json + get :index, params: { format: :json } json = JSON.parse(response.body)['rooms'] expect(response).to be_success @@ -26,7 +26,7 @@ describe Api::V1::RoomsController do context 'with conference scope' do it 'returns all rooms of conference' do - get :index, conference_id: conference.short_title, format: :json + get :index, params: { conference_id: conference.short_title, format: :json } json = JSON.parse(response.body)['rooms'] expect(response).to be_success diff --git a/spec/controllers/api/v1/speakers_controller_spec.rb b/spec/controllers/api/v1/speakers_controller_spec.rb index f3f857f0..fdaa08a0 100644 --- a/spec/controllers/api/v1/speakers_controller_spec.rb +++ b/spec/controllers/api/v1/speakers_controller_spec.rb @@ -19,7 +19,7 @@ describe Api::V1::SpeakersController do context 'without conference scope' do it 'returns all speakers' do - get :index, format: :json + get :index, params: { format: :json } json = JSON.parse(response.body)['speakers'] expect(response).to be_success expect(json.length).to eq(2) @@ -31,7 +31,7 @@ describe Api::V1::SpeakersController do context 'with conference scope' do it 'returns all speakers of conference' do - get :index, conference_id: conference.short_title, format: :json + get :index, params: { conference_id: conference.short_title, format: :json } json = JSON.parse(response.body)['speakers'] expect(response).to be_success diff --git a/spec/controllers/api/v1/tracks_controller_spec.rb b/spec/controllers/api/v1/tracks_controller_spec.rb index 74379414..65346b56 100644 --- a/spec/controllers/api/v1/tracks_controller_spec.rb +++ b/spec/controllers/api/v1/tracks_controller_spec.rb @@ -11,7 +11,7 @@ describe Api::V1::TracksController do context 'without conference scope' do it 'returns all tracks' do - get :index, format: :json + get :index, params: { format: :json } json = JSON.parse(response.body)['tracks'] expect(response).to be_success @@ -25,7 +25,7 @@ describe Api::V1::TracksController do context 'with conference scope' do it 'returns all rooms of conference' do - get :index, conference_id: conference.short_title, format: :json + get :index, params: { conference_id: conference.short_title, format: :json } json = JSON.parse(response.body)['tracks'] expect(response).to be_success diff --git a/spec/controllers/booths_controller_spec.rb b/spec/controllers/booths_controller_spec.rb index be1c4e41..13be8584 100644 --- a/spec/controllers/booths_controller_spec.rb +++ b/spec/controllers/booths_controller_spec.rb @@ -15,7 +15,7 @@ describe BoothsController do end describe 'GET index' do - before { get :index, conference_id: conference.short_title } + before { get :index, params: { conference_id: conference.short_title } } it 'assigns attributes for booths' do expect(assigns(:booths)).to eq([booth]) @@ -27,7 +27,7 @@ describe BoothsController do end describe 'GET #new' do - before { get :new, conference_id: conference.short_title } + before { get :new, params: { conference_id: conference.short_title } } it 'assigns attributes for booths' do expect(assigns(:booth)).to be_a_new(Booth) @@ -40,7 +40,7 @@ describe BoothsController do describe 'POST #create' do context 'successfully created' do - before { post :create, booth: attributes_for(:booth), conference_id: conference.short_title } + before { post :create, params: { booth: attributes_for(:booth), conference_id: conference.short_title } } it 'creates a new booth' do expect(Booth.count).to_not eq(0) @@ -55,16 +55,16 @@ describe BoothsController do end it 'shows success message' do - expect(flash[:notice]).to match('Booth successfully created.') + expect(flash[:notice]).to match("#{(t 'booth').capitalize} successfully created.") end end context 'create action fails' do - before { post :create, booth: attributes_for(:booth, title: ''), conference_id: conference.short_title } + before { post :create, params: { booth: attributes_for(:booth, title: ''), conference_id: conference.short_title } } it 'does not create any record' do expected = expect do - post :create, booth: attributes_for(:booth, title: ''), conference_id: conference.short_title + post :create, params: { booth: attributes_for(:booth, title: ''), conference_id: conference.short_title } end expected.to_not change(Booth, :count) end @@ -74,13 +74,13 @@ describe BoothsController do end it 'shows flash message' do - expect(flash[:error]).to eq("Creating booth failed. Title can't be blank.") + expect(flash[:error]).to eq("Creating #{t 'booth'} failed. Title can't be blank.") end end end describe 'GET #edit' do - before { get :edit, id: booth.id, conference_id: conference.short_title } + before { get :edit, params: { id: booth.id, conference_id: conference.short_title } } it 'renders edit template' do expect(response).to render_template('edit') @@ -93,7 +93,7 @@ describe BoothsController do describe 'PATCH #update' do context 'updates suchessfully' do - before { patch :update, id: booth.id, booth: attributes_for(:booth, title: 'different'), conference_id: conference.short_title } + before { patch :update, params: { id: booth.id, booth: attributes_for(:booth, title: 'different'), conference_id: conference.short_title } } it 'redirects to booth index path' do expect(response).to redirect_to conference_booths_path diff --git a/spec/controllers/conference_registration_controller_spec.rb b/spec/controllers/conference_registration_controller_spec.rb index c046d23e..f2849c27 100644 --- a/spec/controllers/conference_registration_controller_spec.rb +++ b/spec/controllers/conference_registration_controller_spec.rb @@ -13,7 +13,7 @@ describe ConferenceRegistrationsController, type: :controller do 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 + get :new, params: { conference_id: conference.short_title } end it 'redirects' do @@ -29,7 +29,7 @@ describe ConferenceRegistrationsController, type: :controller do 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 + get :new, params: { conference_id: conference.short_title } end it 'user variable exists' do @@ -231,7 +231,7 @@ describe ConferenceRegistrationsController, type: :controller do context 'successful request' do before do - get :show, conference_id: conference.short_title + get :show, params: { conference_id: conference.short_title } end it 'assigns variables' do @@ -250,7 +250,7 @@ describe ConferenceRegistrationsController, type: :controller do @purchased_ticket = create(:ticket_purchase, conference: conference, user: user, ticket: @ticket) - get :show, conference_id: conference.short_title + get :show, params: { conference_id: conference.short_title } end it 'does not assign price of purchased tickets to total_price and purchased tickets to tickets without payment' do @@ -260,7 +260,7 @@ describe ConferenceRegistrationsController, type: :controller do context 'user has not purchased any ticket' do before do - get :show, conference_id: conference.short_title + get :show, params: { conference_id: conference.short_title } end it 'assigns 0 dollars to total_price and empty array to tickets variables' do @@ -273,7 +273,7 @@ describe ConferenceRegistrationsController, type: :controller do describe 'GET #edit' do before do @registration = create(:registration, conference: conference, user: user) - get :edit, conference_id: conference.short_title + get :edit, params: { conference_id: conference.short_title } end it 'assigns conference and registration variable' do @@ -296,8 +296,8 @@ describe ConferenceRegistrationsController, type: :controller do context 'updates successfully' do before do - patch :update, registration: attributes_for(:registration, arrival: Date.new(2014, 04, 29)), - conference_id: conference.short_title + patch :update, params: { registration: attributes_for(:registration, arrival: Date.new(2014, 04, 29)), + conference_id: conference.short_title } end it 'redirects to registration show path' do @@ -317,8 +317,8 @@ describe ConferenceRegistrationsController, type: :controller do context 'update fails' do before do allow_any_instance_of(Registration).to receive(:update_attributes).and_return(false) - patch :update, registration: attributes_for(:registration, arrival: Date.new(2014, 04, 27)), - conference_id: conference.short_title + patch :update, params: { registration: attributes_for(:registration, arrival: Date.new(2014, 04, 27)), + conference_id: conference.short_title } end it 'renders edit template' do @@ -343,7 +343,7 @@ describe ConferenceRegistrationsController, type: :controller do context 'deletes successfully' do before(:each, run: true) do - delete :destroy, conference_id: conference.short_title + delete :destroy, params: { conference_id: conference.short_title } end it 'redirects to root path', run: true do @@ -356,7 +356,7 @@ describe ConferenceRegistrationsController, type: :controller do it 'deletes the registration' do expect do - delete :destroy, conference_id: conference.short_title + delete :destroy, params: { conference_id: conference.short_title } end.to change{ Registration.count }.from(2).to(1) end end @@ -364,7 +364,7 @@ describe ConferenceRegistrationsController, type: :controller do context 'delete fails' do before do allow_any_instance_of(Registration).to receive(:destroy).and_return(false) - delete :destroy, conference_id: conference.short_title + delete :destroy, params: { conference_id: conference.short_title } end it 'redirects to registration show path' do diff --git a/spec/controllers/conferences_controller_spec.rb b/spec/controllers/conferences_controller_spec.rb index 91585d79..c9a17d14 100644 --- a/spec/controllers/conferences_controller_spec.rb +++ b/spec/controllers/conferences_controller_spec.rb @@ -17,12 +17,12 @@ describe ConferencesController do describe 'GET #show' do context 'conference made public' do it 'assigns the requested conference to conference' do - get :show, id: conference.short_title + get :show, params: { id: conference.short_title } expect(assigns(:conference)).to eq conference end it 'renders the show template' do - get :show, id: conference.short_title + get :show, params: { id: conference.short_title } expect(response).to render_template :show end end @@ -44,7 +44,7 @@ describe ConferencesController do describe 'OPTIONS #index' do it 'Response code is 200' do - process :index, 'OPTIONS' + process :index expect(response.response_code).to eq(200) end end diff --git a/spec/controllers/confirmations_controller_spec.rb b/spec/controllers/confirmations_controller_spec.rb index 68e1837a..60675d47 100644 --- a/spec/controllers/confirmations_controller_spec.rb +++ b/spec/controllers/confirmations_controller_spec.rb @@ -11,7 +11,7 @@ describe ConfirmationsController do context 'user is not signed in' do it 'confirms and signs in user' do - get :show, confirmation_token: user.confirmation_token + get :show, params: { confirmation_token: user.confirmation_token } user.reload expect(user.confirmed?).to eq true expect(controller.current_user).to eq user @@ -22,7 +22,7 @@ describe ConfirmationsController do before { sign_in user } it 'confirms user' do - get :show, confirmation_token: user.confirmation_token + get :show, params: { confirmation_token: user.confirmation_token } user.reload expect(user.confirmed?).to eq true end diff --git a/spec/controllers/organizations_controller_spec.rb b/spec/controllers/organizations_controller_spec.rb index e14e22fb..e719f823 100644 --- a/spec/controllers/organizations_controller_spec.rb +++ b/spec/controllers/organizations_controller_spec.rb @@ -37,7 +37,7 @@ describe OrganizationsController do describe 'GET #conferences' do before :each do - get :conferences, id: organization.id + get :conferences, params: { id: organization.id } end it 'loads the organization' do diff --git a/spec/controllers/physical_ticket_controller_spec.rb b/spec/controllers/physical_ticket_controller_spec.rb index 5367fb96..7b2a02c4 100644 --- a/spec/controllers/physical_ticket_controller_spec.rb +++ b/spec/controllers/physical_ticket_controller_spec.rb @@ -11,7 +11,7 @@ describe PhysicalTicketsController do describe 'GET #show' do before :each do sign_in user - get :show, id: physical_ticket.token, conference_id: conference.short_title + get :show, params: { id: physical_ticket.token, conference_id: conference.short_title } end it 'assigns ticket_layout' do diff --git a/spec/controllers/proposals_controller_spec.rb b/spec/controllers/proposals_controller_spec.rb index 2537569e..db52ffd1 100644 --- a/spec/controllers/proposals_controller_spec.rb +++ b/spec/controllers/proposals_controller_spec.rb @@ -13,7 +13,7 @@ describe ProposalsController do before do # We allow new proposal only if program has open cfp create(:cfp, program: conference.program) - get :new, conference_id: conference.short_title + get :new, params: { conference_id: conference.short_title } end it 'assigns user and url variables' do @@ -31,9 +31,9 @@ describe ProposalsController do before { create(:cfp, program: conference.program) } it 'assigns url variables' do - post :create, event: attributes_for(:event, event_type_id: event_type.id), - conference_id: conference.short_title, - user: attributes_for(:user) + post :create, params: { event: attributes_for(:event, event_type_id: event_type.id), + conference_id: conference.short_title, + user: attributes_for(:user) } expect(assigns(:url)).to eq '/conferences/lama101/program/proposals' end @@ -41,9 +41,9 @@ describe ProposalsController do describe 'user related actions' do before do @new_user = attributes_for(:user) - post :create, event: attributes_for(:event, event_type_id: event_type.id), - conference_id: conference.short_title, - user: @new_user + post :create, params: { event: attributes_for(:event, event_type_id: event_type.id), + conference_id: conference.short_title, + user: @new_user } end it 'creates new user' do @@ -58,9 +58,9 @@ describe ProposalsController do context 'creates proposal successfully' do before(:each, run: true) do @new_user = attributes_for(:user) - post :create, event: attributes_for(:event, event_type_id: event_type.id), - conference_id: conference.short_title, - user: @new_user + post :create, params: { event: attributes_for(:event, event_type_id: event_type.id), + conference_id: conference.short_title, + user: @new_user } end it 'assigns event variable', run: true do @@ -86,9 +86,9 @@ describe ProposalsController do it 'creates new event' do expect do - post :create, event: attributes_for(:event, event_type_id: event_type.id), - conference_id: conference.short_title, - user: attributes_for(:user) + post :create, params: { event: attributes_for(:event, event_type_id: event_type.id), + conference_id: conference.short_title, + user: attributes_for(:user) } end.to change{ Event.count }.by 1 end end @@ -96,9 +96,9 @@ describe ProposalsController do context 'proposal save fails' do before(:each, run: true) do allow_any_instance_of(Event).to receive(:save).and_return(false) - post :create, event: attributes_for(:event, event_type_id: event_type.id), - conference_id: conference.short_title, - user: attributes_for(:user) + post :create, params: { event: attributes_for(:event, event_type_id: event_type.id), + conference_id: conference.short_title, + user: attributes_for(:user) } end it 'renders new template', run: true do @@ -112,9 +112,9 @@ describe ProposalsController do it 'does not create new proposal' do allow_any_instance_of(Event).to receive(:save).and_return(false) expect do - post :create, event: attributes_for(:event, event_type_id: event_type.id), - conference_id: conference.short_title, - user: attributes_for(:user) + post :create, params: { event: attributes_for(:event, event_type_id: event_type.id), + conference_id: conference.short_title, + user: attributes_for(:user) } end.not_to change{ Event.count } end end @@ -125,25 +125,25 @@ describe ProposalsController do it 'does not create new user' do expect do - post :create, event: attributes_for(:event, event_type_id: event_type.id), - conference_id: conference.short_title, - user: attributes_for(:user) + post :create, params: { event: attributes_for(:event, event_type_id: event_type.id), + conference_id: conference.short_title, + user: attributes_for(:user) } end.not_to change { User.count } end it 'does not create new event' do expect do - post :create, event: attributes_for(:event, event_type_id: event_type.id), - conference_id: conference.short_title, - user: attributes_for(:user) + post :create, params: { event: attributes_for(:event, event_type_id: event_type.id), + conference_id: conference.short_title, + user: attributes_for(:user) } end.not_to change { Event.count } end describe 'response' do before do - post :create, event: attributes_for(:event, event_type_id: event_type.id), - conference_id: conference.short_title, - user: attributes_for(:user) + post :create, params: { event: attributes_for(:event, event_type_id: event_type.id), + conference_id: conference.short_title, + user: attributes_for(:user) } end it 'renders new template' do @@ -164,7 +164,7 @@ describe ProposalsController do end describe 'GET #index' do - before { get :index, conference_id: conference.short_title } + before { get :index, params: { conference_id: conference.short_title } } it 'assigns conference, program and events variables' do expect(assigns(:conference)).to eq conference @@ -179,7 +179,7 @@ describe ProposalsController do describe 'GET #show' do before do - get :show, conference_id: conference.short_title, id: event.id + get :show, params: { conference_id: conference.short_title, id: event.id } end it 'assigns event variable' do @@ -195,7 +195,7 @@ describe ProposalsController do before do # We allow new proposal only if program has open cfp create(:cfp, program: conference.program) - get :new, conference_id: conference.short_title + get :new, params: { conference_id: conference.short_title } end it 'assigns user and url variables' do @@ -210,7 +210,7 @@ describe ProposalsController do describe 'GET #edit' do before do - get :edit, conference_id: conference.short_title, id: event.id + get :edit, params: { conference_id: conference.short_title, id: event.id } end it 'assigns event and url variables' do @@ -228,15 +228,15 @@ describe ProposalsController do before { create(:cfp, program: conference.program) } it 'assigns url variables' do - post :create, event: attributes_for(:event, event_type_id: event_type.id), - conference_id: conference.short_title + post :create, params: { event: attributes_for(:event, event_type_id: event_type.id), + conference_id: conference.short_title } expect(assigns(:url)).to eq '/conferences/lama101/program/proposals' end context 'creates proposal successfully' do before(:each, run: true) do - post :create, event: attributes_for(:event, event_type_id: event_type.id), - conference_id: conference.short_title + post :create, params: { event: attributes_for(:event, event_type_id: event_type.id), + conference_id: conference.short_title } end it 'assigns event variable', run: true do @@ -262,8 +262,8 @@ describe ProposalsController do it 'creates new event' do expect do - post :create, event: attributes_for(:event, event_type_id: event_type.id), - conference_id: conference.short_title + post :create, params: { event: attributes_for(:event, event_type_id: event_type.id), + conference_id: conference.short_title } end.to change{ Event.count }.by 1 end end @@ -271,8 +271,8 @@ describe ProposalsController do context 'proposal save fails' do before(:each, run: true) do allow_any_instance_of(Event).to receive(:save).and_return(false) - post :create, event: attributes_for(:event, event_type_id: event_type.id), - conference_id: conference.short_title + post :create, params: { event: attributes_for(:event, event_type_id: event_type.id), + conference_id: conference.short_title } end it 'renders new template', run: true do @@ -286,8 +286,8 @@ describe ProposalsController do it 'does not create new proposal' do allow_any_instance_of(Event).to receive(:save).and_return(false) expect do - post :create, event: attributes_for(:event, event_type_id: event_type.id), - conference_id: conference.short_title + post :create, params: { event: attributes_for(:event, event_type_id: event_type.id), + conference_id: conference.short_title } end.not_to change{ Event.count } end end @@ -296,17 +296,17 @@ describe ProposalsController do describe 'PATCH #update' do it 'assigns url variable' do - patch :update, event: attributes_for(:event, title: 'some title', event_type_id: event_type.id), - conference_id: conference.short_title, - id: event.id + patch :update, params: { event: attributes_for(:event, title: 'some title', event_type_id: event_type.id), + conference_id: conference.short_title, + id: event.id } expect(assigns(:url)).to eq "/conferences/lama101/program/proposals/#{event.id}" end context 'updates successfully' do before do - patch :update, event: attributes_for(:event, title: 'some title', event_type_id: event_type.id), - conference_id: conference.short_title, - id: event.id + patch :update, params: { event: attributes_for(:event, title: 'some title', event_type_id: event_type.id), + conference_id: conference.short_title, + id: event.id } end it 'updates the proposal' do @@ -326,9 +326,9 @@ describe ProposalsController do context 'update fails' do before do allow_any_instance_of(Event).to receive(:save).and_return(false) - patch :update, event: attributes_for(:event, title: 'some title', event_type_id: event_type.id), - conference_id: conference.short_title, - id: event.id + patch :update, params: { event: attributes_for(:event, title: 'some title', event_type_id: event_type.id), + conference_id: conference.short_title, + id: event.id } end it 'does not update the proposal' do @@ -349,13 +349,13 @@ describe ProposalsController do describe 'PATCH #withdraw' do it 'assigns url variable' do - patch :withdraw, conference_id: conference.short_title, id: event.id + patch :withdraw, params: { conference_id: conference.short_title, id: event.id } expect(assigns(:url)).to eq "/conferences/lama101/program/proposals/#{event.id}" end context 'withdraws successfully' do before do - patch :withdraw, conference_id: conference.short_title, id: event.id + patch :withdraw, params: { conference_id: conference.short_title, id: event.id } end it 'changes state of event to withdrawn' do @@ -376,7 +376,7 @@ describe ProposalsController do before do request.env['HTTP_REFERER'] = '/' allow_any_instance_of(Event).to receive(:withdraw).and_raise(Transitions::InvalidTransition) - patch :withdraw, conference_id: conference.short_title, id: event.id + patch :withdraw, params: { conference_id: conference.short_title, id: event.id } end it 'does not withdraw event' do @@ -396,7 +396,7 @@ describe ProposalsController do context 'event save fails' do before do allow_any_instance_of(Event).to receive(:save).and_return(false) - patch :withdraw, conference_id: conference.short_title, id: event.id + patch :withdraw, params: { conference_id: conference.short_title, id: event.id } end it 'does not withdraw event' do @@ -423,7 +423,7 @@ describe ProposalsController do event.require_registration = true event.max_attendees = nil event.save! - patch :confirm, conference_id: conference.short_title, id: event.id + patch :confirm, params: { conference_id: conference.short_title, id: event.id } end it 'assigns url variable' do @@ -437,7 +437,7 @@ describe ProposalsController do end describe 'general actions' do - before { patch :confirm, conference_id: conference.short_title, id: event.id } + before { patch :confirm, params: { conference_id: conference.short_title, id: event.id } } it 'assigns url variable' do expect(assigns(:url)).to eq "/conferences/lama101/program/proposals/#{event.id}" @@ -452,7 +452,7 @@ describe ProposalsController do context 'user has registered for the conference' do before do create(:registration, conference: conference, user: event.submitter) - patch :confirm, conference_id: conference.short_title, id: event.id + patch :confirm, params: { conference_id: conference.short_title, id: event.id } end it 'redirects to proposal index path' do @@ -466,7 +466,7 @@ describe ProposalsController do context 'user has not registered for the conference' do before do - patch :confirm, conference_id: conference.short_title, id: event.id + patch :confirm, params: { conference_id: conference.short_title, id: event.id } end it 'redirects to new registration path' do @@ -483,7 +483,7 @@ describe ProposalsController do before do request.env['HTTP_REFERER'] = '/' allow_any_instance_of(Event).to receive(:confirm).and_raise(Transitions::InvalidTransition) - patch :confirm, conference_id: conference.short_title, id: event.id + patch :confirm, params: { conference_id: conference.short_title, id: event.id } end it 'does not confirm event' do @@ -503,7 +503,7 @@ describe ProposalsController do before do event.update_attributes(state: 'unconfirmed') allow_any_instance_of(Event).to receive(:save).and_return(false) - patch :confirm, conference_id: conference.short_title, id: event.id + patch :confirm, params: { conference_id: conference.short_title, id: event.id } end it 'does not confirm event' do @@ -524,13 +524,13 @@ describe ProposalsController do before { event.update_attributes(state: 'withdrawn') } it 'assigns url variable' do - patch :restart, conference_id: conference.short_title, id: event.id + patch :restart, params: { conference_id: conference.short_title, id: event.id } expect(assigns(:url)).to eq "/conferences/lama101/program/proposals/#{event.id}" end context 'resubmits successfully' do before do - patch :restart, conference_id: conference.short_title, id: event.id + patch :restart, params: { conference_id: conference.short_title, id: event.id } end it 'changes state of event to new' do @@ -550,7 +550,7 @@ describe ProposalsController do context 'event resubmission fails' do before do allow_any_instance_of(Event).to receive(:restart).and_raise(Transitions::InvalidTransition) - patch :restart, conference_id: conference.short_title, id: event.id + patch :restart, params: { conference_id: conference.short_title, id: event.id } end it 'does not change state of event to new' do @@ -570,7 +570,7 @@ describe ProposalsController do context 'event save fails' do before do allow_any_instance_of(Event).to receive(:save).and_return(false) - patch :restart, conference_id: conference.short_title, id: event.id + patch :restart, params: { conference_id: conference.short_title, id: event.id } end it 'does not change state of event to new' do diff --git a/spec/controllers/schedules_controller_spec.rb b/spec/controllers/schedules_controller_spec.rb index a448627a..8724c21b 100644 --- a/spec/controllers/schedules_controller_spec.rb +++ b/spec/controllers/schedules_controller_spec.rb @@ -13,7 +13,7 @@ describe SchedulesController do create(:event_scheduled, program: conference.program) create(:event_scheduled, program: conference.program) - get :show, conference_id: conference.short_title, format: :xml + get :show, params: { conference_id: conference.short_title, format: :xml } end it 'assigns variables' do diff --git a/spec/controllers/subscriptions_controller_spec.rb b/spec/controllers/subscriptions_controller_spec.rb index c47d7ca5..dcc964a7 100644 --- a/spec/controllers/subscriptions_controller_spec.rb +++ b/spec/controllers/subscriptions_controller_spec.rb @@ -9,7 +9,7 @@ describe SubscriptionsController do describe 'POST #create' do context 'when user is a guest' do it 'redirects to sign in page' do - post :create, conference_id: conference.short_title + post :create, params: { conference_id: conference.short_title } expect(response).to redirect_to new_user_session_path end end @@ -20,17 +20,17 @@ describe SubscriptionsController do end it 'redirects to home page' do - post :create, conference_id: conference.short_title + post :create, params: { conference_id: conference.short_title } expect(response).to redirect_to root_path end it 'shows success message in flash notice' do - post :create, conference_id: conference.short_title + post :create, params: { conference_id: conference.short_title } expect(flash[:notice]).to match("You have subscribed to receive email notifications for #{conference.title}") end it 'subscribes user to conference' do - post :create, conference_id: conference.short_title + post :create, params: { conference_id: conference.short_title } expect(user.subscriptions.pluck(:conference_id)).to include(conference.id) end end @@ -39,17 +39,17 @@ describe SubscriptionsController do describe 'DELETE #destroy' do before(:each) do sign_in(user) - post :create, conference_id: conference.short_title + post :create, params: { conference_id: conference.short_title } end it 'redirects to home page' do - delete :destroy, conference_id: conference.short_title + delete :destroy, params: { conference_id: conference.short_title } expect(response).to redirect_to root_path end it 'shows success message in flash notice' do - delete :destroy, conference_id: conference.short_title - expect(flash[:notice]).to match("You have unsubscribed and you will not be receiving email notifications for #{conference.title}.") + delete :destroy, params: { conference_id: conference.short_title } + expect(flash[:notice]).to match("You have unsubscribed and you will not be receiving email notifications for #{conference.title}.") end end end diff --git a/spec/controllers/surveys_controller_spec.rb b/spec/controllers/surveys_controller_spec.rb index fb62de8e..67b6cac0 100644 --- a/spec/controllers/surveys_controller_spec.rb +++ b/spec/controllers/surveys_controller_spec.rb @@ -14,7 +14,7 @@ describe SurveysController do describe 'GET #index' do context 'guest' do before :each do - get :index, conference_id: conference.short_title + get :index, params: { conference_id: conference.short_title } end it '@sureveys variable is nil' do @@ -25,7 +25,7 @@ describe SurveysController do context 'signed in user' do before :each do sign_in user - get :index, conference_id: conference.short_title + get :index, params: { conference_id: conference.short_title } end it 'assigns @surveys with active surveys' do diff --git a/spec/controllers/tracks_controller_spec.rb b/spec/controllers/tracks_controller_spec.rb index 84ffcc5d..3216e8d0 100644 --- a/spec/controllers/tracks_controller_spec.rb +++ b/spec/controllers/tracks_controller_spec.rb @@ -15,7 +15,7 @@ describe TracksController do describe 'GET #index' do before :each do - get :index, conference_id: conference.short_title + get :index, params: { conference_id: conference.short_title } end it 'assigns @tracks with the correct values' do @@ -31,7 +31,7 @@ describe TracksController do describe 'GET #show' do before :each do - get :show, conference_id: conference.short_title, id: self_organized_track.short_name + get :show, params: { conference_id: conference.short_title, id: self_organized_track.short_name } end it 'assigns the correct track' do @@ -45,7 +45,7 @@ describe TracksController do describe 'GET #new' do before :each do - get :new, conference_id: conference.short_title + get :new, params: { conference_id: conference.short_title } end it 'assigns a new track with the correct conference' do @@ -62,7 +62,7 @@ describe TracksController do describe 'POST #create' do context 'saves successfuly' do before :each do - post :create, track: attributes_for(:track, :self_organized, short_name: 'my_track'), conference_id: conference.short_title + post :create, params: { track: attributes_for(:track, :self_organized, short_name: 'my_track'), conference_id: conference.short_title } end it 'redirects to tracks index path' do @@ -88,7 +88,7 @@ describe TracksController do context 'save fails' do before :each do allow_any_instance_of(Track).to receive(:save).and_return(false) - post :create, track: attributes_for(:track, :self_organized, short_name: 'my_track'), conference_id: conference.short_title + post :create, params: { track: attributes_for(:track, :self_organized, short_name: 'my_track'), conference_id: conference.short_title } end it 'assigns a new track with the correct conference' do @@ -113,7 +113,7 @@ describe TracksController do describe 'GET #edit' do before :each do - get :edit, conference_id: conference.short_title, id: self_organized_track.short_name + get :edit, params: { conference_id: conference.short_title, id: self_organized_track.short_name } end it 'assigns the correct track' do @@ -128,9 +128,9 @@ describe TracksController do describe 'PATCH #update' do context 'updates successfully' do before :each do - patch :update, track: attributes_for(:track, :self_organized, color: '#FF0000'), - conference_id: conference.short_title, - id: self_organized_track.short_name + patch :update, params: { track: attributes_for(:track, :self_organized, color: '#FF0000'), + conference_id: conference.short_title, + id: self_organized_track.short_name } end it 'assigns the correct track' do @@ -154,9 +154,9 @@ describe TracksController do context 'update fails' do before :each do allow_any_instance_of(Track).to receive(:save).and_return(false) - patch :update, track: attributes_for(:track, :self_organized, color: '#FF0000'), - conference_id: conference.short_title, - id: self_organized_track.short_name + patch :update, params: { track: attributes_for(:track, :self_organized, color: '#FF0000'), + conference_id: conference.short_title, + id: self_organized_track.short_name } end it 'assigns the correct track' do @@ -182,7 +182,7 @@ describe TracksController do before :each do self_organized_track.state = 'withdrawn' self_organized_track.save! - patch :restart, conference_id: conference.short_title, id: self_organized_track.short_name + patch :restart, params: { conference_id: conference.short_title, id: self_organized_track.short_name } self_organized_track.reload end @@ -203,7 +203,7 @@ describe TracksController do before :each do self_organized_track.state = 'accepted' self_organized_track.save! - patch :confirm, conference_id: conference.short_title, id: self_organized_track.short_name + patch :confirm, params: { conference_id: conference.short_title, id: self_organized_track.short_name } self_organized_track.reload end @@ -224,7 +224,7 @@ describe TracksController do before :each do self_organized_track.state = 'confirmed' self_organized_track.save! - patch :withdraw, conference_id: conference.short_title, id: self_organized_track.short_name + patch :withdraw, params: { conference_id: conference.short_title, id: self_organized_track.short_name } self_organized_track.reload end diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index eb325f88..c2010e89 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -8,7 +8,7 @@ describe UsersController do describe 'GET #show' do before :each do - get :show, id: user.id + get :show, params: { id: user.id } end it 'renders show template' do @@ -35,7 +35,7 @@ describe UsersController do describe 'GET #edit' do it 'assigns the right value to @user' do sign_in user - get :edit, id: user.id + get :edit, params: { id: user.id } expect(assigns(:user)).to eq user end end @@ -44,7 +44,7 @@ describe UsersController do context 'with valid attributes' do before :each do sign_in user - patch :update, id: user.id, user: attributes_for(:user, name: 'My Test Name') + patch :update, params: { id: user.id, user: attributes_for(:user, name: 'My Test Name') } user.reload end diff --git a/spec/factories/users.rb b/spec/factories/users.rb index f868a738..24affba4 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -13,7 +13,8 @@ # `create(:admin, is_admin: false)` # # For a non-admin user, use: `create(:user)` -# For an admin user, use: `create(:admin) +# For an admin user, use: `create(:admin)` +# For an organizer user, use `create(:organizer)` FactoryBot.define do factory :user do @@ -31,6 +32,7 @@ FactoryBot.define do Quisque cursus facilisis consequat. Etiam volutpat ligula turpis, at gravida. EOS + last_sign_in_at { Date.today } is_disabled { false } after(:create) do |user| @@ -57,4 +59,14 @@ FactoryBot.define do biography { '
' } end + factory :organizer, parent: :user do + transient do + resource { create(:resource) } + end + + after(:create) do |user, evaluator| + user.roles << Role.find_or_create_by(name: 'organizer', resource: evaluator.resource) + user.save! + end + end end diff --git a/spec/features/cfp_spec.rb b/spec/features/cfp_spec.rb deleted file mode 100644 index 566d0e7b..00000000 --- a/spec/features/cfp_spec.rb +++ /dev/null @@ -1,86 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -feature Conference do - - let!(:conference) { create(:conference) } - let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } - let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } - - shared_examples 'add and update cfp' do - scenario 'adds a new cfp', feature: true, js: true do - expected_count = Cfp.count + 1 - - sign_in organizer - - visit new_admin_conference_program_cfp_path(conference.short_title) - - click_button 'Create Cfp' - - page.find('#flash') - 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 - page.execute_script( - "$('#registration-period-start-datepicker').val('#{today.strftime('%d/%m/%Y')}')") - page.execute_script( - "$('#registration-period-end-datepicker').val('#{(today + 6).strftime('%d/%m/%Y')}')") - - click_button 'Create Cfp' - - # 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')) - - expect(Cfp.count).to eq(expected_count) - end - - scenario 'update cfp', feature: true, js: true do - create(:cfp, program: conference.program) - expected_count = Cfp.count - - sign_in organizer - visit admin_conference_program_cfp_path(conference.short_title, conference.program.cfp) - click_link 'Edit' - - # Validate update with empty start date will not saved - page.execute_script( - "$('#registration-period-start-datepicker').val('')") - click_button 'Update Cfp' - page.find('#flash') - expect(flash) - .to eq('Updating call for papers failed. ' + - "Start date can't be blank.") - - # Fill in date - today = Date.today - 9 - page.execute_script( - "$('#registration-period-start-datepicker').val('#{today.strftime('%d/%m/%Y')}')") - page.execute_script( - "$('#registration-period-end-datepicker').val('#{(today + 14).strftime('%d/%m/%Y')}')") - - click_button 'Update Cfp' - - # Validations - page.find('#flash') - 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) - end - end - - describe 'organizer' do - it_behaves_like 'add and update cfp' - end -end diff --git a/spec/features/commercials_spec.rb b/spec/features/commercials_spec.rb index 107a0693..a0710f86 100644 --- a/spec/features/commercials_spec.rb +++ b/spec/features/commercials_spec.rb @@ -6,8 +6,7 @@ feature Commercial do # It is necessary to use bang version of let to build roles before user let!(:conference) { create(:conference) } let!(:cfp) { create(:cfp, program: conference.program) } - let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } - let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } + let!(:organizer) { create(:organizer, resource: conference) } let!(:participant) { create(:user) } context 'in admin area' do diff --git a/spec/features/conference_spec.rb b/spec/features/conference_spec.rb index 9810a762..95f422bc 100644 --- a/spec/features/conference_spec.rb +++ b/spec/features/conference_spec.rb @@ -39,8 +39,7 @@ feature Conference do scenario 'update conference', feature: true, js: true do conference = create(:conference) - organizer_role = Role.find_by(name: 'organizer', resource: conference) - organizer = create(:user, role_ids: [organizer_role.id]) + organizer = create(:organizer, resource: conference) expected_count = Conference.count @@ -50,6 +49,14 @@ feature Conference do fill_in 'conference_title', with: 'New Con' fill_in 'conference_short_title', with: '' + day = Time.zone.today + 10 + page + .execute_script("$('#conference-start-datepicker').val('" + + "#{day.strftime('%d/%m/%Y')}')") + page + .execute_script("$('#conference-end-datepicker').val('" + + "#{(day + 7).strftime('%d/%m/%Y')}')") + page.accept_alert do click_button 'Update Conference' end diff --git a/spec/features/contact_spec.rb b/spec/features/contact_spec.rb index 10b2d761..47585cc9 100644 --- a/spec/features/contact_spec.rb +++ b/spec/features/contact_spec.rb @@ -5,8 +5,7 @@ require 'spec_helper' feature Contact do let!(:conference) { create(:conference) } - let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } - let!(:organizer) { create(:user, email: 'admin@example.com', role_ids: [organizer_role.id]) } + let!(:organizer) { create(:organizer, resource: conference) } shared_examples 'contact field' do |field_name, field_value| it 'updates a contact' do diff --git a/spec/features/difficulty_levels_spec.rb b/spec/features/difficulty_levels_spec.rb index bb513cf0..c8ce8b2f 100644 --- a/spec/features/difficulty_levels_spec.rb +++ b/spec/features/difficulty_levels_spec.rb @@ -4,8 +4,7 @@ require 'spec_helper' feature DifficultyLevel 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!(:organizer) { create(:organizer, resource: conference) } shared_examples 'difficulty levels' do scenario 'adds difficulty level', feature: true, js: true do diff --git a/spec/features/email_spec.rb b/spec/features/email_spec.rb index 0856e15b..a110dd2c 100644 --- a/spec/features/email_spec.rb +++ b/spec/features/email_spec.rb @@ -4,8 +4,7 @@ require 'spec_helper' feature EmailSettings 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!(:organizer) { create(:organizer, resource: conference) } shared_examples 'email settings' do scenario 'updates email settings', diff --git a/spec/features/event_types_spec.rb b/spec/features/event_types_spec.rb index 7e256bd5..8e05784a 100644 --- a/spec/features/event_types_spec.rb +++ b/spec/features/event_types_spec.rb @@ -4,8 +4,7 @@ require 'spec_helper' feature EventType 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!(:organizer) { create(:organizer, resource: conference) } shared_examples 'event types' do scenario 'adds and updates event type', feature: true do diff --git a/spec/features/lodgings_spec.rb b/spec/features/lodgings_spec.rb index 1728c286..f8cc7626 100644 --- a/spec/features/lodgings_spec.rb +++ b/spec/features/lodgings_spec.rb @@ -4,8 +4,7 @@ require 'spec_helper' feature Lodging 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!(:organizer) { create(:organizer, resource: conference) } scenario 'Add a lodging', feature: true, js: true do path = "#{Rails.root}/app/assets/images/rails.png" diff --git a/spec/features/program_spec.rb b/spec/features/program_spec.rb index 968d287e..273e79cb 100644 --- a/spec/features/program_spec.rb +++ b/spec/features/program_spec.rb @@ -6,8 +6,7 @@ feature Program do let!(:conference) { create(:conference) } let!(:program) { conference.program } - let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } - let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } + let!(:organizer) { create(:organizer, resource: conference) } describe 'edit program' do before :each do diff --git a/spec/features/proposals_spec.rb b/spec/features/proposals_spec.rb index 0a9ea422..9bd0e1c3 100644 --- a/spec/features/proposals_spec.rb +++ b/spec/features/proposals_spec.rb @@ -6,8 +6,7 @@ feature Event do let!(:conference) { create(:conference) } let!(:registration_period) { create(:registration_period, conference: conference, start_date: Date.current) } let!(:cfp) { create(:cfp, program_id: conference.program.id) } - let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } - let!(:organizer) { create(:user, email: 'admin@example.com', role_ids: [organizer_role.id]) } + let!(:organizer) { create(:organizer, resource: conference) } let!(:participant) { create(:user) } let!(:participant_without_bio) { create(:user, biography: '') } @@ -119,10 +118,11 @@ feature Event do fill_in 'event_title', with: 'Example Proposal' select('Example Event Type', from: 'event[event_type_id]') fill_in 'event_abstract', with: 'Lorem ipsum abstract' - click_link 'Do you require something special?' + expect(page).to have_text('You have used 3 words') - page.find('#event_description') + click_link 'Do you require something special?' fill_in 'event_description', with: 'Lorem ipsum description' + click_button 'Create Proposal' page.find('#flash') diff --git a/spec/features/registration_periods_spec.rb b/spec/features/registration_periods_spec.rb index 89af9a4e..4ef0573b 100644 --- a/spec/features/registration_periods_spec.rb +++ b/spec/features/registration_periods_spec.rb @@ -3,19 +3,21 @@ require 'spec_helper' feature RegistrationPeriod do - # It is necessary to use bang version of let to build roles before user let!(:conference) { create(:conference) } - let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } - let!(:organizer) { create(:user, email: 'admin@example.com', role_ids: [organizer_role.id]) } - let!(:registration_ticket) { create(:registration_ticket, conference: conference) } + let!(:organizer) { create(:organizer, email: 'admin@example.com', resource: conference) } + let(:start_date) { Date.today } + let(:end_date) { Date.today + 5 } - shared_examples 'successfully' do - scenario 'create and update registration period', js: true do + context 'as organizer' do + before do sign_in organizer - visit admin_conference_registration_period_path( - conference_id: conference.short_title) + visit admin_conference_registration_period_path(conference_id: conference) + click_link 'New Registration Period' + end + scenario 'requires start date and end date', feature: true do + visit admin_conference_registration_period_path(conference_id: conference) click_link 'New Registration Period' click_button 'Save Registration Period' @@ -23,27 +25,54 @@ feature RegistrationPeriod do 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.find('#flash .close').click - page - .execute_script("$('#registration-period-start-datepicker').val('" + - "#{Date.today.strftime('%d/%m/%Y')}')") - page - .execute_script("$('#registration-period-end-datepicker').val('" + - "#{(Date.today + 5).strftime('%d/%m/%Y')}')") + end - click_button 'Save Registration Period' - page.find('#flash') - expect(flash).to eq('Registration Period successfully updated.') - expect(current_path).to eq(admin_conference_registration_period_path(conference.short_title)) + context 'with tickets' do + let!(:registration_ticket) do + create(:registration_ticket, conference: conference) + end - registration_period = RegistrationPeriod.where(conference_id: conference.id).first - registration_period.reload - expect(registration_period.start_date).to eq(Date.today) - expect(registration_period.end_date).to eq(Date.today + 5) + it 'creates registration period', feature: true, js: true do + page + .execute_script("$('#registration-period-start-datepicker').val('" + + "#{start_date.strftime('%d/%m/%Y')}')") + page + .execute_script("$('#registration-period-end-datepicker').val('" + + "#{end_date.strftime('%d/%m/%Y')}')") + + click_button 'Save Registration Period' + page.find('#flash') + expect(flash).to eq('Registration Period successfully updated.') + expect(current_path).to eq(admin_conference_registration_period_path(conference.short_title)) + expect(page).to have_text("Ticket required?\nYes") + + registration_period = RegistrationPeriod.where(conference_id: conference.id).first + registration_period.reload + expect(registration_period.start_date).to eq(start_date) + expect(registration_period.end_date).to eq(end_date) + end + end + + context 'without tickets' do + it 'creates registration period', feature: true, js: true do + page + .execute_script("$('#registration-period-start-datepicker').val('" + + "#{start_date.strftime('%d/%m/%Y')}')") + page + .execute_script("$('#registration-period-end-datepicker').val('" + + "#{end_date.strftime('%d/%m/%Y')}')") + + click_button 'Save Registration Period' + page.find('#flash') + expect(flash).to eq('Registration Period successfully updated.') + expect(current_path).to eq(admin_conference_registration_period_path(conference.short_title)) + expect(page).to have_text("Ticket required?\nNo") + + registration_period = RegistrationPeriod.where(conference_id: conference.id).first + registration_period.reload + expect(registration_period.start_date).to eq(start_date) + expect(registration_period.end_date).to eq(end_date) + end end end - - describe 'organizer' do - it_behaves_like 'successfully' - end end diff --git a/spec/features/rooms_spec.rb b/spec/features/rooms_spec.rb index b4a4fb24..fbb2dcbe 100644 --- a/spec/features/rooms_spec.rb +++ b/spec/features/rooms_spec.rb @@ -5,8 +5,7 @@ require 'spec_helper' feature Room do let!(:conference) { create(:conference) } let!(:venue) { create(:venue, conference: conference) } - let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } - let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } + let!(:organizer) { create(:organizer, resource: conference) } shared_examples 'rooms' do scenario 'adds a room', feature: true, js: true do diff --git a/spec/features/splashpage_spec.rb b/spec/features/splashpage_spec.rb index c87fca4a..c637d523 100644 --- a/spec/features/splashpage_spec.rb +++ b/spec/features/splashpage_spec.rb @@ -6,8 +6,7 @@ feature Splashpage do # It is necessary to use bang version of let to build roles before user let!(:conference) { create(:conference) } - let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } - let!(:organizer) { create(:user, email: 'admin@example.com', role_ids: [organizer_role.id]) } + let!(:organizer) { create(:organizer, resource: conference) } let!(:participant) { create(:user, biography: '', is_admin: false) } scenario 'create a valid splashpage', js: true do diff --git a/spec/features/sponsor_spec.rb b/spec/features/sponsor_spec.rb index 270d33bb..e64946ea 100644 --- a/spec/features/sponsor_spec.rb +++ b/spec/features/sponsor_spec.rb @@ -4,8 +4,7 @@ require 'spec_helper' feature Sponsor 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!(:organizer) { create(:organizer, resource: conference) } shared_examples 'sponsors' do scenario 'adds and updates sponsors', feature: true, js: true do diff --git a/spec/features/sponsorship_level_spec.rb b/spec/features/sponsorship_level_spec.rb index 92ba6d4c..5392978c 100644 --- a/spec/features/sponsorship_level_spec.rb +++ b/spec/features/sponsorship_level_spec.rb @@ -4,8 +4,7 @@ require 'spec_helper' feature SponsorshipLevel 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!(:organizer) { create(:organizer, resource: conference) } shared_examples 'sponsorship_levels' do scenario 'adds a sponsorship level', feature: true, js: true do diff --git a/spec/features/tickets_spec.rb b/spec/features/tickets_spec.rb index c786315f..13f5a24b 100644 --- a/spec/features/tickets_spec.rb +++ b/spec/features/tickets_spec.rb @@ -4,8 +4,7 @@ require 'spec_helper' feature Ticket do let!(:conference) { create(:conference, title: 'ExampleCon') } - let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } - let!(:organizer) { create(:user, email: 'admin@example.com', role_ids: [organizer_role.id]) } + let!(:organizer) { create(:organizer, resource: conference) } context 'as a organizer' do before(:each) do diff --git a/spec/features/tracks_spec.rb b/spec/features/tracks_spec.rb index 9b0d2428..2abda427 100644 --- a/spec/features/tracks_spec.rb +++ b/spec/features/tracks_spec.rb @@ -4,8 +4,7 @@ require 'spec_helper' feature Track 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!(:organizer) { create(:organizer, resource: conference) } let(:user) { create(:user) } shared_examples 'admin tracks' do diff --git a/spec/features/venues_spec.rb b/spec/features/venues_spec.rb index d345a9f4..9d513d40 100644 --- a/spec/features/venues_spec.rb +++ b/spec/features/venues_spec.rb @@ -4,8 +4,7 @@ require 'spec_helper' feature Conference 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!(:organizer) { create(:organizer, resource: conference) } shared_examples 'venue' do scenario 'adds and updates venue' do diff --git a/spec/features/versions_spec.rb b/spec/features/versions_spec.rb index a0963323..ec443fd0 100644 --- a/spec/features/versions_spec.rb +++ b/spec/features/versions_spec.rb @@ -5,8 +5,7 @@ require 'spec_helper' feature 'Version' do let!(:conference) { create(:conference) } let!(:cfp) { create(:cfp, program: conference.program) } - let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } - let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } + let!(:organizer) { create(:organizer, resource: conference) } 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') } @@ -212,7 +211,7 @@ feature 'Version' do visit admin_revision_history_path expect(page).to have_text("#{organizer.name} submitted new event ABC in conference #{conference.short_title}") - expect(page).to have_text("#{organizer.name} updated difficulty level and subtitle of event ABC in conference #{conference.short_title}") + expect(page).to have_text("#{organizer.name} updated subtitle and difficulty level of event ABC in conference #{conference.short_title}") expect(page).to have_text("#{organizer.name} rejected event ABC in conference #{conference.short_title}") expect(page).to have_text("#{organizer.name} resubmitted event ABC in conference #{conference.short_title}") expect(page).to have_text("#{organizer.name} accepted event ABC in conference #{conference.short_title}") diff --git a/spec/features/volunteers_spec.rb b/spec/features/volunteers_spec.rb index 50d86108..30960a73 100644 --- a/spec/features/volunteers_spec.rb +++ b/spec/features/volunteers_spec.rb @@ -4,8 +4,7 @@ require 'spec_helper' feature Conference 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!(:organizer) { create(:organizer, resource: conference) } shared_examples 'volunteer' do scenario 'adds and updates vdays', feature: true, js: true do diff --git a/spec/models/cfp_spec.rb b/spec/models/cfp_spec.rb index f836c560..74d16907 100644 --- a/spec/models/cfp_spec.rb +++ b/spec/models/cfp_spec.rb @@ -10,7 +10,7 @@ describe Cfp do 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 } + it { is_expected.to validate_uniqueness_of(:cfp_type).ignoring_case_sensitivity.scoped_to(:program_id) } end describe '.for_events' do diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb index bb294079..e3376e79 100644 --- a/spec/models/comment_spec.rb +++ b/spec/models/comment_spec.rb @@ -5,8 +5,12 @@ require 'spec_helper' describe Commercial do describe '.find_since_last_login' do + let!(:user) do + create(:user, last_sign_in_at: nil) + end + it 'returns none if last_sign_in_at is nil' do - expect(Comment.find_since_last_login(create(:user))).to eq(Comment.none) + expect(Comment.find_since_last_login(user)).to eq(Comment.none) end end end diff --git a/spec/models/conference_spec.rb b/spec/models/conference_spec.rb index f740cc61..81e7d406 100755 --- a/spec/models/conference_spec.rb +++ b/spec/models/conference_spec.rb @@ -166,7 +166,7 @@ describe Conference do describe '#get_submissions_data' do it 'returns emtpy hash if there is no cfp or events' do - expect(subject.get_submissions_data).to eq({}) + expect(subject.get_submissions_data).to eq [] end it 'calculates the correct result with data from database' do @@ -191,12 +191,7 @@ describe Conference do create(:event, program: subject.program, created_at: Date.today - 2.weeks) - result = { - 'Submitted' => [1, 1, 1], - 'Confirmed' => [1, 3, 0], - 'Unconfirmed' => [2, 4, 0], - 'Weeks' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - } + result = [{ name: 'Submitted', data: { 'Wk 1' => 1, 'Wk 2' => 1, 'Wk 3' => 1 } }, { name: 'Confirmed', data: { 'Wk 1' => 1, 'Wk 2' => 3, 'Wk 3' => 0 } }, { name: 'Unconfirmed', data: { 'Wk 1' => 2, 'Wk 2' => 4, 'Wk 3' => 0 } }] expect(subject.get_submissions_data).to eq(result) end @@ -207,12 +202,11 @@ describe Conference do create(:cfp, start_date: Date.today, program: subject.program) create(:event, program: subject.program) - result = { - 'Submitted' => [1], - 'Confirmed' => [0], - 'Unconfirmed' => [0], - 'Weeks' => [1, 2, 3, 4, 5, 6, 7, 8] - } + result = [ + { name: 'Submitted', data: { 'Wk 1'=>1 } }, + { name: 'Confirmed', data: { 'Wk 1'=>0 } }, + { name: 'Unconfirmed', data: { 'Wk 1'=>0 } } + ] expect(subject.get_submissions_data).to eq(result) end @@ -232,12 +226,20 @@ describe Conference do confirmed.accept!(options) confirmed.confirm! - result = { - 'Submitted' => [0, 0, 3], - 'Confirmed' => [0, 0, 1], - 'Unconfirmed' => [0, 0, 1], - 'Weeks' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] - } + result = [ + { + name: 'Submitted', + data: { 'Wk 1' => 0, 'Wk 2' => 0, 'Wk 3' => 3 } + }, + { + name: 'Confirmed', + data: { 'Wk 1' => 0, 'Wk 2' => 0, 'Wk 3' => 1 } + }, + { + name: 'Unconfirmed', + data: { 'Wk 1' => 0, 'Wk 2' => 0, 'Wk 3' => 1 } + } + ] expect(subject.get_submissions_data).to eq(result) end @@ -263,20 +265,27 @@ describe Conference do create(:event, program: subject.program, created_at: Date.today - 3.weeks) - result = { - 'Submitted' => [1, 1, 1, 1], - 'Confirmed' => [1, 0, 3, 0], - 'Unconfirmed' => [2, 0, 4, 0], - 'Weeks' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] - } + result = [ + { + name: 'Submitted', + data: { 'Wk 1' => 1, 'Wk 2' => 1, 'Wk 3' => 1, 'Wk 4' => 1 } + }, + { + name: 'Confirmed', + data: { 'Wk 1' => 1, 'Wk 2' => 0, 'Wk 3' => 3, 'Wk 4' => 0 } + }, + { + name: 'Unconfirmed', + data: { 'Wk 1' => 2, 'Wk 2' => 0, 'Wk 3' => 4, 'Wk 4' => 0 } + } + ] expect(subject.get_submissions_data).to eq(result) end end describe '#get_top_submitter' 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!(:organizer) { create(:organizer, resource: conference) } it 'calculates correct hash with top submitters' do event = create(:event, program: subject.program) @@ -768,13 +777,7 @@ describe Conference do canceled.accept!(@options) canceled.cancel! - @result = {} - @result['New'] = { 'value' => 1, 'color' => '#0000FF' } - @result['Withdrawn'] = { 'value' => 1, 'color' => '#FF8000' } - @result['Unconfirmed'] = { 'value' => 1, 'color' => '#FFFF00' } - @result['Rejected'] = { 'value' => 1, 'color' => '#FF0000' } - @result['Confirmed'] = { 'value' => 1, 'color' => '#00FF00' } - @result['Canceled'] = { 'value' => 1, 'color' => '#848484' } + @result = { 'New' => 1, 'Withdrawn' => 1, 'Unconfirmed' => 1, 'Confirmed' => 1, 'Canceled' => 1, 'Rejected' => 1 } end it '#event_distribution does calculate correct values with events' do @@ -789,7 +792,7 @@ describe Conference do it 'event_distribution does calculate correct values with just a new event' do conference = create(:conference) create(:event, program: conference.program) - result = { 'New' => { 'value' => 1, 'color' => '#0000FF' } } + result = { 'New' => 1, 'Withdrawn' => 0, 'Unconfirmed' => 0, 'Confirmed' => 0, 'Canceled' => 0, 'Rejected' => 0 } expect(conference.event_distribution).to eq(result) end @@ -797,7 +800,7 @@ describe Conference do conference = create(:conference) event = create(:event, program: conference.program) event.withdraw! - result = { 'Withdrawn' => { 'value' => 1, 'color' => '#FF8000' } } + result = { 'New' => 0, 'Withdrawn' => 1, 'Unconfirmed' => 0, 'Confirmed' => 0, 'Canceled' => 0, 'Rejected' => 0 } expect(conference.event_distribution).to eq(result) end @@ -805,7 +808,7 @@ describe Conference do conference = create(:conference) event = create(:event, program: conference.program) event.accept!(@options) - result = { 'Unconfirmed' => { 'value' => 1, 'color' => '#FFFF00' } } + result = { 'New' => 0, 'Withdrawn' => 0, 'Unconfirmed' => 1, 'Confirmed' => 0, 'Canceled' => 0, 'Rejected' => 0 } expect(conference.event_distribution).to eq(result) end @@ -813,7 +816,7 @@ describe Conference do conference = create(:conference) event = create(:event, program: conference.program) event.reject!(@options) - result = { 'Rejected' => { 'value' => 1, 'color' => '#FF0000' } } + result = { 'New' => 0, 'Withdrawn' => 0, 'Unconfirmed' => 0, 'Confirmed' => 0, 'Canceled' => 0, 'Rejected' => 1 } expect(conference.event_distribution).to eq(result) end @@ -823,7 +826,7 @@ describe Conference do event = create(:event, program: conference.program) event.accept!(@options) event.confirm! - result = { 'Confirmed' => { 'value' => 1, 'color' => '#00FF00' } } + result = { 'New' => 0, 'Withdrawn' => 0, 'Unconfirmed' => 0, 'Confirmed' => 1, 'Canceled' => 0, 'Rejected' => 0 } expect(conference.event_distribution).to eq(result) end @@ -832,7 +835,7 @@ describe Conference do event = create(:event, program: conference.program) event.accept!(@options) event.cancel! - result = { 'Canceled' => { 'value' => 1, 'color' => '#848484' } } + result = { 'New' => 0, 'Withdrawn' => 0, 'Unconfirmed' => 0, 'Confirmed' => 0, 'Canceled' => 1, 'Rejected' => 0 } expect(conference.event_distribution).to eq(result) end @@ -848,61 +851,31 @@ describe Conference do it 'self#event_distribution does calculate correct values with just a new event' do @conference.program.events.clear create(:event, program: @conference.program) - result = { 'New' => { 'value' => 1, 'color' => '#0000FF' } } + result = { 'New' => 1, 'Withdrawn' => 0, 'Unconfirmed' => 0, 'Confirmed' => 0, 'Canceled' => 0, 'Rejected' => 0 } expect(Conference.event_distribution).to eq(result) end it 'self#event_distribution does calculate correct values with just a new events from different conferences' do create(:event, program: @conference.program) - @result['New'] = { 'value' => 2, 'color' => '#0000FF' } - expect(Conference.event_distribution).to eq(@result) + result = { 'New' => 2, 'Withdrawn' => 1, 'Unconfirmed' => 1, 'Confirmed' => 1, 'Canceled' => 1, 'Rejected' => 1 } + expect(Conference.event_distribution).to eq(result) end end describe 'self#event_distribution' 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!(:organizer) { create(:organizer, resource: conference) } - it 'self#event_distribution calculates correct values with user' do - create(:user, last_sign_in_at: Date.today - 3.months + 1.day) # active - create(:user, confirmed_at: nil) # unconfirmed - create(:user, last_sign_in_at: Date.today - 1.year - 1.day) # dead + it 'self#user_distribution calculates correct values with user' do result = {} result['Active'] = { 'color' => 'green', 'value' => 1 } result['Unconfirmed'] = { 'color' => 'red', 'value' => 1 } result['Dead'] = { 'color' => 'black', 'value' => 1 } - expect(Conference.user_distribution).to eq(result) - end - - it 'self#event_distribution calculates correct with only active user' do - create(:user, last_sign_in_at: Date.today - 3.months + 1.day) # active - result = {} - result['Active'] = { 'color' => 'green', 'value' => 1 } - - expect(Conference.user_distribution).to eq(result) - end - - it 'self#event_distribution calculates correct values with only unconfirmed user' do - create(:user, confirmed_at: nil) # unconfirmed - result = {} - result['Unconfirmed'] = { 'color' => 'red', 'value' => 1 } - - expect(Conference.user_distribution).to eq(result) - end - - it 'self#event_distribution calculates correct values with only dead user' do - create(:user, last_sign_in_at: Time.now - 1.year - 1.day) # dead - result = {} - result['Dead'] = { 'color' => 'black', 'value' => 1 } - - expect(Conference.user_distribution).to eq(result) - end - - it 'self#event_distribution calculates correct values without user' do - expect(Conference.user_distribution).to eq({}) + expect( + Conference.calculate_user_distribution_hash(1, 1, 1) + ).to eq(result) end end @@ -1152,7 +1125,7 @@ describe Conference do cfp.end_date = Date.new(2014, 05, 26) + 21 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]) + expect(subject.get_submissions_per_week.values).to eq([1, 1, 1, 1, 1]) end it 'does calculate correct if cfp end date is altered' do @@ -1161,7 +1134,7 @@ describe Conference do cfp.end_date = Date.new(2014, 05, 26) + 21 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]) + expect(subject.get_submissions_per_week.values).to eq([0, 0, 0, 0, 1]) end it 'pads with zeros if there are no submissions' do @@ -1169,7 +1142,7 @@ describe Conference do cfp.start_date = Date.new(2014, 05, 26) cfp.end_date = Date.new(2014, 05, 26) + 21 cfp.save! - expect(subject.get_submissions_per_week).to eq([0, 0, 0, 0]) + expect(subject.get_submissions_per_week.values).to eq([0, 0, 0, 0]) end it 'summarized correct if there are no submissions in one week' do @@ -1180,7 +1153,7 @@ describe Conference do 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)] - expect(subject.get_submissions_per_week).to eq([0, 1, 2, 2, 3]) + expect(subject.get_submissions_per_week.values).to eq([0, 1, 2, 2, 3]) end it 'summarized correct if there are submissions every week except the first' do @@ -1190,7 +1163,7 @@ describe Conference do 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]) + expect(subject.get_submissions_per_week.values).to eq([0, 1, 2, 2]) end it 'summarized correct if there are submissions every week' do @@ -1201,7 +1174,9 @@ describe Conference do 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)] - expect(subject.get_submissions_per_week).to eq([1, 2, 3, 3]) + expect(subject.get_submissions_per_week).to eq( + 'Wk 1' => 1, 'Wk 2' => 2, 'Wk 3' => 3, 'Wk 4' => 3 + ) end it 'pads left' do @@ -1210,7 +1185,7 @@ describe Conference do cfp.end_date = Date.new(2014, 05, 26) + 21 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]) + expect(subject.get_submissions_per_week.values).to eq([0, 0, 0, 1]) end it 'pads middle' do @@ -1220,7 +1195,7 @@ describe Conference do 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]) + expect(subject.get_submissions_per_week.values).to eq([1, 1, 1, 2]) end it 'pads right' do @@ -1229,7 +1204,7 @@ describe Conference do cfp.end_date = Date.new(2014, 05, 26) + 21 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]) + expect(subject.get_submissions_per_week.values).to eq([1, 1, 1, 1]) end end @@ -1240,7 +1215,7 @@ describe Conference do start_date: Date.new(2014, 05, 26), end_date: Date.new(2014, 05, 26) + 21, conference: subject) - expect(subject.get_registrations_per_week).to eq([0, 0, 0, 0]) + expect(subject.get_registrations_per_week.values).to eq([0, 0, 0, 0]) end it 'summarized correct if there are no registrations in one week' do @@ -1255,7 +1230,7 @@ describe Conference do create(:registration, conference: subject, created_at: Date.new(2014, 05, 26) + 28) - expect(subject.get_registrations_per_week).to eq([0, 1, 2, 2, 3]) + expect(subject.get_registrations_per_week.values).to eq([0, 1, 2, 2, 3]) end it 'returns [1] if there is one registration on the first day' do @@ -1265,7 +1240,7 @@ describe Conference do create(:registration, conference: subject, created_at: Date.new(2014, 05, 26)) - expect(subject.get_registrations_per_week).to eq([1, 1]) + expect(subject.get_registrations_per_week.values).to eq([1, 1]) end it 'summarized correct if there are registrations every week' do @@ -1279,7 +1254,7 @@ describe Conference do create(:registration, conference: subject, created_at: Date.new(2014, 05, 26) + 14) - expect(subject.get_registrations_per_week).to eq([1, 2, 3, 3]) + expect(subject.get_registrations_per_week.values).to eq([1, 2, 3, 3]) end it 'summarized correct if there are registrations every week except the first' do @@ -1294,7 +1269,7 @@ describe Conference do create(:registration, conference: subject, created_at: Date.new(2014, 05, 26) + 28) - expect(subject.get_registrations_per_week).to eq([0, 1, 2, 2, 3]) + expect(subject.get_registrations_per_week.values).to eq([0, 1, 2, 2, 3]) end it 'pads left' do @@ -1309,7 +1284,7 @@ describe Conference do create(:registration, conference: subject, created_at: Date.new(2014, 05, 26) + 35) - expect(subject.get_registrations_per_week).to eq([0, 0, 0, 1, 2, 3]) + expect(subject.get_registrations_per_week.values).to eq([0, 0, 0, 1, 2, 3]) end it 'pads middle' do @@ -1322,7 +1297,7 @@ describe Conference do create(:registration, conference: subject, created_at: Date.new(2014, 05, 26) + 35) - expect(subject.get_registrations_per_week).to eq([1, 1, 1, 1, 1, 2]) + expect(subject.get_registrations_per_week.values).to eq([1, 1, 1, 1, 1, 2]) end it 'pads right' do @@ -1335,7 +1310,7 @@ describe Conference do create(:registration, conference: subject, created_at: Date.new(2014, 05, 26) + 7) - expect(subject.get_registrations_per_week).to eq([1, 2, 2, 2, 2, 2]) + expect(subject.get_registrations_per_week.values).to eq([1, 2, 2, 2, 2, 2]) end end @@ -1409,9 +1384,7 @@ describe Conference do # It is necessary to use bang version of let to build roles before user let!(:conference) { create(:conference) } - let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } - let!(:organizer) { create(:user, role_ids: [organizer_role.id]) } - + let!(:organizer) { create(:organizer, resource: conference) } let(:user) { create(:user) } context 'user not registered' do diff --git a/spec/models/role_spec.rb b/spec/models/role_spec.rb index 5edeb8e8..58c2e287 100644 --- a/spec/models/role_spec.rb +++ b/spec/models/role_spec.rb @@ -4,9 +4,9 @@ require 'spec_helper' describe Role do let(:conference) { create(:conference) } - let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } - let!(:cfp_role) { Role.find_by(name: 'cfp', resource: conference) } - let!(:organizer) { create(:user, role_ids: organizer_role.id) } + let!(:organizer_role) { Role.find_or_create_by(name: 'organizer', resource: conference) } + let!(:cfp_role) { Role.find_or_create_by(name: 'cfp', resource: conference) } + let!(:organizer) { create(:organizer, resource: conference) } let(:user) { create(:user) } it 'get_users' do diff --git a/spec/models/track_spec.rb b/spec/models/track_spec.rb index 3d7cbb9c..b58fc622 100644 --- a/spec/models/track_spec.rb +++ b/spec/models/track_spec.rb @@ -27,7 +27,8 @@ describe Track do 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) } + # there is a bug: https://github.com/thoughtbot/shoulda-matchers/issues/814 + # it { is_expected.to validate_uniqueness_of(:short_name).ignoring_case_sensitivity.scoped_to(:program) } it { is_expected.to validate_presence_of(:state) } it { is_expected.to validate_inclusion_of(:state).in_array(%w[new to_accept accepted confirmed to_reject rejected canceled withdrawn]) } it { is_expected.to validate_inclusion_of(:cfp_active).in_array([true, false]) } diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 13fcec74..29aadfe6 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -10,7 +10,7 @@ describe User do let(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let(:cfp_role) { Role.find_by(name: 'cfp', resource: conference) } let(:volunteers_coordinator_role) { Role.find_by(name: 'volunteers_coordinator', resource: conference) } - let(:organizer) { create(:user, role_ids: [organizer_role.id]) } + let(:organizer) { create(:organizer, resource: conference) } let(:user) { create(:user) } let(:user_disabled) { create(:user, :disabled) } @@ -27,7 +27,7 @@ describe User do it { is_expected.to validate_presence_of(:email) } it { is_expected.to validate_presence_of(:username) } - it { is_expected.to validate_uniqueness_of(:username) } + it { is_expected.to validate_uniqueness_of(:username).ignoring_case_sensitivity } it 'biography can not have more than 150 words' do # Text with 151 words @@ -99,6 +99,23 @@ describe User do expect(User.comment_notifiable(conference)).not_to include(user) end end + + describe 'user distribution scopes' do + it 'scopes recent users' do + create(:user, last_sign_in_at: Date.today - 3.months + 1.day) # active + expect(User.recent.count).to eq(1) + end + + it 'scopes unconfirmed users' do + create(:user, confirmed_at: nil) # unconfirmed + expect(User.unconfirmed.count).to eq(1) + end + + it 'scopes dead users' do + create(:user, last_sign_in_at: Time.zone.now - 1.year - 1.day) # dead + expect(User.dead.count).to eq(1) + end + end end describe 'methods' do @@ -400,8 +417,7 @@ describe User do describe '#has_cached_role?' do describe 'when user has a role' do it 'returns true when the user has the role' do - user = create(:user, role_ids: organizer_role.id) - expect(user.has_cached_role?('organizer', conference)).to be true + expect(organizer.has_cached_role?('organizer', conference)).to be true end it 'returns false when the user does not have the role' do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index e9d32f4a..fe6bab9b 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -14,6 +14,8 @@ require File.expand_path('../../config/environment', __FILE__) require 'rspec/rails' require 'shoulda/matchers' +require 'webdrivers' + # To avoid confusion on missed migrations - use Rails 4 checker to ensure # all migrations applied ActiveRecord::Migration.maintain_test_schema! @@ -21,8 +23,6 @@ ActiveRecord::Migration.maintain_test_schema! # Keep capybara and the database on the same page require 'transactional_capybara/rspec' -require 'selenium/webdriver' - # Adds rspec helper provided by paper_trail # makes it easier to control when PaperTrail is enabled during testing. require 'paper_trail/frameworks/rspec' @@ -60,6 +60,8 @@ RSpec.configure do |config| # --seed 1234 config.order = 'random' + Capybara.disable_animation = true + Capybara.register_driver :firefox do |app| Capybara::Selenium::Driver.new(app, browser: :firefox) end @@ -77,7 +79,7 @@ RSpec.configure do |config| Capybara.register_driver :chrome_headless do |app| capabilities = Selenium::WebDriver::Remote::Capabilities.chrome( - chromeOptions: { args: %w(headless disable-gpu window-size=1920x1080) } + chromeOptions: { args: %w(headless disable-gpu window-size=1920x1080 no-sandbox) } ) Capybara::Selenium::Driver.new( app, browser: :chrome, desired_capabilities: capabilities @@ -119,6 +121,17 @@ RSpec.configure do |config| # save_and_open_page # end # end + + # use the config to use + # t('some.locale.key') instead of always having to type I18n.t + config.include AbstractController::Translation end OmniAuth.config.test_mode = true + +Shoulda::Matchers.configure do |config| + config.integrate do |with| + with.test_framework :rspec + with.library :rails + end +end diff --git a/spec/support/save_feature_failures.rb b/spec/support/save_feature_failures.rb index 698e8894..8b1fb104 100644 --- a/spec/support/save_feature_failures.rb +++ b/spec/support/save_feature_failures.rb @@ -4,13 +4,16 @@ RSpec.configure do |config| config.after(:each, type: :feature) do example_filename = RSpec.current_example.full_description example_filename = example_filename.tr(' ', '_') - example_filename += '.html' example_filename = File.expand_path(example_filename, Capybara.save_path) + example_screenshotname = "#{example_filename}.png" + example_filename += '.html' if RSpec.current_example.exception.present? save_page(example_filename) + save_page(example_screenshotname) # remove the file if the test starts working again - elsif File.exist?(example_filename) - File.unlink(example_filename) + else + File.unlink(example_filename) if File.exist?(example_filename) + File.unlink(example_screenshotname) if File.exist?(example_screenshotname) end end end