diff --git a/test/test_application.rb b/test/test_application.rb new file mode 100644 index 0000000..4fcec4e --- /dev/null +++ b/test/test_application.rb @@ -0,0 +1,136 @@ +require 'minitest/autorun' +require 'prism' +require 'support' + +class SampleApp < Prism::Application + enable_sessions(secret: 'test-secret') + + before '/admin/*' do + halt(401, 'unauthorized') unless params['token'] == 'let-me-in' + end + + get '/' do + 'root' + end + + get '/users/:id' do + json(id: params['id']) + end + + get '/search' do + json(q: params['q']) + end + + post '/echo' do + json(got: params.to_h) + end + + get '/old' do + redirect '/new', 301 + end + + get '/greet/:name' do + erb('

Hi <%= name %>

', locals: { name: params['name'] }) + end + + get '/admin/panel' do + json(secret: 'shown') + end + + get '/count' do + session['count'] = (session['count'] || 0) + 1 + json(count: session['count']) + end + + get '/first' do + pass if params['skip'] == 'yes' + 'first' + end + + get '/first' do + 'second' + end +end + +class ApplicationTest < Minitest::Test + include TestSupport + + def call(method, path, **opts) + SampleApp.call(env_for(method, path, **opts)) + end + + def test_root + status, _, body = call('GET', '/') + assert_equal 200, status + assert_equal 'root', body.join + end + + def test_path_param + status, headers, body = call('GET', '/users/77') + assert_equal 200, status + assert_equal 'application/json', headers['Content-Type'] + assert_equal({ 'id' => '77' }, JSON.parse(body.join)) + end + + def test_query_param + _, _, body = call('GET', '/search?q=prism') + assert_equal({ 'q' => 'prism' }, JSON.parse(body.join)) + end + + def test_post_json + payload = JSON.generate(name: 'x', n: 5) + _, _, body = call('POST', '/echo', headers: { 'Content-Type' => 'application/json' }, body: payload) + assert_equal({ 'name' => 'x', 'n' => 5 }, JSON.parse(body.join)['got']) + end + + def test_redirect + status, headers, = call('GET', '/old') + assert_equal 301, status + assert_equal '/new', headers['Location'] + end + + def test_not_found + status, _, body = call('GET', '/missing') + assert_equal 404, status + assert_includes body.join, 'Not Found' + end + + def test_template_escaping + _, _, body = call('GET', '/greet/%3Cb%3E') + assert_equal '

Hi <b>

', body.join + end + + def test_before_filter_blocks + status, _, body = call('GET', '/admin/panel') + assert_equal 401, status + assert_equal 'unauthorized', body.join + end + + def test_before_filter_allows + status, _, body = call('GET', '/admin/panel?token=let-me-in') + assert_equal 200, status + assert_equal 'shown', JSON.parse(body.join)['secret'] + end + + def test_session_write_and_read + _, headers, body = call('GET', '/count') + assert_equal 1, JSON.parse(body.join)['count'] + cookie = headers['Set-Cookie'].split(';').first + name, value = cookie.split('=', 2) + _, _, body2 = call('GET', '/count', cookies: "#{name}=#{value}") + assert_equal 2, JSON.parse(body2.join)['count'] + end + + def test_pass + _, _, body = call('GET', '/first?skip=yes') + assert_equal 'second', body.join + _, _, second = call('GET', '/first') + assert_equal 'first', second.join + end + + def test_head_has_empty_body + status, _, body = call('HEAD', '/') + assert_equal 200, status + assert_equal '', body.join + end +end diff --git a/test/test_application_routing.rb b/test/test_application_routing.rb new file mode 100644 index 0000000..810a272 --- /dev/null +++ b/test/test_application_routing.rb @@ -0,0 +1,100 @@ +require 'minitest/autorun' +require 'prism' +require 'support' + +class ResourceApp < Prism::Application + enable_sessions(secret: 'routing-secret') + + root(to: 'welcome#show') + + resources :routing_posts, only: %i[index show create] + + get '/whoami' do + json(path: url_for(:routing_post, id: 5)) + end + + get '/write-flash' do + flash[:notice] = 'saved!' + redirect '/after-flash' + end + + get '/after-flash' do + json(notice: flash[:notice]) + end +end + +class WelcomeController < Prism::Controller + def show + html('welcome') + end +end + +class RoutingPostsController < Prism::Controller + def index + json(action: 'index') + end + + def show + json(action: 'show', id: params['id']) + end + + def create + json(action: 'create') + end +end + +class ApplicationRoutingTest < Minitest::Test + include TestSupport + + def call(method, path, **opts) + ResourceApp.call(env_for(method, path, **opts)) + end + + def test_root_dispatches_to_controller + status, _, body = call('GET', '/') + assert_equal 200, status + assert_equal 'welcome', body.join + end + + def test_resources_index + _, _, body = call('GET', '/routing_posts') + assert_equal({ 'action' => 'index' }, JSON.parse(body.join)) + end + + def test_resources_show + _, _, body = call('GET', '/routing_posts/9') + assert_equal({ 'action' => 'show', 'id' => '9' }, JSON.parse(body.join)) + end + + def test_resources_create + _, _, body = call('POST', '/routing_posts') + assert_equal({ 'action' => 'create' }, JSON.parse(body.join)) + end + + def test_resources_only_registers_requested_actions + status, = call('DELETE', '/routing_posts/1') + assert_equal 404, status + end + + def test_url_for_named_resource_route + _, _, body = call('GET', '/whoami') + assert_equal '/routing_posts/5', JSON.parse(body.join)['path'] + end + + def test_flash_survives_a_redirect + status, headers, = call('GET', '/write-flash') + assert_equal 302, status + cookie = headers['Set-Cookie'].split(';').first + _, _, body = call('GET', '/after-flash', cookies: cookie) + assert_equal 'saved!', JSON.parse(body.join)['notice'] + end + + def test_flash_does_not_survive_a_second_request + _, headers, = call('GET', '/write-flash') + cookie = headers['Set-Cookie'].split(';').first + _, headers2, = call('GET', '/after-flash', cookies: cookie) + cookie2 = headers2['Set-Cookie']&.split(';')&.first || cookie + _, _, body = call('GET', '/after-flash', cookies: cookie2) + assert_nil JSON.parse(body.join)['notice'] + end +end