diff --git a/Gemfile b/Gemfile index f69b180..2d3b7c3 100644 --- a/Gemfile +++ b/Gemfile @@ -55,6 +55,8 @@ group :development, :test do # Run tests gem 'rspec-rails', '~> 6.0.1' + + gem 'rails-controller-testing', '~> 1.0.5' end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index 54885c4..64bb9db 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -251,6 +251,10 @@ GEM activesupport (= 7.0.6) bundler (>= 1.15.0) railties (= 7.0.6) + rails-controller-testing (1.0.5) + actionpack (>= 5.0.1.rc1) + actionview (>= 5.0.1.rc1) + activesupport (>= 5.0.1.rc1) rails-dom-testing (2.2.0) activesupport (>= 5.0.0) minitest @@ -423,6 +427,7 @@ DEPENDENCIES pundit (>= 2.3.0) rack-mini-profiler (~> 2.0) rails (~> 7.0) + rails-controller-testing (~> 1.0.5) rspec-rails (~> 6.0.1) rubocop (~> 1.22) sassc-rails (~> 2.1.2) diff --git a/app/controllers/admin/events_controller.rb b/app/controllers/admin/events_controller.rb index adc8e58..a218434 100644 --- a/app/controllers/admin/events_controller.rb +++ b/app/controllers/admin/events_controller.rb @@ -66,10 +66,15 @@ def generate_talk @talk.id = params[:talk_id] if params[:talk_id] != 'create_talk' if @talk.valid? - render 'admin/events/form/_card_talk_new', locals: { talk: @talk, talk_id: talk_id } + render 'admin/events/form/_card_talk_new', + locals: { + talk: @talk, + talk_id: talk_id, + }, + formats: [:turbo_stream] else @url = generate_talk_admin_events_path(talk_id: talk_id) - render :set_talk, status: :bad_request + render :set_talk, status: :bad_request, formats: [:turbo_stream] end end diff --git a/spec/controllers/admin/events_controller_spec.rb b/spec/controllers/admin/events_controller_spec.rb index 9f2ea52..c3803f0 100644 --- a/spec/controllers/admin/events_controller_spec.rb +++ b/spec/controllers/admin/events_controller_spec.rb @@ -13,7 +13,7 @@ end context 'when user is not admin' do - let(:user) { FactoryBot.create(:user) } + let(:user) { create(:user) } before { sign_in user } it 'returns 401' do @@ -23,7 +23,7 @@ end context 'when user is admin' do - let(:user) { FactoryBot.create(:user, :admin) } + let(:user) { create(:user, :admin) } before { sign_in user } it 'returns 200' do @@ -35,7 +35,7 @@ describe 'GET #edit' do context 'when user is not authenticated' do - let(:event) { FactoryBot.create(:event) } + let(:event) { create(:event) } it 'returns 302' do get :edit, params: { id: event.id } @@ -45,9 +45,9 @@ end context 'when user is not admin' do - let(:user) { FactoryBot.create(:user) } + let(:user) { create(:user) } before { sign_in user } - let(:event) { FactoryBot.create(:event) } + let(:event) { create(:event) } it 'returns 401' do get :edit, params: { id: event.id } @@ -56,9 +56,9 @@ end context 'when user is admin' do - let(:user) { FactoryBot.create(:user, :admin) } + let(:user) { create(:user, :admin) } before { sign_in user } - let(:event) { FactoryBot.create(:event) } + let(:event) { create(:event) } it 'returns 200' do get :edit, params: { id: event.id } @@ -69,7 +69,7 @@ describe 'PUT #update' do context 'when user is not authenticated' do - let(:event) { FactoryBot.create(:event) } + let(:event) { create(:event) } it 'returns 302' do put :update, params: { id: event.id } @@ -79,9 +79,9 @@ end context 'when user is not admin' do - let(:user) { FactoryBot.create(:user) } + let(:user) { create(:user) } before { sign_in user } - let(:event) { FactoryBot.create(:event) } + let(:event) { create(:event) } it 'returns 401' do post :update, params: { id: event.id } @@ -90,9 +90,9 @@ end context 'when user is admin' do - let(:user) { FactoryBot.create(:user, role: User::ADMIN) } + let(:user) { create(:user, role: User::ADMIN) } before { sign_in user } - let(:event) { FactoryBot.create(:event) } + let(:event) { create(:event) } it 'returns 302' do post :update, params: { id: event.id, event: { description: 'Great event' } } @@ -121,7 +121,7 @@ end context 'when user is not admin' do - let(:user) { FactoryBot.create(:user) } + let(:user) { create(:user) } before { sign_in user } it 'returns 401' do @@ -132,7 +132,7 @@ end context 'when user is admin' do - let(:user) { FactoryBot.create(:user, :admin) } + let(:user) { create(:user, :admin) } before { sign_in user } it 'returns 302' do @@ -196,4 +196,129 @@ end end end + + describe 'GET #set_talk' do + context 'when user is not authenticated' do + it 'returns 302' do + get :set_talk, params: { talk_id: 'new_talk' } + expect(response).to have_http_status(302) + expect(response).to redirect_to(new_user_session_path) + end + end + + context 'when user is not admin' do + let(:user) { create(:user) } + before { sign_in user } + + it 'returns 401' do + get :set_talk, params: { talk_id: 'new_talk' } + expect(response).to have_http_status(401) + end + end + + context 'when user is admin' do + let(:user) { create(:user, :admin) } + before { sign_in user } + + context 'when talk_id is new_talk' do + it 'assigns a new Talk object to @talk' do + get :set_talk, params: { talk_id: 'new_talk' }, format: :turbo_stream + expect(controller.instance_variable_get(:@talk)).to be_a_new(Talk) + end + + it 'assigns the correct URL to @url' do + get :set_talk, params: { talk_id: 'new_talk' }, format: :turbo_stream + expect(controller.instance_variable_get(:@url)).to eq( + generate_talk_admin_events_path(talk_id: 'create_talk'), + ) + end + end + + context 'when talk_id is not new_talk' do + let!(:talk) { create(:talk, :with_event) } + before do + params = + ActionController::Parameters.new( + { + event: { + talks_attributes: { + talk.id.to_s => { + _destroy: false, + id: talk.id, + speaker_id: talk.speaker.id, + event_id: talk.event.id, + }, + }, + }, + talk_id: talk.id.to_s, + }, + ) + allow(controller).to receive(:params).and_return(params) + end + + it 'assigns an existing Talk object to @talk' do + get :set_talk, params: { talk_id: talk.id }, format: :turbo_stream + expect(controller.instance_variable_get(:@talk)).to eq(talk) + end + + it 'assigns the correct URL to @url' do + get :set_talk, params: { talk_id: talk.id }, format: :turbo_stream + expect(controller.instance_variable_get(:@url)).to eq( + generate_talk_admin_events_path(talk_id: talk.id), + ) + end + end + end + end + + describe 'POST #generate_talk' do + let(:talk) { instance_double(Talk) } + let(:talk_params) { { foo: 'bar' } } + let(:user) { create(:user, :admin) } + + before do + sign_in user + allow(Talk).to receive(:new).and_return(talk) + allow(talk).to receive(:object_id).and_return(123) + allow(controller).to receive(:generate_talk_admin_events_path).and_return( + '/admin/events/generate_talk', + ) + end + + context 'when talk is valid' do + before do + allow(controller).to receive(:talk_params).and_return(talk_params) + allow(talk).to receive(:valid?).and_return(true) + allow(talk).to receive(:id=) + end + + it 'renders the _card_talk_new template' do + post :generate_talk, params: { talk_params: talk_params, talk_id: 'example_talk_id' } + expect(response).to render_template('admin/events/form/_card_talk_new') + end + + it 'returns a ok status' do + post :generate_talk, params: { talk_params: talk_params, talk_id: 'example_talk_id' } + expect(response).to have_http_status(:ok) + end + end + + context 'when talk is not valid' do + before do + allow(controller).to receive(:talk_params).and_return(talk_params) + allow(talk).to receive(:valid?).and_return(false) + allow(talk).to receive(:id=) + end + + it 'renders the set_talk template' do + post :generate_talk, params: { talk_params: talk_params, talk_id: 'example_talk_id' } + expect(response).to render_template('admin/events/set_talk') + end + + it 'returns a bad_request status' do + post :generate_talk, params: { talk_params: talk_params, talk_id: 'example_talk_id' } + expect(response).to have_http_status(:bad_request) + end + end + end end diff --git a/spec/factories/talks.rb b/spec/factories/talks.rb index 1e2b851..e416795 100644 --- a/spec/factories/talks.rb +++ b/spec/factories/talks.rb @@ -7,7 +7,15 @@ talk_description { Faker::Lorem.paragraph } trait :with_event do - association :event + before(:create) do |talk| + event = create(:event) + event.talks << talk + end + + before(:build) do |talk| + event = build(:event) + event.talks << talk + end end end end diff --git a/spec/support/should_marchers.rb b/spec/support/should_marchers.rb index 7d045f3..edcf9dd 100644 --- a/spec/support/should_marchers.rb +++ b/spec/support/should_marchers.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Shoulda::Matchers.configure do |config| config.integrate do |with| with.test_framework :rspec