From f7c0b64eb51a210bdfe6f719cf7e82ed07809914 Mon Sep 17 00:00:00 2001 From: nasia Date: Wed, 17 May 2017 13:31:27 +0300 Subject: [PATCH] Introduce Booths for admin --- .haml-lint_todo.yml | 4 + app/controllers/admin/booths_controller.rb | 94 +++++++++++++++++++ app/helpers/application_helper.rb | 7 ++ app/models/admin_ability.rb | 2 + app/models/booth.rb | 75 +++++++++++++++ app/models/booth_request.rb | 9 ++ app/models/conference.rb | 1 + app/models/user.rb | 3 + .../booths/_change_state_dropdown.html.haml | 29 ++++++ app/views/admin/booths/_form.html.haml | 33 +++++++ app/views/admin/booths/edit.html.haml | 5 + app/views/admin/booths/index.html.haml | 58 ++++++++++++ app/views/admin/booths/new.html.haml | 3 + app/views/admin/booths/show.html.haml | 57 +++++++++++ config/routes.rb | 13 +++ db/migrate/20170516190048_create_booths.rb | 16 ++++ .../20170530112510_create_booth_requests.rb | 11 +++ db/schema.rb | 26 ++++- spec/factories/booths.rb | 15 +++ spec/features/cfp_ability_spec.rb | 10 ++ spec/features/organizer_ability_spec.rb | 10 ++ spec/models/booth_spec.rb | 54 +++++++++++ 22 files changed, 534 insertions(+), 1 deletion(-) create mode 100644 app/controllers/admin/booths_controller.rb create mode 100644 app/models/booth.rb create mode 100644 app/models/booth_request.rb create mode 100644 app/views/admin/booths/_change_state_dropdown.html.haml create mode 100644 app/views/admin/booths/_form.html.haml create mode 100644 app/views/admin/booths/edit.html.haml create mode 100644 app/views/admin/booths/index.html.haml create mode 100644 app/views/admin/booths/new.html.haml create mode 100644 app/views/admin/booths/show.html.haml create mode 100644 db/migrate/20170516190048_create_booths.rb create mode 100644 db/migrate/20170530112510_create_booth_requests.rb create mode 100644 spec/factories/booths.rb create mode 100644 spec/models/booth_spec.rb diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index 4644a6bb..b42ccb06 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -11,6 +11,9 @@ linters: # Offense count: 945 LineLength: 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/index.html.haml" - "app/views/admin/cfps/_form.html.haml" @@ -179,6 +182,7 @@ linters: # Offense count: 223 InstanceVariables: exclude: + - "app/views/admin/booths/_change_state_dropdown.html.haml" - "app/views/admin/campaigns/_form.html.haml" - "app/views/admin/cfps/_booths_cfp.html.haml" - "app/views/admin/cfps/_form.html.haml" diff --git a/app/controllers/admin/booths_controller.rb b/app/controllers/admin/booths_controller.rb new file mode 100644 index 00000000..f5096c34 --- /dev/null +++ b/app/controllers/admin/booths_controller.rb @@ -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 diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index fe81dfad..0abf6088 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -162,6 +162,13 @@ module ApplicationHelper include_blank: false, label: 'Speakers', input_html: { class: 'select-help-toggle', multiple: 'true' } 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) conference.program.event_types.map { |et| et.title.pluralize }.to_sentence end diff --git a/app/models/admin_ability.rb b/app/models/admin_ability.rb index d43683fd..4244d049 100644 --- a/app/models/admin_ability.rb +++ b/app/models/admin_ability.rb @@ -120,6 +120,7 @@ class AdminAbility commercialable_id: conf_ids can :manage, Registration, 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 do |question| !(question.conferences.pluck(:id) & conf_ids).empty? @@ -170,6 +171,7 @@ class AdminAbility conf_ids_for_cfp.include?(conf.id) end 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, EventType, program: { conference_id: conf_ids_for_cfp } can :manage, Track, program: { conference_id: conf_ids_for_cfp } diff --git a/app/models/booth.rb b/app/models/booth.rb new file mode 100644 index 00000000..e692c663 --- /dev/null +++ b/app/models/booth.rb @@ -0,0 +1,75 @@ +class Booth < ActiveRecord::Base + include ActiveRecord::Transitions + + 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] + 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 diff --git a/app/models/booth_request.rb b/app/models/booth_request.rb new file mode 100644 index 00000000..438b4167 --- /dev/null +++ b/app/models/booth_request.rb @@ -0,0 +1,9 @@ +class BoothRequest < ActiveRecord::Base + belongs_to :booth + belongs_to :user + + validates :role, + presence: true + + ROLES = %w[submitter responsible].freeze +end diff --git a/app/models/conference.rb b/app/models/conference.rb index db6b4745..b528d755 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -28,6 +28,7 @@ class Conference < ActiveRecord::Base has_many :supporters, through: :ticket_purchases, source: :user has_many :tickets, dependent: :destroy has_many :resources, dependent: :destroy + has_many :booths, dependent: :destroy has_many :lodgings, dependent: :destroy has_many :registrations, dependent: :destroy diff --git a/app/models/user.rb b/app/models/user.rb index 54a9deba..f3f03ab7 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -56,6 +56,9 @@ class User < ActiveRecord::Base has_many :voted_events, through: :votes, source: :events has_many :subscriptions, dependent: :destroy 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 scope :admin, -> { where(is_admin: true) } diff --git a/app/views/admin/booths/_change_state_dropdown.html.haml b/app/views/admin/booths/_change_state_dropdown.html.haml new file mode 100644 index 00000000..c0418d67 --- /dev/null +++ b/app/views/admin/booths/_change_state_dropdown.html.haml @@ -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}" diff --git a/app/views/admin/booths/_form.html.haml b/app/views/admin/booths/_form.html.haml new file mode 100644 index 00000000..41637ac0 --- /dev/null +++ b/app/views/admin/booths/_form.html.haml @@ -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, 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: 'Your personal relationship with the organization you are applying for', + hint: 'e.g. employee, member of the open source community 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 + } ) + }); diff --git a/app/views/admin/booths/edit.html.haml b/app/views/admin/booths/edit.html.haml new file mode 100644 index 00000000..9f9a5a61 --- /dev/null +++ b/app/views/admin/booths/edit.html.haml @@ -0,0 +1,5 @@ +%h1 + Editing + = @booth.title + += render 'form' diff --git a/app/views/admin/booths/index.html.haml b/app/views/admin/booths/index.html.haml new file mode 100644 index 00000000..0bcccb91 --- /dev/null +++ b/app/views/admin/booths/index.html.haml @@ -0,0 +1,58 @@ +.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 + = 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?"} diff --git a/app/views/admin/booths/new.html.haml b/app/views/admin/booths/new.html.haml new file mode 100644 index 00000000..db1c4736 --- /dev/null +++ b/app/views/admin/booths/new.html.haml @@ -0,0 +1,3 @@ +%h1 New booth + += render 'form' diff --git a/app/views/admin/booths/show.html.haml b/app/views/admin/booths/show.html.haml new file mode 100644 index 00000000..8c692bc4 --- /dev/null +++ b/app/views/admin/booths/show.html.haml @@ -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 diff --git a/config/routes.rb b/config/routes.rb index 1643fc6b..5a17d314 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -37,6 +37,19 @@ Osem::Application.routes.draw do get '/volunteers' => 'volunteers#index', as: 'volunteers_info' 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 member do patch :toggle_attendance diff --git a/db/migrate/20170516190048_create_booths.rb b/db/migrate/20170516190048_create_booths.rb new file mode 100644 index 00000000..d2aa0be6 --- /dev/null +++ b/db/migrate/20170516190048_create_booths.rb @@ -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 diff --git a/db/migrate/20170530112510_create_booth_requests.rb b/db/migrate/20170530112510_create_booth_requests.rb new file mode 100644 index 00000000..75e73a93 --- /dev/null +++ b/db/migrate/20170530112510_create_booth_requests.rb @@ -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 diff --git a/db/schema.rb b/db/schema.rb index f1a213a5..64ac0393 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -14,7 +14,7 @@ ActiveRecord::Schema.define(version: 20170711102511) do create_table "ahoy_events", force: :cascade do |t| - t.uuid "visit_id", limit: 16 + t.integer "visit_id" t.integer "user_id" t.string "name" t.text "properties" @@ -31,6 +31,30 @@ ActiveRecord::Schema.define(version: 20170711102511) do t.datetime "updated_at" end + create_table "booth_requests", force: :cascade do |t| + t.integer "booth_id" + t.integer "user_id" + t.string "role" + t.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| t.integer "conference_id" t.string "name" diff --git a/spec/factories/booths.rb b/spec/factories/booths.rb new file mode 100644 index 00000000..a67d30f0 --- /dev/null +++ b/spec/factories/booths.rb @@ -0,0 +1,15 @@ +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 + + after(:build) do |booth| + booth.responsibles << create(:user) + end + end +end diff --git a/spec/features/cfp_ability_spec.rb b/spec/features/cfp_ability_spec.rb index b12a2ef5..46db11c2 100644 --- a/spec/features/cfp_ability_spec.rb +++ b/spec/features/cfp_ability_spec.rb @@ -249,6 +249,16 @@ feature 'Has correct abilities' do visit 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) expect(current_path).to eq(admin_conference_resources_path(conference.short_title)) diff --git a/spec/features/organizer_ability_spec.rb b/spec/features/organizer_ability_spec.rb index 10c5d726..06a2a836 100644 --- a/spec/features/organizer_ability_spec.rb +++ b/spec/features/organizer_ability_spec.rb @@ -237,6 +237,16 @@ feature 'Has correct abilities' do visit edit_admin_conference_target_path(conference.short_title, conference.targets.first) expect(current_path).to eq(edit_admin_conference_target_path(conference.short_title, conference.targets.first)) + visit admin_conference_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) expect(current_path).to eq(admin_conference_program_tracks_path(conference.short_title)) diff --git a/spec/models/booth_spec.rb b/spec/models/booth_spec.rb new file mode 100644 index 00000000..f13eb536 --- /dev/null +++ b/spec/models/booth_spec.rb @@ -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: false }, + to_reject: { restart: true, withdraw: true, accept: false, to_accept: true, to_reject: false, reject: true, cancel: false }, + 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