Merge branch 'master' into rails5_gem_update

This commit is contained in:
Stella Rouzi 2017-08-06 02:32:09 +03:00 committed by GitHub
commit 8fc1aa3d19
44 changed files with 970 additions and 95 deletions

View file

@ -11,6 +11,9 @@ linters:
# Offense count: 945 # Offense count: 945
LineLength: LineLength:
exclude: exclude:
- "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" - "app/views/admin/campaigns/_form.html.haml"
- "app/views/admin/campaigns/index.html.haml" - "app/views/admin/campaigns/index.html.haml"
- "app/views/admin/cfps/_form.html.haml" - "app/views/admin/cfps/_form.html.haml"
@ -179,6 +182,7 @@ linters:
# Offense count: 223 # Offense count: 223
InstanceVariables: InstanceVariables:
exclude: exclude:
- "app/views/admin/booths/_change_state_dropdown.html.haml"
- "app/views/admin/campaigns/_form.html.haml" - "app/views/admin/campaigns/_form.html.haml"
- "app/views/admin/cfps/_booths_cfp.html.haml" - "app/views/admin/cfps/_booths_cfp.html.haml"
- "app/views/admin/cfps/_form.html.haml" - "app/views/admin/cfps/_form.html.haml"

View file

@ -90,3 +90,7 @@ p.comment-body {
.changeset{ .changeset{
display: none; display: none;
} }
.box{
height: 230px;
}

View file

@ -0,0 +1,94 @@
module Admin
class BoothsController < Admin::BaseController
load_and_authorize_resource :conference, find_by: :short_title
load_and_authorize_resource through: :conference
def index; end
def show; end
def new; end
def create
@booth = @conference.booths.new(booth_params)
@booth.submitter = current_user
if @booth.save
redirect_to admin_conference_booths_path,
notice: 'Booth successfully created.'
else
flash[:error] = "Creating booth failed. #{@booth.errors.full_messages.to_sentence}."
render :new
end
end
def edit; end
def update
@booth.update_attributes(booth_params)
if @booth.save
redirect_to admin_conference_booths_path,
notice: "Successfully updated booth for #{@booth.title}."
else
flash[:error] = "An error prohibited the Booth for #{@booth.title} "\
"#{@booth.errors.full_messages.join('. ')}."
render :edit
end
end
def destroy
if @booth.destroy
redirect_to admin_conference_booths_path,
notice: 'Booth successfully destroyed.'
else
redirect_to admin_conference_booths_path,
error: "Booth couldn't be deleted. #{@booth.errors.full_messages.join('. ')}."
end
end
def accept
update_state(:accept, 'Booth accepted!')
end
def to_accept
update_state(:to_accept, 'Booth to accept')
end
def to_reject
update_state(:to_reject, 'Booth to reject')
end
def reject
update_state(:reject, 'Booth rejected')
end
def restart
update_state(:restart, 'Booth is submitted')
end
def cancel
update_state(:cancel, 'Booth is canceled')
end
private
def update_state(transition, notice)
alert = @booth.update_state(transition, notice)
if alert.blank?
flash[:notice] = notice
redirect_back_or_to(admin_conference_booths_path(conference_id: @conference.short_title)) && return
else
flash[:error] = alert
return redirect_back_or_to(admin_conference_booths_path(conference_id: @conference.short_title)) && return
end
end
def booth_params
params.require(:booth).permit(:title, :description, :reasoning, :state, :picture, :conference_id,
:created_at, :updated_at, :submitter_relationship, :website_url, responsible_ids: [])
end
end
end

View file

@ -1,7 +1,7 @@
class PhysicalTicketController < ApplicationController class PhysicalTicketController < ApplicationController
before_action :authenticate_user! before_action :authenticate_user!
load_resource :conference, find_by: :short_title load_resource :conference, find_by: :short_title
load_and_authorize_resource load_and_authorize_resource find_by: :token
authorize_resource :conference_registrations, class: Registration authorize_resource :conference_registrations, class: Registration
def index def index
@ -13,5 +13,15 @@ class PhysicalTicketController < ApplicationController
@file_name = "ticket_for_#{@conference.short_title}" @file_name = "ticket_for_#{@conference.short_title}"
@user = @physical_ticket.user @user = @physical_ticket.user
@ticket_layout = @conference.ticket_layout.to_sym @ticket_layout = @conference.ticket_layout.to_sym
respond_to do |format|
format.html
format.pdf do
pdf = TicketPdf.new(@conference, @user, @physical_ticket, @ticket_layout, @file_name)
send_data pdf.render,
filename: @file_name,
type: 'application/pdf',
disposition: 'attachment'
end
end
end end
end end

View file

@ -5,17 +5,19 @@ class SubscriptionsController < ApplicationController
def create def create
@subscription = current_user.subscriptions.build(conference_id: @conference.id) @subscription = current_user.subscriptions.build(conference_id: @conference.id)
if @subscription.save! if @subscription.save
redirect_to root_path, notice: "You have been subscribed to receive email notifications for #{@conference.short_title}." redirect_to root_path, notice: "You have subscribed to receive email notifications for #{@conference.title}."
else else
redirect_to root_path, error: subscription.errors.full_messages.to_sentence redirect_to root_path, error: @subscription.errors.full_messages.to_sentence
end end
end end
def destroy def destroy
@subscription = current_user.subscriptions.find_by(conference_id: @conference.id) @subscription = current_user.subscriptions.find_by(conference_id: @conference.id)
redirect_to(root_path, error: "You are not subscribed to #{@conference.title}.") && return unless @subscription
if @subscription.destroy if @subscription.destroy
redirect_to root_path, notice: "You have been unsubscribed and now you will not be receiving email notifications for #{@conference.short_title}." redirect_to root_path, notice: "You have unsubscribed and you will not be receiving email notifications for #{@conference.title}."
else else
redirect_to root_path, error: @subscription.errors.full_messages.to_sentence redirect_to root_path, error: @subscription.errors.full_messages.to_sentence
end end

View file

@ -162,6 +162,13 @@ module ApplicationHelper
include_blank: false, label: 'Speakers', input_html: { class: 'select-help-toggle', multiple: 'true' } include_blank: false, label: 'Speakers', input_html: { class: 'select-help-toggle', multiple: 'true' }
end end
def responsibles_selector_input(form)
users = User.active.pluck(:id, :name, :username, :email).map { |user| [user[0], user[1].blank? ? user[2] : user[1], user[2], user[3]] }.sort_by { |user| user[1].downcase }
form.input :responsibles, as: :select,
collection: options_for_select(users.map {|user| ["#{user[1]} (#{user[2]}) #{user[3]}", user[0]]}, @booth.responsibles.map(&:id)),
include_blank: false, label: 'Responsibles', input_html: { class: 'select-help-toggle', multiple: 'true' }
end
def event_types(conference) def event_types(conference)
conference.program.event_types.map { |et| et.title.pluralize }.to_sentence conference.program.event_types.map { |et| et.title.pluralize }.to_sentence
end end

View file

@ -8,6 +8,22 @@ class Mailbot < ActionMailer::Base
conference.email_settings.registration_body)) conference.email_settings.registration_body))
end end
def ticket_confirmation_mail(ticket_purchase)
@ticket_purchase = ticket_purchase
@conference = ticket_purchase.conference
@user = ticket_purchase.user
PhysicalTicket.last(ticket_purchase.quantity).each do |physical_ticket|
pdf = TicketPdf.new(@conference, @user, physical_ticket, @conference.ticket_layout.to_sym, "ticket_for_#{@conference.short_title}_#{physical_ticket.id}")
attachments["ticket_for_#{@conference.short_title}_#{physical_ticket.id}.pdf"] = pdf.render
end
mail(to: @user.email,
from: @conference.contact.email,
template_name: 'ticket_confirmation_template',
subject: "#{@conference.title} | Ticket Confirmation and PDF!")
end
def acceptance_mail(event) def acceptance_mail(event)
conference = event.program.conference conference = event.program.conference

