From c71d15565e0180f729ae212eec79852a111fffa3 Mon Sep 17 00:00:00 2001 From: Aditya Prakash Date: Sun, 28 Feb 2016 12:07:13 +0530 Subject: [PATCH 1/5] Fix authorization of new and create in ConferenceRegistrationsController Before authorization we need to set conference relation. Change in proposal spec cause conference has to have valid registration period for successful redirect to registration after confirm proposal. --- .../conference_registrations_controller.rb | 8 +++++--- app/models/ability.rb | 6 +++++- spec/features/conference_registration_spec.rb | 11 +++++++++++ spec/features/proposal_spec.rb | 2 ++ spec/models/ability_spec.rb | 10 +++++++++- 5 files changed, 32 insertions(+), 5 deletions(-) diff --git a/app/controllers/conference_registrations_controller.rb b/app/controllers/conference_registrations_controller.rb index c9d7d216..40218b31 100644 --- a/app/controllers/conference_registrations_controller.rb +++ b/app/controllers/conference_registrations_controller.rb @@ -1,7 +1,7 @@ class ConferenceRegistrationsController < ApplicationController before_filter :authenticate_user!, except: [:new, :create] load_resource :conference, find_by: :short_title - authorize_resource :conference_registrations, class: Registration + authorize_resource :conference_registrations, class: Registration, except: [:new, :create] before_action :set_registration, only: [:edit, :update, :destroy, :show] def new @@ -25,8 +25,9 @@ class ConferenceRegistrationsController < ApplicationController return end - @registration = Registration.new - + @registration = Registration.new(conference_id: @conference.id) + # make sure that conference is open for registration + authorize! :new, @registration # @user variable needs to be set so that _sign_up_form_embedded works properly @user = @registration.build_user end @@ -50,6 +51,7 @@ class ConferenceRegistrationsController < ApplicationController end @registration.user = @user + authorize! :create, @registration if @registration.save # Trigger ahoy event diff --git a/app/models/ability.rb b/app/models/ability.rb index 16313da9..c20ddfc0 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -46,9 +46,13 @@ class Ability can :show, Commercial, commercialable_type: 'Event', commercialable_id: Event.where(state: 'confirmed').pluck(:id) can :show, User unless CONFIG['authentication']['ichain']['enabled'] - can [:show, :create], Registration do |registration| + can :show, Registration do |registration| registration.new_record? end + + can [:new, :create], Registration do |registration| + registration.conference.registration_open? && registration.new_record? + end can :show, Event do |event| event.new_record? end diff --git a/spec/features/conference_registration_spec.rb b/spec/features/conference_registration_spec.rb index b1ab5f08..3084e9d0 100644 --- a/spec/features/conference_registration_spec.rb +++ b/spec/features/conference_registration_spec.rb @@ -49,5 +49,16 @@ feature Registration do expect(conference.user_registered?(participant)).to be(true) end end + + context 'registration is closed' do + let(:conference_with_closed_registration) { create(:conference, registration_period: create(:registration_period)) } + + scenario 'registers for a conference', feature: true do + participant.is_admin = false + visit new_conference_conference_registrations_path(conference_with_closed_registration.short_title) + expect(current_path).to eq(root_path) + expect(flash).to eq 'You are not authorized to access this page.' + end + end end end diff --git a/spec/features/proposal_spec.rb b/spec/features/proposal_spec.rb index 720a1bc3..55c8ebb5 100644 --- a/spec/features/proposal_spec.rb +++ b/spec/features/proposal_spec.rb @@ -2,6 +2,7 @@ require 'spec_helper' feature Event do let!(:conference) { create(:conference) } + let!(:registration_period) { create(:registration_period, conference: conference, start_date: Date.current) } let!(:cfp) { create(:cfp, program_id: conference.program.id) } let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:organizer) { create(:user, email: 'admin@example.com', role_ids: [organizer_role.id]) } @@ -134,6 +135,7 @@ feature Event do click_link "confirm_proposal_#{@event.id}" expect(flash). to eq('The proposal was confirmed. Please register to attend the conference.') + expect(current_path).to eq(new_conference_conference_registrations_path(conference.short_title)) @event.reload expect(@event.state).to eq('confirmed') end diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index 71e11171..dd389545 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -35,6 +35,11 @@ describe 'User' do # Test abilities for not signed in users context 'when user is not signed in' do + let(:conference_with_open_registration) { create(:conference) } + let!(:open_registration_period) { create(:registration_period, conference: conference_with_open_registration, start_date: Date.current - 6.days) } + let(:conference_with_closed_registration) { create(:conference) } + let!(:closed_registration_period) { create(:registration_period, conference: conference_with_closed_registration, start_date: Date.current - 6.days, end_date: Date.current - 6.days) } + it{ should be_able_to(:index, Conference)} it{ should be_able_to(:show, conference_public)} @@ -55,8 +60,11 @@ describe 'User' do it{ should be_able_to(:show, User)} - it{ should be_able_to(:create, Registration)} it{ should be_able_to(:show, Registration.new)} + it{ should be_able_to(:create, Registration.new(conference_id: conference_with_open_registration.id))} + it{ should be_able_to(:new, Registration.new(conference_id: conference_with_open_registration.id))} + it{ should_not be_able_to(:new, Registration.new(conference_id: conference_with_closed_registration.id))} + it{ should_not be_able_to(:create, Registration.new(conference_id: conference_with_closed_registration.id))} it{ should_not be_able_to(:manage, registration)} it{ should be_able_to(:create, Event)} From 13a6586f81421bab61a0ae76ed6fee95ddbaeede Mon Sep 17 00:00:00 2001 From: Aditya Prakash Date: Sat, 27 Feb 2016 13:43:19 +0530 Subject: [PATCH 2/5] Tests for registration model Before registration we need to make sure that conference has registration_period --- spec/factories/conferences.rb | 2 +- spec/models/registration_spec.rb | 83 ++++++++++++++++++++++++++------ 2 files changed, 70 insertions(+), 15 deletions(-) diff --git a/spec/factories/conferences.rb b/spec/factories/conferences.rb index a63dd0d5..7d35fc6c 100644 --- a/spec/factories/conferences.rb +++ b/spec/factories/conferences.rb @@ -7,7 +7,7 @@ FactoryGirl.define do timezone 'Amsterdam' start_date { Date.today } end_date { 6.days.from_now } - registration_limit 0 + registration_limit 10 after(:create) do |conference| Role.where(name: 'organizer', resource: conference).first_or_create(description: 'For the organizers of the conference (who shall have full access)') diff --git a/spec/models/registration_spec.rb b/spec/models/registration_spec.rb index 1bf9e88f..d9ea534f 100644 --- a/spec/models/registration_spec.rb +++ b/spec/models/registration_spec.rb @@ -1,24 +1,79 @@ -#!/bin/env ruby -# encoding: utf-8 require 'spec_helper' -describe 'Registration' do - describe 'validations' do +describe Registration do + subject { create(:registration) } + + describe 'validation' do + it 'has a valid factory' do expect(build(:registration)).to be_valid end + it { should validate_presence_of(:user) } + + it 'validates uniqueness of user in scope of conference' do + expect(build(:registration, conference: subject.conference, user: subject.user)).not_to be_valid + end + describe 'registration_limit_not_exceed' do - it 'is not valid when limit exceeded' do - conference = build(:conference) - conference.registration_limit = 1 - registration1 = build(:registration, conference: conference) - registration1.save - registration2 = build(:registration, conference: conference) - registration2.save - expect(conference.registrations.size).to be 1 - expect(registration2.valid?).to be false - expect(registration2.errors.full_messages).to eq(['Registration limit exceeded']) + context 'registration_limit has exceeded' do + before do + conference = create(:conference, registration_limit: 1) + create(:registration, conference: conference) + @second_registration = build(:registration, conference: conference) + end + + it 'is not valid factory' do + expect(@second_registration.valid?).to be false + expect(@second_registration.errors.full_messages).to eq(['Registration limit exceeded']) + end + end + end + end + + describe 'association' do + it { should belong_to(:user) } + it { should belong_to(:conference) } + it { should belong_to(:dietary_choice) } + it { should have_and_belong_to_many(:social_events) } + it { should have_and_belong_to_many(:events) } + it { should have_and_belong_to_many(:qanswers) } + it { should have_and_belong_to_many(:vchoices) } + it { should have_many(:events_registrations) } + it { should have_many(:workshops) } + end + + describe 'callback' do + after { subject.run_callbacks(:create) } + + # set_week and subscribe_to_conference are private methods + describe '#set_week' do + before { subject.created_at = Time.utc(2014, 5, 10) } + + it 'sets week of registration' do + expect(subject).to receive(:set_week) + expect(subject.week).to eq 18 + end + end + + describe '#subscribe_to_conference' do + it 'subscribes to conference' do + expect(subject).to receive(:subscribe_to_conference) + expect(subject.user.subscribed?(subject.conference)).to be_truthy + end + end + + it 'sends registrations mail' do + expect(subject).to receive(:send_registration_mail) + end + end + + describe 'method' do + describe '#week' do + before { subject.created_at = Date.new(2014, 06, 30) } + + it 'returns week number of created_at' do + expect(subject.week).to eq(26) end end end From 5bff60ec7d497726befa2ce918d1c89cf15417d5 Mon Sep 17 00:00:00 2001 From: Aditya Prakash Date: Mon, 29 Feb 2016 00:21:24 +0530 Subject: [PATCH 3/5] Tests for ConferenceRegistrations controller Authorization needs to be done first or else it will give CanCan::AuthorizationNotPerformed error for some of branches. Removed if condition is dead code. Small fix in flash message of destroy and its feature test. --- .../conference_registrations_controller.rb | 17 +- ...conference_registration_controller_spec.rb | 284 ++++++++++++++++++ spec/factories/registration.rb | 1 + spec/features/conference_registration_spec.rb | 30 +- 4 files changed, 314 insertions(+), 18 deletions(-) create mode 100644 spec/controllers/conference_registration_controller_spec.rb diff --git a/app/controllers/conference_registrations_controller.rb b/app/controllers/conference_registrations_controller.rb index 40218b31..04779edf 100644 --- a/app/controllers/conference_registrations_controller.rb +++ b/app/controllers/conference_registrations_controller.rb @@ -5,6 +5,9 @@ class ConferenceRegistrationsController < ApplicationController before_action :set_registration, only: [:edit, :update, :destroy, :show] def new + @registration = Registration.new(conference_id: @conference.id) + authorize! :new, @registration + # Redirect to registration edit when user is already registered if @conference.user_registered?(current_user) redirect_to edit_conference_conference_registrations_path(@conference.short_title) @@ -15,19 +18,11 @@ class ConferenceRegistrationsController < ApplicationController return end - # avoid openid sign_in to redirect to register/new when the sign_in user had already a registration - if current_user && @conference.user_registered?(current_user) - redirect_to edit_conference_conference_registrations_path(@conference.short_title) - end - if @conference.registration_limit_exceeded? redirect_to root_path, alert: "Sorry, registration limit exceeded for #{@conference.title}" return end - @registration = Registration.new(conference_id: @conference.id) - # make sure that conference is open for registration - authorize! :new, @registration # @user variable needs to be set so that _sign_up_form_embedded works properly @user = @registration.build_user end @@ -91,9 +86,9 @@ class ConferenceRegistrationsController < ApplicationController redirect_to root_path, notice: "You are not registered for #{@conference.title} anymore!" else - redirect_to root_path, - error: "Could not update your registration for #{@conference.title}: "\ - "#{@registration.errors.full_messages.join('. ')}." + redirect_to conference_conference_registrations_path(@conference.short_title), + flash: { error: "Could not delete your registration for #{@conference.title}: "\ + "#{@registration.errors.full_messages.join('. ')}." } end end diff --git a/spec/controllers/conference_registration_controller_spec.rb b/spec/controllers/conference_registration_controller_spec.rb new file mode 100644 index 00000000..78870f25 --- /dev/null +++ b/spec/controllers/conference_registration_controller_spec.rb @@ -0,0 +1,284 @@ +require 'spec_helper' + +describe ConferenceRegistrationsController, type: :controller do + let!(:first_user) { create(:user) } + let(:conference) { create(:conference) } + let(:conference_with_open_registration) { create(:conference) } + let!(:open_registration_period) { create(:registration_period, conference: conference_with_open_registration, start_date: Date.current - 6.days) } + let(:user) { create(:user) } + + context 'user is not signed in' do + describe 'GET #new' do + context 'ichain is enabled' do + before do + CONFIG['authentication']['ichain']['enabled'] = true + get :new, conference_id: conference_with_open_registration.short_title + end + + after { CONFIG['authentication']['ichain']['enabled'] = false } + + it 'redirects to root path' do + expect(response).to redirect_to root_path + end + end + end + + describe 'POST #create' do + before do + post :create, user: attributes_for(:user), + registration: attributes_for(:registration), + conference_id: conference_with_open_registration.short_title + end + + it 'assigns user variable' do + expect(assigns(:user)).not_to be_nil + end + + it 'signs in registration user' do + expect(controller.current_user).not_to be_nil + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match('You are now registered and will be receiving E-Mail notifications.') + end + + it 'redirects to registration show path' do + expect(response).to redirect_to conference_conference_registrations_path(conference_with_open_registration.short_title) + end + + it 'creates a new registration' do + expect(Registration.count).to eq 1 + end + end + end + + context 'user is signed in' do + before { sign_in(user) } + + describe 'GET #new' do + context 'user is registered to conference' do + before do + create(:registration, user: user, conference: conference_with_open_registration) + get :new, conference_id: conference_with_open_registration.short_title + end + + it 'redirects to edit registration page' do + expect(response).to redirect_to edit_conference_conference_registrations_path(conference_with_open_registration.short_title) + end + end + + context 'registration limit has reached' do + before do + conference_with_open_registration.update_attributes(registration_limit: 1) + create(:registration, conference: conference_with_open_registration) + get :new, conference_id: conference_with_open_registration.short_title + end + + it 'redirects to root path' do + expect(response).to redirect_to root_path + end + + it 'shows error in flash message' do + expect(flash[:alert]).to match "Sorry, registration limit exceeded for #{conference_with_open_registration.title}" + end + end + + context 'successful request' do + before do + get :new, conference_id: conference_with_open_registration.short_title + end + + it 'assigns registration and user variables' do + expect(assigns(:registration)).to be_instance_of(Registration) + expect(assigns(:user)).to be_instance_of(User) + end + + it 'renders the new template' do + expect(response).to render_template('new') + end + end + end + + describe 'GET #show' do + before do + @registration = create(:registration, conference: conference_with_open_registration, user: user) + end + + context 'user has purchased a ticket' do + before do + @ticket = create(:ticket, conference: conference_with_open_registration) + @purchased_ticket = create(:ticket_purchase, conference: conference_with_open_registration, + user: user, + ticket: @ticket) + get :show, conference_id: conference_with_open_registration.short_title + end + + it 'renders the show template' do + expect(response).to render_template('show') + end + + it 'assigns workshops variable' do + expect(assigns(:workshops)).to eq @registration.workshops + end + + it 'assigns price of purchased tickets to total_price and purchased tickets to tickets' do + expect(assigns(:total_price)).to eq Money.new(10000, 'USD') + expect(assigns(:tickets)).to match_array [@purchased_ticket] + end + end + + context 'user has not purchased any ticket' do + before do + get :show, conference_id: conference_with_open_registration.short_title + end + + it 'assigns 0 dollars to total_price and empty array to tickets variables' do + expect(assigns(:total_price)).to eq Money.new(0, 'USD') + expect(assigns(:tickets)).to match_array [] + end + end + end + + describe 'GET #edit' do + before do + create(:registration, conference: conference_with_open_registration, user: user) + get :edit, conference_id: conference_with_open_registration.short_title + end + + it 'renders the edit template' do + expect(response).to render_template('edit') + end + end + + describe 'POST #create' do + context "tickets are available and user hasn't bought any" do + before do + create(:ticket, conference: conference_with_open_registration) + post :create, registration: attributes_for(:registration), + conference_id: conference_with_open_registration.short_title + end + + it 'assigns user variable' do + expect(assigns(:user)).to eq user + end + + it 'redirects to conference tickets path' do + expect(response).to redirect_to conference_tickets_path(conference_with_open_registration.short_title) + end + + it 'creates a new registration' do + expect(Registration.count).to eq 1 + end + end + + context 'registration save fails' do + before do + allow_any_instance_of(Registration).to receive(:save).and_return(false) + post :create, registration: attributes_for(:registration), + conference_id: conference_with_open_registration.short_title + end + + it 'renders the new template' do + expect(response).to render_template('new') + end + + it 'does not create registration' do + expect(Registration.count).to eq 0 + end + end + end + + describe 'PATCH #update' do + before do + @registration = create(:registration, + conference: conference_with_open_registration, + user: user, + arrival: Date.new(2014, 04, 25)) + end + + context 'updates successfully' do + before do + patch :update, registration: attributes_for(:registration, arrival: Date.new(2014, 04, 29)), + conference_id: conference_with_open_registration.short_title + end + + it 'redirects to registration show path' do + expect(response).to redirect_to conference_conference_registrations_path(conference_with_open_registration.short_title) + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match('Registration was successfully updated.') + end + + it 'updates the registration' do + @registration.reload + expect(@registration.arrival).to eq Date.new(2014, 04, 29) + end + end + + context 'update fails' do + before do + allow_any_instance_of(Registration).to receive(:update_attributes).and_return(false) + patch :update, registration: attributes_for(:registration, arrival: Date.new(2014, 04, 27)), + conference_id: conference_with_open_registration.short_title + end + + it 'renders edit template' do + expect(response).to render_template('edit') + end + + it 'shows error in flash message' do + expect(flash[:error]).to include 'Could not update your registration' + end + + it 'does not update the registration' do + @registration.reload + expect(@registration.arrival).to eq Date.new(2014, 04, 25) + end + end + end + + describe 'DELETE #destroy' do + before do + @registration = create(:registration, conference: conference_with_open_registration, user: user) + end + + context 'deletes successfully' do + before do + delete :destroy, conference_id: conference_with_open_registration.short_title + end + + it 'redirects to root path' do + expect(response).to redirect_to root_path + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match("You are not registered for #{conference_with_open_registration.title} anymore!") + end + + it 'deletes the registration' do + expect(Registration.count).to eq 0 + end + end + + context 'delete fails' do + before do + allow_any_instance_of(Registration).to receive(:destroy).and_return(false) + delete :destroy, conference_id: conference_with_open_registration.short_title + end + + it 'redirects to registration show path' do + expect(response).to redirect_to conference_conference_registrations_path(conference_with_open_registration.short_title) + end + + it 'shows error in flash message' do + expect(flash[:error]).to include 'Could not delete your registration' + end + + it 'does not delete the registration' do + expect(Registration.last).to eq @registration + end + end + end + end +end diff --git a/spec/factories/registration.rb b/spec/factories/registration.rb index fb79cb4d..6debd8ae 100644 --- a/spec/factories/registration.rb +++ b/spec/factories/registration.rb @@ -4,5 +4,6 @@ FactoryGirl.define do factory :registration do user conference + arrival 3.days.ago end end diff --git a/spec/features/conference_registration_spec.rb b/spec/features/conference_registration_spec.rb index 3084e9d0..6fa644fe 100644 --- a/spec/features/conference_registration_spec.rb +++ b/spec/features/conference_registration_spec.rb @@ -1,6 +1,7 @@ require 'spec_helper' feature Registration do + let!(:first_user) { create(:user) } # first user is admin let!(:conference) { create(:conference, registration_period: create(:registration_period, start_date: 3.days.ago)) } let!(:participant) { create(:user) } @@ -28,13 +29,29 @@ feature Registration do expect(conference.user_registered?(participant)).to be(true) end - scenario 'unregisters for a conference', feature: true, js: true do - visit root_path - click_link 'My Registration' - expect(current_path).to eq(conference_conference_registrations_path(conference.short_title)) + context 'unregisters for a conference', feature: true, js: true do + before do + visit root_path + click_link 'My Registration' + end - click_link 'Unregister' - expect(conference.user_registered?(participant)).to be(false) + scenario 'deletion of registration is successful' do + expect(current_path).to eq(conference_conference_registrations_path(conference.short_title)) + + click_link 'Unregister' + expect(conference.user_registered?(participant)).to be(false) + expect(current_path).to eq root_path + expect(flash).to eq "You are not registered for #{conference.title} anymore!" + end + + scenario 'deletion of registration is unsuccessful' do + allow_any_instance_of(Registration).to receive(:destroy).and_return(false) + + click_link 'Unregister' + expect(conference.user_registered?(participant)).to be(true) + expect(current_path).to eq conference_conference_registrations_path(conference.short_title) + expect(flash).to eq "Could not delete your registration for #{conference.title}: #{registration.errors.full_messages.join('. ')}." + end end end @@ -54,7 +71,6 @@ feature Registration do let(:conference_with_closed_registration) { create(:conference, registration_period: create(:registration_period)) } scenario 'registers for a conference', feature: true do - participant.is_admin = false visit new_conference_conference_registrations_path(conference_with_closed_registration.short_title) expect(current_path).to eq(root_path) expect(flash).to eq 'You are not authorized to access this page.' From 7e4d91adaf7d112ee9f097f0466016a186200355 Mon Sep 17 00:00:00 2001 From: Aditya Prakash Date: Sat, 12 Mar 2016 17:46:50 +0530 Subject: [PATCH 4/5] Improvements in registration specs Check for true and not truthy in registration model spec. Cover general cases in conf registration controller. Add test for flash in new action when ichain is set and user is not signed in. --- ...conference_registration_controller_spec.rb | 121 +++++++++++++----- spec/features/conference_registration_spec.rb | 2 +- spec/models/registration_spec.rb | 2 +- 3 files changed, 88 insertions(+), 37 deletions(-) diff --git a/spec/controllers/conference_registration_controller_spec.rb b/spec/controllers/conference_registration_controller_spec.rb index 78870f25..e00e37af 100644 --- a/spec/controllers/conference_registration_controller_spec.rb +++ b/spec/controllers/conference_registration_controller_spec.rb @@ -9,6 +9,22 @@ describe ConferenceRegistrationsController, type: :controller do context 'user is not signed in' do describe 'GET #new' do + context 'ichain is disabled' do + before do + get :new, conference_id: conference_with_open_registration.short_title + end + + it 'assigns conference, registration and user variable' do + expect(assigns(:conference)).to eq conference_with_open_registration + expect(assigns(:registration)).to be_instance_of Registration + expect(assigns(:user)).to be_instance_of User + end + + it 'renders the new template' do + expect(response).to render_template('new') + end + end + context 'ichain is enabled' do before do CONFIG['authentication']['ichain']['enabled'] = true @@ -20,6 +36,10 @@ describe ConferenceRegistrationsController, type: :controller do it 'redirects to root path' do expect(response).to redirect_to root_path end + + it 'shows error in flash message' do + expect(flash[:alert]).to match 'You are not authorized to access this page. Maybe you need to sign in?' + end end end @@ -56,6 +76,21 @@ describe ConferenceRegistrationsController, type: :controller do before { sign_in(user) } describe 'GET #new' do + context 'successful request' do + before do + get :new, conference_id: conference_with_open_registration.short_title + end + + it 'assigns registration and user variables' do + expect(assigns(:registration)).to be_instance_of(Registration) + expect(assigns(:user)).to be_instance_of(User) + end + + it 'renders the new template' do + expect(response).to render_template('new') + end + end + context 'user is registered to conference' do before do create(:registration, user: user, conference: conference_with_open_registration) @@ -82,21 +117,6 @@ describe ConferenceRegistrationsController, type: :controller do expect(flash[:alert]).to match "Sorry, registration limit exceeded for #{conference_with_open_registration.title}" end end - - context 'successful request' do - before do - get :new, conference_id: conference_with_open_registration.short_title - end - - it 'assigns registration and user variables' do - expect(assigns(:registration)).to be_instance_of(Registration) - expect(assigns(:user)).to be_instance_of(User) - end - - it 'renders the new template' do - expect(response).to render_template('new') - end - end end describe 'GET #show' do @@ -104,6 +124,22 @@ describe ConferenceRegistrationsController, type: :controller do @registration = create(:registration, conference: conference_with_open_registration, user: user) end + context 'successful request' do + before do + get :show, conference_id: conference_with_open_registration.short_title + end + + it 'assigns conference, registration and workshops variables' do + expect(assigns(:conference)).to eq conference_with_open_registration + expect(assigns(:registration)).to eq @registration + expect(assigns(:workshops)).to eq @registration.workshops + end + + it 'renders the show template' do + expect(response).to render_template('show') + end + end + context 'user has purchased a ticket' do before do @ticket = create(:ticket, conference: conference_with_open_registration) @@ -113,14 +149,6 @@ describe ConferenceRegistrationsController, type: :controller do get :show, conference_id: conference_with_open_registration.short_title end - it 'renders the show template' do - expect(response).to render_template('show') - end - - it 'assigns workshops variable' do - expect(assigns(:workshops)).to eq @registration.workshops - end - it 'assigns price of purchased tickets to total_price and purchased tickets to tickets' do expect(assigns(:total_price)).to eq Money.new(10000, 'USD') expect(assigns(:tickets)).to match_array [@purchased_ticket] @@ -141,33 +169,56 @@ describe ConferenceRegistrationsController, type: :controller do describe 'GET #edit' do before do - create(:registration, conference: conference_with_open_registration, user: user) + @registration = create(:registration, conference: conference_with_open_registration, user: user) get :edit, conference_id: conference_with_open_registration.short_title end + it 'assigns conference and registration variable' do + expect(assigns(:conference)).to eq conference_with_open_registration + expect(assigns(:registration)).to eq @registration + end + it 'renders the edit template' do expect(response).to render_template('edit') end end describe 'POST #create' do - context "tickets are available and user hasn't bought any" do + context 'successfully registers' do + it 'assigns user variable' do + post :create, registration: attributes_for(:registration), + conference_id: conference_with_open_registration.short_title + expect(assigns(:user)).to eq user + end + + it 'creates a new registration' do + expect do + post :create, registration: attributes_for(:registration), + conference_id: conference_with_open_registration.short_title + end.to change{ Registration.count }.by 1 + end + end + + context 'tickets are available' do before do create(:ticket, conference: conference_with_open_registration) post :create, registration: attributes_for(:registration), conference_id: conference_with_open_registration.short_title end - it 'assigns user variable' do - expect(assigns(:user)).to eq user - end - it 'redirects to conference tickets path' do expect(response).to redirect_to conference_tickets_path(conference_with_open_registration.short_title) end + end - it 'creates a new registration' do - expect(Registration.count).to eq 1 + context 'tickets are not available' do + before do + post :create, registration: attributes_for(:registration), + conference_id: conference_with_open_registration.short_title + end + + it 'redirects to registration show path' do + expect(response).to redirect_to conference_conference_registrations_path(conference_with_open_registration.short_title) end end @@ -228,7 +279,7 @@ describe ConferenceRegistrationsController, type: :controller do end it 'shows error in flash message' do - expect(flash[:error]).to include 'Could not update your registration' + expect(flash[:error]).to match "Could not update your registration for The dog and pony show: #{@registration.errors.full_messages.join('. ')}." end it 'does not update the registration' do @@ -253,7 +304,7 @@ describe ConferenceRegistrationsController, type: :controller do end it 'shows success message in flash notice' do - expect(flash[:notice]).to match("You are not registered for #{conference_with_open_registration.title} anymore!") + expect(flash[:notice]).to match('You are not registered for The dog and pony show anymore!') end it 'deletes the registration' do @@ -272,11 +323,11 @@ describe ConferenceRegistrationsController, type: :controller do end it 'shows error in flash message' do - expect(flash[:error]).to include 'Could not delete your registration' + expect(flash[:error]).to match "Could not delete your registration for The dog and pony show: #{@registration.errors.full_messages.join('. ')}." end it 'does not delete the registration' do - expect(Registration.last).to eq @registration + expect(assigns(:registration)).to eq @registration end end end diff --git a/spec/features/conference_registration_spec.rb b/spec/features/conference_registration_spec.rb index 6fa644fe..ff7f000d 100644 --- a/spec/features/conference_registration_spec.rb +++ b/spec/features/conference_registration_spec.rb @@ -41,7 +41,7 @@ feature Registration do click_link 'Unregister' expect(conference.user_registered?(participant)).to be(false) expect(current_path).to eq root_path - expect(flash).to eq "You are not registered for #{conference.title} anymore!" + expect(flash).to eq 'You are not registered for The dog and pony show anymore!' end scenario 'deletion of registration is unsuccessful' do diff --git a/spec/models/registration_spec.rb b/spec/models/registration_spec.rb index d9ea534f..cf87466b 100644 --- a/spec/models/registration_spec.rb +++ b/spec/models/registration_spec.rb @@ -59,7 +59,7 @@ describe Registration do describe '#subscribe_to_conference' do it 'subscribes to conference' do expect(subject).to receive(:subscribe_to_conference) - expect(subject.user.subscribed?(subject.conference)).to be_truthy + expect(subject.user.subscribed?(subject.conference)).to be true end end From 7822a8d4e31ba9e182f280944ae4053ca247dd23 Mon Sep 17 00:00:00 2001 From: Aditya Prakash Date: Mon, 14 Mar 2016 23:38:55 +0530 Subject: [PATCH 5/5] Do not allow signed in users to registor unless registration is open --- app/models/ability.rb | 4 ++++ spec/models/ability_spec.rb | 12 +++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/app/models/ability.rb b/app/models/ability.rb index c20ddfc0..dd80ef6b 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -72,6 +72,10 @@ class Ability can :manage, Registration, user_id: user.id + can [:new, :create], Registration do |registration| + registration.conference.registration_open? + end + can :index, Ticket can :manage, TicketPurchase, user_id: user.id diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index dd389545..f9fdd6c8 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -33,13 +33,13 @@ describe 'User' do let(:registration) { create(:registration) } + let(:conference_with_open_registration) { create(:conference) } + let!(:open_registration_period) { create(:registration_period, conference: conference_with_open_registration, start_date: Date.current - 6.days) } + let(:conference_with_closed_registration) { create(:conference) } + let!(:closed_registration_period) { create(:registration_period, conference: conference_with_closed_registration, start_date: Date.current - 6.days, end_date: Date.current - 6.days) } + # Test abilities for not signed in users context 'when user is not signed in' do - let(:conference_with_open_registration) { create(:conference) } - let!(:open_registration_period) { create(:registration_period, conference: conference_with_open_registration, start_date: Date.current - 6.days) } - let(:conference_with_closed_registration) { create(:conference) } - let!(:closed_registration_period) { create(:registration_period, conference: conference_with_closed_registration, start_date: Date.current - 6.days, end_date: Date.current - 6.days) } - it{ should be_able_to(:index, Conference)} it{ should be_able_to(:show, conference_public)} @@ -88,6 +88,8 @@ describe 'User' do it{ should be_able_to(:manage, registration_public) } it{ should be_able_to(:manage, registration_not_public) } + it{ should_not be_able_to(:new, Registration.new(conference_id: conference_with_closed_registration.id))} + it{ should_not be_able_to(:create, Registration.new(conference_id: conference_with_closed_registration.id))} it{ should be_able_to(:index, Ticket) } it{ should be_able_to(:manage, TicketPurchase.new(user_id: user.id)) }