test: cover PaginationHelpersTest, teardown and ParamsNestedTest
This commit is contained in:
1 parent
a51e8536c4
commit
d23fb5fec3
2 files changed
+151
No files matched your search
@@ -0,0 +1,74 @@
|
|||||||
|
require 'minitest/autorun'
|
||||||
|
require 'prism'
|
||||||
|
require 'tmpdir'
|
||||||
|
require 'fileutils'
|
||||||
|
|
||||||
|
class PaginationHelpersTest < Minitest::Test
|
||||||
|
def setup
|
||||||
|
@dir = Dir.mktmpdir('prism-pagination-helpers')
|
||||||
|
@store = Prism::Orm::Store.new(File.join(@dir, 'test.pstore'))
|
||||||
|
@store.create_table(:widgets, %w[id name position])
|
||||||
|
widget_class = Class.new(Prism::Orm::Model) { table_name :widgets }
|
||||||
|
widget_class.store = @store
|
||||||
|
Object.const_set(:PaginatedWidget, widget_class)
|
||||||
|
25.times { |i| PaginatedWidget.create!(name: "widget-#{i}", position: i) }
|
||||||
|
|
||||||
|
@context = Prism::Template::Context.new({})
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
FileUtils.remove_entry(@dir)
|
||||||
|
Object.send(:remove_const, :PaginatedWidget) if Object.const_defined?(:PaginatedWidget)
|
||||||
|
end
|
||||||
|
|
||||||
|
def path_for
|
||||||
|
->(page) { "/widgets?page=#{page}" }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_returns_blank_when_everything_fits_on_one_page
|
||||||
|
relation = PaginatedWidget.page(1)
|
||||||
|
assert_equal '', @context.paginate(relation, path: path_for)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_renders_a_link_per_page_within_the_window
|
||||||
|
relation = PaginatedWidget.order(:position).page(1).per(5)
|
||||||
|
html = @context.paginate(relation, path: path_for)
|
||||||
|
assert_includes html, 'href="/widgets?page=2"'
|
||||||
|
assert_includes html, '>2<'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_current_page_link_carries_the_current_class
|
||||||
|
relation = PaginatedWidget.order(:position).page(3).per(5)
|
||||||
|
html = @context.paginate(relation, path: path_for)
|
||||||
|
assert_includes html, 'href="/widgets?page=3" class="page-link current"'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_first_page_disables_the_previous_link
|
||||||
|
relation = PaginatedWidget.order(:position).page(1).per(5)
|
||||||
|
html = @context.paginate(relation, path: path_for)
|
||||||
|
assert_includes html, '<span class="page-link disabled">Previous</span>'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_last_page_disables_the_next_link
|
||||||
|
relation = PaginatedWidget.order(:position).page(5).per(5)
|
||||||
|
html = @context.paginate(relation, path: path_for)
|
||||||
|
assert_includes html, '<span class="page-link disabled">Next</span>'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_far_apart_pages_are_separated_by_a_gap_marker
|
||||||
|
relation = PaginatedWidget.order(:position).page(1).per(1)
|
||||||
|
html = @context.paginate(relation, path: path_for)
|
||||||
|
assert_includes html, '<span class="page-gap">...</span>'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_renders_through_a_real_erb_template
|
||||||
|
views_dir = File.join(@dir, 'views', 'widgets')
|
||||||
|
FileUtils.mkdir_p(views_dir)
|
||||||
|
File.write(File.join(views_dir, 'index.erb'), '<%== paginate(widgets, path: ->(n) { "/widgets?page=#{n}" }) %>')
|
||||||
|
|
||||||
|
view = Prism::View.new(File.join(@dir, 'views'))
|
||||||
|
output = view.render('widgets/index', locals: { widgets: PaginatedWidget.order(:position).page(1).per(5) })
|
||||||
|
assert_includes output, '<nav class="pagination">'
|
||||||
|
assert_includes output, 'href="/widgets?page=2"'
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
require 'minitest/autorun'
|
||||||
|
require 'prism'
|
||||||
|
require 'support'
|
||||||
|
|
||||||
|
class ParamsNestedTest < Minitest::Test
|
||||||
|
include TestSupport
|
||||||
|
|
||||||
|
def test_nested_from_expands_bracketed_keys_into_a_hash
|
||||||
|
params = Prism::Params.nested_from([['post[title]', 'hi'], ['post[body]', 'yo']])
|
||||||
|
assert_equal 'hi', params['post']['title']
|
||||||
|
assert_equal 'yo', params['post']['body']
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_nested_from_collects_trailing_brackets_into_an_array
|
||||||
|
params = Prism::Params.nested_from([['tags[]', 'ruby'], ['tags[]', 'web']])
|
||||||
|
assert_equal %w[ruby web], params['tags']
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_nested_from_supports_an_array_nested_under_a_hash_key
|
||||||
|
params = Prism::Params.nested_from([['post[tags][]', 'a'], ['post[tags][]', 'b']])
|
||||||
|
assert_equal %w[a b], params['post']['tags']
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_nested_from_supports_multiple_levels_of_nesting
|
||||||
|
params = Prism::Params.nested_from([['address[city][zip]', '00-001']])
|
||||||
|
assert_equal '00-001', params['address']['city']['zip']
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_nested_from_leaves_plain_keys_untouched
|
||||||
|
params = Prism::Params.nested_from([['title', 'hi']])
|
||||||
|
assert_equal 'hi', params['title']
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_nested_from_symbol_and_string_keys_are_interchangeable_at_every_level
|
||||||
|
params = Prism::Params.nested_from([['post[title]', 'hi']])
|
||||||
|
assert_equal 'hi', params[:post][:title]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_urlencoded_form_body_with_object_bracket_names_is_parsed_as_nested_params
|
||||||
|
request = Prism::Request.new(env_for('POST', '/posts',
|
||||||
|
headers: { 'Content-Type' => 'application/x-www-form-urlencoded' },
|
||||||
|
body: 'post%5Btitle%5D=Hello&post%5Bbody%5D=World&tags%5B%5D=a&tags%5B%5D=b'))
|
||||||
|
assert_equal 'Hello', request.params['post']['title']
|
||||||
|
assert_equal 'World', request.params['post']['body']
|
||||||
|
assert_equal %w[a b], request.params['tags']
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_urlencoded_query_string_with_object_bracket_names_is_parsed_as_nested_params
|
||||||
|
request = Prism::Request.new(env_for('GET', '/search?filter%5Bname%5D=fox&filter%5Bactive%5D=1'))
|
||||||
|
assert_equal 'fox', request.params['filter']['name']
|
||||||
|
assert_equal '1', request.params['filter']['active']
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_nested_form_params_survive_a_strong_parameters_require_and_permit_round_trip
|
||||||
|
request = Prism::Request.new(env_for('POST', '/posts',
|
||||||
|
headers: { 'Content-Type' => 'application/x-www-form-urlencoded' },
|
||||||
|
body: 'post%5Btitle%5D=Hello&post%5Badmin%5D=1'))
|
||||||
|
permitted = request.params.require(:post).permit(:title)
|
||||||
|
assert_equal({ 'title' => 'Hello' }, permitted.to_h)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_multipart_body_with_object_bracket_names_is_parsed_as_nested_params
|
||||||
|
boundary = '----ParamsNestedTestBoundary'
|
||||||
|
body = [
|
||||||
|
"--#{boundary}\r\nContent-Disposition: form-data; name=\"post[title]\"\r\n\r\nHello\r\n",
|
||||||
|
"--#{boundary}\r\nContent-Disposition: form-data; name=\"post[cover]\"; filename=\"a.png\"\r\n" \
|
||||||
|
"Content-Type: image/png\r\n\r\nbytes\r\n",
|
||||||
|
"--#{boundary}--\r\n"
|
||||||
|
].join
|
||||||
|
request = Prism::Request.new(env_for('POST', '/posts',
|
||||||
|
headers: { 'Content-Type' => "multipart/form-data; boundary=#{boundary}" },
|
||||||
|
body: body))
|
||||||
|
assert_equal 'Hello', request.params['post']['title']
|
||||||
|
assert_instance_of Prism::UploadedFile, request.params['post']['cover']
|
||||||
|
assert_equal 'a.png', request.params['post']['cover'].original_filename
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in new issue
Block a user