View file

@ -18,7 +18,6 @@ class AdminAbility
end end
def common_abilities_for_roles(user) def common_abilities_for_roles(user)
can :manage, User, id: user.id
can :manage, Registration, user_id: user.id can :manage, Registration, user_id: user.id
can :index, Conference can :index, Conference
@ -120,6 +119,7 @@ class AdminAbility
commercialable_id: conf_ids commercialable_id: conf_ids
can :manage, Registration, conference_id: conf_ids can :manage, Registration, conference_id: conf_ids
can :manage, RegistrationPeriod, conference_id: conf_ids can :manage, RegistrationPeriod, conference_id: conf_ids
can :manage, Booth, conference_id: conf_ids
can :manage, Question, conference_id: conf_ids can :manage, Question, conference_id: conf_ids
can :manage, Question do |question| can :manage, Question do |question|
!(question.conferences.pluck(:id) & conf_ids).empty? !(question.conferences.pluck(:id) & conf_ids).empty?
@ -170,6 +170,7 @@ class AdminAbility
conf_ids_for_cfp.include?(conf.id) conf_ids_for_cfp.include?(conf.id)
end end
can [:index, :show, :update], Resource, conference_id: conf_ids_for_cfp can [:index, :show, :update], Resource, conference_id: conf_ids_for_cfp
can :manage, Booth, conference_id: conf_ids_for_cfp
can :manage, Event, program: { conference_id: conf_ids_for_cfp } can :manage, Event, program: { conference_id: conf_ids_for_cfp }
can :manage, EventType, program: { conference_id: conf_ids_for_cfp } can :manage, EventType, program: { conference_id: conf_ids_for_cfp }
can :manage, Track, program: { conference_id: conf_ids_for_cfp } can :manage, Track, program: { conference_id: conf_ids_for_cfp }

76
app/models/booth.rb Normal file
View file

@ -0,0 +1,76 @@
class Booth < ActiveRecord::Base
include ActiveRecord::Transitions
has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id }
belongs_to :conference
has_many :booth_requests, dependent: :destroy
has_many :users, through: :booth_requests
has_one :submitter_booth_user, -> { where(role: 'submitter') }, class_name: 'BoothRequest'
has_one :submitter, through: :submitter_booth_user, source: :user
has_many :responsibles_booth_user, -> { where(role: 'responsible') }, class_name: 'BoothRequest'
has_many :responsibles, through: :responsibles_booth_user, source: :user
validates :title,
uniqueness: { case_sensitive: false },
presence: true
validates :description,
:reasoning,
:state,
:responsibles,
:conference_id,
:website_url,
:submitter_relationship,
presence: true
mount_uploader :picture, PictureUploader, mount_on: :logo_link
state_machine initial: :new do
state :new
state :withdrawn
state :to_accept
state :accepted
state :to_reject
state :rejected
state :canceled
event :restart do
transitions to: :new, from: [:withdrawn, :to_accept, :to_reject, :canceled]
end
event :withdraw do
transitions to: :withdrawn, from: [:new, :to_accept, :accepted, :to_reject, :rejected]
end
event :to_accept do
transitions to: :to_accept, from: [:new, :to_reject]
end
event :to_reject do
transitions to: :to_reject, from: [:new, :to_accept]
end
event :accept do
transitions to: :accepted, from: [:new, :to_accept]
end
event :reject do
transitions to: :rejected, from: [:new, :to_reject]
end
event :cancel do
transitions to: :canceled, from: [:accepted, :rejected, :to_accept, :to_reject]
end
end
def transition_possible?(transition)
self.class.state_machine.events_for(current_state).include?(transition)
end
def update_state(transition, _notice)
alert = ''
begin
send(transition)
save
rescue Transitions::InvalidTransition => e
alert = "Update state failed. #{e.message}"
end
alert
end
end

View file

@ -0,0 +1,9 @@
class BoothRequest < ActiveRecord::Base
belongs_to :booth
belongs_to :user
validates :role,
presence: true
ROLES = %w[submitter responsible].freeze
end

View file

@ -28,6 +28,7 @@ class Conference < ActiveRecord::Base
has_many :supporters, through: :ticket_purchases, source: :user has_many :supporters, through: :ticket_purchases, source: :user
has_many :tickets, dependent: :destroy has_many :tickets, dependent: :destroy
has_many :resources, dependent: :destroy has_many :resources, dependent: :destroy
has_many :booths, dependent: :destroy
has_many :lodgings, dependent: :destroy has_many :lodgings, dependent: :destroy
has_many :registrations, dependent: :destroy has_many :registrations, dependent: :destroy

View file

