diff --git a/Gemfile b/Gemfile index 2535d020..98363e07 100644 --- a/Gemfile +++ b/Gemfile @@ -11,10 +11,10 @@ version = ENV['RAILS_VERSION'] || 'default' platforms :ruby do gem 'pg' - if version.start_with?('4.2', '5.0') - gem 'sqlite3', '~> 1.3.13' + if version.start_with?('8.1') + gem 'sqlite3', '>= 2.1' else - gem 'sqlite3', '~> 1.4' + gem 'sqlite3', '~> 1.3.13' end end @@ -24,6 +24,7 @@ when 'master' gem 'arel', { git: 'https://github.com/rails/arel.git' } when 'default' gem 'railties', '>= 6.0' + gem 'csv' else gem 'railties', "~> #{version}" -end \ No newline at end of file +end diff --git a/lib/jsonapi-resources.rb b/lib/jsonapi-resources.rb index 401d9bbc..35818bf2 100644 --- a/lib/jsonapi-resources.rb +++ b/lib/jsonapi-resources.rb @@ -43,3 +43,4 @@ require 'jsonapi/resource_set' require 'jsonapi/path' require 'jsonapi/path_segment' +require 'jsonapi/deprecator' diff --git a/lib/jsonapi/active_relation_resource.rb b/lib/jsonapi/active_relation_resource.rb index 581ed1e0..4a2aeb09 100644 --- a/lib/jsonapi/active_relation_resource.rb +++ b/lib/jsonapi/active_relation_resource.rb @@ -847,7 +847,16 @@ def alias_table_field(table, field, quoted = false) end def quote(field) - "\"#{field.to_s}\"" + if oracle? + "\"#{field.to_s.upcase}\"" + else + "\"#{field.to_s}\"" + end + end + + def oracle? + defined?(ActiveRecord::Base.connection) && + ActiveRecord::Base.connection.adapter_name =~ /oracle/i end def apply_filters(records, filters, options = {}) diff --git a/lib/jsonapi/basic_resource.rb b/lib/jsonapi/basic_resource.rb index 2eeba5c5..0d55879d 100644 --- a/lib/jsonapi/basic_resource.rb +++ b/lib/jsonapi/basic_resource.rb @@ -547,7 +547,7 @@ def attribute(attribute_name, options = {}) check_reserved_attribute_name(attr) if (attr == :id) && (options[:format].nil?) - ActiveSupport::Deprecation.warn('Id without format is no longer supported. Please remove ids from attributes, or specify a format.') + JSONAPI.deprecator.warn('Id without format is no longer supported. Please remove ids from attributes, or specify a format.') end check_duplicate_attribute_name(attr) if options[:format].nil? @@ -609,7 +609,7 @@ def has_one(*attrs) end def belongs_to(*attrs) - ActiveSupport::Deprecation.warn "In #{name} you exposed a `has_one` relationship "\ + JSONAPI.deprecator.warn"In #{name} you exposed a `has_one` relationship "\ " using the `belongs_to` class method. We think `has_one`" \ " is more appropriate. If you know what you're doing," \ " and don't want to see this warning again, override the" \ diff --git a/lib/jsonapi/configuration.rb b/lib/jsonapi/configuration.rb index 6cd5d8e1..675d4331 100644 --- a/lib/jsonapi/configuration.rb +++ b/lib/jsonapi/configuration.rb @@ -241,18 +241,18 @@ def default_processor_klass_name=(default_processor_klass_name) end def allow_include=(allow_include) - ActiveSupport::Deprecation.warn('`allow_include` has been replaced by `default_allow_include_to_one` and `default_allow_include_to_many` options.') + JSONAPI.deprecator.warn('`allow_include` has been replaced by `default_allow_include_to_one` and `default_allow_include_to_many` options.') @default_allow_include_to_one = allow_include @default_allow_include_to_many = allow_include end def whitelist_all_exceptions=(allow_all_exceptions) - ActiveSupport::Deprecation.warn('`whitelist_all_exceptions` has been replaced by `allow_all_exceptions`') + JSONAPI.deprecator.warn('`whitelist_all_exceptions` has been replaced by `allow_all_exceptions`') @allow_all_exceptions = allow_all_exceptions end def exception_class_whitelist=(exception_class_allowlist) - ActiveSupport::Deprecation.warn('`exception_class_whitelist` has been replaced by `exception_class_allowlist`') + JSONAPI.deprecator.warn('`exception_class_whitelist` has been replaced by `exception_class_allowlist`') @exception_class_allowlist = exception_class_allowlist end @@ -315,11 +315,13 @@ def exception_class_whitelist=(exception_class_allowlist) class << self attr_accessor :configuration - end - @configuration ||= Configuration.new + def configuration + @configuration ||= Configuration.new + end + end def self.configure - yield(@configuration) + yield(configuration) end end diff --git a/lib/jsonapi/deprecator.rb b/lib/jsonapi/deprecator.rb new file mode 100644 index 00000000..856761d6 --- /dev/null +++ b/lib/jsonapi/deprecator.rb @@ -0,0 +1,5 @@ +module JSONAPI + def self.deprecator + @deprecator ||= ActiveSupport::Deprecation.new('1.0', 'jsonapi-resources') + end +end diff --git a/lib/jsonapi/exceptions.rb b/lib/jsonapi/exceptions.rb index e917118c..a0c437ee 100644 --- a/lib/jsonapi/exceptions.rb +++ b/lib/jsonapi/exceptions.rb @@ -498,7 +498,7 @@ def errors def json_api_error(attr_key, message) create_error_object(code: JSONAPI::VALIDATION_ERROR, - status: :unprocessable_entity, + status: :unprocessable_content, title: message, detail: detail(attr_key, message), source: { pointer: pointer(attr_key) }, @@ -532,7 +532,7 @@ def general_error?(attr_key) class SaveFailed < Error def errors [create_error_object(code: JSONAPI::SAVE_FAILED, - status: :unprocessable_entity, + status: :unprocessable_content, title: I18n.translate('jsonapi-resources.exceptions.save_failed.title', default: 'Save failed or was cancelled'), detail: I18n.translate('jsonapi-resources.exceptions.save_failed.detail', diff --git a/lib/jsonapi/routing_ext.rb b/lib/jsonapi/routing_ext.rb index b0b94013..221f3bde 100644 --- a/lib/jsonapi/routing_ext.rb +++ b/lib/jsonapi/routing_ext.rb @@ -46,7 +46,7 @@ def jsonapi_resource(*resources, &_block) options[:except] << :destroy unless options[:except].include?(:destroy) || options[:except].include?('destroy') end - resource @resource_type, options do + resource @resource_type, **options do # :nocov: if @scope.respond_to? :[]= # Rails 4 @@ -59,7 +59,7 @@ def jsonapi_resource(*resources, &_block) end else # Rails 5 - jsonapi_resource_scope(SingletonResource.new(@resource_type, api_only?, @scope[:shallow], options), @resource_type) do + jsonapi_resource_scope(SingletonResource.new(@resource_type, api_only?, @scope[:shallow], **options), @resource_type) do if block_given? yield else @@ -121,7 +121,7 @@ def jsonapi_resources(*resources, &_block) options[:except] << :destroy unless options[:except].include?(:destroy) || options[:except].include?('destroy') end - resources @resource_type, options do + resources @resource_type, **options do # :nocov: if @scope.respond_to? :[]= # Rails 4 @@ -133,7 +133,7 @@ def jsonapi_resources(*resources, &_block) end else # Rails 5 - jsonapi_resource_scope(Resource.new(@resource_type, api_only?, @scope[:shallow], options), @resource_type) do + jsonapi_resource_scope(Resource.new(@resource_type, api_only?, @scope[:shallow], **options), @resource_type) do if block_given? yield else diff --git a/test/controllers/controller_test.rb b/test/controllers/controller_test.rb index e2568f97..a2f22066 100644 --- a/test/controllers/controller_test.rb +++ b/test/controllers/controller_test.rb @@ -761,7 +761,7 @@ def test_create_link_to_missing_object } } - assert_response :unprocessable_entity + assert_response :unprocessable_content # TODO: check if this validation is working assert_match /author - can't be blank/, response.body assert_nil response.location @@ -864,7 +864,7 @@ def test_create_with_invalid_data } } - assert_response :unprocessable_entity + assert_response :unprocessable_content assert_equal "/data/relationships/author", json_response['errors'][0]['source']['pointer'] assert_equal "can't be blank", json_response['errors'][0]['title'] @@ -2019,7 +2019,7 @@ def test_delete_with_validation_error_base assert_equal "can't destroy me", json_response['errors'][0]['title'] assert_equal "/data", json_response['errors'][0]['source']['pointer'] - assert_response :unprocessable_entity + assert_response :unprocessable_content end def test_delete_with_validation_error_attr @@ -2028,7 +2028,7 @@ def test_delete_with_validation_error_attr assert_equal "is locked", json_response['errors'][0]['title'] assert_equal "/data/attributes/title", json_response['errors'][0]['source']['pointer'] - assert_response :unprocessable_entity + assert_response :unprocessable_content end def test_delete_single @@ -2631,7 +2631,7 @@ def test_create_validations_missing_attribute } } - assert_response :unprocessable_entity + assert_response :unprocessable_content assert_equal 2, json_response['errors'].size assert_equal JSONAPI::VALIDATION_ERROR, json_response['errors'][0]['code'] assert_equal JSONAPI::VALIDATION_ERROR, json_response['errors'][1]['code'] @@ -2653,7 +2653,7 @@ def test_update_validations_missing_attribute } } - assert_response :unprocessable_entity + assert_response :unprocessable_content assert_equal 1, json_response['errors'].size assert_equal JSONAPI::VALIDATION_ERROR, json_response['errors'][0]['code'] assert_match /name - can't be blank/, response.body @@ -3183,7 +3183,7 @@ def test_create_with_invalid_data } } - assert_response :unprocessable_entity + assert_response :unprocessable_content assert_equal "/data/attributes/spouse-name", json_response['errors'][0]['source']['pointer'] assert_equal "can't be blank", json_response['errors'][0]['title'] @@ -3779,7 +3779,7 @@ def test_save_model_callbacks_fail } } - assert_response :unprocessable_entity + assert_response :unprocessable_content assert_match /Save failed or was cancelled/, json_response['errors'][0]['detail'] end end @@ -4077,7 +4077,7 @@ def test_delete_with_validation_error_base_on_resource assert_equal "can't destroy me", json_response['errors'][0]['title'] assert_equal "/data/attributes/base", json_response['errors'][0]['source']['pointer'] - assert_response :unprocessable_entity + assert_response :unprocessable_content end end diff --git a/test/fixtures/active_record.rb b/test/fixtures/active_record.rb index f8959317..3f81501c 100644 --- a/test/fixtures/active_record.rb +++ b/test/fixtures/active_record.rb @@ -52,7 +52,7 @@ end create_table :posts, force: true do |t| - t.string :title, length: 255 + t.string :title, limit: 255 t.text :body t.integer :author_id t.integer :parent_post_id @@ -324,8 +324,8 @@ create_table :related_things, force: true do |t| t.string :name - t.references :from, references: :thing - t.references :to, references: :thing + t.references :from, foreign_key: { to_table: :things } + t.references :to, foreign_key: { to_table: :things } t.timestamps null: false end diff --git a/test/integration/requests/request_test.rb b/test/integration/requests/request_test.rb index b7895608..4cdbe331 100644 --- a/test/integration/requests/request_test.rb +++ b/test/integration/requests/request_test.rb @@ -578,7 +578,7 @@ def test_put_invalid_json assert_equal 400, status assert_equal 'Bad Request', json_response['errors'][0]['title'] - assert_match 'unexpected token at', json_response['errors'][0]['detail'] + assert_match "expected ',' or '}' after object value", json_response['errors'][0]['detail'] end def test_put_valid_json_but_array @@ -1367,7 +1367,11 @@ def test_deprecated_include_parameter_not_allowed end def test_deprecated_include_message - ActiveSupport::Deprecation.silenced = false + if ActiveSupport::Deprecation.respond_to?(:silenced=) + ActiveSupport::Deprecation.silenced = false + else + JSONAPI.deprecator.silenced = false + end original_config = JSONAPI.configuration.dup _out, err = capture_io do eval <<-CODE @@ -1377,7 +1381,11 @@ def test_deprecated_include_message assert_match /DEPRECATION WARNING: `allow_include` has been replaced by `default_allow_include_to_one` and `default_allow_include_to_many` options./, err ensure JSONAPI.configuration = original_config - ActiveSupport::Deprecation.silenced = true + if ActiveSupport::Deprecation.respond_to?(:silenced=) + ActiveSupport::Deprecation.silenced = true + else + JSONAPI.deprecator.silenced = true + end end diff --git a/test/test_helper.rb b/test/test_helper.rb index c1faea37..c82caeb0 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -23,7 +23,6 @@ ENV['DATABASE_URL'] ||= "sqlite3:test_db" require 'active_record/railtie' -require 'rails/test_help' require 'minitest/mock' require 'jsonapi-resources' require 'pry' @@ -42,7 +41,11 @@ config.json_key_format = :camelized_key end -ActiveSupport::Deprecation.silenced = true +if ActiveSupport::Deprecation.respond_to?(:silenced=) + ActiveSupport::Deprecation.silenced = true +else + JSONAPI.deprecator.silenced = true +end puts "Testing With RAILS VERSION #{Rails.version}" @@ -56,7 +59,7 @@ class TestApp < Rails::Application config.action_controller.action_on_unpermitted_parameters = :raise ActiveRecord::Schema.verbose = false - config.active_record.schema_format = :none + config.active_record.schema_format = Rails::VERSION::MAJOR >= 8 ? :ruby : :none config.active_support.test_order = :random config.active_support.halt_callback_chains_on_return_false = false @@ -67,9 +70,6 @@ class TestApp < Rails::Application end end -DatabaseCleaner.allow_remote_database_url = true -DatabaseCleaner.strategy = :transaction - module MyEngine class Engine < ::Rails::Engine isolate_namespace MyEngine @@ -191,6 +191,13 @@ def show_queries end TestApp.initialize! +require 'rails/test_help' + +# Disable foreign key constraints for SQLite tests +ActiveRecord::Base.connection.execute('PRAGMA foreign_keys = OFF') if ActiveRecord::Base.connection.adapter_name == 'SQLite' + +DatabaseCleaner.allow_remote_database_url = true +DatabaseCleaner.strategy = :transaction require File.expand_path('../fixtures/active_record', __FILE__) @@ -460,12 +467,12 @@ def run_in_transaction? true end - self.fixture_path = "#{Rails.root}/fixtures" + self.fixture_paths = ["#{Rails.root}/fixtures"] fixtures :all end class ActiveSupport::TestCase - self.fixture_path = "#{Rails.root}/fixtures" + self.fixture_paths = ["#{Rails.root}/fixtures"] fixtures :all setup do @routes = TestApp.routes @@ -473,7 +480,7 @@ class ActiveSupport::TestCase end class ActionDispatch::IntegrationTest - self.fixture_path = "#{Rails.root}/fixtures" + self.fixture_paths = ["#{Rails.root}/fixtures"] fixtures :all def assert_jsonapi_response(expected_status, msg = nil) diff --git a/test/unit/active_relation_resource_finder/join_manager_test.rb b/test/unit/active_relation_resource_finder/join_manager_test.rb index 840c90ee..5dfc9629 100644 --- a/test/unit/active_relation_resource_finder/join_manager_test.rb +++ b/test/unit/active_relation_resource_finder/join_manager_test.rb @@ -4,16 +4,7 @@ class JoinTreeTest < ActiveSupport::TestCase def db_true - case ActiveRecord::Base.connection.adapter_name - when 'SQLite' - if Rails::VERSION::MAJOR >= 6 || (Rails::VERSION::MAJOR >= 5 && ActiveRecord::VERSION::MINOR >= 2) - "1" - else - "'t'" - end - when 'PostgreSQL' - 'TRUE' - end + ActiveRecord::Base.connection.quoted_true end def test_no_added_joins diff --git a/test/unit/resource/resource_test.rb b/test/unit/resource/resource_test.rb index df2df173..c48ac1c4 100644 --- a/test/unit/resource/resource_test.rb +++ b/test/unit/resource/resource_test.rb @@ -433,8 +433,12 @@ def test_key_type_proc end def test_id_attr_deprecation + if ActiveSupport::Deprecation.respond_to?(:silenced=) + ActiveSupport::Deprecation.silenced = false + else + JSONAPI.deprecator.silenced = false + end - ActiveSupport::Deprecation.silenced = false _out, err = capture_io do eval <<-CODE class ProblemResource < JSONAPI::Resource @@ -442,10 +446,14 @@ class ProblemResource < JSONAPI::Resource end CODE end - assert_match /DEPRECATION WARNING: Id without format is no longer supported. Please remove ids from attributes, or specify a format./, err - ensure - ActiveSupport::Deprecation.silenced = true - end + assert_match /Id without format is no longer supported\. Please remove ids from attributes, or specify a format\./, err + ensure + if ActiveSupport::Deprecation.respond_to?(:silenced=) + ActiveSupport::Deprecation.silenced = true + else + JSONAPI.deprecator.silenced = true + end + end def test_id_attr_with_format _out, err = capture_io do