diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index ce007b99..25ccb622 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -11,6 +11,8 @@ linters: # Offense count: 945 LineLength: exclude: + - "app/views/admin/booths/_change_state_dropdown.html.haml" + - "app/views/admin/booths/_form.html.haml" - "app/views/admin/booths/index.html.haml" - "app/views/admin/booths/show.html.haml" - "app/views/admin/campaigns/_form.html.haml" diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 38bf269f..a91f2ae9 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -330,6 +330,8 @@ Metrics/LineLength: # Configuration parameters: CountComments. Metrics/MethodLength: Max: 56 + Exclude: + - 'app/models/admin_ability.rb' # Offense count: 3 # Configuration parameters: CountComments. @@ -443,6 +445,7 @@ Style/HashSyntax: # Configuration parameters: MaxLineLength. Style/IfUnlessModifier: Exclude: + - 'app/controllers/admin/booths_controller.rb' - 'app/controllers/admin/events_controller.rb' - 'app/controllers/api/v1/events_controller.rb' - 'app/controllers/conference_registrations_controller.rb' diff --git a/app/assets/javascripts/osem-dashboard.js b/app/assets/javascripts/osem-dashboard.js index c8d5b853..83d2b468 100644 --- a/app/assets/javascripts/osem-dashboard.js +++ b/app/assets/javascripts/osem-dashboard.js @@ -55,7 +55,6 @@ $(function() { } function draw_line_chart(animation, $canvas){ - var options = get_animation({}, animation); var chart_data = create_dataset($canvas); var weeks = $canvas.parent().data('weeks'); var data = { @@ -63,10 +62,27 @@ $(function() { 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'); diff --git a/app/assets/stylesheets/osem.css.scss b/app/assets/stylesheets/osem.css.scss index 5a331436..79768c5d 100644 --- a/app/assets/stylesheets/osem.css.scss +++ b/app/assets/stylesheets/osem.css.scss @@ -94,3 +94,13 @@ p.comment-body { .box{ height: 230px; } + +/* sidebar hamburger btn */ +.side-nav-btn{ + margin-left: 10px; + float: left; + } + +.qr-image{ + margin-left: 120px; +} diff --git a/app/controllers/admin/conferences_controller.rb b/app/controllers/admin/conferences_controller.rb index 6716a253..3905012c 100644 --- a/app/controllers/admin/conferences_controller.rb +++ b/app/controllers/admin/conferences_controller.rb @@ -211,7 +211,7 @@ module Admin :vpositions_attributes, :use_volunteers, :color, :sponsorship_levels_attributes, :sponsors_attributes, :targets, :targets_attributes, - :campaigns, :campaigns_attributes, :registration_limit, :organization_id, :ticket_layout) + :campaigns, :campaigns_attributes, :registration_limit, :organization_id, :ticket_layout, :booth_limit) end end end diff --git a/app/controllers/physical_ticket_controller.rb b/app/controllers/physical_ticket_controller.rb index fb25ae63..af02155c 100644 --- a/app/controllers/physical_ticket_controller.rb +++ b/app/controllers/physical_ticket_controller.rb @@ -13,6 +13,7 @@ class PhysicalTicketController < ApplicationController @file_name = "ticket_for_#{@conference.short_title}" @user = @physical_ticket.user @ticket_layout = @conference.ticket_layout.to_sym + @qrcode_image = RQRCode::QRCode.new(@physical_ticket.token).as_png(size: 180, border_modules: 0) respond_to do |format| format.html format.pdf do diff --git a/app/controllers/ticket_purchases_controller.rb b/app/controllers/ticket_purchases_controller.rb index 792122e2..f15fc993 100644 --- a/app/controllers/ticket_purchases_controller.rb +++ b/app/controllers/ticket_purchases_controller.rb @@ -2,6 +2,7 @@ class TicketPurchasesController < ApplicationController before_filter :authenticate_user! load_resource :conference, find_by: :short_title authorize_resource :conference_registrations, class: Registration + authorize_resource def create current_user.ticket_purchases.by_conference(@conference).unpaid.destroy_all diff --git a/app/models/admin_ability.rb b/app/models/admin_ability.rb index 7db0cfd7..cfe17d1d 100644 --- a/app/models/admin_ability.rb +++ b/app/models/admin_ability.rb @@ -74,6 +74,11 @@ class AdminAbility cannot :destroy, Track do |track| track.self_organized? end + # Can't accept a booth when booth_limit is reached + cannot :accept, Booth do |booth| + conference = booth.conference + conference.maximum_accepted_booths? + end end # Abilities for signed in users with roles @@ -116,7 +121,10 @@ class AdminAbility can :manage, Commercial, commercialable_type: 'Conference', commercialable_id: conf_ids can :manage, Registration, conference_id: conf_ids - can :manage, RegistrationPeriod, conference_id: conf_ids + can :manage, RegistrationPeriod do |registration_period| + conference = registration_period.conference + conf_ids.include?(conference.id) && conference.tickets.for_registration.any? + end can :manage, Booth, conference_id: conf_ids can :manage, Question, conference_id: conf_ids can :manage, Question do |question| diff --git a/app/models/booth.rb b/app/models/booth.rb index d7cc3eb2..4e42d839 100644 --- a/app/models/booth.rb +++ b/app/models/booth.rb @@ -25,6 +25,7 @@ class Booth < ActiveRecord::Base :submitter_relationship, presence: true + scope :accepted, -> { where(state: 'accepted') } scope :confirmed, -> { where(state: 'confirmed') } mount_uploader :picture, PictureUploader, mount_on: :logo_link diff --git a/app/models/conference.rb b/app/models/conference.rb index b528d755..919bf7e5 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -26,7 +26,11 @@ class Conference < ActiveRecord::Base has_many :ticket_purchases, dependent: :destroy has_many :payments, dependent: :destroy has_many :supporters, through: :ticket_purchases, source: :user - has_many :tickets, dependent: :destroy + has_many :tickets, dependent: :destroy do + def for_registration + where(registration_ticket: true) + end + end has_many :resources, dependent: :destroy has_many :booths, dependent: :destroy @@ -738,6 +742,15 @@ class Conference < ActiveRecord::Base (start_hour..(end_hour - 1)).cover?(current_hour) ? current_hour - start_hour : 0 end + ## + # + # ====Returns + # * +True+ -> if accepted booths are equal to the booth limit + # * +False+ -> Accepted booths have not reached the booth limit + def maximum_accepted_booths? + booth_limit > 0 && booths.accepted.count + booths.confirmed.count >= booth_limit + end + ## # Return the current conference object to be used in RevisionCount # diff --git a/app/pdfs/ticket_pdf.rb b/app/pdfs/ticket_pdf.rb index 1c26ec77..ecb4cd2c 100644 --- a/app/pdfs/ticket_pdf.rb +++ b/app/pdfs/ticket_pdf.rb @@ -77,5 +77,9 @@ class TicketPdf < Prawn::Document move_up 180 end - def draw_fourth_square; end + def draw_fourth_square + x = @mid_horizontal + (@right - @mid_horizontal - 180) / 2 + y = cursor - (bounds.top - @mid_vertical - 180) / 2 + print_qr_code(@physical_ticket.token, pos: [x, y], extent: 180, stroke: false) + end end diff --git a/app/views/admin/booths/_change_state_dropdown.html.haml b/app/views/admin/booths/_change_state_dropdown.html.haml index 8178a790..12b982df 100644 --- a/app/views/admin/booths/_change_state_dropdown.html.haml +++ b/app/views/admin/booths/_change_state_dropdown.html.haml @@ -1,11 +1,17 @@ + - if booth.transition_possible? :accept - - if @conference.email_settings.send_on_booths_acceptance - - link = 'Accept with email' - - else - - link = 'Accept booth' - %li= link_to link, - accept_admin_conference_booth_path(@conference.short_title, booth), - method: :patch ,id: "accept_booth_#{booth.id}" + - 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?" + - 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 + - else + - link = 'Accept booth' + %li= link_to link, + accept_admin_conference_booth_path(@conference.short_title, booth), + method: :patch ,id: "accept_booth_#{booth.id}", + data: (confirm_message ? { confirm: confirm_message } : nil) - if booth.transition_possible? :reject - if @conference.email_settings.send_on_booths_rejection @@ -14,7 +20,8 @@ - link = 'Reject' %li= link_to link, reject_admin_conference_booth_path(@conference.short_title, booth), - method: :patch, id: "reject_booth_#{booth.id}" + method: :patch, id: "reject_booth_#{booth.id}", + 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', diff --git a/app/views/admin/booths/index.html.haml b/app/views/admin/booths/index.html.haml index 27f505ad..fc3f3ba3 100644 --- a/app/views/admin/booths/index.html.haml +++ b/app/views/admin/booths/index.html.haml @@ -9,48 +9,68 @@ = link_to 'Add Booth', new_admin_conference_booth_path(@conference.short_title), class: 'button btn btn-primary' %p.text-muted All the booth requests + .row .col-md-12 - .margin-booth-table - %table.table.table-striped.table-bordered.table-hover.datatable - %thead - %th - %b ID - %th - %b Logo - %th - %b Title - %th - %b Submitter - %th - %b Responsibles - %th - %b State - %th - %b Actions - - @booths.each do |booth| - %tr + %h4 + - 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. + - elsif !@conference.maximum_accepted_booths? + %p + You cannot accept more than + %b + = pluralize(@conference.booth_limit, 'booth') + ( + = pluralize(@conference.booths.accepted.count + @conference.booths.confirmed.count, 'accepted booth') + so far) + - else + %p + You have reached the maximum number of accepted booths. + ( + = link_to "#{@conference.booth_limit} booths", edit_admin_conference_path(@conference.short_title) + ) + %table.table.table-striped.table-bordered.table-hover.datatable + %thead + %th + %b ID + %th + %b Logo + %th + %b Title + %th + %b Submitter + %th + %b Responsibles + %th + %b State + %th + %b Actions + - @booths.each do |booth| + %tr + %td + = booth.id + %td + - if booth.logo_link + = image_tag(booth.picture.thumb.url, width: '20%') + %td + = link_to booth.title, admin_conference_booth_path(@conference.short_title, booth) + %td + = link_to booth.submitter.name, admin_user_path(booth.submitter) if booth.submitter + %td + .responsibles + - booth.responsibles.each_with_index do |responsible, i| + = link_to responsible.name, admin_user_path(responsible) + = ", " unless i == booth.responsibles.length - 1 + %td + .btn-group + %button{ type: 'button', class: 'btn btn-link dropdown-toggle', 'data-toggle' => 'dropdown' } + = booth.state.humanize + %span.caret + %ul.dropdown-menu{ role: 'menu' } + = render 'change_state_dropdown', booth: booth %td - = booth.id - %td - - if booth.logo_link - = image_tag(booth.picture.thumb.url, width: '20%') - %td - = link_to booth.title, admin_conference_booth_path(@conference.short_title, booth) - %td - = link_to booth.submitter.name, admin_user_path(booth.submitter) if booth.submitter - %td - .responsibles - - booth.responsibles.each_with_index do |responsible, i| - = link_to responsible.name, admin_user_path(responsible) - = ", " unless i == booth.responsibles.length - 1 - %td - .btn-group - %button{ type: 'button', class: 'btn btn-link dropdown-toggle', 'data-toggle' => 'dropdown' } - = booth.state.humanize - %span.caret - %ul.dropdown-menu{ role: 'menu' } - = render 'change_state_dropdown', booth: booth - %td - = link_to 'Edit', edit_admin_conference_booth_path(@conference.short_title, booth.id), - class: 'btn btn-primary' + = link_to 'Edit', edit_admin_conference_booth_path(@conference.short_title, booth.id), + class: 'btn btn-primary' diff --git a/app/views/admin/conferences/edit.html.haml b/app/views/admin/conferences/edit.html.haml index 2d5df126..26ae198f 100644 --- a/app/views/admin/conferences/edit.html.haml +++ b/app/views/admin/conferences/edit.html.haml @@ -26,4 +26,7 @@ = f.input :end_hour, input_html: {size: 2, type: 'number', min: 1, max: 24} = f.inputs name: 'Registrations' do = f.input :registration_limit, as: :number, in: 0..9999, hint: 'Limit the number of registrations to the conference (0 no limit). 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') +'.' = f.action :submit, as: :button, button_html: {class: 'btn btn-primary'} diff --git a/app/views/admin/emails/index.html.haml b/app/views/admin/emails/index.html.haml index 99d02130..83ebe210 100644 --- a/app/views/admin/emails/index.html.haml +++ b/app/views/admin/emails/index.html.haml @@ -109,7 +109,7 @@ %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-body-input-id' => 'email_settings_booths_acceptance_body', - 'data-body-text' => "Dear {name},\n\nWe are really 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 look 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 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 diff --git a/app/views/admin/registration_periods/show.html.haml b/app/views/admin/registration_periods/show.html.haml index 057a7a37..e923d089 100644 --- a/app/views/admin/registration_periods/show.html.haml +++ b/app/views/admin/registration_periods/show.html.haml @@ -25,5 +25,12 @@ = link_to 'Delete', admin_conference_registration_period_path, method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-danger' - else - - if can? :create, @conference.build_registration_period - = link_to 'New Registration Period', new_admin_conference_registration_period_path, class: 'btn btn-primary' + - unless @conference.tickets.for_registration.empty? + - if can? :create, @conference.build_registration_period + = link_to 'New Registration Period', new_admin_conference_registration_period_path, class: 'btn btn-primary' + - else + .h3.text-left + No Registration Tickets! + %small + = link_to 'Create registration tickets', new_admin_conference_ticket_path + before creating the registration period. diff --git a/app/views/layouts/_admin_sidebar.html.haml b/app/views/layouts/_admin_sidebar.html.haml index 1c7bac9a..28ef62e2 100644 --- a/app/views/layouts/_admin_sidebar.html.haml +++ b/app/views/layouts/_admin_sidebar.html.haml @@ -1,4 +1,4 @@ -%ul.nav.nav-stacked.nav-pills.mySidebar +%ul.nav.nav-stacked.nav-pills.mySidebar.collapse.navbar-collapse#side-nav .btn-group %button{type:'button', class: 'btn btn-default btn-link dropdown-toggle', 'data-toggle'=>'dropdown'} %span.fa.fa-cog diff --git a/app/views/layouts/_navigation.html.haml b/app/views/layouts/_navigation.html.haml index 9750be92..9995123b 100644 --- a/app/views/layouts/_navigation.html.haml +++ b/app/views/layouts/_navigation.html.haml @@ -1,7 +1,13 @@ .navbar.navbar-default.navbar-fixed-top.nav-osem{role: 'navigation'} .container .navbar-header - %button{"data-target"=>".navbar-collapse", "data-toggle"=>"collapse", class: 'navbar-toggle', type: 'button'} + - if @conference && @conference.short_title.present? + %button{ "data-target"=>"#side-nav", "data-toggle"=>"collapse", class: 'navbar-toggle side-nav-btn', type: 'button' } + %span.sr-only Toggle navigation + %span.icon-bar + %span.icon-bar + %span.icon-bar + %button{"data-target"=>"#main-nav", "data-toggle"=>"collapse", class: 'navbar-toggle', type: 'button'} %span.sr-only Toggle navigation %span.icon-bar @@ -11,7 +17,7 @@ = link_to (ENV['OSEM_NAME'] || 'OSEM'), root_path, class: 'navbar-brand', title: 'Open Source Event Manager' - else = link_to conference.organization.name, organizations_path, class: 'navbar-brand', title: 'Open Source Event Manager' - .collapse.navbar-collapse + .collapse.navbar-collapse#main-nav - if content_for :splash_nav %ul.nav.navbar-nav#splash-nav = content_for :splash_nav diff --git a/app/views/physical_ticket/show.html.haml b/app/views/physical_ticket/show.html.haml index 067f0a9b..40513ae8 100644 --- a/app/views/physical_ticket/show.html.haml +++ b/app/views/physical_ticket/show.html.haml @@ -67,6 +67,7 @@ = @physical_ticket.ticket_purchase.id %br .col-md-5.col-md-offset-2.box.well + = image_tag(@qrcode_image.to_data_url, class: 'img-responsive qr-image') .row .col-md-12 %p.text-left diff --git a/db/migrate/20170728182033_add_booth_limit_to_conferences.rb b/db/migrate/20170728182033_add_booth_limit_to_conferences.rb new file mode 100644 index 00000000..60643784 --- /dev/null +++ b/db/migrate/20170728182033_add_booth_limit_to_conferences.rb @@ -0,0 +1,5 @@ +class AddBoothLimitToConferences < ActiveRecord::Migration + def change + add_column :conferences, :booth_limit, :integer, default: 0 + end +end diff --git a/db/schema.rb b/db/schema.rb index 6c40c572..83499b33 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -127,6 +127,7 @@ ActiveRecord::Schema.define(version: 20170807092805) do t.integer "end_hour", default: 20 t.integer "organization_id" t.integer "ticket_layout", default: 0 + t.integer "booth_limit", default: 0 end add_index "conferences", ["organization_id"], name: "index_conferences_on_organization_id" diff --git a/spec/controllers/admin/registration_periods_controller_spec.rb b/spec/controllers/admin/registration_periods_controller_spec.rb index 6177fde7..fd98ce77 100644 --- a/spec/controllers/admin/registration_periods_controller_spec.rb +++ b/spec/controllers/admin/registration_periods_controller_spec.rb @@ -5,7 +5,7 @@ describe Admin::RegistrationPeriodsController do # It is necessary to use bang version of let to build roles before user let(:conference) { create(:conference) } let!(: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(:participant) { create(:user) } diff --git a/spec/factories/tickets.rb b/spec/factories/tickets.rb index 88532b86..c4bb1539 100644 --- a/spec/factories/tickets.rb +++ b/spec/factories/tickets.rb @@ -3,5 +3,8 @@ FactoryGirl.define do title { "#{Faker::Hipster.word} Ticket" } price_cents 1000 price_currency 'USD' + factory :registration_ticket do + registration_ticket true + end end end diff --git a/spec/features/organization_admin_ability_spec.rb b/spec/features/organization_admin_ability_spec.rb index 8bccd2cf..d84a7c01 100644 --- a/spec/features/organization_admin_ability_spec.rb +++ b/spec/features/organization_admin_ability_spec.rb @@ -5,6 +5,7 @@ feature 'Has correct abilities' do let(:conference) { create(:full_conference, organization: organization) } let(:role_organization_admin) { Role.find_by(name: 'organization_admin', resource: organization) } let(:user_organization_admin) { create(:user, role_ids: [role_organization_admin.id]) } + let!(:registration_ticket) { create(:registration_ticket, conference: conference) } context 'when user is organization_admin' do before do diff --git a/spec/features/organizer_ability_spec.rb b/spec/features/organizer_ability_spec.rb index 5345b58c..0127ea2f 100644 --- a/spec/features/organizer_ability_spec.rb +++ b/spec/features/organizer_ability_spec.rb @@ -8,6 +8,7 @@ feature 'Has correct abilities' do let(:role_organizer_conf) { Role.find_by(name: 'organizer', resource: conference) } let(:role_organizer_other_conf) { Role.find_by(name: 'organizer', resource: other_conference) } let(:user_organizer) { create(:user, role_ids: [role_organizer_conf.id, role_organizer_other_conf.id]) } + let!(:registration_ticket) { create(:registration_ticket, conference: conference) } context 'when user is organizer' do before do diff --git a/spec/features/registration_periods_spec.rb b/spec/features/registration_periods_spec.rb index c6cc992e..5c1c90b5 100644 --- a/spec/features/registration_periods_spec.rb +++ b/spec/features/registration_periods_spec.rb @@ -6,6 +6,7 @@ feature RegistrationPeriod 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!(:registration_ticket) { create(:registration_ticket, conference: conference) } shared_examples 'successfully' do scenario 'create and update registration period', js: true do diff --git a/spec/models/admin_ability_spec.rb b/spec/models/admin_ability_spec.rb index 6c375363..f148b2ae 100644 --- a/spec/models/admin_ability_spec.rb +++ b/spec/models/admin_ability_spec.rb @@ -11,6 +11,7 @@ describe 'User with admin role' do let!(:organization) { create(:organization) } let!(:my_conference) { create(:full_conference, organization: organization) } + let!(:registration_ticket) { create(:registration_ticket, conference: my_conference) } let(:my_venue) { my_conference.venue || create(:venue, conference: my_conference) } let(:my_registration) { create(:registration, conference: my_conference, user: admin) } diff --git a/spec/models/registration_period_spec.rb b/spec/models/registration_period_spec.rb index ef28bab1..52fb3755 100644 --- a/spec/models/registration_period_spec.rb +++ b/spec/models/registration_period_spec.rb @@ -2,6 +2,7 @@ require 'spec_helper' describe RegistrationPeriod do let!(:conference) { create(:conference, start_date: Date.today, end_date: Date.today + 6) } + let!(:registration_ticket) { create(:registration_ticket, conference: conference) } let!(:registration_period) { create(:registration_period, start_date: Date.today - 2, end_date: Date.today - 1, conference: conference) } describe 'validations' do