@ -4,4 +4,19 @@ class PhysicalTicket < ActiveRecord::Base
has_one :conference, through: :ticket_purchase has_one :conference, through: :ticket_purchase
has_one :user, through: :ticket_purchase has_one :user, through: :ticket_purchase
has_many :ticket_scannings has_many :ticket_scannings
before_create :set_token
private
def set_token
self.token = generate_token
end
def generate_token
loop do
token = SecureRandom.hex(10)
break token unless PhysicalTicket.exists?(token: token)
end
end
end end

View file

@ -1,5 +1,4 @@
class Subscription < ActiveRecord::Base class Subscription < ActiveRecord::Base
validates :user_id, uniqueness: { scope: [:conference_id] }
belongs_to :conference belongs_to :conference
belongs_to :user belongs_to :user

View file

@ -69,6 +69,7 @@ class TicketPurchase < ActiveRecord::Base
PhysicalTicket.transaction do PhysicalTicket.transaction do
quantity.times { physical_tickets.create } quantity.times { physical_tickets.create }
end end
Mailbot.ticket_confirmation_mail(self).deliver_later
end end
end end

View file

@ -56,6 +56,9 @@ class User < ActiveRecord::Base
has_many :voted_events, through: :votes, source: :events has_many :voted_events, through: :votes, source: :events
has_many :subscriptions, dependent: :destroy has_many :subscriptions, dependent: :destroy
has_many :tracks, foreign_key: 'submitter_id' has_many :tracks, foreign_key: 'submitter_id'
has_many :booth_requests
has_many :booth_requests, dependent: :destroy
has_many :booths, through: :booth_requests
accepts_nested_attributes_for :roles accepts_nested_attributes_for :roles
scope :admin, -> { where(is_admin: true) } scope :admin, -> { where(is_admin: true) }

81
app/pdfs/ticket_pdf.rb Normal file
View file

@ -0,0 +1,81 @@
class TicketPdf < Prawn::Document
def initialize(conference, user, physical_ticket, ticket_layout, file_name)
super(page_layout: ticket_layout, page_size: 'A4', filename: file_name)
@user = user
@physical_ticket = physical_ticket
@conference = conference
@left = bounds.left
@right = bounds.right
@mid_vertical = (bounds.top - bounds.bottom) / 2
@mid_horizontal = (bounds.right - bounds.left) / 2
@x = 0
draw_first_square
draw_second_square
draw_third_square
draw_fourth_square
end
def draw_first_square
move_down @mid_vertical
dash(2, space: 1)
stroke_horizontal_rule
stroke_vertical_line bounds.top, bounds.bottom, at: @mid_horizontal
move_up @mid_vertical
draw_text 'TICKET HOLDER', at: [@x, cursor - 30], size: 17
dash(2, space: 0)
stroke_rectangle [@x, cursor - 50], 230, 150
move_down 80
draw_text 'NAME', at: [@x + 10, cursor], size: 13
fill_color '808080'
draw_text @user.name.to_s, at: [@x + 10, cursor - 25], size: 20
fill_color '000000'
draw_text 'EMAIL', at: [@x + 10, cursor - 50], size: 13
fill_color '808080'
draw_text @user.email.to_s, at: [@x + 10, cursor - 75], size: 20
fill_color '000000'
move_up 20
end
def draw_second_square
if @conference.picture?
if 7 * @conference.picture.image[:width] > 12 * @conference.picture.image[:height]
image "#{Rails.root}/public#{@conference.picture_url}", at: [@mid_horizontal + 30, cursor], width: 120
else
image "#{Rails.root}/public#{@conference.picture_url}", at: [@mid_horizontal + 30, cursor], height: 70
end
else
image "#{Rails.root}/public/img/osem-logo.png", at: [@mid_horizontal + 30, cursor], height: 70
end
move_down 70
draw_text @conference.title.to_s, at: [@mid_horizontal + 30, cursor - 30], size: 12
draw_text @conference.organization.name.to_s, at: [@mid_horizontal + 30, cursor - 50], size: 12
draw_text @conference.venue.name.to_s, at: [@mid_horizontal + 30, cursor - 70]
move_up 130
move_down @mid_vertical
end
def draw_third_square
draw_text 'EVENT', at: [@x, cursor - 40], size: 15
fill_color '808080'
draw_text @conference.title.to_s, at: [@x, cursor - 60], size: 12
draw_text @conference.start_date.strftime('%B %d, %Y').to_s, at: [@x, cursor - 80], size: 12
move_down 80
fill_color '000000'
draw_text 'TICKET', at: [@x, cursor - 30], size: 15
fill_color '808080'
draw_text @physical_ticket.ticket.title.to_s, at: [@x, cursor - 50], size: 12
move_down 50
fill_color '000000'
draw_text 'TICKET REF.', at: [@x, cursor - 30], size: 15
fill_color '808080'
draw_text @physical_ticket.ticket_purchase.id.to_s, at: [@x, cursor - 50], size: 12
move_down 50
fill_color '000000'
draw_text 'Powered By OSEM', at: [(@mid_horizontal - @left - 100) / 2, cursor - 100], size: 11
move_up 180
end
def draw_fourth_square; end
end

View file

@ -0,0 +1,29 @@
- if booth.transition_possible? :accept
%li= link_to 'Accept booth',
accept_admin_conference_booth_path(@conference.short_title, booth),
method: :patch, id: "accept_booth_#{booth.id}"
- if booth.transition_possible? :reject
%li= link_to 'Reject booth',
reject_admin_conference_booth_path(@conference.short_title, booth),
method: :patch, confirm: 'Are you sure?', id: "reject_booth_#{booth.id}"
- if booth.transition_possible? :to_reject
%li= link_to 'To reject booth',
to_reject_admin_conference_booth_path(@conference.short_title, booth),
method: :patch, confirm: 'Are you sure?', id: "to_reject_booth_#{booth.id}"
- if booth.transition_possible? :restart
%li= link_to 'Start review',
restart_admin_conference_booth_path(@conference.short_title, booth),
method: :patch, id: "restart_booth_#{booth.id}"
- if booth.transition_possible? :to_accept
%li= link_to 'To accept 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',
cancel_admin_conference_booth_path(@conference.short_title, booth),
method: :patch, id: "cancel_booth_#{booth.id}"

View file

