acts_as_api-1.0.1/0000755000004100000410000000000013162253634014014 5ustar www-datawww-dataacts_as_api-1.0.1/Rakefile0000644000004100000410000000163213162253634015463 0ustar www-datawww-datarequire 'bundler' require 'rspec/core' require 'rspec/core/rake_task' Bundler::GemHelper.install_tasks RSpec::Core::RakeTask.new namespace :spec do supported_orms = %w(mongoid active_record) supported_orms.each do |orm| desc "Run #{orm} specs only" RSpec::Core::RakeTask.new(orm) do |t| t.rspec_opts = ['--color'] end task "prepare_#{orm}" do ENV['ACTS_AS_API_ORM'] = orm end Rake::Task["spec:#{orm}"].prerequisites << "spec:prepare_#{orm}" end desc "Runs specs for all ORMs (#{supported_orms.join(', ')})" task :all do supported_orms.each do |orm| puts "Starting to run specs for #{orm}..." system("bundle exec rake spec:#{orm}") raise "#{orm} failed!" unless $?.exitstatus.zero? end end end task default: 'spec:all' desc 'Generate the gh_pages site' task :rocco do system 'bundle exec rocco docs/index.rb -t docs/layout.mustache' end acts_as_api-1.0.1/Gemfile0000644000004100000410000000053713162253634015314 0ustar www-datawww-datasource 'http://rubygems.org' # Specify your gem's dependencies in acts_as_api.gemspec gemspec group :test do gem 'pry' gem 'sqlite3' gem 'mongoid', '>= 6.0.2' gem 'rspec', '>= 3.5.0' gem 'rspec-collection_matchers' gem 'capybara' gem 'rspec-rails', '>= 3.5.0' gem 'responders' gem 'shared_engine', path: './spec/shared_engine' end acts_as_api-1.0.1/LICENSE.txt0000644000004100000410000000205013162253634015634 0ustar www-datawww-dataCopyright (c) 2010 Christian Bäuerlein Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. acts_as_api-1.0.1/History.txt0000644000004100000410000000502513162253634016220 0ustar www-datawww-data=== 1.0.1 2017-08-04 * Updates spec suite to Rails 5.1.3 === 1.0.0 2016-11-24 * Ditch Ruby 1.8 syntax, overall modernization * Finally, 1.0! === 0.4.4 2016-11-09 * Updates spec suite to Rails 5 === 0.4.3 2016-07-31 * Sets correct content type for JSONP responses (see PR #98) === 0.4.2 2013-12-28 * Fixed problem with rendering of POROs (see PR #88) === 0.4.1 2012-07-18 * Added support for Mongoid 3 === 0.4 2012-04-30 * Added support for a second parameter (options) to pass to as_api_response === 0.3.11 2011-11-06 * Added :postfix, :prefix options for template rendering === 0.3.10 2011-10-03 * Fixed Mongoid problems, when no ActiveRecord is available (Ticket #36) === 0.3.9 2011-09-24 * Spec suite now running on Rails 3.1 * Fixed naming issue with ActiveRecord::Relation (Ticket #35) === 0.3.8 2011-06-21 * Fixed Rails 3.1 deprecation warning === 0.3.7 2011-06-13 * Added before/around/after callbacks === 0.3.6 2011-05-13 * Finally added Mongoid Support out of the box * Support for Rails 3 Responders === 0.3.4 2011-04-26 * Fixed a bug concerning the inheritance of sub templates/additional options === 0.3.3 2011-04-24 * Added support for :if and :unless options === 0.3.2 2011-04-20 * Raise an exception if a specified api template is not found === 0.3.1 2011-04-08 * Added the :template option to specify sub templates * Fixed a bug concerning extended api templates === 0.3.0 2011-02-22 * Added bundler support * Added mongoid support * Removed lots of unnecessary dependencies esp. ActiveRecord === 0.2.2 2010-10-21 * Version bump only for changing the github account in the docs. === 0.2.1 2010-09-20 * Updated to work with Rails 3.0.0 * Added support for multiple renderings of the same model (e.g. useful for versioning). Note that the interface of acts as api changed, soyou have to update your code. * Updated dependecies to user Rails 3.0.0 libs instead of beta. === 0.1.10 2010-07-23 * More Bugfixes. When you want to render an Array of records (e.g. from MyRecord.all) make sure you pass the :root options to render_as_api - in case it will return an empty array === 0.1.7 2010-07-05 * Fixed bug with multi-word models. === 0.1.4 2010-07-04 * Added better documentation. === 0.1.3 2010-07-04 * Support for including methods of associated models. * Better root name determination for arrays. === 0.0.3 2010-07-01 * 1 small bugfix === 0.0.2 2010-07-01 * 1 major enhancement: * Added a wrapping root node for JSON responses by default. === 0.0.1 2010-06-27 * 1 major enhancement: * Initial release acts_as_api-1.0.1/spec/0000755000004100000410000000000013162253634014746 5ustar www-datawww-dataacts_as_api-1.0.1/spec/controllers/0000755000004100000410000000000013162253634017314 5ustar www-datawww-dataacts_as_api-1.0.1/spec/controllers/respond_with_users_controller_spec.rb0000644000004100000410000000747713162253634027063 0ustar www-datawww-datarequire 'spec_helper' describe SharedEngine::RespondWithUsersController, type: :controller do routes { SharedEngine::Engine.routes } before(:each) do setup_models end after(:each) do clean_up_models end # see spec/support/controller_examples.rb it_behaves_like 'a controller with ActsAsApi responses' describe 'default ActionController::Responder behavior' do context 'json responses' do context 'creating valid models' do before(:each) do post :create, format: 'json', params: { user: { first_name: 'Luke', last_name: 'Skywalker' }, api_template: :name_only } end it 'should return HTTP 201 status' do expect(response.code).to eq('201') end it 'should contain the specified attributes' do expect(response_body_json['user']).to have_key('first_name') expect(response_body_json['user']).to have_key('last_name') end it 'should contain the specified values' do expect(response_body_json['user']['first_name']).to eql('Luke') expect(response_body_json['user']['last_name']).to eql('Skywalker') end end context 'creating invalid models' do before(:each) do post :create, format: 'json', params: { user: { first_name: 'Luke' }, api_template: :name_only } end it 'should return HTTP 422 status' do expect(response.code).to eq('422') end it 'should return errors as json' do expect(response_body_json['errors']['last_name']).to include('can\'t be blank') end end context 'returning all models without default root and no order' do before(:each) do get :index_no_root_no_order, format: 'json', params: { api_template: :name_only } end it 'should return HTTP 200 status' do expect(response.code).to eq('200') end it 'should contain the specified attributes' do response_body_json['users'].each do |user| expect(user).to have_key('first_name') expect(user).to have_key('last_name') end end end end context 'xml responses' do context 'creating valid models' do before(:each) do post :create, format: 'xml', params: { user: { first_name: 'Luke', last_name: 'Skywalker' }, api_template: :name_only } end it 'should return HTTP 201 status' do expect(response.code).to eq('201') end it 'should include HTTP Location header' do expect(response.headers['Location']).to match "/shared/users/#{User.last.id}" end it 'should contain the specified attributes' do expect(response_body).to have_selector('user > first-name') expect(response_body).to have_selector('user > last-name') end end context 'creating invalid models' do before(:each) do post :create, format: 'xml', params: { user: { first_name: 'Luke' }, api_template: :name_only } end it 'should return HTTP 422 status' do expect(response.code).to eq('422') end it 'should return errors as xml' do expect(response_body).to have_selector('errors > error') end end context 'returning all models without default root and no order' do before(:each) do get :index_no_root_no_order, format: 'xml', params: { api_template: :name_only } end it 'should return HTTP 200 status' do expect(response.code).to eq('200') end it 'should contain the specified attributes' do expect(response_body).to have_selector('users > user > first-name', count: 3) expect(response_body).to have_selector('users > user > last-name', count: 3) end end end end end acts_as_api-1.0.1/spec/controllers/plain_objects_controller_spec.rb0000644000004100000410000000220013162253634025724 0ustar www-datawww-datarequire 'spec_helper' describe SharedEngine::PlainObjectsController, type: :controller do include ApiTestHelpers routes { SharedEngine::Engine.routes } before(:each) do class SharedEngine::PlainObjectsController include SimpleFixtures end end describe 'get all users as a an array of plain objects, autodetecting the root node name' do before(:each) do get :index, format: 'json', params: { api_template: :name_only } end it 'should have a root node named users' do expect(response_body_json).to have_key('plain_objects') end it 'should contain all users' do expect(response_body_json['plain_objects']).to be_a(Array) end it 'should contain the specified attributes' do expect(response_body_json['plain_objects'].first).to have_key('first_name') expect(response_body_json['plain_objects'].first).to have_key('last_name') end it 'should contain the specified values' do expect(response_body_json['plain_objects'].first['first_name']).to eql('Han') expect(response_body_json['plain_objects'].first['last_name']).to eql('Solo') end end end acts_as_api-1.0.1/spec/controllers/users_controller_spec.rb0000644000004100000410000000042613162253634024261 0ustar www-datawww-datarequire 'spec_helper' describe SharedEngine::UsersController, type: :controller do before(:each) do setup_models end after(:each) do clean_up_models end # see spec/support/controller_examples.rb it_behaves_like 'a controller with ActsAsApi responses' end acts_as_api-1.0.1/spec/mongoid_dummy/0000755000004100000410000000000013162253634017615 5ustar www-datawww-dataacts_as_api-1.0.1/spec/mongoid_dummy/Rakefile0000644000004100000410000000042513162253634021263 0ustar www-datawww-data#!/usr/bin/env rake # Add your own tasks in files placed in lib/tasks ending in .rake, # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. require File.expand_path('../config/application', __FILE__) MongoidDummy::Application.load_tasks acts_as_api-1.0.1/spec/mongoid_dummy/Gemfile0000644000004100000410000000026113162253634021107 0ustar www-datawww-datasource 'https://rubygems.org' gem 'rails', '5.0.0.1' gem 'bson_ext' gem 'mongoid', '>= 6.0.2' gem 'shared_engine', path: '../shared_engine' gem 'acts_as_api', path: '../../' acts_as_api-1.0.1/spec/mongoid_dummy/script/0000755000004100000410000000000013162253634021121 5ustar www-datawww-dataacts_as_api-1.0.1/spec/mongoid_dummy/script/rails0000755000004100000410000000044513162253634022164 0ustar www-datawww-data#!/usr/bin/env ruby # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. APP_PATH = File.expand_path('../../config/application', __FILE__) require File.expand_path('../../config/boot', __FILE__) require 'rails/commands' acts_as_api-1.0.1/spec/mongoid_dummy/log/0000755000004100000410000000000013162253634020376 5ustar www-datawww-dataacts_as_api-1.0.1/spec/mongoid_dummy/log/.gitkeep0000644000004100000410000000000013162253634022015 0ustar www-datawww-dataacts_as_api-1.0.1/spec/mongoid_dummy/db/0000755000004100000410000000000013162253634020202 5ustar www-datawww-dataacts_as_api-1.0.1/spec/mongoid_dummy/db/seeds.rb0000644000004100000410000000052713162253634021636 0ustar www-datawww-data# This file should contain all the record creation needed to seed the database with its default values. # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). # # Examples: # # cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) # Mayor.create(name: 'Emanuel', city: cities.first) acts_as_api-1.0.1/spec/mongoid_dummy/.gitignore0000644000004100000410000000065613162253634021614 0ustar www-datawww-data# See http://help.github.com/ignore-files/ for more about ignoring files. # # If you find yourself ignoring temporary files generated by your text editor # or operating system, you probably want to add a global ignore instead: # git config --global core.excludesfile ~/.gitignore_global # Ignore bundler config /.bundle # Ignore the default SQLite database. /db/*.sqlite3 # Ignore all logfiles and tempfiles. /log/*.log /tmp acts_as_api-1.0.1/spec/mongoid_dummy/config/0000755000004100000410000000000013162253634021062 5ustar www-datawww-dataacts_as_api-1.0.1/spec/mongoid_dummy/config/application.rb0000644000004100000410000000472013162253634023715 0ustar www-datawww-datarequire File.expand_path('../boot', __FILE__) # Pick the frameworks you want: # require 'active_record/railtie' require 'action_controller/railtie' require 'action_mailer/railtie' require 'sprockets/railtie' require 'rails/test_unit/railtie' if defined?(Bundler) # If you precompile assets before deploying to production, use this line Bundler.require(*Rails.groups(assets: %w(development test))) # If you want your assets lazily compiled in production, use this line # Bundler.require(:default, :assets, Rails.env) end module MongoidDummy class Application < Rails::Application # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. # Custom directories with classes and modules you want to be autoloadable. # config.autoload_paths += %W(#{config.root}/extras) # Only load the plugins named here, in the order given (default is alphabetical). # :all can be used as a placeholder for all plugins not explicitly named. # config.plugins = [ :exception_notification, :ssl_requirement, :all ] # Activate observers that should always be running. # config.active_record.observers = :cacher, :garbage_collector, :forum_observer # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. # config.time_zone = 'Central Time (US & Canada)' # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] # config.i18n.default_locale = :de # Configure the default encoding used in templates for Ruby 1.9. config.encoding = 'utf-8' # Configure sensitive parameters which will be filtered from the log file. config.filter_parameters += [:password] # Use SQL instead of Active Record's schema dumper when creating the database. # This is necessary if your schema can't be completely dumped by the schema dumper, # like if you have constraints or database-specific column types # config.active_record.schema_format = :sql # Enable the asset pipeline config.assets.enabled = true # Version of your assets, change this if you want to expire all your assets config.assets.version = '1.0' end end acts_as_api-1.0.1/spec/mongoid_dummy/config/initializers/0000755000004100000410000000000013162253634023570 5ustar www-datawww-dataacts_as_api-1.0.1/spec/mongoid_dummy/config/initializers/secret_token.rb0000644000004100000410000000076713162253634026614 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # Your secret key for verifying the integrity of signed cookies. # If you change this key, all old signed cookies will become invalid! # Make sure the secret is at least 30 characters and all random, # no regular words or you'll be exposed to dictionary attacks. MongoidDummy::Application.config.secret_token = '6b56ce25197cabc62558d2cea0a7577dbf7b23e9a3003e34f0e2831fa1438e1f7545d7ab4959632d502a98651f4933e97fcf89ae22be67c4b06f1b8988fc8761' acts_as_api-1.0.1/spec/mongoid_dummy/config/initializers/include_acts_as_api.rb0000644000004100000410000000014313162253634030064 0ustar www-datawww-dataif defined?(Mongoid::Document) Mongoid::Document.send :include, ActsAsApi::Adapters::Mongoid end acts_as_api-1.0.1/spec/mongoid_dummy/config/initializers/session_store.rb0000644000004100000410000000065513162253634027022 0ustar www-datawww-data# Be sure to restart your server when you modify this file. MongoidDummy::Application.config.session_store :cookie_store, key: '_mongoid_dummy_session' # Use the database for sessions instead of the cookie-based default, # which shouldn't be used to store highly confidential information # (create the session table with "rails generate session_migration") # MongoidDummy::Application.config.session_store :active_record_store acts_as_api-1.0.1/spec/mongoid_dummy/config/initializers/mime_types.rb0000644000004100000410000000031513162253634026267 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # Add new mime types for use in respond_to blocks: # Mime::Type.register "text/richtext", :rtf # Mime::Type.register_alias "text/html", :iphone acts_as_api-1.0.1/spec/mongoid_dummy/config/initializers/wrap_parameters.rb0000644000004100000410000000052413162253634027312 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # # This file contains settings for ActionController::ParamsWrapper which # is enabled by default. # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. ActiveSupport.on_load(:action_controller) do wrap_parameters format: [:json] end acts_as_api-1.0.1/spec/mongoid_dummy/config/initializers/generators.rb0000644000004100000410000000005713162253634026270 0ustar www-datawww-dataRails.application.config.generators do |g| end acts_as_api-1.0.1/spec/mongoid_dummy/config/initializers/backtrace_silencers.rb0000644000004100000410000000062413162253634030105 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. # Rails.backtrace_cleaner.remove_silencers! acts_as_api-1.0.1/spec/mongoid_dummy/config/initializers/inflections.rb0000644000004100000410000000102513162253634026430 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # Add new inflection rules using the following format # (all these examples are active by default): # ActiveSupport::Inflector.inflections do |inflect| # inflect.plural /^(ox)$/i, '\1en' # inflect.singular /^(ox)en/i, '\1' # inflect.irregular 'person', 'people' # inflect.uncountable %w( fish sheep ) # end # # These inflection rules are supported but not enabled by default: # ActiveSupport::Inflector.inflections do |inflect| # inflect.acronym 'RESTful' # end acts_as_api-1.0.1/spec/mongoid_dummy/config/boot.rb0000644000004100000410000000027613162253634022357 0ustar www-datawww-datarequire 'rubygems' # Set up gems listed in the Gemfile. ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) acts_as_api-1.0.1/spec/mongoid_dummy/config/environments/0000755000004100000410000000000013162253634023611 5ustar www-datawww-dataacts_as_api-1.0.1/spec/mongoid_dummy/config/environments/test.rb0000644000004100000410000000257613162253634025127 0ustar www-datawww-dataMongoidDummy::Application.configure do # Settings specified here will take precedence over those in config/application.rb # The test environment is used exclusively to run your application's # test suite. You never need to work with it otherwise. Remember that # your test database is "scratch space" for the test suite and is wiped # and recreated between test runs. Don't rely on the data there! config.cache_classes = true # Configure static asset server for tests with Cache-Control for performance config.serve_static_assets = true # Log error messages when you accidentally call methods on nil config.whiny_nils = true # Show full error reports and disable caching config.consider_all_requests_local = true config.action_controller.perform_caching = false # Raise exceptions instead of rendering exception templates config.action_dispatch.show_exceptions = false # Disable request forgery protection in test environment config.action_controller.allow_forgery_protection = false # Tell Action Mailer not to deliver emails to the real world. # The :test delivery method accumulates sent emails in the # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test config.eager_load = false config.secret_key_base = 'helloworld123' # Print deprecation notices to the stderr config.active_support.deprecation = :stderr end acts_as_api-1.0.1/spec/mongoid_dummy/config/environments/production.rb0000644000004100000410000000436113162253634026330 0ustar www-datawww-dataMongoidDummy::Application.configure do # Settings specified here will take precedence over those in config/application.rb # Code is not reloaded between requests config.cache_classes = true # Full error reports are disabled and caching is turned on config.consider_all_requests_local = false config.action_controller.perform_caching = true # Disable Rails's static asset server (Apache or nginx will already do this) config.serve_static_assets = false # Compress JavaScripts and CSS config.assets.compress = true # Don't fallback to assets pipeline if a precompiled asset is missed config.assets.compile = false # Generate digests for assets URLs config.assets.digest = true # Defaults to Rails.root.join("public/assets") # config.assets.manifest = YOUR_PATH # Specifies the header that your server uses for sending files # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. # config.force_ssl = true # See everything in the log (default is :info) # config.log_level = :debug # Prepend all log lines with the following tags # config.log_tags = [ :subdomain, :uuid ] # Use a different logger for distributed setups # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) # Use a different cache store in production # config.cache_store = :mem_cache_store # Enable serving of images, stylesheets, and JavaScripts from an asset server # config.action_controller.asset_host = "http://assets.example.com" # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) # config.assets.precompile += %w( search.js ) # Disable delivery errors, bad email addresses will be ignored # config.action_mailer.raise_delivery_errors = false # Enable threaded mode # config.threadsafe! # Enable locale fallbacks for I18n (makes lookups for any locale fall back to # the I18n.default_locale when a translation can not be found) config.i18n.fallbacks = true # Send deprecation notices to registered listeners config.active_support.deprecation = :notify end acts_as_api-1.0.1/spec/mongoid_dummy/config/environments/development.rb0000644000004100000410000000217513162253634026465 0ustar www-datawww-dataMongoidDummy::Application.configure do # Settings specified here will take precedence over those in config/application.rb # In the development environment your application's code is reloaded on # every request. This slows down response time but is perfect for development # since you don't have to restart the web server when you make code changes. config.cache_classes = false # Log error messages when you accidentally call methods on nil. config.whiny_nils = true # Show full error reports and disable caching config.consider_all_requests_local = true config.action_controller.perform_caching = false # Don't care if the mailer can't send config.action_mailer.raise_delivery_errors = false # Print deprecation notices to the Rails logger config.active_support.deprecation = :log # Only use best-standards-support built into browsers config.action_dispatch.best_standards_support = :builtin # Do not compress assets config.assets.compress = false config.eager_load = false config.secret_key_base = 'helloworld123' # Expands the lines which load the assets config.assets.debug = true end acts_as_api-1.0.1/spec/mongoid_dummy/config/mongoid.yml0000644000004100000410000000030113162253634023233 0ustar www-datawww-datadevelopment: clients: default: database: mongoid hosts: - localhost:27017 test: clients: default: database: mongoid hosts: - localhost:27017 acts_as_api-1.0.1/spec/mongoid_dummy/config/routes.rb0000644000004100000410000000015013162253634022724 0ustar www-datawww-dataMongoidDummy::Application.routes.draw do mount SharedEngine::Engine => '/shared', :as => 'shared' end acts_as_api-1.0.1/spec/mongoid_dummy/config/environment.rb0000644000004100000410000000023413162253634023752 0ustar www-datawww-data# Load the rails application require File.expand_path('../application', __FILE__) # Initialize the rails application MongoidDummy::Application.initialize! acts_as_api-1.0.1/spec/mongoid_dummy/config/locales/0000755000004100000410000000000013162253634022504 5ustar www-datawww-dataacts_as_api-1.0.1/spec/mongoid_dummy/config/locales/en.yml0000644000004100000410000000032613162253634023632 0ustar www-datawww-data# Sample localization file for English. Add more files in this directory for other locales. # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. en: hello: "Hello world" acts_as_api-1.0.1/spec/mongoid_dummy/app/0000755000004100000410000000000013162253634020375 5ustar www-datawww-dataacts_as_api-1.0.1/spec/mongoid_dummy/app/models/0000755000004100000410000000000013162253634021660 5ustar www-datawww-dataacts_as_api-1.0.1/spec/mongoid_dummy/app/models/task.rb0000644000004100000410000000046213162253634023151 0ustar www-datawww-dataclass Task include Mongoid::Document field :heading, type: String field :description, type: String field :time_spent, type: Integer field :done, type: Boolean field :created_at, type: DateTime field :updated_at, type: DateTime embedded_in :user, class_name: 'User', inverse_of: :task end acts_as_api-1.0.1/spec/mongoid_dummy/app/models/profile.rb0000644000004100000410000000036413162253634023650 0ustar www-datawww-dataclass Profile include Mongoid::Document field :avatar, type: String field :homepage, type: String field :created_at, type: DateTime field :updated_at, type: DateTime embedded_in :user, class_name: 'User', inverse_of: :profile end acts_as_api-1.0.1/spec/mongoid_dummy/app/models/.gitkeep0000644000004100000410000000000013162253634023277 0ustar www-datawww-dataacts_as_api-1.0.1/spec/mongoid_dummy/app/models/untouched.rb0000644000004100000410000000023013162253634024176 0ustar www-datawww-dataclass Untouched include Mongoid::Document field :nothing, type: String field :created_at, type: DateTime field :updated_at, type: DateTime end acts_as_api-1.0.1/spec/mongoid_dummy/app/models/user.rb0000644000004100000410000000137013162253634023164 0ustar www-datawww-dataclass User include Mongoid::Document field :first_name, type: String field :last_name, type: String field :age, type: Integer field :active, type: Boolean field :created_at, type: DateTime field :updated_at, type: DateTime embeds_one :profile, class_name: 'Profile', inverse_of: :user embeds_many :tasks, class_name: 'Task', inverse_of: :user validates :first_name, :last_name, presence: true acts_as_api include UserTemplate def over_thirty? age > 30 end def under_thirty? age < 30 end def return_nil nil end def full_name '' << first_name.to_s << ' ' << last_name.to_s end def say_something 'something' end def sub_hash { foo: 'bar', hello: 'world' } end end acts_as_api-1.0.1/spec/mongoid_dummy/config.ru0000644000004100000410000000024113162253634021427 0ustar www-datawww-data# This file is used by Rack-based servers to start the application. require ::File.expand_path('../config/environment', __FILE__) run MongoidDummy::Application acts_as_api-1.0.1/spec/spec.opts0000644000004100000410000000001113162253634016577 0ustar www-datawww-data--colour acts_as_api-1.0.1/spec/spec_helper.rb0000644000004100000410000000106413162253634017565 0ustar www-datawww-dataENV['RAILS_ENV'] = 'test' if ENV['ACTS_AS_API_ORM'] == 'active_record' require 'active_record_dummy/config/environment' load "#{Rails.root}/db/schema.rb" # use db agnostic schema by default # ActiveRecord::Migrator.up('db/migrate') # use migrations elsif ENV['ACTS_AS_API_ORM'] == 'mongoid' require 'mongoid_dummy/config/environment' end require 'rspec/rails' # Requires supporting ruby files with custom matchers and macros, etc, # in spec/support/ and its subdirectories. Dir[File.dirname(__FILE__) + '/support/**/*.rb'].each { |file| require file } acts_as_api-1.0.1/spec/shared_engine/0000755000004100000410000000000013162253634017541 5ustar www-datawww-dataacts_as_api-1.0.1/spec/shared_engine/Rakefile0000644000004100000410000000117213162253634021207 0ustar www-datawww-data#!/usr/bin/env rake begin require 'bundler/setup' rescue LoadError puts 'You must `gem install bundler` and `bundle install` to run rake tasks' end begin require 'rdoc/task' rescue LoadError require 'rdoc/rdoc' require 'rake/rdoctask' RDoc::Task = Rake::RDocTask end RDoc::Task.new(:rdoc) do |rdoc| rdoc.rdoc_dir = 'rdoc' rdoc.title = 'SharedEngine' rdoc.options << '--line-numbers' rdoc.rdoc_files.include('README.rdoc') rdoc.rdoc_files.include('lib/**/*.rb') end APP_RAKEFILE = File.expand_path('../active_record_dummy/Rakefile', __FILE__) load 'rails/tasks/engine.rake' Bundler::GemHelper.install_tasks acts_as_api-1.0.1/spec/shared_engine/Gemfile0000644000004100000410000000106713162253634021040 0ustar www-datawww-datasource 'http://rubygems.org' # Declare your gem's dependencies in shared_engine.gemspec. # Bundler will treat runtime dependencies like base dependencies, and # development dependencies will be added by default to the :development group. gemspec # Declare any dependencies that are still in development here instead of in # your gemspec. These might include edge Rails or gems from your path or # Git. Remember to move these dependencies to your gemspec before releasing # your gem to rubygems.org. # To use debugger # gem 'ruby-debug19', :require => 'ruby-debug' acts_as_api-1.0.1/spec/shared_engine/script/0000755000004100000410000000000013162253634021045 5ustar www-datawww-dataacts_as_api-1.0.1/spec/shared_engine/script/rails0000755000004100000410000000050413162253634022104 0ustar www-datawww-data#!/usr/bin/env ruby # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. ENGINE_ROOT = File.expand_path('../..', __FILE__) ENGINE_PATH = File.expand_path('../../lib/shared_engine/engine', __FILE__) require 'rails/all' require 'rails/engine/commands' acts_as_api-1.0.1/spec/shared_engine/lib/0000755000004100000410000000000013162253634020307 5ustar www-datawww-dataacts_as_api-1.0.1/spec/shared_engine/lib/shared_engine/0000755000004100000410000000000013162253634023102 5ustar www-datawww-dataacts_as_api-1.0.1/spec/shared_engine/lib/shared_engine/engine.rb0000644000004100000410000000014213162253634024671 0ustar www-datawww-datamodule SharedEngine class Engine < ::Rails::Engine isolate_namespace SharedEngine end end acts_as_api-1.0.1/spec/shared_engine/lib/shared_engine/version.rb0000644000004100000410000000006313162253634025113 0ustar www-datawww-datamodule SharedEngine VERSION = '0.0.1'.freeze end acts_as_api-1.0.1/spec/shared_engine/lib/shared_engine.rb0000644000004100000410000000007013162253634023424 0ustar www-datawww-datarequire 'shared_engine/engine' module SharedEngine end acts_as_api-1.0.1/spec/shared_engine/lib/tasks/0000755000004100000410000000000013162253634021434 5ustar www-datawww-dataacts_as_api-1.0.1/spec/shared_engine/lib/tasks/shared_engine_tasks.rake0000644000004100000410000000013313162253634026275 0ustar www-datawww-data# desc "Explaining what the task does" # task :shared_engine do # # Task goes here # end acts_as_api-1.0.1/spec/shared_engine/.gitignore0000644000004100000410000000013013162253634021523 0ustar www-datawww-data.bundle/ log/*.log pkg/ dummy/db/*.sqlite3 dummy/log/*.log dummy/tmp/ dummy/.sass-cache acts_as_api-1.0.1/spec/shared_engine/config/0000755000004100000410000000000013162253634021006 5ustar www-datawww-dataacts_as_api-1.0.1/spec/shared_engine/config/routes.rb0000644000004100000410000000101713162253634022653 0ustar www-datawww-dataSharedEngine::Engine.routes.draw do resources :users do collection do get 'index_meta' get 'index_relation' end member do get 'show_meta' get 'show_default' get 'show_prefix_postfix' end end resources :respond_with_users do collection do get 'index_meta' get 'index_relation' get 'index_no_root_no_order' end member do get 'show_meta' get 'show_default' get 'show_prefix_postfix' end end resources :plain_objects end acts_as_api-1.0.1/spec/shared_engine/shared_engine.gemspec0000644000004100000410000000113613162253634023702 0ustar www-datawww-data$LOAD_PATH.push File.expand_path('../lib', __FILE__) # Maintain your gem's version: require 'shared_engine/version' # Describe your gem and declare its dependencies: Gem::Specification.new do |s| s.name = 'shared_engine' s.version = SharedEngine::VERSION s.authors = ['Your name'] s.email = ['Your email'] s.summary = 'Summary of SharedEngine.' s.description = 'Description of SharedEngine.' s.files = Dir['{app,config,db,lib}/**/*'] + ['MIT-LICENSE', 'Rakefile', 'README.rdoc'] s.add_dependency 'rails', '~> 5.1.3' s.add_development_dependency 'sqlite3' end acts_as_api-1.0.1/spec/shared_engine/app/0000755000004100000410000000000013162253634020321 5ustar www-datawww-dataacts_as_api-1.0.1/spec/shared_engine/app/controllers/0000755000004100000410000000000013162253634022667 5ustar www-datawww-dataacts_as_api-1.0.1/spec/shared_engine/app/controllers/shared_engine/0000755000004100000410000000000013162253634025462 5ustar www-datawww-dataacts_as_api-1.0.1/spec/shared_engine/app/controllers/shared_engine/users_controller.rb0000644000004100000410000000521313162253634031414 0ustar www-datawww-datamodule SharedEngine class UsersController < SharedEngine::ApplicationController def index @users = User.all.sort_by(&:first_name) respond_to do |format| format.xml { render_for_api params[:api_template].to_sym, xml: @users, root: :users } format.json { render_for_api params[:api_template].to_sym, json: @users, root: :users } end end def index_meta @users = User.all.to_a meta_hash = { page: 1, total: 999 } respond_to do |format| format.xml { render_for_api params[:api_template].to_sym, xml: @users, root: :users, meta: meta_hash } format.json { render_for_api params[:api_template].to_sym, json: @users, root: :users, meta: meta_hash } end end def index_relation @users = if defined?(ActiveRecord::Base) && User < ActiveRecord::Base User.where('id > 0').order('first_name ASC').all else User.limit(100).sort_by(&:first_name) end respond_to do |format| format.xml { render_for_api params[:api_template].to_sym, xml: @users } format.json { render_for_api params[:api_template].to_sym, json: @users } end end def show @user = User.find(params[:id]) respond_to do |format| # :root => :user is only used here because we need it for the node name of the MongoUser model format.xml { render_for_api params[:api_template].to_sym, xml: @user, root: :user } format.json { render_for_api params[:api_template].to_sym, json: @user, root: :user } end end def show_meta @user = User.find(params[:id]) meta_hash = { page: 1, total: 999 } respond_to do |format| # :root => :user is only used here because we need it for the node name of the MongoUser model format.xml { render_for_api params[:api_template].to_sym, xml: @user, root: :user } format.json { render_for_api params[:api_template].to_sym, json: @user, root: :user, meta: meta_hash } end end def show_default @user = User.find(params[:id]) respond_to do |format| format.xml { render xml: @user } format.json { render json: @user } end end def show_prefix_postfix @user = User.find(params[:id]) template = { template: params[:api_template], prefix: params[:api_prefix], postfix: params[:api_postfix] } respond_to do |format| # :root => :user is only used here because we need it for the node name of the MongoUser model format.xml { render_for_api template, xml: @user, root: :user } format.json { render_for_api template, json: @user, root: :user } end end end end acts_as_api-1.0.1/spec/shared_engine/app/controllers/shared_engine/respond_with_users_controller.rb0000644000004100000410000000367213162253634034210 0ustar www-datawww-datamodule SharedEngine class RespondWithUsersController < SharedEngine::ApplicationController respond_to :json, :xml self.responder = ActsAsApi::Responder def index @users = User.all.sort_by(&:first_name) respond_with @users, api_template: params[:api_template].to_sym, root: :users end def index_no_root_no_order @users = User.all.to_a respond_with @users, api_template: params[:api_template].to_sym end def index_meta @users = User.all.to_a meta_hash = { page: 1, total: 999 } respond_with @users, api_template: params[:api_template].to_sym, root: :users, meta: meta_hash end def index_relation @users = User.limit(100).sort_by(&:first_name) respond_with @users, api_template: params[:api_template].to_sym end def show @user = User.find(params[:id]) # root: :user is only used here because we need it for the node name of the MongoUser model respond_with @user, api_template: params[:api_template].to_sym, root: :user end def show_meta @user = User.find(params[:id]) meta_hash = { page: 1, total: 999 } # root: :user is only used here because we need it for the node name of the MongoUser model respond_with @user, api_template: params[:api_template].to_sym, root: :user, meta: meta_hash end def show_default @user = User.find(params[:id]) respond_with @user end def show_prefix_postfix @user = User.find(params[:id]) # root: :user is only used here because we need it for the node name of the MongoUser model respond_with @user, api_template: { template: params[:api_template], prefix: params[:api_prefix], postfix: params[:api_postfix] }, root: :user end def create @user = User.new(params[:user].permit!) if @user.save respond_with @user, api_template: params[:api_template] else respond_with @user end end end end acts_as_api-1.0.1/spec/shared_engine/app/controllers/shared_engine/plain_objects_controller.rb0000644000004100000410000000061113162253634033064 0ustar www-datawww-datamodule SharedEngine class PlainObjectsController < SharedEngine::ApplicationController before_action :setup_objects def index @users = [@han, @luke, @leia] respond_to do |format| format.xml { render_for_api params[:api_template].to_sym, xml: @users } format.json { render_for_api params[:api_template].to_sym, json: @users } end end end end acts_as_api-1.0.1/spec/shared_engine/app/controllers/shared_engine/application_controller.rb0000644000004100000410000000012513162253634032553 0ustar www-datawww-datamodule SharedEngine class ApplicationController < ActionController::Base end end acts_as_api-1.0.1/spec/shared_engine/app/models/0000755000004100000410000000000013162253634021604 5ustar www-datawww-dataacts_as_api-1.0.1/spec/shared_engine/app/models/user_template.rb0000644000004100000410000000726613162253634025015 0ustar www-datawww-datamodule UserTemplate extend ActiveSupport::Concern included do api_accessible :name_only do |t| t.add :first_name t.add :last_name end api_accessible :only_full_name do |t| t.add :full_name end api_accessible :rename_last_name do |t| t.add :last_name, as: :family_name end api_accessible :rename_full_name do |t| t.add :full_name, as: :other_full_name end api_accessible :with_former_value do |t| t.add :first_name t.add :last_name end api_accessible :age_and_first_name, extend: :with_former_value do |t| t.add :age t.remove :last_name end api_accessible :calling_a_proc do |t| t.add proc { |model| model.full_name.upcase }, as: :all_caps_name t.add proc { |_| Time.now.class.to_s }, as: :without_param end api_accessible :calling_a_lambda do |t| t.add ->(model) { model.full_name.upcase }, as: :all_caps_name t.add ->(_) { Time.now.class.to_s }, as: :without_param end api_accessible :include_tasks do |t| t.add :tasks end api_accessible :include_profile do |t| t.add :profile end api_accessible :other_sub_template do |t| t.add :first_name t.add :tasks, template: :other_template end api_accessible :include_completed_tasks do |t| t.add 'tasks.completed.all', as: :completed_tasks end api_accessible :sub_node do |t| t.add Hash[foo: :say_something], as: :sub_nodes end api_accessible :nested_sub_node do |t| t.add Hash[:foo, Hash[:bar, :last_name]], as: :sub_nodes end api_accessible :nested_sub_hash do |t| t.add :sub_hash end api_accessible :if_over_thirty do |t| t.add :first_name t.add :last_name, if: :over_thirty? end api_accessible :if_returns_nil do |t| t.add :first_name t.add :last_name, if: :return_nil end api_accessible :if_over_thirty_proc do |t| t.add :first_name t.add :last_name, if: ->(model) { model.over_thirty? } end api_accessible :if_returns_nil_proc do |t| t.add :first_name t.add :last_name, if: ->(_) { nil } end api_accessible :unless_under_thirty do |t| t.add :first_name t.add :last_name, unless: :under_thirty? end api_accessible :unless_returns_nil do |t| t.add :first_name t.add :last_name, unless: :return_nil end api_accessible :unless_under_thirty_proc do |t| t.add :first_name t.add :last_name, unless: ->(model) { model.under_thirty? } end api_accessible :unless_returns_nil_proc do |t| t.add :first_name t.add :last_name, unless: ->(_) { nil } end api_accessible :with_prefix_name_only do |t| t.add ->(_) { 'true' }, as: :prefix t.add :first_name t.add :last_name end api_accessible :name_only_with_postfix do |t| t.add :first_name t.add :last_name t.add ->(_) { 'true' }, as: :postfix end api_accessible :with_prefix_name_only_with_postfix do |t| t.add ->(_) { 'true' }, as: :prefix t.add :first_name t.add :last_name t.add ->(_) { 'true' }, as: :postfix end def before_api_response(_api_response) @before_api_response_called = true end def before_api_response_called? !!@before_api_response_called end def after_api_response(_api_response) @after_api_response_called = true end def after_api_response_called? !!@after_api_response_called end def skip_api_response=(should_skip) @skip_api_response = should_skip end def around_api_response(_api_response) @skip_api_response ? { skipped: true } : yield end end end acts_as_api-1.0.1/spec/shared_engine/app/models/plain_object.rb0000644000004100000410000000043413162253634024563 0ustar www-datawww-dataclass PlainObject extend ActsAsApi::Base attr_accessor :first_name, :last_name, :age, :active def initialize(opts) opts.each do |k, v| send("#{k}=", v) end end def model_name 'plain_object' end acts_as_api include SharedEngine::UserTemplate end acts_as_api-1.0.1/spec/models/0000755000004100000410000000000013162253634016231 5ustar www-datawww-dataacts_as_api-1.0.1/spec/models/model_spec.rb0000644000004100000410000000165113162253634020673 0ustar www-datawww-datarequire 'spec_helper' describe 'Models', type: :model do before(:each) do setup_models end after(:each) do clean_up_models end describe :act_as_api do it_supports 'including an association in the api template' it_supports 'calling a closure in the api template' it_supports 'conditional if statements' it_supports 'conditional unless statements' it_supports 'acts_as_api is enabled' it_supports 'extending a given api template' it_supports 'calling a method in the api template' it_supports 'renaming' it_supports 'listing attributes in the api template' it_supports 'creating a sub hash in the api template' it_supports 'trying to render an api template that is not defined' # deactivated for vanilla ruby as acts_as_api won't get mixed into any class it_supports 'untouched models' it_supports 'defining a model callback' it_supports 'options' end end acts_as_api-1.0.1/spec/active_record_dummy/0000755000004100000410000000000013162253634020772 5ustar www-datawww-dataacts_as_api-1.0.1/spec/active_record_dummy/Rakefile0000644000004100000410000000043213162253634022436 0ustar www-datawww-data#!/usr/bin/env rake # Add your own tasks in files placed in lib/tasks ending in .rake, # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. require File.expand_path('../config/application', __FILE__) ActiveRecordDummy::Application.load_tasks acts_as_api-1.0.1/spec/active_record_dummy/Gemfile0000644000004100000410000000022613162253634022265 0ustar www-datawww-datasource 'https://rubygems.org' gem 'rails', '5.0.0.1' gem 'sqlite3' gem 'shared_engine', path: '../shared_engine' gem 'acts_as_api', path: '../../' acts_as_api-1.0.1/spec/active_record_dummy/script/0000755000004100000410000000000013162253634022276 5ustar www-datawww-dataacts_as_api-1.0.1/spec/active_record_dummy/script/rails0000755000004100000410000000044513162253634023341 0ustar www-datawww-data#!/usr/bin/env ruby # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. APP_PATH = File.expand_path('../../config/application', __FILE__) require File.expand_path('../../config/boot', __FILE__) require 'rails/commands' acts_as_api-1.0.1/spec/active_record_dummy/log/0000755000004100000410000000000013162253634021553 5ustar www-datawww-dataacts_as_api-1.0.1/spec/active_record_dummy/log/.gitkeep0000644000004100000410000000000013162253634023172 0ustar www-datawww-dataacts_as_api-1.0.1/spec/active_record_dummy/db/0000755000004100000410000000000013162253634021357 5ustar www-datawww-dataacts_as_api-1.0.1/spec/active_record_dummy/db/schema.rb0000644000004100000410000000273213162253634023150 0ustar www-datawww-data# This file is auto-generated from the current state of the database. Instead # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. # # Note that this schema.rb definition is the authoritative source for your # database schema. If you need to create the application database on another # system, you should be using db:schema:load, not running all the migrations # from scratch. The latter is a flawed and unsustainable approach (the more migrations # you'll amass, the slower it'll run and the greater likelihood for issues). # # It's strongly recommended to check this file into your version control system. ActiveRecord::Schema.define(version: 20110214201640) do create_table 'tasks', force: true do |t| t.integer 'user_id' t.string 'heading' t.string 'description' t.integer 'time_spent' t.boolean 'done' t.datetime 'created_at' t.datetime 'updated_at' end create_table 'profiles', force: true do |t| t.integer 'user_id' t.string 'avatar' t.string 'homepage' t.datetime 'created_at' t.datetime 'updated_at' end create_table 'users', force: true do |t| t.string 'first_name' t.string 'last_name' t.integer 'age' t.boolean 'active' t.datetime 'created_at' t.datetime 'updated_at' end create_table 'untoucheds', force: true do |t| t.string 'nothing' t.timestamps end end acts_as_api-1.0.1/spec/active_record_dummy/db/seeds.rb0000644000004100000410000000054113162253634023007 0ustar www-datawww-data# This file should contain all the record creation needed to seed the database with its default values. # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). # # Examples: # # cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }]) # Mayor.create(:name => 'Daley', :city => cities.first) acts_as_api-1.0.1/spec/active_record_dummy/db/migrate/0000755000004100000410000000000013162253634023007 5ustar www-datawww-dataacts_as_api-1.0.1/spec/active_record_dummy/db/migrate/20110214201640_create_tables.rb0000644000004100000410000000167013162253634027564 0ustar www-datawww-dataclass CreateTables < ActiveRecord::Migration def self.up create_table 'users', force: true do |t| t.string 'first_name' t.string 'last_name' t.integer 'age' t.boolean 'active' t.datetime 'created_at' t.datetime 'updated_at' end create_table 'tasks', force: true do |t| t.integer 'user_id' t.string 'heading' t.string 'description' t.integer 'time_spent' t.boolean 'done' t.datetime 'created_at' t.datetime 'updated_at' end create_table 'profiles', force: true do |t| t.integer 'user_id' t.string 'avatar' t.string 'homepage' t.datetime 'created_at' t.datetime 'updated_at' end create_table :untoucheds do |t| t.string 'nothing' t.timestamps end end def self.down drop_table :untoucheds drop_table :profiles drop_table :tasks drop_table :users end end acts_as_api-1.0.1/spec/active_record_dummy/.gitignore0000644000004100000410000000065613162253634022771 0ustar www-datawww-data# See http://help.github.com/ignore-files/ for more about ignoring files. # # If you find yourself ignoring temporary files generated by your text editor # or operating system, you probably want to add a global ignore instead: # git config --global core.excludesfile ~/.gitignore_global # Ignore bundler config /.bundle # Ignore the default SQLite database. /db/*.sqlite3 # Ignore all logfiles and tempfiles. /log/*.log /tmp acts_as_api-1.0.1/spec/active_record_dummy/config/0000755000004100000410000000000013162253634022237 5ustar www-datawww-dataacts_as_api-1.0.1/spec/active_record_dummy/config/application.rb0000644000004100000410000000444513162253634025076 0ustar www-datawww-datarequire File.expand_path('../boot', __FILE__) require 'rails/all' if defined?(Bundler) # If you precompile assets before deploying to production, use this line Bundler.require(*Rails.groups(assets: %w(development test))) # If you want your assets lazily compiled in production, use this line # Bundler.require(:default, :assets, Rails.env) end module ActiveRecordDummy class Application < Rails::Application # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. # Custom directories with classes and modules you want to be autoloadable. # config.autoload_paths += %W(#{config.root}/extras) # Only load the plugins named here, in the order given (default is alphabetical). # :all can be used as a placeholder for all plugins not explicitly named. # config.plugins = [ :exception_notification, :ssl_requirement, :all ] # Activate observers that should always be running. # config.active_record.observers = :cacher, :garbage_collector, :forum_observer # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. # config.time_zone = 'Central Time (US & Canada)' # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] # config.i18n.default_locale = :de # Configure the default encoding used in templates for Ruby 1.9. config.encoding = 'utf-8' # Configure sensitive parameters which will be filtered from the log file. config.filter_parameters += [:password] # Use SQL instead of Active Record's schema dumper when creating the database. # This is necessary if your schema can't be completely dumped by the schema dumper, # like if you have constraints or database-specific column types # config.active_record.schema_format = :sql # Enable the asset pipeline config.assets.enabled = true # Version of your assets, change this if you want to expire all your assets config.assets.version = '1.0' end end acts_as_api-1.0.1/spec/active_record_dummy/config/initializers/0000755000004100000410000000000013162253634024745 5ustar www-datawww-dataacts_as_api-1.0.1/spec/active_record_dummy/config/initializers/secret_token.rb0000644000004100000410000000077413162253634027767 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # Your secret key for verifying the integrity of signed cookies. # If you change this key, all old signed cookies will become invalid! # Make sure the secret is at least 30 characters and all random, # no regular words or you'll be exposed to dictionary attacks. ActiveRecordDummy::Application.config.secret_token = '937dff1ad181db43bc2170d1d12ae4bff955f0b2a657d6e2cfa006976ed6e4311de228e9321fc530ff00157be4189022b715832ffb0c6fa8be12e7185b41d7a4' acts_as_api-1.0.1/spec/active_record_dummy/config/initializers/session_store.rb0000644000004100000410000000067513162253634030201 0ustar www-datawww-data# Be sure to restart your server when you modify this file. ActiveRecordDummy::Application.config.session_store :cookie_store, key: '_active_record_dummy_session' # Use the database for sessions instead of the cookie-based default, # which shouldn't be used to store highly confidential information # (create the session table with "rails generate session_migration") # ActiveRecordDummy::Application.config.session_store :active_record_store acts_as_api-1.0.1/spec/active_record_dummy/config/initializers/mime_types.rb0000644000004100000410000000031513162253634027444 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # Add new mime types for use in respond_to blocks: # Mime::Type.register "text/richtext", :rtf # Mime::Type.register_alias "text/html", :iphone acts_as_api-1.0.1/spec/active_record_dummy/config/initializers/wrap_parameters.rb0000644000004100000410000000072113162253634030466 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # # This file contains settings for ActionController::ParamsWrapper which # is enabled by default. # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. ActiveSupport.on_load(:action_controller) do wrap_parameters format: [:json] end # Disable root element in JSON by default. ActiveSupport.on_load(:active_record) do self.include_root_in_json = false end acts_as_api-1.0.1/spec/active_record_dummy/config/initializers/generators.rb0000644000004100000410000000005713162253634027445 0ustar www-datawww-dataRails.application.config.generators do |g| end acts_as_api-1.0.1/spec/active_record_dummy/config/initializers/backtrace_silencers.rb0000644000004100000410000000062413162253634031262 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. # Rails.backtrace_cleaner.remove_silencers! acts_as_api-1.0.1/spec/active_record_dummy/config/initializers/inflections.rb0000644000004100000410000000102513162253634027605 0ustar www-datawww-data# Be sure to restart your server when you modify this file. # Add new inflection rules using the following format # (all these examples are active by default): # ActiveSupport::Inflector.inflections do |inflect| # inflect.plural /^(ox)$/i, '\1en' # inflect.singular /^(ox)en/i, '\1' # inflect.irregular 'person', 'people' # inflect.uncountable %w( fish sheep ) # end # # These inflection rules are supported but not enabled by default: # ActiveSupport::Inflector.inflections do |inflect| # inflect.acronym 'RESTful' # end acts_as_api-1.0.1/spec/active_record_dummy/config/boot.rb0000644000004100000410000000027613162253634023534 0ustar www-datawww-datarequire 'rubygems' # Set up gems listed in the Gemfile. ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) acts_as_api-1.0.1/spec/active_record_dummy/config/environments/0000755000004100000410000000000013162253634024766 5ustar www-datawww-dataacts_as_api-1.0.1/spec/active_record_dummy/config/environments/test.rb0000644000004100000410000000260313162253634026273 0ustar www-datawww-dataActiveRecordDummy::Application.configure do # Settings specified here will take precedence over those in config/application.rb # The test environment is used exclusively to run your application's # test suite. You never need to work with it otherwise. Remember that # your test database is "scratch space" for the test suite and is wiped # and recreated between test runs. Don't rely on the data there! config.cache_classes = true # Configure static asset server for tests with Cache-Control for performance config.serve_static_assets = true # Log error messages when you accidentally call methods on nil config.whiny_nils = true # Show full error reports and disable caching config.consider_all_requests_local = true config.action_controller.perform_caching = false # Raise exceptions instead of rendering exception templates config.action_dispatch.show_exceptions = false # Disable request forgery protection in test environment config.action_controller.allow_forgery_protection = false # Tell Action Mailer not to deliver emails to the real world. # The :test delivery method accumulates sent emails in the # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test config.eager_load = false config.secret_key_base = 'helloworld123' # Print deprecation notices to the stderr config.active_support.deprecation = :stderr end acts_as_api-1.0.1/spec/active_record_dummy/config/environments/production.rb0000644000004100000410000000436613162253634027512 0ustar www-datawww-dataActiveRecordDummy::Application.configure do # Settings specified here will take precedence over those in config/application.rb # Code is not reloaded between requests config.cache_classes = true # Full error reports are disabled and caching is turned on config.consider_all_requests_local = false config.action_controller.perform_caching = true # Disable Rails's static asset server (Apache or nginx will already do this) config.serve_static_assets = false # Compress JavaScripts and CSS config.assets.compress = true # Don't fallback to assets pipeline if a precompiled asset is missed config.assets.compile = false # Generate digests for assets URLs config.assets.digest = true # Defaults to Rails.root.join("public/assets") # config.assets.manifest = YOUR_PATH # Specifies the header that your server uses for sending files # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. # config.force_ssl = true # See everything in the log (default is :info) # config.log_level = :debug # Prepend all log lines with the following tags # config.log_tags = [ :subdomain, :uuid ] # Use a different logger for distributed setups # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) # Use a different cache store in production # config.cache_store = :mem_cache_store # Enable serving of images, stylesheets, and JavaScripts from an asset server # config.action_controller.asset_host = "http://assets.example.com" # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) # config.assets.precompile += %w( search.js ) # Disable delivery errors, bad email addresses will be ignored # config.action_mailer.raise_delivery_errors = false # Enable threaded mode # config.threadsafe! # Enable locale fallbacks for I18n (makes lookups for any locale fall back to # the I18n.default_locale when a translation can not be found) config.i18n.fallbacks = true # Send deprecation notices to registered listeners config.active_support.deprecation = :notify end acts_as_api-1.0.1/spec/active_record_dummy/config/environments/development.rb0000644000004100000410000000220213162253634027631 0ustar www-datawww-dataActiveRecordDummy::Application.configure do # Settings specified here will take precedence over those in config/application.rb # In the development environment your application's code is reloaded on # every request. This slows down response time but is perfect for development # since you don't have to restart the web server when you make code changes. config.cache_classes = false # Log error messages when you accidentally call methods on nil. config.whiny_nils = true # Show full error reports and disable caching config.consider_all_requests_local = true config.action_controller.perform_caching = false # Don't care if the mailer can't send config.action_mailer.raise_delivery_errors = false # Print deprecation notices to the Rails logger config.active_support.deprecation = :log # Only use best-standards-support built into browsers config.action_dispatch.best_standards_support = :builtin # Do not compress assets config.assets.compress = false config.eager_load = false config.secret_key_base = 'helloworld123' # Expands the lines which load the assets config.assets.debug = true end acts_as_api-1.0.1/spec/active_record_dummy/config/database.yml0000644000004100000410000000110013162253634024516 0ustar www-datawww-data# SQLite version 3.x # gem install sqlite3 # # Ensure the SQLite 3 gem is defined in your Gemfile # gem 'sqlite3' development: adapter: sqlite3 database: db/development.sqlite3 pool: 5 timeout: 5000 # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: adapter: sqlite3 database: db/test.sqlite3 pool: 5 timeout: 5000 production: adapter: sqlite3 database: db/production.sqlite3 pool: 5 timeout: 5000 acts_as_api-1.0.1/spec/active_record_dummy/config/routes.rb0000644000004100000410000000015513162253634024106 0ustar www-datawww-dataActiveRecordDummy::Application.routes.draw do mount SharedEngine::Engine => '/shared', :as => 'shared' end acts_as_api-1.0.1/spec/active_record_dummy/config/environment.rb0000644000004100000410000000024113162253634025125 0ustar www-datawww-data# Load the rails application require File.expand_path('../application', __FILE__) # Initialize the rails application ActiveRecordDummy::Application.initialize! acts_as_api-1.0.1/spec/active_record_dummy/config/locales/0000755000004100000410000000000013162253634023661 5ustar www-datawww-dataacts_as_api-1.0.1/spec/active_record_dummy/config/locales/en.yml0000644000004100000410000000032613162253634025007 0ustar www-datawww-data# Sample localization file for English. Add more files in this directory for other locales. # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. en: hello: "Hello world" acts_as_api-1.0.1/spec/active_record_dummy/app/0000755000004100000410000000000013162253634021552 5ustar www-datawww-dataacts_as_api-1.0.1/spec/active_record_dummy/app/models/0000755000004100000410000000000013162253634023035 5ustar www-datawww-dataacts_as_api-1.0.1/spec/active_record_dummy/app/models/task.rb0000644000004100000410000000006713162253634024327 0ustar www-datawww-dataclass Task < ActiveRecord::Base belongs_to :user end acts_as_api-1.0.1/spec/active_record_dummy/app/models/profile.rb0000644000004100000410000000007213162253634025021 0ustar www-datawww-dataclass Profile < ActiveRecord::Base belongs_to :user end acts_as_api-1.0.1/spec/active_record_dummy/app/models/.gitkeep0000644000004100000410000000000013162253634024454 0ustar www-datawww-dataacts_as_api-1.0.1/spec/active_record_dummy/app/models/untouched.rb0000644000004100000410000000005113162253634025354 0ustar www-datawww-dataclass Untouched < ActiveRecord::Base end acts_as_api-1.0.1/spec/active_record_dummy/app/models/user.rb0000644000004100000410000000747313162253634024353 0ustar www-datawww-dataclass User < ActiveRecord::Base validates :first_name, :last_name, presence: true has_many :tasks has_one :profile acts_as_api api_accessible :name_only do |t| t.add :first_name t.add :last_name end api_accessible :only_full_name do |t| t.add :full_name end api_accessible :rename_last_name do |t| t.add :last_name, as: :family_name end api_accessible :rename_full_name do |t| t.add :full_name, as: :other_full_name end api_accessible :with_former_value do |t| t.add :first_name t.add :last_name end api_accessible :age_and_first_name, extend: :with_former_value do |t| t.add :age t.remove :last_name end api_accessible :calling_a_proc do |t| t.add proc { |model| model.full_name.upcase }, as: :all_caps_name t.add proc { |_| Time.now.class.to_s }, as: :without_param end api_accessible :calling_a_lambda do |t| t.add ->(model) { model.full_name.upcase }, as: :all_caps_name t.add ->(_) { Time.now.class.to_s }, as: :without_param end api_accessible :include_tasks do |t| t.add :tasks end api_accessible :include_profile do |t| t.add :profile end api_accessible :other_sub_template do |t| t.add :first_name t.add :tasks, template: :other_template end api_accessible :include_completed_tasks do |t| t.add 'tasks.completed.all', as: :completed_tasks end api_accessible :sub_node do |t| t.add Hash[foo: :say_something], as: :sub_nodes end api_accessible :nested_sub_node do |t| t.add Hash[:foo, Hash[:bar, :last_name]], as: :sub_nodes end api_accessible :nested_sub_hash do |t| t.add :sub_hash end api_accessible :if_over_thirty do |t| t.add :first_name t.add :last_name, if: :over_thirty? end api_accessible :if_returns_nil do |t| t.add :first_name t.add :last_name, if: :return_nil end api_accessible :if_over_thirty_proc do |t| t.add :first_name t.add :last_name, if: ->(model) { model.over_thirty? } end api_accessible :if_returns_nil_proc do |t| t.add :first_name t.add :last_name, if: ->(_) { nil } end api_accessible :unless_under_thirty do |t| t.add :first_name t.add :last_name, unless: :under_thirty? end api_accessible :unless_returns_nil do |t| t.add :first_name t.add :last_name, unless: :return_nil end api_accessible :unless_under_thirty_proc do |t| t.add :first_name t.add :last_name, unless: ->(model) { model.under_thirty? } end api_accessible :unless_returns_nil_proc do |t| t.add :first_name t.add :last_name, unless: ->(_) { nil } end api_accessible :with_prefix_name_only do |t| t.add ->(_) { 'true' }, as: :prefix t.add :first_name t.add :last_name end api_accessible :name_only_with_postfix do |t| t.add :first_name t.add :last_name t.add ->(_) { 'true' }, as: :postfix end api_accessible :with_prefix_name_only_with_postfix do |t| t.add ->(_) { 'true' }, as: :prefix t.add :first_name t.add :last_name t.add ->(_) { 'true' }, as: :postfix end def before_api_response(_api_response) @before_api_response_called = true end def before_api_response_called? !!@before_api_response_called end def after_api_response(_api_response) @after_api_response_called = true end def after_api_response_called? !!@after_api_response_called end def skip_api_response=(should_skip) @skip_api_response = should_skip end def around_api_response(_api_response) @skip_api_response ? { skipped: true } : yield end def over_thirty? age > 30 end def under_thirty? age < 30 end def return_nil nil end def full_name '' << first_name.to_s << ' ' << last_name.to_s end def say_something 'something' end def sub_hash { foo: 'bar', hello: 'world' } end end acts_as_api-1.0.1/spec/active_record_dummy/config.ru0000644000004100000410000000024613162253634022611 0ustar www-datawww-data# This file is used by Rack-based servers to start the application. require ::File.expand_path('../config/environment', __FILE__) run ActiveRecordDummy::Application acts_as_api-1.0.1/spec/support/0000755000004100000410000000000013162253634016462 5ustar www-datawww-dataacts_as_api-1.0.1/spec/support/controller_examples.rb0000644000004100000410000003115013162253634023070 0ustar www-datawww-datashared_examples_for 'a controller with ActsAsApi responses' do include ApiTestHelpers routes { SharedEngine::Engine.routes } describe 'xml responses' do describe 'get all users' do before(:each) do get :index, format: 'xml', params: { api_template: :name_only } end it 'should have a root node named users' do expect(response_body).to have_selector('users') end it 'should contain all users' do expect(response_body).to have_selector('users > user') do |users| expect(users.size).to eql(3) end end it 'should contain the specified attributes' do expect(response_body).to have_selector('users > user > first-name') expect(response_body).to have_selector('users > user > last-name') end end describe 'get a single user' do before(:each) do get :show, format: 'xml', params: { api_template: :name_only, id: @luke.id } end it 'should have a root node named user' do expect(response_body).to have_selector('user') end it 'should contain the specified attributes' do expect(response_body).to have_selector('user > first-name') expect(response_body).to have_selector('user > last-name') end end end describe 'json responses' do describe 'get all users' do before(:each) do get :index, format: 'json', params: { api_template: :name_only } end it 'should have a root node named users' do expect(response_body_json).to have_key('users') end it 'should contain all users' do expect(response_body_json['users']).to be_a(Array) end it 'should contain the specified attributes' do expect(response_body_json['users'].first).to have_key('first_name') expect(response_body_json['users'].first).to have_key('last_name') end it 'should contain the specified values' do expect(response_body_json['users'].first['first_name']).to eql('Han') expect(response_body_json['users'].first['last_name']).to eql('Solo') end end describe 'get all users as a ActiveRecord::Relation (or similar chained) object, autodetecting the root node name' do before(:each) do get :index_relation, format: 'json', params: { api_template: :name_only } end it 'should have a root node named users' do expect(response_body_json).to have_key('users') end it 'should contain all users' do expect(response_body_json['users']).to be_a(Array) end it 'should contain the specified attributes' do expect(response_body_json['users'].first).to have_key('first_name') expect(response_body_json['users'].first).to have_key('last_name') end it 'should contain the specified values' do expect(response_body_json['users'].first['first_name']).to eql('Han') expect(response_body_json['users'].first['last_name']).to eql('Solo') end end describe 'get a single user' do before(:each) do get :show, format: 'json', params: { api_template: :name_only, id: @luke.id } end it 'should have a root node named user' do expect(response_body_json).to have_key('user') end it 'should contain the specified attributes' do expect(response_body_json['user']).to have_key('first_name') expect(response_body_json['user']).to have_key('last_name') end it 'should contain the specified values' do expect(response_body_json['user']['first_name']).to eql('Luke') expect(response_body_json['user']['last_name']).to eql('Skywalker') end end describe 'get a single user with a nil profile' do before(:each) do Profile.acts_as_api Profile.api_accessible :include_profile do |t| t.add :avatar t.add :homepage end get :show, format: 'json', params: { api_template: :include_profile, id: @han.id } end it 'should have a root node named user' do expect(response_body_json).to have_key('user') end it 'should contain the specified attributes' do expect(response_body_json['user']).to have(1).keys expect(response_body_json['user']).to have_key('profile') end it 'should contain the specified values' do expect(response_body_json['user']['profile']).to be_nil end end describe 'get a user without specifying an api template' do before(:each) do get :show_default, format: 'json', params: { id: @luke.id } end it 'should respond with HTTP 200' do expect(response.code).to eq('200') end it 'should render the model with to_json' do expect(response.body).to eq(@luke.to_json) end end end describe 'Rails 3 default style json responses' do before(:each) do @org_include_root_in_json_collections = ActsAsApi::Config.include_root_in_json_collections ActsAsApi::Config.include_root_in_json_collections = true end after(:each) do ActsAsApi::Config.include_root_in_json_collections = @org_include_root_in_json_collections end describe 'get all users' do before(:each) do get :index, format: 'json', params: { api_template: :name_only } end it 'should have a root node named users' do expect(response_body_json).to have_key('users') end it 'should contain all users' do expect(response_body_json['users']).to be_a(Array) end it 'should contain the specified attributes' do expect(response_body_json['users'].first['user']).to have_key('first_name') expect(response_body_json['users'].first['user']).to have_key('last_name') end it 'contains the user root nodes' do expect(response_body_json['users'].collect(&:keys).flatten.uniq).to eql(['user']) end it 'should contain the specified values' do expect(response_body_json['users'].first['user']['first_name']).to eql('Han') expect(response_body_json['users'].first['user']['last_name']).to eql('Solo') end end describe 'get a single user' do before(:each) do get :show, format: 'json', params: { api_template: :name_only, id: @luke.id } end it 'should have a root node named user' do expect(response_body_json).to have_key('user') end it 'should contain the specified attributes' do expect(response_body_json['user']).to have_key('first_name') expect(response_body_json['user']).to have_key('last_name') end it 'should contain the specified values' do expect(response_body_json['user']['first_name']).to eql('Luke') expect(response_body_json['user']['last_name']).to eql('Skywalker') end end end describe 'jsonp responses with callback' do it 'should be disabled by default' do @callback = 'mycallback' get :index, format: 'json', params: { api_template: :name_only, callback: @callback } expect(response_body_jsonp(@callback)).to be_nil end describe 'enabled jsonp callbacks' do before(:each) do @callback = 'mycallback' User.acts_as_api do |config| config.allow_jsonp_callback = true end end after(:each) do # put things back to the way they were User.acts_as_api do |config| config.allow_jsonp_callback = false end end describe 'get all users' do before(:each) do get :index, format: 'json', params: { api_template: :name_only, callback: @callback } end it 'should wrap the response in the callback' do expect(response_body_jsonp(@callback)).not_to be_nil end end describe 'get a single user' do before(:each) do get :show, format: 'json', params: { api_template: :name_only, id: @luke.id, callback: @callback } end it 'should wrap the response in the callback' do expect(response_body_jsonp(@callback)).not_to be_nil end end describe 'Requesting the JSONP content as JavaScript' do before(:each) do get :index, format: :json, params: { api_template: :name_only, callback: @callback } end it 'should set the content type to JavaScript' do expect(response.content_type).to eq(Mime[:js]) end end end end describe 'config.add_root_node_for is empty, so no root node is created' do before(:each) do @org_add_root_node_for_config = ActsAsApi::Config.add_root_node_for.dup ActsAsApi::Config.add_root_node_for = [] end after(:each) do ActsAsApi::Config.add_root_node_for = @org_add_root_node_for_config end describe 'get all users' do before(:each) do get :index, format: 'json', params: { api_template: :name_only, callback: @callback } end it 'response has no named root node' do expect(response_body_json).to be_an(Array) end end describe 'get a single user' do before(:each) do get :show, format: 'json', params: { api_template: :name_only, id: @luke.id } end it 'response has no named root node' do expect(response_body_json).to be_a(Hash) expect(response_body_json.keys).to include('first_name') end end end describe 'pass meta information on rendering' do describe 'get all users' do before(:each) do get :index_meta, format: 'json', params: { api_template: :name_only } end it 'shows model response fields' do expect(response_body_json).to be_a(Hash) expect(response_body_json).to have_key('users') expect(response_body_json['users']).to be_an(Array) end it 'shows page field' do expect(response_body_json).to have_key('page') end it 'shows total field' do expect(response_body_json).to have_key('total') end end describe 'get a single user' do before(:each) do get :show_meta, format: 'json', params: { api_template: :name_only, id: @luke.id } end it 'shows model response fields' do expect(response_body_json).to be_a(Hash) expect(response_body_json).to have_key('user') end it 'shows page field' do expect(response_body_json).to have_key('page') end it 'shows total field' do expect(response_body_json).to have_key('total') end end end describe 'api prefix' do describe 'get single user' do before(:each) do get :show_prefix_postfix, format: 'xml', params: { api_template: :name_only, api_prefix: :with_prefix, id: @luke.id } end it 'should have a root node named user' do expect(response_body).to have_selector('user') end it 'should contain the specified attributes' do expect(response_body).to have_selector('user > prefix') expect(response_body).to have_selector('user > first-name') expect(response_body).to have_selector('user > last-name') end it 'should not contain the specified attributes' do expect(response_body).not_to have_selector('user > postfix') end end end describe 'api postfix' do describe 'get single user' do before(:each) do get :show_prefix_postfix, format: 'xml', params: { api_template: :name_only, api_postfix: :with_postfix, id: @luke.id } end it 'should have a root node named user' do expect(response_body).to have_selector('user') end it 'should contain the specified attributes' do expect(response_body).to have_selector('user > first-name') expect(response_body).to have_selector('user > last-name') expect(response_body).to have_selector('user > postfix') end it 'should not contain the specified attributes' do expect(response_body).not_to have_selector('user > prefix') end end end describe 'api prefix and api postfix' do describe 'get single user' do before(:each) do get :show_prefix_postfix, format: 'xml', params: { api_template: :name_only, api_prefix: :with_prefix, api_postfix: :with_postfix, id: @luke.id } end it 'should have a root node named user' do expect(response_body).to have_selector('user') end it 'should contain the specified attributes' do expect(response_body).to have_selector('user > prefix') expect(response_body).to have_selector('user > first-name') expect(response_body).to have_selector('user > last-name') expect(response_body).to have_selector('user > postfix') end end end end acts_as_api-1.0.1/spec/support/simple_fixtures.rb0000644000004100000410000000247613162253634022242 0ustar www-datawww-datamodule SimpleFixtures def setup_models @luke = User.create(first_name: 'Luke', last_name: 'Skywalker', age: 25, active: true) @han = User.create(first_name: 'Han', last_name: 'Solo', age: 35, active: true) @leia = User.create(first_name: 'Princess', last_name: 'Leia', age: 25, active: false) @luke.profile = Profile.new(avatar: 'picard.jpg', homepage: 'lukasarts.com') @luke.profile.save! @destroy_deathstar = @luke.tasks.create(heading: 'Destroy Deathstar', description: 'XWing, Shoot, BlowUp', time_spent: 30, done: true) @study_with_yoda = @luke.tasks.create(heading: 'Study with Yoda', description: 'Jedi Stuff, ya know', time_spent: 60, done: true) @win_rebellion = @luke.tasks.create(heading: 'Win Rebellion', description: 'no idea yet...', time_spent: 180, done: false) @luke.save! @han.save! @leia.save! end def clean_up_models User.delete_all end def setup_objects @luke = PlainObject.new(first_name: 'Luke', last_name: 'Skywalker', age: 25, active: true) @han = PlainObject.new(first_name: 'Han', last_name: 'Solo', age: 35, active: true) @leia = PlainObject.new(first_name: 'Princess', last_name: 'Leia', age: 25, active: false) end end RSpec.configure do |c| c.include SimpleFixtures end acts_as_api-1.0.1/spec/support/model_examples/0000755000004100000410000000000013162253634021460 5ustar www-datawww-dataacts_as_api-1.0.1/spec/support/model_examples/conditional_if.rb0000644000004100000410000000771613162253634025001 0ustar www-datawww-datashared_examples_for 'conditional if statements' do describe 'using the :if option' do describe 'passing a symbol' do describe 'that returns false' do subject(:response) { @luke.as_api_response(:if_over_thirty) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(1).keys end it 'will not add the conditional field but all others' do expect(response.keys).to include(:first_name) expect(response.keys).not_to include(:full_name) end it 'the other specified fields have the correct value' do expect(response.values).to include(@luke.first_name) end end describe 'that returns nil' do subject(:response) { @luke.as_api_response(:if_returns_nil) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(1).keys end it 'will not add the conditional field but all others' do expect(response.keys).to include(:first_name) expect(response.keys).not_to include(:full_name) end it 'the other specified fields have the correct value' do expect(response.values).to include(@luke.first_name) end end describe 'that returns true' do subject(:response) { @han.as_api_response(:if_over_thirty) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(2).keys end it 'will not add the conditional field but all others' do expect(response.keys).to include(:first_name) expect(response.keys).to include(:last_name) end it 'the other specified fields have the correct value' do expect(response.values).to include(@han.first_name, @han.last_name) end end end end describe 'passing a proc' do describe 'that returns false' do subject(:response) { @luke.as_api_response(:if_over_thirty_proc) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(1).keys end it 'will not add the conditional field but all others' do expect(response.keys).to include(:first_name) expect(response.keys).not_to include(:full_name) end it 'the other specified fields have the correct value' do expect(response.values).to include(@luke.first_name) end end describe 'that returns nil' do subject(:response) { @luke.as_api_response(:if_returns_nil_proc) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(1).keys end it 'will not add the conditional field but all others' do expect(response.keys).to include(:first_name) expect(response.keys).not_to include(:full_name) end it 'the other specified fields have the correct value' do expect(response.values).to include(@luke.first_name) end end describe 'that returns true' do subject(:response) { @han.as_api_response(:if_over_thirty_proc) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(2).keys end it 'will not add the conditional field but all others' do expect(response.keys).to include(:first_name) expect(response.keys).to include(:last_name) end it 'the other specified fields have the correct value' do expect(response.values).to include(@han.first_name, @han.last_name) end end end end acts_as_api-1.0.1/spec/support/model_examples/sub_nodes.rb0000644000004100000410000000476213162253634023777 0ustar www-datawww-datashared_examples_for 'creating a sub hash in the api template' do describe 'and putting an attribute in it' do subject(:response) { @luke.as_api_response(:sub_node) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(1).keys end it 'returns all specified fields' do expect(response.keys).to include(:sub_nodes) end it 'returns the correct values for the specified fields' do expect(response[:sub_nodes]).to be_a Hash end it 'provides the correct number of sub nodes' do expect(response[:sub_nodes]).to have(1).keys end it 'provides the correct sub nodes values' do expect(response[:sub_nodes][:foo]).to eql('something') end end describe 'multiple times and putting an attribute in it' do subject(:response) { @luke.as_api_response(:nested_sub_node) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(1).keys end it 'returns all specified fields' do expect(response.keys).to include(:sub_nodes) end it 'returns the correct values for the specified fields' do expect(response[:sub_nodes]).to be_a Hash end it 'provides the correct number of sub nodes' do expect(response[:sub_nodes]).to have(1).keys end it 'provides the correct number of sub nodes in the second level' do expect(response[:sub_nodes][:foo]).to have(1).keys end it 'provides the correct sub nodes values' do response[:sub_nodes][:foo].tap do |foo| foo[:bar].tap do |bar| expect(bar).to eql(@luke.last_name) end end end end describe 'using a method' do subject(:response) { @luke.as_api_response(:nested_sub_hash) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(1).keys end it 'returns all specified fields' do expect(response.keys).to include(:sub_hash) end it 'provides the correct number of sub nodes' do expect(response[:sub_hash]).to have(2).keys end it 'provides the correct sub nodes' do expect(response[:sub_hash].keys).to include(:foo, :hello) end it 'provides the correct values in its sub nodes' do expect(response[:sub_hash].values).to include('bar', 'world') end end end acts_as_api-1.0.1/spec/support/model_examples/options.rb0000644000004100000410000000277213162253634023510 0ustar www-datawww-datashared_examples_for 'options' do describe 'options in the api template' do before :each do User.api_accessible :with_options do |t| t.add ->(_, options) { options }, as: :options t.add :profile t.add :first_name, if: ->(_, options) { options[:with_name] } end Profile.acts_as_api Profile.api_accessible :with_options do |t| t.add ->(_, options) { options }, as: :options end Task.acts_as_api Task.api_accessible :other_template do |t| t.add :description t.add :time_spent t.add ->(_, options) { options }, as: :options end end context 'as_api_response accept options' do subject(:response) { @luke.as_api_response(:with_options, loc: [12, 13]) } it 'returns the options field as specified' do expect(response[:options][:loc]).to eq([12, 13]) end it 'returns the option for the associations ' do expect(response[:profile][:options][:loc]).to eq([12, 13]) end end context 'allowed_to_render accept options' do it 'should not contains first_name when options[:with_name] is false' do response = @luke.as_api_response(:with_options, with_name: false) expect(response).not_to include(:first_name) end it 'should contains first_name when options[:with_name] is true' do response = @luke.as_api_response(:with_options, with_name: true) expect(response[:first_name]).to eq('Luke') end end end end acts_as_api-1.0.1/spec/support/model_examples/conditional_unless.rb0000644000004100000410000000777313162253634025717 0ustar www-datawww-datashared_examples_for 'conditional unless statements' do describe 'using the :unless option' do describe 'passing a symbol' do describe 'that returns false' do subject(:response) { @luke.as_api_response(:unless_under_thirty) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(1).keys end it 'will not add the conditional field but all others' do expect(response.keys).to include(:first_name) expect(response.keys).not_to include(:full_name) end it 'the other specified fields have the correct value' do expect(response.values).to include(@luke.first_name) end end describe 'that returns nil' do subject(:response) { @luke.as_api_response(:unless_returns_nil) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(2).keys end it 'will not add the conditional field but all others' do expect(response.keys).to include(:first_name) expect(response.keys).to include(:last_name) end it 'the other specified fields have the correct value' do expect(response.values).to include(@luke.first_name, @luke.last_name) end end describe 'that returns true' do subject(:response) { @han.as_api_response(:unless_under_thirty) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(2).keys end it 'will not add the conditional field but all others' do expect(response.keys).to include(:first_name) expect(response.keys).to include(:last_name) end it 'the other specified fields have the correct value' do expect(response.values).to include(@han.first_name, @han.last_name) end end end end describe 'passing a proc' do describe 'that returns false' do subject(:response) { @luke.as_api_response(:unless_under_thirty_proc) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(1).keys end it 'will not add the conditional field but all others' do expect(response.keys).to include(:first_name) expect(response.keys).not_to include(:full_name) end it 'the other specified fields have the correct value' do expect(response.values).to include(@luke.first_name) end end describe 'that returns nil' do subject(:response) { @luke.as_api_response(:if_returns_nil_proc) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(1).keys end it 'will not add the conditional field but all others' do expect(response.keys).to include(:first_name) expect(response.keys).not_to include(:full_name) end it 'the other specified fields have the correct value' do expect(response.values).to include(@luke.first_name) end end describe 'that returns true' do subject(:response) { @han.as_api_response(:unless_under_thirty_proc) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(2).keys end it 'will not add the conditional field but all others' do expect(response.keys).to include(:first_name) expect(response.keys).to include(:last_name) end it 'the other specified fields have the correct value' do expect(response.values).to include(@han.first_name, @han.last_name) end end end end acts_as_api-1.0.1/spec/support/model_examples/simple.rb0000644000004100000410000000103313162253634023273 0ustar www-datawww-datashared_examples_for 'listing attributes in the api template' do subject(:response) { @luke.as_api_response(:name_only) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(2).keys end it 'returns the specified fields only' do expect(response.keys).to include(:first_name, :last_name) end it 'the specified fields have the correct value' do expect(response.values).to include(@luke.first_name, @luke.last_name) end end acts_as_api-1.0.1/spec/support/model_examples/untouched.rb0000644000004100000410000000050713162253634024005 0ustar www-datawww-datashared_examples_for 'untouched models' do describe 'has disabled acts_as_api by default' do it 'indicates that acts_as_api is disabled' do expect(Untouched.acts_as_api?).to eq(false) end it 'does not respond to api_accessible' do expect(Untouched).not_to respond_to :api_accessible end end end acts_as_api-1.0.1/spec/support/model_examples/closures.rb0000644000004100000410000000235613162253634023652 0ustar www-datawww-datashared_examples_for 'calling a closure in the api template' do describe 'i.e. a proc (the record is passed as only parameter)' do subject(:response) { @luke.as_api_response(:calling_a_proc) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(2).keys end it 'returns all specified fields' do expect(response.keys.sort_by(&:to_s)).to eql([:all_caps_name, :without_param]) end it 'returns the correct values for the specified fields' do expect(response.values.sort).to eql(['LUKE SKYWALKER', 'Time']) end end describe 'i.e. a lambda (the record is passed as only parameter)' do subject(:response) { @luke.as_api_response(:calling_a_lambda) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(2).keys end it 'returns all specified fields' do expect(response.keys.sort_by(&:to_s)).to eql([:all_caps_name, :without_param]) end it 'returns the correct values for the specified fields' do expect(response.values.sort).to eql(['LUKE SKYWALKER', 'Time']) end end end acts_as_api-1.0.1/spec/support/model_examples/associations.rb0000644000004100000410000001656713162253634024523 0ustar www-datawww-datashared_examples_for 'including an association in the api template' do describe 'which does not acts_as_api' do subject(:response) { @luke.as_api_response(:include_tasks) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(1).keys end it 'returns all specified fields' do expect(response.keys).to include(:tasks) end it 'returns the correct values for the specified fields' do expect(response[:tasks]).to be_an Array expect(response[:tasks].size).to eq(3) end it 'should contain the associated sub models' do expect(response[:tasks]).to include(@destroy_deathstar, @study_with_yoda, @win_rebellion) end end describe 'which does acts_as_api' do context 'has_many' do before(:each) do Task.acts_as_api Task.api_accessible :include_tasks do |t| t.add :heading t.add :done end end subject(:response) { @luke.as_api_response(:include_tasks) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(1).keys end it 'returns all specified fields' do expect(response.keys).to include(:tasks) end it 'returns the correct values for the specified fields' do expect(response[:tasks]).to be_an Array expect(response[:tasks].size).to eq(3) end it 'contains the associated child models with the determined api template' do response[:tasks].each do |task| expect(task.keys).to include(:heading, :done) expect(task.keys.size).to eq(2) end end it 'contains the correct data of the child models' do task_hash = [@destroy_deathstar, @study_with_yoda, @win_rebellion].collect { |t| { done: t.done, heading: t.heading } } expect(response[:tasks]).to eql task_hash end end context 'has_one' do before(:each) do Profile.acts_as_api Profile.api_accessible :include_profile do |t| t.add :avatar t.add :homepage end end subject(:response) { @luke.as_api_response(:include_profile) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(1).keys end it 'returns all specified fields' do expect(response.keys).to include(:profile) end it 'returns the correct values for the specified fields' do expect(response[:profile]).to be_a Hash expect(response[:profile].size).to eq(2) end it 'contains the associated child models with the determined api template' do expect(response[:profile].keys).to include(:avatar, :homepage) end it 'contains the correct data of the child models' do profile_hash = { avatar: @luke.profile.avatar, homepage: @luke.profile.homepage } expect(response[:profile]).to eql profile_hash end end end describe 'which does acts_as_api, but with using another template name' do before(:each) do Task.acts_as_api Task.api_accessible :other_template do |t| t.add :description t.add :time_spent end end subject(:response) { @luke.as_api_response(:other_sub_template) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(2).keys end it 'returns all specified fields' do expect(response.keys).to include(:first_name) end it 'returns the correct values for the specified fields' do expect(response.values).to include(@luke.first_name) end it 'returns all specified fields' do expect(response.keys).to include(:tasks) end it 'returns the correct values for the specified fields' do expect(response[:tasks]).to be_an Array expect(response[:tasks].size).to eq(3) end it 'contains the associated child models with the determined api template' do response[:tasks].each do |task| expect(task.keys).to include(:description, :time_spent) expect(task.keys.size).to eq(2) end end it 'contains the correct data of the child models' do task_hash = [@destroy_deathstar, @study_with_yoda, @win_rebellion].collect { |t| { description: t.description, time_spent: t.time_spent } } expect(response[:tasks]).to eql task_hash end end describe 'that is scoped' do before(:each) do # extend task model with scope Task.class_eval do scope :completed, -> { where(done: true) } end Task.acts_as_api Task.api_accessible :include_completed_tasks do |t| t.add :heading t.add :done end end subject(:response) { @luke.as_api_response(:include_completed_tasks) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response.size).to eq(1) end it 'returns all specified fields' do expect(response.keys).to include(:completed_tasks) end it 'returns the correct values for the specified fields' do expect(response[:completed_tasks]).to be_an Array expect(response[:completed_tasks].size).to eq(2) end it 'contains the associated child models with the determined api template' do response[:completed_tasks].each do |task| expect(task.keys).to include(:heading, :done) expect(task.keys.size).to eq(2) end end it 'contains the correct data of the child models' do task_hash = [@destroy_deathstar, @study_with_yoda].collect { |t| { done: t.done, heading: t.heading } } expect(response[:completed_tasks]).to eql task_hash end end describe 'handling nil values' do context 'has_many' do before(:each) do Task.acts_as_api Task.api_accessible :include_tasks do |t| t.add :heading t.add :done end end subject(:response) { @han.as_api_response(:include_tasks) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(1).keys end it 'returns all specified fields' do expect(response.keys).to include(:tasks) end it 'returns the correct values for the specified fields' do expect(response[:tasks]).to be_kind_of(Array) end it 'contains no associated child models' do expect(response[:tasks]).to have(0).items end end context 'has one' do before(:each) do Profile.acts_as_api Profile.api_accessible :include_profile do |t| t.add :avatar t.add :homepage end end subject(:response) { @han.as_api_response(:include_profile) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(1).keys end it 'returns all specified fields' do expect(response.keys).to include(:profile) end it 'returns nil for the association' do expect(response[:profile]).to be_nil end end end end acts_as_api-1.0.1/spec/support/model_examples/extending.rb0000644000004100000410000000610213162253634023771 0ustar www-datawww-datashared_examples_for 'extending a given api template' do describe 'multiple times' do before(:each) do User.api_accessible :public do |t| t.add :first_name end User.api_accessible :for_buddies, extend: :public do |t| t.add :age end User.api_accessible :private, extend: :for_buddies do |t| t.add :last_name end end subject(:response) { @luke.as_api_response(:private) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(3).keys end it 'returns all specified fields' do expect(response.keys.sort_by(&:to_s)).to eql([:age, :first_name, :last_name]) end it 'returns the correct values for the specified fields' do expect(response.values.sort_by(&:to_s)).to eql([@luke.age, @luke.first_name, @luke.last_name].sort_by(&:to_s)) end end describe 'and removing a former added value' do subject(:response) { @luke.as_api_response(:age_and_first_name) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(2).keys end it 'returns all specified fields' do expect(response.keys.sort_by(&:to_s)).to eql([:first_name, :age].sort_by(&:to_s)) end it 'returns the correct values for the specified fields' do expect(response.values.sort_by(&:to_s)).to eql([@luke.first_name, @luke.age].sort_by(&:to_s)) end end describe 'and inherit a field using another template name' do before(:each) do Task.acts_as_api Task.api_accessible :other_template do |t| t.add :description t.add :time_spent end User.api_accessible :extending_other_template, extend: :other_sub_template end subject(:response) { @luke.as_api_response(:extending_other_template) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(2).keys end it 'returns all specified fields' do expect(response.keys).to include(:first_name) end it 'returns the correct values for the specified fields' do expect(response.values).to include(@luke.first_name) end it 'returns all specified fields' do expect(response.keys).to include(:tasks) end it 'returns the correct values for the specified fields' do expect(response[:tasks]).to be_an Array expect(response[:tasks].size).to eq(3) end it 'contains the associated child models with the determined api template' do response[:tasks].each do |task| expect(task.keys).to include(:description, :time_spent) expect(task.keys.size).to eq(2) end end it 'contains the correct data of the child models' do task_hash = [@destroy_deathstar, @study_with_yoda, @win_rebellion].collect { |t| { description: t.description, time_spent: t.time_spent } } expect(response[:tasks]).to eql task_hash end end end acts_as_api-1.0.1/spec/support/model_examples/callbacks.rb0000644000004100000410000000145313162253634023727 0ustar www-datawww-datashared_examples_for 'defining a model callback' do describe 'for a' do describe 'around_api_response' do it 'skips rendering if not yielded' do @luke.skip_api_response = true expect(@luke.as_api_response(:name_only).keys).to include(:skipped) end it 'renders if yielded' do expect(@luke.as_api_response(:name_only).keys).not_to include(:skipped) end end describe 'before_api_response' do it 'is called properly' do @luke.as_api_response(:name_only) expect(@luke.before_api_response_called?).to eql(true) end end describe 'after_api_response' do it 'is called properly' do @luke.as_api_response(:name_only) expect(@luke.after_api_response_called?).to eql(true) end end end end acts_as_api-1.0.1/spec/support/model_examples/enabled.rb0000644000004100000410000000036313162253634023401 0ustar www-datawww-datashared_examples_for 'acts_as_api is enabled' do it 'indicates that acts_as_api is enabled' do expect(User.acts_as_api?).to eq(true) end it 'does respond to api_accessible' do expect(User).to respond_to :api_accessible end end acts_as_api-1.0.1/spec/support/model_examples/renaming.rb0000644000004100000410000000214113162253634023603 0ustar www-datawww-datashared_examples_for 'renaming' do describe 'an attribute in the api template' do subject(:response) { @luke.as_api_response(:rename_last_name) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(1).keys end it 'returns all specified fields' do expect(response.keys).to include(:family_name) end it 'returns the correct values for the specified fields' do expect(response.values).to include(@luke.last_name) end end describe 'the node/key of a method in the api template' do subject(:response) { @luke.as_api_response(:rename_full_name) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(1).keys end it 'returns all specified fields' do expect(response.keys).to include(:other_full_name) end it 'returns the correct values for the specified fields' do expect(response.values).to include(@luke.full_name) end end end acts_as_api-1.0.1/spec/support/model_examples/methods.rb0000644000004100000410000000101213162253634023442 0ustar www-datawww-datashared_examples_for 'calling a method in the api template' do subject(:response) { @luke.as_api_response(:only_full_name) } it 'returns a hash' do expect(response).to be_kind_of(Hash) end it 'returns the correct number of fields' do expect(response).to have(1).keys end it 'returns all specified fields by name' do expect(response.keys).to include(:full_name) end it 'returns the correct values for the specified fields' do expect(response.values).to include(@luke.full_name) end end acts_as_api-1.0.1/spec/support/model_examples/undefined.rb0000644000004100000410000000034513162253634023750 0ustar www-datawww-datashared_examples_for 'trying to render an api template that is not defined' do it 'raises an descriptive error' do expect { @luke.as_api_response(:does_not_exist) }.to raise_error(ActsAsApi::TemplateNotFoundError) end end acts_as_api-1.0.1/spec/support/it_supports.rb0000644000004100000410000000013013162253634021374 0ustar www-datawww-dataRSpec.configure do |c| c.alias_it_should_behave_like_to :it_supports, 'supports:' end acts_as_api-1.0.1/spec/support/api_test_helpers.rb0000644000004100000410000000057313162253634022346 0ustar www-datawww-datamodule ApiTestHelpers def response_body response.body.strip end def response_body_json ActiveSupport::JSON.decode(response_body) end def response_body_jsonp(callback) jsonp_callback(callback).match(response_body) end def jsonp_callback(callback) /\A#{callback}\((.*),\s+\d{3}\)\z/ end end RSpec.configure do |c| c.include ApiTestHelpers end acts_as_api-1.0.1/spec/README.md0000644000004100000410000000450413162253634016230 0ustar www-datawww-data# Spec folder intro ## Running specs Every ORM has a rake task. Run `rake -T` to see them all. `rake spec:all` will run all spec suites in a row. `rake spec:#{orm_name}` will run the spec suite for a specific ORM. ## Working with the specs acts_as_api can be used with lots of different configurations, depending e.g. on the ORM (ActiveRecord, Mongoid, vanilla ruby) or the way the content is rendered (usual Rails controller vs. Responder). A goal of the lib is to stay consistent in its behaviour over these different configurations, so it won't get in your way, once you change other parts of your application. To achieve this goal and because of the need to keep the specs as DRY as possible, the following spec setup was created: ### A shared engine In order to keep the spec suite DRY it uses a Rails engine, available at `./shared_engine`. It contains the controllers that are re-used by the ORM-specific Rails apps and some mixins that can be shared over the models of different ORMs. ### Dummy Rails apps There used to be one Rails app that contained all supported ORMs. But multiple times this setup veiled problems e.g. with ORM-specific dependencies. Now there are multiple Rails apps, one for every supported ORM: `./active_record_dummy` and `./mongoid_dummy`. These are very simple apps, they contain **no controllers** to be tested, just models that match the tested ones. ### Debugging in the dummy apps Even though they are simple, you can still use the `rails console` of the dummy apps to debug acts_as_api. ``` $ cd spec/active_record_dummy $ rails c irb> User.last.as_api_response(:name_only) ``` This can come in very handy sometimes. ### Adding a new dummy Rails app (in case you want to add another ORM) * Create a new Rails app in the folder `./spec/#{orm_name}_dummy`. * Create the models used in the spec (`User, Profile, Untouched, Task`). * Include `UserTemplate` in your `User` model. * Add `mount SharedEngine::Engine => "/shared", :as => "shared"` to your `routes.rb` * Add the following lines to your Gemfile: ```ruby gem 'shared_engine', :path => '../shared_engine' gem 'acts_as_api', :path => '../../' ``` * Add your dummy app to the `Rakefile` in the root folder by adding it to the `supported_orms` array. If you have to do some special setup (e.g. creating a schema) you can do this in `./spec_helper.rb`. acts_as_api-1.0.1/.travis.yml0000644000004100000410000000014213162253634016122 0ustar www-datawww-datalanguage: ruby sudo: false script: bundle exec rake spec:all services: - mongodb rvm: - 2.3.1 acts_as_api-1.0.1/lib/0000755000004100000410000000000013162253634014562 5ustar www-datawww-dataacts_as_api-1.0.1/lib/acts_as_api/0000755000004100000410000000000013162253634017030 5ustar www-datawww-dataacts_as_api-1.0.1/lib/acts_as_api/adapters/0000755000004100000410000000000013162253634020633 5ustar www-datawww-dataacts_as_api-1.0.1/lib/acts_as_api/adapters/mongoid.rb0000644000004100000410000000025013162253634022611 0ustar www-datawww-datamodule ActsAsApi module Adapters module Mongoid extend ActiveSupport::Concern included do extend ActsAsApi::Base end end end end acts_as_api-1.0.1/lib/acts_as_api/adapters.rb0000644000004100000410000000014313162253634021156 0ustar www-datawww-datamodule ActsAsApi module Adapters autoload :Mongoid, 'acts_as_api/adapters/mongoid' end end acts_as_api-1.0.1/lib/acts_as_api/responder.rb0000644000004100000410000000226713162253634021365 0ustar www-datawww-datamodule ActsAsApi # A custom Rails responder class to automatically use render_for_api in your # controller actions. # # Example: # # class UsersController < ApplicationController # # Set this controller to use our custom responder # # (This could be done in a base controller class, if desired) # self.responder = ActsAsApi::Responder # # respond_to :json, :xml # # def index # @users = User.all # respond_with @users, :api_template => :name_only # end # end # # The `:api_template` parameter is required so the responder knows which api template it should render. class Responder < ActionController::Responder # Overrides the base implementation of display, replacing it with # the render_for_api method whenever api_template is specified. def display(resource, given_options = {}) api_template = options[:api_template] if api_template.nil? || !resource.respond_to?(:as_api_response) controller.render given_options.merge!(options).merge!(format => resource) else controller.render_for_api api_template, given_options.merge!(options).merge!(format => resource) end end end end acts_as_api-1.0.1/lib/acts_as_api/rails_renderer.rb0000644000004100000410000000111413162253634022352 0ustar www-datawww-datamodule ActsAsApi # Contains rails specific renderers used by acts_as_api to render a jsonp response # # See ActsAsApi::Config about the possible configurations module RailsRenderer def self.setup ActionController.add_renderer :acts_as_api_jsonp do |json, options| json = ActiveSupport::JSON.encode(json) unless json.respond_to?(:to_str) if options[:callback].present? json = "#{options[:callback]}(#{json}, #{response.status})" self.content_type = Mime[:js] end self.response_body = json end end end end acts_as_api-1.0.1/lib/acts_as_api/rendering.rb0000644000004100000410000000643613162253634021343 0ustar www-datawww-datamodule ActsAsApi # The methods of this module are included into the AbstractController::Rendering # module. module Rendering # Provides an alternative to the +render+ method used within the controller # to simply generate API outputs. # # The default Rails serializers are used to serialize the data. def render_for_api(api_template_or_options, render_options) if api_template_or_options.is_a?(Hash) api_template = [] api_template << api_template_or_options.delete(:prefix) api_template << api_template_or_options.delete(:template) api_template << api_template_or_options.delete(:postfix) api_template = api_template.reject(&:blank?).join('_') else api_template = api_template_or_options end # extract the api format and model api_format_options = {} ActsAsApi::Config.accepted_api_formats.each do |item| if render_options.key?(item) api_format_options[item] = render_options[item] render_options.delete item end end meta_hash = render_options[:meta] if render_options.key?(:meta) api_format = api_format_options.keys.first api_model = api_format_options.values.first # set the params to render output_params = render_options api_root_name = nil if !output_params[:root].nil? api_root_name = output_params[:root].to_s elsif api_model.class.respond_to?(:model_name) api_root_name = api_model.class.model_name elsif api_model.respond_to?(:collection_name) api_root_name = api_model.collection_name elsif api_model.is_a?(Array) && !api_model.empty? && api_model.first.class.respond_to?(:model_name) api_root_name = api_model.first.class.model_name elsif api_model.is_a?(Array) && !api_model.empty? && api_model.first.respond_to?(:model_name) api_root_name = api_model.first.model_name elsif api_model.respond_to?(:model_name) api_root_name = api_model.model_name else api_root_name = ActsAsApi::Config.default_root.to_s end api_root_name = api_root_name.to_s.underscore.tr('/', '_') if api_model.is_a?(Array) || (defined?(ActiveRecord) && api_model.is_a?(ActiveRecord::Relation)) api_root_name = api_root_name.pluralize end api_root_name = api_root_name.dasherize if ActsAsApi::Config.dasherize_for.include? api_format.to_sym output_params[:root] = api_root_name api_response = api_model.as_api_response(api_template) if api_response.is_a?(Array) && api_format.to_sym == :json && ActsAsApi::Config.include_root_in_json_collections api_response = api_response.collect { |f| { api_root_name.singularize => f } } end if meta_hash || ActsAsApi::Config.add_root_node_for.include?(api_format) api_response = { api_root_name.to_sym => api_response } end api_response = meta_hash.merge api_response if meta_hash if ActsAsApi::Config.allow_jsonp_callback && params[:callback] output_params[:callback] = params[:callback] api_format = :acts_as_api_jsonp if ActsAsApi::Config.add_http_status_to_jsonp_response end # create the Hash as response output_params[api_format] = api_response render output_params end end end acts_as_api-1.0.1/lib/acts_as_api/version.rb0000644000004100000410000000006013162253634021036 0ustar www-datawww-datamodule ActsAsApi VERSION = '1.0.1'.freeze end acts_as_api-1.0.1/lib/acts_as_api/config.rb0000644000004100000410000000333213162253634020623 0ustar www-datawww-datamodule ActsAsApi module Config class << self attr_writer :accepted_api_formats, :dasherize_for, :include_root_in_json_collections, :add_root_node_for, :default_root, :allow_jsonp_callback, :add_http_status_to_jsonp_response # The accepted response formats # Default is [:xml, :json] def accepted_api_formats @accepted_api_formats || [:xml, :json] end # Holds formats that should be dasherized # Default is [:xml] def dasherize_for @dasherize_for || [:xml] end # If true, the root node in json collections will be added # so the response will look like the default Rails 3 json # response def include_root_in_json_collections @include_root_in_json_collections || false end # Holds references to formats that need # to get added an additional root node # with the name of the model. def add_root_node_for @add_root_node_for || [:json] end # The default name of a root node of a response # if no root paramter is passed in render_for_api # and the gem is not able to determine a root name # automatically def default_root @default_root || :record end # If true a json response will be automatically wrapped into # a JavaScript function call in case a :callback param is passed. def allow_jsonp_callback @allow_jsonp_callback || false end # If true the jsonp function call will get the http status passed # as a second parameter def add_http_status_to_jsonp_response @add_http_status_to_jsonp_response.nil? ? true : @add_http_status_to_jsonp_response end end end end acts_as_api-1.0.1/lib/acts_as_api/collection.rb0000644000004100000410000000075313162253634021515 0ustar www-datawww-datamodule ActsAsApi module Collection # The collection checks all its items if they respond to the +as_api_response+ method. # If they do, the result of this method will be collected. # If they don't, the item itself will be collected. def as_api_response(api_template, options = {}) collect do |item| if item.respond_to?(:as_api_response) item.as_api_response(api_template, options) else item end end end end end acts_as_api-1.0.1/lib/acts_as_api/base.rb0000644000004100000410000000507613162253634020277 0ustar www-datawww-datamodule ActsAsApi # This module enriches the ActiveRecord::Base module of Rails. module Base # Indicates if the current model acts as api. # False by default. def acts_as_api? false end # When invoked, it enriches the current model with the # class and instance methods to act as api. def acts_as_api class_eval do include ActsAsApi::Base::InstanceMethods extend ActsAsApi::Base::ClassMethods end if block_given? yield ActsAsApi::Config end end module ClassMethods def acts_as_api? #:nodoc: included_modules.include?(InstanceMethods) end # Determines the attributes, methods of the model that are accessible in the api response. # *Note*: There is only whitelisting for api accessible attributes. # So once the model acts as api, you have to determine all attributes here that should # be contained in the api responses. def api_accessible(api_template, options = {}, &block) attributes = api_accessible_attributes(api_template).try(:dup) || ApiTemplate.new(api_template) attributes.merge!(api_accessible_attributes(options[:extend])) if options[:extend] if block_given? yield attributes end class_attribute "api_accessible_#{api_template}".to_sym send "api_accessible_#{api_template}=", attributes end # Returns an array of all the attributes that have been made accessible to the api response. def api_accessible_attributes(api_template) begin send "api_accessible_#{api_template}".to_sym rescue nil end end end module InstanceMethods # Creates the api response of the model and returns it as a Hash. # Will raise an exception if the passed api template is not defined for the model def as_api_response(api_template, options = {}) api_attributes = self.class.api_accessible_attributes(api_template) raise ActsAsApi::TemplateNotFoundError.new("acts_as_api template :#{api_template} was not found for model #{self.class}") if api_attributes.nil? before_api_response(api_template) response_hash = around_api_response(api_template) do api_attributes.to_response_hash(self, api_attributes, options) end after_api_response(api_template) response_hash end protected def before_api_response(_api_template) end def after_api_response(_api_template) end def around_api_response(_api_template) yield end end end end acts_as_api-1.0.1/lib/acts_as_api/api_template.rb0000644000004100000410000001005213162253634022017 0ustar www-datawww-datamodule ActsAsApi # Represents an api template for a model. # This class should not be initiated by yourself, api templates # are created by defining them in the model by calling: +api_accessible+. # # The api template is configured in the block passed to +api_accessible+. # # Please note that +ApiTemplate+ inherits from +Hash+ so you can use all # kind of +Hash+ and +Enumerable+ methods to manipulate the template. class ApiTemplate < Hash # The name of the api template as a Symbol. attr_accessor :api_template attr_reader :options def initialize(api_template) self.api_template = api_template @options ||= {} end def merge!(other_hash, &block) super options.merge!(other_hash.options) if other_hash.respond_to?(:options) end # Adds a field to the api template # # The value passed can be one of the following: # * Symbol - the method with the same name will be called on the model when rendering. # * String - must be in the form "method1.method2.method3", will call this method chain. # * Hash - will be added as a sub hash and all its items will be resolved the way described above. # # Possible options to pass: # * :template - Determine the template that should be used to render the item if it is # +api_accessible+ itself. def add(val, options = {}) item_key = (options[:as] || val).to_sym self[item_key] = val @options[item_key] = options end # Removes a field from the template def remove(field) delete(field) end # Returns the options of a field in the api template def options_for(field) @options[field] end # Returns the passed option of a field in the api template def option_for(field, option) @options[field][option] if @options[field] end # If a special template name for the passed item is specified # it will be returned, if not the original api template. def api_template_for(fieldset, field) fieldset.option_for(field, :template) || api_template end # Decides if the passed item should be added to # the response based on the conditional options passed. def allowed_to_render?(fieldset, field, model, options) return true unless fieldset.is_a? ActsAsApi::ApiTemplate fieldset_options = fieldset.options_for(field) if fieldset_options[:unless] !(condition_fulfilled?(model, fieldset_options[:unless], options)) elsif fieldset_options[:if] condition_fulfilled?(model, fieldset_options[:if], options) else true end end # Checks if a condition is fulfilled # (result is not nil or false) def condition_fulfilled?(model, condition, options) case condition when Symbol result = model.send(condition) when Proc result = call_proc(condition, model, options) end !!result end # Generates a hash that represents the api response based on this # template for the passed model instance. def to_response_hash(model, fieldset = self, options = {}) api_output = {} fieldset.each do |field, value| next unless allowed_to_render?(fieldset, field, model, options) out = process_value(model, value, options) if out.respond_to?(:as_api_response) sub_template = api_template_for(fieldset, field) out = out.as_api_response(sub_template, options) end api_output[field] = out end api_output end private def process_value(model, value, options) case value when Symbol model.send(value) when Proc call_proc(value, model, options) when String value.split('.').inject(model) { |result, method| result.send(method) } when Hash to_response_hash(model, value) end end def call_proc(the_proc, model, options) if the_proc.arity == 2 the_proc.call(model, options) else the_proc.call(model) end end end end acts_as_api-1.0.1/lib/acts_as_api/exceptions.rb0000644000004100000410000000016413162253634021537 0ustar www-datawww-datamodule ActsAsApi class ActsAsApiError < RuntimeError; end class TemplateNotFoundError < ActsAsApiError; end end acts_as_api-1.0.1/lib/acts_as_api.rb0000644000004100000410000000353513162253634017363 0ustar www-datawww-datarequire 'active_model' require 'active_support/core_ext/class' require 'acts_as_api/collection' require 'acts_as_api/rails_renderer' require 'acts_as_api/exceptions' # acts_as_api is a gem that aims to make the construction of JSON and XML # responses in Rails 3, 4 and 5 easy and fun. # # Therefore it attaches a couple of helper methods to active record and # the action controller base classes. # # acts_as_api uses the default serializers of your rails app and doesn't # force you into more dependencies. module ActsAsApi autoload :Config, 'acts_as_api/config' autoload :ApiTemplate, 'acts_as_api/api_template' autoload :Base, 'acts_as_api/base' autoload :Rendering, 'acts_as_api/rendering' autoload :Responder, 'acts_as_api/responder' autoload :Adapters, 'acts_as_api/adapters' end # Neccessary to render an Array of models, e.g. the result of a search. Array.include(ActsAsApi::Collection) # Attach ourselves to ActiveRecord if defined?(ActiveRecord::Base) ActiveRecord::Base.extend ActsAsApi::Base # Rails 5 compatibility if defined?(ActiveRecord::Relation) ActiveRecord::Relation.include(ActsAsApi::Collection) end if defined?(ActiveRecord::Associations::CollectionProxy) ActiveRecord::Associations::CollectionProxy.include(ActsAsApi::Collection) end if defined?(ActiveRecord::AssociationRelation) ActiveRecord::AssociationRelation.include(ActsAsApi::Collection) end end # Attach ourselves to ActiveResource if defined?(ActiveResource::Base) ActiveResource::Base.extend ActsAsApi::Base end # Attach ourselves to Mongoid if defined?(Mongoid::Document) Mongoid::Document.send :include, ActsAsApi::Adapters::Mongoid end # Attach ourselves to the action controller of Rails if defined?(ActionController::Base) ActionController::Base.send :include, ActsAsApi::Rendering ActsAsApi::RailsRenderer.setup end acts_as_api-1.0.1/acts_as_api.gemspec0000644000004100000410000000232013162253634017624 0ustar www-datawww-data# encoding: utf-8 $LOAD_PATH.push File.expand_path('../lib', __FILE__) require 'acts_as_api/version' Gem::Specification.new do |s| s.name = 'acts_as_api' s.version = ActsAsApi::VERSION s.platform = Gem::Platform::RUBY s.authors = ['Christian Bäuerlein'] s.email = ['christian@ffwdme.com'] s.homepage = 'https://github.com/fabrik42/acts_as_api' s.summary = 'Makes creating XML/JSON responses in Rails 3, 4 and 5 easy and fun.' s.description = 'acts_as_api enriches the models and controllers of your app in a rails-like way so you can easily determine how your XML/JSON API responses should look like.' s.add_dependency('activemodel', '>= 3.0.0') s.add_dependency('activesupport', '>= 3.0.0') s.add_dependency('rack', '>= 1.1.0') s.add_development_dependency('rails', ['>= 3.2.22.2']) s.add_development_dependency('mongoid', ['>= 3.0.1']) s.add_development_dependency('rocco', ['>= 0.8.0']) s.rdoc_options = ['--charset=UTF-8'] s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) } s.require_paths = ['lib'] end acts_as_api-1.0.1/.gitignore0000644000004100000410000000042013162253634016000 0ustar www-datawww-datanbproject/ pkg/* .bundle Gemfile.lock test acts_as_api.tmproj spec/active_record_dummy/db/*.sqlite3 spec/active_record_dummy/tmp/**/* spec/active_record_dummy/log/*.log spec/mongoid_dummy/tmp/**/* spec/mongoid_dummy/log/*.log .rspec .ruby-version .rvmrc *.sqlite3-journal acts_as_api-1.0.1/docs/0000755000004100000410000000000013162253634014744 5ustar www-datawww-dataacts_as_api-1.0.1/docs/index.rb0000644000004100000410000001074613162253634016410 0ustar www-datawww-data# The built-in XML/JSON support of Rails is great but: # You surely don’t want to expose your models always with all attributes. # # acts_as_api enriches the models and controllers of your app in a rails-like way so you can easily determine how your API responses should look like. ### Features # * DRY templates for your api responses # * Ships with support for **ActiveRecord** and **Mongoid** # * Support for Rails 3, 4 and 5 Responders # * Plays very well together with client libs like [Backbone.js][b1] or [RestKit][r1] (iOS). # * Easy but very flexible syntax for defining the templates # * XML, JSON and JSON-P support out of the box, easy to extend # * Support for meta data like pagination info, etc... # * Minimal dependecies (you can also use it without Rails) # * Supports multiple api rendering templates for a models. This is especially useful for API versioning or for example for private vs. public access points to a user’s profile. # [b1]: http://documentcloud.github.com/backbone # [r1]: http://restkit.org # *** ### Rails 3.x Quickstart # Add to gemfile gem 'acts_as_api' # Update your bundle bundle install #### Setting up your Model # Given you have a model `User`. # If you only want to expose the `first_name` and `last_name` attribute of a user via your api, you would do something like this: # Within your model: # # First you activate acts_as_api for your model by calling `acts_as_api`. # # Then you define an api template to render the model with `api_accessible`. class User < ActiveRecord::Base acts_as_api api_accessible :name_only do |template| template.add :first_name template.add :last_name end end # An API template with the name `:name_only` was created. # # See below how to use it in the controller: #### Setting up your Controller # Now you just have to exchange the `render` method in your controller for the `render_for_api` method. class UsersController < ApplicationController def index @users = User.all # Note that it's wise to add a `root` param when rendering lists. respond_to do |format| format.xml { render_for_api :name_only, xml: @users, root: :users } format.json { render_for_api :name_only, json: @users, root: :users } end end def show @user = User.find(params[:id]) respond_to do |format| format.xml { render_for_api :name_only, xml: @user } format.json { render_for_api :name_only, json: @user } end end end #### That's it! # Try it. The JSON response of #show should now look like this: # # Other attributes of the model like `created_at` or `updated_at` won’t be included # because they were not listed by `api_accessible` in the model. { "user": { "first_name": "John", "last_name": "Doe" } } # *** ### But wait! ... there's more # # Often the pure rendering of database values is just not enough, so acts_as_api # provides you some tools to customize your API responses. #### What can I include in my responses? # # You can do basically anything: # # * [Include attributes and all other kinds of methods of your model][w1] # * [Include child associations (if they also act_as_api this will be considered)][w2] # * [Include lambdas and Procs][w3] # * [Call methods of a parent association][w4] # * [Call scopes of your model or child associations][w5] # * [Rename attributes, methods, associations][w6] # * [Create your own hierarchies][w7] # # You can find more advanced examples in the [Github Wiki][wi] # # [wi]: https://github.com/fabrik42/acts_as_api/wiki/ # [w1]: https://github.com/fabrik42/acts_as_api/wiki/Calling-a-method-of-the-model # [w2]: https://github.com/fabrik42/acts_as_api/wiki/Including-a-child-association # [w3]: https://github.com/fabrik42/acts_as_api/wiki/Calling-a-lambda-in-the-api-template # [w4]: https://github.com/fabrik42/acts_as_api/wiki/Calling-a-method-of-the-model # [w5]: https://github.com/fabrik42/acts_as_api/wiki/Calling-a-scope-of-a-sub-resource # [w6]: https://github.com/fabrik42/acts_as_api/wiki/Renaming-an-attribute # [w7]: https://github.com/fabrik42/acts_as_api/wiki/Creating-a-completely-different-response-structure # *** ### Links # * Check out the [source code on Github][so] # * For more usage examples visit the [wiki][wi] # * Found a bug or do you have a feature request? [issue tracker][to] # * [Docs][do] # # [so]: https://github.com/fabrik42/acts_as_api/ # [wi]: https://github.com/fabrik42/acts_as_api/wiki/ # [to]: https://github.com/fabrik42/acts_as_api/issues # [do]: http://rdoc.info/github/fabrik42/acts_as_api acts_as_api-1.0.1/docs/docco.css0000644000004100000410000001567513162253634016563 0ustar www-datawww-data/*--------------------- Layout and Typography ----------------------------*/ body { font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; font-size: 15px; line-height: 22px; color: #252519; margin: 0; padding: 0; } a { color: #261a3b; } a:visited { color: #261a3b; } p { margin: 0 0 15px 0; } h1, h2, h3, h4, h5, h6 { margin: 0px 0 15px 0; } h1 { margin-top: 40px; } #container { position: relative; } #background { position: fixed; top: 0; left: 525px; right: 0; bottom: 0; background: #f5f5ff; border-left: 1px solid #e5e5ee; z-index: -1; } #jump_to, #jump_page { background: white; -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777; -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; font: 10px Arial; text-transform: uppercase; cursor: pointer; text-align: right; } #jump_to, #jump_wrapper { position: fixed; right: 0; top: 0; padding: 5px 10px; } #jump_wrapper { padding: 0; display: none; } #jump_to:hover #jump_wrapper { display: block; } #jump_page { padding: 5px 0 3px; margin: 0 0 25px 25px; } #jump_page .source { display: block; padding: 5px 10px; text-decoration: none; border-top: 1px solid #eee; } #jump_page .source:hover { background: #f5f5ff; } #jump_page .source:first-child { } table td { border: 0; outline: 0; } td.docs, th.docs { max-width: 450px; min-width: 450px; min-height: 5px; padding: 10px 25px 1px 50px; overflow-x: hidden; vertical-align: top; text-align: left; } .docs pre { margin: 15px 0 15px; padding-left: 15px; } .docs p tt, .docs p code { background: #f8f8ff; border: 1px solid #dedede; font-size: 12px; padding: 0 0.2em; } .pilwrap { position: relative; } .pilcrow { font: 12px Arial; text-decoration: none; color: #454545; position: absolute; top: 3px; left: -20px; padding: 1px 2px; opacity: 0; -webkit-transition: opacity 0.2s linear; } td.docs:hover .pilcrow { opacity: 1; } td.code, th.code { padding: 14px 15px 16px 25px; width: 100%; vertical-align: top; background: #f5f5ff; border-left: 1px solid #e5e5ee; } pre, tt, code { font-size: 12px; line-height: 18px; font-family: Monaco, Consolas, "Lucida Console", monospace; margin: 0; padding: 0; } /*---------------------- Syntax Highlighting -----------------------------*/ td.linenos { background-color: #f0f0f0; padding-right: 10px; } span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; } body .hll { background-color: #ffffcc } body .c { color: #408080; font-style: italic } /* Comment */ body .err { border: 1px solid #FF0000 } /* Error */ body .k { color: #954121 } /* Keyword */ body .o { color: #666666 } /* Operator */ body .cm { color: #408080; font-style: italic } /* Comment.Multiline */ body .cp { color: #BC7A00 } /* Comment.Preproc */ body .c1 { color: #408080; font-style: italic } /* Comment.Single */ body .cs { color: #408080; font-style: italic } /* Comment.Special */ body .gd { color: #A00000 } /* Generic.Deleted */ body .ge { font-style: italic } /* Generic.Emph */ body .gr { color: #FF0000 } /* Generic.Error */ body .gh { color: #000080; font-weight: bold } /* Generic.Heading */ body .gi { color: #00A000 } /* Generic.Inserted */ body .go { color: #808080 } /* Generic.Output */ body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ body .gs { font-weight: bold } /* Generic.Strong */ body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ body .gt { color: #0040D0 } /* Generic.Traceback */ body .kc { color: #954121 } /* Keyword.Constant */ body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */ body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */ body .kp { color: #954121 } /* Keyword.Pseudo */ body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */ body .kt { color: #B00040 } /* Keyword.Type */ body .m { color: #666666 } /* Literal.Number */ body .s { color: #219161 } /* Literal.String */ body .na { color: #7D9029 } /* Name.Attribute */ body .nb { color: #954121 } /* Name.Builtin */ body .nc { color: #0000FF; font-weight: bold } /* Name.Class */ body .no { color: #880000 } /* Name.Constant */ body .nd { color: #AA22FF } /* Name.Decorator */ body .ni { color: #999999; font-weight: bold } /* Name.Entity */ body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ body .nf { color: #0000FF } /* Name.Function */ body .nl { color: #A0A000 } /* Name.Label */ body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ body .nt { color: #954121; font-weight: bold } /* Name.Tag */ body .nv { color: #19469D } /* Name.Variable */ body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ body .w { color: #bbbbbb } /* Text.Whitespace */ body .mf { color: #666666 } /* Literal.Number.Float */ body .mh { color: #666666 } /* Literal.Number.Hex */ body .mi { color: #666666 } /* Literal.Number.Integer */ body .mo { color: #666666 } /* Literal.Number.Oct */ body .sb { color: #219161 } /* Literal.String.Backtick */ body .sc { color: #219161 } /* Literal.String.Char */ body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */ body .s2 { color: #219161 } /* Literal.String.Double */ body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ body .sh { color: #219161 } /* Literal.String.Heredoc */ body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ body .sx { color: #954121 } /* Literal.String.Other */ body .sr { color: #BB6688 } /* Literal.String.Regex */ body .s1 { color: #219161 } /* Literal.String.Single */ body .ss { color: #19469D } /* Literal.String.Symbol */ body .bp { color: #954121 } /* Name.Builtin.Pseudo */ body .vc { color: #19469D } /* Name.Variable.Class */ body .vg { color: #19469D } /* Name.Variable.Global */ body .vi { color: #19469D } /* Name.Variable.Instance */ body .il { color: #666666 } /* Literal.Number.Integer.Long */acts_as_api-1.0.1/docs/layout.mustache0000644000004100000410000000376113162253634020023 0ustar www-datawww-data acts_as_api
{{#sources?}}
Jump To …
{{#sources}} {{ basename }} {{/sources}}
{{/sources?}} {{#sections}} {{/sections}}

acts_as_api

Makes creating XML/JSON responses in Rails 3, 4 and 5 easy and fun.

{{{ docs }}}
{{{ code }}}
Fork me on GitHub acts_as_api-1.0.1/docs/index.html0000644000004100000410000003474313162253634016754 0ustar www-datawww-data acts_as_api

acts_as_api

Makes creating XML/JSON responses in Rails 3, 4 and 5 easy and fun.

The built-in XML/JSON support of Rails is great but: You surely don’t want to expose your models always with all attributes.

actsasapi enriches the models and controllers of your app in a rails-like way so you can easily determine how your API responses should look like.

Features

  • DRY templates for your api responses
  • Ships with support for ActiveRecord and Mongoid
  • Support for Rails 3, 4 and 5 Responders
  • Plays very well together with client libs like Backbone.js or RestKit (iOS).
  • Easy but very flexible syntax for defining the templates
  • XML, JSON and JSON-P support out of the box, easy to extend
  • Support for meta data like pagination info, etc...
  • Minimal dependecies (you can also use it without Rails)
  • Supports multiple api rendering templates for a models. This is especially useful for API versioning or for example for private vs. public access points to a user’s profile.

Rails 3.x Quickstart

Add to gemfile

gem 'acts_as_api'

Update your bundle

bundle install

Setting up your Model

Given you have a model User. If you only want to expose the first_name and last_name attribute of a user via your api, you would do something like this:

Within your model:

First you activate actsasapi for your model by calling acts_as_api.

Then you define an api template to render the model with api_accessible.

class User < ActiveRecord::Base

  acts_as_api

  api_accessible :name_only do |template|
    template.add :first_name
    template.add :last_name
  end

end

An API template with the name :name_only was created.

See below how to use it in the controller:

Setting up your Controller

Now you just have to exchange the render method in your controller for the render_for_api method.

class UsersController < ApplicationController

  def index
    @users = User.all

Note that it's wise to add a root param when rendering lists.

    respond_to do |format|
      format.xml  { render_for_api :name_only, xml: @users,  root: :users }
      format.json { render_for_api :name_only, json: @users, root: :users }
    end
  end

  def show
    @user = User.find(params[:id])

    respond_to do |format|
      format.xml  { render_for_api :name_only, xml: @user  }
      format.json { render_for_api :name_only, json: @user }
    end
  end

end

That's it!

Try it. The JSON response of #show should now look like this:

Other attributes of the model like created_at or updated_at won’t be included because they were not listed by api_accessible in the model.

{
  "user": {
    "first_name": "John",
    "last_name":  "Doe"
  }
}

But wait! ... there's more

Often the pure rendering of database values is just not enough, so actsasapi provides you some tools to customize your API responses.

What can I include in my responses?

You can do basically anything:

You can find more advanced examples in the Github Wiki


Fork me on GitHub acts_as_api-1.0.1/README.md0000644000004100000410000000733613162253634015304 0ustar www-datawww-data# acts_as_api ![acts_as_api on travis ci](https://secure.travis-ci.org/fabrik42/acts_as_api.png?branch=master) acts_as_api makes creating XML/JSON responses in Rails 3, 4 and 5 easy and fun. It provides a simple interface to determine the representation of your model data, that should be rendered in your API responses. In addition to Rails it theoretically can be used with any ruby app and any database (__ActiveRecord__, __Mongoid__ and __ActiveResource__ are supported out of the box) as it only has few dependencies. The lib is _very_ fast in generating your responses and battle tested in production with platforms like [Diaspora](https://joindiaspora.com) or [flinc](https://flinc.org). ## Introduction acts_as_api enriches the models and controllers of your app in a Rails-like way so you can easily determine how your API responses should look like: ```ruby class User < ActiveRecord::Base acts_as_api api_accessible :public do |template| template.add :first_name template.add :age end # will render json: { "user": { "first_name": "John", "age": 26 } } api_accessible :private, extend: :public do |template| template.add :last_name template.add :email end # will render json: { "user": { "first_name": "John", "last_name": "Doe", "age": 26, "email": "john@example.org" } } end ``` ## Getting started A nice introduction about acts_as_api with examples can be found here: http://fabrik42.github.com/acts_as_api See the Wiki for a lot of usage examples and features: https://github.com/fabrik42/acts_as_api/wiki There are a lot of how-tos like: * [Extending existing api templates](https://github.com/fabrik42/acts_as_api/wiki/Extending-an-existing-api-template) * [Include attributes and all other kinds of methods of your model](https://github.com/fabrik42/acts_as_api/wiki/Calling-a-method-of-the-model) * [Include child associations (if they also act_as_api this will be considered)](https://github.com/fabrik42/acts_as_api/wiki/Including-a-child-association) * [Rename attributes, methods, associations](https://github.com/fabrik42/acts_as_api/wiki/Renaming-an-attribute) * [Keep your API templates out of your models](https://github.com/fabrik42/acts_as_api/wiki/Keep-your-api-templates-out-of-your-models) * [and much more...](https://github.com/fabrik42/acts_as_api/wiki) ## Features: * DRY templates for your api responses * Ships with support for __ActiveRecord__ and __Mongoid__ * Support for Rails 3/4 Responders (extracted to responders gem since Rails 5) * Plays very well together with client libs like [Backbone.js](http://documentcloud.github.com/backbone), [RestKit](http://restkit.org) (iOS) or [gson](http://code.google.com/p/google-gson) (Android). * Easy but very flexible syntax for defining the templates * XML, JSON and JSON-P support out of the box, easy to extend * Minimal dependecies (you can also use it without Rails) * Supports multiple api rendering templates per model. This is especially useful for API versioning or for example for private vs. public access points to a user’s profile. ### Requirements: * ActiveModel (>= 3.0.0) * ActiveSupport (>= 3.0.0) * Rack (>= 1.1.0) ### Links * Introduction: http://fabrik42.github.com/acts_as_api * Docs: http://rdoc.info/projects/fabrik42/acts_as_api * Found a bug? http://github.com/fabrik42/acts_as_api/issues * Wiki: https://github.com/fabrik42/acts_as_api/wiki * Want to contribute - the spec suite is explained here: https://github.com/fabrik42/acts_as_api/tree/master/spec ### Downwards Compatibility Note that upgrading to 0.3.0 will break code that worked with previous versions due to a complete overhaul of the lib. For a legacy version of this readme file look here: https://github.com/fabrik42/acts_as_api/wiki/legacy-acts_as_api-0.2-readme