diff --git a/Gemfile.lock b/Gemfile.lock index bc8d511..0e97018 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -82,6 +82,8 @@ GEM rack (>= 3.0.0, < 4) rack-session (2.0.0) rack (>= 3.0.0) + rack-test (2.1.0) + rack (>= 1.3) rackup (2.2.1) rack (>= 3) rainbow (3.1.1) @@ -166,6 +168,7 @@ DEPENDENCIES pry-byebug (~> 3.0) puma (~> 6.5) rack-flash3 (~> 1.0) + rack-test (~> 2.1) rackup (~> 2.0) rake (~> 13.0) rerun (~> 0.0) diff --git a/config.ru b/config.ru index 72a77d3..79b717a 100644 --- a/config.ru +++ b/config.ru @@ -8,6 +8,7 @@ require 'sidekiq' require 'sidekiq/web' require 'outboxer/web' +require_relative 'app/models/application_record' require_relative 'app/models/event' use Rack::Session::Cookie, secret: ENV['SESSION_SECRET'], same_site: true, max_age: 86400 diff --git a/lib/outboxer/web.rb b/lib/outboxer/web.rb index 5dd3739..78a4227 100755 --- a/lib/outboxer/web.rb +++ b/lib/outboxer/web.rb @@ -38,7 +38,10 @@ module Outboxer class Web < Sinatra::Base + enable :sessions + use Rack::Flash + set :logger, Logger.new($stdout) set :views, File.expand_path('../web/views', __FILE__) set :public_folder, File.expand_path('../web/public', __FILE__) @@ -523,7 +526,7 @@ def normalise_query_string(status: Messages::LIST_STATUS_DEFAULT, time_zone: denormalised_query_params[:time_zone]) result = Messages.requeue_all( - status: denormalised_query_params[:status], older_than: Time.now.utc) + status: denormalised_query_params[:status]) message_text = result[:requeued_count] == 1 ? 'message' : 'messages' flash[:primary] = "#{result[:requeued_count]} #{message_text} have been queued" diff --git a/outboxer.gemspec b/outboxer.gemspec index 1c3d17f..fc87d60 100644 --- a/outboxer.gemspec +++ b/outboxer.gemspec @@ -33,6 +33,7 @@ Gem::Specification.new do |spec| spec.add_dependency "activerecord", ">= 7.0.8.6" + spec.add_development_dependency "rack-test", "~> 2.1" spec.add_development_dependency "database_cleaner", "~> 2.0" spec.add_development_dependency "dotenv", "~> 3.0" spec.add_development_dependency "factory_bot", "~> 6.0" diff --git a/spec/factories/outboxer_publishers.rb b/spec/factories/outboxer_publishers.rb index bc9196d..d93ecbf 100644 --- a/spec/factories/outboxer_publishers.rb +++ b/spec/factories/outboxer_publishers.rb @@ -15,9 +15,9 @@ { 'throughput' => 1000, 'latency' => 0, - 'cpu' => '10.5%', - 'rss' => '40.95 MB', - 'rtt' => '3.35 ms' + 'cpu' => 10.5, + 'rss' => 40.95, + 'rtt' => 3.35 } } created_at { DateTime.parse("2024-11-10T00:00:00") } diff --git a/spec/lib/outboxer/web/home_spec.rb b/spec/lib/outboxer/web/home_spec.rb new file mode 100644 index 0000000..f0d5173 --- /dev/null +++ b/spec/lib/outboxer/web/home_spec.rb @@ -0,0 +1,39 @@ +require 'spec_helper' + +require_relative "../../../../lib/outboxer/web" + +RSpec.describe 'GET /', type: :request do + include Rack::Test::Methods + + def app + Outboxer::Web + end + + context 'when there are no publishers' do + before do + header 'Host', 'localhost' + + get '/' + end + + it "doesn't show any publishers" do + expect(last_response).to be_ok + expect(last_response.body).to include('There are no publishers to display') + end + end + + context 'when there is a publisher' do + let!(:publisher) { create(:outboxer_publisher, :publishing, name: 'localhost:14325') } + + before do + header 'Host', 'localhost' + + get '/' + end + + it "shows publisher" do + expect(last_response).to be_ok + expect(last_response.body).to include(publisher.name) + end + end +end diff --git a/spec/lib/outboxer/web/message/delete_spec.rb b/spec/lib/outboxer/web/message/delete_spec.rb new file mode 100644 index 0000000..4721c07 --- /dev/null +++ b/spec/lib/outboxer/web/message/delete_spec.rb @@ -0,0 +1,36 @@ +require 'spec_helper' + +require_relative '../../../../../app/models/application_record' +require_relative '../../../../../app/models/event' + +require_relative "../../../../../lib/outboxer/web" + +RSpec.describe 'POST /message/:id/delete', type: :request do + include Rack::Test::Methods + + def app + Outboxer::Web + end + + let!(:event) { Event.create!(id: 1, type: 'Event') } + let!(:message) do + Outboxer::Models::Message.find_by!(messageable_type: 'Event', messageable_id: event.id) + end + + before do + header 'Host', 'localhost' + + post "/message/#{message.id}/delete" + + follow_redirect! + end + + it 'deletes message' do + expect(Outboxer::Models::Message.exists?(message.id)).to be false + end + + it 'redirects with flash' do + expect(last_response).to be_ok + expect(last_request.env['x-rack.flash'][:primary]).to include('was deleted') + end +end diff --git a/spec/lib/outboxer/web/message/messageable_spec.rb b/spec/lib/outboxer/web/message/messageable_spec.rb new file mode 100644 index 0000000..f38a5c0 --- /dev/null +++ b/spec/lib/outboxer/web/message/messageable_spec.rb @@ -0,0 +1,29 @@ +require 'spec_helper' + +require_relative '../../../../../app/models/application_record' +require_relative '../../../../../app/models/event' + +require_relative "../../../../../lib/outboxer/web" + +RSpec.describe 'GET /message/:id/messageable', type: :request do + include Rack::Test::Methods + + def app + Outboxer::Web + end + + let(:event) { Event.create!(type: 'Event') } + let!(:message) do + Outboxer::Models::Message.find_by!(messageable_type: 'Event', messageable_id: event.id) + end + + before do + header 'Host', 'localhost' + + get "/message/#{message.id}/messageable" + end + + it 'loads the associated messageable object for a message' do + expect(last_response).to be_ok + end +end diff --git a/spec/lib/outboxer/web/message/requeue_spec.rb b/spec/lib/outboxer/web/message/requeue_spec.rb new file mode 100644 index 0000000..3225540 --- /dev/null +++ b/spec/lib/outboxer/web/message/requeue_spec.rb @@ -0,0 +1,38 @@ +require 'spec_helper' + +require_relative '../../../../../app/models/application_record' +require_relative '../../../../../app/models/event' + +require_relative "../../../../../lib/outboxer/web" + +RSpec.describe 'POST /message/:id/requeue', type: :request do + include Rack::Test::Methods + + def app + Outboxer::Web + end + + let!(:event) { Event.create!(id: 1, type: 'Event') } + let!(:message) do + Outboxer::Models::Message.find_by!(messageable_type: 'Event', messageable_id: event.id) + end + + before do + header 'Host', 'localhost' + + post "/message/#{message.id}/requeue" + + follow_redirect! + + message.reload + end + + it 'requeues a message' do + expect(message.status).to eql('queued') + end + + it 'redirects with flash' do + expect(last_response).to be_ok + expect(last_request.env['x-rack.flash'][:primary]).to include('was queued') + end +end diff --git a/spec/lib/outboxer/web/message/show_spec.rb b/spec/lib/outboxer/web/message/show_spec.rb new file mode 100644 index 0000000..9ece28e --- /dev/null +++ b/spec/lib/outboxer/web/message/show_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper' + +require_relative '../../../../../app/models/application_record' +require_relative '../../../../../app/models/event' + +require_relative "../../../../../lib/outboxer/web" + +RSpec.describe 'GET /message/:id', type: :request do + include Rack::Test::Methods + + def app + Outboxer::Web + end + + let(:event) { Event.create!(type: 'Event') } + let!(:message) do + Outboxer::Models::Message.find_by!(messageable_type: 'Event', messageable_id: event.id) + end + + before do + header 'Host', 'localhost' + + get "/message/#{message.id}" + end + + it 'loads message' do + expect(last_response).to be_ok + expect(last_response.body).to include(message.id.to_s) + end +end diff --git a/spec/lib/outboxer/web/messages/delete_all_spec.rb b/spec/lib/outboxer/web/messages/delete_all_spec.rb new file mode 100644 index 0000000..9a294ba --- /dev/null +++ b/spec/lib/outboxer/web/messages/delete_all_spec.rb @@ -0,0 +1,102 @@ +require 'spec_helper' + +require_relative '../../../../../app/models/application_record' +require_relative '../../../../../app/models/event' + +require_relative "../../../../../lib/outboxer/web" + +RSpec.describe 'POST /messages/delete_all', type: :request do + include Rack::Test::Methods + + def app + Outboxer::Web + end + + let!(:event_1) { Event.create!(id: 1, type: 'Event') } + let!(:message_1) do + Outboxer::Models::Message.find_by!(messageable_type: 'Event', messageable_id: event_1.id) + end + + let!(:event_2) { Event.create!(id: 2, type: 'Event') } + let!(:message_2) do + Outboxer::Models::Message.find_by!(messageable_type: 'Event', messageable_id: event_2.id) + end + + let!(:event_3) { Event.create!(id: 3, type: 'Event') } + let!(:message_3) do + Outboxer::Models::Message.find_by!(messageable_type: 'Event', messageable_id: event_3.id) + end + + context 'when no status provided' do + before do + header 'Host', 'localhost' + + post '/messages/delete_all', { + page: 1, + per_page: 10, + sort: :queued_at, + order: :desc, + time_zone: 'Australia/Sydney' + } + + follow_redirect! + end + + it 'deletes all messages' do + expect(Outboxer::Models::Message.count).to eq(0) + end + + it 'does not delete events' do + expect(Event.count).to eq(3) + end + + it 'redirects to /messages' do + expect(last_response).to be_ok + expect(last_request.url).to include( + "messages?sort=queued_at&order=desc&per_page=10&time_zone=Australia%2FSydney") + end + + it 'flashes deleted messages count' do + expect(last_request.env['x-rack.flash'][:primary]).to include('3 messages have been deleted') + end + end + + context 'when failed status provided' do + before do + message_2.update!(status: Outboxer::Models::Message::Status::PUBLISHING) + message_3.update!(status: Outboxer::Models::Message::Status::FAILED) + + header 'Host', 'localhost' + + post '/messages/delete_all', { + status: :failed, + page: 1, + per_page: 10, + sort: :queued_at, + order: :desc, + time_zone: 'Australia/Sydney' + } + + follow_redirect! + end + + it 'deletes failed messages' do + expect(Outboxer::Models::Message.failed.count).to eq(0) + end + + it 'does not delete other messages' do + expect(Outboxer::Models::Message.queued.count).to eq(1) + expect(Outboxer::Models::Message.publishing.count).to eq(1) + end + + it 'redirects to /messages' do + expect(last_response).to be_ok + expect(last_request.url).to include( + "messages?status=failed&sort=queued_at&order=desc&per_page=10&time_zone=Australia%2FSydney") + end + + it 'flashes deleted messages count' do + expect(last_request.env['x-rack.flash'][:primary]).to include('1 message have been deleted') + end + end +end diff --git a/spec/lib/outboxer/web/messages/list_spec.rb b/spec/lib/outboxer/web/messages/list_spec.rb new file mode 100644 index 0000000..2a11cb8 --- /dev/null +++ b/spec/lib/outboxer/web/messages/list_spec.rb @@ -0,0 +1,65 @@ +require 'spec_helper' + +require_relative '../../../../../app/models/application_record' +require_relative '../../../../../app/models/event' + +require_relative "../../../../../lib/outboxer/web" + +RSpec.describe 'GET /messages', type: :request do + include Rack::Test::Methods + + def app + Outboxer::Web + end + + context 'when no status provided' do + let!(:event_1) { Event.create!(id: 1, type: 'Event') } + let!(:message_1) do + Outboxer::Models::Message.find_by!(messageable_type: 'Event', messageable_id: event_1.id) + end + + let!(:event_2) { Event.create!(id: 2, type: 'Event') } + let!(:message_2) do + Outboxer::Models::Message.find_by!(messageable_type: 'Event', messageable_id: event_2.id) + end + + before do + header 'Host', 'localhost' + + get '/messages', { page: 1, per_page: 10 } + end + + it 'displays messages with pagination' do + expect(last_response).to be_ok + expect(last_response.body).to include("href=\"/message/#{message_1.id}?per_page=10\"") + expect(last_response.body).to include("href=\"/message/#{message_2.id}?per_page=10\"") + end + end + + context 'when publishing status provided' do + let!(:event_1) { Event.create!(id: 1, type: 'Event') } + let!(:message_1) do + Outboxer::Models::Message.find_by!(messageable_type: 'Event', messageable_id: event_1.id) + end + + let!(:event_2) { Event.create!(id: 2, type: 'Event') } + let!(:message_2) do + Outboxer::Models::Message.find_by!(messageable_type: 'Event', messageable_id: event_2.id) + end + + before do + message_2.update!(status: Outboxer::Models::Message::Status::PUBLISHING) + + header 'Host', 'localhost' + + get '/messages', { page: 1, status: 'publishing', per_page: 10 } + end + + it 'displays publishing message' do + expect(last_response).to be_ok + expect(last_response.body).not_to include("href=\"/message/#{message_1.id}?per_page=10\"") + expect(last_response.body).to include( + "href=\"/message/#{message_2.id}?status=publishing&per_page=10\"") + end + end +end diff --git a/spec/lib/outboxer/web/messages/requeue_all_spec.rb b/spec/lib/outboxer/web/messages/requeue_all_spec.rb new file mode 100644 index 0000000..af04656 --- /dev/null +++ b/spec/lib/outboxer/web/messages/requeue_all_spec.rb @@ -0,0 +1,94 @@ +require 'spec_helper' + +require_relative '../../../../../app/models/application_record' +require_relative '../../../../../app/models/event' + +require_relative "../../../../../lib/outboxer/web" + +RSpec.describe 'POST /messages/requeue_all', type: :request do + include Rack::Test::Methods + + def app + Outboxer::Web + end + + let!(:event_1) { Event.create!(id: 1, type: 'Event') } + let!(:message_1) do + Outboxer::Models::Message.find_by!(messageable_type: 'Event', messageable_id: event_1) + end + + let!(:event_2) { Event.create!(id: 2, type: 'Event') } + let!(:message_2) do + Outboxer::Models::Message.find_by!(messageable_type: 'Event', messageable_id: event_2) + end + + let!(:event_3) { Event.create!(id: 3, type: 'Event') } + let!(:message_3) do + Outboxer::Models::Message.find_by!(messageable_type: 'Event', messageable_id: event_3) + end + + context 'when no status provided' do + before do + message_2.update!(status: Outboxer::Models::Message::Status::PUBLISHING) + message_3.update!(status: Outboxer::Models::Message::Status::FAILED) + + header 'Host', 'localhost' + + post '/messages/requeue_all', { + page: 1, + per_page: 10, + sort: :queued_at, + order: :desc, + time_zone: 'Australia/Sydney' + } + end + + it 'responds with 500 internal server error' do + expect(last_response.status).to eq(500) + end + + it 'does not requeue messages' do + expect(Outboxer::Models::Message.queued.count).to eq(1) + expect(Outboxer::Models::Message.publishing.count).to eq(1) + expect(Outboxer::Models::Message.failed.count).to eq(1) + end + end + + context 'when failed status provided' do + before do + message_2.update!(status: Outboxer::Models::Message::Status::PUBLISHING) + message_3.update!(status: Outboxer::Models::Message::Status::FAILED) + + header 'Host', 'localhost' + + post '/messages/requeue_all', { + status: :failed, + page: 1, + per_page: 10, + sort: :queued_at, + order: :desc, + time_zone: 'Australia/Sydney' + } + + follow_redirect! + end + + it 'requeues messages' do + expect(Outboxer::Models::Message.queued.count).to eq(2) + end + + it 'does not requeue publishing messages' do + expect(Outboxer::Models::Message.publishing.count).to eq(1) + end + + it 'redirects to /messages' do + expect(last_response).to be_ok + expect(last_request.url).to include( + "messages?status=failed&sort=queued_at&order=desc&per_page=10&time_zone=Australia%2FSydney") + end + + it 'flashes requeued messages count' do + expect(last_request.env['x-rack.flash'][:primary]).to include('1 message have been queued') + end + end +end diff --git a/spec/lib/outboxer/web/messages/update_per_page_spec.rb b/spec/lib/outboxer/web/messages/update_per_page_spec.rb new file mode 100644 index 0000000..6297970 --- /dev/null +++ b/spec/lib/outboxer/web/messages/update_per_page_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +require_relative '../../../../../app/models/application_record' +require_relative '../../../../../app/models/event' + +require_relative "../../../../../lib/outboxer/web" + +RSpec.describe 'POST /messages/update_per_page', type: :request do + include Rack::Test::Methods + + def app + Outboxer::Web + end + + before do + header 'Host', 'localhost' + + post '/messages/update_per_page', { + status: 'queued', + sort: 'queued_at', + order: 'desc', + page: 1, + per_page: 10, + time_zone: 'Australia/Sydney' + } + + follow_redirect! + end + + it 'redirects with updated per_page param' do + expect(last_request.url).to include( + 'messages?status=queued&sort=queued_at&order=desc&per_page=10&time_zone=Australia%2FSydney') + end +end diff --git a/spec/lib/outboxer/web/messages/update_spec.rb b/spec/lib/outboxer/web/messages/update_spec.rb new file mode 100644 index 0000000..1884c12 --- /dev/null +++ b/spec/lib/outboxer/web/messages/update_spec.rb @@ -0,0 +1,118 @@ +require 'spec_helper' + +require_relative '../../../../../app/models/application_record' +require_relative '../../../../../app/models/event' + +require_relative "../../../../../lib/outboxer/web" + +RSpec.describe 'POST /messages/update', type: :request do + include Rack::Test::Methods + + def app + Outboxer::Web + end + + let!(:event_1) { Event.create!(id: 1, type: 'Event') } + let!(:message_1) do + Outboxer::Models::Message.find_by!(messageable_type: 'Event', messageable_id: event_1.id) + end + + let!(:event_2) { Event.create!(id: 2, type: 'Event') } + let!(:message_2) do + Outboxer::Models::Message.find_by!(messageable_type: 'Event', messageable_id: event_2.id) + end + + let!(:event_3) { Event.create!(id: 3, type: 'Event') } + let!(:message_3) do + Outboxer::Models::Message.find_by!(messageable_type: 'Event', messageable_id: event_3.id) + end + + before do + message_2.update!(status: Outboxer::Models::Message::Status::PUBLISHING) + message_3.update!(status: Outboxer::Models::Message::Status::FAILED) + + header 'Host', 'localhost' + end + + context 'when action is requeue_by_ids' do + let(:ids) { [message_2.id, message_3.id] } + + before do + post '/messages/update', { + selected_ids: ids, + action: 'requeue_by_ids', + status: :failed, + page: 1, + per_page: 10, + sort: :queued_at, + order: :desc, + time_zone: 'Australia/Sydney' + } + + follow_redirect! + end + + it 'queues selected messages' do + expect(Outboxer::Models::Message.queued.pluck(:id)).to eq([ + message_1.id, message_2.id, message_3.id ]) + end + + it 'redirects with flash message' do + expect(last_response).to be_ok + expect(last_request.url).to include( + 'messages?status=failed&sort=queued_at&order=desc&per_page=10&time_zone=Australia%2FSydney') + expect(last_request.env['x-rack.flash'][:primary]).to include('Requeued 2 messages') + end + end + + context 'when action is delete_by_ids' do + let(:ids) { [message_2.id, message_3.id] } + + before do + post '/messages/update', { + selected_ids: ids, + action: 'delete_by_ids', + status: :failed, + page: 1, + per_page: 10, + sort: :queued_at, + order: :desc, + time_zone: 'Australia/Sydney' + } + + follow_redirect! + end + + it 'deletes selected messages' do + expect(Outboxer::Models::Message.all.pluck(:id)).to eq([message_1.id]) + end + + it 'redirects with flash message' do + expect(last_response).to be_ok + expect(last_request.url).to include( + 'messages?status=failed&sort=queued_at&order=desc&per_page=10&time_zone=Australia%2FSydney') + expect(last_request.env['x-rack.flash'][:primary]).to include('Deleted 2 messages') + end + end + + context 'with invalid action' do + let(:ids) { [message_2.id, message_3.id] } + + before do + post '/messages/update', { + selected_ids: ids, + action: 'invalid', + status: :failed, + page: 1, + per_page: 10, + sort: :queued_at, + order: :desc, + time_zone: 'Australia/Sydney' + } + end + + it 'responds with 500 internal server error' do + expect(last_response.status).to eq(500) + end + end +end diff --git a/spec/lib/outboxer/web/publisher/create_signal_spec.rb b/spec/lib/outboxer/web/publisher/create_signal_spec.rb new file mode 100644 index 0000000..5548cee --- /dev/null +++ b/spec/lib/outboxer/web/publisher/create_signal_spec.rb @@ -0,0 +1,37 @@ +require 'spec_helper' + +require_relative '../../../../../app/models/application_record' +require_relative '../../../../../app/models/event' + +require_relative "../../../../../lib/outboxer/web" + +RSpec.describe 'POST /publisher/:id/signals', type: :request do + include Rack::Test::Methods + + def app + Outboxer::Web + end + + let(:event) { Event.create!(type: 'Event') } + let!(:message) do + Outboxer::Models::Message.find_by!(messageable_type: 'Event', messageable_id: event.id) + end + let(:publisher) { create(:outboxer_publisher, :publishing, name: 'Test Publisher') } + + before do + header 'Host', 'localhost' + + post "/publisher/#{publisher.id}/signals", { name: 'TSTP' } + + follow_redirect! + end + + it 'creates signal' do + expect(publisher.signals.first.name).to eql('TSTP') + end + + it 'displays flash' do + expect(last_response).to be_ok + expect(last_request.env['x-rack.flash'][:primary]).to include('signalled') + end +end diff --git a/spec/lib/outboxer/web/publisher/delete_spec.rb b/spec/lib/outboxer/web/publisher/delete_spec.rb new file mode 100644 index 0000000..8d6204d --- /dev/null +++ b/spec/lib/outboxer/web/publisher/delete_spec.rb @@ -0,0 +1,36 @@ +require 'spec_helper' + +require_relative '../../../../../app/models/application_record' +require_relative '../../../../../app/models/event' + +require_relative "../../../../../lib/outboxer/web" + +RSpec.describe 'POST /publisher/:id/delete', type: :request do + include Rack::Test::Methods + + def app + Outboxer::Web + end + + let(:event) { Event.create!(type: 'Event') } + let!(:message) do + Outboxer::Models::Message.find_by!(messageable_type: 'Event', messageable_id: event.id) + end + let(:publisher) { create(:outboxer_publisher, :publishing, name: 'Test Publisher') } + + before do + header 'Host', 'localhost' + post "/publisher/#{publisher.id}/delete" + + follow_redirect! + end + + it 'deletes publisher' do + expect(Outboxer::Models::Publisher.exists?(publisher.id)).to be false + end + + it 'displays flash' do + expect(last_response).to be_ok + expect(last_request.env['x-rack.flash'][:primary]).to include('was deleted') + end +end diff --git a/spec/lib/outboxer/web/publisher/show_spec.rb b/spec/lib/outboxer/web/publisher/show_spec.rb new file mode 100644 index 0000000..5454e0b --- /dev/null +++ b/spec/lib/outboxer/web/publisher/show_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +require_relative '../../../../../app/models/application_record' +require_relative '../../../../../app/models/event' + +require_relative "../../../../../lib/outboxer/web" + +RSpec.describe 'POST /publisher/:id/signals', type: :request do + include Rack::Test::Methods + + def app + Outboxer::Web + end + + let(:event) { Event.create!(type: 'Event') } + let!(:message) do + Outboxer::Models::Message.find_by!(messageable_type: 'Event', messageable_id: event.id) + end + let(:message) { create(:outboxer_message, :queued, messageable: event) } + let(:publisher) { create(:outboxer_publisher, :publishing, name: 'Test Publisher') } + + before do + header 'Host', 'localhost' + + get "/publisher/#{publisher.id}" + end + + it 'returns publisher details' do + expect(last_response).to be_ok + expect(last_response.body).to include(message.id.to_s) + end +end diff --git a/spec/lib/outboxer/web/update_time_zone_spec.rb b/spec/lib/outboxer/web/update_time_zone_spec.rb new file mode 100644 index 0000000..65313b8 --- /dev/null +++ b/spec/lib/outboxer/web/update_time_zone_spec.rb @@ -0,0 +1,24 @@ +require 'spec_helper' + +require_relative "../../../../lib/outboxer/web" + +RSpec.describe 'POST /update_time_zone', type: :request do + include Rack::Test::Methods + + def app + Outboxer::Web + end + + before do + header 'Host', 'localhost' + + post '/update_time_zone', { time_zone: 'Australia/Sydney' } + + follow_redirect! + end + + it 'redirects with updated time zone parameters' do + expect(last_response).to be_ok + expect(last_request.url).to include('time_zone=Australia%2FSydney') + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ca26881..4016077 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -3,6 +3,7 @@ require 'database_cleaner' require 'pry-byebug' require 'factory_bot' +require 'rack/test' Dir[File.join(__dir__, 'factories/**/*.rb')].each { |f| require f }