diff --git a/.gitignore b/.gitignore
index 75a1bdc6..ce3e7f0f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,3 +38,5 @@ pickle-email-*.html
.env.local
docker-compose.env
docker-compose.yml
+.DS_Store
+.byebug_history
diff --git a/.travis.yml b/.travis.yml
index 9191bbd7..6650fbf9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,7 +8,7 @@ before_install:
- "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
- "echo `phantomjs -v`"
addons:
- mariadb: '10.1'
+ mariadb: '10.2'
notifications:
email:
on_success: change
diff --git a/Gemfile b/Gemfile
index 08170e30..22dc5f6e 100644
--- a/Gemfile
+++ b/Gemfile
@@ -83,6 +83,8 @@ gem 'jquery-ui-rails', '~> 4.2.1'
# for languages validation
gem 'iso-639'
+gem 'thor', '0.19.1'
+
# frontend javascripts
source 'https://rails-assets.org' do
# for placeholder images
@@ -198,6 +200,11 @@ gem 'sprockets-rails'
# for multiple speakers select on proposal/event forms
gem 'selectize-rails'
+# Nokogiri < 1.8.1 is subject to:
+# CVE-2017-0663, CVE-2017-7375, CVE-2017-7376, CVE-2017-9047, CVE-2017-9048,
+# CVE-2017-9049, CVE-2017-9050
+gem 'nokogiri', '>= 1.8.1'
+
# Use guard and spring for testing in development
group :development do
# to launch specs when files are modified
diff --git a/Gemfile.lock b/Gemfile.lock
index faaa8246..dc730e82 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -270,7 +270,7 @@ GEM
open4 (~> 1.3.4)
rake
mini_magick (4.5.1)
- mini_portile2 (2.2.0)
+ mini_portile2 (2.3.0)
minitest (5.10.2)
momentjs-rails (2.8.1)
railties (>= 3.1)
@@ -287,11 +287,11 @@ GEM
multi_json (1.12.1)
multi_xml (0.5.5)
multipart-post (2.0.0)
- mysql2 (0.4.2)
+ mysql2 (0.4.9)
nenv (0.3.0)
netrc (0.11.0)
- nokogiri (1.8.0)
- mini_portile2 (~> 2.2.0)
+ nokogiri (1.8.1)
+ mini_portile2 (~> 2.3.0)
notiffany (0.1.1)
nenv (~> 0.1)
shellany (~> 0.0)
@@ -511,7 +511,7 @@ GEM
sysexits (1.2.0)
term-ansicolor (1.3.2)
tins (~> 1.0)
- thor (0.19.4)
+ thor (0.19.1)
thread_safe (0.3.6)
tilt (1.4.1)
timecop (0.7.1)
@@ -609,6 +609,7 @@ DEPENDENCIES
mini_magick
money-rails
mysql2
+ nokogiri (>= 1.8.1)
omniauth
omniauth-facebook
omniauth-github
@@ -651,6 +652,7 @@ DEPENDENCIES
sqlite3
stripe
stripe-ruby-mock
+ thor (= 0.19.1)
timecop
transitions
turbolinks
@@ -661,4 +663,4 @@ DEPENDENCIES
whenever
BUNDLED WITH
- 1.15.1
+ 1.15.4
diff --git a/app/assets/javascripts/osem-tickets.js b/app/assets/javascripts/osem-tickets.js
index ea99a349..51881055 100644
--- a/app/assets/javascripts/osem-tickets.js
+++ b/app/assets/javascripts/osem-tickets.js
@@ -4,12 +4,12 @@ function update_price($this){
// Calculate price for row
var value = $this.val();
var price = $('#price_' + id).text();
- $('#total_row_' + id).text(value * price);
+ $('#total_row_' + id).text((value * price).toFixed(2));
// Calculate total price
var total = 0;
$('.total_row').each(function( index ) {
- total += parseInt($(this).text());
+ total += parseFloat($(this).text());
});
$('#total_price').text(total);
}
diff --git a/app/controllers/admin/booths_controller.rb b/app/controllers/admin/booths_controller.rb
index a65de090..102eb10b 100644
--- a/app/controllers/admin/booths_controller.rb
+++ b/app/controllers/admin/booths_controller.rb
@@ -22,7 +22,7 @@ module Admin
redirect_to admin_conference_booths_path,
notice: 'Booth successfully created.'
else
- flash[:error] = "Creating booth failed. #{@booth.errors.full_messages.to_sentence}."
+ flash.now[:error] = "Creating booth failed. #{@booth.errors.full_messages.to_sentence}."
render :new
end
end
@@ -40,7 +40,7 @@ module Admin
redirect_to admin_conference_booths_path,
notice: "Successfully updated booth for #{@booth.title}."
else
- flash[:error] = "An error prohibited the Booth for #{@booth.title} "\
+ flash.now[:error] = "An error prohibited the Booth for #{@booth.title} "\
"#{@booth.errors.full_messages.join('. ')}."
render :edit
end
diff --git a/app/controllers/admin/events_controller.rb b/app/controllers/admin/events_controller.rb
index bb23dac9..accfb281 100644
--- a/app/controllers/admin/events_controller.rb
+++ b/app/controllers/admin/events_controller.rb
@@ -102,7 +102,7 @@ module Admin
ahoy.track 'Event submission', title: 'New submission'
redirect_to admin_conference_program_events_path(@conference.short_title), notice: 'Event was successfully submitted.'
else
- flash[:error] = "Could not submit proposal: #{@event.errors.full_messages.join(', ')}"
+ flash.now[:error] = "Could not submit proposal: #{@event.errors.full_messages.join(', ')}"
render action: 'new'
end
end
diff --git a/app/controllers/admin/physical_ticket_controller.rb b/app/controllers/admin/physical_tickets_controller.rb
similarity index 88%
rename from app/controllers/admin/physical_ticket_controller.rb
rename to app/controllers/admin/physical_tickets_controller.rb
index d43c5c33..0fb26ad8 100644
--- a/app/controllers/admin/physical_ticket_controller.rb
+++ b/app/controllers/admin/physical_tickets_controller.rb
@@ -1,5 +1,5 @@
module Admin
- class PhysicalTicketController < Admin::BaseController
+ class PhysicalTicketsController < Admin::BaseController
before_action :authenticate_user!
load_resource :conference, find_by: :short_title
load_and_authorize_resource
diff --git a/app/controllers/booths_controller.rb b/app/controllers/booths_controller.rb
index 99fde3bc..f0457b88 100644
--- a/app/controllers/booths_controller.rb
+++ b/app/controllers/booths_controller.rb
@@ -23,7 +23,7 @@ class BoothsController < ApplicationController
redirect_to conference_booths_path,
notice: 'Booth successfully created.'
else
- flash[:error] = "Creating booth failed. #{@booth.errors.full_messages.to_sentence}."
+ flash.now[:error] = "Creating booth failed. #{@booth.errors.full_messages.to_sentence}."
render :new
end
end
@@ -40,7 +40,7 @@ class BoothsController < ApplicationController
redirect_to conference_booths_path,
notice: 'Booth successfully updated!'
else
- flash[:error] = "Booth could not be updated. #{@booth.errors.full_messages.to_sentence}."
+ flash.now[:error] = "Booth could not be updated. #{@booth.errors.full_messages.to_sentence}."
end
end
@@ -56,7 +56,7 @@ class BoothsController < ApplicationController
redirect_to conference_booths_path,
notice: 'Booth successfully withdrawn'
else
- flash[:error] = "Booth could not be withdrawn. #{@booth.errors.full_messages.to_sentence}."
+ flash.now[:error] = "Booth could not be withdrawn. #{@booth.errors.full_messages.to_sentence}."
end
end
@@ -70,7 +70,7 @@ class BoothsController < ApplicationController
redirect_to conference_booths_path,
notice: 'Booth successfully confirmed'
else
- flash[:error] = "Booth could not be confirmed. #{@booth.errors.full_messages.to_sentence}."
+ flash.now[:error] = "Booth could not be confirmed. #{@booth.errors.full_messages.to_sentence}."
end
end
@@ -84,7 +84,7 @@ class BoothsController < ApplicationController
redirect_to conference_booths_path,
notice: 'Booth successfully re-submitted'
else
- flash[:error] = "Booth could not be re-submitted. #{@booth.errors.full_messages.to_sentence}."
+ flash.now[:error] = "Booth could not be re-submitted. #{@booth.errors.full_messages.to_sentence}."
end
end
diff --git a/app/controllers/payments_controller.rb b/app/controllers/payments_controller.rb
index b5e2c193..322ed397 100644
--- a/app/controllers/payments_controller.rb
+++ b/app/controllers/payments_controller.rb
@@ -10,6 +10,9 @@ class PaymentsController < ApplicationController
def new
@total_amount_to_pay = Ticket.total_price(@conference, current_user, paid: false)
+ if @total_amount_to_pay.zero?
+ raise CanCan::AccessDenied.new('Nothing to pay for!', :new, Payment)
+ end
@unpaid_ticket_purchases = current_user.ticket_purchases.unpaid.by_conference(@conference)
end
@@ -18,7 +21,7 @@ class PaymentsController < ApplicationController
if @payment.purchase && @payment.save
update_purchased_ticket_purchases
- redirect_to conference_physical_ticket_index_path,
+ redirect_to conference_physical_tickets_path,
notice: 'Thanks! Your ticket is booked successfully.'
else
@total_amount_to_pay = Ticket.total_price(@conference, current_user, paid: false)
diff --git a/app/controllers/physical_ticket_controller.rb b/app/controllers/physical_tickets_controller.rb
similarity index 94%
rename from app/controllers/physical_ticket_controller.rb
rename to app/controllers/physical_tickets_controller.rb
index af02155c..2f6f18ec 100644
--- a/app/controllers/physical_ticket_controller.rb
+++ b/app/controllers/physical_tickets_controller.rb
@@ -1,4 +1,4 @@
-class PhysicalTicketController < ApplicationController
+class PhysicalTicketsController < ApplicationController
before_action :authenticate_user!
load_resource :conference, find_by: :short_title
load_and_authorize_resource find_by: :token
diff --git a/app/controllers/schedules_controller.rb b/app/controllers/schedules_controller.rb
index eeb272e0..eb145730 100644
--- a/app/controllers/schedules_controller.rb
+++ b/app/controllers/schedules_controller.rb
@@ -21,10 +21,10 @@ class SchedulesController < ApplicationController
# the schedule takes you to today if it is a date of the schedule
@current_day = @conference.current_conference_day
@day = @current_day.present? ? @current_day : @dates.first
- return unless @current_day
- # the schedule takes you to the current time if it is beetween the start and the end time.
- @hour_column = @conference.hours_from_start_time(@conf_start, @conference.end_hour)
-
+ unless @current_day
+ # the schedule takes you to the current time if it is beetween the start and the end time.
+ @hour_column = @conference.hours_from_start_time(@conf_start, @conference.end_hour)
+ end
# Ids of the schedules of confrmed self_organized tracks along with the selected_schedule_id
@selected_schedules_ids = [@conference.program.selected_schedule_id]
@conference.program.tracks.self_organized.confirmed.each do |track|
diff --git a/app/controllers/ticket_purchases_controller.rb b/app/controllers/ticket_purchases_controller.rb
index f15fc993..3eb8b68d 100644
--- a/app/controllers/ticket_purchases_controller.rb
+++ b/app/controllers/ticket_purchases_controller.rb
@@ -12,14 +12,14 @@ class TicketPurchasesController < ApplicationController
redirect_to new_conference_payment_path,
notice: 'Please pay here to get tickets.'
elsif current_user.ticket_purchases.by_conference(@conference).paid.any?
- redirect_to conference_physical_ticket_index_path,
+ redirect_to conference_physical_tickets_path,
notice: 'You have free tickets for the conference.'
else
redirect_to conference_tickets_path(@conference.short_title),
error: 'Please get at least one ticket to continue.'
end
else
- redirect_to conference_conference_registration_path(@conference.short_title),
+ redirect_to conference_tickets_path(@conference.short_title),
error: "Oops, something went wrong with your purchase! #{message}"
end
end
diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb
index e8f295d5..8f620e62 100644
--- a/app/helpers/events_helper.rb
+++ b/app/helpers/events_helper.rb
@@ -44,7 +44,7 @@ module EventsHelper
if @program.tracks.confirmed.cfp_active.any?
form.input :track_id, as: :select,
collection: @program.tracks.confirmed.cfp_active.pluck(:name, :id),
- include_blank: true
+ include_blank: '(Please select)'
end
end
end
diff --git a/app/models/ticket_purchase.rb b/app/models/ticket_purchase.rb
index a2ed2747..97fa9957 100644
--- a/app/models/ticket_purchase.rb
+++ b/app/models/ticket_purchase.rb
@@ -5,7 +5,8 @@ class TicketPurchase < ActiveRecord::Base
belongs_to :payment
validates :ticket_id, :user_id, :conference_id, :quantity, presence: true
-
+ validate :one_registration_ticket_per_user
+ validate :registration_ticket_already_purchased, on: :create
validates :quantity, numericality: { greater_than: 0 }
delegate :title, to: :ticket
@@ -25,18 +26,21 @@ class TicketPurchase < ActiveRecord::Base
def self.purchase(conference, user, purchases)
errors = []
- ActiveRecord::Base.transaction do
- conference.tickets.each do |ticket|
- quantity = purchases[ticket.id.to_s].to_i
- # if the user bought the ticket and is still unpaid, just update the quantity
- purchase = if ticket.bought?(user) && ticket.unpaid?(user)
- update_quantity(conference, quantity, ticket, user)
- else
- purchase_ticket(conference, quantity, ticket, user)
- end
-
- if purchase && !purchase.save
- errors.push(purchase.errors.full_messages)
+ if count_purchased_registration_tickets(conference, purchases) > 1
+ errors.push('You cannot buy more than one registration tickets.')
+ else
+ ActiveRecord::Base.transaction do
+ conference.tickets.each do |ticket|
+ quantity = purchases[ticket.id.to_s].to_i
+ # if the user bought the ticket and is still unpaid, just update the quantity
+ purchase = if ticket.bought?(user) && ticket.unpaid?(user)
+ update_quantity(conference, quantity, ticket, user)
+ else
+ purchase_ticket(conference, quantity, ticket, user)
+ end
+ if purchase && !purchase.save
+ errors.push(purchase.errors.full_messages)
+ end
end
end
end
@@ -71,6 +75,18 @@ class TicketPurchase < ActiveRecord::Base
end
Mailbot.ticket_confirmation_mail(self).deliver_later
end
+
+ def one_registration_ticket_per_user
+ if ticket.try(:registration_ticket?) && quantity != 1
+ errors.add(:quantity, 'cannot be greater than one for registration tickets.')
+ end
+ end
+
+ def registration_ticket_already_purchased
+ if ticket.try(:registration_ticket?) && user.tickets.for_registration(conference).present?
+ errors.add(:quantity, 'cannot be greater than one for registration tickets.')
+ end
+ end
end
private
@@ -79,3 +95,9 @@ def set_week
self.week = created_at.strftime('%W')
save!
end
+
+def count_purchased_registration_tickets(conference, purchases)
+ conference.tickets.for_registration.inject(0) do |sum, registration_ticket|
+ sum + purchases[registration_ticket.id.to_s].to_i
+ end
+end
diff --git a/app/models/ticket_scanning.rb b/app/models/ticket_scanning.rb
index 6ce9d00c..350d4f9b 100644
--- a/app/models/ticket_scanning.rb
+++ b/app/models/ticket_scanning.rb
@@ -1,3 +1,13 @@
class TicketScanning < ActiveRecord::Base
belongs_to :physical_ticket
+
+ before_create :mark_user_present
+
+ private
+
+ def mark_user_present
+ if physical_ticket.ticket.registration_ticket?
+ physical_ticket.user.mark_attendance_for_conference(physical_ticket.conference)
+ end
+ end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 793db609..231e1c11 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -47,11 +47,19 @@ class User < ActiveRecord::Base
has_many :event_users, dependent: :destroy
has_many :events, -> { uniq }, through: :event_users
has_many :presented_events, -> { joins(:event_users).where(event_users: {event_role: 'speaker'}).uniq }, through: :event_users, source: :event
- has_many :registrations, dependent: :destroy
+ has_many :registrations, dependent: :destroy do
+ def for_conference conference
+ where(conference: conference).first
+ 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
+ has_many :tickets, through: :ticket_purchases, source: :ticket do
+ def for_registration conference
+ where(conference: conference, registration_ticket: true).first
+ end
+ end
has_many :votes, dependent: :destroy
has_many :voted_events, through: :votes, source: :events
has_many :subscriptions, dependent: :destroy
@@ -89,6 +97,12 @@ class User < ActiveRecord::Base
event_registration.attended
end
+ def mark_attendance_for_conference conference
+ registration = registrations.for_conference(conference)
+ registration.attended = true
+ registration.save
+ end
+
def name
self[:name].blank? ? username : self[:name]
end
diff --git a/app/pdfs/ticket_pdf.rb b/app/pdfs/ticket_pdf.rb
index ecb4cd2c..9a09f9fe 100644
--- a/app/pdfs/ticket_pdf.rb
+++ b/app/pdfs/ticket_pdf.rb
@@ -25,20 +25,23 @@ class TicketPdf < Prawn::Document
move_up @mid_vertical
draw_text 'TICKET HOLDER', at: [@x, cursor - 30], size: 17
dash(2, space: 0)
- stroke_rectangle [@x, cursor - 50], 230, 150
- move_down 80
- draw_text 'NAME', at: [@x + 10, cursor], size: 13
- fill_color '808080'
- draw_text @user.name.to_s, at: [@x + 10, cursor - 25], size: 20
- fill_color '000000'
- draw_text 'EMAIL', at: [@x + 10, cursor - 50], size: 13
- fill_color '808080'
- draw_text @user.email.to_s, at: [@x + 10, cursor - 75], size: 20
- fill_color '000000'
- move_up 20
+ bounding_box [@x, cursor - 50], width: 230, height: 150 do
+ pad(15) do
+ text_box 'NAME', at: [@x + 10, cursor], size: 13
+ fill_color '808080'
+ text_box @user.name.to_s, at: [@x + 10, cursor - 20], size: 18
+ fill_color '000000'
+ text_box 'EMAIL', at: [@x + 10, cursor - 60], size: 13
+ fill_color '808080'
+ text_box @user.email.to_s, at: [@x + 10, cursor - 80], size: 18, overflow: :shrink_to_fit
+ fill_color '000000'
+ end
+ stroke_bounds
+ end
end
def draw_second_square
+ move_up 150
if @conference.picture?
if 7 * @conference.picture.image[:width] > 12 * @conference.picture.image[:height]
image "#{Rails.root}/public#{@conference.picture_url}", at: [@mid_horizontal + 30, cursor], width: 120
@@ -51,7 +54,11 @@ class TicketPdf < Prawn::Document
move_down 70
draw_text @conference.title.to_s, at: [@mid_horizontal + 30, cursor - 30], size: 12
draw_text @conference.organization.name.to_s, at: [@mid_horizontal + 30, cursor - 50], size: 12
- draw_text @conference.venue.name.to_s, at: [@mid_horizontal + 30, cursor - 70]
+ if @conference.venue
+ draw_text @conference.venue.name, at: [@mid_horizontal + 30, cursor - 70]
+ draw_text @conference.venue.street, at: [@mid_horizontal + 30, cursor - 90]
+ draw_text @conference.venue.city, at: [@mid_horizontal + 30, cursor - 110]
+ end
move_up 130
move_down @mid_vertical
end
diff --git a/app/views/admin/booths/index.html.haml b/app/views/admin/booths/index.html.haml
index fc3f3ba3..428895e5 100644
--- a/app/views/admin/booths/index.html.haml
+++ b/app/views/admin/booths/index.html.haml
@@ -4,9 +4,6 @@
%h1
Booths
= "(#{@booths.length})" if @booths.any?
- .pull-right
- - if can? :create, Booth
- = link_to 'Add Booth', new_admin_conference_booth_path(@conference.short_title), class: 'button btn btn-primary'
%p.text-muted
All the booth requests
@@ -32,45 +29,50 @@
(
= 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
+ - if @booths.any?
+ %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
- = link_to 'Edit', edit_admin_conference_booth_path(@conference.short_title, booth.id),
- class: 'btn btn-primary'
+ = 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'
+.row
+ .col-md-12.text-right
+ - if can? :create, Booth
+ = link_to 'New Booth', new_admin_conference_booth_path(@conference.short_title), class: 'button btn btn-primary'
diff --git a/app/views/admin/cfps/_booths_cfp.html.haml b/app/views/admin/cfps/_booths_cfp.html.haml
index 89012336..7cdc6db4 100644
--- a/app/views/admin/cfps/_booths_cfp.html.haml
+++ b/app/views/admin/cfps/_booths_cfp.html.haml
@@ -1,12 +1,16 @@
%dt
- Start Date
+ Type:
+%dd
+ = @cfp.cfp_type.capitalize
+%dt
+ Start Date:
%dd
= @cfp.start_date.strftime('%A, %B %e. %Y')
%dt
- End Date
+ End Date:
%dd
= @cfp.end_date.strftime('%A, %B %e. %Y')
%dt
- Days Left
+ Days Left:
%dd
= pluralize(@cfp.remaining_days, 'day')
diff --git a/app/views/admin/cfps/_events_cfp.html.haml b/app/views/admin/cfps/_events_cfp.html.haml
index 51bc2079..f06aa6ca 100644
--- a/app/views/admin/cfps/_events_cfp.html.haml
+++ b/app/views/admin/cfps/_events_cfp.html.haml
@@ -1,3 +1,7 @@
+%dt
+ Type:
+%dd
+ = @cfp.cfp_type.capitalize
%dt
Start Date:
%dd#start_date
@@ -19,7 +23,7 @@
%dd
= tracks(@conference)
%dt
- Public Schedule
+ Public Schedule:
%dd#schedule_public
- if @program.schedule_public
Yes
@@ -33,6 +37,6 @@
- else
No
%dt
- Rating Levels
+ Rating Levels:
%dd#rating
= @program.rating
diff --git a/app/views/admin/cfps/_tracks_cfp.html.haml b/app/views/admin/cfps/_tracks_cfp.html.haml
index e381df96..bcc2df43 100644
--- a/app/views/admin/cfps/_tracks_cfp.html.haml
+++ b/app/views/admin/cfps/_tracks_cfp.html.haml
@@ -1,3 +1,7 @@
+%dt
+ Type:
+%dd
+ = @cfp.cfp_type.capitalize
%dt
Start Date:
%dd#start_date
diff --git a/app/views/admin/events/_nested_comments.html.haml b/app/views/admin/events/_nested_comments.html.haml
index 8ab3cabb..0bfb440c 100644
--- a/app/views/admin/events/_nested_comments.html.haml
+++ b/app/views/admin/events/_nested_comments.html.haml
@@ -6,9 +6,9 @@
%div
%a.pull-right.comment-reply-link{ href: '#' } Reply
.comment-reply
- = semantic_form_for :comment, url: '#{comment_admin_conference_program_event_path(@conference.short_title, comment.commentable_id)}', method: :post do |f|
+ = semantic_form_for :comment, url: comment_admin_conference_program_event_path(@conference.short_title, comment.commentable_id), method: :post do |f|
= f.input :body
- %input{ name: 'parent', type: 'hidden', value: '#{comment.id}' }
+ %input{ name: 'parent', type: 'hidden', value: comment.id }
%input{ name: 'authenticity_token', type: 'hidden', value: '#{form_authenticity_token}' }
%button.btn.btn-primary.pull-right{ name: 'button', type: 'submit' } Add Reply
- comment.children.each do |child|
diff --git a/app/views/admin/events/index.html.haml b/app/views/admin/events/index.html.haml
index 50d7acd5..f8b58b63 100644
--- a/app/views/admin/events/index.html.haml
+++ b/app/views/admin/events/index.html.haml
@@ -9,13 +9,14 @@
=link_to 'Add Event', new_admin_conference_program_event_path(@conference.short_title), class: 'button btn btn-default btn-info'
- if can? :read, Event
.btn-group
- %button.btn.btn-default.dropdown-toggle{ 'data-toggle' => 'dropdown', type: 'button', class: 'btn btn-success' }
- Export PDF
- %span.caret
- %ul.dropdown-menu{ role: 'menu' }
- %li= link_to 'All Events', admin_conference_program_events_path(@conference.short_title, format: :pdf, event_export_option: 'all')
- %li= link_to 'Confirmed Events', admin_conference_program_events_path(@conference.short_title, format: :pdf, event_export_option: 'confirmed')
- %li= link_to 'All Events with Comments', admin_conference_program_events_path(@conference.short_title, format: :pdf, event_export_option: 'all_with_comments')
+ .btn-group
+ %button.btn.btn-default.dropdown-toggle{ 'data-toggle' => 'dropdown', type: 'button', class: 'btn btn-success' }
+ Export PDF
+ %span.caret
+ %ul.dropdown-menu{ role: 'menu' }
+ %li= link_to 'All Events', admin_conference_program_events_path(@conference.short_title, format: :pdf, event_export_option: 'all')
+ %li= link_to 'Confirmed Events', admin_conference_program_events_path(@conference.short_title, format: :pdf, event_export_option: 'confirmed')
+ %li= link_to 'All Events with Comments', admin_conference_program_events_path(@conference.short_title, format: :pdf, event_export_option: 'all_with_comments')
.btn-group
%button.btn.btn-default.dropdown-toggle{ 'data-toggle' => 'dropdown', type: 'button', class: 'btn btn-success' }
Export CSV
diff --git a/app/views/admin/physical_ticket/index.html.haml b/app/views/admin/physical_tickets/index.html.haml
similarity index 100%
rename from app/views/admin/physical_ticket/index.html.haml
rename to app/views/admin/physical_tickets/index.html.haml
diff --git a/app/views/admin/schedules/show.html.haml b/app/views/admin/schedules/show.html.haml
index 9009fcbb..258b4d87 100644
--- a/app/views/admin/schedules/show.html.haml
+++ b/app/views/admin/schedules/show.html.haml
@@ -40,11 +40,23 @@
.tab-pane{ class: "#{ (@dates.first == date) ? 'active' : '' }", id: "#{date}" }
= render partial: 'day_tab', locals: { date: date }
- else
- .h3
- No Rooms!
- %small
- = link_to 'Create rooms', admin_conference_venue_rooms_path
- before creating the schedule.
+ - if @venue.try(:rooms).present?
+ .text-right
+ - if can? :create, @program.schedules.new
+ = link_to 'Add Schedule', admin_conference_schedules_path(@conference.short_title),
+ method: :post, class: 'btn btn-primary'
+ - elsif @venue
+ .h3
+ No Rooms!
+ %small
+ = link_to 'Create rooms', admin_conference_venue_rooms_path
+ before creating the schedule.
+ - else
+ .h3
+ No Venue!
+ %small
+ = link_to 'Create a venue with rooms', new_admin_conference_venue_path
+ before creating the schedule.
:javascript
$(document).ready( function() {
diff --git a/app/views/admin/tickets/index.html.haml b/app/views/admin/tickets/index.html.haml
index b8cdb505..42154ae7 100644
--- a/app/views/admin/tickets/index.html.haml
+++ b/app/views/admin/tickets/index.html.haml
@@ -40,4 +40,4 @@
.row
.col-md-12
= link_to 'Add Ticket', new_admin_conference_ticket_path, class: 'btn btn-success pull-right'
- = link_to 'Tickets Sold', admin_conference_physical_ticket_index_path, class: 'button btn btn-default btn-info pull-right'
+ = link_to 'Tickets Sold', admin_conference_physical_tickets_path, class: 'button btn btn-default btn-info pull-right'
diff --git a/app/views/admin/tracks/index.html.haml b/app/views/admin/tracks/index.html.haml
index 6ac42003..b814ac8e 100644
--- a/app/views/admin/tracks/index.html.haml
+++ b/app/views/admin/tracks/index.html.haml
@@ -7,75 +7,76 @@
Categorize events in your conference
.row
.col-md-12
- %table.table.table-hover.table-striped.table-bordered.datatable#tracks
- %thead
- %th ID
- %th Name
- %th Description
- %th Room
- %th Start Date
- %th End Date
- %th Submitter
- %th Included in Cfp
- %th State
- %th Actions
- %tbody
- - @tracks.each do |track|
- %tr
- %td
- = track.id
- %td{ style: 'padding: 15px 0px 0px 10px;' }
- = link_to admin_conference_program_track_path(@conference.short_title, track), class: 'btn' do
- %span.label{style: "background-color: #{track.color}; color: #{ contrast_color(track.color) }"}
- = track.name
- %td
- %p
- = markdown(truncate(track.description))
- %td
- = track.room.try(:name)
- %td
- = track.start_date.strftime('%A, %B %-d. %Y') if track.start_date
- %td
- = track.end_date.strftime('%A, %B %-d. %Y') if track.end_date
- %td
- = link_to track.submitter.name, admin_user_path(track.submitter) if track.self_organized?
- %td.text-center{ 'id' => "cfp_switch_#{track.id}", 'data-order' => track.cfp_active.to_s }
- = check_box_tag "#{@conference.short_title}_#{track.short_name}", track.id, track.cfp_active,
- class: 'switch-checkbox', method: :patch,
- url: toggle_cfp_inclusion_admin_conference_program_track_path(@conference.short_title, id: track.short_name)+"?included=",
- data: { size: 'small',
- on_color: 'success',
- off_color: 'warning',
- on_text: 'Yes',
- off_text: 'No' }
+ - if @tracks.any?
+ %table.table.table-hover.table-striped.table-bordered.datatable#tracks
+ %thead
+ %th ID
+ %th Name
+ %th Description
+ %th Room
+ %th Start Date
+ %th End Date
+ %th Submitter
+ %th Included in Cfp
+ %th State
+ %th Actions
+ %tbody
+ - @tracks.each do |track|
+ %tr
+ %td
+ = track.id
+ %td{ style: 'padding: 15px 0px 0px 10px;' }
+ = link_to admin_conference_program_track_path(@conference.short_title, track), class: 'btn' do
+ %span.label{style: "background-color: #{track.color}; color: #{ contrast_color(track.color) }"}
+ = track.name
+ %td
+ %p
+ = markdown(truncate(track.description))
+ %td
+ = track.room.try(:name)
+ %td
+ = track.start_date.strftime('%A, %B %-d. %Y') if track.start_date
+ %td
+ = track.end_date.strftime('%A, %B %-d. %Y') if track.end_date
+ %td
+ = link_to track.submitter.name, admin_user_path(track.submitter) if track.self_organized?
+ %td.text-center{ 'id' => "cfp_switch_#{track.id}", 'data-order' => track.cfp_active.to_s }
+ = check_box_tag "#{@conference.short_title}_#{track.short_name}", track.id, track.cfp_active,
+ class: 'switch-checkbox', method: :patch,
+ url: toggle_cfp_inclusion_admin_conference_program_track_path(@conference.short_title, id: track.short_name)+"?included=",
+ data: { size: 'small',
+ on_color: 'success',
+ off_color: 'warning',
+ on_text: 'Yes',
+ off_text: 'No' }
- %td.text-center
- - if track.self_organized?
- .btn-group
- %button{ type: 'button', class: 'btn btn-link dropdown-toggle', 'data-toggle' => 'dropdown' }
- = track.state.humanize
- %span.caret
- %ul.dropdown-menu{ role: 'menu' }
- = render 'change_state_dropdown', track: track
- - else
- = track.state.humanize
- %td
- .btn-group{ role: 'group' }
- - if can? :edit, track
- = link_to 'Edit', edit_admin_conference_program_track_path(@conference.short_title, track), class: 'btn btn-primary'
- - special_style = true
- - if can? :destroy, track
- = link_to 'Delete', admin_conference_program_track_path(@conference.short_title, track), method: :delete, class: 'btn btn-danger',
- data: { confirm: "Do you really want to delete #{track.name}? Attention: This track will be removed from all Events that have it set" }
+ %td.text-center
- if track.self_organized?
- - if track.selected_schedule
- - if can? :show, track.selected_schedule
- = link_to 'Show Schedule', admin_conference_schedule_path(@conference.short_title, track.selected_schedule),
- class: 'btn btn-default'
- - elsif can? :create, @program.schedules.build(track: track)
- = button_to 'Create Schedule', admin_conference_schedules_path(@conference.short_title),
- form: { class: 'btn', style: 'padding: 0px 0px; margin-top: -1px;' }, class: 'btn btn-default',
- style: ('border-top-left-radius: 0; border-bottom-left-radius: 0;' if special_style), params: { 'schedule[track_id]' => track.id }
+ .btn-group
+ %button{ type: 'button', class: 'btn btn-link dropdown-toggle', 'data-toggle' => 'dropdown' }
+ = track.state.humanize
+ %span.caret
+ %ul.dropdown-menu{ role: 'menu' }
+ = render 'change_state_dropdown', track: track
+ - else
+ = track.state.humanize
+ %td
+ .btn-group{ role: 'group' }
+ - if can? :edit, track
+ = link_to 'Edit', edit_admin_conference_program_track_path(@conference.short_title, track), class: 'btn btn-primary'
+ - special_style = true
+ - if can? :destroy, track
+ = link_to 'Delete', admin_conference_program_track_path(@conference.short_title, track), method: :delete, class: 'btn btn-danger',
+ data: { confirm: "Do you really want to delete #{track.name}? Attention: This track will be removed from all Events that have it set" }
+ - if track.self_organized?
+ - if track.selected_schedule
+ - if can? :show, track.selected_schedule
+ = link_to 'Show Schedule', admin_conference_schedule_path(@conference.short_title, track.selected_schedule),
+ class: 'btn btn-default'
+ - elsif can? :create, @program.schedules.build(track: track)
+ = button_to 'Create Schedule', admin_conference_schedules_path(@conference.short_title),
+ form: { class: 'btn', style: 'padding: 0px 0px; margin-top: -1px;' }, class: 'btn btn-default',
+ style: ('border-top-left-radius: 0; border-bottom-left-radius: 0;' if special_style), params: { 'schedule[track_id]' => track.id }
.row
.col-md-12.text-right
- = link_to 'New Track', new_admin_conference_program_track_path(@conference.short_title), class: 'btn btn-success'
+ = link_to 'New Track', new_admin_conference_program_track_path(@conference.short_title), class: 'btn btn-primary'
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 12f9dbbc..8c717900 100644
--- a/app/views/admin/versions/_object_desc_and_link.html.haml
+++ b/app/views/admin/versions/_object_desc_and_link.html.haml
@@ -19,7 +19,7 @@
- else
- conference = Conference.find_by(id: version.conference_id)
- conference_short_title = conference.try(:short_title) || current_or_last_object_state('Conference', version.conference_id).try(:short_title) || ' '
- = link_if_alive version, role.try(:name), admin_conference_role_path(role.try(:name) || ' ', conference_short_title), conference
+ = link_if_alive version, role.try(:name), admin_conference_role_path(conference_short_title,role.try(:name) || ' '), conference
= version.event == 'create' ? 'to' : 'from'
user
@@ -106,7 +106,8 @@
= 'booth'
- booth = current_or_last_object_state(version.item_type, version.item_id)
= link_if_alive version, booth.title,
- admin_conference_booth_path(conference_id: Conference.find(version.conference_id).short_title, id: version.item_id )
+ admin_conference_booth_path(conference_id: Conference.find(version.conference_id).short_title, id: version.item_id ),
+ conference
- when 'Program'
= link_if_alive version, 'program',
diff --git a/app/views/conference_registrations/show.html.haml b/app/views/conference_registrations/show.html.haml
index c510a263..83d6d89c 100644
--- a/app/views/conference_registrations/show.html.haml
+++ b/app/views/conference_registrations/show.html.haml
@@ -109,7 +109,7 @@
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 ticket)
+ (Your participation won't be valid without getting a registration ticket)
.row
.col-md-12
diff --git a/app/views/conferences/_conference_details.html.haml b/app/views/conferences/_conference_details.html.haml
index ebf80ef6..84a87303 100644
--- a/app/views/conferences/_conference_details.html.haml
+++ b/app/views/conferences/_conference_details.html.haml
@@ -47,4 +47,4 @@
- else
= link_to 'Unsubscribe', conference_subscriptions_path(conference.short_title), method: :delete, class: 'btn btn-default'
- if current_user && current_user.physical_tickets.by_conference(conference).any?
- = link_to "My Tickets", conference_physical_ticket_index_path(conference.short_title), class: 'btn btn-default'
+ = link_to "My Tickets", conference_physical_tickets_path(conference.short_title), class: 'btn btn-default'
diff --git a/app/views/conferences/_venue.html.haml b/app/views/conferences/_venue.html.haml
index 62af90c7..4436b0fe 100644
--- a/app/views/conferences/_venue.html.haml
+++ b/app/views/conferences/_venue.html.haml
@@ -32,4 +32,4 @@
= @conference.venue.country_name
- if @conference.venue.website
%br
- =link_to @conference.venue.website, @conference.venue.website
+ =link_to(h(@conference.venue.website), h(@conference.venue.website)).html_safe
diff --git a/app/views/conferences/_venue_map.html.haml b/app/views/conferences/_venue_map.html.haml
index b58b3053..717069d5 100644
--- a/app/views/conferences/_venue_map.html.haml
+++ b/app/views/conferences/_venue_map.html.haml
@@ -3,15 +3,15 @@
- content_for(:script_body) do
:javascript
// create a map in the "map" div, set the view to a given place and zoom
- var map = L.map('map', { scrollWheelZoom: false }).setView([#{@conference.venue.latitude}, #{@conference.venue.longitude}], 11);
+ var map = L.map('map', { scrollWheelZoom: false }).setView([#{h(@conference.venue.latitude)}, #{h(@conference.venue.longitude)}], 11);
// add an OpenStreetMap tile layer
L.tileLayer('//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
maxZoom: 18
}).addTo(map);
// add a marker in the given location, attach some popup content to it and open the popup
- L.marker([#{@conference.venue.latitude}, #{@conference.venue.longitude}]).addTo(map)
- .bindPopup("#{popup}")
+ L.marker([#{h(@conference.venue.latitude)}, #{h(@conference.venue.longitude)}]).addTo(map)
+ .bindPopup("#{h(popup)}")
.openPopup();
// Turn scrollwheel on when user clicks
map.on('focus', function(e) {
diff --git a/app/views/conferences/show.html.haml b/app/views/conferences/show.html.haml
index f94b8ee4..dd6b2d62 100644
--- a/app/views/conferences/show.html.haml
+++ b/app/views/conferences/show.html.haml
@@ -82,7 +82,7 @@
- content_for :script_head do
:javascript
- var triangle_tcs = tinycolor("#{@conference.color}").monochromatic();
+ var triangle_tcs = tinycolor("#{h(@conference.color)}").monochromatic();
var triangle_colors = triangle_tcs.map(function(t) { return t.toHexString(); });
$(function () {
$(document).ready(function() {
diff --git a/app/views/physical_ticket/index.html.haml b/app/views/physical_tickets/index.html.haml
similarity index 100%
rename from app/views/physical_ticket/index.html.haml
rename to app/views/physical_tickets/index.html.haml
diff --git a/app/views/physical_ticket/show.html.haml b/app/views/physical_tickets/show.html.haml
similarity index 100%
rename from app/views/physical_ticket/show.html.haml
rename to app/views/physical_tickets/show.html.haml
diff --git a/app/views/proposals/_encouragement_text.html.haml b/app/views/proposals/_encouragement_text.html.haml
index c6d574d6..48fcd045 100644
--- a/app/views/proposals/_encouragement_text.html.haml
+++ b/app/views/proposals/_encouragement_text.html.haml
@@ -2,7 +2,7 @@
- if @program.event_types.any?
You can submit proposals for
= "#{event_types(@conference)}."
- - if @program.tracks.any?
+ - if @program.tracks.confirmed.cfp_active.any?
Proposals should fit in one of the
= "#{pluralize(@program.tracks.confirmed.cfp_active.count, 'track')}:"
= "#{tracks(@conference)}."
diff --git a/app/views/tickets/_ticket.html.haml b/app/views/tickets/_ticket.html.haml
index e3985773..8f5fc82b 100644
--- a/app/views/tickets/_ticket.html.haml
+++ b/app/views/tickets/_ticket.html.haml
@@ -1,5 +1,5 @@
%tr
- %td.col-sm-8.col-md-6
+ %td.col-sm-8.col-md-4
.media
.media-body
%h4.media-heading
@@ -7,9 +7,14 @@
%h5.media-heading
- unless ticket.description.blank?
= markdown(ticket.description)
+ %td.col-sm-1.col-md-2.text-center
+ = ticket.registration_ticket? ? 'Yes' : 'No'
%td.col-sm-1.col-md-1
- = text_field_tag("tickets[][#{ticket.id}]", 0,
- type: 'number', min: 0, class: "form-control quantity", 'data-id' => ticket.id)
+ - options = { type: 'number', min: 0, 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?
+ = text_field_tag("tickets[][#{ticket.id}]", 0, options)
%td.col-sm-1.col-md-1.text-center
= ticket.price.symbol
%span{id: "price_#{ticket.id}"}
diff --git a/app/views/tickets/index.html.haml b/app/views/tickets/index.html.haml
index dc67f529..cba13ea5 100644
--- a/app/views/tickets/index.html.haml
+++ b/app/views/tickets/index.html.haml
@@ -14,6 +14,7 @@
%thead
%tr
%th Ticket
+ %th Registration Ticket
%th Quantity
%th Price
%th Total
@@ -21,6 +22,7 @@
- @conference.tickets.each do |ticket|
= render partial: 'ticket', f: f, locals: {ticket: ticket}
%tr
+ %td
%td
%td
%td.col-sm-1.col-md-1.text-center
@@ -46,4 +48,4 @@
.col-md-13
%p.text-muted.text-center
%small
- * Getting a ticket is mandatory. Your participation will not be valid until you get a ticket.
+ * Getting a registration ticket is mandatory. Your participation will not be valid until you get a registration ticket.
diff --git a/config/environments/production.rb b/config/environments/production.rb
index cb3a5d67..4e2c2e79 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -36,7 +36,7 @@ Osem::Application.configure do
# config.force_ssl = true
# See everything in the log (default is :info)
- # config.log_level = :debug
+ config.log_level = :info
# Prepend all log lines with the following tags
# config.log_tags = [ :subdomain, :uuid ]
diff --git a/config/routes.rb b/config/routes.rb
index 0d7e7aec..99f716e4 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -122,7 +122,7 @@ Osem::Application.routes.draw do
resources :targets, except: [:show]
resources :campaigns, except: [:show]
resources :emails, only: [:show, :update, :index]
- resources :physical_ticket, only: [:index]
+ resources :physical_tickets, only: [:index]
resources :roles, except: [:new, :create] do
member do
post :toggle_user
@@ -184,7 +184,7 @@ Osem::Application.routes.draw do
resources :tickets, only: [:index]
resources :ticket_purchases, only: [:create, :destroy, :index]
resources :payments, only: [:index, :new, :create]
- resources :physical_ticket, only: [:index, :show]
+ resources :physical_tickets, only: [:index, :show]
resource :subscriptions, only: [:create, :destroy]
resource :schedule, only: [:show] do
member do
diff --git a/spec/controllers/admin/ticket_scannings_controller_spec.rb b/spec/controllers/admin/ticket_scannings_controller_spec.rb
index 245bd885..2eb2e4ed 100644
--- a/spec/controllers/admin/ticket_scannings_controller_spec.rb
+++ b/spec/controllers/admin/ticket_scannings_controller_spec.rb
@@ -4,7 +4,9 @@ describe Admin::TicketScanningsController do
let(:admin) { create(:admin) }
let(:conference) { create(:conference) }
let(:user) { create(:user) }
- let(:paid_ticket_purchase) { create(:ticket_purchase, conference: conference, user: user) }
+ let!(:registration) { create(:registration, conference: conference, user: user) }
+ let(:registration_ticket) { create(:registration_ticket, conference: conference) }
+ let(:paid_ticket_purchase) { create(:ticket_purchase, conference: conference, user: user, ticket: registration_ticket, quantity: 1) }
let(:physical_ticket) { create(:physical_ticket, ticket_purchase: paid_ticket_purchase) }
context 'logged in as user with no role' do
diff --git a/spec/controllers/physical_ticket_controller_spec.rb b/spec/controllers/physical_ticket_controller_spec.rb
index 863e27af..476a1717 100644
--- a/spec/controllers/physical_ticket_controller_spec.rb
+++ b/spec/controllers/physical_ticket_controller_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe PhysicalTicketController do
+describe PhysicalTicketsController do
let(:conference) { create(:conference) }
let(:user) { create(:user) }
let(:paid_ticket_purchase) { create(:ticket_purchase, conference: conference, user: user) }
diff --git a/spec/factories/ticket_scanning.rb b/spec/factories/ticket_scanning.rb
new file mode 100644
index 00000000..540d1fd0
--- /dev/null
+++ b/spec/factories/ticket_scanning.rb
@@ -0,0 +1,5 @@
+FactoryGirl.define do
+ factory :ticket_scanning do
+ physical_ticket
+ end
+end
diff --git a/spec/features/sponsor_spec.rb b/spec/features/sponsor_spec.rb
index c6b5009e..b12ee90d 100644
--- a/spec/features/sponsor_spec.rb
+++ b/spec/features/sponsor_spec.rb
@@ -36,7 +36,14 @@ feature Sponsor do
end
# Remove sponsor
- click_link 'Delete'
+ visit admin_conference_sponsors_path(
+ conference_id: conference.short_title
+ )
+ within('table#sponsors') do
+ page.accept_confirm do
+ click_link 'Delete'
+ end
+ end
expect(flash).to eq('Sponsor successfully deleted.')
expect(page).to_not have_selector('table#sponsors')
end
diff --git a/spec/features/ticket_purchases_spec.rb b/spec/features/ticket_purchases_spec.rb
index 958ae645..9cace981 100644
--- a/spec/features/ticket_purchases_spec.rb
+++ b/spec/features/ticket_purchases_spec.rb
@@ -3,7 +3,9 @@ require 'spec_helper'
feature Registration do
let!(:ticket) { create(:ticket) }
let!(:free_ticket) { create(:ticket, price_cents: 0) }
- let!(:conference) { create(:conference, title: 'ExampleCon', tickets: [ticket, free_ticket], registration_period: create(:registration_period, start_date: 3.days.ago)) }
+ let!(:first_registration_ticket) { create(:registration_ticket, price_cents: 0) }
+ let!(:second_registration_ticket) { create(:registration_ticket, price_cents: 0) }
+ let!(:conference) { create(:conference, title: 'ExampleCon', tickets: [ticket, free_ticket, first_registration_ticket, second_registration_ticket], registration_period: create(:registration_period, start_date: 3.days.ago)) }
let!(:participant) { create(:user) }
context 'as a participant' do
@@ -101,11 +103,43 @@ feature Registration do
click_button 'Continue'
- expect(current_path).to eq(conference_physical_ticket_index_path(conference.short_title))
+ expect(current_path).to eq(conference_physical_tickets_path(conference.short_title))
purchase = TicketPurchase.where(user_id: participant.id, ticket_id: free_ticket.id).first
expect(purchase.quantity).to eq(5)
expect(purchase.paid).to be true
end
+
+ scenario 'purchases more than one registration tickets of a single type' do
+ visit root_path
+ click_link 'Register'
+
+ expect(current_path).to eq(new_conference_conference_registration_path(conference.short_title))
+ click_button 'Register'
+
+ fill_in "tickets__#{first_registration_ticket.id}", with: '5'
+ expect(current_path).to eq(conference_tickets_path(conference.short_title))
+
+ click_button 'Continue'
+
+ expect(current_path).to eq(conference_tickets_path(conference.short_title))
+ end
+
+ scenario 'purchases one registration ticket of a different types' do
+ visit root_path
+ click_link 'Register'
+
+ expect(current_path).to eq(new_conference_conference_registration_path(conference.short_title))
+ click_button 'Register'
+
+ fill_in "tickets__#{first_registration_ticket.id}", with: '1'
+ fill_in "tickets__#{second_registration_ticket.id}", with: '1'
+ expect(current_path).to eq(conference_tickets_path(conference.short_title))
+
+ click_button 'Continue'
+
+ expect(flash).to eq('Oops, something went wrong with your purchase! You cannot buy more than one registration tickets.')
+ expect(current_path).to eq(conference_tickets_path(conference.short_title))
+ end
end
context 'who is registered' do
diff --git a/spec/features/tracks_spec.rb b/spec/features/tracks_spec.rb
index 0819c650..f753abc2 100644
--- a/spec/features/tracks_spec.rb
+++ b/spec/features/tracks_spec.rb
@@ -36,16 +36,18 @@ feature Track do
expected = expect do
visit admin_conference_program_tracks_path(conference_id: conference.short_title)
-
- click_link 'Delete'
+ within('#tracks', visible: true) do
+ page.accept_confirm do
+ find_link('Delete').click
+ end
+ end
end
expected.to change { Track.count }.by(-1)
expect(flash).to eq('Track successfully deleted.')
- within('table#tracks') do
- expect(page.has_content?(track.name)).to be false
- expect(page.has_content?(track.description)).to be false
- end
+ expect(page.has_css?('table#tracks')).to be false
+ expect(page.has_content?(track.name)).to be false
+ expect(page.has_content?(track.description)).to be false
end
scenario 'updates a track', feature: true, js: true do
@@ -54,7 +56,9 @@ feature Track do
expected = expect do
visit admin_conference_program_tracks_path(conference_id: conference.short_title)
- click_link 'Edit'
+ within('#tracks', visible: true) do
+ find_link('Edit').trigger('click')
+ end
fill_in 'track_name', with: 'Distribution'
fill_in 'track_short_name', with: 'Distribution'
diff --git a/spec/models/ticket_purchase_spec.rb b/spec/models/ticket_purchase_spec.rb
index 3ef9a861..bfca5efc 100644
--- a/spec/models/ticket_purchase_spec.rb
+++ b/spec/models/ticket_purchase_spec.rb
@@ -34,6 +34,22 @@ describe TicketPurchase do
it 'is valid with a quantity greater than zero' do
should allow_value(1).for(:quantity)
end
+
+ describe 'one_registration_ticket_per_user' do
+ let(:registration_ticket) { create(:registration_ticket) }
+ let(:ticket_purchase) { build(:ticket_purchase, ticket: registration_ticket, quantity: 1) }
+
+ it 'it is valid, if quantity for registration tickets is less than or equal to one' do
+ expect(ticket_purchase.valid?).to eq true
+ end
+
+ it 'it is not valid, if quantity for registration tickets is greater than to one' do
+ ticket_purchase.quantity = 4
+
+ expect(ticket_purchase.valid?).to eq false
+ expect(ticket_purchase.errors[:quantity]).to eq ['cannot be greater than one for registration tickets.']
+ end
+ end
end
describe 'self#purchase' do
diff --git a/spec/models/ticket_scanning_spec.rb b/spec/models/ticket_scanning_spec.rb
new file mode 100644
index 00000000..3d978f4f
--- /dev/null
+++ b/spec/models/ticket_scanning_spec.rb
@@ -0,0 +1,20 @@
+require 'spec_helper'
+
+describe TicketScanning do
+ let(:conference) { create(:conference) }
+ let(:user) { create(:user) }
+ let(:registration) { create(:registration, conference: conference, user: user) }
+ let(:registration_ticket) { create(:registration_ticket, conference: conference) }
+ let(:paid_ticket_purchase) { create(:ticket_purchase, conference: conference, user: user, ticket: registration_ticket, quantity: 1) }
+ let(:physical_ticket) { create(:physical_ticket, ticket_purchase: paid_ticket_purchase) }
+ let(:ticket_scanning) { create(:ticket_scanning, physical_ticket: physical_ticket) }
+
+ describe 'before_create' do
+ it 'marks user as present' do
+ expect(registration.attended).to eq(false)
+ ticket_scanning
+ registration.reload
+ expect(registration.attended).to eq(true)
+ end
+ end
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index fc56e829..d9283117 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -59,7 +59,7 @@ RSpec.configure do |config|
Capybara.javascript_driver = :poltergeist
Capybara.register_driver :poltergeist do |app|
- Capybara::Poltergeist::Driver.new(app, phantomjs: Phantomjs.path, js_errors: false)
+ Capybara::Poltergeist::Driver.new(app, phantomjs: Phantomjs.path, js_errors: false, window_size: [1920, 1080])
end
# Includes helpers and connect them to specific types of tests
@@ -82,6 +82,14 @@ RSpec.configure do |config|
# Types of tests (controller, feature, model) will
# be inferred from subfolder name
config.infer_spec_type_from_file_location!
+
+ # Enable this if you like to see what you're debugging
+ # config.after(:example) do |example|
+ # if example.exception
+ # save_and_open_screenshot
+ # save_and_open_page
+ # end
+ # end
end
OmniAuth.config.test_mode = true