active_cached_resource 0.0.1.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +22 -0
- data/.standard.yml +2 -0
- data/CHANGELOG.md +5 -0
- data/README.md +45 -0
- data/Rakefile +21 -0
- data/example/consumer/.dockerignore +41 -0
- data/example/consumer/.gitattributes +9 -0
- data/example/consumer/.gitignore +36 -0
- data/example/consumer/.kamal/hooks/docker-setup.sample +3 -0
- data/example/consumer/.kamal/hooks/post-deploy.sample +14 -0
- data/example/consumer/.kamal/hooks/post-proxy-reboot.sample +3 -0
- data/example/consumer/.kamal/hooks/pre-build.sample +51 -0
- data/example/consumer/.kamal/hooks/pre-connect.sample +47 -0
- data/example/consumer/.kamal/hooks/pre-deploy.sample +109 -0
- data/example/consumer/.kamal/hooks/pre-proxy-reboot.sample +3 -0
- data/example/consumer/.kamal/secrets +17 -0
- data/example/consumer/Dockerfile +65 -0
- data/example/consumer/Gemfile +17 -0
- data/example/consumer/Rakefile +6 -0
- data/example/consumer/app/controllers/application_controller.rb +2 -0
- data/example/consumer/app/controllers/concerns/.keep +0 -0
- data/example/consumer/app/jobs/application_job.rb +7 -0
- data/example/consumer/app/mailers/application_mailer.rb +4 -0
- data/example/consumer/app/models/application_record.rb +3 -0
- data/example/consumer/app/models/concerns/.keep +0 -0
- data/example/consumer/app/models/person.rb +9 -0
- data/example/consumer/app/views/layouts/mailer.html.erb +13 -0
- data/example/consumer/app/views/layouts/mailer.text.erb +1 -0
- data/example/consumer/bin/brakeman +7 -0
- data/example/consumer/bin/bundle +109 -0
- data/example/consumer/bin/dev +2 -0
- data/example/consumer/bin/docker-entrypoint +14 -0
- data/example/consumer/bin/jobs +6 -0
- data/example/consumer/bin/kamal +27 -0
- data/example/consumer/bin/rails +4 -0
- data/example/consumer/bin/rake +4 -0
- data/example/consumer/bin/rubocop +8 -0
- data/example/consumer/bin/setup +34 -0
- data/example/consumer/bin/thrust +5 -0
- data/example/consumer/config/application.rb +20 -0
- data/example/consumer/config/boot.rb +3 -0
- data/example/consumer/config/cache.yml +16 -0
- data/example/consumer/config/credentials.yml.enc +1 -0
- data/example/consumer/config/database.yml +14 -0
- data/example/consumer/config/deploy.yml +116 -0
- data/example/consumer/config/environment.rb +5 -0
- data/example/consumer/config/environments/development.rb +64 -0
- data/example/consumer/config/environments/production.rb +85 -0
- data/example/consumer/config/environments/test.rb +50 -0
- data/example/consumer/config/initializers/cors.rb +16 -0
- data/example/consumer/config/initializers/filter_parameter_logging.rb +8 -0
- data/example/consumer/config/initializers/inflections.rb +16 -0
- data/example/consumer/config/locales/en.yml +31 -0
- data/example/consumer/config/puma.rb +41 -0
- data/example/consumer/config/queue.yml +18 -0
- data/example/consumer/config/recurring.yml +10 -0
- data/example/consumer/config/routes.rb +10 -0
- data/example/consumer/config.ru +6 -0
- data/example/consumer/db/cache_schema.rb +14 -0
- data/example/consumer/db/queue_schema.rb +129 -0
- data/example/consumer/db/seeds.rb +0 -0
- data/example/consumer/lib/tasks/.keep +0 -0
- data/example/consumer/log/.keep +0 -0
- data/example/consumer/public/robots.txt +1 -0
- data/example/consumer/script/.keep +0 -0
- data/example/consumer/storage/.keep +0 -0
- data/example/consumer/tmp/.keep +0 -0
- data/example/consumer/tmp/cache/.keep +0 -0
- data/example/consumer/tmp/pids/.keep +0 -0
- data/example/consumer/tmp/storage/.keep +0 -0
- data/example/consumer/vendor/.keep +0 -0
- data/example/provider/.dockerignore +41 -0
- data/example/provider/.gitattributes +9 -0
- data/example/provider/.gitignore +32 -0
- data/example/provider/.kamal/hooks/docker-setup.sample +3 -0
- data/example/provider/.kamal/hooks/post-deploy.sample +14 -0
- data/example/provider/.kamal/hooks/post-proxy-reboot.sample +3 -0
- data/example/provider/.kamal/hooks/pre-build.sample +51 -0
- data/example/provider/.kamal/hooks/pre-connect.sample +47 -0
- data/example/provider/.kamal/hooks/pre-deploy.sample +109 -0
- data/example/provider/.kamal/hooks/pre-proxy-reboot.sample +3 -0
- data/example/provider/.kamal/secrets +17 -0
- data/example/provider/Dockerfile +65 -0
- data/example/provider/Gemfile +14 -0
- data/example/provider/Rakefile +6 -0
- data/example/provider/app/controllers/application_controller.rb +2 -0
- data/example/provider/app/controllers/concerns/.keep +0 -0
- data/example/provider/app/controllers/people_controller.rb +68 -0
- data/example/provider/app/jobs/application_job.rb +7 -0
- data/example/provider/app/mailers/application_mailer.rb +4 -0
- data/example/provider/app/models/address.rb +3 -0
- data/example/provider/app/models/application_record.rb +3 -0
- data/example/provider/app/models/company.rb +3 -0
- data/example/provider/app/models/concerns/.keep +0 -0
- data/example/provider/app/models/person.rb +6 -0
- data/example/provider/app/views/layouts/mailer.html.erb +13 -0
- data/example/provider/app/views/layouts/mailer.text.erb +1 -0
- data/example/provider/bin/brakeman +7 -0
- data/example/provider/bin/bundle +109 -0
- data/example/provider/bin/dev +2 -0
- data/example/provider/bin/docker-entrypoint +14 -0
- data/example/provider/bin/jobs +6 -0
- data/example/provider/bin/kamal +27 -0
- data/example/provider/bin/rails +4 -0
- data/example/provider/bin/rake +4 -0
- data/example/provider/bin/rubocop +8 -0
- data/example/provider/bin/setup +34 -0
- data/example/provider/bin/thrust +5 -0
- data/example/provider/config/application.rb +44 -0
- data/example/provider/config/boot.rb +3 -0
- data/example/provider/config/cache.yml +16 -0
- data/example/provider/config/credentials.yml.enc +1 -0
- data/example/provider/config/database.yml +20 -0
- data/example/provider/config/deploy.yml +116 -0
- data/example/provider/config/environment.rb +5 -0
- data/example/provider/config/environments/development.rb +64 -0
- data/example/provider/config/environments/production.rb +85 -0
- data/example/provider/config/environments/test.rb +50 -0
- data/example/provider/config/initializers/cors.rb +16 -0
- data/example/provider/config/initializers/filter_parameter_logging.rb +8 -0
- data/example/provider/config/initializers/inflections.rb +16 -0
- data/example/provider/config/locales/en.yml +31 -0
- data/example/provider/config/puma.rb +41 -0
- data/example/provider/config/queue.yml +18 -0
- data/example/provider/config/recurring.yml +10 -0
- data/example/provider/config/routes.rb +4 -0
- data/example/provider/config.ru +6 -0
- data/example/provider/db/cache_schema.rb +14 -0
- data/example/provider/db/migrate/20241202183937_create_people.rb +11 -0
- data/example/provider/db/migrate/20241202183955_create_addresses.rb +13 -0
- data/example/provider/db/migrate/20241202184017_create_companies.rb +14 -0
- data/example/provider/db/queue_schema.rb +129 -0
- data/example/provider/db/schema.rb +47 -0
- data/example/provider/db/seeds.rb +18 -0
- data/example/provider/lib/tasks/.keep +0 -0
- data/example/provider/log/.keep +0 -0
- data/example/provider/public/robots.txt +1 -0
- data/example/provider/script/.keep +0 -0
- data/example/provider/storage/.keep +0 -0
- data/example/provider/tmp/.keep +0 -0
- data/example/provider/tmp/pids/.keep +0 -0
- data/example/provider/tmp/storage/.keep +0 -0
- data/example/provider/vendor/.keep +0 -0
- data/lib/active_cached_resource/caching.rb +176 -0
- data/lib/active_cached_resource/caching_strategies/active_support_cache.rb +31 -0
- data/lib/active_cached_resource/caching_strategies/base.rb +114 -0
- data/lib/active_cached_resource/caching_strategies/sql_cache.rb +32 -0
- data/lib/active_cached_resource/configuration.rb +50 -0
- data/lib/active_cached_resource/logger.rb +22 -0
- data/lib/active_cached_resource/model.rb +33 -0
- data/lib/active_cached_resource/version.rb +12 -0
- data/lib/active_cached_resource.rb +64 -0
- data/lib/activeresource/.gitignore +15 -0
- data/lib/activeresource/README.md +283 -0
- data/lib/activeresource/examples/performance.rb +72 -0
- data/lib/activeresource/lib/active_resource/active_job_serializer.rb +26 -0
- data/lib/activeresource/lib/active_resource/associations/builder/association.rb +32 -0
- data/lib/activeresource/lib/active_resource/associations/builder/belongs_to.rb +16 -0
- data/lib/activeresource/lib/active_resource/associations/builder/has_many.rb +14 -0
- data/lib/activeresource/lib/active_resource/associations/builder/has_one.rb +14 -0
- data/lib/activeresource/lib/active_resource/associations.rb +175 -0
- data/lib/activeresource/lib/active_resource/base.rb +1741 -0
- data/lib/activeresource/lib/active_resource/callbacks.rb +22 -0
- data/lib/activeresource/lib/active_resource/collection.rb +214 -0
- data/lib/activeresource/lib/active_resource/connection.rb +298 -0
- data/lib/activeresource/lib/active_resource/custom_methods.rb +129 -0
- data/lib/activeresource/lib/active_resource/exceptions.rb +98 -0
- data/lib/activeresource/lib/active_resource/formats/json_format.rb +28 -0
- data/lib/activeresource/lib/active_resource/formats/xml_format.rb +27 -0
- data/lib/activeresource/lib/active_resource/formats.rb +24 -0
- data/lib/activeresource/lib/active_resource/http_mock.rb +386 -0
- data/lib/activeresource/lib/active_resource/inheriting_hash.rb +34 -0
- data/lib/activeresource/lib/active_resource/log_subscriber.rb +26 -0
- data/lib/activeresource/lib/active_resource/railtie.rb +31 -0
- data/lib/activeresource/lib/active_resource/reflection.rb +78 -0
- data/lib/activeresource/lib/active_resource/schema.rb +60 -0
- data/lib/activeresource/lib/active_resource/singleton.rb +111 -0
- data/lib/activeresource/lib/active_resource/threadsafe_attributes.rb +65 -0
- data/lib/activeresource/lib/active_resource/validations.rb +176 -0
- data/lib/activeresource/lib/active_resource.rb +49 -0
- data/lib/activeresource/lib/activeresource.rb +3 -0
- data/lib/activeresource/test/abstract_unit.rb +153 -0
- data/lib/activeresource/test/cases/active_job_serializer_test.rb +53 -0
- data/lib/activeresource/test/cases/association_test.rb +104 -0
- data/lib/activeresource/test/cases/associations/builder/belongs_to_test.rb +42 -0
- data/lib/activeresource/test/cases/associations/builder/has_many_test.rb +28 -0
- data/lib/activeresource/test/cases/associations/builder/has_one_test.rb +28 -0
- data/lib/activeresource/test/cases/authorization_test.rb +276 -0
- data/lib/activeresource/test/cases/base/custom_methods_test.rb +155 -0
- data/lib/activeresource/test/cases/base/equality_test.rb +53 -0
- data/lib/activeresource/test/cases/base/load_test.rb +249 -0
- data/lib/activeresource/test/cases/base/schema_test.rb +428 -0
- data/lib/activeresource/test/cases/base_errors_test.rb +129 -0
- data/lib/activeresource/test/cases/base_test.rb +1622 -0
- data/lib/activeresource/test/cases/callbacks_test.rb +155 -0
- data/lib/activeresource/test/cases/collection_test.rb +172 -0
- data/lib/activeresource/test/cases/connection_test.rb +357 -0
- data/lib/activeresource/test/cases/finder_test.rb +217 -0
- data/lib/activeresource/test/cases/format_test.rb +137 -0
- data/lib/activeresource/test/cases/http_mock_test.rb +213 -0
- data/lib/activeresource/test/cases/inheritence_test.rb +19 -0
- data/lib/activeresource/test/cases/inheriting_hash_test.rb +25 -0
- data/lib/activeresource/test/cases/log_subscriber_test.rb +63 -0
- data/lib/activeresource/test/cases/reflection_test.rb +65 -0
- data/lib/activeresource/test/cases/validations_test.rb +78 -0
- data/lib/activeresource/test/fixtures/address.rb +20 -0
- data/lib/activeresource/test/fixtures/beast.rb +16 -0
- data/lib/activeresource/test/fixtures/comment.rb +5 -0
- data/lib/activeresource/test/fixtures/customer.rb +5 -0
- data/lib/activeresource/test/fixtures/inventory.rb +14 -0
- data/lib/activeresource/test/fixtures/person.rb +15 -0
- data/lib/activeresource/test/fixtures/pet.rb +6 -0
- data/lib/activeresource/test/fixtures/post.rb +5 -0
- data/lib/activeresource/test/fixtures/product.rb +11 -0
- data/lib/activeresource/test/fixtures/project.rb +19 -0
- data/lib/activeresource/test/fixtures/proxy.rb +6 -0
- data/lib/activeresource/test/fixtures/sound.rb +11 -0
- data/lib/activeresource/test/fixtures/street_address.rb +6 -0
- data/lib/activeresource/test/fixtures/subscription_plan.rb +7 -0
- data/lib/activeresource/test/fixtures/weather.rb +21 -0
- data/lib/activeresource/test/setter_trap.rb +28 -0
- data/lib/activeresource/test/singleton_test.rb +138 -0
- data/lib/activeresource/test/threadsafe_attributes_test.rb +91 -0
- data/lib/generators/active_cached_resource/install_generator.rb +31 -0
- data/lib/generators/active_cached_resource/templates/migration.erb +16 -0
- data/sorbet/config +4 -0
- data/sorbet/rbi/annotations/.gitattributes +1 -0
- data/sorbet/rbi/annotations/activemodel.rbi +89 -0
- data/sorbet/rbi/annotations/activesupport.rbi +457 -0
- data/sorbet/rbi/annotations/minitest.rbi +119 -0
- data/sorbet/rbi/annotations/rainbow.rbi +269 -0
- data/sorbet/rbi/dsl/.gitattributes +1 -0
- data/sorbet/rbi/dsl/active_support/callbacks.rbi +21 -0
- data/sorbet/rbi/gems/.gitattributes +1 -0
- data/sorbet/rbi/gems/actioncable@8.0.0.rbi +252 -0
- data/sorbet/rbi/gems/actionmailbox@8.0.0.rbi +9 -0
- data/sorbet/rbi/gems/actionmailer@8.0.0.rbi +9 -0
- data/sorbet/rbi/gems/actionpack@8.0.0.rbi +20909 -0
- data/sorbet/rbi/gems/actiontext@8.0.0.rbi +9 -0
- data/sorbet/rbi/gems/actionview@8.0.0.rbi +16207 -0
- data/sorbet/rbi/gems/activejob@8.0.0.rbi +9 -0
- data/sorbet/rbi/gems/activemodel-serializers-xml@1.0.3.rbi +166 -0
- data/sorbet/rbi/gems/activemodel@8.0.0.rbi +6857 -0
- data/sorbet/rbi/gems/activerecord@8.0.0.rbi +42896 -0
- data/sorbet/rbi/gems/activeresource@6.1.4.rbi +3944 -0
- data/sorbet/rbi/gems/activestorage@8.0.0.rbi +9 -0
- data/sorbet/rbi/gems/activesupport@8.0.0.rbi +21251 -0
- data/sorbet/rbi/gems/ast@2.4.2.rbi +585 -0
- data/sorbet/rbi/gems/base64@0.2.0.rbi +509 -0
- data/sorbet/rbi/gems/benchmark@0.4.0.rbi +618 -0
- data/sorbet/rbi/gems/bigdecimal@3.1.8.rbi +78 -0
- data/sorbet/rbi/gems/builder@3.3.0.rbi +9 -0
- data/sorbet/rbi/gems/bump@0.10.0.rbi +169 -0
- data/sorbet/rbi/gems/byebug@11.1.3.rbi +3607 -0
- data/sorbet/rbi/gems/coderay@1.1.3.rbi +3427 -0
- data/sorbet/rbi/gems/concurrent-ruby@1.3.4.rbi +11645 -0
- data/sorbet/rbi/gems/connection_pool@2.4.1.rbi +9 -0
- data/sorbet/rbi/gems/crass@1.0.6.rbi +623 -0
- data/sorbet/rbi/gems/date@3.4.0.rbi +75 -0
- data/sorbet/rbi/gems/diff-lcs@1.5.1.rbi +1131 -0
- data/sorbet/rbi/gems/docile@1.4.1.rbi +377 -0
- data/sorbet/rbi/gems/drb@2.2.1.rbi +1347 -0
- data/sorbet/rbi/gems/erubi@1.13.0.rbi +150 -0
- data/sorbet/rbi/gems/globalid@1.2.1.rbi +9 -0
- data/sorbet/rbi/gems/i18n@1.14.6.rbi +2359 -0
- data/sorbet/rbi/gems/io-console@0.7.2.rbi +9 -0
- data/sorbet/rbi/gems/json@2.8.2.rbi +1901 -0
- data/sorbet/rbi/gems/language_server-protocol@3.17.0.3.rbi +14238 -0
- data/sorbet/rbi/gems/lint_roller@1.1.0.rbi +240 -0
- data/sorbet/rbi/gems/logger@1.6.1.rbi +920 -0
- data/sorbet/rbi/gems/loofah@2.23.1.rbi +1081 -0
- data/sorbet/rbi/gems/mail@2.8.1.rbi +9 -0
- data/sorbet/rbi/gems/marcel@1.0.4.rbi +9 -0
- data/sorbet/rbi/gems/method_source@1.1.0.rbi +304 -0
- data/sorbet/rbi/gems/mini_mime@1.1.5.rbi +9 -0
- data/sorbet/rbi/gems/minitest@5.25.2.rbi +1547 -0
- data/sorbet/rbi/gems/net-imap@0.5.1.rbi +9 -0
- data/sorbet/rbi/gems/net-pop@0.1.2.rbi +9 -0
- data/sorbet/rbi/gems/net-protocol@0.2.2.rbi +292 -0
- data/sorbet/rbi/gems/net-smtp@0.5.0.rbi +9 -0
- data/sorbet/rbi/gems/netrc@0.11.0.rbi +159 -0
- data/sorbet/rbi/gems/nio4r@2.7.4.rbi +9 -0
- data/sorbet/rbi/gems/nokogiri@1.16.7.rbi +7311 -0
- data/sorbet/rbi/gems/parallel@1.26.3.rbi +291 -0
- data/sorbet/rbi/gems/parser@3.3.6.0.rbi +5519 -0
- data/sorbet/rbi/gems/prism@1.2.0.rbi +39085 -0
- data/sorbet/rbi/gems/pry-byebug@3.10.1.rbi +1151 -0
- data/sorbet/rbi/gems/pry@0.14.2.rbi +10076 -0
- data/sorbet/rbi/gems/psych@5.2.0.rbi +1785 -0
- data/sorbet/rbi/gems/racc@1.8.1.rbi +162 -0
- data/sorbet/rbi/gems/rack-session@2.0.0.rbi +727 -0
- data/sorbet/rbi/gems/rack-test@2.1.0.rbi +747 -0
- data/sorbet/rbi/gems/rack@3.1.8.rbi +4905 -0
- data/sorbet/rbi/gems/rackup@2.2.1.rbi +230 -0
- data/sorbet/rbi/gems/rails-dom-testing@2.2.0.rbi +758 -0
- data/sorbet/rbi/gems/rails-html-sanitizer@1.6.0.rbi +785 -0
- data/sorbet/rbi/gems/rails@8.0.0.rbi +9 -0
- data/sorbet/rbi/gems/railties@8.0.0.rbi +6287 -0
- data/sorbet/rbi/gems/rainbow@3.1.1.rbi +403 -0
- data/sorbet/rbi/gems/rake@13.2.1.rbi +3091 -0
- data/sorbet/rbi/gems/rbi@0.2.1.rbi +4535 -0
- data/sorbet/rbi/gems/rdoc@6.8.1.rbi +12572 -0
- data/sorbet/rbi/gems/regexp_parser@2.9.2.rbi +3772 -0
- data/sorbet/rbi/gems/reline@0.5.12.rbi +2416 -0
- data/sorbet/rbi/gems/rexml@3.3.9.rbi +4858 -0
- data/sorbet/rbi/gems/rspec-core@3.13.2.rbi +11287 -0
- data/sorbet/rbi/gems/rspec-expectations@3.13.3.rbi +8183 -0
- data/sorbet/rbi/gems/rspec-mocks@3.13.2.rbi +5341 -0
- data/sorbet/rbi/gems/rspec-support@3.13.1.rbi +1630 -0
- data/sorbet/rbi/gems/rspec@3.13.0.rbi +83 -0
- data/sorbet/rbi/gems/rubocop-ast@1.36.1.rbi +7303 -0
- data/sorbet/rbi/gems/rubocop-performance@1.21.1.rbi +9 -0
- data/sorbet/rbi/gems/rubocop@1.65.1.rbi +58170 -0
- data/sorbet/rbi/gems/ruby-progressbar@1.13.0.rbi +1318 -0
- data/sorbet/rbi/gems/securerandom@0.3.2.rbi +395 -0
- data/sorbet/rbi/gems/simplecov-html@0.13.1.rbi +225 -0
- data/sorbet/rbi/gems/simplecov@0.22.0.rbi +2149 -0
- data/sorbet/rbi/gems/simplecov_json_formatter@0.1.4.rbi +9 -0
- data/sorbet/rbi/gems/spoom@1.5.0.rbi +4932 -0
- data/sorbet/rbi/gems/standard-custom@1.0.2.rbi +9 -0
- data/sorbet/rbi/gems/standard-performance@1.4.0.rbi +9 -0
- data/sorbet/rbi/gems/standard@1.40.0.rbi +929 -0
- data/sorbet/rbi/gems/stringio@3.1.2.rbi +9 -0
- data/sorbet/rbi/gems/tapioca@0.16.4.rbi +3597 -0
- data/sorbet/rbi/gems/thor@1.3.2.rbi +4378 -0
- data/sorbet/rbi/gems/timeout@0.4.2.rbi +151 -0
- data/sorbet/rbi/gems/tzinfo@2.0.6.rbi +5918 -0
- data/sorbet/rbi/gems/unicode-display_width@2.6.0.rbi +66 -0
- data/sorbet/rbi/gems/uri@1.0.2.rbi +2377 -0
- data/sorbet/rbi/gems/useragent@0.16.10.rbi +9 -0
- data/sorbet/rbi/gems/websocket-driver@0.7.6.rbi +9 -0
- data/sorbet/rbi/gems/websocket-extensions@0.1.5.rbi +9 -0
- data/sorbet/rbi/gems/yard-sorbet@0.9.0.rbi +435 -0
- data/sorbet/rbi/gems/yard@0.9.37.rbi +18504 -0
- data/sorbet/rbi/gems/zeitwerk@2.7.1.rbi +9 -0
- data/sorbet/tapioca/config.yml +13 -0
- data/sorbet/tapioca/require.rb +12 -0
- metadata +543 -0
@@ -0,0 +1,1622 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "abstract_unit"
|
4
|
+
require "fixtures/person"
|
5
|
+
require "fixtures/customer"
|
6
|
+
require "fixtures/street_address"
|
7
|
+
require "fixtures/sound"
|
8
|
+
require "fixtures/beast"
|
9
|
+
require "fixtures/proxy"
|
10
|
+
require "fixtures/address"
|
11
|
+
require "fixtures/subscription_plan"
|
12
|
+
require "fixtures/post"
|
13
|
+
require "fixtures/comment"
|
14
|
+
require "fixtures/product"
|
15
|
+
require "fixtures/inventory"
|
16
|
+
require "active_support/json"
|
17
|
+
require "active_support/core_ext/hash/conversions"
|
18
|
+
require "mocha/minitest"
|
19
|
+
|
20
|
+
class BaseTest < ActiveSupport::TestCase
|
21
|
+
def setup
|
22
|
+
setup_response # find me in abstract_unit
|
23
|
+
@original_person_site = Person.site
|
24
|
+
@original_person_proxy = Person.proxy
|
25
|
+
end
|
26
|
+
|
27
|
+
def teardown
|
28
|
+
Person.site = @original_person_site
|
29
|
+
Person.proxy = @original_person_proxy
|
30
|
+
end
|
31
|
+
|
32
|
+
########################################################################
|
33
|
+
# Tests relating to setting up the API-connection configuration
|
34
|
+
########################################################################
|
35
|
+
|
36
|
+
def test_site_accessor_accepts_uri_or_string_argument
|
37
|
+
site = URI.parse("http://localhost")
|
38
|
+
|
39
|
+
assert_nothing_raised { Person.site = "http://localhost" }
|
40
|
+
assert_equal site, Person.site
|
41
|
+
|
42
|
+
assert_nothing_raised { Person.site = site }
|
43
|
+
assert_equal site, Person.site
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_should_use_site_prefix_and_credentials
|
47
|
+
assert_equal "http://foo:bar@beast.caboo.se", Forum.site.to_s
|
48
|
+
assert_equal "http://foo:bar@beast.caboo.se/forums/:forum_id", Topic.site.to_s
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_site_variable_can_be_reset
|
52
|
+
actor = Class.new(ActiveResource::Base)
|
53
|
+
assert_nil actor.site
|
54
|
+
actor.site = "http://localhost:31337"
|
55
|
+
actor.site = nil
|
56
|
+
assert_nil actor.site
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_proxy_accessor_accepts_uri_or_string_argument
|
60
|
+
proxy = URI.parse("http://localhost")
|
61
|
+
|
62
|
+
assert_nothing_raised { Person.proxy = "http://localhost" }
|
63
|
+
assert_equal proxy, Person.proxy
|
64
|
+
|
65
|
+
assert_nothing_raised { Person.proxy = proxy }
|
66
|
+
assert_equal proxy, Person.proxy
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_should_use_proxy_prefix_and_credentials
|
70
|
+
assert_equal "http://user:password@proxy.local:3000", ProxyResource.proxy.to_s
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_proxy_variable_can_be_reset
|
74
|
+
actor = Class.new(ActiveResource::Base)
|
75
|
+
assert_nil actor.site
|
76
|
+
actor.proxy = "http://localhost:31337"
|
77
|
+
actor.proxy = nil
|
78
|
+
assert_nil actor.site
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_should_accept_setting_user
|
82
|
+
Forum.user = "david"
|
83
|
+
assert_equal("david", Forum.user)
|
84
|
+
assert_equal("david", Forum.connection.user)
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_should_accept_setting_password
|
88
|
+
Forum.password = "test123"
|
89
|
+
assert_equal("test123", Forum.password)
|
90
|
+
assert_equal("test123", Forum.connection.password)
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_should_accept_setting_bearer_token
|
94
|
+
Forum.bearer_token = "token123"
|
95
|
+
assert_equal("token123", Forum.bearer_token)
|
96
|
+
assert_equal("token123", Forum.connection.bearer_token)
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_should_accept_setting_auth_type
|
100
|
+
Forum.auth_type = :digest
|
101
|
+
assert_equal(:digest, Forum.auth_type)
|
102
|
+
assert_equal(:digest, Forum.connection.auth_type)
|
103
|
+
|
104
|
+
Forum.auth_type = :bearer
|
105
|
+
assert_equal(:bearer, Forum.auth_type)
|
106
|
+
assert_equal(:bearer, Forum.connection.auth_type)
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_should_accept_setting_timeout
|
110
|
+
Forum.timeout = 5
|
111
|
+
assert_equal(5, Forum.timeout)
|
112
|
+
assert_equal(5, Forum.connection.timeout)
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_should_accept_setting_open_timeout
|
116
|
+
Forum.open_timeout = 5
|
117
|
+
assert_equal(5, Forum.open_timeout)
|
118
|
+
assert_equal(5, Forum.connection.open_timeout)
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_should_accept_setting_read_timeout
|
122
|
+
Forum.read_timeout = 5
|
123
|
+
assert_equal(5, Forum.read_timeout)
|
124
|
+
assert_equal(5, Forum.connection.read_timeout)
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_should_accept_setting_ssl_options
|
128
|
+
expected = { verify: 1 }
|
129
|
+
Forum.ssl_options = expected
|
130
|
+
assert_equal(expected, Forum.ssl_options)
|
131
|
+
assert_equal(expected, Forum.connection.ssl_options)
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_user_variable_can_be_reset
|
135
|
+
actor = Class.new(ActiveResource::Base)
|
136
|
+
actor.site = "http://cinema"
|
137
|
+
assert_nil actor.user
|
138
|
+
actor.user = "username"
|
139
|
+
actor.user = nil
|
140
|
+
assert_nil actor.user
|
141
|
+
assert_nil actor.connection.user
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_password_variable_can_be_reset
|
145
|
+
actor = Class.new(ActiveResource::Base)
|
146
|
+
actor.site = "http://cinema"
|
147
|
+
assert_nil actor.password
|
148
|
+
actor.password = "username"
|
149
|
+
actor.password = nil
|
150
|
+
assert_nil actor.password
|
151
|
+
assert_nil actor.connection.password
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_bearer_token_variable_can_be_reset
|
155
|
+
actor = Class.new(ActiveResource::Base)
|
156
|
+
actor.site = "http://cinema"
|
157
|
+
assert_nil actor.bearer_token
|
158
|
+
actor.bearer_token = "token"
|
159
|
+
actor.bearer_token = nil
|
160
|
+
assert_nil actor.bearer_token
|
161
|
+
assert_nil actor.connection.bearer_token
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_timeout_variable_can_be_reset
|
165
|
+
actor = Class.new(ActiveResource::Base)
|
166
|
+
actor.site = "http://cinema"
|
167
|
+
assert_nil actor.timeout
|
168
|
+
actor.timeout = 5
|
169
|
+
actor.timeout = nil
|
170
|
+
assert_nil actor.timeout
|
171
|
+
assert_nil actor.connection.timeout
|
172
|
+
end
|
173
|
+
|
174
|
+
def test_open_timeout_variable_can_be_reset
|
175
|
+
actor = Class.new(ActiveResource::Base)
|
176
|
+
actor.site = "http://cinema"
|
177
|
+
assert_nil actor.open_timeout
|
178
|
+
actor.open_timeout = 5
|
179
|
+
actor.open_timeout = nil
|
180
|
+
assert_nil actor.open_timeout
|
181
|
+
assert_nil actor.connection.open_timeout
|
182
|
+
end
|
183
|
+
|
184
|
+
def test_read_timeout_variable_can_be_reset
|
185
|
+
actor = Class.new(ActiveResource::Base)
|
186
|
+
actor.site = "http://cinema"
|
187
|
+
assert_nil actor.read_timeout
|
188
|
+
actor.read_timeout = 5
|
189
|
+
actor.read_timeout = nil
|
190
|
+
assert_nil actor.read_timeout
|
191
|
+
assert_nil actor.connection.read_timeout
|
192
|
+
end
|
193
|
+
|
194
|
+
def test_ssl_options_hash_can_be_reset
|
195
|
+
# SSL options are nil, resulting in an empty hash on the connection.
|
196
|
+
actor = Class.new(ActiveResource::Base)
|
197
|
+
actor.site = "https://cinema"
|
198
|
+
assert_nil actor.ssl_options
|
199
|
+
connection = actor.connection
|
200
|
+
assert_equal Hash.new, connection.ssl_options
|
201
|
+
|
202
|
+
# Setting SSL options wipes the connection.
|
203
|
+
actor.ssl_options = { foo: 5 }
|
204
|
+
assert_not_equal connection, actor.connection
|
205
|
+
connection = actor.connection
|
206
|
+
assert_equal 5, connection.ssl_options[:foo]
|
207
|
+
|
208
|
+
# Setting SSL options to nil also wipes the connection.
|
209
|
+
actor.ssl_options = nil
|
210
|
+
assert_not_equal connection, actor.connection
|
211
|
+
assert_equal Hash.new, actor.connection.ssl_options
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_credentials_from_site_are_decoded
|
215
|
+
actor = Class.new(ActiveResource::Base)
|
216
|
+
actor.site = "http://my%40email.com:%31%32%33@cinema"
|
217
|
+
assert_equal("my@email.com", actor.user)
|
218
|
+
assert_equal("123", actor.password)
|
219
|
+
end
|
220
|
+
|
221
|
+
def test_site_reader_uses_superclass_site_until_written
|
222
|
+
# Superclass is Object so returns nil.
|
223
|
+
assert_nil ActiveResource::Base.site
|
224
|
+
assert_nil Class.new(ActiveResource::Base).site
|
225
|
+
|
226
|
+
# Subclass uses superclass site.
|
227
|
+
actor = Class.new(Person)
|
228
|
+
assert_equal Person.site, actor.site
|
229
|
+
|
230
|
+
# Subclass returns frozen superclass copy.
|
231
|
+
assert_not Person.site.frozen?
|
232
|
+
assert actor.site.frozen?
|
233
|
+
|
234
|
+
# Changing subclass site doesn't change superclass site.
|
235
|
+
actor.site = "http://localhost:31337"
|
236
|
+
assert_not_equal Person.site, actor.site
|
237
|
+
|
238
|
+
# Changed subclass site is not frozen.
|
239
|
+
assert_not actor.site.frozen?
|
240
|
+
|
241
|
+
# Changing superclass site doesn't overwrite subclass site.
|
242
|
+
Person.site = "http://somewhere.else"
|
243
|
+
assert_not_equal Person.site, actor.site
|
244
|
+
|
245
|
+
# Changing superclass site after subclassing changes subclass site.
|
246
|
+
jester = Class.new(actor)
|
247
|
+
actor.site = "http://nomad"
|
248
|
+
assert_equal actor.site, jester.site
|
249
|
+
assert jester.site.frozen?
|
250
|
+
|
251
|
+
# Subclasses are always equal to superclass site when not overridden
|
252
|
+
fruit = Class.new(ActiveResource::Base)
|
253
|
+
apple = Class.new(fruit)
|
254
|
+
|
255
|
+
fruit.site = "http://market"
|
256
|
+
assert_equal fruit.site, apple.site, "subclass did not adopt changes from parent class"
|
257
|
+
|
258
|
+
fruit.site = "http://supermarket"
|
259
|
+
assert_equal fruit.site, apple.site, "subclass did not adopt changes from parent class"
|
260
|
+
end
|
261
|
+
|
262
|
+
def test_proxy_reader_uses_superclass_site_until_written
|
263
|
+
# Superclass is Object so returns nil.
|
264
|
+
assert_nil ActiveResource::Base.proxy
|
265
|
+
assert_nil Class.new(ActiveResource::Base).proxy
|
266
|
+
|
267
|
+
Person.proxy = "http://proxy.local"
|
268
|
+
|
269
|
+
# Subclass uses superclass proxy.
|
270
|
+
actor = Class.new(Person)
|
271
|
+
assert_equal Person.proxy, actor.proxy
|
272
|
+
|
273
|
+
# Subclass returns frozen superclass copy.
|
274
|
+
assert_not Person.proxy.frozen?
|
275
|
+
assert actor.proxy.frozen?
|
276
|
+
|
277
|
+
# Changing subclass proxy doesn't change superclass site.
|
278
|
+
actor.proxy = "http://localhost:31337"
|
279
|
+
assert_not_equal Person.proxy, actor.proxy
|
280
|
+
|
281
|
+
# Changed subclass proxy is not frozen.
|
282
|
+
assert_not actor.proxy.frozen?
|
283
|
+
|
284
|
+
# Changing superclass proxy doesn't overwrite subclass site.
|
285
|
+
Person.proxy = "http://somewhere.else"
|
286
|
+
assert_not_equal Person.proxy, actor.proxy
|
287
|
+
|
288
|
+
# Changing superclass proxy after subclassing changes subclass site.
|
289
|
+
jester = Class.new(actor)
|
290
|
+
actor.proxy = "http://nomad"
|
291
|
+
assert_equal actor.proxy, jester.proxy
|
292
|
+
assert jester.proxy.frozen?
|
293
|
+
|
294
|
+
# Subclasses are always equal to superclass proxy when not overridden
|
295
|
+
fruit = Class.new(ActiveResource::Base)
|
296
|
+
apple = Class.new(fruit)
|
297
|
+
|
298
|
+
fruit.proxy = "http://market"
|
299
|
+
assert_equal fruit.proxy, apple.proxy, "subclass did not adopt changes from parent class"
|
300
|
+
|
301
|
+
fruit.proxy = "http://supermarket"
|
302
|
+
assert_equal fruit.proxy, apple.proxy, "subclass did not adopt changes from parent class"
|
303
|
+
end
|
304
|
+
|
305
|
+
def test_user_reader_uses_superclass_user_until_written
|
306
|
+
# Superclass is Object so returns nil.
|
307
|
+
assert_nil ActiveResource::Base.user
|
308
|
+
assert_nil Class.new(ActiveResource::Base).user
|
309
|
+
person_user = Person.user
|
310
|
+
Person.user = "anonymous".dup
|
311
|
+
|
312
|
+
# Subclass uses superclass user.
|
313
|
+
actor = Class.new(Person)
|
314
|
+
assert_equal Person.user, actor.user
|
315
|
+
|
316
|
+
# Subclass returns frozen superclass copy.
|
317
|
+
assert_not Person.user.frozen?
|
318
|
+
assert actor.user.frozen?
|
319
|
+
|
320
|
+
# Changing subclass user doesn't change superclass user.
|
321
|
+
actor.user = "david"
|
322
|
+
assert_not_equal Person.user, actor.user
|
323
|
+
|
324
|
+
# Changing superclass user doesn't overwrite subclass user.
|
325
|
+
Person.user = "john"
|
326
|
+
assert_not_equal Person.user, actor.user
|
327
|
+
|
328
|
+
# Changing superclass user after subclassing changes subclass user.
|
329
|
+
jester = Class.new(actor)
|
330
|
+
actor.user = "john.doe"
|
331
|
+
assert_equal actor.user, jester.user
|
332
|
+
|
333
|
+
# Subclasses are always equal to superclass user when not overridden
|
334
|
+
fruit = Class.new(ActiveResource::Base)
|
335
|
+
apple = Class.new(fruit)
|
336
|
+
|
337
|
+
fruit.user = "manager"
|
338
|
+
assert_equal fruit.user, apple.user, "subclass did not adopt changes from parent class"
|
339
|
+
|
340
|
+
fruit.user = "client"
|
341
|
+
assert_equal fruit.user, apple.user, "subclass did not adopt changes from parent class"
|
342
|
+
ensure
|
343
|
+
Person.user = person_user
|
344
|
+
end
|
345
|
+
|
346
|
+
def test_password_reader_uses_superclass_password_until_written
|
347
|
+
# Superclass is Object so returns nil.
|
348
|
+
assert_nil ActiveResource::Base.password
|
349
|
+
assert_nil Class.new(ActiveResource::Base).password
|
350
|
+
Person.password = "my-password".dup
|
351
|
+
|
352
|
+
# Subclass uses superclass password.
|
353
|
+
actor = Class.new(Person)
|
354
|
+
assert_equal Person.password, actor.password
|
355
|
+
|
356
|
+
# Subclass returns frozen superclass copy.
|
357
|
+
assert_not Person.password.frozen?
|
358
|
+
assert actor.password.frozen?
|
359
|
+
|
360
|
+
# Changing subclass password doesn't change superclass password.
|
361
|
+
actor.password = "secret"
|
362
|
+
assert_not_equal Person.password, actor.password
|
363
|
+
|
364
|
+
# Changing superclass password doesn't overwrite subclass password.
|
365
|
+
Person.password = "super-secret"
|
366
|
+
assert_not_equal Person.password, actor.password
|
367
|
+
|
368
|
+
# Changing superclass password after subclassing changes subclass password.
|
369
|
+
jester = Class.new(actor)
|
370
|
+
actor.password = "even-more-secret"
|
371
|
+
assert_equal actor.password, jester.password
|
372
|
+
|
373
|
+
# Subclasses are always equal to superclass password when not overridden
|
374
|
+
fruit = Class.new(ActiveResource::Base)
|
375
|
+
apple = Class.new(fruit)
|
376
|
+
|
377
|
+
fruit.password = "mega-secret"
|
378
|
+
assert_equal fruit.password, apple.password, "subclass did not adopt changes from parent class"
|
379
|
+
|
380
|
+
fruit.password = "ok-password"
|
381
|
+
assert_equal fruit.password, apple.password, "subclass did not adopt changes from parent class"
|
382
|
+
end
|
383
|
+
|
384
|
+
def test_bearer_token_reader_uses_superclass_bearer_token_until_written
|
385
|
+
# Superclass is Object so returns nil.
|
386
|
+
assert_nil ActiveResource::Base.bearer_token
|
387
|
+
assert_nil Class.new(ActiveResource::Base).bearer_token
|
388
|
+
Person.bearer_token = "my-token".dup
|
389
|
+
|
390
|
+
# Subclass uses superclass bearer_token.
|
391
|
+
actor = Class.new(Person)
|
392
|
+
assert_equal Person.bearer_token, actor.bearer_token
|
393
|
+
|
394
|
+
# Subclass returns frozen superclass copy.
|
395
|
+
assert_not Person.bearer_token.frozen?
|
396
|
+
assert actor.bearer_token.frozen?
|
397
|
+
|
398
|
+
# Changing subclass bearer_token doesn't change superclass bearer_token.
|
399
|
+
actor.bearer_token = "token123"
|
400
|
+
assert_not_equal Person.bearer_token, actor.bearer_token
|
401
|
+
|
402
|
+
# Changing superclass bearer_token doesn't overwrite subclass bearer_token.
|
403
|
+
Person.bearer_token = "super-secret-token"
|
404
|
+
assert_not_equal Person.bearer_token, actor.bearer_token
|
405
|
+
|
406
|
+
# Changing superclass bearer_token after subclassing changes subclass bearer_token.
|
407
|
+
jester = Class.new(actor)
|
408
|
+
actor.bearer_token = "super-secret-token123"
|
409
|
+
assert_equal actor.bearer_token, jester.bearer_token
|
410
|
+
|
411
|
+
# Subclasses are always equal to superclass bearer_token when not overridden
|
412
|
+
fruit = Class.new(ActiveResource::Base)
|
413
|
+
apple = Class.new(fruit)
|
414
|
+
|
415
|
+
fruit.bearer_token = "mega-secret-token"
|
416
|
+
assert_equal fruit.bearer_token, apple.bearer_token, "subclass did not adopt changes from parent class"
|
417
|
+
|
418
|
+
fruit.bearer_token = "ok-token"
|
419
|
+
assert_equal fruit.bearer_token, apple.bearer_token, "subclass did not adopt changes from parent class"
|
420
|
+
|
421
|
+
Person.bearer_token = nil
|
422
|
+
end
|
423
|
+
|
424
|
+
def test_timeout_reader_uses_superclass_timeout_until_written
|
425
|
+
# Superclass is Object so returns nil.
|
426
|
+
assert_nil ActiveResource::Base.timeout
|
427
|
+
assert_nil Class.new(ActiveResource::Base).timeout
|
428
|
+
Person.timeout = 5
|
429
|
+
|
430
|
+
# Subclass uses superclass timeout.
|
431
|
+
actor = Class.new(Person)
|
432
|
+
assert_equal Person.timeout, actor.timeout
|
433
|
+
|
434
|
+
# Changing subclass timeout doesn't change superclass timeout.
|
435
|
+
actor.timeout = 10
|
436
|
+
assert_not_equal Person.timeout, actor.timeout
|
437
|
+
|
438
|
+
# Changing superclass timeout doesn't overwrite subclass timeout.
|
439
|
+
Person.timeout = 15
|
440
|
+
assert_not_equal Person.timeout, actor.timeout
|
441
|
+
|
442
|
+
# Changing superclass timeout after subclassing changes subclass timeout.
|
443
|
+
jester = Class.new(actor)
|
444
|
+
actor.timeout = 20
|
445
|
+
assert_equal actor.timeout, jester.timeout
|
446
|
+
|
447
|
+
# Subclasses are always equal to superclass timeout when not overridden.
|
448
|
+
fruit = Class.new(ActiveResource::Base)
|
449
|
+
apple = Class.new(fruit)
|
450
|
+
|
451
|
+
fruit.timeout = 25
|
452
|
+
assert_equal fruit.timeout, apple.timeout, "subclass did not adopt changes from parent class"
|
453
|
+
|
454
|
+
fruit.timeout = 30
|
455
|
+
assert_equal fruit.timeout, apple.timeout, "subclass did not adopt changes from parent class"
|
456
|
+
end
|
457
|
+
|
458
|
+
def test_open_and_read_timeout_readers_uses_superclass_timeout_until_written
|
459
|
+
# Superclass is Object so returns nil.
|
460
|
+
assert_nil ActiveResource::Base.open_timeout
|
461
|
+
assert_nil Class.new(ActiveResource::Base).open_timeout
|
462
|
+
assert_nil ActiveResource::Base.read_timeout
|
463
|
+
assert_nil Class.new(ActiveResource::Base).read_timeout
|
464
|
+
Person.open_timeout = 5
|
465
|
+
Person.read_timeout = 5
|
466
|
+
|
467
|
+
# Subclass uses superclass open and read timeouts.
|
468
|
+
actor = Class.new(Person)
|
469
|
+
assert_equal Person.open_timeout, actor.open_timeout
|
470
|
+
assert_equal Person.read_timeout, actor.read_timeout
|
471
|
+
|
472
|
+
# Changing subclass open and read timeouts doesn't change superclass timeouts.
|
473
|
+
actor.open_timeout = 10
|
474
|
+
actor.read_timeout = 10
|
475
|
+
assert_not_equal Person.open_timeout, actor.open_timeout
|
476
|
+
assert_not_equal Person.read_timeout, actor.read_timeout
|
477
|
+
|
478
|
+
# Changing superclass open and read timeouts doesn't overwrite subclass timeouts.
|
479
|
+
Person.open_timeout = 15
|
480
|
+
Person.read_timeout = 15
|
481
|
+
assert_not_equal Person.open_timeout, actor.open_timeout
|
482
|
+
assert_not_equal Person.read_timeout, actor.read_timeout
|
483
|
+
|
484
|
+
# Changing superclass open and read timeouts after subclassing changes subclass timeouts.
|
485
|
+
jester = Class.new(actor)
|
486
|
+
actor.open_timeout = 20
|
487
|
+
actor.read_timeout = 20
|
488
|
+
assert_equal actor.open_timeout, jester.open_timeout
|
489
|
+
assert_equal actor.read_timeout, jester.read_timeout
|
490
|
+
|
491
|
+
# Subclasses are always equal to superclass open and read timeouts when not overridden.
|
492
|
+
fruit = Class.new(ActiveResource::Base)
|
493
|
+
apple = Class.new(fruit)
|
494
|
+
|
495
|
+
fruit.open_timeout = 25
|
496
|
+
fruit.read_timeout = 25
|
497
|
+
assert_equal fruit.open_timeout, apple.open_timeout, "subclass did not adopt changes from parent class"
|
498
|
+
assert_equal fruit.read_timeout, apple.read_timeout, "subclass did not adopt changes from parent class"
|
499
|
+
|
500
|
+
fruit.open_timeout = 30
|
501
|
+
fruit.read_timeout = 30
|
502
|
+
assert_equal fruit.open_timeout, apple.open_timeout, "subclass did not adopt changes from parent class"
|
503
|
+
assert_equal fruit.read_timeout, apple.read_timeout, "subclass did not adopt changes from parent class"
|
504
|
+
end
|
505
|
+
|
506
|
+
def test_primary_key_uses_superclass_primary_key_until_written
|
507
|
+
# Superclass is Object so defaults to 'id'
|
508
|
+
assert_equal "id", ActiveResource::Base.primary_key
|
509
|
+
assert_equal "id", Class.new(ActiveResource::Base).primary_key
|
510
|
+
Person.primary_key = :first
|
511
|
+
|
512
|
+
# Subclass uses superclass primary_key
|
513
|
+
actor = Class.new(Person)
|
514
|
+
assert_equal Person.primary_key, actor.primary_key
|
515
|
+
|
516
|
+
# Changing subclass primary_key doesn't change superclass primary_key
|
517
|
+
actor.primary_key = :second
|
518
|
+
assert_not_equal Person.primary_key, actor.primary_key
|
519
|
+
|
520
|
+
# Changing superclass primary_key doesn't overwrite subclass primary_key
|
521
|
+
Person.primary_key = :third
|
522
|
+
assert_not_equal Person.primary_key, actor.primary_key
|
523
|
+
|
524
|
+
# Changing superclass primary_key after subclassing changes subclass primary_key
|
525
|
+
jester = Class.new(actor)
|
526
|
+
actor.primary_key = :fourth
|
527
|
+
assert_equal actor.primary_key, jester.primary_key
|
528
|
+
|
529
|
+
# Subclass primary_keys are always equal to superclass primary_key when not overridden
|
530
|
+
fruit = Class.new(ActiveResource::Base)
|
531
|
+
apple = Class.new(fruit)
|
532
|
+
|
533
|
+
fruit.primary_key = :fifth
|
534
|
+
assert_equal fruit.primary_key, apple.primary_key, "subclass did not adopt changes from parent class"
|
535
|
+
|
536
|
+
fruit.primary_key = :sixth
|
537
|
+
assert_equal fruit.primary_key, apple.primary_key, "subclass did not adopt changes from parent class"
|
538
|
+
|
539
|
+
# Reset the primary key for subsequent tests
|
540
|
+
Person.primary_key = "id"
|
541
|
+
end
|
542
|
+
|
543
|
+
def test_ssl_options_reader_uses_superclass_ssl_options_until_written
|
544
|
+
# Superclass is Object so returns nil.
|
545
|
+
assert_nil ActiveResource::Base.ssl_options
|
546
|
+
assert_nil Class.new(ActiveResource::Base).ssl_options
|
547
|
+
Person.ssl_options = { foo: "bar" }
|
548
|
+
|
549
|
+
# Subclass uses superclass ssl_options.
|
550
|
+
actor = Class.new(Person)
|
551
|
+
assert_equal Person.ssl_options, actor.ssl_options
|
552
|
+
|
553
|
+
# Changing subclass ssl_options doesn't change superclass ssl_options.
|
554
|
+
actor.ssl_options = { baz: "" }
|
555
|
+
assert_not_equal Person.ssl_options, actor.ssl_options
|
556
|
+
|
557
|
+
# Changing superclass ssl_options doesn't overwrite subclass ssl_options.
|
558
|
+
Person.ssl_options = { color: "blue" }
|
559
|
+
assert_not_equal Person.ssl_options, actor.ssl_options
|
560
|
+
|
561
|
+
# Changing superclass ssl_options after subclassing changes subclass ssl_options.
|
562
|
+
jester = Class.new(actor)
|
563
|
+
actor.ssl_options = { color: "red" }
|
564
|
+
assert_equal actor.ssl_options, jester.ssl_options
|
565
|
+
|
566
|
+
# Subclasses are always equal to superclass ssl_options when not overridden.
|
567
|
+
fruit = Class.new(ActiveResource::Base)
|
568
|
+
apple = Class.new(fruit)
|
569
|
+
|
570
|
+
fruit.ssl_options = { alpha: "betas" }
|
571
|
+
assert_equal fruit.ssl_options, apple.ssl_options, "subclass did not adopt changes from parent class"
|
572
|
+
|
573
|
+
fruit.ssl_options = { omega: "moos" }
|
574
|
+
assert_equal fruit.ssl_options, apple.ssl_options, "subclass did not adopt changes from parent class"
|
575
|
+
end
|
576
|
+
|
577
|
+
def test_updating_baseclass_site_object_wipes_descendent_cached_connection_objects
|
578
|
+
# Subclasses are always equal to superclass site when not overridden
|
579
|
+
fruit = Class.new(ActiveResource::Base)
|
580
|
+
apple = Class.new(fruit)
|
581
|
+
|
582
|
+
fruit.site = "http://market"
|
583
|
+
assert_equal fruit.connection.site, apple.connection.site
|
584
|
+
first_connection = apple.connection.object_id
|
585
|
+
|
586
|
+
fruit.site = "http://supermarket"
|
587
|
+
assert_equal fruit.connection.site, apple.connection.site
|
588
|
+
second_connection = apple.connection.object_id
|
589
|
+
assert_not_equal(first_connection, second_connection, "Connection should be re-created")
|
590
|
+
end
|
591
|
+
|
592
|
+
def test_updating_baseclass_user_wipes_descendent_cached_connection_objects
|
593
|
+
# Subclasses are always equal to superclass user when not overridden
|
594
|
+
fruit = Class.new(ActiveResource::Base)
|
595
|
+
apple = Class.new(fruit)
|
596
|
+
fruit.site = "http://market"
|
597
|
+
|
598
|
+
fruit.user = "david"
|
599
|
+
assert_equal fruit.connection.user, apple.connection.user
|
600
|
+
first_connection = apple.connection.object_id
|
601
|
+
|
602
|
+
fruit.user = "john"
|
603
|
+
assert_equal fruit.connection.user, apple.connection.user
|
604
|
+
second_connection = apple.connection.object_id
|
605
|
+
assert_not_equal(first_connection, second_connection, "Connection should be re-created")
|
606
|
+
end
|
607
|
+
|
608
|
+
def test_updating_baseclass_password_wipes_descendent_cached_connection_objects
|
609
|
+
# Subclasses are always equal to superclass password when not overridden
|
610
|
+
fruit = Class.new(ActiveResource::Base)
|
611
|
+
apple = Class.new(fruit)
|
612
|
+
fruit.site = "http://market"
|
613
|
+
|
614
|
+
fruit.password = "secret"
|
615
|
+
assert_equal fruit.connection.password, apple.connection.password
|
616
|
+
first_connection = apple.connection.object_id
|
617
|
+
|
618
|
+
fruit.password = "supersecret"
|
619
|
+
assert_equal fruit.connection.password, apple.connection.password
|
620
|
+
second_connection = apple.connection.object_id
|
621
|
+
assert_not_equal(first_connection, second_connection, "Connection should be re-created")
|
622
|
+
end
|
623
|
+
|
624
|
+
def test_updating_baseclass_bearer_token_wipes_descendent_cached_connection_objects
|
625
|
+
# Subclasses are always equal to superclass bearer_token when not overridden
|
626
|
+
fruit = Class.new(ActiveResource::Base)
|
627
|
+
apple = Class.new(fruit)
|
628
|
+
fruit.site = "http://market"
|
629
|
+
|
630
|
+
fruit.bearer_token = "my-token"
|
631
|
+
assert_equal fruit.connection.bearer_token, apple.connection.bearer_token
|
632
|
+
first_connection = apple.connection.object_id
|
633
|
+
|
634
|
+
fruit.bearer_token = "another-token"
|
635
|
+
assert_equal fruit.connection.bearer_token, apple.connection.bearer_token
|
636
|
+
second_connection = apple.connection.object_id
|
637
|
+
assert_not_equal(first_connection, second_connection, "Connection should be re-created")
|
638
|
+
end
|
639
|
+
|
640
|
+
def test_updating_baseclass_timeout_wipes_descendent_cached_connection_objects
|
641
|
+
# Subclasses are always equal to superclass timeout when not overridden
|
642
|
+
fruit = Class.new(ActiveResource::Base)
|
643
|
+
apple = Class.new(fruit)
|
644
|
+
fruit.site = "http://market"
|
645
|
+
|
646
|
+
fruit.timeout = 5
|
647
|
+
assert_equal fruit.connection.timeout, apple.connection.timeout
|
648
|
+
first_connection = apple.connection.object_id
|
649
|
+
|
650
|
+
fruit.timeout = 10
|
651
|
+
assert_equal fruit.connection.timeout, apple.connection.timeout
|
652
|
+
second_connection = apple.connection.object_id
|
653
|
+
assert_not_equal(first_connection, second_connection, "Connection should be re-created")
|
654
|
+
end
|
655
|
+
|
656
|
+
def test_updating_baseclass_read_and_open_timeouts_wipes_descendent_cached_connection_objects
|
657
|
+
# Subclasses are always equal to superclass timeout when not overridden
|
658
|
+
fruit = Class.new(ActiveResource::Base)
|
659
|
+
apple = Class.new(fruit)
|
660
|
+
fruit.site = "http://market"
|
661
|
+
|
662
|
+
fruit.open_timeout = 1
|
663
|
+
fruit.read_timeout = 5
|
664
|
+
assert_equal fruit.connection.open_timeout, apple.connection.open_timeout
|
665
|
+
assert_equal fruit.connection.read_timeout, apple.connection.read_timeout
|
666
|
+
first_connection = apple.connection.object_id
|
667
|
+
|
668
|
+
fruit.open_timeout = 2
|
669
|
+
fruit.read_timeout = 10
|
670
|
+
assert_equal fruit.connection.open_timeout, apple.connection.open_timeout
|
671
|
+
assert_equal fruit.connection.read_timeout, apple.connection.read_timeout
|
672
|
+
second_connection = apple.connection.object_id
|
673
|
+
assert_not_equal(first_connection, second_connection, "Connection should be re-created")
|
674
|
+
end
|
675
|
+
|
676
|
+
def test_header_inheritance
|
677
|
+
fruit = Class.new(ActiveResource::Base)
|
678
|
+
apple = Class.new(fruit)
|
679
|
+
fruit.site = "http://market"
|
680
|
+
|
681
|
+
fruit.headers["key"] = "value"
|
682
|
+
assert_equal "value", apple.headers["key"]
|
683
|
+
end
|
684
|
+
|
685
|
+
def test_header_inheritance_set_at_multiple_points
|
686
|
+
fruit = Class.new(ActiveResource::Base)
|
687
|
+
apple = Class.new(fruit)
|
688
|
+
fruit.site = "http://market"
|
689
|
+
|
690
|
+
fruit.headers["key"] = "value"
|
691
|
+
assert_equal "value", apple.headers["key"]
|
692
|
+
|
693
|
+
apple.headers["key2"] = "value2"
|
694
|
+
fruit.headers["key3"] = "value3"
|
695
|
+
|
696
|
+
assert_equal "value", apple.headers["key"]
|
697
|
+
assert_equal "value2", apple.headers["key2"]
|
698
|
+
assert_equal "value3", apple.headers["key3"]
|
699
|
+
end
|
700
|
+
|
701
|
+
def test_header_inheritance_should_not_leak_upstream
|
702
|
+
fruit = Class.new(ActiveResource::Base)
|
703
|
+
apple = Class.new(fruit)
|
704
|
+
fruit.site = "http://market"
|
705
|
+
|
706
|
+
fruit.headers["key"] = "value"
|
707
|
+
|
708
|
+
apple.headers["key2"] = "value2"
|
709
|
+
assert_nil fruit.headers["key2"]
|
710
|
+
end
|
711
|
+
|
712
|
+
def test_header_inheritance_can_override_upstream
|
713
|
+
fruit = Class.new(ActiveResource::Base)
|
714
|
+
apple = Class.new(fruit)
|
715
|
+
fruit.site = "http://market"
|
716
|
+
|
717
|
+
fruit.headers["key"] = "fruit-value"
|
718
|
+
assert_equal "fruit-value", apple.headers["key"]
|
719
|
+
|
720
|
+
apple.headers["key"] = "apple-value"
|
721
|
+
assert_equal "apple-value", apple.headers["key"]
|
722
|
+
assert_equal "fruit-value", fruit.headers["key"]
|
723
|
+
end
|
724
|
+
|
725
|
+
|
726
|
+
def test_header_inheritance_should_not_override_upstream_on_read
|
727
|
+
fruit = Class.new(ActiveResource::Base)
|
728
|
+
apple = Class.new(fruit)
|
729
|
+
fruit.site = "http://market"
|
730
|
+
|
731
|
+
fruit.headers["key"] = "value"
|
732
|
+
assert_equal "value", apple.headers["key"]
|
733
|
+
|
734
|
+
fruit.headers["key"] = "new-value"
|
735
|
+
assert_equal "new-value", apple.headers["key"]
|
736
|
+
end
|
737
|
+
|
738
|
+
def test_header_should_be_copied_to_main_thread_if_not_defined
|
739
|
+
fruit = Class.new(ActiveResource::Base)
|
740
|
+
|
741
|
+
Thread.new do
|
742
|
+
fruit.site = "http://market"
|
743
|
+
assert_equal "http://market", fruit.site.to_s
|
744
|
+
|
745
|
+
fruit.headers["key"] = "value"
|
746
|
+
assert_equal "value", fruit.headers["key"]
|
747
|
+
end.join
|
748
|
+
|
749
|
+
assert_equal "http://market", fruit.site.to_s
|
750
|
+
assert_equal "value", fruit.headers["key"]
|
751
|
+
end
|
752
|
+
|
753
|
+
def test_connection_should_use_connection_class
|
754
|
+
apple = Class.new(ActiveResource::Base)
|
755
|
+
orange = Class.new(ActiveResource::Base)
|
756
|
+
telephone = Class.new(ActiveResource::Connection)
|
757
|
+
orange.connection_class = telephone
|
758
|
+
apple.site = orange.site = "https://some-site.com/api"
|
759
|
+
|
760
|
+
assert_equal ActiveResource::Connection, apple.connection.class
|
761
|
+
assert_equal telephone, orange.connection.class
|
762
|
+
end
|
763
|
+
|
764
|
+
########################################################################
|
765
|
+
# Tests for setting up remote URLs for a given model (including adding
|
766
|
+
# parameters appropriately)
|
767
|
+
########################################################################
|
768
|
+
def test_collection_name
|
769
|
+
assert_equal "people", Person.collection_name
|
770
|
+
end
|
771
|
+
|
772
|
+
def test_collection_path
|
773
|
+
assert_equal "/people.json", Person.collection_path
|
774
|
+
end
|
775
|
+
|
776
|
+
def test_collection_path_with_parameters
|
777
|
+
assert_equal "/people.json?gender=male", Person.collection_path(gender: "male")
|
778
|
+
assert_equal "/people.json?gender=false", Person.collection_path(gender: false)
|
779
|
+
assert_equal "/people.json?gender=", Person.collection_path(gender: nil)
|
780
|
+
|
781
|
+
assert_equal "/people.json?gender=male", Person.collection_path("gender" => "male")
|
782
|
+
|
783
|
+
# Use includes? because ordering of param hash is not guaranteed
|
784
|
+
assert Person.collection_path(gender: "male", student: true).include?("/people.json?")
|
785
|
+
assert Person.collection_path(gender: "male", student: true).include?("gender=male")
|
786
|
+
assert Person.collection_path(gender: "male", student: true).include?("student=true")
|
787
|
+
|
788
|
+
assert_equal "/people.json?name%5B%5D=bob&name%5B%5D=your+uncle%2Bme&name%5B%5D=&name%5B%5D=false", Person.collection_path(name: ["bob", "your uncle+me", nil, false])
|
789
|
+
assert_equal "/people.json?struct%5Ba%5D%5B%5D=2&struct%5Ba%5D%5B%5D=1&struct%5Bb%5D=fred", Person.collection_path(struct: { :a => [2, 1], "b" => "fred" })
|
790
|
+
end
|
791
|
+
|
792
|
+
def test_custom_element_path
|
793
|
+
assert_equal "/people/1/addresses/1.json", StreetAddress.element_path(1, person_id: 1)
|
794
|
+
assert_equal "/people/1/addresses/1.json", StreetAddress.element_path(1, "person_id" => 1)
|
795
|
+
assert_equal "/people/Greg/addresses/1.json", StreetAddress.element_path(1, "person_id" => "Greg")
|
796
|
+
assert_equal "/people/ann%20mary/addresses/ann+mary.json", StreetAddress.element_path(:'ann mary', "person_id" => "ann mary")
|
797
|
+
end
|
798
|
+
|
799
|
+
def test_custom_element_path_without_required_prefix_param
|
800
|
+
assert_raise ActiveResource::MissingPrefixParam do
|
801
|
+
StreetAddress.element_path(1)
|
802
|
+
end
|
803
|
+
end
|
804
|
+
|
805
|
+
def test_module_element_path
|
806
|
+
assert_equal "/sounds/1.json", Asset::Sound.element_path(1)
|
807
|
+
end
|
808
|
+
|
809
|
+
def test_module_element_url
|
810
|
+
assert_equal "http://37s.sunrise.i:3000/sounds/1.json", Asset::Sound.element_url(1)
|
811
|
+
end
|
812
|
+
|
813
|
+
def test_custom_element_path_with_redefined_to_param
|
814
|
+
Person.module_eval do
|
815
|
+
alias_method :original_to_param_element_path, :to_param
|
816
|
+
def to_param
|
817
|
+
name
|
818
|
+
end
|
819
|
+
end
|
820
|
+
|
821
|
+
# Class method.
|
822
|
+
assert_equal "/people/Greg.json", Person.element_path("Greg")
|
823
|
+
|
824
|
+
# Protected Instance method.
|
825
|
+
assert_equal "/people/Greg.json", Person.find("Greg").send(:element_path)
|
826
|
+
|
827
|
+
ensure
|
828
|
+
# revert back to original
|
829
|
+
Person.module_eval do
|
830
|
+
# save the 'new' to_param so we don't get a warning about discarding the method
|
831
|
+
alias_method :element_path_to_param, :to_param
|
832
|
+
alias_method :to_param, :original_to_param_element_path
|
833
|
+
end
|
834
|
+
end
|
835
|
+
|
836
|
+
def test_custom_element_path_with_parameters
|
837
|
+
assert_equal "/people/1/addresses/1.json?type=work", StreetAddress.element_path(1, person_id: 1, type: "work")
|
838
|
+
assert_equal "/people/1/addresses/1.json?type=work", StreetAddress.element_path(1, "person_id" => 1, :type => "work")
|
839
|
+
assert_equal "/people/1/addresses/1.json?type=work", StreetAddress.element_path(1, type: "work", person_id: 1)
|
840
|
+
assert_equal "/people/1/addresses/1.json?type%5B%5D=work&type%5B%5D=play+time", StreetAddress.element_path(1, person_id: 1, type: ["work", "play time"])
|
841
|
+
end
|
842
|
+
|
843
|
+
def test_custom_element_path_with_prefix_and_parameters
|
844
|
+
assert_equal "/people/1/addresses/1.json?type=work", StreetAddress.element_path(1, { person_id: 1 }, { type: "work" })
|
845
|
+
end
|
846
|
+
|
847
|
+
def test_custom_collection_path_without_required_prefix_param
|
848
|
+
assert_raise ActiveResource::MissingPrefixParam do
|
849
|
+
StreetAddress.collection_path
|
850
|
+
end
|
851
|
+
end
|
852
|
+
|
853
|
+
def test_custom_collection_path
|
854
|
+
assert_equal "/people/1/addresses.json", StreetAddress.collection_path(person_id: 1)
|
855
|
+
assert_equal "/people/1/addresses.json", StreetAddress.collection_path("person_id" => 1)
|
856
|
+
end
|
857
|
+
|
858
|
+
def test_custom_collection_path_with_parameters
|
859
|
+
assert_equal "/people/1/addresses.json?type=work", StreetAddress.collection_path(person_id: 1, type: "work")
|
860
|
+
assert_equal "/people/1/addresses.json?type=work", StreetAddress.collection_path("person_id" => 1, :type => "work")
|
861
|
+
end
|
862
|
+
|
863
|
+
def test_custom_collection_path_with_prefix_and_parameters
|
864
|
+
assert_equal "/people/1/addresses.json?type=work", StreetAddress.collection_path({ person_id: 1 }, { type: "work" })
|
865
|
+
end
|
866
|
+
|
867
|
+
def test_custom_element_name
|
868
|
+
assert_equal "address", StreetAddress.element_name
|
869
|
+
end
|
870
|
+
|
871
|
+
def test_custom_collection_name
|
872
|
+
assert_equal "addresses", StreetAddress.collection_name
|
873
|
+
end
|
874
|
+
|
875
|
+
def test_prefix
|
876
|
+
assert_equal "/", Person.prefix
|
877
|
+
assert_equal Set.new, Person.__send__(:prefix_parameters)
|
878
|
+
end
|
879
|
+
|
880
|
+
def test_set_prefix
|
881
|
+
SetterTrap.rollback_sets(Person) do |person_class|
|
882
|
+
person_class.prefix = "the_prefix"
|
883
|
+
assert_equal "the_prefix", person_class.prefix
|
884
|
+
end
|
885
|
+
end
|
886
|
+
|
887
|
+
def test_set_prefix_with_inline_keys
|
888
|
+
SetterTrap.rollback_sets(Person) do |person_class|
|
889
|
+
person_class.prefix = "the_prefix:the_param"
|
890
|
+
assert_equal "the_prefixthe_param_value", person_class.prefix(the_param: "the_param_value")
|
891
|
+
end
|
892
|
+
end
|
893
|
+
|
894
|
+
def test_set_prefix_twice_should_clear_params
|
895
|
+
SetterTrap.rollback_sets(Person) do |person_class|
|
896
|
+
person_class.prefix = "the_prefix/:the_param1"
|
897
|
+
assert_equal Set.new([:the_param1]), person_class.prefix_parameters
|
898
|
+
person_class.prefix = "the_prefix/:the_param2"
|
899
|
+
assert_equal Set.new([:the_param2]), person_class.prefix_parameters
|
900
|
+
person_class.prefix = "the_prefix/:the_param1/other_prefix/:the_param2"
|
901
|
+
assert_equal Set.new([:the_param2, :the_param1]), person_class.prefix_parameters
|
902
|
+
end
|
903
|
+
end
|
904
|
+
|
905
|
+
def test_set_prefix_with_default_value
|
906
|
+
SetterTrap.rollback_sets(Person) do |person_class|
|
907
|
+
person_class.set_prefix
|
908
|
+
assert_equal "/", person_class.prefix
|
909
|
+
end
|
910
|
+
end
|
911
|
+
|
912
|
+
def test_custom_prefix
|
913
|
+
assert_equal "/people//", StreetAddress.prefix
|
914
|
+
assert_equal "/people/1/", StreetAddress.prefix(person_id: 1)
|
915
|
+
assert_equal [:person_id].to_set, StreetAddress.__send__(:prefix_parameters)
|
916
|
+
end
|
917
|
+
|
918
|
+
|
919
|
+
########################################################################
|
920
|
+
# Tests basic CRUD functions (find/save/create etc)
|
921
|
+
########################################################################
|
922
|
+
def test_respond_to
|
923
|
+
matz = Person.find(1)
|
924
|
+
assert_respond_to matz, :name
|
925
|
+
assert_respond_to matz, :name=
|
926
|
+
assert_respond_to matz, :name?
|
927
|
+
assert_not matz.respond_to?(:super_scalable_stuff)
|
928
|
+
end
|
929
|
+
|
930
|
+
def test_custom_header
|
931
|
+
Person.headers["key"] = "value"
|
932
|
+
assert_raise(ActiveResource::ResourceNotFound) { Person.find(4) }
|
933
|
+
ensure
|
934
|
+
Person.headers.delete("key")
|
935
|
+
end
|
936
|
+
|
937
|
+
def test_build_with_custom_header
|
938
|
+
Person.headers["key"] = "value"
|
939
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
940
|
+
mock.get "/people/new.json", {}, Person.new.to_json
|
941
|
+
mock.get "/people/new.json", { "key" => "value" }, Person.new.to_json, 404
|
942
|
+
end
|
943
|
+
assert_raise(ActiveResource::ResourceNotFound) { Person.build }
|
944
|
+
ensure
|
945
|
+
Person.headers.delete("key")
|
946
|
+
end
|
947
|
+
|
948
|
+
def test_build_without_attributes_for_prefix_call
|
949
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
950
|
+
mock.get "/people/1/addresses/new.json", {}, StreetAddress.new.to_json
|
951
|
+
end
|
952
|
+
assert_raise(ActiveResource::InvalidRequestError) { StreetAddress.build }
|
953
|
+
end
|
954
|
+
|
955
|
+
def test_build_with_attributes_for_prefix_call
|
956
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
957
|
+
mock.get "/people/1/addresses/new.json", {}, StreetAddress.new.to_json
|
958
|
+
end
|
959
|
+
assert_nothing_raised { StreetAddress.build(person_id: 1) }
|
960
|
+
end
|
961
|
+
|
962
|
+
def test_build_with_non_prefix_attributes
|
963
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
964
|
+
mock.get "/people/1/addresses/new.json", {}, StreetAddress.new.to_json
|
965
|
+
end
|
966
|
+
assert_nothing_raised do
|
967
|
+
address = StreetAddress.build(person_id: 1, city: "Toronto")
|
968
|
+
assert_equal "Toronto", address.city
|
969
|
+
end
|
970
|
+
end
|
971
|
+
|
972
|
+
def test_save
|
973
|
+
rick = Person.new
|
974
|
+
assert rick.save
|
975
|
+
assert_equal "5", rick.id
|
976
|
+
end
|
977
|
+
|
978
|
+
def test_save!
|
979
|
+
rick = Person.new
|
980
|
+
assert rick.save!
|
981
|
+
assert_equal "5", rick.id
|
982
|
+
end
|
983
|
+
|
984
|
+
def test_id_from_response
|
985
|
+
p = Person.new
|
986
|
+
resp = { "Location" => "/foo/bar/1" }
|
987
|
+
assert_equal "1", p.__send__(:id_from_response, resp)
|
988
|
+
|
989
|
+
resp["Location"] += ".json"
|
990
|
+
assert_equal "1", p.__send__(:id_from_response, resp)
|
991
|
+
end
|
992
|
+
|
993
|
+
def test_id_from_response_without_location
|
994
|
+
p = Person.new
|
995
|
+
resp = {}
|
996
|
+
assert_nil p.__send__(:id_from_response, resp)
|
997
|
+
end
|
998
|
+
|
999
|
+
def test_not_persisted_with_no_body_and_positive_content_length
|
1000
|
+
resp = ActiveResource::Response.new(nil)
|
1001
|
+
resp["Content-Length"] = "100"
|
1002
|
+
Person.connection.expects(:post).returns(resp)
|
1003
|
+
assert_not Person.create.persisted?
|
1004
|
+
end
|
1005
|
+
|
1006
|
+
def test_not_persisted_with_body_and_zero_content_length
|
1007
|
+
resp = ActiveResource::Response.new(@rick)
|
1008
|
+
resp["Content-Length"] = "0"
|
1009
|
+
Person.connection.expects(:post).returns(resp)
|
1010
|
+
assert_not Person.create.persisted?
|
1011
|
+
end
|
1012
|
+
|
1013
|
+
# These response codes aren't allowed to have bodies per HTTP spec
|
1014
|
+
def test_not_persisted_with_empty_response_codes
|
1015
|
+
[100, 101, 204, 304].each do |status_code|
|
1016
|
+
resp = ActiveResource::Response.new(@rick, status_code)
|
1017
|
+
Person.connection.expects(:post).returns(resp)
|
1018
|
+
assert_not Person.create.persisted?
|
1019
|
+
end
|
1020
|
+
end
|
1021
|
+
|
1022
|
+
# Content-Length is not required by HTTP 1.1, so we should read
|
1023
|
+
# the body anyway in its absence.
|
1024
|
+
def test_persisted_with_no_content_length
|
1025
|
+
resp = ActiveResource::Response.new(@rick)
|
1026
|
+
resp["Content-Length"] = nil
|
1027
|
+
Person.connection.expects(:post).returns(resp)
|
1028
|
+
assert Person.create.persisted?
|
1029
|
+
end
|
1030
|
+
|
1031
|
+
def test_create_with_custom_prefix
|
1032
|
+
matzs_house = StreetAddress.new(person_id: 1)
|
1033
|
+
matzs_house.save
|
1034
|
+
assert_equal "5", matzs_house.id
|
1035
|
+
end
|
1036
|
+
|
1037
|
+
# Test that loading a resource preserves its prefix_options.
|
1038
|
+
def test_load_preserves_prefix_options
|
1039
|
+
address = StreetAddress.find(1, params: { person_id: 1 })
|
1040
|
+
ryan = Person.new(id: 1, name: "Ryan", address: address)
|
1041
|
+
assert_equal address.prefix_options, ryan.address.prefix_options
|
1042
|
+
end
|
1043
|
+
|
1044
|
+
def test_reload_works_with_prefix_options
|
1045
|
+
address = StreetAddress.find(1, params: { person_id: 1 })
|
1046
|
+
assert_equal address, address.reload
|
1047
|
+
end
|
1048
|
+
|
1049
|
+
def test_reload_with_redefined_to_param
|
1050
|
+
Person.module_eval do
|
1051
|
+
alias_method :original_to_param_reload, :to_param
|
1052
|
+
def to_param
|
1053
|
+
name
|
1054
|
+
end
|
1055
|
+
end
|
1056
|
+
|
1057
|
+
person = Person.find("Greg")
|
1058
|
+
assert_equal person, person.reload
|
1059
|
+
|
1060
|
+
ensure
|
1061
|
+
# revert back to original
|
1062
|
+
Person.module_eval do
|
1063
|
+
# save the 'new' to_param so we don't get a warning about discarding the method
|
1064
|
+
alias_method :reload_to_param, :to_param
|
1065
|
+
alias_method :to_param, :original_to_param_reload
|
1066
|
+
end
|
1067
|
+
end
|
1068
|
+
|
1069
|
+
def test_reload_works_without_prefix_options
|
1070
|
+
person = Person.find(:first)
|
1071
|
+
assert_equal person, person.reload
|
1072
|
+
end
|
1073
|
+
|
1074
|
+
def test_create
|
1075
|
+
rick = Person.create(name: "Rick")
|
1076
|
+
assert rick.valid?
|
1077
|
+
assert_not rick.new?
|
1078
|
+
assert_equal "5", rick.id
|
1079
|
+
|
1080
|
+
# test additional attribute returned on create
|
1081
|
+
assert_equal 25, rick.age
|
1082
|
+
|
1083
|
+
# Test that save exceptions get bubbled up too
|
1084
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
1085
|
+
mock.post "/people.json", {}, nil, 409
|
1086
|
+
end
|
1087
|
+
assert_raise(ActiveResource::ResourceConflict) { Person.create(name: "Rick") }
|
1088
|
+
end
|
1089
|
+
|
1090
|
+
def test_create_without_location
|
1091
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
1092
|
+
mock.post "/people.json", {}, nil, 201
|
1093
|
+
end
|
1094
|
+
person = Person.create(name: "Rick")
|
1095
|
+
assert_nil person.id
|
1096
|
+
end
|
1097
|
+
|
1098
|
+
def test_create!
|
1099
|
+
rick = Person.create(name: "Rick")
|
1100
|
+
rick_bang = Person.create!(name: "Rick")
|
1101
|
+
|
1102
|
+
assert_equal rick.id, rick_bang.id
|
1103
|
+
assert_equal rick.age, rick_bang.age
|
1104
|
+
|
1105
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
1106
|
+
mock.post "/people.json", {}, nil, 422
|
1107
|
+
end
|
1108
|
+
assert_raise(ActiveResource::ResourceInvalid) { Person.create!(name: "Rick") }
|
1109
|
+
end
|
1110
|
+
|
1111
|
+
def test_clone
|
1112
|
+
matz = Person.find(1)
|
1113
|
+
matz_c = matz.clone
|
1114
|
+
assert matz_c.new?
|
1115
|
+
matz.attributes.each do |k, v|
|
1116
|
+
assert_equal v, matz_c.send(k) if k != Person.primary_key
|
1117
|
+
end
|
1118
|
+
end
|
1119
|
+
|
1120
|
+
def test_nested_clone
|
1121
|
+
addy = StreetAddress.find(1, params: { person_id: 1 })
|
1122
|
+
addy_c = addy.clone
|
1123
|
+
assert addy_c.new?
|
1124
|
+
addy.attributes.each do |k, v|
|
1125
|
+
assert_equal v, addy_c.send(k) if k != StreetAddress.primary_key
|
1126
|
+
end
|
1127
|
+
assert_equal addy.prefix_options, addy_c.prefix_options
|
1128
|
+
end
|
1129
|
+
|
1130
|
+
def test_complex_clone
|
1131
|
+
matz = Person.find(1)
|
1132
|
+
matz.address = StreetAddress.find(1, params: { person_id: matz.id })
|
1133
|
+
matz.non_ar_hash = { not: "an ARes instance" }
|
1134
|
+
matz.non_ar_arr = ["not", "ARes"]
|
1135
|
+
matz_c = matz.clone
|
1136
|
+
assert matz_c.new?
|
1137
|
+
assert_raise(NoMethodError) { matz_c.address }
|
1138
|
+
assert_equal matz.non_ar_hash, matz_c.non_ar_hash
|
1139
|
+
assert_equal matz.non_ar_arr, matz_c.non_ar_arr
|
1140
|
+
|
1141
|
+
# Test that actual copy, not just reference copy
|
1142
|
+
matz.non_ar_hash[:not] = "changed"
|
1143
|
+
assert_not_equal matz.non_ar_hash, matz_c.non_ar_hash
|
1144
|
+
end
|
1145
|
+
|
1146
|
+
def test_update
|
1147
|
+
matz = Person.find(:first)
|
1148
|
+
matz.name = "David"
|
1149
|
+
assert_kind_of Person, matz
|
1150
|
+
assert_equal "David", matz.name
|
1151
|
+
assert_equal true, matz.save
|
1152
|
+
end
|
1153
|
+
|
1154
|
+
def test_update_with_custom_prefix_with_specific_id
|
1155
|
+
addy = StreetAddress.find(1, params: { person_id: 1 })
|
1156
|
+
addy.street = "54321 Street"
|
1157
|
+
assert_kind_of StreetAddress, addy
|
1158
|
+
assert_equal "54321 Street", addy.street
|
1159
|
+
addy.save
|
1160
|
+
end
|
1161
|
+
|
1162
|
+
def test_update_with_custom_prefix_without_specific_id
|
1163
|
+
addy = StreetAddress.find(:first, params: { person_id: 1 })
|
1164
|
+
addy.street = "54321 Lane"
|
1165
|
+
assert_kind_of StreetAddress, addy
|
1166
|
+
assert_equal "54321 Lane", addy.street
|
1167
|
+
addy.save
|
1168
|
+
end
|
1169
|
+
|
1170
|
+
def test_update_conflict
|
1171
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
1172
|
+
mock.get "/people/2.json", {}, @david
|
1173
|
+
mock.put "/people/2.json", @default_request_headers, nil, 409
|
1174
|
+
end
|
1175
|
+
assert_raise(ActiveResource::ResourceConflict) { Person.find(2).save }
|
1176
|
+
end
|
1177
|
+
|
1178
|
+
|
1179
|
+
######
|
1180
|
+
# update_attribute(s)(!)
|
1181
|
+
|
1182
|
+
def test_update_attribute_as_symbol
|
1183
|
+
matz = Person.first
|
1184
|
+
matz.expects(:save).returns(true)
|
1185
|
+
|
1186
|
+
assert_equal "Matz", matz.name
|
1187
|
+
assert matz.update_attribute(:name, "David")
|
1188
|
+
assert_equal "David", matz.name
|
1189
|
+
end
|
1190
|
+
|
1191
|
+
def test_update_attribute_as_string
|
1192
|
+
matz = Person.first
|
1193
|
+
matz.expects(:save).returns(true)
|
1194
|
+
|
1195
|
+
assert_equal "Matz", matz.name
|
1196
|
+
assert matz.update_attribute("name", "David")
|
1197
|
+
assert_equal "David", matz.name
|
1198
|
+
end
|
1199
|
+
|
1200
|
+
|
1201
|
+
def test_update_attributes_as_symbols
|
1202
|
+
addy = StreetAddress.first(params: { person_id: 1 })
|
1203
|
+
addy.expects(:save).returns(true)
|
1204
|
+
|
1205
|
+
assert_equal "12345 Street", addy.street
|
1206
|
+
assert_equal "Australia", addy.country
|
1207
|
+
assert addy.update_attributes(street: "54321 Street", country: "USA")
|
1208
|
+
assert_equal "54321 Street", addy.street
|
1209
|
+
assert_equal "USA", addy.country
|
1210
|
+
end
|
1211
|
+
|
1212
|
+
def test_update_attributes_as_strings
|
1213
|
+
addy = StreetAddress.first(params: { person_id: 1 })
|
1214
|
+
addy.expects(:save).returns(true)
|
1215
|
+
|
1216
|
+
assert_equal "12345 Street", addy.street
|
1217
|
+
assert_equal "Australia", addy.country
|
1218
|
+
assert addy.update_attributes("street" => "54321 Street", "country" => "USA")
|
1219
|
+
assert_equal "54321 Street", addy.street
|
1220
|
+
assert_equal "USA", addy.country
|
1221
|
+
end
|
1222
|
+
|
1223
|
+
|
1224
|
+
#####
|
1225
|
+
# Mayhem and destruction
|
1226
|
+
|
1227
|
+
def test_destroy
|
1228
|
+
assert Person.find(1).destroy
|
1229
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
1230
|
+
mock.get "/people/1.json", {}, nil, 404
|
1231
|
+
end
|
1232
|
+
assert_raise(ActiveResource::ResourceNotFound) { Person.find(1).destroy }
|
1233
|
+
end
|
1234
|
+
|
1235
|
+
def test_destroy_with_custom_prefix
|
1236
|
+
assert StreetAddress.find(1, params: { person_id: 1 }).destroy
|
1237
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
1238
|
+
mock.get "/people/1/addresses/1.json", {}, nil, 404
|
1239
|
+
end
|
1240
|
+
assert_raise(ActiveResource::ResourceNotFound) { StreetAddress.find(1, params: { person_id: 1 }) }
|
1241
|
+
end
|
1242
|
+
|
1243
|
+
def test_destroy_with_410_gone
|
1244
|
+
assert Person.find(1).destroy
|
1245
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
1246
|
+
mock.get "/people/1.json", {}, nil, 410
|
1247
|
+
end
|
1248
|
+
assert_raise(ActiveResource::ResourceGone) { Person.find(1).destroy }
|
1249
|
+
end
|
1250
|
+
|
1251
|
+
def test_delete
|
1252
|
+
assert Person.delete(1)
|
1253
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
1254
|
+
mock.get "/people/1.json", {}, nil, 404
|
1255
|
+
end
|
1256
|
+
assert_raise(ActiveResource::ResourceNotFound) { Person.find(1) }
|
1257
|
+
end
|
1258
|
+
|
1259
|
+
def test_delete_with_custom_prefix
|
1260
|
+
assert StreetAddress.delete(1, person_id: 1)
|
1261
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
1262
|
+
mock.get "/people/1/addresses/1.json", {}, nil, 404
|
1263
|
+
end
|
1264
|
+
assert_raise(ActiveResource::ResourceNotFound) { StreetAddress.find(1, params: { person_id: 1 }) }
|
1265
|
+
end
|
1266
|
+
|
1267
|
+
def test_delete_with_410_gone
|
1268
|
+
assert Person.delete(1)
|
1269
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
1270
|
+
mock.get "/people/1.json", {}, nil, 410
|
1271
|
+
end
|
1272
|
+
assert_raise(ActiveResource::ResourceGone) { Person.find(1) }
|
1273
|
+
end
|
1274
|
+
|
1275
|
+
def test_delete_with_custom_header
|
1276
|
+
Person.headers["key"] = "value"
|
1277
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
1278
|
+
mock.delete "/people/1.json", {}, nil, 200
|
1279
|
+
mock.delete "/people/1.json", { "key" => "value" }, nil, 404
|
1280
|
+
end
|
1281
|
+
assert_raise(ActiveResource::ResourceNotFound) { Person.delete(1) }
|
1282
|
+
ensure
|
1283
|
+
Person.headers.delete("key")
|
1284
|
+
end
|
1285
|
+
|
1286
|
+
########################################################################
|
1287
|
+
# Tests the more miscellaneous helper methods
|
1288
|
+
########################################################################
|
1289
|
+
def test_exists
|
1290
|
+
# Class method.
|
1291
|
+
assert_equal false, Person.exists?(nil)
|
1292
|
+
assert_equal true, Person.exists?(1)
|
1293
|
+
assert_equal false, Person.exists?(99)
|
1294
|
+
|
1295
|
+
# Instance method.
|
1296
|
+
assert_equal false, Person.new.exists?
|
1297
|
+
assert_equal true, Person.find(1).exists?
|
1298
|
+
assert_equal false, Person.new(id: 99).exists?
|
1299
|
+
|
1300
|
+
# Nested class method.
|
1301
|
+
assert_equal true, StreetAddress.exists?(1, params: { person_id: 1 })
|
1302
|
+
assert_equal false, StreetAddress.exists?(1, params: { person_id: 2 })
|
1303
|
+
assert_equal false, StreetAddress.exists?(2, params: { person_id: 1 })
|
1304
|
+
|
1305
|
+
# Nested instance method.
|
1306
|
+
assert_equal true, StreetAddress.find(1, params: { person_id: 1 }).exists?
|
1307
|
+
assert_equal false, StreetAddress.new(id: 1, person_id: 2).exists?
|
1308
|
+
assert_equal false, StreetAddress.new(id: 2, person_id: 1).exists?
|
1309
|
+
end
|
1310
|
+
|
1311
|
+
def test_exists_with_redefined_to_param
|
1312
|
+
Person.module_eval do
|
1313
|
+
alias_method :original_to_param_exists, :to_param
|
1314
|
+
def to_param
|
1315
|
+
name
|
1316
|
+
end
|
1317
|
+
end
|
1318
|
+
|
1319
|
+
# Class method.
|
1320
|
+
assert Person.exists?("Greg")
|
1321
|
+
|
1322
|
+
# Instance method.
|
1323
|
+
assert Person.find("Greg").exists?
|
1324
|
+
|
1325
|
+
# Nested class method.
|
1326
|
+
assert StreetAddress.exists?(1, params: { person_id: Person.find("Greg").to_param })
|
1327
|
+
|
1328
|
+
# Nested instance method.
|
1329
|
+
assert StreetAddress.find(1, params: { person_id: Person.find("Greg").to_param }).exists?
|
1330
|
+
|
1331
|
+
ensure
|
1332
|
+
# revert back to original
|
1333
|
+
Person.module_eval do
|
1334
|
+
# save the 'new' to_param so we don't get a warning about discarding the method
|
1335
|
+
alias_method :exists_to_param, :to_param
|
1336
|
+
alias_method :to_param, :original_to_param_exists
|
1337
|
+
end
|
1338
|
+
end
|
1339
|
+
|
1340
|
+
def test_exists_without_http_mock
|
1341
|
+
http = Net::HTTP.new(Person.site.host, Person.site.port)
|
1342
|
+
ActiveResource::Connection.any_instance.expects(:http).returns(http)
|
1343
|
+
http.expects(:request).returns(ActiveResource::Response.new(""))
|
1344
|
+
|
1345
|
+
assert Person.exists?("not-mocked")
|
1346
|
+
end
|
1347
|
+
|
1348
|
+
def test_exists_with_410_gone
|
1349
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
1350
|
+
mock.head "/people/1.json", {}, nil, 410
|
1351
|
+
end
|
1352
|
+
|
1353
|
+
assert_not Person.exists?(1)
|
1354
|
+
end
|
1355
|
+
|
1356
|
+
def test_exists_with_204_no_content
|
1357
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
1358
|
+
mock.head "/people/1.json", {}, nil, 204
|
1359
|
+
end
|
1360
|
+
|
1361
|
+
assert Person.exists?(1)
|
1362
|
+
end
|
1363
|
+
|
1364
|
+
def test_read_attribute_for_serialization
|
1365
|
+
joe = Person.find(6)
|
1366
|
+
joe.singleton_class.class_eval do
|
1367
|
+
def non_attribute_field
|
1368
|
+
"foo"
|
1369
|
+
end
|
1370
|
+
|
1371
|
+
def id
|
1372
|
+
"bar"
|
1373
|
+
end
|
1374
|
+
end
|
1375
|
+
|
1376
|
+
assert_equal joe.read_attribute_for_serialization(:id), 6
|
1377
|
+
assert_equal joe.read_attribute_for_serialization(:name), "Joe"
|
1378
|
+
assert_equal joe.read_attribute_for_serialization(:likes_hats), true
|
1379
|
+
assert_equal joe.read_attribute_for_serialization(:non_attribute_field), "foo"
|
1380
|
+
end
|
1381
|
+
|
1382
|
+
def test_to_xml
|
1383
|
+
Person.format = :xml
|
1384
|
+
matz = Person.find(1)
|
1385
|
+
encode = matz.encode
|
1386
|
+
xml = matz.to_xml
|
1387
|
+
|
1388
|
+
assert_equal encode, xml
|
1389
|
+
assert xml.include?('<?xml version="1.0" encoding="UTF-8"?>')
|
1390
|
+
assert xml.include?("<name>Matz</name>")
|
1391
|
+
assert xml.include?('<id type="integer">1</id>')
|
1392
|
+
ensure
|
1393
|
+
Person.format = :json
|
1394
|
+
end
|
1395
|
+
|
1396
|
+
def test_to_xml_with_element_name
|
1397
|
+
Person.format = :xml
|
1398
|
+
old_elem_name = Person.element_name
|
1399
|
+
matz = Person.find(1)
|
1400
|
+
Person.element_name = "ruby_creator"
|
1401
|
+
encode = matz.encode
|
1402
|
+
xml = matz.to_xml
|
1403
|
+
|
1404
|
+
assert_equal encode, xml
|
1405
|
+
assert xml.include?('<?xml version="1.0" encoding="UTF-8"?>')
|
1406
|
+
assert xml.include?("<ruby-creator>")
|
1407
|
+
assert xml.include?("<name>Matz</name>")
|
1408
|
+
assert xml.include?('<id type="integer">1</id>')
|
1409
|
+
assert xml.include?("</ruby-creator>")
|
1410
|
+
ensure
|
1411
|
+
Person.format = :json
|
1412
|
+
Person.element_name = old_elem_name
|
1413
|
+
end
|
1414
|
+
|
1415
|
+
def test_to_xml_with_private_method_name_as_attribute
|
1416
|
+
Person.format = :xml
|
1417
|
+
|
1418
|
+
customer = Customer.new(foo: "foo")
|
1419
|
+
customer.singleton_class.class_eval do
|
1420
|
+
def foo
|
1421
|
+
"bar"
|
1422
|
+
end
|
1423
|
+
private :foo
|
1424
|
+
end
|
1425
|
+
|
1426
|
+
assert_not customer.to_xml.include?("<foo>bar</foo>")
|
1427
|
+
assert customer.to_xml.include?("<foo>foo</foo>")
|
1428
|
+
ensure
|
1429
|
+
Person.format = :json
|
1430
|
+
end
|
1431
|
+
|
1432
|
+
def test_to_json
|
1433
|
+
joe = Person.find(6)
|
1434
|
+
encode = joe.encode
|
1435
|
+
json = joe.to_json
|
1436
|
+
|
1437
|
+
assert_equal encode, json
|
1438
|
+
assert_match %r{^\{"person":\{}, json
|
1439
|
+
assert_match %r{"id":6}, json
|
1440
|
+
assert_match %r{"name":"Joe"}, json
|
1441
|
+
assert_match %r{\}\}$}, json
|
1442
|
+
end
|
1443
|
+
|
1444
|
+
def test_to_json_without_root
|
1445
|
+
ActiveResource::Base.include_root_in_json = false
|
1446
|
+
joe = Person.find(6)
|
1447
|
+
encode = joe.encode
|
1448
|
+
json = joe.to_json
|
1449
|
+
|
1450
|
+
assert_equal encode, json
|
1451
|
+
assert_match %r{^\{"id":6}, json
|
1452
|
+
assert_match %r{"name":"Joe"}, json
|
1453
|
+
assert_match %r{\}$}, json
|
1454
|
+
ensure
|
1455
|
+
ActiveResource::Base.include_root_in_json = true
|
1456
|
+
end
|
1457
|
+
|
1458
|
+
def test_to_json_with_element_name
|
1459
|
+
old_elem_name = Person.element_name
|
1460
|
+
joe = Person.find(6)
|
1461
|
+
Person.element_name = "ruby_creator"
|
1462
|
+
encode = joe.encode
|
1463
|
+
json = joe.to_json
|
1464
|
+
|
1465
|
+
assert_equal encode, json
|
1466
|
+
assert_match %r{^\{"ruby_creator":\{}, json
|
1467
|
+
assert_match %r{"id":6}, json
|
1468
|
+
assert_match %r{"name":"Joe"}, json
|
1469
|
+
assert_match %r{\}\}$}, json
|
1470
|
+
ensure
|
1471
|
+
Person.element_name = old_elem_name
|
1472
|
+
end
|
1473
|
+
|
1474
|
+
def test_to_param_quacks_like_active_record
|
1475
|
+
new_person = Person.new
|
1476
|
+
assert_nil new_person.to_param
|
1477
|
+
matz = Person.find(1)
|
1478
|
+
assert_equal "1", matz.to_param
|
1479
|
+
end
|
1480
|
+
|
1481
|
+
def test_to_key_quacks_like_active_record
|
1482
|
+
new_person = Person.new
|
1483
|
+
assert_nil new_person.to_key
|
1484
|
+
matz = Person.find(1)
|
1485
|
+
assert_equal [1], matz.to_key
|
1486
|
+
end
|
1487
|
+
|
1488
|
+
def test_parse_deep_nested_resources
|
1489
|
+
luis = Customer.find(1)
|
1490
|
+
assert_kind_of Customer, luis
|
1491
|
+
luis.friends.each do |friend|
|
1492
|
+
assert_kind_of Customer::Friend, friend
|
1493
|
+
friend.brothers.each do |brother|
|
1494
|
+
assert_kind_of Customer::Friend::Brother, brother
|
1495
|
+
brother.children.each do |child|
|
1496
|
+
assert_kind_of Customer::Friend::Brother::Child, child
|
1497
|
+
end
|
1498
|
+
end
|
1499
|
+
end
|
1500
|
+
end
|
1501
|
+
|
1502
|
+
def test_persisted_nested_resources_from_response
|
1503
|
+
luis = Customer.find(1)
|
1504
|
+
luis.friends.each do |friend|
|
1505
|
+
assert_not friend.new?
|
1506
|
+
friend.brothers.each do |brother|
|
1507
|
+
assert_not brother.new?
|
1508
|
+
brother.children.each do |child|
|
1509
|
+
assert_not child.new?
|
1510
|
+
end
|
1511
|
+
end
|
1512
|
+
end
|
1513
|
+
end
|
1514
|
+
|
1515
|
+
def test_parse_resource_with_given_has_one_resources
|
1516
|
+
Customer.send(:has_one, :mother, class_name: "external/person")
|
1517
|
+
luis = Customer.find(1)
|
1518
|
+
assert_kind_of External::Person, luis.mother
|
1519
|
+
end
|
1520
|
+
|
1521
|
+
def test_parse_resources_with_given_has_many_resources
|
1522
|
+
Customer.send(:has_many, :enemies, class_name: "external/person")
|
1523
|
+
luis = Customer.find(1)
|
1524
|
+
luis.enemies.each do |enemy|
|
1525
|
+
assert_kind_of External::Person, enemy
|
1526
|
+
end
|
1527
|
+
end
|
1528
|
+
|
1529
|
+
def test_parse_resources_with_has_many_makes_get_request_on_nested_route
|
1530
|
+
Post.send(:has_many, :comments)
|
1531
|
+
post = Post.find(1)
|
1532
|
+
post.comments.each do |comment|
|
1533
|
+
assert_kind_of Comment, comment
|
1534
|
+
end
|
1535
|
+
end
|
1536
|
+
|
1537
|
+
def test_parse_resource_with_has_one_makes_get_request_on_child_route
|
1538
|
+
Product.send(:has_one, :inventory)
|
1539
|
+
product = Product.find(1)
|
1540
|
+
assert product.inventory.status == ActiveSupport::JSON.decode(@inventory)["status"]
|
1541
|
+
end
|
1542
|
+
|
1543
|
+
def test_parse_non_singleton_resource_with_has_one_makes_get_request_on_child_route
|
1544
|
+
accepts = { "Accept" => "application/json" }
|
1545
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
1546
|
+
mock.get "/posts/1.json", accepts, @post
|
1547
|
+
mock.get "/posts/1/author.json", accepts, @matz
|
1548
|
+
end
|
1549
|
+
|
1550
|
+
Post.send(:has_one, :author, class_name: "Person")
|
1551
|
+
post = Post.find(1)
|
1552
|
+
assert post.author.name == ActiveSupport::JSON.decode(@matz)["person"]["name"]
|
1553
|
+
end
|
1554
|
+
|
1555
|
+
def test_with_custom_formatter
|
1556
|
+
addresses = [{ id: "1", street: "1 Infinite Loop", city: "Cupertino", state: "CA" }].to_xml(root: :addresses)
|
1557
|
+
|
1558
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
1559
|
+
mock.get "/addresses.xml", {}, addresses, 200
|
1560
|
+
end
|
1561
|
+
|
1562
|
+
# late bind the site
|
1563
|
+
AddressResource.site = "http://localhost"
|
1564
|
+
addresses = AddressResource.find(:all)
|
1565
|
+
|
1566
|
+
assert_equal "Cupertino, CA", addresses.first.city_state
|
1567
|
+
end
|
1568
|
+
|
1569
|
+
def test_create_with_custom_primary_key
|
1570
|
+
silver_plan = { plan: { code: "silver", price: 5.00 } }.to_json
|
1571
|
+
|
1572
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
1573
|
+
mock.post "/plans.json", {}, silver_plan, 201, "Location" => "/plans/silver.json"
|
1574
|
+
end
|
1575
|
+
|
1576
|
+
plan = SubscriptionPlan.new(code: "silver", price: 5.00)
|
1577
|
+
assert plan.new?
|
1578
|
+
|
1579
|
+
plan.save!
|
1580
|
+
assert_not plan.new?
|
1581
|
+
end
|
1582
|
+
|
1583
|
+
def test_update_with_custom_primary_key
|
1584
|
+
silver_plan = { plan: { code: "silver", price: 5.00 } }.to_json
|
1585
|
+
silver_plan_updated = { plan: { code: "silver", price: 10.00 } }.to_json
|
1586
|
+
|
1587
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
1588
|
+
mock.get "/plans/silver.json", {}, silver_plan
|
1589
|
+
mock.put "/plans/silver.json", {}, silver_plan_updated, 201, "Location" => "/plans/silver.json"
|
1590
|
+
end
|
1591
|
+
|
1592
|
+
plan = SubscriptionPlan.find("silver")
|
1593
|
+
assert_not plan.new?
|
1594
|
+
assert_equal 5.00, plan.price
|
1595
|
+
|
1596
|
+
# update price
|
1597
|
+
plan.price = 10.00
|
1598
|
+
plan.save!
|
1599
|
+
assert_equal 10.00, plan.price
|
1600
|
+
end
|
1601
|
+
|
1602
|
+
def test_namespacing
|
1603
|
+
sound = Asset::Sound.find(1)
|
1604
|
+
assert_equal "Asset::Sound::Author", sound.author.class.to_s
|
1605
|
+
end
|
1606
|
+
|
1607
|
+
def test_paths_with_format
|
1608
|
+
assert_equal "/customers.json", Customer.collection_path
|
1609
|
+
assert_equal "/customers/1.json", Customer.element_path(1)
|
1610
|
+
assert_equal "/customers/new.json", Customer.new_element_path
|
1611
|
+
end
|
1612
|
+
|
1613
|
+
def test_paths_without_format
|
1614
|
+
ActiveResource::Base.include_format_in_path = false
|
1615
|
+
assert_equal "/customers", Customer.collection_path
|
1616
|
+
assert_equal "/customers/1", Customer.element_path(1)
|
1617
|
+
assert_equal "/customers/new", Customer.new_element_path
|
1618
|
+
|
1619
|
+
ensure
|
1620
|
+
ActiveResource::Base.include_format_in_path = true
|
1621
|
+
end
|
1622
|
+
end
|