diff --git a/test/controllers/controller_test.rb b/test/controllers/controller_test.rb index e2568f97..d27eb2e6 100644 --- a/test/controllers/controller_test.rb +++ b/test/controllers/controller_test.rb @@ -494,15 +494,15 @@ def test_sorting_by_relationship_field assert_response :success assert json_response['data'].length > 10, 'there are enough records to show sort' + expected = Post + .all + .left_joins(:author) + .merge(Person.order(name: :asc)) + .map(&:id) + .map(&:to_s) + ids = json_response['data'].map {|data| data['id'] } - # Postgres sorts nulls last, whereas sqlite and mysql sort nulls first - if ENV['DATABASE_URL'].starts_with?('postgres') - assert_equal '17', json_response['data'][-1]['id'], 'nil is at the start' - assert_equal post.id.to_s, json_response['data'][0]['id'], 'alphabetically first user is not first' - else - assert_equal '17', json_response['data'][0]['id'], 'nil is at the end' - assert_equal post.id.to_s, json_response['data'][1]['id'], 'alphabetically first user is second' - end + assert_equal expected, ids, "since adapter_sorts_nulls_last=#{adapter_sorts_nulls_last}" end def test_desc_sorting_by_relationship_field @@ -512,14 +512,15 @@ def test_desc_sorting_by_relationship_field assert_response :success assert json_response['data'].length > 10, 'there are enough records to show sort' - # Postgres sorts nulls last, whereas sqlite and mysql sort nulls first - if ENV['DATABASE_URL'].starts_with?('postgres') - assert_equal '17', json_response['data'][0]['id'], 'nil is at the start' - assert_equal post.id.to_s, json_response['data'][-1]['id'] - else - assert_equal '17', json_response['data'][-1]['id'], 'nil is at the end' - assert_equal post.id.to_s, json_response['data'][-2]['id'], 'alphabetically first user is second last' - end + expected = Post + .all + .left_joins(:author) + .merge(Person.order(name: :desc)) + .map(&:id) + .map(&:to_s) + ids = json_response['data'].map {|data| data['id'] } + + assert_equal expected, ids, "since adapter_sorts_nulls_last=#{adapter_sorts_nulls_last}" end def test_sorting_by_relationship_field_include @@ -529,13 +530,15 @@ def test_sorting_by_relationship_field_include assert_response :success assert json_response['data'].length > 10, 'there are enough records to show sort' - if ENV['DATABASE_URL'].starts_with?('postgres') - assert_equal '17', json_response['data'][-1]['id'], 'nil is at the top' - assert_equal post.id.to_s, json_response['data'][0]['id'] - else - assert_equal '17', json_response['data'][0]['id'], 'nil is at the top' - assert_equal post.id.to_s, json_response['data'][1]['id'], 'alphabetically first user is second' - end + expected = Post + .all + .left_joins(:author) + .merge(Person.order(name: :asc)) + .map(&:id) + .map(&:to_s) + ids = json_response['data'].map {|data| data['id'] } + + assert_equal expected, ids, "since adapter_sorts_nulls_last=#{adapter_sorts_nulls_last}" end def test_invalid_sort_param @@ -4772,11 +4775,11 @@ def test_fetch_robots_with_sort_by_name assert_cacheable_get :index, params: {sort: 'name'} assert_response :success - if ENV['DATABASE_URL'].starts_with?('postgres') - assert_equal 'jane', json_response['data'].first['attributes']['name'] - else - assert_equal 'John', json_response['data'].first['attributes']['name'] - end + expected_names = Robot + .all + .order(name: :asc) + .map(&:name) + assert_equal expected_names.first, json_response['data'].first['attributes']['name'], "since adapter_sorts_nulls_last=#{adapter_sorts_nulls_last}" end def test_fetch_robots_with_sort_by_lower_name diff --git a/test/integration/requests/request_test.rb b/test/integration/requests/request_test.rb index 1863b5c7..f66e80af 100644 --- a/test/integration/requests/request_test.rb +++ b/test/integration/requests/request_test.rb @@ -1443,16 +1443,32 @@ def test_sort_primary_attribute end def test_sort_included_attribute - # Postgres sorts nulls last, whereas sqlite and mysql sort nulls first - pg = ENV['DATABASE_URL'].starts_with?('postgres') - get '/api/v6/authors?sort=author_detail.author_stuff', headers: { 'Accept' => JSONAPI::MEDIA_TYPE } assert_jsonapi_response 200 - assert_equal pg ? '1001' : '1000', json_response['data'][0]['id'] + up_expected_ids = AuthorResource + ._model_class + .all + .left_joins(:author_detail) + .merge(AuthorDetail.order(author_stuff: :asc)) + .map(&:id) + expected = up_expected_ids.first.to_s + ids = json_response['data'].map {|data| data['id'] } + actual = ids.first + assert_equal expected, actual, "since adapter_sorts_nulls_last=#{adapter_sorts_nulls_last} ands actual=#{ids} vs. expected=#{up_expected_ids}" get '/api/v6/authors?sort=-author_detail.author_stuff', headers: { 'Accept' => JSONAPI::MEDIA_TYPE } assert_jsonapi_response 200 - assert_equal pg ? '1000' : '1002', json_response['data'][0]['id'] + down_expected_ids = AuthorResource + ._model_class + .all + .left_joins(:author_detail) + .merge(AuthorDetail.order(author_stuff: :desc)) + .map(&:id) + expected = down_expected_ids.first.to_s + ids = json_response['data'].map {|data| data['id'] } + actual = ids.first + assert_equal expected, actual, "since adapter_sorts_nulls_last=#{adapter_sorts_nulls_last} ands actual=#{ids} vs. expected=#{down_expected_ids}" + refute_equal up_expected_ids, down_expected_ids # sanity check end def test_include_parameter_quoted diff --git a/test/test_helper.rb b/test/test_helper.rb index 9850a49c..91b20114 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -459,6 +459,24 @@ def run_in_transaction? self.fixture_path = "#{Rails.root}/fixtures" fixtures :all + + def adapter_name + ActiveRecord::Base.connection.adapter_name + end + + # Postgres sorts nulls last, whereas sqlite and mysql sort nulls first + def adapter_sorts_nulls_last + case adapter_name + when 'PostgreSQL' then true + when 'SQLite', 'Mysql2' then false + else + fail ArgumentError, "Unhandled adapter #{adapter_name} in #{__callee__}" + end + end + + def db_true + ActiveRecord::Base.connection.quote(true) + end end class ActiveSupport::TestCase