@ -0,0 +1,33 @@
.row
.col-md-12
.page-header
%title Request a Booth
.row
.col-md-8
= semantic_form_for(@booth, url: @booth.new_record? ? admin_conference_booths_path(@conference.short_title) : admin_conference_booth_path(@conference.short_title, @booth.id), html: { multipart: true }) do |f|
= f.input :title, as: :string, autofocus: true, required: true
= f.input :description, input_html: { rows: 5, data: { provide: 'markdown-editable' } }, required: true,
hint: 'This field becomes public upon request acceptance'
= f.input :reasoning, input_html: { rows: 5, data: { provide: 'markdown-editable' } }, required: true,
label: 'How it fits the conference'
= f.input :submitter_relationship, input_html: { rows: 5, data: { provide: 'markdown-editable' } }, required: true,
label: 'Submitter\'s relation',
hint: 'e.g. employee, comunity manager, etc'
= f.input :website_url
= responsibles_selector_input f
= image_tag f.object.picture.thumb.url if f.object.picture?
= f.input :picture
%p.text-right
- if @booth.new_record?
= f.submit 'Create Booth Request', class: 'btn btn-success'
- else
= f.submit 'Update Booth Request', class: 'btn btn-success'
:javascript
$(document).ready(function() {
$('#booth_responsible_ids').selectize({
plugins: ['remove_button'],
minItems: 2
} )
});

View file

@ -0,0 +1,5 @@
%h1
Editing
= @booth.title
= render 'form'

View file

@ -0,0 +1,59 @@
.row
.col-md-12
.page-header
%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
.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
%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 do |responsible|
= link_to responsible.name, admin_user_path(responsible)
%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
.btn-group{ role: "group" }
= link_to 'Edit', edit_admin_conference_booth_path(@conference.short_title, booth.id),
class: 'btn btn-primary'
= link_to 'Delete', admin_conference_booth_path(@conference.short_title, booth.id),
method: :delete, class: 'btn btn-danger',
data: {confirm: "Do you really want to delete this booth request?"}

View file

@ -0,0 +1,3 @@
%h1 New booth
= render 'form'

View file

@ -0,0 +1,57 @@
.row
.col-md-12
%h3
= image_tag(@booth.picture.thumb.url, size: '20%', alt: '')
= @booth.title
.btn-group.pull-right
= link_to 'Edit', edit_admin_conference_booth_path(@conference.short_title, @booth), class: 'btn btn-mini btn-primary'
.row
.col-md-12
%table.table
%tr
%td.col-md-2
%b Description
%td
= markdown(@booth.description)
%tr
%td.col-md-2
%b Reasoning
%td
= markdown(@booth.reasoning)
%tr
%td.col-md-2
%b Website
%td
- if @booth.website_url.present?
= link_to @booth.website_url, @booth.website_url
%tr
%td.col-md-2
%b Submitter
%td
= link_to @booth.submitter.name, admin_user_path(@booth.submitter)
%tr
%td.col-md-2
%b Submitter's relationship
%td
= @booth.submitter_relationship
%tr
%td.col-md-2
%b Responsibles
%td
- @booth.responsibles.each do |responsibles|
.responsibles
= link_to responsibles.name, admin_user_path(responsibles)
(
= responsibles.email
)
%tr
%td.col-md-2
%b Submitted on
%td
= @booth.created_at
%tr
%td.col-md-2
%b Last updated on
%td
= @booth.updated_at

View file

@ -32,11 +32,11 @@
.btn-group .btn-group
= link_to 'Show', = link_to 'Show',
conference_physical_ticket_path(@conference.short_title, conference_physical_ticket_path(@conference.short_title,
physical_ticket.id), physical_ticket.token),
class: 'btn btn-primary' class: 'btn btn-primary'
= link_to 'Generate PDF', = link_to 'Generate PDF',
conference_physical_ticket_path(@conference.short_title, conference_physical_ticket_path(@conference.short_title,
physical_ticket.id, physical_ticket.token,
format: :pdf), format: :pdf),
class: 'button btn btn-default btn-info' class: 'button btn btn-default btn-info'
- else - else

View file

@ -80,6 +80,12 @@
= link_if_alive version, 'contact details', = link_if_alive version, 'contact details',
edit_admin_conference_contact_path(conference_id: Conference.find(version.conference_id).short_title) edit_admin_conference_contact_path(conference_id: Conference.find(version.conference_id).short_title)
- when 'Booth'
= '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 )
- when 'Program' - when 'Program'
= link_if_alive version, 'program', = link_if_alive version, 'program',
admin_conference_program_path(conference_id: Conference.find(version.conference_id).short_title) admin_conference_program_path(conference_id: Conference.find(version.conference_id).short_title)

View file

@ -0,0 +1,8 @@
Dear <%= @user.name %>,
Thanks! You have successfully booked <%= @ticket_purchase.quantity %> <%= @ticket_purchase.ticket.title %> ticket(s) for the event <%= @conference.title %>. Your transaction id is <%= @ticket_purchase.id %>.
Please, find the ticket(s) pdf attached.
Best wishes,
<%= @conference.title %> Team

View file

@ -24,11 +24,11 @@
.btn-group .btn-group
= link_to 'Show', = link_to 'Show',
conference_physical_ticket_path(@conference.short_title, conference_physical_ticket_path(@conference.short_title,
physical_ticket.id), physical_ticket.token),
class: 'btn btn-primary' class: 'btn btn-primary'
= link_to 'Generate PDF', = link_to 'Generate PDF',
conference_physical_ticket_path(@conference.short_title, conference_physical_ticket_path(@conference.short_title,
physical_ticket.id, physical_ticket.token,
format: :pdf), format: :pdf),
class: 'button btn btn-default btn-info' class: 'button btn btn-default btn-info'
- else - else

View file

