├── .gitignore
├── .ruby-version
├── .travis.yml
├── Gemfile
├── Gemfile.lock
├── LICENSE
├── Procfile
├── README.md
├── Rakefile
├── bin
├── bundle
├── rails
└── rake
├── build.sh
├── components
├── documentation
│ ├── .rspec
│ ├── Gemfile
│ ├── Gemfile.lock
│ ├── Rakefile
│ ├── app
│ │ ├── assets
│ │ │ └── stylesheets
│ │ │ │ └── documentation
│ │ │ │ └── application.css
│ │ ├── controllers
│ │ │ └── documentation
│ │ │ │ └── root_controller.rb
│ │ └── views
│ │ │ ├── documentation
│ │ │ └── root
│ │ │ │ └── index.html.erb
│ │ │ └── layouts
│ │ │ └── documentation
│ │ │ └── application.html.erb
│ ├── config
│ │ └── routes.rb
│ ├── documentation.gemspec
│ ├── lib
│ │ ├── documentation.rb
│ │ └── documentation
│ │ │ ├── engine.rb
│ │ │ └── version.rb
│ ├── spec
│ │ ├── dummy
│ │ │ ├── Rakefile
│ │ │ ├── bin
│ │ │ │ ├── bundle
│ │ │ │ ├── rails
│ │ │ │ ├── rake
│ │ │ │ └── setup
│ │ │ ├── config.ru
│ │ │ ├── config
│ │ │ │ ├── application.rb
│ │ │ │ ├── boot.rb
│ │ │ │ ├── database.yml
│ │ │ │ ├── environment.rb
│ │ │ │ ├── environments
│ │ │ │ │ └── test.rb
│ │ │ │ ├── routes.rb
│ │ │ │ └── secrets.yml
│ │ │ ├── db
│ │ │ │ └── schema.rb
│ │ │ └── log
│ │ │ │ └── .keep
│ │ ├── features
│ │ │ └── root_page_spec.rb
│ │ ├── rails_helper.rb
│ │ ├── spec_helper.rb
│ │ └── support
│ │ │ └── capybara.rb
│ └── test.sh
└── movie_manager
│ ├── .rspec
│ ├── Gemfile
│ ├── Gemfile.lock
│ ├── Rakefile
│ ├── app
│ ├── controllers
│ │ └── movie_manager
│ │ │ └── movies_controller.rb
│ └── models
│ │ └── movie_manager
│ │ ├── movie.rb
│ │ ├── movie_repo.rb
│ │ └── movie_serializer.rb
│ ├── config
│ └── routes.rb
│ ├── db
│ └── migrate
│ │ ├── 20131215170206_create_movies.rb
│ │ ├── 20140128061928_add_director_to_movies.rb
│ │ └── 20141206230010_add_timestamps_to_movies.rb
│ ├── lib
│ ├── movie_manager.rb
│ └── movie_manager
│ │ ├── engine.rb
│ │ └── version.rb
│ ├── movie_manager.gemspec
│ ├── spec
│ ├── dummy
│ │ ├── Rakefile
│ │ ├── bin
│ │ │ ├── bundle
│ │ │ ├── rails
│ │ │ ├── rake
│ │ │ └── setup
│ │ ├── config.ru
│ │ ├── config
│ │ │ ├── application.rb
│ │ │ ├── boot.rb
│ │ │ ├── database.yml
│ │ │ ├── environment.rb
│ │ │ ├── environments
│ │ │ │ └── test.rb
│ │ │ ├── routes.rb
│ │ │ └── secrets.yml
│ │ └── db
│ │ │ └── schema.rb
│ ├── models
│ │ └── movie_manager
│ │ │ └── movie_repo_spec.rb
│ ├── rails_helper.rb
│ ├── requests
│ │ └── movies_api_spec.rb
│ ├── spec_helper.rb
│ └── support
│ │ └── object_creation_methods.rb
│ └── test.sh
├── config.ru
├── config
├── application.rb
├── boot.rb
├── database.yml
├── environment.rb
├── environments
│ ├── development.rb
│ ├── production.rb
│ └── test.rb
├── initializers
│ ├── secret_token.rb
│ └── wrap_parameters.rb
└── routes.rb
├── db
├── schema.rb
└── seeds.rb
└── deploy_app.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | /.bundle
2 | *.log
3 | tmp
4 | /.vagrant
5 | /public/assets
6 | /.env
7 | .idea
8 |
9 |
--------------------------------------------------------------------------------
/.ruby-version:
--------------------------------------------------------------------------------
1 | 2.2.2
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: ruby
2 | gemfile:
3 | - components/documentation/Gemfile
4 | - components/movie_manager/Gemfile
5 | script:
6 | - travis_retry ./test.sh
7 | before_install:
8 | - cd $(dirname $BUNDLE_GEMFILE)
9 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | ruby "2.2.2"
4 |
5 | gem "documentation", path: "components/documentation"
6 | gem "movie_manager", path: "components/movie_manager"
7 |
8 | gem "pg"
9 | gem "rack-cors", :require => "rack/cors"
10 | gem "pry-rails"
11 |
12 | group :production do
13 | gem "rails_12factor"
14 | end
15 |
16 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | PATH
2 | remote: components/documentation
3 | specs:
4 | documentation (0.0.1)
5 | rails (= 4.1.5)
6 |
7 | PATH
8 | remote: components/movie_manager
9 | specs:
10 | movie_manager (0.0.1)
11 | oj
12 | rails (= 4.1.5)
13 | thin
14 |
15 | GEM
16 | remote: https://rubygems.org/
17 | specs:
18 | actionmailer (4.1.5)
19 | actionpack (= 4.1.5)
20 | actionview (= 4.1.5)
21 | mail (~> 2.5.4)
22 | actionpack (4.1.5)
23 | actionview (= 4.1.5)
24 | activesupport (= 4.1.5)
25 | rack (~> 1.5.2)
26 | rack-test (~> 0.6.2)
27 | actionview (4.1.5)
28 | activesupport (= 4.1.5)
29 | builder (~> 3.1)
30 | erubis (~> 2.7.0)
31 | activemodel (4.1.5)
32 | activesupport (= 4.1.5)
33 | builder (~> 3.1)
34 | activerecord (4.1.5)
35 | activemodel (= 4.1.5)
36 | activesupport (= 4.1.5)
37 | arel (~> 5.0.0)
38 | activesupport (4.1.5)
39 | i18n (~> 0.6, >= 0.6.9)
40 | json (~> 1.7, >= 1.7.7)
41 | minitest (~> 5.1)
42 | thread_safe (~> 0.1)
43 | tzinfo (~> 1.1)
44 | arel (5.0.1.20140414130214)
45 | builder (3.2.2)
46 | coderay (1.1.0)
47 | daemons (1.1.9)
48 | erubis (2.7.0)
49 | eventmachine (1.0.4)
50 | hike (1.2.3)
51 | i18n (0.7.0)
52 | json (1.8.1)
53 | mail (2.5.4)
54 | mime-types (~> 1.16)
55 | treetop (~> 1.4.8)
56 | method_source (0.8.2)
57 | mime-types (1.25.1)
58 | minitest (5.5.0)
59 | multi_json (1.10.1)
60 | oj (2.11.4)
61 | pg (0.17.1)
62 | polyglot (0.3.5)
63 | pry (0.10.1)
64 | coderay (~> 1.1.0)
65 | method_source (~> 0.8.1)
66 | slop (~> 3.4)
67 | pry-rails (0.3.3)
68 | pry (>= 0.9.10)
69 | rack (1.5.2)
70 | rack-cors (0.3.1)
71 | rack-test (0.6.2)
72 | rack (>= 1.0)
73 | rails (4.1.5)
74 | actionmailer (= 4.1.5)
75 | actionpack (= 4.1.5)
76 | actionview (= 4.1.5)
77 | activemodel (= 4.1.5)
78 | activerecord (= 4.1.5)
79 | activesupport (= 4.1.5)
80 | bundler (>= 1.3.0, < 2.0)
81 | railties (= 4.1.5)
82 | sprockets-rails (~> 2.0)
83 | rails_12factor (0.0.3)
84 | rails_serve_static_assets
85 | rails_stdout_logging
86 | rails_serve_static_assets (0.0.4)
87 | rails_stdout_logging (0.0.3)
88 | railties (4.1.5)
89 | actionpack (= 4.1.5)
90 | activesupport (= 4.1.5)
91 | rake (>= 0.8.7)
92 | thor (>= 0.18.1, < 2.0)
93 | rake (10.4.2)
94 | slop (3.6.0)
95 | sprockets (2.12.3)
96 | hike (~> 1.2)
97 | multi_json (~> 1.0)
98 | rack (~> 1.0)
99 | tilt (~> 1.1, != 1.3.0)
100 | sprockets-rails (2.2.2)
101 | actionpack (>= 3.0)
102 | activesupport (>= 3.0)
103 | sprockets (>= 2.8, < 4.0)
104 | thin (1.6.3)
105 | daemons (~> 1.0, >= 1.0.9)
106 | eventmachine (~> 1.0)
107 | rack (~> 1.0)
108 | thor (0.19.1)
109 | thread_safe (0.3.4)
110 | tilt (1.4.1)
111 | treetop (1.4.15)
112 | polyglot
113 | polyglot (>= 0.3.1)
114 | tzinfo (1.2.2)
115 | thread_safe (~> 0.1)
116 |
117 | PLATFORMS
118 | ruby
119 |
120 | DEPENDENCIES
121 | documentation!
122 | movie_manager!
123 | pg
124 | pry-rails
125 | rack-cors
126 | rails_12factor
127 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | Copyright (c) 2016 Eno Compton
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of
5 | this software and associated documentation files (the "Software"), to deal in
6 | the Software without restriction, including without limitation the rights to
7 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8 | of the Software, and to permit persons to whom the Software is furnished to do
9 | so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all
12 | copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | SOFTWARE.
21 |
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | web: bundle exec rails server -p $PORT
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Json-Api
2 |
3 | A simple set of JSON RESTful endpoints using the repository pattern and Rails engines.
4 |
5 | ## About
6 |
7 | This app lives at [json-api.herokuapp.com](http://json-api.herokuapp.com) and responds to requests at `/api/movies`.
8 |
9 | There are two things which make this otherwise plain app interesting:
10 |
11 | 1. Any interaction with ActiveRecord is hidden behind a repository interface. I have written about the rationale of doing this [here](http://commandercoriander.net/blog/2014/10/02/isolating-active-record/).
12 | 2. The app uses engines and has no `app` folder in the top level. For some context on why this is valuable, see the talk by Stephan Hagemann, [Component-based Architectures in Ruby and Rails](https://www.youtube.com/watch?v=-54SDanDC00). If you prefer reading about the topic, there is also [a book](https://leanpub.com/cbra).
13 |
14 | For an introduction to how this app's API was written, see the post [here](http://commandercoriander.net/blog/2014/01/04/test-driving-a-json-api-in-rails/).
15 |
16 | If you would like to practice using `curl` while interacting with the app, see the post [here](http://commandercoriander.net/blog/2014/01/11/curling-with-rails/).
17 |
18 | ## JavaScript Clients
19 |
20 | See [here](https://github.com/enocom/angular_client) for an AngularJS client.
21 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require File.expand_path('../config/application', __FILE__)
2 |
3 | JsonRails::Application.load_tasks
4 |
--------------------------------------------------------------------------------
/bin/bundle:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
3 | load Gem.bin_path('bundler', 'bundle')
4 |
--------------------------------------------------------------------------------
/bin/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | APP_PATH = File.expand_path('../../config/application', __FILE__)
3 | require_relative '../config/boot'
4 | require 'rails/commands'
5 |
--------------------------------------------------------------------------------
/bin/rake:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require_relative '../config/boot'
3 | require 'rake'
4 | Rake.application.run
5 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | result=0
4 |
5 | for test_script in $(find . -name test.sh); do
6 | pushd `dirname $test_script` > /dev/null
7 | ./test.sh
8 | result+=$?
9 | popd > /dev/null
10 | done
11 |
12 | if [ $result -eq 0 ]; then
13 | echo "SUCCESS"
14 | else
15 | echo "FAILURE"
16 | fi
17 |
18 | exit $result
19 |
--------------------------------------------------------------------------------
/components/documentation/.rspec:
--------------------------------------------------------------------------------
1 | --color
2 |
--------------------------------------------------------------------------------
/components/documentation/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | gemspec
4 |
--------------------------------------------------------------------------------
/components/documentation/Gemfile.lock:
--------------------------------------------------------------------------------
1 | PATH
2 | remote: .
3 | specs:
4 | documentation (0.0.1)
5 | rails (= 4.1.5)
6 |
7 | GEM
8 | remote: https://rubygems.org/
9 | specs:
10 | actionmailer (4.1.5)
11 | actionpack (= 4.1.5)
12 | actionview (= 4.1.5)
13 | mail (~> 2.5.4)
14 | actionpack (4.1.5)
15 | actionview (= 4.1.5)
16 | activesupport (= 4.1.5)
17 | rack (~> 1.5.2)
18 | rack-test (~> 0.6.2)
19 | actionview (4.1.5)
20 | activesupport (= 4.1.5)
21 | builder (~> 3.1)
22 | erubis (~> 2.7.0)
23 | activemodel (4.1.5)
24 | activesupport (= 4.1.5)
25 | builder (~> 3.1)
26 | activerecord (4.1.5)
27 | activemodel (= 4.1.5)
28 | activesupport (= 4.1.5)
29 | arel (~> 5.0.0)
30 | activesupport (4.1.5)
31 | i18n (~> 0.6, >= 0.6.9)
32 | json (~> 1.7, >= 1.7.7)
33 | minitest (~> 5.1)
34 | thread_safe (~> 0.1)
35 | tzinfo (~> 1.1)
36 | arel (5.0.1.20140414130214)
37 | builder (3.2.2)
38 | capybara (2.4.4)
39 | mime-types (>= 1.16)
40 | nokogiri (>= 1.3.3)
41 | rack (>= 1.0.0)
42 | rack-test (>= 0.5.4)
43 | xpath (~> 2.0)
44 | cliver (0.3.2)
45 | diff-lcs (1.2.5)
46 | erubis (2.7.0)
47 | i18n (0.7.0)
48 | json (1.8.2)
49 | mail (2.5.4)
50 | mime-types (~> 1.16)
51 | treetop (~> 1.4.8)
52 | mime-types (1.25.1)
53 | mini_portile (0.6.2)
54 | minitest (5.6.1)
55 | multi_json (1.10.1)
56 | nokogiri (1.6.6.2)
57 | mini_portile (~> 0.6.0)
58 | pg (0.18.1)
59 | poltergeist (1.5.1)
60 | capybara (~> 2.1)
61 | cliver (~> 0.3.1)
62 | multi_json (~> 1.0)
63 | websocket-driver (>= 0.2.0)
64 | polyglot (0.3.5)
65 | rack (1.5.3)
66 | rack-test (0.6.3)
67 | rack (>= 1.0)
68 | rails (4.1.5)
69 | actionmailer (= 4.1.5)
70 | actionpack (= 4.1.5)
71 | actionview (= 4.1.5)
72 | activemodel (= 4.1.5)
73 | activerecord (= 4.1.5)
74 | activesupport (= 4.1.5)
75 | bundler (>= 1.3.0, < 2.0)
76 | railties (= 4.1.5)
77 | sprockets-rails (~> 2.0)
78 | railties (4.1.5)
79 | actionpack (= 4.1.5)
80 | activesupport (= 4.1.5)
81 | rake (>= 0.8.7)
82 | thor (>= 0.18.1, < 2.0)
83 | rake (10.4.2)
84 | rspec-core (3.1.7)
85 | rspec-support (~> 3.1.0)
86 | rspec-expectations (3.1.2)
87 | diff-lcs (>= 1.2.0, < 2.0)
88 | rspec-support (~> 3.1.0)
89 | rspec-mocks (3.1.3)
90 | rspec-support (~> 3.1.0)
91 | rspec-rails (3.1.0)
92 | actionpack (>= 3.0)
93 | activesupport (>= 3.0)
94 | railties (>= 3.0)
95 | rspec-core (~> 3.1.0)
96 | rspec-expectations (~> 3.1.0)
97 | rspec-mocks (~> 3.1.0)
98 | rspec-support (~> 3.1.0)
99 | rspec-support (3.1.2)
100 | sprockets (3.1.0)
101 | rack (~> 1.0)
102 | sprockets-rails (2.3.1)
103 | actionpack (>= 3.0)
104 | activesupport (>= 3.0)
105 | sprockets (>= 2.8, < 4.0)
106 | thor (0.19.1)
107 | thread_safe (0.3.5)
108 | treetop (1.4.15)
109 | polyglot
110 | polyglot (>= 0.3.1)
111 | tzinfo (1.2.2)
112 | thread_safe (~> 0.1)
113 | websocket-driver (0.5.1)
114 | websocket-extensions (>= 0.1.0)
115 | websocket-extensions (0.1.1)
116 | xpath (2.0.0)
117 | nokogiri (~> 1.3)
118 |
119 | PLATFORMS
120 | ruby
121 |
122 | DEPENDENCIES
123 | capybara
124 | documentation!
125 | pg
126 | poltergeist
127 | rspec-rails
128 |
--------------------------------------------------------------------------------
/components/documentation/Rakefile:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env rake
2 | begin
3 | require "bundler/setup"
4 | rescue LoadError
5 | puts "You must `gem install bundler` and `bundle install` to run rake tasks"
6 | end
7 |
8 | APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
9 | load "rails/tasks/engine.rake"
10 |
11 | Bundler::GemHelper.install_tasks
12 |
--------------------------------------------------------------------------------
/components/documentation/app/assets/stylesheets/documentation/application.css:
--------------------------------------------------------------------------------
1 | /*
2 | *= require_self
3 | */
4 | .page {
5 | text-align: center;
6 | border: 1px solid black;
7 | width: 400px;
8 | margin: 0 auto;
9 | background: white;
10 | }
11 |
12 | body {
13 | background: grey;
14 | width: 100%;
15 | }
16 |
--------------------------------------------------------------------------------
/components/documentation/app/controllers/documentation/root_controller.rb:
--------------------------------------------------------------------------------
1 | module Documentation
2 | class RootController < ActionController::Base
3 | def index
4 | render layout: "documentation/application"
5 | end
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/components/documentation/app/views/documentation/root/index.html.erb:
--------------------------------------------------------------------------------
1 |
json-api.rocks
2 |
3 | JSON Endpoints
4 |
5 |
6 |
GET /api/movies
7 |
POST /api/movies
8 |
GET /api/movies/:id
9 |
PUT /api/movies/:id
10 |
DELETE /api/movies/:id
11 |
12 |
13 |
14 |
Psst...
15 |
Accept: application/json
16 |
Content-Type: application/json
17 |
18 |
19 | Read about the API here.
20 |
21 |
--------------------------------------------------------------------------------
/components/documentation/app/views/layouts/documentation/application.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | json-api.rocks
7 | <%= stylesheet_link_tag "documentation/application", media: "all" %>
8 |
9 |
10 |
11 |
12 | <%= yield %>
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/components/documentation/config/routes.rb:
--------------------------------------------------------------------------------
1 | Documentation::Engine.routes.draw do
2 | root to: "root#index"
3 | end
4 |
--------------------------------------------------------------------------------
/components/documentation/documentation.gemspec:
--------------------------------------------------------------------------------
1 | $:.push(File.expand_path("../lib", __FILE__))
2 |
3 | require "documentation/version"
4 |
5 | Gem::Specification.new do |s|
6 | s.name = "documentation"
7 | s.version = Documentation::VERSION
8 | s.files = Dir["{app,config,lib}/**/*"]
9 |
10 | s.add_dependency "rails", "4.1.5"
11 |
12 | s.add_development_dependency "rspec-rails"
13 | s.add_development_dependency "capybara"
14 | s.add_development_dependency "poltergeist"
15 | s.add_development_dependency "pg"
16 | end
17 |
18 |
--------------------------------------------------------------------------------
/components/documentation/lib/documentation.rb:
--------------------------------------------------------------------------------
1 | require "documentation/engine"
2 |
3 | module Documentation
4 | end
5 |
--------------------------------------------------------------------------------
/components/documentation/lib/documentation/engine.rb:
--------------------------------------------------------------------------------
1 | module Documentation
2 | class Engine < ::Rails::Engine
3 | isolate_namespace Documentation
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/components/documentation/lib/documentation/version.rb:
--------------------------------------------------------------------------------
1 | module Documentation
2 | VERSION = "0.0.1"
3 | end
4 |
--------------------------------------------------------------------------------
/components/documentation/spec/dummy/Rakefile:
--------------------------------------------------------------------------------
1 | # Add your own tasks in files placed in lib/tasks ending in .rake,
2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3 |
4 | require File.expand_path('../config/application', __FILE__)
5 |
6 | Rails.application.load_tasks
7 |
--------------------------------------------------------------------------------
/components/documentation/spec/dummy/bin/bundle:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
3 | load Gem.bin_path('bundler', 'bundle')
4 |
--------------------------------------------------------------------------------
/components/documentation/spec/dummy/bin/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | APP_PATH = File.expand_path('../../config/application', __FILE__)
3 | require_relative '../config/boot'
4 | require 'rails/commands'
5 |
--------------------------------------------------------------------------------
/components/documentation/spec/dummy/bin/rake:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require_relative '../config/boot'
3 | require 'rake'
4 | Rake.application.run
5 |
--------------------------------------------------------------------------------
/components/documentation/spec/dummy/bin/setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require 'pathname'
3 |
4 | # path to your application root.
5 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
6 |
7 | Dir.chdir APP_ROOT do
8 | # This script is a starting point to setup your application.
9 | # Add necessary setup steps to this file:
10 |
11 | puts "== Installing dependencies =="
12 | system "gem install bundler --conservative"
13 | system "bundle check || bundle install"
14 |
15 | # puts "\n== Copying sample files =="
16 | # unless File.exist?("config/database.yml")
17 | # system "cp config/database.yml.sample config/database.yml"
18 | # end
19 |
20 | puts "\n== Preparing database =="
21 | system "bin/rake db:setup"
22 |
23 | puts "\n== Removing old logs and tempfiles =="
24 | system "rm -f log/*"
25 | system "rm -rf tmp/cache"
26 |
27 | puts "\n== Restarting application server =="
28 | system "touch tmp/restart.txt"
29 | end
30 |
--------------------------------------------------------------------------------
/components/documentation/spec/dummy/config.ru:
--------------------------------------------------------------------------------
1 | # This file is used by Rack-based servers to start the application.
2 |
3 | require ::File.expand_path('../config/environment', __FILE__)
4 | run Rails.application
5 |
--------------------------------------------------------------------------------
/components/documentation/spec/dummy/config/application.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path('../boot', __FILE__)
2 |
3 | require "active_record/railtie"
4 | require "action_controller/railtie"
5 | require "action_mailer/railtie"
6 | require "action_view/railtie"
7 | require "sprockets/railtie"
8 |
9 | Bundler.require(*Rails.groups)
10 | require "documentation"
11 |
12 | module Dummy
13 | class Application < Rails::Application
14 | end
15 | end
16 |
17 |
--------------------------------------------------------------------------------
/components/documentation/spec/dummy/config/boot.rb:
--------------------------------------------------------------------------------
1 | # Set up gems listed in the Gemfile.
2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__)
3 |
4 | require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
5 | $LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__)
6 |
--------------------------------------------------------------------------------
/components/documentation/spec/dummy/config/database.yml:
--------------------------------------------------------------------------------
1 | test:
2 | adapter: postgresql
3 | encoding: unicode
4 | pool: 5
5 | database: documentation_dummy_test
6 |
--------------------------------------------------------------------------------
/components/documentation/spec/dummy/config/environment.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path('../application', __FILE__)
2 |
3 | Rails.application.initialize!
4 |
--------------------------------------------------------------------------------
/components/documentation/spec/dummy/config/environments/test.rb:
--------------------------------------------------------------------------------
1 | Rails.application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb.
3 |
4 | # The test environment is used exclusively to run your application's
5 | # test suite. You never need to work with it otherwise. Remember that
6 | # your test database is "scratch space" for the test suite and is wiped
7 | # and recreated between test runs. Don't rely on the data there!
8 | config.cache_classes = true
9 |
10 | # Do not eager load code on boot. This avoids loading your whole application
11 | # just for the purpose of running a single test. If you are using a tool that
12 | # preloads Rails for running tests, you may have to set it to true.
13 | config.eager_load = false
14 |
15 | # Configure static file server for tests with Cache-Control for performance.
16 | config.serve_static_files = true
17 | config.static_cache_control = 'public, max-age=3600'
18 |
19 | # Show full error reports and disable caching.
20 | config.consider_all_requests_local = true
21 | config.action_controller.perform_caching = false
22 |
23 | # Raise exceptions instead of rendering exception templates.
24 | config.action_dispatch.show_exceptions = false
25 |
26 | # Disable request forgery protection in test environment.
27 | config.action_controller.allow_forgery_protection = false
28 |
29 | # Tell Action Mailer not to deliver emails to the real world.
30 | # The :test delivery method accumulates sent emails in the
31 | # ActionMailer::Base.deliveries array.
32 | config.action_mailer.delivery_method = :test
33 |
34 | # Randomize the order test cases are executed.
35 | config.active_support.test_order = :random
36 |
37 | # Print deprecation notices to the stderr.
38 | config.active_support.deprecation = :stderr
39 |
40 | # Raises error for missing translations
41 | # config.action_view.raise_on_missing_translations = true
42 | end
43 |
--------------------------------------------------------------------------------
/components/documentation/spec/dummy/config/routes.rb:
--------------------------------------------------------------------------------
1 | Rails.application.routes.draw do
2 | mount Documentation::Engine => "/"
3 | end
4 |
--------------------------------------------------------------------------------
/components/documentation/spec/dummy/config/secrets.yml:
--------------------------------------------------------------------------------
1 | test:
2 | secret_key_base: d59ea66b1b8771507c639379f16ec1a9609faeddfc79489e38ac19a27c05d2902df5794d895736c88091b0741937075712eb43b197e048433342a5fda960bd7c
3 |
--------------------------------------------------------------------------------
/components/documentation/spec/dummy/db/schema.rb:
--------------------------------------------------------------------------------
1 | # encoding: UTF-8
2 | # This file is auto-generated from the current state of the database. Instead
3 | # of editing this file, please use the migrations feature of Active Record to
4 | # incrementally modify your database, and then regenerate this schema definition.
5 | #
6 | # Note that this schema.rb definition is the authoritative source for your
7 | # database schema. If you need to create the application database on another
8 | # system, you should be using db:schema:load, not running all the migrations
9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10 | # you'll amass, the slower it'll run and the greater likelihood for issues).
11 | #
12 | # It's strongly recommended that you check this file into your version control system.
13 |
14 | ActiveRecord::Schema.define(version: 0) do
15 |
16 | # These are extensions that must be enabled in order to support this database
17 | enable_extension "plpgsql"
18 |
19 | end
20 |
--------------------------------------------------------------------------------
/components/documentation/spec/dummy/log/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/enocom/json-api/63a6477635d3e3caa2015de6931a0835ffe2cb58/components/documentation/spec/dummy/log/.keep
--------------------------------------------------------------------------------
/components/documentation/spec/features/root_page_spec.rb:
--------------------------------------------------------------------------------
1 | require "rails_helper"
2 |
3 | RSpec.describe "Root Page", type: :feature do
4 | specify "visiting the root page" do
5 | visit "/"
6 |
7 | expect(page).to have_content "json-api.rocks"
8 | expect(page).to have_content "JSON Endpoints"
9 | expect(page).to have_content "GET /api/movies"
10 | expect(page).to have_content "POST /api/movies"
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/components/documentation/spec/rails_helper.rb:
--------------------------------------------------------------------------------
1 | ENV["RAILS_ENV"] ||= "test"
2 |
3 | require File.expand_path("../dummy/config/environment", __FILE__)
4 |
5 | require "rspec/rails"
6 |
7 | Dir[Documentation::Engine.root.join("spec/support/**/*.rb")].each { |f| require f }
8 |
9 | ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)
10 |
11 | RSpec.configure do |config|
12 | config.use_transactional_fixtures = true
13 | end
14 |
--------------------------------------------------------------------------------
/components/documentation/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | RSpec.configure do |config|
2 | config.order = :random
3 |
4 | Kernel.srand config.seed
5 |
6 | config.expect_with :rspec do |expectations|
7 | expectations.syntax = :expect
8 | end
9 |
10 | config.mock_with :rspec do |mocks|
11 | mocks.syntax = :expect
12 | mocks.verify_partial_doubles = true
13 | end
14 |
15 | config.disable_monkey_patching!
16 | end
17 |
--------------------------------------------------------------------------------
/components/documentation/spec/support/capybara.rb:
--------------------------------------------------------------------------------
1 | require "capybara/rspec"
2 | require "capybara/poltergeist"
3 |
4 | Capybara.javascript_driver = :poltergeist
5 | Capybara.ignore_hidden_elements = true
6 |
--------------------------------------------------------------------------------
/components/documentation/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | exit_code=0
4 |
5 | echo "*** Running documentation engine specs"
6 | bundle install | grep Installing
7 | RAILS_ENV=test bundle exec rake db:create
8 | RAILS_ENV=test bundle exec rake db:migrate
9 | bundle exec rspec spec
10 | exit_code+=$?
11 |
12 | exit $exit_code
13 |
--------------------------------------------------------------------------------
/components/movie_manager/.rspec:
--------------------------------------------------------------------------------
1 | --color
2 |
--------------------------------------------------------------------------------
/components/movie_manager/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | gemspec
4 |
--------------------------------------------------------------------------------
/components/movie_manager/Gemfile.lock:
--------------------------------------------------------------------------------
1 | PATH
2 | remote: .
3 | specs:
4 | movie_manager (0.0.1)
5 | oj
6 | rails (= 4.1.5)
7 | thin
8 |
9 | GEM
10 | remote: https://rubygems.org/
11 | specs:
12 | actionmailer (4.1.5)
13 | actionpack (= 4.1.5)
14 | actionview (= 4.1.5)
15 | mail (~> 2.5.4)
16 | actionpack (4.1.5)
17 | actionview (= 4.1.5)
18 | activesupport (= 4.1.5)
19 | rack (~> 1.5.2)
20 | rack-test (~> 0.6.2)
21 | actionview (4.1.5)
22 | activesupport (= 4.1.5)
23 | builder (~> 3.1)
24 | erubis (~> 2.7.0)
25 | activemodel (4.1.5)
26 | activesupport (= 4.1.5)
27 | builder (~> 3.1)
28 | activerecord (4.1.5)
29 | activemodel (= 4.1.5)
30 | activesupport (= 4.1.5)
31 | arel (~> 5.0.0)
32 | activesupport (4.1.5)
33 | i18n (~> 0.6, >= 0.6.9)
34 | json (~> 1.7, >= 1.7.7)
35 | minitest (~> 5.1)
36 | thread_safe (~> 0.1)
37 | tzinfo (~> 1.1)
38 | arel (5.0.1.20140414130214)
39 | builder (3.2.2)
40 | coderay (1.1.0)
41 | daemons (1.1.9)
42 | diff-lcs (1.2.5)
43 | erubis (2.7.0)
44 | eventmachine (1.0.4)
45 | i18n (0.7.0)
46 | json (1.8.2)
47 | mail (2.5.4)
48 | mime-types (~> 1.16)
49 | treetop (~> 1.4.8)
50 | method_source (0.8.2)
51 | mime-types (1.25.1)
52 | minitest (5.6.1)
53 | oj (2.11.4)
54 | pg (0.18.1)
55 | polyglot (0.3.5)
56 | pry (0.10.1)
57 | coderay (~> 1.1.0)
58 | method_source (~> 0.8.1)
59 | slop (~> 3.4)
60 | pry-rails (0.3.3)
61 | pry (>= 0.9.10)
62 | rack (1.5.3)
63 | rack-test (0.6.3)
64 | rack (>= 1.0)
65 | rails (4.1.5)
66 | actionmailer (= 4.1.5)
67 | actionpack (= 4.1.5)
68 | actionview (= 4.1.5)
69 | activemodel (= 4.1.5)
70 | activerecord (= 4.1.5)
71 | activesupport (= 4.1.5)
72 | bundler (>= 1.3.0, < 2.0)
73 | railties (= 4.1.5)
74 | sprockets-rails (~> 2.0)
75 | railties (4.1.5)
76 | actionpack (= 4.1.5)
77 | activesupport (= 4.1.5)
78 | rake (>= 0.8.7)
79 | thor (>= 0.18.1, < 2.0)
80 | rake (10.4.2)
81 | rspec-core (3.1.7)
82 | rspec-support (~> 3.1.0)
83 | rspec-expectations (3.1.2)
84 | diff-lcs (>= 1.2.0, < 2.0)
85 | rspec-support (~> 3.1.0)
86 | rspec-mocks (3.1.3)
87 | rspec-support (~> 3.1.0)
88 | rspec-rails (3.1.0)
89 | actionpack (>= 3.0)
90 | activesupport (>= 3.0)
91 | railties (>= 3.0)
92 | rspec-core (~> 3.1.0)
93 | rspec-expectations (~> 3.1.0)
94 | rspec-mocks (~> 3.1.0)
95 | rspec-support (~> 3.1.0)
96 | rspec-support (3.1.2)
97 | slop (3.6.0)
98 | sprockets (3.1.0)
99 | rack (~> 1.0)
100 | sprockets-rails (2.3.1)
101 | actionpack (>= 3.0)
102 | activesupport (>= 3.0)
103 | sprockets (>= 2.8, < 4.0)
104 | thin (1.6.3)
105 | daemons (~> 1.0, >= 1.0.9)
106 | eventmachine (~> 1.0)
107 | rack (~> 1.0)
108 | thor (0.19.1)
109 | thread_safe (0.3.5)
110 | treetop (1.4.15)
111 | polyglot
112 | polyglot (>= 0.3.1)
113 | tzinfo (1.2.2)
114 | thread_safe (~> 0.1)
115 |
116 | PLATFORMS
117 | ruby
118 |
119 | DEPENDENCIES
120 | movie_manager!
121 | pg
122 | pry-rails
123 | rspec-rails
124 |
--------------------------------------------------------------------------------
/components/movie_manager/Rakefile:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env rake
2 | begin
3 | require "bundler/setup"
4 | rescue LoadError
5 | puts "You must `gem install bundler` and `bundle install` to run rake tasks"
6 | end
7 |
8 | APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
9 | load "rails/tasks/engine.rake"
10 |
11 | Bundler::GemHelper.install_tasks
12 |
--------------------------------------------------------------------------------
/components/movie_manager/app/controllers/movie_manager/movies_controller.rb:
--------------------------------------------------------------------------------
1 | module MovieManager
2 | class MoviesController < ActionController::Base
3 | protect_from_forgery with: :null_session
4 |
5 | def index
6 | all_movies = MovieRepo.all.map do |movie|
7 | MovieSerializer.new(movie).as_json
8 | end
9 |
10 | render json: all_movies
11 | end
12 |
13 | def show
14 | movie = MovieRepo.find(params[:id])
15 |
16 | if movie.present?
17 | render json: MovieSerializer.new(movie).as_json
18 | else
19 | render json: { errors: ["Movie not found"] }, status: :not_found
20 | end
21 | end
22 |
23 | def update
24 | movie = MovieRepo.find(params[:id])
25 | updated_movie = MovieRepo.update(movie, movie_params)
26 |
27 | render json: MovieSerializer.new(updated_movie).as_json
28 | end
29 |
30 | def create
31 | persisted_movie = MovieRepo.persist(
32 | title: movie_params[:title],
33 | director: movie_params[:director]
34 | )
35 |
36 | render json: MovieSerializer.new(persisted_movie).as_json,
37 | location: movie_path(persisted_movie.id),
38 | status: :created
39 | end
40 |
41 | def destroy
42 | movie = MovieRepo.find(params[:id])
43 |
44 | MovieRepo.delete(movie)
45 |
46 | head :no_content
47 | end
48 |
49 | private
50 |
51 | def movie_params
52 | params.permit(:title, :director)
53 | end
54 |
55 | end
56 | end
57 |
--------------------------------------------------------------------------------
/components/movie_manager/app/models/movie_manager/movie.rb:
--------------------------------------------------------------------------------
1 | module MovieManager
2 | class Movie
3 | attr_reader :id, :title, :director
4 |
5 | def initialize(id, title, director)
6 | @id = id
7 | @title = title
8 | @director = director
9 | end
10 |
11 | def attributes
12 | {
13 | id: id,
14 | title: title,
15 | director: director
16 | }
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/components/movie_manager/app/models/movie_manager/movie_repo.rb:
--------------------------------------------------------------------------------
1 | module MovieManager
2 | class MovieRepo
3 | class PersistFailedError < StandardError
4 | end
5 |
6 | def self.all
7 | Movie.all.map { |m| build_movie(m) }
8 | end
9 |
10 | def self.find(movie_id)
11 | movie = Movie.find(movie_id)
12 |
13 | build_movie(movie)
14 | rescue ActiveRecord::RecordNotFound
15 | nil
16 | end
17 |
18 | def self.persist(movie_attrs)
19 | m = Movie.create!(movie_attrs)
20 |
21 | build_movie(m)
22 | rescue
23 | raise PersistFailedError
24 | end
25 |
26 | def self.update(movie, attrs)
27 | m = Movie.find(movie.id)
28 | m.update_attributes(attrs)
29 | build_movie(m)
30 | end
31 |
32 | def self.delete(movie)
33 | delete_count = Movie.delete(movie.id)
34 | delete_count == 1
35 | end
36 |
37 | private
38 |
39 | def self.build_movie(m)
40 | MovieManager::Movie.new(id = m.id, title = m.title, director = m.director)
41 | end
42 |
43 | class Movie < ActiveRecord::Base
44 | end
45 | end
46 | end
47 |
--------------------------------------------------------------------------------
/components/movie_manager/app/models/movie_manager/movie_serializer.rb:
--------------------------------------------------------------------------------
1 | module MovieManager
2 | class MovieSerializer
3 | def initialize(movie)
4 | @movie = movie
5 | end
6 |
7 | def as_json(options = {})
8 | {
9 | "id" => movie.id,
10 | "title" => movie.title,
11 | "director" => movie.director
12 | }
13 | end
14 |
15 | private
16 |
17 | attr_reader :movie
18 | end
19 | end
20 |
21 |
--------------------------------------------------------------------------------
/components/movie_manager/config/routes.rb:
--------------------------------------------------------------------------------
1 | MovieManager::Engine.routes.draw do
2 | resources :movies, only: [:index, :show, :update, :create, :destroy]
3 | end
4 |
--------------------------------------------------------------------------------
/components/movie_manager/db/migrate/20131215170206_create_movies.rb:
--------------------------------------------------------------------------------
1 | class CreateMovies < ActiveRecord::Migration
2 | def change
3 | create_table :movie_manager_movies do |t|
4 | t.string :title, null: false, unique: true
5 | end
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/components/movie_manager/db/migrate/20140128061928_add_director_to_movies.rb:
--------------------------------------------------------------------------------
1 | class AddDirectorToMovies < ActiveRecord::Migration
2 | def change
3 | add_column :movie_manager_movies, :director, :string
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/components/movie_manager/db/migrate/20141206230010_add_timestamps_to_movies.rb:
--------------------------------------------------------------------------------
1 | class AddTimestampsToMovies < ActiveRecord::Migration
2 | def change
3 | change_table :movie_manager_movies do |t|
4 | t.timestamps
5 | end
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/components/movie_manager/lib/movie_manager.rb:
--------------------------------------------------------------------------------
1 | require "movie_manager/engine"
2 | require "pg"
3 | require "yaml"
4 |
5 | module MovieManager
6 | end
7 |
--------------------------------------------------------------------------------
/components/movie_manager/lib/movie_manager/engine.rb:
--------------------------------------------------------------------------------
1 | module MovieManager
2 | class Engine < ::Rails::Engine
3 | isolate_namespace MovieManager
4 |
5 | initializer :append_migrations do |app|
6 | unless app.root.to_s.match root.to_s + File::SEPARATOR
7 | config.paths["db/migrate"].expanded.each do |path|
8 | app.config.paths["db/migrate"] << path
9 | end
10 | end
11 | end
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/components/movie_manager/lib/movie_manager/version.rb:
--------------------------------------------------------------------------------
1 | module MovieManager
2 | VERSION = "0.0.1"
3 | end
4 |
--------------------------------------------------------------------------------
/components/movie_manager/movie_manager.gemspec:
--------------------------------------------------------------------------------
1 | $:.push(File.expand_path("../lib", __FILE__))
2 |
3 | require "movie_manager/version"
4 |
5 | Gem::Specification.new do |s|
6 | s.name = "movie_manager"
7 | s.version = MovieManager::VERSION
8 | s.files = Dir["{app,config,db,lib}/**/*"]
9 |
10 | s.add_dependency "oj"
11 | s.add_dependency "rails", "4.1.5"
12 | s.add_dependency "thin"
13 |
14 | s.add_development_dependency "pg"
15 | s.add_development_dependency "pry-rails"
16 | s.add_development_dependency "rspec-rails"
17 | end
18 |
--------------------------------------------------------------------------------
/components/movie_manager/spec/dummy/Rakefile:
--------------------------------------------------------------------------------
1 | require File.expand_path("../config/application", __FILE__)
2 |
3 | Rails.application.load_tasks
4 |
--------------------------------------------------------------------------------
/components/movie_manager/spec/dummy/bin/bundle:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
3 | load Gem.bin_path('bundler', 'bundle')
4 |
--------------------------------------------------------------------------------
/components/movie_manager/spec/dummy/bin/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | APP_PATH = File.expand_path('../../config/application', __FILE__)
3 | require_relative '../config/boot'
4 | require 'rails/commands'
5 |
--------------------------------------------------------------------------------
/components/movie_manager/spec/dummy/bin/rake:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require_relative '../config/boot'
3 | require 'rake'
4 | Rake.application.run
5 |
--------------------------------------------------------------------------------
/components/movie_manager/spec/dummy/bin/setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require 'pathname'
3 |
4 | # path to your application root.
5 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
6 |
7 | Dir.chdir APP_ROOT do
8 | # This script is a starting point to setup your application.
9 | # Add necessary setup steps to this file:
10 |
11 | puts "== Installing dependencies =="
12 | system "gem install bundler --conservative"
13 | system "bundle check || bundle install"
14 |
15 | # puts "\n== Copying sample files =="
16 | # unless File.exist?("config/database.yml")
17 | # system "cp config/database.yml.sample config/database.yml"
18 | # end
19 |
20 | puts "\n== Preparing database =="
21 | system "bin/rake db:setup"
22 |
23 | puts "\n== Removing old logs and tempfiles =="
24 | system "rm -f log/*"
25 | system "rm -rf tmp/cache"
26 |
27 | puts "\n== Restarting application server =="
28 | system "touch tmp/restart.txt"
29 | end
30 |
--------------------------------------------------------------------------------
/components/movie_manager/spec/dummy/config.ru:
--------------------------------------------------------------------------------
1 | # This file is used by Rack-based servers to start the application.
2 |
3 | require ::File.expand_path('../config/environment', __FILE__)
4 | run Rails.application
5 |
--------------------------------------------------------------------------------
/components/movie_manager/spec/dummy/config/application.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path("../boot", __FILE__)
2 |
3 | require "active_record/railtie"
4 | require "action_controller/railtie"
5 |
6 | Bundler.require(*Rails.groups)
7 | require "movie_manager"
8 |
9 | module Dummy
10 | class Application < Rails::Application
11 | end
12 | end
13 |
14 |
--------------------------------------------------------------------------------
/components/movie_manager/spec/dummy/config/boot.rb:
--------------------------------------------------------------------------------
1 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", __FILE__)
2 |
3 | require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"])
4 | $LOAD_PATH.unshift(File.expand_path("../../../../lib", __FILE__))
5 |
--------------------------------------------------------------------------------
/components/movie_manager/spec/dummy/config/database.yml:
--------------------------------------------------------------------------------
1 | test:
2 | adapter: postgresql
3 | encoding: unicode
4 | pool: 5
5 | database: movie_manager_dummy_test
6 |
--------------------------------------------------------------------------------
/components/movie_manager/spec/dummy/config/environment.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path("../application", __FILE__)
2 |
3 | Rails.application.initialize!
4 |
--------------------------------------------------------------------------------
/components/movie_manager/spec/dummy/config/environments/test.rb:
--------------------------------------------------------------------------------
1 | Rails.application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb.
3 |
4 | # The test environment is used exclusively to run your application's
5 | # test suite. You never need to work with it otherwise. Remember that
6 | # your test database is "scratch space" for the test suite and is wiped
7 | # and recreated between test runs. Don't rely on the data there!
8 | config.cache_classes = true
9 |
10 | # Do not eager load code on boot. This avoids loading your whole application
11 | # just for the purpose of running a single test. If you are using a tool that
12 | # preloads Rails for running tests, you may have to set it to true.
13 | config.eager_load = false
14 |
15 | # Configure static file server for tests with Cache-Control for performance.
16 | config.serve_static_files = true
17 | config.static_cache_control = 'public, max-age=3600'
18 |
19 | # Show full error reports and disable caching.
20 | config.consider_all_requests_local = true
21 | config.action_controller.perform_caching = false
22 |
23 | # Raise exceptions instead of rendering exception templates.
24 | config.action_dispatch.show_exceptions = false
25 |
26 | # Disable request forgery protection in test environment.
27 | config.action_controller.allow_forgery_protection = false
28 |
29 | # Randomize the order test cases are executed.
30 | config.active_support.test_order = :random
31 |
32 | # Print deprecation notices to the stderr.
33 | config.active_support.deprecation = :stderr
34 |
35 | # Raises error for missing translations
36 | # config.action_view.raise_on_missing_translations = true
37 | end
38 |
--------------------------------------------------------------------------------
/components/movie_manager/spec/dummy/config/routes.rb:
--------------------------------------------------------------------------------
1 | Rails.application.routes.draw do
2 | mount MovieManager::Engine => "/"
3 | end
4 |
--------------------------------------------------------------------------------
/components/movie_manager/spec/dummy/config/secrets.yml:
--------------------------------------------------------------------------------
1 | test:
2 | secret_key_base: d59ea66b1b8771507c639379f16ec1a9609faeddfc79489e38ac19a27c05d2902df5794d895736c88091b0741937075712eb43b197e048433342a5fda960bd7c
3 |
--------------------------------------------------------------------------------
/components/movie_manager/spec/dummy/db/schema.rb:
--------------------------------------------------------------------------------
1 | # encoding: UTF-8
2 | # This file is auto-generated from the current state of the database. Instead
3 | # of editing this file, please use the migrations feature of Active Record to
4 | # incrementally modify your database, and then regenerate this schema definition.
5 | #
6 | # Note that this schema.rb definition is the authoritative source for your
7 | # database schema. If you need to create the application database on another
8 | # system, you should be using db:schema:load, not running all the migrations
9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10 | # you'll amass, the slower it'll run and the greater likelihood for issues).
11 | #
12 | # It's strongly recommended that you check this file into your version control system.
13 |
14 | ActiveRecord::Schema.define(version: 20141206230010) do
15 |
16 | # These are extensions that must be enabled in order to support this database
17 | enable_extension "plpgsql"
18 |
19 | create_table "movie_manager_movies", force: true do |t|
20 | t.string "title", null: false
21 | t.string "director"
22 | t.datetime "created_at"
23 | t.datetime "updated_at"
24 | end
25 |
26 | end
27 |
--------------------------------------------------------------------------------
/components/movie_manager/spec/models/movie_manager/movie_repo_spec.rb:
--------------------------------------------------------------------------------
1 | require "rails_helper"
2 |
3 | module MovieManager
4 | RSpec.describe MovieRepo do
5 | describe "all movies" do
6 | it "returns all the persisted movies" do
7 | create_movie(title: "Foo", director: "Bar")
8 |
9 | result = MovieRepo.all
10 |
11 | expect(result.count).to eq 1
12 | expect(result.first.id).not_to be_nil
13 | expect(result.first.title).to eq "Foo"
14 | expect(result.first.director).to eq "Bar"
15 | end
16 |
17 | it "returns an empty collection when no movies exist" do
18 | expect(MovieRepo.all).to eq []
19 | end
20 |
21 | it "returns value objects instead of Active Record objects" do
22 | create_movie(title: "Foo", director: "Bar")
23 |
24 | result = MovieRepo.all
25 |
26 | expect(result.first.is_a?(Movie)).to eq true
27 | expect(result.first.id).to be_present
28 | expect(result.first.title).to eq "Foo"
29 | expect(result.first.director).to eq "Bar"
30 | end
31 | end
32 |
33 | describe "querying movies" do
34 | it "finds movies based on an ID" do
35 | movie = create_movie(title: "Foo", director: "Bar")
36 |
37 | found_movie = MovieRepo.find(movie.id)
38 |
39 | expect(found_movie.id).to eq movie.id
40 | expect(found_movie.title).to eq "Foo"
41 | expect(found_movie.director).to eq "Bar"
42 | end
43 |
44 | it "returns nil when a movie is not found" do
45 | expect(MovieRepo.find(bogus_id = 123)).to be_nil
46 | end
47 | end
48 |
49 | describe "persisting movies" do
50 | it "stores movies in the database" do
51 | persisted_movie = MovieRepo.persist(title: "The Shining",
52 | director: "Stanley Kubrick")
53 |
54 | expect(persisted_movie.id).to be_present
55 | end
56 |
57 | it "returns value objects after persisting movie data" do
58 | persisted_movie = MovieRepo.persist(title: "The Shining",
59 | director: "Stanley Kubrick")
60 |
61 | expect(persisted_movie.is_a?(Movie)).to eq true
62 | end
63 |
64 | it "raises an error when persiting data fails" do
65 | allow(MovieRepo::Movie).to receive(:create!).and_raise
66 |
67 | expect {
68 | MovieRepo.persist(garbage: :data)
69 | }.to raise_error(MovieRepo::PersistFailedError)
70 | end
71 | end
72 |
73 | describe "updating movies" do
74 | it "updates a movie" do
75 | movie = create_movie(title: "Foo", director: "Bar")
76 |
77 | updated = MovieRepo.update(movie, title: "Oof", director: "Rab")
78 |
79 | expect(updated.id).to eq movie.id
80 | expect(updated.title).to eq "Oof"
81 | expect(updated.director).to eq "Rab"
82 |
83 | sanity_check = MovieRepo.find(updated.id)
84 | expect(sanity_check.id).to eq movie.id
85 | expect(sanity_check.title).to eq "Oof"
86 | expect(sanity_check.director).to eq "Rab"
87 | end
88 |
89 | it "accepts partial updates" do
90 | movie = create_movie(title: "Foo", director: "Bar")
91 |
92 | updated = MovieRepo.update(movie, title: "Oof")
93 |
94 | expect(updated.id).to eq movie.id
95 | expect(updated.title).to eq "Oof"
96 | expect(updated.director).to eq "Bar"
97 | end
98 | end
99 |
100 | describe "deleting movies" do
101 | it "deletes movies from the database" do
102 | movie = create_movie
103 |
104 | result = MovieRepo.delete(movie)
105 |
106 | expect(result).to eq true
107 | expect(MovieRepo.all).to eq []
108 | end
109 |
110 | it "returns false when the delete fails" do
111 | FakeMovie = Struct.new(:id)
112 |
113 | result = MovieRepo.delete(FakeMovie.new(123))
114 |
115 | expect(result).to eq false
116 | end
117 | end
118 | end
119 | end
120 |
--------------------------------------------------------------------------------
/components/movie_manager/spec/rails_helper.rb:
--------------------------------------------------------------------------------
1 | ENV["RAILS_ENV"] ||= "test"
2 | require File.expand_path("../dummy/config/environment", __FILE__)
3 | require "rspec/rails"
4 |
5 | Dir[MovieManager::Engine.root.join("spec/support/**/*.rb")].each { |f| require f }
6 |
7 | ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)
8 |
9 | RSpec.configure do |config|
10 | config.use_transactional_fixtures = true
11 |
12 | config.include ObjectCreationMethods
13 | end
14 |
--------------------------------------------------------------------------------
/components/movie_manager/spec/requests/movies_api_spec.rb:
--------------------------------------------------------------------------------
1 | require "rails_helper"
2 |
3 | module MovieManager
4 | RSpec.describe "movies API", :type => :request do
5 | let(:accept_json) { {"Accept" => "application/json"} }
6 | let(:json_content_type) { {"Content-Type" => "application/json"} }
7 | let(:accept_and_return_json) { accept_json.merge(json_content_type) }
8 |
9 | describe "GET /movies" do
10 | before do
11 | create_movie(
12 | :title => "The Hobbit",
13 | :director => "Peter Jackson"
14 | )
15 | create_movie(
16 | :title => "The Fellowship of the Ring",
17 | :director => "Peter Jackson"
18 | )
19 | end
20 |
21 | it "returns all the movies" do
22 | get "/movies", {}, accept_json
23 |
24 | expect(response.status).to eq 200
25 |
26 | body = JSON.parse(response.body)
27 | movie_titles = body.map { |m| m["title"] }
28 | movie_directors = body.map { |m| m["director"] }
29 |
30 | expect(movie_titles).to match_array(["The Hobbit",
31 | "The Fellowship of the Ring"])
32 | expect(movie_directors).to match_array(["Peter Jackson",
33 | "Peter Jackson"])
34 | end
35 | end
36 |
37 | describe "GET /movies/:id" do
38 | let(:movie) do
39 | create_movie(
40 | :title => "2001: A Space Odyssy",
41 | :director => "Stanley Kubrick"
42 | )
43 | end
44 |
45 | it "returns a requested movie" do
46 | get "/movies/#{movie.id}", {}, accept_json
47 |
48 | expect(response.status).to be 200
49 |
50 | body = JSON.parse(response.body)
51 | expect(body["title"]).to eq "2001: A Space Odyssy"
52 | expect(body["director"]).to eq "Stanley Kubrick"
53 | end
54 | end
55 |
56 | describe "PUT /movies/:id" do
57 | let(:movie) do
58 | create_movie(
59 | :title => "Star Battles",
60 | :director => "Leorge Gucas"
61 | )
62 | end
63 |
64 | let(:movie_params) do
65 | {"title" => "Star Wars", "director" => "George Lucas"}
66 | end
67 |
68 | it "updates a movie" do
69 | patch "/movies/#{movie.id}", movie_params.to_json, accept_and_return_json
70 |
71 | expect(response.status).to be 200
72 |
73 | body = JSON.parse(response.body)
74 |
75 | expect(body["title"]).to eq "Star Wars"
76 | expect(body["director"]).to eq "George Lucas"
77 | end
78 | end
79 |
80 | describe "POST /movies" do
81 | let(:movie_params) do
82 | {
83 | "title" => "Indiana Jones and the Temple of Doom",
84 | "director" => "Steven Spielberg"
85 | }
86 | end
87 |
88 | it "creates a movie" do
89 | post "/movies", movie_params.to_json, accept_and_return_json
90 |
91 | expect(response.status).to eq 201
92 |
93 | response_body = JSON.parse(response.body)
94 |
95 | expect(response_body["id"]).to be_present
96 | expect(response_body["director"]).to eq("Steven Spielberg")
97 |
98 | expect(response_body["title"])
99 | .to eq "Indiana Jones and the Temple of Doom"
100 | end
101 | end
102 |
103 | describe "DELETE /movies/:id" do
104 | let(:movie) do
105 | create_movie(
106 | :title => "The Shining",
107 | :director => "Stanley Kubrick"
108 | )
109 | end
110 |
111 | it "deletes a movie" do
112 | delete "/movies/#{movie.id}", {}, accept_json
113 |
114 | expect(response.status).to be 204
115 | end
116 | end
117 | end
118 | end
119 |
--------------------------------------------------------------------------------
/components/movie_manager/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | RSpec.configure do |config|
2 | config.order = :random
3 |
4 | Kernel.srand config.seed
5 |
6 | config.expect_with :rspec do |expectations|
7 | expectations.syntax = :expect
8 | end
9 |
10 | config.mock_with :rspec do |mocks|
11 | mocks.syntax = :expect
12 | mocks.verify_partial_doubles = true
13 | end
14 |
15 | config.disable_monkey_patching!
16 | end
17 |
--------------------------------------------------------------------------------
/components/movie_manager/spec/support/object_creation_methods.rb:
--------------------------------------------------------------------------------
1 | module ObjectCreationMethods
2 | def create_movie(overrides = {})
3 | new_movie(overrides).tap(&:save!)
4 | end
5 |
6 | def new_movie(overrides = {})
7 | defaults = {
8 | title: "The Shining",
9 | director: "Stanley Kubrick"
10 |
11 | }
12 |
13 | MovieManager::MovieRepo::Movie.new(defaults.merge(overrides))
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/components/movie_manager/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | exit_code=0
4 |
5 | echo "*** Running movie manager engine specs"
6 | bundle install | grep Installing
7 | RAILS_ENV=test bundle exec rake db:create
8 | RAILS_ENV=test bundle exec rake db:migrate
9 | bundle exec rspec spec
10 | exit_code+=$?
11 |
12 | exit $exit_code
13 |
--------------------------------------------------------------------------------
/config.ru:
--------------------------------------------------------------------------------
1 | require ::File.expand_path('../config/environment', __FILE__)
2 | run Rails.application
3 |
--------------------------------------------------------------------------------
/config/application.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path('../boot', __FILE__)
2 |
3 | require "active_record/railtie"
4 | require "action_controller/railtie"
5 | require "action_view/railtie"
6 | require "sprockets/railtie"
7 |
8 | Bundler.setup(:default, Rails.env)
9 |
10 | require "pry-rails"
11 | require "rack/cors"
12 |
13 | require "documentation"
14 | require "movie_manager"
15 |
16 | module JsonRails
17 | class Application < Rails::Application
18 | config.i18n.enforce_available_locales = true
19 |
20 | config.middleware.use Rack::Cors do
21 | allow do
22 | origins "*"
23 | resource "*", :headers => :any, :methods => [:get, :post, :delete, :put, :options]
24 | end
25 | end
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/config/boot.rb:
--------------------------------------------------------------------------------
1 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__)
2 |
3 | require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"])
4 |
--------------------------------------------------------------------------------
/config/database.yml:
--------------------------------------------------------------------------------
1 | development:
2 | adapter: postgresql
3 | encoding: unicode
4 | database: json-rails_development
5 | pool: 5
6 |
7 | test:
8 | adapter: postgresql
9 | encoding: unicode
10 | database: json-rails_test
11 | pool: 5
12 |
--------------------------------------------------------------------------------
/config/environment.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path('../application', __FILE__)
2 | JsonRails::Application.initialize!
3 |
--------------------------------------------------------------------------------
/config/environments/development.rb:
--------------------------------------------------------------------------------
1 | JsonRails::Application.configure do
2 | config.cache_classes = false
3 | config.eager_load = false
4 | config.consider_all_requests_local = true
5 | config.action_controller.perform_caching = false
6 | config.active_support.deprecation = :log
7 | config.active_record.migration_error = :page_load
8 | config.assets.debug = true
9 | end
10 |
--------------------------------------------------------------------------------
/config/environments/production.rb:
--------------------------------------------------------------------------------
1 | JsonRails::Application.configure do
2 | config.cache_classes = true
3 | config.eager_load = true
4 | config.consider_all_requests_local = false
5 | config.action_controller.perform_caching = true
6 | config.serve_static_assets = true
7 | config.assets.js_compressor = :uglifier
8 | config.assets.compile = false
9 | config.assets.digest = true
10 | config.assets.version = '1.0'
11 | config.log_level = :debug
12 | config.i18n.fallbacks = true
13 | config.active_support.deprecation = :notify
14 | config.log_formatter = ::Logger::Formatter.new
15 | end
16 |
--------------------------------------------------------------------------------
/config/environments/test.rb:
--------------------------------------------------------------------------------
1 | JsonRails::Application.configure do
2 | config.cache_classes = true
3 | config.eager_load = false
4 | config.serve_static_assets = true
5 | config.static_cache_control = "public, max-age=3600"
6 | config.consider_all_requests_local = true
7 | config.action_controller.perform_caching = false
8 | config.action_dispatch.show_exceptions = false
9 | config.action_controller.allow_forgery_protection = false
10 | config.active_support.deprecation = :stderr
11 | end
12 |
--------------------------------------------------------------------------------
/config/initializers/secret_token.rb:
--------------------------------------------------------------------------------
1 | JsonRails::Application.config.secret_key_base = '98c57dee58abd58bae2fb48e704754fef46df62f16e5ccb1d3eed622b592e71a1912488472883d3b6b4c01c0a651377c0c95f9db644f1012f3f0c3a513f7a37c'
2 |
--------------------------------------------------------------------------------
/config/initializers/wrap_parameters.rb:
--------------------------------------------------------------------------------
1 | ActiveSupport.on_load(:action_controller) do
2 | wrap_parameters format: [:json] if respond_to?(:wrap_parameters)
3 | end
4 |
--------------------------------------------------------------------------------
/config/routes.rb:
--------------------------------------------------------------------------------
1 | JsonRails::Application.routes.draw do
2 | mount Documentation::Engine, at: "/"
3 | mount MovieManager::Engine, at: "/api"
4 | end
5 |
--------------------------------------------------------------------------------
/db/schema.rb:
--------------------------------------------------------------------------------
1 | # encoding: UTF-8
2 | # This file is auto-generated from the current state of the database. Instead
3 | # of editing this file, please use the migrations feature of Active Record to
4 | # incrementally modify your database, and then regenerate this schema definition.
5 | #
6 | # Note that this schema.rb definition is the authoritative source for your
7 | # database schema. If you need to create the application database on another
8 | # system, you should be using db:schema:load, not running all the migrations
9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10 | # you'll amass, the slower it'll run and the greater likelihood for issues).
11 | #
12 | # It's strongly recommended that you check this file into your version control system.
13 |
14 | ActiveRecord::Schema.define(version: 20141206230010) do
15 |
16 | # These are extensions that must be enabled in order to support this database
17 | enable_extension "plpgsql"
18 |
19 | create_table "movie_manager_movies", force: true do |t|
20 | t.string "title", null: false
21 | t.string "director"
22 | t.datetime "created_at"
23 | t.datetime "updated_at"
24 | end
25 |
26 | end
27 |
--------------------------------------------------------------------------------
/db/seeds.rb:
--------------------------------------------------------------------------------
1 | [
2 | { title: "Seven Samurai", director: "Akira Kurozawa" },
3 | { title: "Dune", director: "Alan Smithee" },
4 | { title: "2001", director: "Stanley Kubrick" }
5 | ].each do |movie_info|
6 | MovieManager::MovieRepo.persist(title: movie_info[:title],
7 | director: movie_info[:director])
8 | end
9 |
--------------------------------------------------------------------------------
/deploy_app.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set -x -e
4 |
5 | echo "Pushing to heroku acceptance environment"
6 | git push git@heroku.com:json-rails-acceptance.git master
7 |
8 | echo "Migrating acceptance database"
9 | heroku run rake db:migrate --app json-rails-acceptance
10 |
11 | echo "Restarting app"
12 | heroku restart --app json-rails-acceptance
13 |
--------------------------------------------------------------------------------