diff --git a/app/controllers/admin/targets_controller.rb b/app/controllers/admin/targets_controller.rb index 6f73dc0a..d15d5726 100644 --- a/app/controllers/admin/targets_controller.rb +++ b/app/controllers/admin/targets_controller.rb @@ -3,9 +3,7 @@ module Admin load_and_authorize_resource :conference, find_by: :short_title load_and_authorize_resource :target, through: :conference - def index - authorize! :update, Target.new(conference_id: @conference.id) - end + def index; end def new @target = @conference.targets.new @@ -39,9 +37,9 @@ module Admin redirect_to(admin_conference_targets_path(conference_id: @conference.short_title), notice: 'Target successfully destroyed.') else - redirect_to(admin_conference_targets_path(conference_id: @conference.short_title), - error: 'Target was successfully destroyed.' \ - "#{@target.errors.full_messages.join('. ')}.") + redirect_to admin_conference_targets_path(conference_id: @conference.short_title), + flash: { error: "Could not delete target for #{@conference.title}: "\ + "#{@target.errors.full_messages.join('. ')}." } end end diff --git a/app/models/target.rb b/app/models/target.rb index a1b496a2..ea91b38a 100644 --- a/app/models/target.rb +++ b/app/models/target.rb @@ -64,7 +64,7 @@ class Target < ActiveRecord::Base 'unit' => unit, 'created_at' => created_at, 'progress' => progress, - 'days_left' => days_left, + 'days_left' => days_left } result end diff --git a/spec/controllers/admin/targets_controller_spec.rb b/spec/controllers/admin/targets_controller_spec.rb new file mode 100644 index 00000000..2b8b5dd4 --- /dev/null +++ b/spec/controllers/admin/targets_controller_spec.rb @@ -0,0 +1,168 @@ +require 'spec_helper' + +describe Admin::TargetsController, type: :controller do + let(:admin) { create(:admin) } + let(:conference) { create(:conference) } + let(:target) { create(:target, conference: conference, target_count: 100) } + + context 'user is admin' do + before { sign_in admin } + + describe 'GET #index' do + before { get :index, conference_id: conference.short_title } + + it 'renders index template' do + expect(response).to render_template('index') + end + + it 'assigns targets and conference variables' do + expect(assigns(:conference)).to eq conference + expect(assigns(:targets)).to eq [target] + end + end + + describe 'GET #new' do + before { get :new, conference_id: conference.short_title } + + it 'renders new template' do + expect(response).to render_template('new') + end + + it 'assigns target variable' do + expect(assigns(:target)).to be_instance_of(Target) + end + end + + describe 'POST #create' do + context 'saves successfuly' do + before do + post :create, target: attributes_for(:target), conference_id: conference.short_title + end + + it 'redirects to admin target index path' do + expect(response).to redirect_to admin_conference_targets_path(conference_id: conference.short_title) + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match('Target successfully created.') + end + + it 'creates new target' do + expect(Target.count).to eq 1 + end + end + + context 'save fails' do + before do + allow_any_instance_of(Target).to receive(:save).and_return(false) + post :create, target: attributes_for(:target), conference_id: conference.short_title + end + + it 'renders new template' do + expect(response).to render_template('new') + end + + it 'shows error in flash message' do + expect(flash[:error]).to match("Creating target failed: #{target.errors.full_messages.join('. ')}.") + end + + it 'does not create new target' do + expect(Target.count).to eq 0 + end + end + end + + describe 'GET #edit' do + before { get :edit, conference_id: conference.short_title, id: target.id } + + it 'renders edit template' do + expect(response).to render_template('edit') + end + + it 'assigns target variable' do + expect(assigns(:target)).to eq target + end + end + + describe 'PATCH #update' do + context 'updates successfully' do + before do + patch :update, target: attributes_for(:target, target_count: 2), + conference_id: conference.short_title, + id: target.id + end + + it 'redirects to admin target index path' do + expect(response).to redirect_to admin_conference_targets_path(conference_id: conference.short_title) + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match('Target successfully updated.') + end + + it 'updates the target' do + target.reload + expect(target.target_count).to eq 2 + end + end + + context 'update fails' do + before do + allow_any_instance_of(Target).to receive(:save).and_return(false) + patch :update, target: attributes_for(:target, target_count: 2), + conference_id: conference.short_title, + id: target.id + end + + it 'renders edit template' do + expect(response).to render_template('edit') + end + + it 'shows error in flash message' do + expect(flash[:error]).to match("Target update failed: #{target.errors.full_messages.join('. ')}.") + end + + it 'does not update target' do + expect(target.target_count).to eq 100 + end + end + end + + describe 'DELETE #destroy' do + context 'deletes successfully' do + before { delete :destroy, conference_id: conference.short_title, id: target.id } + + it 'redirects to admin target index path' do + expect(response).to redirect_to admin_conference_targets_path(conference_id: conference.short_title) + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match('Target successfully destroyed.') + end + + it 'deletes target' do + expect(Target.count).to eq 0 + end + end + + context 'delete fails' do + before do + allow_any_instance_of(Target).to receive(:destroy).and_return(false) + delete :destroy, conference_id: conference.short_title, id: target.id + end + + it 'redirects to admin target index path' do + expect(response).to redirect_to admin_conference_targets_path(conference_id: conference.short_title) + end + + it 'shows error in flash message' do + expect(flash[:error]).to match("Could not delete target for #{conference.title}: #{target.errors.full_messages.join('. ')}.") + end + + it 'does not delete target' do + expect(Target.count).to eq 1 + end + end + end + end +end diff --git a/spec/models/target_spec.rb b/spec/models/target_spec.rb index 50a4103f..5297cabc 100644 --- a/spec/models/target_spec.rb +++ b/spec/models/target_spec.rb @@ -1,8 +1,11 @@ require 'spec_helper' describe Target do + let(:registration_target) { create(:target, target_count: 10, unit: Target.units[:registrations]) } + let(:submission_target) { create(:target, target_count: 10, unit: Target.units[:submissions]) } + let(:program_minutes_target) { create(:target, target_count: 300, unit: Target.units[:program_minutes]) } - describe 'validations' do + describe 'validation' do it 'has a valid factory' do expect(build(:target)).to be_valid end @@ -32,74 +35,130 @@ describe Target do end end + describe 'default scope' do + before do + @first_target = create(:target, due_date: 2.days.from_now) + @second_target = create(:target, due_date: 3.days.from_now) + end + + it 'orders by ascending due_date' do + expect(Target.all).to match_array [@first_target, @second_target] + end + end + + describe 'association' do + it { should belong_to(:conference) } + it { should belong_to(:campaign) } + end + describe '#get_progress' do - it 'returns zero if there are no registrations' do - conference = build(:conference) - target = build(:target, target_count: 10, unit: Target.units[:registrations]) - conference.targets = [target] - - expect(target.get_progress).to eq('0') + it 'returns zero, when there are no registrations' do + expect(registration_target.get_progress).to eq('0') end - it 'returns 10 if there one registrations of 10' do - conference = create(:conference) - target = create(:target, target_count: 10, unit: Target.units[:registrations]) - registration = create(:registration) + it 'returns 10, when there is 1 registration and the target is 10' do + create(:registration, conference: registration_target.conference) - conference.targets = [target] - conference.registrations = [registration] - - expect(target.get_progress).to eq('10') + expect(registration_target.get_progress).to eq('10') end - it 'returns zero if there are no submissions' do - conference = create(:conference) - target = build(:target, target_count: 10, unit: Target.units[:submissions]) - conference.targets = [target] - - expect(target.get_progress).to eq('0') + it 'returns zero, when there are no submissions' do + expect(submission_target.get_progress).to eq('0') end - it 'returns 10 if there one submissions of 10' do - conference = create(:conference) - target = create(:target, target_count: 10, unit: Target.units[:submissions]) - event = create(:event) + it 'returns 10, when there is 1 submission and the target is 10' do + create(:event, program: submission_target.conference.program) - conference.targets = [target] - conference.program.events = [event] - - expect(target.get_progress).to eq('10') + expect(submission_target.get_progress).to eq('10') end - it 'returns zero if there are no program minutes' do - conference = create(:conference) - target = build(:target, target_count: 10, unit: Target.units[:program_minutes]) - conference.targets = [target] - - expect(target.get_progress).to eq('0') + it 'returns zero, when there are no program minutes' do + expect(program_minutes_target.get_progress).to eq('0') end - it 'returns 10 if there are 30 program minutes of 300' do - conference = create(:conference) - target = create(:target, target_count: 300, unit: Target.units[:program_minutes]) - event = create(:event) + it 'returns 10, when there are 30 program minutes and the target is 300' do + create(:event, program: program_minutes_target.conference.program) - conference.targets = [target] - conference.program.events = [event] + expect(program_minutes_target.get_progress).to eq('10') + end + end - expect(target.get_progress).to eq('10') + describe '#get_campaign' do + context 'submissions' do + before do + submission_target.campaign = create(:campaign, name: 'Submission Campaign', conference: submission_target.conference) + submission_target.created_at = Time.utc(2014, 5, 10) + submission_target.due_date = Date.today + 4.days + allow(submission_target.campaign).to receive(:submissions_count) { 20 } + end + + it 'returns a hash with values of the corresponding campaign submissions' do + result = { + 'target_name' => "10 Submissions by #{Date.today + 4.days}", + 'campaign_name' => 'Submission Campaign', + 'value' => 20, + 'unit' => 'Submission', + 'created_at' => Time.utc(2014, 5, 10).in_time_zone, + 'progress' => '200', + 'days_left' => 4 + } + + expect(submission_target.get_campaign).to eq result + end + end + + context 'registrations' do + before do + registration_target.campaign = create(:campaign, name: 'Registration Campaign', conference: registration_target.conference) + registration_target.created_at = Time.utc(2014, 5, 10) + registration_target.due_date = Date.today + 4.days + allow(registration_target.campaign).to receive(:registrations_count) { 20 } + end + + it 'returns a hash with values of the corresponding campaign registrations' do + result = { + 'target_name' => "10 Registrations by #{Date.today + 4.days}", + 'campaign_name' => 'Registration Campaign', + 'value' => 20, + 'unit' => 'Registration', + 'created_at' => Time.utc(2014, 5, 10).in_time_zone, + 'progress' => '200', + 'days_left' => 4 + } + + expect(registration_target.get_campaign).to eq result + end + end + + context 'program_minutes' do + before do + program_minutes_target.campaign = create(:campaign, name: 'Program Campaign', conference: program_minutes_target.conference) + program_minutes_target.created_at = Time.utc(2014, 5, 10) + program_minutes_target.due_date = Date.today + 4.days + allow(program_minutes_target.conference).to receive(:current_program_minutes) { 20 } + end + + it 'returns a hash with values of the corresponding campaign program minutes' do + result = { + 'target_name' => "300 Program minutes by #{Date.today + 4.days}", + 'campaign_name' => 'Program Campaign', + 'value' => 20, + 'unit' => 'Program minute', + 'created_at' => Time.utc(2014, 5, 10).in_time_zone, + 'progress' => '7', + 'days_left' => 4 + } + + expect(program_minutes_target.get_campaign).to eq result + end end end describe '#to_s' do it 'returns a string in the correct format' do - conference = build(:conference) - target = build(:target, target_count: 10, unit: Target.units[:registrations]) - conference.targets = [target] - result = "10 Registrations by #{14.days.from_now.to_date}" - expect(target.to_s).to eq(result) + expect(registration_target.to_s).to eq(result) end end end