@ -0,0 +1,77 @@
.container
.row
.col-md-12
.page-header
%h1
Ticket for
= @conference.title
%p.text-muted
- if @conference.venue
at
%strong
#{@conference.venue.name},
#{@conference.venue.street},
#{@conference.venue.city} / #{@conference.venue.country_name}.
%small
= date_string(@conference.start_date, @conference.end_date)
.row
.col-md-5.box.well
%h3.text-center
Ticket Holder
%p.text-left
%strong
Name
%br
= @user.name
%br
%br
%strong
Email
%br
= @user.email
.col-md-5.col-md-offset-2.box.well
- if @conference.picture?
- width = @conference.picture.image[:width]
- height = @conference.picture.image[:height]
- if 10 * width > 15 * height
= image_tag(@conference.picture_url, width: '150')
- else
= image_tag(@conference.picture_url, height: '100')
- else
= image_tag('/img/osem-logo.png', class: 'img-responsive')
%p.text-left
%br
%strong
Organization
%br
= @conference.organization.name
.col-md-5.box.well
%p.text-left
%strong
Event
%br
= @conference.title
%br
= @conference.start_date.strftime('%B %d, %Y')
%br
%br
%strong
Ticket
%br
= @physical_ticket.ticket.title
%br
%br
%strong
Ticket Ref.
%br
= @physical_ticket.ticket_purchase.id
%br
.col-md-5.col-md-offset-2.box.well
.row
.col-md-12
%p.text-left
= link_to 'Generate PDF',
conference_physical_ticket_path(@conference.short_title,
@physical_ticket.token,
format: :pdf),
class: 'button btn btn-default btn-info'

View file

@ -1,62 +0,0 @@
prawn_document(filename: @file_name, page_layout: @ticket_layout, :page_size =>'A4' ) do |pdf|
# Vertical Layout
top = pdf.bounds.top
bottom = pdf.bounds.bottom
left = pdf.bounds.left
right = pdf.bounds.right
mid_vertical = (pdf.bounds.top-pdf.bounds.bottom)/2
mid_horizontal = (pdf.bounds.right-pdf.bounds.left)/2
x = 0
pdf.move_down mid_vertical
pdf.dash(2, :space => 1)
pdf.stroke_horizontal_rule
pdf.stroke_vertical_line pdf.bounds.top, pdf.bounds.bottom, :at => mid_horizontal
pdf.move_up mid_vertical
pdf.draw_text "TICKET HOLDER", :at => [x,pdf.cursor-30], :size => 17
pdf.dash(2, :space => 0)
pdf.stroke_rectangle [x, pdf.cursor-50], 230, 150
pdf.move_down 80
pdf.draw_text "NAME", :at => [x+10,pdf.cursor], :size => 13
pdf.fill_color "808080"
pdf.draw_text "#{@user.name}", :at => [x+10,pdf.cursor-25], size: 20
pdf.fill_color "000000"
pdf.draw_text "EMAIL", :at => [x+10,pdf.cursor-50], :size => 13
pdf.fill_color "808080"
pdf.draw_text "#{@user.email}", :at => [x+10,pdf.cursor-75], size: 20
pdf.fill_color "000000"
pdf.move_up 20
if @conference.picture?
if 7 * @conference.picture.image[:width] > 12 * @conference.picture.image[:height]
pdf.image "#{Rails.root}/public#{@conference.picture_url}", :at => [mid_horizontal+30, pdf.cursor], :width => 120
else
pdf.image "#{Rails.root}/public#{@conference.picture_url}", :at => [mid_horizontal+30, pdf.cursor], :height => 70
end
else
pdf.image "#{Rails.root}/public/img/osem-logo.png", :at => [mid_horizontal+30, pdf.cursor], :height => 70
end
pdf.move_down 70
pdf.draw_text "#{@conference.title}", :at => [mid_horizontal+30,pdf.cursor-30], :size => 12
pdf.draw_text "#{@conference.organization.name}", :at => [mid_horizontal+30,pdf.cursor-50], :size => 12
pdf.draw_text "#{@conference.venue.name}", :at => [mid_horizontal+30,pdf.cursor-70]
pdf.move_up 130
pdf.move_down mid_vertical
pdf.draw_text "EVENT", :at => [x,pdf.cursor-40], :size => 15
pdf.fill_color "808080"
pdf.draw_text "#{@conference.title}", :at => [x,pdf.cursor-60], size: 12
pdf.draw_text "#{@conference.start_date.strftime('%B %d, %Y')}", :at => [x,pdf.cursor-80], size: 12
pdf.move_down 80
pdf.fill_color "000000"
pdf.draw_text "TICKET", :at => [x,pdf.cursor-30], :size => 15
pdf.fill_color "808080"
pdf.draw_text "#{@physical_ticket.ticket.title}", :at => [x,pdf.cursor-50], size: 12
pdf.move_down 50
pdf.fill_color "000000"
pdf.draw_text "TICKET REF.", :at => [x,pdf.cursor-30], :size => 15
pdf.fill_color "808080"
pdf.draw_text "#{@physical_ticket.ticket_purchase.id}", :at => [x,pdf.cursor-50], size: 12
pdf.move_down 50
pdf.fill_color "000000"
pdf.draw_text "Powered By OSEM", :at => [(mid_horizontal-left-100)/2,pdf.cursor-100], :size => 11
pdf.move_up 180
end

View file

@ -37,6 +37,19 @@ Osem::Application.routes.draw do
get '/volunteers' => 'volunteers#index', as: 'volunteers_info' get '/volunteers' => 'volunteers#index', as: 'volunteers_info'
patch '/volunteers' => 'volunteers#update', as: 'volunteers_update' patch '/volunteers' => 'volunteers#update', as: 'volunteers_update'
resources :booths do
member do
patch :accept
patch :restart
patch :withdrawn
patch :to_accept
patch :reject
patch :reset
patch :to_reject
patch :cancel
end
end
resources :registrations, except: [:create, :new] do resources :registrations, except: [:create, :new] do
member do member do
patch :toggle_attendance patch :toggle_attendance

View file

@ -0,0 +1,16 @@
class CreateBooths < ActiveRecord::Migration
def change
create_table :booths 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.references :conference
t.timestamps null: false
end
end
end

View file

@ -0,0 +1,11 @@
class CreateBoothRequests < ActiveRecord::Migration
def change
create_table :booth_requests do |t|
t.references :booth, index: true, foreign_key: true
t.references :user, index: true, foreign_key: true
t.string :role
t.timestamps null: false
end
end
end

View file

@ -0,0 +1,6 @@
class AddIndexToPhysicalTickets < ActiveRecord::Migration
def change
add_column :physical_tickets, :token, :string
add_index :physical_tickets, :token, unique: true
end
end

View file

