ibm_db 5.6.1 → 5.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/Makefile +13 -9
- data/ext/extconf.rb +176 -110
- data/ext/ibm_db.c +60 -0
- data/ext/ibm_db.o +0 -0
- data/ext/ibm_db.so +0 -0
- data/ext/mkmf.log +6 -6
- data/ext/ruby_ibm_db_cli.c +14 -10
- data/ext/ruby_ibm_db_cli.h +4 -0
- data/ext/ruby_ibm_db_cli.o +0 -0
- data/lib/IBM_DB.rb +2 -2
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1254 -277
- data/test/active_record/connection_adapters/fake_legacy_adapter.rb +17 -0
- data/test/active_record/connection_adapters/fake_misleading_legacy_adapter.rb +8 -0
- data/test/activejob/destroy_association_async_job_test.rb +62 -0
- data/test/activejob/destroy_association_async_test.rb +147 -11
- data/test/activejob/job_runtime_test.rb +41 -0
- data/test/activejob/unloadable_base_job.rb +3 -0
- data/test/cases/active_record_schema_test.rb +196 -0
- data/test/cases/active_record_test.rb +21 -0
- data/test/cases/adapter_prevent_writes_test.rb +26 -202
- data/test/cases/adapter_test.rb +592 -82
- data/test/cases/adapters/abstract_mysql_adapter/active_schema_test.rb +210 -0
- data/test/cases/adapters/abstract_mysql_adapter/adapter_prevent_writes_test.rb +111 -0
- data/test/cases/adapters/abstract_mysql_adapter/auto_increment_test.rb +48 -0
- data/test/cases/adapters/abstract_mysql_adapter/bind_parameter_test.rb +91 -0
- data/test/cases/adapters/abstract_mysql_adapter/case_sensitivity_test.rb +65 -0
- data/test/cases/adapters/abstract_mysql_adapter/charset_collation_test.rb +85 -0
- data/test/cases/adapters/abstract_mysql_adapter/connection_test.rb +267 -0
- data/test/cases/adapters/abstract_mysql_adapter/count_deleted_rows_with_lock_test.rb +29 -0
- data/test/cases/adapters/abstract_mysql_adapter/json_test.rb +24 -0
- data/test/cases/adapters/abstract_mysql_adapter/mysql_boolean_test.rb +102 -0
- data/test/cases/adapters/abstract_mysql_adapter/mysql_enum_test.rb +47 -0
- data/test/cases/adapters/abstract_mysql_adapter/mysql_explain_test.rb +71 -0
- data/test/cases/adapters/abstract_mysql_adapter/nested_deadlock_test.rb +191 -0
- data/test/cases/adapters/abstract_mysql_adapter/optimizer_hints_test.rb +69 -0
- data/test/cases/adapters/abstract_mysql_adapter/quoting_test.rb +49 -0
- data/test/cases/adapters/abstract_mysql_adapter/schema_migrations_test.rb +68 -0
- data/test/cases/adapters/abstract_mysql_adapter/schema_test.rb +130 -0
- data/test/cases/adapters/abstract_mysql_adapter/set_test.rb +32 -0
- data/test/cases/adapters/abstract_mysql_adapter/sp_test.rb +39 -0
- data/test/cases/adapters/abstract_mysql_adapter/sql_types_test.rb +16 -0
- data/test/cases/adapters/abstract_mysql_adapter/table_options_test.rb +125 -0
- data/test/cases/adapters/abstract_mysql_adapter/transaction_test.rb +204 -0
- data/test/cases/adapters/abstract_mysql_adapter/unsigned_type_test.rb +77 -0
- data/test/cases/adapters/abstract_mysql_adapter/virtual_column_test.rb +69 -0
- data/test/cases/adapters/abstract_mysql_adapter/warnings_test.rb +109 -0
- data/test/cases/adapters/mysql2/check_constraint_quoting_test.rb +35 -0
- data/test/cases/adapters/mysql2/dbconsole_test.rb +87 -0
- data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +136 -10
- data/test/cases/adapters/mysql2/mysql2_rake_test.rb +433 -0
- data/test/cases/adapters/postgresql/active_schema_test.rb +8 -4
- data/test/cases/adapters/postgresql/array_test.rb +6 -6
- data/test/cases/adapters/postgresql/bind_parameter_test.rb +52 -0
- data/test/cases/adapters/postgresql/bit_string_test.rb +2 -2
- data/test/cases/adapters/postgresql/bytea_test.rb +3 -3
- data/test/cases/adapters/postgresql/case_insensitive_test.rb +1 -1
- data/test/cases/adapters/postgresql/change_schema_test.rb +32 -1
- data/test/cases/adapters/postgresql/cidr_test.rb +17 -0
- data/test/cases/adapters/postgresql/citext_test.rb +7 -1
- data/test/cases/adapters/postgresql/collation_test.rb +1 -1
- data/test/cases/adapters/postgresql/composite_test.rb +1 -1
- data/test/cases/adapters/postgresql/connection_test.rb +43 -36
- data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +3 -2
- data/test/cases/adapters/postgresql/datatype_test.rb +9 -4
- data/test/cases/adapters/postgresql/date_test.rb +2 -2
- data/test/cases/adapters/postgresql/dbconsole_test.rb +109 -0
- data/test/cases/adapters/postgresql/deferred_constraints_test.rb +55 -0
- data/test/cases/adapters/postgresql/domain_test.rb +1 -1
- data/test/cases/adapters/postgresql/enum_test.rb +208 -8
- data/test/cases/adapters/postgresql/explain_test.rb +25 -6
- data/test/cases/adapters/postgresql/extension_migration_test.rb +51 -9
- data/test/cases/adapters/postgresql/foreign_table_test.rb +3 -3
- data/test/cases/adapters/postgresql/full_text_test.rb +1 -1
- data/test/cases/adapters/postgresql/geometric_test.rb +13 -6
- data/test/cases/adapters/postgresql/hstore_test.rb +22 -32
- data/test/cases/adapters/postgresql/infinity_test.rb +13 -2
- data/test/cases/adapters/postgresql/integer_test.rb +1 -1
- data/test/cases/adapters/postgresql/interval_test.rb +9 -17
- data/test/cases/adapters/postgresql/invertible_migration_test.rb +139 -0
- data/test/cases/adapters/postgresql/json_test.rb +5 -0
- data/test/cases/adapters/postgresql/ltree_test.rb +1 -1
- data/test/cases/adapters/postgresql/money_test.rb +17 -9
- data/test/cases/adapters/postgresql/network_test.rb +13 -1
- data/test/cases/adapters/postgresql/numbers_test.rb +18 -2
- data/test/cases/adapters/postgresql/optimizer_hints_test.rb +9 -9
- data/test/cases/adapters/postgresql/partitions_test.rb +5 -2
- data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +7 -110
- data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +403 -20
- data/test/cases/adapters/postgresql/postgresql_rake_test.rb +637 -0
- data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +1 -1
- data/test/cases/adapters/postgresql/quoting_test.rb +60 -1
- data/test/cases/adapters/postgresql/range_test.rb +185 -21
- data/test/cases/adapters/postgresql/referential_integrity_test.rb +29 -5
- data/test/cases/adapters/postgresql/rename_table_test.rb +35 -8
- data/test/cases/adapters/postgresql/schema_authorization_test.rb +2 -2
- data/test/cases/adapters/postgresql/schema_test.rb +270 -20
- data/test/cases/adapters/postgresql/serial_test.rb +5 -5
- data/test/cases/adapters/postgresql/statement_pool_test.rb +6 -2
- data/test/cases/adapters/postgresql/timestamp_test.rb +122 -5
- data/test/cases/adapters/postgresql/transaction_nested_test.rb +130 -6
- data/test/cases/adapters/postgresql/transaction_test.rb +37 -11
- data/test/cases/adapters/postgresql/type_lookup_test.rb +1 -1
- data/test/cases/adapters/postgresql/uuid_test.rb +77 -9
- data/test/cases/adapters/postgresql/virtual_column_test.rb +114 -0
- data/test/cases/adapters/postgresql/xml_test.rb +1 -1
- data/test/cases/adapters/sqlite3/bind_parameter_test.rb +52 -0
- data/test/cases/adapters/sqlite3/collation_test.rb +1 -1
- data/test/cases/adapters/sqlite3/copy_table_test.rb +28 -7
- data/test/cases/adapters/sqlite3/dbconsole_test.rb +81 -0
- data/test/cases/adapters/sqlite3/explain_test.rb +3 -3
- data/test/cases/adapters/sqlite3/quoting_test.rb +34 -3
- data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +9 -102
- data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +727 -72
- data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +6 -3
- data/test/cases/adapters/sqlite3/sqlite_rake_test.rb +264 -0
- data/test/cases/adapters/sqlite3/statement_pool_test.rb +1 -1
- data/test/cases/adapters/sqlite3/transaction_test.rb +6 -3
- data/test/cases/adapters/sqlite3/virtual_column_test.rb +138 -0
- data/test/cases/adapters/sqlite3/virtual_table_test.rb +51 -0
- data/test/cases/adapters/trilogy/dbconsole_test.rb +76 -0
- data/test/cases/adapters/trilogy/trilogy_adapter_test.rb +473 -0
- data/test/cases/adapters/trilogy/trilogy_rake_test.rb +433 -0
- data/test/cases/aggregations_test.rb +16 -0
- data/test/cases/annotate_test.rb +14 -12
- data/test/cases/arel/attributes/attribute_test.rb +86 -47
- data/test/cases/arel/collectors/bind_test.rb +1 -1
- data/test/cases/arel/collectors/composite_test.rb +11 -1
- data/test/cases/arel/collectors/sql_string_test.rb +1 -1
- data/test/cases/arel/collectors/substitute_bind_collector_test.rb +1 -1
- data/test/cases/arel/delete_manager_test.rb +0 -6
- data/test/cases/arel/factory_methods_test.rb +45 -0
- data/test/cases/arel/insert_manager_test.rb +1 -7
- data/test/cases/arel/nodes/as_test.rb +12 -0
- data/test/cases/arel/nodes/ascending_test.rb +1 -1
- data/test/cases/arel/nodes/bin_test.rb +1 -1
- data/test/cases/arel/nodes/bound_sql_literal_test.rb +31 -0
- data/test/cases/arel/nodes/cte_test.rb +46 -0
- data/test/cases/arel/nodes/descending_test.rb +1 -1
- data/test/cases/arel/nodes/equality_test.rb +3 -3
- data/test/cases/arel/nodes/filter_test.rb +37 -0
- data/test/cases/arel/nodes/fragments_test.rb +38 -0
- data/test/cases/arel/nodes/homogeneous_in_test.rb +52 -0
- data/test/cases/arel/nodes/infix_operation_test.rb +1 -1
- data/test/cases/arel/nodes/node_test.rb +1 -1
- data/test/cases/arel/nodes/or_test.rb +2 -2
- data/test/cases/arel/nodes/sql_literal_test.rb +18 -1
- data/test/cases/arel/nodes/table_alias_test.rb +12 -0
- data/test/cases/arel/nodes/unary_operation_test.rb +1 -1
- data/test/cases/arel/nodes/update_statement_test.rb +4 -0
- data/test/cases/arel/nodes_test.rb +3 -2
- data/test/cases/arel/select_manager_test.rb +12 -12
- data/test/cases/arel/support/fake_record.rb +22 -17
- data/test/cases/arel/table_test.rb +15 -25
- data/test/cases/arel/update_manager_test.rb +51 -6
- data/test/cases/arel/visitors/dispatch_contamination_test.rb +1 -1
- data/test/cases/arel/visitors/dot_test.rb +177 -2
- data/test/cases/arel/visitors/mysql_test.rb +49 -1
- data/test/cases/arel/visitors/postgres_test.rb +1 -31
- data/test/cases/arel/visitors/sqlite_test.rb +1 -1
- data/test/cases/arel/visitors/to_sql_test.rb +330 -20
- data/test/cases/assertions/query_assertions_test.rb +136 -0
- data/test/cases/associations/belongs_to_associations_test.rb +502 -41
- data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +1 -1
- data/test/cases/associations/cascaded_eager_loading_test.rb +26 -15
- data/test/cases/associations/eager_load_nested_include_test.rb +1 -1
- data/test/cases/associations/eager_singularization_test.rb +1 -1
- data/test/cases/associations/eager_test.rb +255 -93
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +25 -53
- data/test/cases/associations/has_many_associations_test.rb +282 -72
- data/test/cases/associations/has_many_through_associations_test.rb +172 -45
- data/test/cases/associations/has_many_through_disable_joins_associations_test.rb +197 -0
- data/test/cases/associations/has_one_associations_test.rb +160 -29
- data/test/cases/associations/has_one_through_associations_test.rb +64 -15
- data/test/cases/associations/has_one_through_disable_joins_associations_test.rb +82 -0
- data/test/cases/associations/inner_join_association_test.rb +36 -6
- data/test/cases/associations/inverse_associations_test.rb +177 -40
- data/test/cases/associations/join_model_test.rb +17 -12
- data/test/cases/associations/left_outer_join_association_test.rb +14 -3
- data/test/cases/associations/nested_error_test.rb +116 -0
- data/test/cases/associations/nested_through_associations_test.rb +54 -19
- data/test/cases/associations/required_test.rb +1 -1
- data/test/cases/associations_test.rb +1278 -21
- data/test/cases/asynchronous_queries_test.rb +310 -0
- data/test/cases/attribute_methods/read_test.rb +6 -0
- data/test/cases/attribute_methods/time_zone_converter_test.rb +21 -0
- data/test/cases/attribute_methods_test.rb +565 -46
- data/test/cases/attributes_test.rb +42 -1
- data/test/cases/autosave_association_test.rb +645 -92
- data/test/cases/base_prevent_writes_test.rb +28 -159
- data/test/cases/base_test.rb +434 -209
- data/test/cases/batches_test.rb +441 -57
- data/test/cases/binary_test.rb +31 -0
- data/test/cases/bind_parameter_test.rb +107 -16
- data/test/cases/cache_key_test.rb +7 -7
- data/test/cases/calculations_test.rb +541 -110
- data/test/cases/callbacks_test.rb +0 -1
- data/test/cases/clone_test.rb +5 -4
- data/test/cases/coders/yaml_column_test.rb +97 -2
- data/test/cases/collection_cache_key_test.rb +24 -16
- data/test/cases/column_alias_test.rb +2 -8
- data/test/cases/column_definition_test.rb +12 -3
- data/test/cases/comment_test.rb +23 -26
- data/test/cases/connection_adapters/adapter_leasing_test.rb +9 -9
- data/test/cases/connection_adapters/connection_handler_test.rb +145 -99
- data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +79 -55
- data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +17 -20
- data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +146 -55
- data/test/cases/connection_adapters/connection_swapping_nested_test.rb +136 -23
- data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +96 -27
- data/test/cases/connection_adapters/mysql_type_lookup_test.rb +5 -5
- data/test/cases/connection_adapters/registration_test.rb +98 -0
- data/test/cases/connection_adapters/schema_cache_test.rb +288 -135
- data/test/cases/connection_adapters/standalone_connection_test.rb +38 -0
- data/test/cases/connection_adapters/statement_pool_test.rb +29 -0
- data/test/cases/connection_adapters/type_lookup_test.rb +12 -24
- data/test/cases/connection_handling_test.rb +210 -0
- data/test/cases/connection_management_test.rb +44 -7
- data/test/cases/connection_pool_test.rb +466 -99
- data/test/cases/core_test.rb +167 -9
- data/test/cases/counter_cache_test.rb +129 -2
- data/test/cases/custom_locking_test.rb +3 -3
- data/test/cases/database_configurations/hash_config_test.rb +149 -13
- data/test/cases/database_configurations/resolver_test.rb +14 -10
- data/test/cases/database_configurations/url_config_test.rb +53 -0
- data/test/cases/database_configurations_test.rb +86 -43
- data/test/cases/database_selector_test.rb +30 -8
- data/test/cases/database_statements_test.rb +10 -14
- data/test/cases/date_time_precision_test.rb +141 -11
- data/test/cases/date_time_test.rb +19 -1
- data/test/cases/defaults_test.rb +107 -41
- data/test/cases/delegated_type_test.rb +69 -9
- data/test/cases/dirty_test.rb +82 -25
- data/test/cases/disconnected_test.rb +10 -9
- data/test/cases/dup_test.rb +26 -6
- data/test/cases/encryption/cipher/aes256_gcm_test.rb +50 -0
- data/test/cases/encryption/cipher_test.rb +65 -0
- data/test/cases/encryption/concurrency_test.rb +27 -0
- data/test/cases/encryption/config_test.rb +21 -0
- data/test/cases/encryption/configurable_test.rb +93 -0
- data/test/cases/encryption/contexts_test.rb +105 -0
- data/test/cases/encryption/derived_secret_key_provider_test.rb +31 -0
- data/test/cases/encryption/deterministic_key_provider_test.rb +11 -0
- data/test/cases/encryption/encryptable_record_api_test.rb +175 -0
- data/test/cases/encryption/encryptable_record_message_pack_serialized_test.rb +42 -0
- data/test/cases/encryption/encryptable_record_test.rb +470 -0
- data/test/cases/encryption/encrypted_fixtures_test.rb +22 -0
- data/test/cases/encryption/encrypting_only_encryptor_test.rb +20 -0
- data/test/cases/encryption/encryption_schemes_test.rb +240 -0
- data/test/cases/encryption/encryptor_test.rb +113 -0
- data/test/cases/encryption/envelope_encryption_key_provider_test.rb +49 -0
- data/test/cases/encryption/extended_deterministic_queries_test.rb +81 -0
- data/test/cases/encryption/helper.rb +152 -0
- data/test/cases/encryption/key_generator_test.rb +55 -0
- data/test/cases/encryption/key_provider_test.rb +57 -0
- data/test/cases/encryption/key_test.rb +17 -0
- data/test/cases/encryption/message_pack_message_serializer_test.rb +70 -0
- data/test/cases/encryption/message_serializer_test.rb +82 -0
- data/test/cases/encryption/message_test.rb +43 -0
- data/test/cases/encryption/null_encryptor_test.rb +21 -0
- data/test/cases/encryption/properties_test.rb +69 -0
- data/test/cases/encryption/read_only_null_encryptor_test.rb +19 -0
- data/test/cases/encryption/scheme_test.rb +58 -0
- data/test/cases/encryption/unencrypted_attributes_test.rb +27 -0
- data/test/cases/encryption/uniqueness_validations_test.rb +65 -0
- data/test/cases/enum_test.rb +374 -72
- data/test/cases/errors_test.rb +7 -4
- data/test/cases/excluding_test.rb +116 -0
- data/test/cases/explain_subscriber_test.rb +6 -1
- data/test/cases/explain_test.rb +119 -10
- data/test/cases/filter_attributes_test.rb +7 -14
- data/test/cases/finder_respond_to_test.rb +3 -3
- data/test/cases/finder_test.rb +357 -72
- data/test/cases/fixture_set/file_test.rb +9 -0
- data/test/cases/fixtures_test.rb +426 -190
- data/test/cases/helper.rb +66 -192
- data/test/cases/hot_compatibility_test.rb +10 -10
- data/test/cases/inheritance_test.rb +51 -61
- data/test/cases/inherited_test.rb +40 -0
- data/test/cases/insert_all_test.rb +419 -9
- data/test/cases/instrumentation_test.rb +202 -30
- data/test/cases/integration_test.rb +25 -7
- data/test/cases/invalid_connection_test.rb +5 -5
- data/test/cases/invertible_migration_test.rb +108 -24
- data/test/cases/json_attribute_test.rb +1 -0
- data/test/cases/json_serialization_test.rb +5 -5
- data/test/cases/json_shared_test_cases.rb +5 -9
- data/test/cases/locking_test.rb +67 -31
- data/test/cases/log_subscriber_test.rb +17 -15
- data/test/cases/marshal_serialization_test.rb +78 -5
- data/test/cases/message_pack_test.rb +91 -0
- data/test/cases/migration/change_schema_test.rb +77 -46
- data/test/cases/migration/change_table_test.rb +129 -114
- data/test/cases/migration/check_constraint_test.rb +192 -10
- data/test/cases/migration/column_attributes_test.rb +4 -9
- data/test/cases/migration/column_positioning_test.rb +2 -2
- data/test/cases/migration/columns_test.rb +118 -4
- data/test/cases/migration/command_recorder_test.rb +181 -14
- data/test/cases/migration/compatibility_test.rb +883 -196
- data/test/cases/migration/create_join_table_test.rb +8 -1
- data/test/cases/migration/exclusion_constraint_test.rb +192 -0
- data/test/cases/migration/foreign_key_test.rb +356 -14
- data/test/cases/migration/helper.rb +4 -1
- data/test/cases/migration/index_test.rb +67 -2
- data/test/cases/migration/invalid_options_test.rb +129 -0
- data/test/cases/migration/logger_test.rb +7 -4
- data/test/cases/migration/pending_migrations_test.rb +103 -60
- data/test/cases/migration/references_foreign_key_test.rb +73 -4
- data/test/cases/migration/references_index_test.rb +25 -27
- data/test/cases/migration/references_statements_test.rb +27 -3
- data/test/cases/migration/rename_table_test.rb +39 -54
- data/test/cases/migration/schema_definitions_test.rb +109 -0
- data/test/cases/migration/unique_constraint_test.rb +248 -0
- data/test/cases/migration_test.rb +677 -220
- data/test/cases/migrator_test.rb +102 -75
- data/test/cases/multi_db_migrator_test.rb +55 -34
- data/test/cases/multiparameter_attributes_test.rb +26 -29
- data/test/cases/multiple_db_test.rb +42 -19
- data/test/cases/nested_attributes_test.rb +124 -6
- data/test/cases/nested_attributes_with_callbacks_test.rb +2 -2
- data/test/cases/normalized_attribute_test.rb +117 -0
- data/test/cases/null_relation_test.rb +35 -2
- data/test/cases/persistence/reload_association_cache_test.rb +20 -0
- data/test/cases/persistence_test.rb +629 -22
- data/test/cases/pooled_connections_test.rb +57 -56
- data/test/cases/prepared_statement_status_test.rb +8 -3
- data/test/cases/primary_class_test.rb +134 -0
- data/test/cases/primary_keys_test.rb +171 -55
- data/test/cases/query_cache_test.rb +558 -263
- data/test/cases/query_logs_test.rb +293 -0
- data/test/cases/quoting_test.rb +39 -72
- data/test/cases/readonly_test.rb +50 -12
- data/test/cases/reaper_test.rb +22 -6
- data/test/cases/reflection_test.rb +207 -9
- data/test/cases/relation/and_test.rb +43 -0
- data/test/cases/relation/delegation_test.rb +32 -5
- data/test/cases/relation/delete_all_test.rb +27 -6
- data/test/cases/relation/field_ordered_values_test.rb +128 -0
- data/test/cases/relation/load_async_test.rb +650 -0
- data/test/cases/relation/merging_test.rb +80 -109
- data/test/cases/relation/mutation_test.rb +12 -7
- data/test/cases/relation/or_test.rb +11 -8
- data/test/cases/relation/order_test.rb +90 -0
- data/test/cases/relation/predicate_builder_test.rb +21 -6
- data/test/cases/relation/select_test.rb +162 -3
- data/test/cases/relation/structural_compatibility_test.rb +38 -0
- data/test/cases/relation/update_all_test.rb +81 -27
- data/test/cases/relation/where_chain_test.rb +190 -3
- data/test/cases/relation/where_clause_test.rb +43 -1
- data/test/cases/relation/where_test.rb +95 -7
- data/test/cases/relation/with_test.rb +165 -0
- data/test/cases/relation_test.rb +42 -37
- data/test/cases/relations_test.rb +436 -138
- data/test/cases/reload_models_test.rb +18 -14
- data/test/cases/reserved_word_test.rb +2 -1
- data/test/cases/result_test.rb +14 -22
- data/test/cases/sanitize_test.rb +89 -27
- data/test/cases/schema_dumper_test.rb +535 -62
- data/test/cases/scoping/default_scoping_test.rb +219 -35
- data/test/cases/scoping/named_scoping_test.rb +25 -46
- data/test/cases/scoping/relation_scoping_test.rb +112 -4
- data/test/cases/secure_password_test.rb +108 -0
- data/test/cases/secure_token_test.rb +72 -0
- data/test/cases/serialization_test.rb +1 -1
- data/test/cases/serialized_attribute_test.rb +305 -60
- data/test/cases/shard_keys_test.rb +125 -0
- data/test/cases/shard_selector_test.rb +45 -0
- data/test/cases/signed_id_test.rb +57 -5
- data/test/cases/statement_cache_test.rb +31 -30
- data/test/cases/statement_invalid_test.rb +8 -4
- data/test/cases/store_test.rb +73 -9
- data/test/cases/strict_loading_test.rb +327 -13
- data/test/cases/table_metadata_test.rb +16 -0
- data/test/cases/tasks/database_tasks_test.rb +517 -244
- data/test/cases/test_case.rb +254 -60
- data/test/cases/test_case_test.rb +69 -0
- data/test/cases/test_databases_test.rb +7 -3
- data/test/cases/test_fixtures_test.rb +19 -40
- data/test/cases/time_precision_test.rb +17 -5
- data/test/cases/timestamp_test.rb +124 -16
- data/test/cases/token_for_test.rb +165 -0
- data/test/cases/touch_later_test.rb +43 -1
- data/test/cases/transaction_callbacks_test.rb +325 -8
- data/test/cases/transaction_instrumentation_test.rb +453 -0
- data/test/cases/transaction_isolation_test.rb +12 -8
- data/test/cases/transactions_test.rb +629 -112
- data/test/cases/type/date_time_test.rb +7 -1
- data/test/cases/type/time_test.rb +9 -0
- data/test/cases/type/type_map_test.rb +108 -73
- data/test/cases/type/unsigned_integer_test.rb +12 -0
- data/test/cases/type_caster/connection_test.rb +19 -0
- data/test/cases/type_test.rb +1 -1
- data/test/cases/unconnected_test.rb +7 -7
- data/test/cases/unsafe_raw_sql_test.rb +39 -8
- data/test/cases/validations/absence_validation_test.rb +1 -1
- data/test/cases/validations/association_validation_test.rb +25 -3
- data/test/cases/validations/numericality_validation_test.rb +3 -9
- data/test/cases/validations/presence_validation_test.rb +1 -1
- data/test/cases/validations/uniqueness_validation_test.rb +280 -40
- data/test/cases/validations_test.rb +2 -2
- data/test/cases/view_test.rb +33 -22
- data/test/cases/yaml_serialization_test.rb +23 -17
- data/test/config.example.yml +58 -56
- data/test/config.rb +1 -0
- data/test/fixtures/1_need_quoting.yml +2 -0
- data/test/fixtures/accounts.yml +5 -0
- data/test/fixtures/aircrafts.yml +7 -0
- data/test/fixtures/book_identifiers.yml +11 -0
- data/test/fixtures/books.yml +5 -4
- data/test/fixtures/cake_designers.yml +5 -0
- data/test/fixtures/cars.yml +6 -0
- data/test/fixtures/chefs.yml +5 -0
- data/test/fixtures/clothing_items.yml +23 -0
- data/test/fixtures/clubs.yml +1 -1
- data/test/fixtures/comments.yml +2 -1
- data/test/fixtures/cpk_authors.yml +8 -0
- data/test/fixtures/cpk_books.yml +21 -0
- data/test/fixtures/cpk_order_agreements.yml +13 -0
- data/test/fixtures/cpk_order_tags.yml +15 -0
- data/test/fixtures/cpk_orders.yml +11 -0
- data/test/fixtures/cpk_posts.yml +12 -0
- data/test/fixtures/cpk_reviews.yml +13 -0
- data/test/fixtures/cpk_tags.yml +11 -0
- data/test/fixtures/drink_designers.yml +5 -0
- data/test/fixtures/encrypted_book_that_ignores_cases.yml +4 -0
- data/test/fixtures/encrypted_books.yml +4 -0
- data/test/fixtures/fk_object_to_point_to.yml +2 -0
- data/test/fixtures/memberships.yml +15 -15
- data/test/fixtures/paragraphs.yml +5 -0
- data/test/fixtures/parrots.yml +4 -0
- data/test/fixtures/people.yml +2 -0
- data/test/fixtures/pirates.yml +2 -2
- data/test/fixtures/primary_key_error/primary_key_error.yml +6 -0
- data/test/fixtures/references.yml +3 -3
- data/test/fixtures/sharded_blog_posts.yml +14 -0
- data/test/fixtures/sharded_blog_posts_tags.yml +27 -0
- data/test/fixtures/sharded_blogs.yml +8 -0
- data/test/fixtures/sharded_comments.yml +22 -0
- data/test/fixtures/sharded_tags.yml +34 -0
- data/test/fixtures/sponsors.yml +2 -2
- data/test/fixtures/topics.yml +1 -0
- data/test/fixtures/treasures.yml +4 -0
- data/test/fixtures/virtual_columns.yml +5 -0
- data/test/fixtures/warehouse_things.yml +1 -1
- data/test/migrations/old_and_new_versions/20210716122844_add_people_description.rb +5 -0
- data/test/migrations/old_and_new_versions/20210716123013_add_people_number_of_legs.rb +5 -0
- data/test/migrations/old_and_new_versions/230_add_people_hobby.rb +5 -0
- data/test/migrations/old_and_new_versions/231_add_people_last_name.rb +5 -0
- data/test/migrations/scope/1_unscoped.rb +7 -0
- data/test/migrations/scope/2_mysql_only.mysql.rb +7 -0
- data/test/models/admin/user.rb +2 -0
- data/test/models/admin/user_json.rb +48 -0
- data/test/models/attachment.rb +7 -0
- data/test/models/author.rb +70 -3
- data/test/models/author_encrypted.rb +16 -0
- data/test/models/bird.rb +1 -1
- data/test/models/book.rb +18 -11
- data/test/models/book_destroy_async.rb +1 -1
- data/test/models/book_encrypted.rb +106 -0
- data/test/models/book_identifier.rb +5 -0
- data/test/models/branch.rb +11 -0
- data/test/models/bulb.rb +1 -1
- data/test/models/car.rb +8 -1
- data/test/models/cat.rb +1 -1
- data/test/models/category.rb +3 -1
- data/test/models/chat_message.rb +8 -0
- data/test/models/chef.rb +52 -0
- data/test/models/clothing_item.rb +12 -0
- data/test/models/club.rb +4 -1
- data/test/models/comment.rb +7 -4
- data/test/models/comment_overlapping_counter_cache.rb +15 -0
- data/test/models/company.rb +16 -2
- data/test/models/computer.rb +1 -0
- data/test/models/contact.rb +3 -3
- data/test/models/contract.rb +5 -1
- data/test/models/cpk/author.rb +9 -0
- data/test/models/cpk/book.rb +55 -0
- data/test/models/cpk/book_destroy_async.rb +9 -0
- data/test/models/cpk/car.rb +9 -0
- data/test/models/cpk/car_review.rb +9 -0
- data/test/models/cpk/chapter.rb +16 -0
- data/test/models/cpk/chapter_destroy_async.rb +10 -0
- data/test/models/cpk/comment.rb +9 -0
- data/test/models/cpk/order.rb +55 -0
- data/test/models/cpk/order_agreement.rb +10 -0
- data/test/models/cpk/order_tag.rb +10 -0
- data/test/models/cpk/post.rb +10 -0
- data/test/models/cpk/posts_tag.rb +10 -0
- data/test/models/cpk/review.rb +9 -0
- data/test/models/cpk/tag.rb +10 -0
- data/test/models/cpk.rb +15 -0
- data/test/models/customer.rb +3 -1
- data/test/models/destroy_async_parent.rb +1 -1
- data/test/models/developer.rb +44 -3
- data/test/models/discount.rb +4 -0
- data/test/models/drink_designer.rb +1 -0
- data/test/models/editor.rb +8 -0
- data/test/models/editorship.rb +6 -0
- data/test/models/entry.rb +5 -0
- data/test/models/essay.rb +6 -1
- data/test/models/essay_destroy_async.rb +1 -0
- data/test/models/eye.rb +87 -21
- data/test/models/face.rb +1 -1
- data/test/models/friendship.rb +3 -0
- data/test/models/hardback.rb +7 -0
- data/test/models/hotel.rb +2 -0
- data/test/models/human.rb +2 -2
- data/test/models/invoice.rb +2 -1
- data/test/models/invokes_an_undefined_method.rb +5 -0
- data/test/models/line_item.rb +6 -0
- data/test/models/member.rb +9 -4
- data/test/models/membership.rb +2 -2
- data/test/models/message.rb +2 -1
- data/test/models/need_quoting.rb +5 -0
- data/test/models/paragraph.rb +5 -0
- data/test/models/parrot.rb +6 -3
- data/test/models/person.rb +7 -4
- data/test/models/pirate.rb +4 -1
- data/test/models/pk_autopopulated_by_a_trigger_record.rb +5 -0
- data/test/models/post.rb +65 -2
- data/test/models/post_encrypted.rb +15 -0
- data/test/models/post_with_prefetched_pk.rb +15 -0
- data/test/models/project.rb +1 -0
- data/test/models/publication.rb +16 -0
- data/test/models/raises_argument_error.rb +5 -0
- data/test/models/raises_no_method_error.rb +5 -0
- data/test/models/recipient.rb +5 -0
- data/test/models/reference.rb +1 -1
- data/test/models/reply.rb +1 -1
- data/test/models/room.rb +3 -0
- data/test/models/sharded/blog.rb +12 -0
- data/test/models/sharded/blog_post.rb +17 -0
- data/test/models/sharded/blog_post_destroy_async.rb +14 -0
- data/test/models/sharded/blog_post_tag.rb +11 -0
- data/test/models/sharded/blog_post_with_revision.rb +11 -0
- data/test/models/sharded/comment.rb +12 -0
- data/test/models/sharded/comment_destroy_async.rb +12 -0
- data/test/models/sharded/tag.rb +11 -0
- data/test/models/sharded.rb +8 -0
- data/test/models/ship.rb +1 -1
- data/test/models/shipping_line.rb +11 -0
- data/test/models/subscriber.rb +1 -0
- data/test/models/subscription.rb +3 -1
- data/test/models/too_long_table_name.rb +5 -0
- data/test/models/topic.rb +3 -1
- data/test/models/traffic_light.rb +2 -2
- data/test/models/traffic_light_encrypted.rb +21 -0
- data/test/models/translation.rb +9 -0
- data/test/models/treasure.rb +1 -1
- data/test/models/tyre.rb +1 -1
- data/test/models/user.rb +16 -0
- data/test/models/user_with_invalid_relation.rb +28 -0
- data/test/models/uuid_comment.rb +5 -0
- data/test/models/uuid_entry.rb +5 -0
- data/test/models/uuid_message.rb +5 -0
- data/test/models/zine.rb +2 -1
- data/test/schema/mysql2_specific_schema.rb +26 -12
- data/test/schema/postgresql_specific_schema.rb +121 -13
- data/test/schema/schema.rb +361 -103
- data/test/schema/sqlite_specific_schema.rb +17 -6
- data/test/schema/trilogy_specific_schema.rb +96 -0
- data/test/support/adapter_helper.rb +104 -0
- data/test/support/async_helper.rb +15 -0
- data/test/support/config.rb +1 -1
- data/test/support/connection.rb +14 -2
- data/test/support/ddl_helper.rb +1 -1
- data/test/support/fake_adapter.rb +42 -0
- data/test/support/load_schema_helper.rb +22 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic_associations.dump +0 -0
- data/test/support/schema_dumping_helper.rb +15 -9
- data/test/support/tools.rb +37 -0
- data/test/support/yaml_compatibility_fixtures/rails_4_1_no_symbol.yml +22 -0
- metadata +247 -15
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cases/encryption/helper"
|
|
4
|
+
|
|
5
|
+
class ActiveRecord::Encryption::KeyGeneratorTest < ActiveRecord::EncryptionTestCase
|
|
6
|
+
setup do
|
|
7
|
+
@generator = ActiveRecord::Encryption::KeyGenerator.new
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
test "generate_random_key generates random keys with the cipher key length by default" do
|
|
11
|
+
assert_not_equal @generator.generate_random_key, @generator.generate_random_key
|
|
12
|
+
assert_equal ActiveRecord::Encryption.cipher.key_length, @generator.generate_random_key.bytesize
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
test "generate_random_key generates random keys with a custom length" do
|
|
16
|
+
assert_not_equal @generator.generate_random_key(length: 10), @generator.generate_random_key(length: 10)
|
|
17
|
+
assert_equal 10, @generator.generate_random_key(length: 10).bytesize
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
test "generate_random_hex_key generates random hexadecimal keys with the cipher key length by default" do
|
|
21
|
+
assert_not_equal @generator.generate_random_hex_key, @generator.generate_random_hex_key
|
|
22
|
+
assert_equal ActiveRecord::Encryption.cipher.key_length, [ @generator.generate_random_hex_key ].pack("H*").bytesize
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
test "generate_random_hex_key generates random hexadecimal keys with a custom length" do
|
|
26
|
+
assert_not_equal @generator.generate_random_hex_key(length: 10), @generator.generate_random_hex_key(length: 10)
|
|
27
|
+
assert_equal 10, [ @generator.generate_random_hex_key(length: 10) ].pack("H*").bytesize
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
test "derive keys using the configured digest algorithm" do
|
|
31
|
+
assert_derive_key "some secret", digest_class: OpenSSL::Digest::SHA1
|
|
32
|
+
assert_derive_key "some secret", digest_class: OpenSSL::Digest::SHA256
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
test "derive_key derives a key with from the provided password with the cipher key length by default" do
|
|
36
|
+
assert_equal @generator.derive_key_from("some password"), @generator.derive_key_from("some password")
|
|
37
|
+
assert_not_equal @generator.derive_key_from("some password"), @generator.derive_key_from("some other password")
|
|
38
|
+
assert_equal ActiveRecord::Encryption.cipher.key_length, @generator.derive_key_from("some password").length
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
test "derive_key derives a key with a custom length" do
|
|
42
|
+
assert_equal @generator.derive_key_from("some password", length: 12), @generator.derive_key_from("some password", length: 12)
|
|
43
|
+
assert_not_equal @generator.derive_key_from("some password", length: 12), @generator.derive_key_from("some other password", length: 12)
|
|
44
|
+
assert_equal 12, @generator.derive_key_from("some password", length: 12).length
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
def assert_derive_key(secret, digest_class: OpenSSL::Digest::SHA256, length: 20)
|
|
49
|
+
expected_derived_key = ActiveSupport::KeyGenerator.new(secret, hash_digest_class: digest_class)
|
|
50
|
+
.generate_key(ActiveRecord::Encryption.config.key_derivation_salt, length)
|
|
51
|
+
assert_equal length, expected_derived_key.length
|
|
52
|
+
ActiveRecord::Encryption.config.hash_digest_class = digest_class
|
|
53
|
+
assert_equal expected_derived_key, ActiveRecord::Encryption::KeyGenerator.new(hash_digest_class: digest_class).derive_key_from(secret, length: length)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cases/encryption/helper"
|
|
4
|
+
|
|
5
|
+
class ActiveRecord::Encryption::KeyProviderTest < ActiveRecord::EncryptionTestCase
|
|
6
|
+
setup do
|
|
7
|
+
@message ||= ActiveRecord::Encryption::Message.new(payload: "some secret")
|
|
8
|
+
@keys = build_keys(3)
|
|
9
|
+
@key_provider = ActiveRecord::Encryption::KeyProvider.new(@keys)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
test "serves a single key for encrypting and decrypting" do
|
|
13
|
+
key = @keys.first
|
|
14
|
+
key_provider = ActiveRecord::Encryption::KeyProvider.new(key)
|
|
15
|
+
|
|
16
|
+
assert_equal key, key_provider.encryption_key
|
|
17
|
+
assert_equal [ key_provider.encryption_key ], key_provider.decryption_keys(@message)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
test "serves the last key for encrypting" do
|
|
21
|
+
assert_equal @keys.last, @key_provider.encryption_key
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
test "when store_key_references is false, the encryption key contains a reference to the key itself" do
|
|
25
|
+
assert_nil @key_provider.encryption_key.public_tags.encrypted_data_key_id
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
test "when store_key_references is true, the encryption key contains a reference to the key itself" do
|
|
29
|
+
ActiveRecord::Encryption.config.store_key_references = true
|
|
30
|
+
|
|
31
|
+
assert_equal @keys.last.id, @key_provider.encryption_key.public_tags.encrypted_data_key_id
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
test "when the message does not contain any key reference, it returns all the keys" do
|
|
35
|
+
assert_equal @keys, @key_provider.decryption_keys(@message)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
test "when the message to decrypt contains a reference to the key id, it will return an array only with that message" do
|
|
39
|
+
target_key = @keys[1]
|
|
40
|
+
|
|
41
|
+
@message.headers.encrypted_data_key_id = target_key.id
|
|
42
|
+
|
|
43
|
+
assert_equal [target_key], @key_provider.decryption_keys(@message)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
test "work with multiple keys when config.store_key_references is false" do
|
|
47
|
+
ActiveRecord::Encryption.config.store_key_references = false
|
|
48
|
+
|
|
49
|
+
assert_encryptor_works_with @key_provider
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
test "work with multiple keys when config.store_key_references is true" do
|
|
53
|
+
ActiveRecord::Encryption.config.store_key_references = true
|
|
54
|
+
|
|
55
|
+
assert_encryptor_works_with @key_provider
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cases/encryption/helper"
|
|
4
|
+
|
|
5
|
+
class ActiveRecord::Encryption::KeyTest < ActiveRecord::EncryptionTestCase
|
|
6
|
+
test "A key can store a secret and public tags" do
|
|
7
|
+
key = ActiveRecord::Encryption::Key.new("the secret")
|
|
8
|
+
key.public_tags[:key] = "the key reference"
|
|
9
|
+
|
|
10
|
+
assert_equal "the secret", key.secret
|
|
11
|
+
assert_equal "the key reference", key.public_tags[:key]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
test ".derive_from instantiates a key with its secret derived from the passed password" do
|
|
15
|
+
assert_equal ActiveRecord::Encryption.key_generator.derive_key_from("some password"), ActiveRecord::Encryption::Key.derive_from("some password").secret
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cases/encryption/helper"
|
|
4
|
+
require "base64"
|
|
5
|
+
require "active_record/encryption/message_pack_message_serializer"
|
|
6
|
+
|
|
7
|
+
class ActiveRecord::Encryption::MessagePackMessageSerializerTest < ActiveRecord::EncryptionTestCase
|
|
8
|
+
setup do
|
|
9
|
+
@serializer = ActiveRecord::Encryption::MessagePackMessageSerializer.new
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
test "serializes messages" do
|
|
13
|
+
message = build_message
|
|
14
|
+
deserialized_message = serialize_and_deserialize(message)
|
|
15
|
+
assert_equal message, deserialized_message
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
test "serializes messages with nested messages in their headers" do
|
|
19
|
+
message = build_message
|
|
20
|
+
message.headers[:other_message] = ActiveRecord::Encryption::Message.new(payload: "some other secret payload", headers: { some_header: "some other value" })
|
|
21
|
+
|
|
22
|
+
deserialized_message = serialize_and_deserialize(message)
|
|
23
|
+
assert_equal message, deserialized_message
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
test "detects random data and raises a decryption error" do
|
|
27
|
+
assert_raises ActiveRecord::Encryption::Errors::Decryption do
|
|
28
|
+
@serializer.load "hey there"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
test "detects random JSON hashes and raises a decryption error" do
|
|
33
|
+
assert_raises ActiveRecord::Encryption::Errors::Decryption do
|
|
34
|
+
@serializer.load JSON.dump({ some: "other data" })
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
test "raises a TypeError when trying to deserialize other data types" do
|
|
39
|
+
assert_raises TypeError do
|
|
40
|
+
@serializer.load(:it_can_only_deserialize_strings)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
test "raises ForbiddenClass when trying to serialize other data types" do
|
|
45
|
+
assert_raises ActiveRecord::Encryption::Errors::ForbiddenClass do
|
|
46
|
+
@serializer.dump("it can only serialize messages!")
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
test "raises Decryption when trying to parse message with more than one nested message" do
|
|
51
|
+
message = build_message
|
|
52
|
+
message.headers[:other_message] = ActiveRecord::Encryption::Message.new(payload: "some other secret payload", headers: { some_header: "some other value" })
|
|
53
|
+
message.headers[:other_message].headers[:yet_another_message] = ActiveRecord::Encryption::Message.new(payload: "yet some other secret payload", headers: { some_header: "yet some other value" })
|
|
54
|
+
|
|
55
|
+
assert_raises ActiveRecord::Encryption::Errors::Decryption do
|
|
56
|
+
serialize_and_deserialize(message)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
def build_message
|
|
62
|
+
payload = "some payload"
|
|
63
|
+
headers = { key_1: "1" }
|
|
64
|
+
ActiveRecord::Encryption::Message.new(payload: payload, headers: headers)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def serialize_and_deserialize(message, with: @serializer)
|
|
68
|
+
@serializer.load @serializer.dump(message)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cases/encryption/helper"
|
|
4
|
+
require "base64"
|
|
5
|
+
|
|
6
|
+
class ActiveRecord::Encryption::MessageSerializerTest < ActiveRecord::EncryptionTestCase
|
|
7
|
+
setup do
|
|
8
|
+
@serializer = ActiveRecord::Encryption::MessageSerializer.new
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
test "serializes messages" do
|
|
12
|
+
message = build_message
|
|
13
|
+
deserialized_message = serialize_and_deserialize(message)
|
|
14
|
+
assert_equal message, deserialized_message
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
test "serializes messages with nested messages in their headers" do
|
|
18
|
+
message = build_message
|
|
19
|
+
message.headers[:other_message] = ActiveRecord::Encryption::Message.new(payload: "some other secret payload", headers: { some_header: "some other value" })
|
|
20
|
+
|
|
21
|
+
deserialized_message = serialize_and_deserialize(message)
|
|
22
|
+
assert_equal message, deserialized_message
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
test "won't load classes from JSON" do
|
|
26
|
+
class_loading_payload = JSON.dump({ p: ::Base64.strict_encode64("Some payload"), json_class: "MessageSerializerTest::SomeClassThatWillNeverExist" })
|
|
27
|
+
|
|
28
|
+
assert_raises(ArgumentError) { JSON.load(class_loading_payload) }
|
|
29
|
+
assert_nothing_raised { @serializer.load(class_loading_payload) }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
test "detects random JSON data and raises a decryption error" do
|
|
33
|
+
assert_raises ActiveRecord::Encryption::Errors::Decryption do
|
|
34
|
+
@serializer.load JSON.dump("hey there")
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
test "detects random JSON hashes and raises a decryption error" do
|
|
39
|
+
assert_raises ActiveRecord::Encryption::Errors::Decryption do
|
|
40
|
+
@serializer.load JSON.dump({ some: "other data" })
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
test "detects JSON hashes with a 'p' key that is not encoded in base64" do
|
|
45
|
+
assert_raises ActiveRecord::Encryption::Errors::Encoding do
|
|
46
|
+
@serializer.load JSON.dump({ p: "some data not encoded" })
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
test "raises a TypeError when trying to deserialize other data types" do
|
|
51
|
+
assert_raises TypeError do
|
|
52
|
+
@serializer.load(:it_can_only_deserialize_strings)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
test "raises ForbiddenClass when trying to serialize other data types" do
|
|
57
|
+
assert_raises ActiveRecord::Encryption::Errors::ForbiddenClass do
|
|
58
|
+
@serializer.dump("it can only serialize messages!")
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
test "raises Decryption when trying to parse message with more than one nested message" do
|
|
63
|
+
message = build_message
|
|
64
|
+
message.headers[:other_message] = ActiveRecord::Encryption::Message.new(payload: "some other secret payload", headers: { some_header: "some other value" })
|
|
65
|
+
message.headers[:other_message].headers[:yet_another_message] = ActiveRecord::Encryption::Message.new(payload: "yet some other secret payload", headers: { some_header: "yet some other value" })
|
|
66
|
+
|
|
67
|
+
assert_raises ActiveRecord::Encryption::Errors::Decryption do
|
|
68
|
+
serialize_and_deserialize(message)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
def build_message
|
|
74
|
+
payload = "some payload"
|
|
75
|
+
headers = { key_1: "1" }
|
|
76
|
+
ActiveRecord::Encryption::Message.new(payload: payload, headers: headers)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def serialize_and_deserialize(message, with: @serializer)
|
|
80
|
+
@serializer.load @serializer.dump(message)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cases/encryption/helper"
|
|
4
|
+
|
|
5
|
+
class ActiveRecord::Encryption::MessageTest < ActiveRecord::EncryptionTestCase
|
|
6
|
+
test "add_header lets you add headers" do
|
|
7
|
+
message = ActiveRecord::Encryption::Message.new
|
|
8
|
+
message.headers[:header_1] = "value 1"
|
|
9
|
+
|
|
10
|
+
assert_equal "value 1", message.headers[:header_1]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
test "add_headers lets you add multiple headers" do
|
|
14
|
+
message = ActiveRecord::Encryption::Message.new
|
|
15
|
+
message.headers.add(header_1: "value 1", header_2: "value 2")
|
|
16
|
+
assert_equal "value 1", message.headers[:header_1]
|
|
17
|
+
assert_equal "value 2", message.headers[:header_2]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
test "headers can't be overridden" do
|
|
21
|
+
message = ActiveRecord::Encryption::Message.new
|
|
22
|
+
message.headers.add(header_1: "value 1")
|
|
23
|
+
|
|
24
|
+
assert_raises(ActiveRecord::Encryption::Errors::EncryptedContentIntegrity) do
|
|
25
|
+
message.headers.add(header_1: "value 1")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
assert_raises(ActiveRecord::Encryption::Errors::EncryptedContentIntegrity) do
|
|
29
|
+
message.headers.add(header_1: "value 1")
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
test "validates that payloads are either nil or strings" do
|
|
34
|
+
assert_raises ActiveRecord::Encryption::Errors::ForbiddenClass do
|
|
35
|
+
ActiveRecord::Encryption::Message.new(payload: Date.new)
|
|
36
|
+
ActiveRecord::Encryption::Message.new(payload: [])
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
ActiveRecord::Encryption::Message.new
|
|
40
|
+
ActiveRecord::Encryption::Message.new(payload: "")
|
|
41
|
+
ActiveRecord::Encryption::Message.new(payload: "Some payload")
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cases/encryption/helper"
|
|
4
|
+
|
|
5
|
+
class ActiveRecord::Encryption::NullEncryptorTest < ActiveRecord::EncryptionTestCase
|
|
6
|
+
setup do
|
|
7
|
+
@encryptor = ActiveRecord::Encryption::NullEncryptor.new
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
test "encrypt returns the passed data" do
|
|
11
|
+
assert_equal "Some data", @encryptor.encrypt("Some data")
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
test "decrypt returns the passed data" do
|
|
15
|
+
assert_equal "Some data", @encryptor.decrypt("Some data")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
test "encrypted? returns false" do
|
|
19
|
+
assert_not @encryptor.encrypted?("Some data")
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cases/encryption/helper"
|
|
4
|
+
|
|
5
|
+
class ActiveRecord::EncryptionPropertiesTest < ActiveRecord::EncryptionTestCase
|
|
6
|
+
setup do
|
|
7
|
+
@properties = ActiveRecord::Encryption::Properties.new
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
test "behaves like a hash" do
|
|
11
|
+
@properties[:key_1] = "value 1"
|
|
12
|
+
@properties[:key_2] = "value 2"
|
|
13
|
+
|
|
14
|
+
assert_equal "value 1", @properties[:key_1]
|
|
15
|
+
assert_equal "value 2", @properties[:key_2]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
test "defines custom accessors for some default properties" do
|
|
19
|
+
auth_tag = "some auth tag"
|
|
20
|
+
|
|
21
|
+
@properties.auth_tag = auth_tag
|
|
22
|
+
assert_equal auth_tag, @properties.auth_tag
|
|
23
|
+
assert_equal auth_tag, @properties[:at]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
test "raises EncryptedContentIntegrity when trying to override properties" do
|
|
27
|
+
@properties[:key_1] = "value 1"
|
|
28
|
+
|
|
29
|
+
assert_raises ActiveRecord::Encryption::Errors::EncryptedContentIntegrity do
|
|
30
|
+
@properties[:key_1] = "value 1"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
test "add will add all the properties passed" do
|
|
35
|
+
@properties.add(key_1: "value 1", key_2: "value 2")
|
|
36
|
+
|
|
37
|
+
assert_equal "value 1", @properties[:key_1]
|
|
38
|
+
assert_equal "value 2", @properties[:key_2]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
test "validate allowed types on creation" do
|
|
42
|
+
example_of_valid_values.each do |value|
|
|
43
|
+
ActiveRecord::Encryption::Properties.new(some_value: value)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
assert_raises ActiveRecord::Encryption::Errors::ForbiddenClass do
|
|
47
|
+
ActiveRecord::Encryption::Properties.new(my_class: MyClass.new)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
test "validate allowed_types setting headers" do
|
|
52
|
+
example_of_valid_values.each.with_index do |value, index|
|
|
53
|
+
@properties["some_value_#{index}"] = value
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
assert_raises ActiveRecord::Encryption::Errors::ForbiddenClass do
|
|
57
|
+
@properties["some_value"] = MyClass.new
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
MyClass = Struct.new(:some_value)
|
|
62
|
+
|
|
63
|
+
class EncryptionMessageSubClass < ActiveRecord::Encryption::Message
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def example_of_valid_values
|
|
67
|
+
["a string", 123, 123.5, true, false, nil, :a_symbol, ActiveRecord::Encryption::Message.new, EncryptionMessageSubClass.new]
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cases/encryption/helper"
|
|
4
|
+
|
|
5
|
+
class ActiveRecord::Encryption::ReadOnlyNullEncryptorTest < ActiveRecord::EncryptionTestCase
|
|
6
|
+
setup do
|
|
7
|
+
@encryptor = ActiveRecord::Encryption::ReadOnlyNullEncryptor.new
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
test "decrypt returns the encrypted message" do
|
|
11
|
+
assert_equal "some text", @encryptor.decrypt("some text")
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
test "encrypt raises an Encryption" do
|
|
15
|
+
assert_raises ActiveRecord::Encryption::Errors::Encryption do
|
|
16
|
+
@encryptor.encrypt("some text")
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cases/encryption/helper"
|
|
4
|
+
require "models/book"
|
|
5
|
+
|
|
6
|
+
class ActiveRecord::Encryption::SchemeTest < ActiveRecord::EncryptionTestCase
|
|
7
|
+
test "validates config options when using encrypted attributes" do
|
|
8
|
+
assert_invalid_declaration deterministic: false, ignore_case: true
|
|
9
|
+
assert_invalid_declaration key: "1234", key_provider: ActiveRecord::Encryption::DerivedSecretKeyProvider.new("my secret")
|
|
10
|
+
assert_invalid_declaration compress: false, compressor: Zlib
|
|
11
|
+
assert_invalid_declaration compressor: Zlib, encryptor: ActiveRecord::Encryption::Encryptor.new
|
|
12
|
+
|
|
13
|
+
assert_valid_declaration deterministic: true
|
|
14
|
+
assert_valid_declaration key: "1234"
|
|
15
|
+
assert_valid_declaration key_provider: ActiveRecord::Encryption::DerivedSecretKeyProvider.new("my secret")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
test "should create a encryptor well when compressor is given" do
|
|
19
|
+
MyCompressor = Class.new do
|
|
20
|
+
def self.deflate(data)
|
|
21
|
+
"deflated #{data}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.inflate(data)
|
|
25
|
+
data.sub("deflated ", "")
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
type = declare_encrypts_with compressor: MyCompressor
|
|
30
|
+
|
|
31
|
+
assert_equal MyCompressor, type.scheme.to_h[:encryptor].compressor
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
test "should create a encryptor well when compress is false" do
|
|
35
|
+
type = declare_encrypts_with compress: false
|
|
36
|
+
|
|
37
|
+
assert_not type.scheme.to_h[:encryptor].compress?
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
def assert_invalid_declaration(**options)
|
|
42
|
+
assert_raises ActiveRecord::Encryption::Errors::Configuration do
|
|
43
|
+
declare_encrypts_with(options)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def assert_valid_declaration(**options)
|
|
48
|
+
assert_nothing_raised do
|
|
49
|
+
declare_encrypts_with(options)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def declare_encrypts_with(options)
|
|
54
|
+
Class.new(Book) do
|
|
55
|
+
encrypts :name, **options
|
|
56
|
+
end.type_for_attribute(:name)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cases/encryption/helper"
|
|
4
|
+
require "models/post_encrypted"
|
|
5
|
+
|
|
6
|
+
class ActiveRecord::Encryption::UnencryptedAttributesTest < ActiveRecord::EncryptionTestCase
|
|
7
|
+
test "when :support_unencrypted_data is off, it works with unencrypted attributes normally" do
|
|
8
|
+
ActiveRecord::Encryption.config.support_unencrypted_data = true
|
|
9
|
+
|
|
10
|
+
post = ActiveRecord::Encryption.without_encryption { EncryptedPost.create!(title: "The Starfleet is here!", body: "take cover!") }
|
|
11
|
+
assert_not_encrypted_attribute(post, :title, "The Starfleet is here!")
|
|
12
|
+
|
|
13
|
+
# It will encrypt on saving
|
|
14
|
+
post.update! title: "Other title"
|
|
15
|
+
assert_encrypted_attribute(post.reload, :title, "Other title")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
test "when :support_unencrypted_data is on, it won't work with unencrypted attributes" do
|
|
19
|
+
ActiveRecord::Encryption.config.support_unencrypted_data = false
|
|
20
|
+
|
|
21
|
+
post = ActiveRecord::Encryption.without_encryption { EncryptedPost.create!(title: "The Starfleet is here!", body: "take cover!") }
|
|
22
|
+
|
|
23
|
+
assert_raises ActiveRecord::Encryption::Errors::Decryption do
|
|
24
|
+
post.title
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cases/encryption/helper"
|
|
4
|
+
require "models/book_encrypted"
|
|
5
|
+
require "models/author_encrypted"
|
|
6
|
+
|
|
7
|
+
class ActiveRecord::Encryption::UniquenessValidationsTest < ActiveRecord::EncryptionTestCase
|
|
8
|
+
test "uniqueness validations work" do
|
|
9
|
+
EncryptedBookWithDowncaseName.create!(name: "dune")
|
|
10
|
+
assert_raises ActiveRecord::RecordInvalid do
|
|
11
|
+
EncryptedBookWithDowncaseName.create!(name: "dune")
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
test "uniqueness validations work when mixing encrypted an unencrypted data" do
|
|
16
|
+
ActiveRecord::Encryption.config.support_unencrypted_data = true
|
|
17
|
+
|
|
18
|
+
UnencryptedBook.create! name: "dune"
|
|
19
|
+
assert_raises ActiveRecord::RecordInvalid do
|
|
20
|
+
EncryptedBookWithDowncaseName.create!(name: "DUNE")
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
test "uniqueness validations do not work when mixing encrypted an unencrypted data and unencrypted data is opted out per-attribute" do
|
|
25
|
+
ActiveRecord::Encryption.config.support_unencrypted_data = true
|
|
26
|
+
|
|
27
|
+
UnencryptedBook.create! name: "dune"
|
|
28
|
+
assert_nothing_raised do
|
|
29
|
+
EncryptedBookWithUnencryptedDataOptedOut.create!(name: "dune")
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
test "uniqueness validations work when mixing encrypted an unencrypted data and unencrypted data is opted in per-attribute" do
|
|
34
|
+
ActiveRecord::Encryption.config.support_unencrypted_data = true
|
|
35
|
+
|
|
36
|
+
UnencryptedBook.create! name: "dune"
|
|
37
|
+
assert_raises ActiveRecord::RecordInvalid do
|
|
38
|
+
EncryptedBookWithUnencryptedDataOptedIn.create!(name: "dune")
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
test "uniqueness validations work when using old encryption schemes" do
|
|
43
|
+
ActiveRecord::Encryption.config.previous = [ { downcase: true, deterministic: true } ]
|
|
44
|
+
|
|
45
|
+
OldEncryptionBook = Class.new(UnencryptedBook) do
|
|
46
|
+
self.table_name = "encrypted_books"
|
|
47
|
+
|
|
48
|
+
validates :name, uniqueness: true
|
|
49
|
+
encrypts :name, deterministic: true, downcase: false
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
OldEncryptionBook.create! name: "dune"
|
|
53
|
+
|
|
54
|
+
assert_raises ActiveRecord::RecordInvalid do
|
|
55
|
+
OldEncryptionBook.create! name: "DUNE"
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
test "uniqueness validation does not revalidate the attribute with current encryption type" do
|
|
60
|
+
EncryptedBookWithUniquenessValidation.create!(name: "dune")
|
|
61
|
+
record = EncryptedBookWithUniquenessValidation.create(name: "dune")
|
|
62
|
+
|
|
63
|
+
assert_equal 1, record.errors.count
|
|
64
|
+
end
|
|
65
|
+
end
|