refinerycms-api 1.0.0.beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.rbenv-gemsets +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +12 -0
- data/Gemfile +57 -0
- data/LICENSE +27 -0
- data/Rakefile +21 -0
- data/app/controllers/refinery/api/base_controller.rb +174 -0
- data/app/controllers/refinery/api/v1/blog/posts_controller.rb +78 -0
- data/app/controllers/refinery/api/v1/images_controller.rb +76 -0
- data/app/controllers/refinery/api/v1/inquiries/inquiries_controller.rb +69 -0
- data/app/controllers/refinery/api/v1/pages_controller.rb +77 -0
- data/app/controllers/refinery/api/v1/resources_controller.rb +66 -0
- data/app/decorators/models/refinery/authentication/devise/user_decorator.rb +5 -0
- data/app/helpers/refinery/api/api_helpers.rb +54 -0
- data/app/models/concerns/refinery/user_api_authentication.rb +19 -0
- data/app/models/refinery/ability.rb +59 -0
- data/app/views/refinery/api/errors/gateway_error.v1.rabl +2 -0
- data/app/views/refinery/api/errors/invalid_api_key.v1.rabl +2 -0
- data/app/views/refinery/api/errors/invalid_resource.v1.rabl +3 -0
- data/app/views/refinery/api/errors/must_specify_api_key.v1.rabl +2 -0
- data/app/views/refinery/api/errors/not_found.v1.rabl +2 -0
- data/app/views/refinery/api/errors/unauthorized.v1.rabl +2 -0
- data/app/views/refinery/api/v1/blog/posts/index.v1.rabl +5 -0
- data/app/views/refinery/api/v1/blog/posts/new.v1.rabl +3 -0
- data/app/views/refinery/api/v1/blog/posts/show.v1.rabl +5 -0
- data/app/views/refinery/api/v1/images/index.v1.rabl +5 -0
- data/app/views/refinery/api/v1/images/new.v1.rabl +3 -0
- data/app/views/refinery/api/v1/images/show.v1.rabl +6 -0
- data/app/views/refinery/api/v1/inquiries/inquiries/index.v1.rabl +5 -0
- data/app/views/refinery/api/v1/inquiries/inquiries/new.v1.rabl +3 -0
- data/app/views/refinery/api/v1/inquiries/inquiries/show.v1.rabl +5 -0
- data/app/views/refinery/api/v1/pages/index.v1.rabl +8 -0
- data/app/views/refinery/api/v1/pages/new.v1.rabl +3 -0
- data/app/views/refinery/api/v1/pages/pages.v1.rabl +5 -0
- data/app/views/refinery/api/v1/pages/show.v1.rabl +9 -0
- data/app/views/refinery/api/v1/resources/index.v1.rabl +5 -0
- data/app/views/refinery/api/v1/resources/new.v1.rabl +3 -0
- data/app/views/refinery/api/v1/resources/show.v1.rabl +6 -0
- data/bin/rails +5 -0
- data/bin/rake +21 -0
- data/bin/rspec +22 -0
- data/bin/spring +18 -0
- data/config/initializers/metal_load_paths.rb +1 -0
- data/config/locales/en.yml +27 -0
- data/config/routes.rb +24 -0
- data/db/migrate/20160501141738_add_api_key_to_refinery_authentication_devise_users.rb +8 -0
- data/lib/generators/refinery/api/api_generator.rb +16 -0
- data/lib/generators/refinery/api/templates/config/initializers/refinery/api.rb.erb +7 -0
- data/lib/refinery/api.rb +29 -0
- data/lib/refinery/api/configuration.rb +32 -0
- data/lib/refinery/api/controller_helpers/auth.rb +76 -0
- data/lib/refinery/api/controller_helpers/strong_parameters.rb +37 -0
- data/lib/refinery/api/controller_setup.rb +20 -0
- data/lib/refinery/api/engine.rb +52 -0
- data/lib/refinery/api/responders.rb +11 -0
- data/lib/refinery/api/responders/rabl_template.rb +30 -0
- data/lib/refinery/api/testing_support/caching.rb +10 -0
- data/lib/refinery/api/testing_support/helpers.rb +44 -0
- data/lib/refinery/api/testing_support/setup.rb +16 -0
- data/lib/refinery/permitted_attributes.rb +40 -0
- data/lib/refinery/responder.rb +45 -0
- data/lib/refinerycms-api.rb +3 -0
- data/readme.md +69 -0
- data/refinerycms_api.gemspec +22 -0
- data/script/rails +9 -0
- data/spec/controllers/refinery/api/base_controller_spec.rb +73 -0
- data/spec/controllers/refinery/api/v1/blog/posts_controller_spec.rb +140 -0
- data/spec/controllers/refinery/api/v1/images_controller_spec.rb +93 -0
- data/spec/controllers/refinery/api/v1/inquiries/inquiries_controller_spec.rb +126 -0
- data/spec/controllers/refinery/api/v1/pages_controller_spec.rb +150 -0
- data/spec/controllers/refinery/api/v1/resources_controller_spec.rb +94 -0
- data/spec/fixtures/refinery_is_awesome.txt +1 -0
- data/spec/fixtures/thinking-cat.jpg +0 -0
- data/spec/models/refinery/user_spec.rb +23 -0
- data/spec/requests/rabl_cache_spec.rb +17 -0
- data/spec/requests/ransackable_attributes_spec.rb +80 -0
- data/spec/requests/version_spec.rb +23 -0
- data/spec/shared_examples/protect_product_actions.rb +17 -0
- data/spec/spec_helper.rb +77 -0
- data/spec/support/controller_hacks.rb +33 -0
- data/spec/support/database_cleaner.rb +14 -0
- data/spec/support/have_attributes_matcher.rb +9 -0
- data/tasks/refinery_api.rake +14 -0
- data/tasks/rspec.rake +4 -0
- metadata +240 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Refinery
|
|
2
|
+
module Api
|
|
3
|
+
module Responders
|
|
4
|
+
module RablTemplate
|
|
5
|
+
def to_format
|
|
6
|
+
if template
|
|
7
|
+
render template, :status => options[:status] || 200
|
|
8
|
+
else
|
|
9
|
+
super
|
|
10
|
+
end
|
|
11
|
+
rescue ActionView::MissingTemplate => e
|
|
12
|
+
api_behavior
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def template
|
|
16
|
+
options[:default_template]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def api_behavior
|
|
20
|
+
if controller.params[:action] == "destroy"
|
|
21
|
+
# Render a blank template
|
|
22
|
+
super
|
|
23
|
+
else
|
|
24
|
+
# Do nothing and fallback to the default template
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module Refinery
|
|
2
|
+
module Api
|
|
3
|
+
module TestingSupport
|
|
4
|
+
module Helpers
|
|
5
|
+
def json_response
|
|
6
|
+
case body = JSON.parse(response.body)
|
|
7
|
+
when Hash
|
|
8
|
+
body.with_indifferent_access
|
|
9
|
+
when Array
|
|
10
|
+
body
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def assert_not_found!
|
|
15
|
+
expect(json_response).to eq({ "error" => "The resource you were looking for could not be found." })
|
|
16
|
+
expect(response.status).to eq 404
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def assert_unauthorized!
|
|
20
|
+
expect(json_response).to eq({ "error" => "You are not authorized to perform that action." })
|
|
21
|
+
expect(response.status).to eq 401
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def stub_authentication!
|
|
25
|
+
allow(Refinery::Api.user_class).to receive(:find_by).with(hash_including(:refinery_api_key)) { current_api_user }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# This method can be overriden (with a let block) inside a context
|
|
29
|
+
# For instance, if you wanted to have an admin user instead.
|
|
30
|
+
def current_api_user
|
|
31
|
+
@current_api_user ||= stub_model(Refinery::Api.user_class, email: "refinery@example.com")
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def file_path(filename)
|
|
35
|
+
File.open(Refinery::Api::Engine.root + "spec/fixtures" + filename)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def upload_file(filename, mime_type)
|
|
39
|
+
fixture_file_upload(file_path(filename).path, mime_type)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Refinery
|
|
2
|
+
module Api
|
|
3
|
+
module TestingSupport
|
|
4
|
+
module Setup
|
|
5
|
+
def sign_in_as_admin!
|
|
6
|
+
let!(:current_api_user) do
|
|
7
|
+
user = stub_model(Refinery::Api.user_class)
|
|
8
|
+
allow(user).to receive_message_chain(:roles, :pluck).and_return(["superuser"])
|
|
9
|
+
allow(user).to receive(:has_role?).with("superuser").and_return(true)
|
|
10
|
+
user
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Refinery
|
|
2
|
+
module PermittedAttributes
|
|
3
|
+
ATTRIBUTES = [
|
|
4
|
+
:image_attributes,
|
|
5
|
+
:page_attributes,
|
|
6
|
+
:page_part_attributes,
|
|
7
|
+
:resource_attributes,
|
|
8
|
+
:blog_post_attributes,
|
|
9
|
+
:inquiries_inquiry_attributes
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
mattr_reader *ATTRIBUTES
|
|
13
|
+
|
|
14
|
+
@@image_attributes = [
|
|
15
|
+
{ image: [] }, :image_size, :image_title, :image_alt
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
@@page_attributes = [
|
|
19
|
+
:browser_title, :draft, :link_url, :menu_title, :meta_description,
|
|
20
|
+
:parent_id, :skip_to_first_child, :show_in_menu, :title, :view_template,
|
|
21
|
+
:layout_template, :custom_slug, parts_attributes: [:id, :title, :slug, :body, :position]
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
@@page_part_attributes = [
|
|
25
|
+
:title, :slug, :body, :locale
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
@@resource_attributes = [
|
|
29
|
+
:resource_title, { file: [] }
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
@@blog_post_attributes = [
|
|
33
|
+
:title, :body, :custom_teaser, :tag_list,
|
|
34
|
+
:draft, :published_at, :custom_url, :user_id, :username, :browser_title,
|
|
35
|
+
:meta_description, :source_url, :source_url_title, category_ids: []
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
@@inquiries_inquiry_attributes = [:name, :phone, :message, :email]
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module Refinery
|
|
2
|
+
class Responder < ::ActionController::Responder #:nodoc:
|
|
3
|
+
|
|
4
|
+
attr_accessor :on_success, :on_failure
|
|
5
|
+
|
|
6
|
+
def initialize(controller, resources, options={})
|
|
7
|
+
super
|
|
8
|
+
|
|
9
|
+
class_name = controller.class.name.to_sym
|
|
10
|
+
action_name = options.delete(:action_name)
|
|
11
|
+
|
|
12
|
+
if result = Refinery::BaseController.refinery_responders[class_name].try(:[], action_name).try(:[], self.format.to_sym)
|
|
13
|
+
self.on_success = handler(controller, result, :success)
|
|
14
|
+
self.on_failure = handler(controller, result, :failure)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def to_html
|
|
19
|
+
super and return if !(on_success || on_failure)
|
|
20
|
+
has_errors? ? controller.instance_exec(&on_failure) : controller.instance_exec(&on_success)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def to_format
|
|
24
|
+
super and return if !(on_success || on_failure)
|
|
25
|
+
has_errors? ? controller.instance_exec(&on_failure) : controller.instance_exec(&on_success)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def handler(controller, result, status)
|
|
31
|
+
return result if result.respond_to? :call
|
|
32
|
+
|
|
33
|
+
case result
|
|
34
|
+
when Hash
|
|
35
|
+
if result[status].is_a? Symbol
|
|
36
|
+
controller.method(result[status])
|
|
37
|
+
else
|
|
38
|
+
result[status]
|
|
39
|
+
end
|
|
40
|
+
when Symbol
|
|
41
|
+
controller.method(result)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
data/readme.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Refinery CMS Api
|
|
2
|
+
|
|
3
|
+
[](https://travis-ci.org/refinerycms-contrib/refinerycms-api)
|
|
4
|
+
|
|
5
|
+
This extension allows you to use a Rest API with Refinery CMS 3.0 and later.
|
|
6
|
+
|
|
7
|
+
## TODO
|
|
8
|
+
* [ ] Check Abilities
|
|
9
|
+
* [ ] Fix specs
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
Simply put this in the Gemfile of your Refinery application:
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
gem 'refinerycms-api', github: 'refinerycms-contrib/refinerycms-api', master: 'branch'
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Then run `bundle install` to install it.
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Generate and run migrations
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
$ rails g refinery:api # Generate initializer
|
|
26
|
+
$ rake db:migrate
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Then restart your server.
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
### Create an API Token for your user
|
|
34
|
+
|
|
35
|
+
```ruby
|
|
36
|
+
$ rake refinery_api:user:api_token:generate EMAIL=refinery@example.org
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Pages
|
|
40
|
+
|
|
41
|
+
```ruby
|
|
42
|
+
$ curl --header "X-Refinery-Token: YOUR_API_TOKEN" http://localhost:3000/api/v1/pages
|
|
43
|
+
$ curl --header "X-Refinery-Token: YOUR_API_TOKEN" http://localhost:3000/api/v1/pages/1
|
|
44
|
+
$ curl --header "X-Refinery-Token: YOUR_API_TOKEN" http://localhost:3000/api/v1/pages/new
|
|
45
|
+
|
|
46
|
+
$ curl -X POST --header "X-Refinery-Token: YOUR_API_TOKEN" "http://localhost:3000/api/v1/pages" -d 'page[title]=test'
|
|
47
|
+
$ curl -X PUT --header "X-Refinery-Token: YOUR_API_TOKEN" "http://localhost:3000/api/v1/pages/1" -d 'page[title]=test2'
|
|
48
|
+
$ curl -X DELETE -H "X-Refinery-Token: YOUR_API_TOKEN" http://localhost:3000/api/v1/pages/1
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Images
|
|
52
|
+
|
|
53
|
+
```ruby
|
|
54
|
+
$ curl --header "X-Refinery-Token: YOUR_API_TOKEN" http://localhost:3000/api/v1/images
|
|
55
|
+
$ curl --header "X-Refinery-Token: YOUR_API_TOKEN" http://localhost:3000/api/v1/images/1
|
|
56
|
+
$ curl --header "X-Refinery-Token: YOUR_API_TOKEN" http://localhost:3000/api/v1/images/new
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Resources
|
|
60
|
+
|
|
61
|
+
```ruby
|
|
62
|
+
$ curl --header "X-Refinery-Token: YOUR_API_TOKEN" http://localhost:3000/api/v1/resources
|
|
63
|
+
$ curl --header "X-Refinery-Token: YOUR_API_TOKEN" http://localhost:3000/api/v1/resources/1
|
|
64
|
+
$ curl --header "X-Refinery-Token: YOUR_API_TOKEN" http://localhost:3000/api/v1/resources/new
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Contributing
|
|
68
|
+
|
|
69
|
+
Please see the [contributing.md](contributing.md) file for instructions.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Encoding: UTF-8
|
|
2
|
+
Gem::Specification.new do |s|
|
|
3
|
+
s.authors = ["Brice Sanchez", "Ryan Bigg"]
|
|
4
|
+
s.description = %q{Refinery CMS's API}
|
|
5
|
+
s.summary = %q{Refinery CMS's API}
|
|
6
|
+
s.homepage = 'http://www.refinerycms.com'
|
|
7
|
+
s.license = 'BSD-3'
|
|
8
|
+
|
|
9
|
+
s.files = `git ls-files`.split($\)
|
|
10
|
+
s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
11
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
|
12
|
+
s.name = %q{refinerycms-api}
|
|
13
|
+
s.require_paths = ["lib"]
|
|
14
|
+
s.version = %q{1.0.0.beta}
|
|
15
|
+
|
|
16
|
+
s.add_dependency 'refinerycms-core', ['~> 3.0', '>= 3.0.0']
|
|
17
|
+
s.add_dependency 'cancancan', '~> 1.10.1'
|
|
18
|
+
s.add_dependency 'decorators', '~> 2.0'
|
|
19
|
+
s.add_dependency 'rabl', '~> 0.12.0'
|
|
20
|
+
s.add_dependency 'versioncake', '~> 2.3.1'
|
|
21
|
+
s.add_dependency 'responders'
|
|
22
|
+
end
|
data/script/rails
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
|
3
|
+
|
|
4
|
+
ENGINE_ROOT = File.expand_path('../..', __FILE__)
|
|
5
|
+
ENGINE_PATH = File.expand_path('../../lib/refinery/api/engine', __FILE__)
|
|
6
|
+
|
|
7
|
+
require 'rails/all'
|
|
8
|
+
require 'rails/engine/commands'
|
|
9
|
+
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
class FakesController < Refinery::Api::BaseController
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
describe Refinery::Api::BaseController, type: :controller do
|
|
7
|
+
render_views
|
|
8
|
+
controller(Refinery::Api::BaseController) do
|
|
9
|
+
def index
|
|
10
|
+
render text: { "pages": [] }.to_json
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
before do
|
|
15
|
+
@routes = ActionDispatch::Routing::RouteSet.new.tap do |r|
|
|
16
|
+
r.draw { get 'index', to: 'refinery/api/base#index' }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context "cannot make a request to the API" do
|
|
21
|
+
it "without an API key" do
|
|
22
|
+
api_get :index
|
|
23
|
+
expect(json_response).to eq({ "error" => "You must specify an API key." })
|
|
24
|
+
expect(response.status).to eq(401)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "with an invalid API key" do
|
|
28
|
+
request.headers["X-Refinery-Token"] = "fake_key"
|
|
29
|
+
get :index, {}
|
|
30
|
+
expect(json_response).to eq({ "error" => "Invalid API key (fake_key) specified." })
|
|
31
|
+
expect(response.status).to eq(401)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "using an invalid token param" do
|
|
35
|
+
get :index, token: "fake_key"
|
|
36
|
+
expect(json_response).to eq({ "error" => "Invalid API key (fake_key) specified." })
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'handles parameter missing exceptions' do
|
|
41
|
+
expect(subject).to receive(:authenticate_user).and_return(true)
|
|
42
|
+
expect(subject).to receive(:load_user_roles).and_return(true)
|
|
43
|
+
expect(subject).to receive(:index).and_raise(ActionController::ParameterMissing.new('foo'))
|
|
44
|
+
get :index, token: 'exception-message'
|
|
45
|
+
expect(json_response).to eql('exception' => 'param is missing or the value is empty: foo')
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'handles record invalid exceptions' do
|
|
49
|
+
expect(subject).to receive(:authenticate_user).and_return(true)
|
|
50
|
+
expect(subject).to receive(:load_user_roles).and_return(true)
|
|
51
|
+
resource = Refinery::Page.new
|
|
52
|
+
resource.valid? # get some errors
|
|
53
|
+
expect(subject).to receive(:index).and_raise(ActiveRecord::RecordInvalid.new(resource))
|
|
54
|
+
get :index, token: 'exception-message'
|
|
55
|
+
expect(json_response).to eql('exception' => "Validation failed: Title can't be blank")
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "maps semantic keys to nested_attributes keys" do
|
|
59
|
+
klass = double(nested_attributes_options: { line_items: {},
|
|
60
|
+
bill_address: {} })
|
|
61
|
+
attributes = { 'line_items': { id: 1 },
|
|
62
|
+
'bill_address': { id: 2 },
|
|
63
|
+
'name': 'test order' }
|
|
64
|
+
|
|
65
|
+
mapped = subject.map_nested_attributes_keys(klass, attributes)
|
|
66
|
+
expect(mapped.has_key?('line_items_attributes')).to be true
|
|
67
|
+
expect(mapped.has_key?('name')).to be true
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "lets a subclass override the product associations that are eager-loaded" do
|
|
71
|
+
expect(controller.respond_to?(:product_includes, true)).to be
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Refinery
|
|
4
|
+
describe Api::V1::Blog::PostsController, type: :controller do
|
|
5
|
+
render_views
|
|
6
|
+
|
|
7
|
+
let!(:post) { FactoryGirl.create(:blog_post, :title => "Ruby") }
|
|
8
|
+
|
|
9
|
+
let!(:attributes_new) { [ "title", "body", "custom_teaser", "tag_list", "draft", "published_at", "custom_url", "user_id", "username", "browser_title", "meta_description", "source_url", "source_url_title", {"category_ids"=>[]} ] }
|
|
10
|
+
let!(:attributes) { [ "title", "body", "custom_teaser", "tag_list", "draft", "published_at", "custom_url", "user_id", "username", "browser_title", "meta_description", "source_url", "source_url_title", "category_ids" ] }
|
|
11
|
+
|
|
12
|
+
before do
|
|
13
|
+
stub_authentication!
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
context "as a normal user" do
|
|
17
|
+
it "can get a list of blog posts" do
|
|
18
|
+
api_get :index
|
|
19
|
+
|
|
20
|
+
expect(response.status).to eq(200)
|
|
21
|
+
expect(json_response).to have_key("posts")
|
|
22
|
+
attributes.delete("category_ids")
|
|
23
|
+
expect(json_response["posts"].first.keys).to eq(attributes)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# it "paginates through taxons" do
|
|
27
|
+
# new_taxon = create(:taxon, :name => "Go", :taxonomy => taxonomy)
|
|
28
|
+
# taxonomy.root.children << new_taxon
|
|
29
|
+
# expect(taxonomy.root.children.count).to eql(2)
|
|
30
|
+
# api_get :index, :taxonomy_id => taxonomy.id, :page => 1, :per_page => 1
|
|
31
|
+
# expect(json_response["count"]).to eql(1)
|
|
32
|
+
# expect(json_response["total_count"]).to eql(2)
|
|
33
|
+
# expect(json_response["current_page"]).to eql(1)
|
|
34
|
+
# expect(json_response["per_page"]).to eql(1)
|
|
35
|
+
# expect(json_response["pages"]).to eql(2)
|
|
36
|
+
# end
|
|
37
|
+
|
|
38
|
+
# describe 'searching' do
|
|
39
|
+
# context 'with a name' do
|
|
40
|
+
# before do
|
|
41
|
+
# api_get :index, :q => { :name_cont => name }
|
|
42
|
+
# end
|
|
43
|
+
|
|
44
|
+
# context 'with one result' do
|
|
45
|
+
# let(:name) { "Ruby" }
|
|
46
|
+
|
|
47
|
+
# it "returns an array including the matching taxon" do
|
|
48
|
+
# expect(json_response['taxons'].count).to eq(1)
|
|
49
|
+
# expect(json_response['taxons'].first['name']).to eq "Ruby"
|
|
50
|
+
# end
|
|
51
|
+
# end
|
|
52
|
+
|
|
53
|
+
# context 'with no results' do
|
|
54
|
+
# let(:name) { "Imaginary" }
|
|
55
|
+
|
|
56
|
+
# it 'returns an empty array of taxons' do
|
|
57
|
+
# expect(json_response.keys).to include('taxons')
|
|
58
|
+
# expect(json_response['taxons'].count).to eq(0)
|
|
59
|
+
# end
|
|
60
|
+
# end
|
|
61
|
+
# end
|
|
62
|
+
|
|
63
|
+
# context 'with no filters' do
|
|
64
|
+
# it "gets all taxons" do
|
|
65
|
+
# api_get :index
|
|
66
|
+
|
|
67
|
+
# expect(json_response['taxons'].first['name']).to eq taxonomy.root.name
|
|
68
|
+
# children = json_response['taxons'].first['taxons']
|
|
69
|
+
# expect(children.count).to eq 1
|
|
70
|
+
# expect(children.first['name']).to eq taxon.name
|
|
71
|
+
# expect(children.first['taxons'].count).to eq 1
|
|
72
|
+
# end
|
|
73
|
+
# end
|
|
74
|
+
# end
|
|
75
|
+
|
|
76
|
+
it "gets a single blog post" do
|
|
77
|
+
api_get :show, id: post.id
|
|
78
|
+
|
|
79
|
+
expect(json_response['title']).to eq post.title
|
|
80
|
+
expect(json_response['posts']).to be_nil
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it "can learn how to create a new blog post" do
|
|
84
|
+
api_get :new
|
|
85
|
+
expect(json_response["attributes"]).to eq(attributes_new)
|
|
86
|
+
required_attributes = json_response["required_attributes"]
|
|
87
|
+
expect(required_attributes).to include("title")
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it "cannot create a new blog post if not an admin" do
|
|
91
|
+
api_post :create, blog_post: { title: "Location" }
|
|
92
|
+
assert_unauthorized!
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it "cannot update a blog post" do
|
|
96
|
+
api_put :update, id: post.id, post: { title: "I hacked your website!" }
|
|
97
|
+
assert_unauthorized!
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it "cannot delete a blog post" do
|
|
101
|
+
api_delete :destroy, id: post.id
|
|
102
|
+
assert_unauthorized!
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
context "as an admin" do
|
|
107
|
+
sign_in_as_admin!
|
|
108
|
+
|
|
109
|
+
it "can create" do
|
|
110
|
+
expect do
|
|
111
|
+
api_post :create, post: { title: "Colors", body: "Colors of life", published_at: Time.now, username: "John Doe" }
|
|
112
|
+
attributes.delete("category_ids")
|
|
113
|
+
expect(json_response.keys).to eq(attributes)
|
|
114
|
+
expect(response.status).to eq(201)
|
|
115
|
+
end.to change(Blog::Post, :count).by(1)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it "can update the title" do
|
|
119
|
+
api_put :update, id: post.id, post: { title: "I update your website!" }
|
|
120
|
+
expect(response.status).to eq(200)
|
|
121
|
+
expect(Blog::Post.last.title).to eql "I update your website!"
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it "cannot create a new blog post with invalid attributes" do
|
|
125
|
+
api_post :create, post: {}
|
|
126
|
+
expect(response.status).to eq(422)
|
|
127
|
+
expect(json_response["error"]).to eq("Invalid resource. Please fix errors and try again.")
|
|
128
|
+
errors = json_response["errors"]
|
|
129
|
+
|
|
130
|
+
expect(Blog::Post.count).to eq 1
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "can destroy" do
|
|
134
|
+
api_delete :destroy, :id => post.id
|
|
135
|
+
expect(response.status).to eq(204)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
end
|
|
140
|
+
end
|