@ -11,10 +11,10 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20170711102511) do ActiveRecord::Schema.define(version: 20170721001700) do
create_table "ahoy_events", force: :cascade do |t| create_table "ahoy_events", force: :cascade do |t|
t.uuid "visit_id", limit: 16 t.integer "visit_id"
t.integer "user_id" t.integer "user_id"
t.string "name" t.string "name"
t.text "properties" t.text "properties"
@ -31,6 +31,30 @@ ActiveRecord::Schema.define(version: 20170711102511) do
t.datetime "updated_at" t.datetime "updated_at"
end end
create_table "booth_requests", force: :cascade do |t|
t.integer "booth_id"
t.integer "user_id"
t.string "role"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "booth_requests", ["booth_id"], name: "index_booth_requests_on_booth_id"
add_index "booth_requests", ["user_id"], name: "index_booth_requests_on_user_id"
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
end
create_table "campaigns", force: :cascade do |t| create_table "campaigns", force: :cascade do |t|
t.integer "conference_id" t.integer "conference_id"
t.string "name" t.string "name"
@ -293,8 +317,11 @@ ActiveRecord::Schema.define(version: 20170711102511) do
t.integer "ticket_purchase_id", null: false t.integer "ticket_purchase_id", null: false
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.string "token"
end end
add_index "physical_tickets", ["token"], name: "index_physical_tickets_on_token", unique: true
create_table "programs", force: :cascade do |t| create_table "programs", force: :cascade do |t|
t.integer "conference_id" t.integer "conference_id"
t.integer "rating", default: 0 t.integer "rating", default: 0

View file

@ -0,0 +1,148 @@
require 'spec_helper'
describe Admin::BoothsController do
let(:admin) { create(:admin) }
let(:conference) { create(:conference) }
let(:booth) { create(:booth, title: 'Title', conference: conference) }
let(:admin) { create(:admin) }
context 'not logged in user' do
describe 'GET index' do
it 'does not render admin/booths#index' do
get :index, 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
expect(response).to redirect_to(user_session_path)
end
end
end
context 'user is admin' do
before :each do
sign_in admin
end
describe 'GET index' do
before { get :index, conference_id: conference.short_title }
it 'assigns attributes for booths' do
expect(assigns(:booths)).to eq([booth])
end
it 'renders index template' do
expect(response).to render_template('index')
end
end
describe 'GET new' do
before { get :new, conference_id: conference.short_title }
it 'assigns attributes for booths' do
expect(assigns(:booth)).to be_a_new(Booth)
end
it 'renders new template' do
expect(response).to render_template('new')
end
end
describe 'POST #create' do
context 'successfully created' do
before { post :create, 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
end
expected.to change { Booth.count }.by(1)
end
it 'redirects to admin booth index' do
expect(response).to redirect_to(admin_conference_booths_path)
end
it 'has responsibles' do
expect(booth.responsibles.count).to_not eq(0)
end
it 'shows success message' do
expect(flash[:notice]).to match('Booth successfully created.')
end
end
context 'create action fails' do
before { post :create, 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
end
expected.to_not change(Booth, :count)
end
it 'redirects to new' do
expect(response).to render_template('new')
end
it 'shows flash message' do
expect(flash[:error]).to eq("Creating 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 }
it 'renders edit template' do
expect(response).to render_template('edit')
end
it 'assigns booth variable' do
expect(assigns(:booth)).to eq booth
end
end
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 }
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.'
end
it 'updates booth' do
booth.reload
expect(booth.title).to eq('different')
end
end
end
describe 'DELETE #destroy' do
context 'deletes successfully' do
before { delete :destroy, id: booth.id, conference_id: conference.short_title }
it 'booth deleted' do
expect(Booth.count).to eq(0)
end
it 'redirects to admin booth index path' do
expect(response).to redirect_to(admin_conference_booths_path)
end
it 'show success message' do
expect(flash[:notice]).to match('Booth successfully destroyed.')
end
end
end
end
end

View file

@ -9,7 +9,7 @@ describe PhysicalTicketController do
describe 'GET #show' do describe 'GET #show' do
before :each do before :each do
sign_in user sign_in user
get :show, id: physical_ticket.id, conference_id: conference.short_title get :show, id: physical_ticket.token, conference_id: conference.short_title
end end
it 'assigns ticket_layout' do it 'assigns ticket_layout' do

View file

@ -24,7 +24,7 @@ describe SubscriptionsController do
it 'shows success message in flash notice' do it 'shows success message in flash notice' do
post :create, conference_id: conference.short_title post :create, conference_id: conference.short_title
expect(flash[:notice]).to match("You have been subscribed to receive email notifications for #{conference.short_title}") expect(flash[:notice]).to match("You have subscribed to receive email notifications for #{conference.title}")
end end
it 'subscribes user to conference' do it 'subscribes user to conference' do
@ -47,7 +47,7 @@ describe SubscriptionsController do
it 'shows success message in flash notice' do it 'shows success message in flash notice' do
delete :destroy, conference_id: conference.short_title delete :destroy, conference_id: conference.short_title
expect(flash[:notice]).to match("You have been unsubscribed and now you will not be receiving email notifications for #{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 end
end end

View file

@ -0,0 +1,8 @@
FactoryGirl.define do
factory :booth_request do
booth
user
role 'responsible'
end
end

13
spec/factories/booths.rb Normal file
View file

@ -0,0 +1,13 @@
FactoryGirl.define do
factory :booth do
title { Faker::Hipster.sentence }
description { Faker::Lorem.paragraph }
reasoning { Faker::Lorem.paragraph }
website_url { Faker::Internet.url }
submitter_relationship { Faker::Lorem.paragraph }
conference
responsible_ids { [create(:user).id] }
end
end

View file

@ -249,6 +249,16 @@ feature 'Has correct abilities' do
visit admin_conference_roles_path(conference.short_title) visit admin_conference_roles_path(conference.short_title)
expect(current_path).to eq(admin_conference_roles_path(conference.short_title)) expect(current_path).to eq(admin_conference_roles_path(conference.short_title))
visit admin_conference_booths_path(conference.short_title)
expect(current_path).to eq(admin_conference_booths_path(conference.short_title))
visit new_admin_conference_booth_path(conference.short_title)
expect(current_path).to eq(new_admin_conference_booth_path(conference.short_title))
create(:booth, conference: conference)
visit edit_admin_conference_booth_path(conference.short_title, conference.booths.first)
expect(current_path).to eq(edit_admin_conference_booth_path(conference.short_title, conference.booths.first))
visit admin_conference_resources_path(conference.short_title) visit admin_conference_resources_path(conference.short_title)
expect(current_path).to eq(admin_conference_resources_path(conference.short_title)) expect(current_path).to eq(admin_conference_resources_path(conference.short_title))
@ -259,6 +269,12 @@ feature 'Has correct abilities' do
visit edit_admin_conference_resource_path(conference.short_title, conference.resources.first) visit edit_admin_conference_resource_path(conference.short_title, conference.resources.first)
expect(current_path).to eq(edit_admin_conference_resource_path(conference.short_title, conference.resources.first)) expect(current_path).to eq(edit_admin_conference_resource_path(conference.short_title, conference.resources.first))
visit admin_users_path
expect(current_path).to eq(root_path)
visit admin_user_path(user_cfp)
expect(current_path).to eq(root_path)
visit admin_revision_history_path visit admin_revision_history_path
expect(current_path).to eq(root_path) expect(current_path).to eq(root_path)
end end

View file

@ -237,6 +237,12 @@ feature 'Has correct abilities' do
visit admin_conference_program_tracks_path(conference.short_title) visit admin_conference_program_tracks_path(conference.short_title)
expect(current_path).to eq(root_path) expect(current_path).to eq(root_path)
visit admin_users_path
expect(current_path).to eq(root_path)
visit admin_user_path(user_info_desk)
expect(current_path).to eq(root_path)
visit admin_conference_emails_path(conference.short_title) visit admin_conference_emails_path(conference.short_title)
expect(current_path).to eq(root_path) expect(current_path).to eq(root_path)
end end

View file

@ -237,6 +237,16 @@ feature 'Has correct abilities' do
visit edit_admin_conference_target_path(conference.short_title, conference.targets.first) visit edit_admin_conference_target_path(conference.short_title, conference.targets.first)
expect(current_path).to eq(edit_admin_conference_target_path(conference.short_title, conference.targets.first)) expect(current_path).to eq(edit_admin_conference_target_path(conference.short_title, conference.targets.first))
visit admin_conference_booths_path(conference.short_title)
expect(current_path).to eq(admin_conference_booths_path(conference.short_title))
visit new_admin_conference_booth_path(conference.short_title)
expect(current_path).to eq(new_admin_conference_booth_path(conference.short_title))
create(:booth, conference: conference)
visit edit_admin_conference_booth_path(conference.short_title, conference.booths.first)
expect(current_path).to eq(edit_admin_conference_booth_path(conference.short_title, conference.booths.first))
visit admin_conference_program_tracks_path(conference.short_title) visit admin_conference_program_tracks_path(conference.short_title)
expect(current_path).to eq(admin_conference_program_tracks_path(conference.short_title)) expect(current_path).to eq(admin_conference_program_tracks_path(conference.short_title))
@ -256,6 +266,12 @@ feature 'Has correct abilities' do
visit edit_admin_conference_resource_path(conference.short_title, conference.resources.first) visit edit_admin_conference_resource_path(conference.short_title, conference.resources.first)
expect(current_path).to eq(edit_admin_conference_resource_path(conference.short_title, conference.resources.first)) expect(current_path).to eq(edit_admin_conference_resource_path(conference.short_title, conference.resources.first))
visit admin_users_path
expect(current_path).to eq(root_path)
visit admin_user_path(user_organizer)
expect(current_path).to eq(root_path)
visit admin_revision_history_path visit admin_revision_history_path
expect(current_path).to eq(admin_revision_history_path) expect(current_path).to eq(admin_revision_history_path)
end end

View file

@ -28,23 +28,23 @@ feature Event do
scenario 'rejects a proposal', feature: true, js: true do scenario 'rejects a proposal', feature: true, js: true do
visit admin_conference_program_events_path(conference.short_title) visit admin_conference_program_events_path(conference.short_title)
expect(page.has_content?('Example Proposal')).to be true expect(page).to have_content 'Example Proposal'
click_button 'New' click_button 'New'
click_link "reject_event_#{@event.id}" click_link "reject_event_#{@event.id}"
expect(flash).to eq('Event rejected!') expect(page).to have_content 'Event rejected!'
@event.reload @event.reload
expect(@event.state).to eq('rejected') expect(@event.state).to eq('rejected')
end end
scenario 'accepts a proposal', feature: true, js: true do scenario 'accepts a proposal', feature: true, js: true do
visit admin_conference_program_events_path(conference.short_title) visit admin_conference_program_events_path(conference.short_title)
expect(page.has_content?('Example Proposal')).to be true expect(page).to have_content 'Example Proposal'
click_button 'New' click_button 'New'
click_link "accept_event_#{@event.id}" click_link "accept_event_#{@event.id}"
expect(flash).to eq('Event accepted!') expect(page).to have_content 'Event accepted!'
expect(page.has_content?('Unconfirmed')).to be true expect(page).to have_content 'Unconfirmed'
@event.reload @event.reload
expect(@event.state).to eq('unconfirmed') expect(@event.state).to eq('unconfirmed')
end end
@ -52,11 +52,11 @@ feature Event do
scenario 'restarts review of a proposal', feature: true, js: true do scenario 'restarts review of a proposal', feature: true, js: true do
@event.reject!(@options) @event.reject!(@options)
visit admin_conference_program_events_path(conference.short_title) visit admin_conference_program_events_path(conference.short_title)
expect(page.has_content?('Example Proposal')).to be true expect(page).to have_content 'Example Proposal'
click_button 'Rejected' click_button 'Rejected'
click_link "restart_event_#{@event.id}" click_link "restart_event_#{@event.id}"
expect(flash).to eq('Review started!') expect(page).to have_content 'Review started!'
@event.reload @event.reload
expect(@event.state).to eq('new') expect(@event.state).to eq('new')
end end
@ -83,7 +83,7 @@ feature Event do
fill_in 'event_abstract', with: 'Lorem ipsum abstract' fill_in 'event_abstract', with: 'Lorem ipsum abstract'
click_button 'Create Proposal' click_button 'Create Proposal'
expect(flash).to eq('Proposal was successfully submitted.') expect(page).to have_content 'Proposal was successfully submitted.'
expect(Event.count).to eq(expected_count_event) expect(Event.count).to eq(expected_count_event)
expect(User.count).to eq(expected_count_user) expect(User.count).to eq(expected_count_user)
@ -101,7 +101,7 @@ feature Event do
select('Easy', from: 'event[difficulty_level_id]') select('Easy', from: 'event[difficulty_level_id]')
click_button 'Update Proposal' click_button 'Update Proposal'
expect(flash).to eq('Proposal was successfully updated.') expect(page).to have_content 'Proposal was successfully updated.'
end end
scenario 'signed_in user submits a valid proposal', feature: true, js: true do scenario 'signed_in user submits a valid proposal', feature: true, js: true do
@ -119,7 +119,7 @@ feature Event do
fill_in 'event_description', with: 'Lorem ipsum description' fill_in 'event_description', with: 'Lorem ipsum description'
click_button 'Create Proposal' click_button 'Create Proposal'
expect(flash).to eq('Proposal was successfully submitted.') expect(page).to have_content 'Proposal was successfully submitted.'
expect(current_path).to eq(conference_program_proposals_path(conference.short_title)) expect(current_path).to eq(conference_program_proposals_path(conference.short_title))
expect(Event.count).to eq(expected_count) expect(Event.count).to eq(expected_count)
@ -128,11 +128,10 @@ feature Event do
scenario 'confirms a proposal', feature: true, js: true do scenario 'confirms a proposal', feature: true, js: true do
sign_in participant sign_in participant
visit conference_program_proposals_path(conference.short_title) visit conference_program_proposals_path(conference.short_title)
expect(page.has_content?('Example Proposal')).to be true expect(page).to have_content 'Example Proposal'
expect(@event.state).to eq('unconfirmed') expect(@event.state).to eq('unconfirmed')
click_link "confirm_proposal_#{@event.id}" click_link "confirm_proposal_#{@event.id}"
expect(flash) expect(page).to have_content 'The proposal was confirmed. Please register to attend the conference.'
.to eq('The proposal was confirmed. Please register to attend the conference.')
expect(current_path).to eq(new_conference_conference_registration_path(conference.short_title)) expect(current_path).to eq(new_conference_conference_registration_path(conference.short_title))
@event.reload @event.reload
expect(@event.state).to eq('confirmed') expect(@event.state).to eq('confirmed')
@ -142,9 +141,9 @@ feature Event do
sign_in participant sign_in participant
@event.confirm! @event.confirm!
visit conference_program_proposals_path(conference.short_title) visit conference_program_proposals_path(conference.short_title)
expect(page.has_content?('Example Proposal')).to be true expect(page).to have_content 'Example Proposal'
click_link "delete_proposal_#{@event.id}" click_link "delete_proposal_#{@event.id}"
expect(flash).to eq('Proposal was successfully withdrawn.') expect(page).to have_content 'Proposal was successfully withdrawn.'
@event.reload @event.reload
expect(@event.state).to eq('withdrawn') expect(@event.state).to eq('withdrawn')
end end

View file

@ -64,6 +64,10 @@ describe 'User with admin role' do
it{ should_not be_able_to(:edit, Role.find_by(name: 'organization_admin', resource: other_organization)) } it{ should_not be_able_to(:edit, Role.find_by(name: 'organization_admin', resource: other_organization)) }
it{ should_not be_able_to(:show, Role.find_by(name: 'organization_admin', resource: other_organization)) } it{ should_not be_able_to(:show, Role.find_by(name: 'organization_admin', resource: other_organization)) }
it{ should_not be_able_to(:new, User.new) }
it{ should_not be_able_to(:create, User.new) }
it{ should_not be_able_to(:manage, User) }
%w[organizer cfp info_desk volunteers_coordinator].each do |role| %w[organizer cfp info_desk volunteers_coordinator].each do |role|
it{ should_not be_able_to(:toggle_user, Role.find_by(name: role, resource: other_conference)) } it{ should_not be_able_to(:toggle_user, Role.find_by(name: role, resource: other_conference)) }
it{ should_not be_able_to(:update, Role.find_by(name: role, resource: other_conference)) } it{ should_not be_able_to(:update, Role.find_by(name: role, resource: other_conference)) }

54
spec/models/booth_spec.rb Normal file
View file

@ -0,0 +1,54 @@
require 'spec_helper'
describe 'Booth' do
subject { create(:booth) }
let!(:conference) { create(:conference) }
describe 'validation' do
it 'has a valid factory' do
expect(build(:booth)).to be_valid
end
it { is_expected.to validate_presence_of(:reasoning) }
it { is_expected.to validate_presence_of(:description) }
it { is_expected.to validate_presence_of(:responsibles) }
it { is_expected.to validate_presence_of(:submitter_relationship) }
it { is_expected.to validate_presence_of(:website_url) }
it 'is not valid without a title' do
is_expected.to validate_presence_of(:title)
end
end
describe 'association' do
it { is_expected.to belong_to(:conference) }
it { is_expected.to have_many(:booth_requests) }
end
describe '#transition_possible?(transition)' do
shared_examples 'transition_possible?(transition)' do |state, transition, expected|
it "returns #{expected} for #{transition} transition, when the booth is #{state}}" do
my_booth = create(:booth, state: state)
expect(my_booth.transition_possible?(transition.to_sym)).to eq expected
end
end
states = [:new, :withdrawn, :to_accept, :accepted, :to_reject, :rejected, :canceled]
transitions = [:restart, :withdraw, :accept, :reject, :to_accept, :to_reject, :cancel]
states_transitions = { new: { restart: false, withdraw: true, accept: true, to_accept: true, to_reject: true, reject: true, cancel: false },
withdrawn: { restart: true, withdraw: false, accept: false, to_accept: false, to_reject: false, reject: false, cancel: false },
to_accept: { restart: true, withdraw: true, accept: true, to_accept: false, to_reject: true, reject: false, cancel: true },
to_reject: { restart: true, withdraw: true, accept: false, to_accept: true, to_reject: false, reject: true, cancel: true },
accepted: { restart: false, withdraw: true, accept: false, to_accept: false, to_reject: false, reject: false, cancel: true },
rejected: { restart: false, withdraw: true, accept: false, to_accept: false, to_reject: false, reject: false, cancel: true },
canceled: { restart: true, withdraw: false, accept: false, to_accept: false, to_reject: false, reject: false, cancel: false } }
states.each do |state|
transitions.each do |transition|
it_behaves_like 'transition_possible?(transition)', state, transition, states_transitions[state.to_sym][transition.to_sym]
end
end
end
end