refinerycms-api 1.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rbenv-gemsets +1 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +12 -0
  6. data/Gemfile +57 -0
  7. data/LICENSE +27 -0
  8. data/Rakefile +21 -0
  9. data/app/controllers/refinery/api/base_controller.rb +174 -0
  10. data/app/controllers/refinery/api/v1/blog/posts_controller.rb +78 -0
  11. data/app/controllers/refinery/api/v1/images_controller.rb +76 -0
  12. data/app/controllers/refinery/api/v1/inquiries/inquiries_controller.rb +69 -0
  13. data/app/controllers/refinery/api/v1/pages_controller.rb +77 -0
  14. data/app/controllers/refinery/api/v1/resources_controller.rb +66 -0
  15. data/app/decorators/models/refinery/authentication/devise/user_decorator.rb +5 -0
  16. data/app/helpers/refinery/api/api_helpers.rb +54 -0
  17. data/app/models/concerns/refinery/user_api_authentication.rb +19 -0
  18. data/app/models/refinery/ability.rb +59 -0
  19. data/app/views/refinery/api/errors/gateway_error.v1.rabl +2 -0
  20. data/app/views/refinery/api/errors/invalid_api_key.v1.rabl +2 -0
  21. data/app/views/refinery/api/errors/invalid_resource.v1.rabl +3 -0
  22. data/app/views/refinery/api/errors/must_specify_api_key.v1.rabl +2 -0
  23. data/app/views/refinery/api/errors/not_found.v1.rabl +2 -0
  24. data/app/views/refinery/api/errors/unauthorized.v1.rabl +2 -0
  25. data/app/views/refinery/api/v1/blog/posts/index.v1.rabl +5 -0
  26. data/app/views/refinery/api/v1/blog/posts/new.v1.rabl +3 -0
  27. data/app/views/refinery/api/v1/blog/posts/show.v1.rabl +5 -0
  28. data/app/views/refinery/api/v1/images/index.v1.rabl +5 -0
  29. data/app/views/refinery/api/v1/images/new.v1.rabl +3 -0
  30. data/app/views/refinery/api/v1/images/show.v1.rabl +6 -0
  31. data/app/views/refinery/api/v1/inquiries/inquiries/index.v1.rabl +5 -0
  32. data/app/views/refinery/api/v1/inquiries/inquiries/new.v1.rabl +3 -0
  33. data/app/views/refinery/api/v1/inquiries/inquiries/show.v1.rabl +5 -0
  34. data/app/views/refinery/api/v1/pages/index.v1.rabl +8 -0
  35. data/app/views/refinery/api/v1/pages/new.v1.rabl +3 -0
  36. data/app/views/refinery/api/v1/pages/pages.v1.rabl +5 -0
  37. data/app/views/refinery/api/v1/pages/show.v1.rabl +9 -0
  38. data/app/views/refinery/api/v1/resources/index.v1.rabl +5 -0
  39. data/app/views/refinery/api/v1/resources/new.v1.rabl +3 -0
  40. data/app/views/refinery/api/v1/resources/show.v1.rabl +6 -0
  41. data/bin/rails +5 -0
  42. data/bin/rake +21 -0
  43. data/bin/rspec +22 -0
  44. data/bin/spring +18 -0
  45. data/config/initializers/metal_load_paths.rb +1 -0
  46. data/config/locales/en.yml +27 -0
  47. data/config/routes.rb +24 -0
  48. data/db/migrate/20160501141738_add_api_key_to_refinery_authentication_devise_users.rb +8 -0
  49. data/lib/generators/refinery/api/api_generator.rb +16 -0
  50. data/lib/generators/refinery/api/templates/config/initializers/refinery/api.rb.erb +7 -0
  51. data/lib/refinery/api.rb +29 -0
  52. data/lib/refinery/api/configuration.rb +32 -0
  53. data/lib/refinery/api/controller_helpers/auth.rb +76 -0
  54. data/lib/refinery/api/controller_helpers/strong_parameters.rb +37 -0
  55. data/lib/refinery/api/controller_setup.rb +20 -0
  56. data/lib/refinery/api/engine.rb +52 -0
  57. data/lib/refinery/api/responders.rb +11 -0
  58. data/lib/refinery/api/responders/rabl_template.rb +30 -0
  59. data/lib/refinery/api/testing_support/caching.rb +10 -0
  60. data/lib/refinery/api/testing_support/helpers.rb +44 -0
  61. data/lib/refinery/api/testing_support/setup.rb +16 -0
  62. data/lib/refinery/permitted_attributes.rb +40 -0
  63. data/lib/refinery/responder.rb +45 -0
  64. data/lib/refinerycms-api.rb +3 -0
  65. data/readme.md +69 -0
  66. data/refinerycms_api.gemspec +22 -0
  67. data/script/rails +9 -0
  68. data/spec/controllers/refinery/api/base_controller_spec.rb +73 -0
  69. data/spec/controllers/refinery/api/v1/blog/posts_controller_spec.rb +140 -0
  70. data/spec/controllers/refinery/api/v1/images_controller_spec.rb +93 -0
  71. data/spec/controllers/refinery/api/v1/inquiries/inquiries_controller_spec.rb +126 -0
  72. data/spec/controllers/refinery/api/v1/pages_controller_spec.rb +150 -0
  73. data/spec/controllers/refinery/api/v1/resources_controller_spec.rb +94 -0
  74. data/spec/fixtures/refinery_is_awesome.txt +1 -0
  75. data/spec/fixtures/thinking-cat.jpg +0 -0
  76. data/spec/models/refinery/user_spec.rb +23 -0
  77. data/spec/requests/rabl_cache_spec.rb +17 -0
  78. data/spec/requests/ransackable_attributes_spec.rb +80 -0
  79. data/spec/requests/version_spec.rb +23 -0
  80. data/spec/shared_examples/protect_product_actions.rb +17 -0
  81. data/spec/spec_helper.rb +77 -0
  82. data/spec/support/controller_hacks.rb +33 -0
  83. data/spec/support/database_cleaner.rb +14 -0
  84. data/spec/support/have_attributes_matcher.rb +9 -0
  85. data/tasks/refinery_api.rake +14 -0
  86. data/tasks/rspec.rake +4 -0
  87. metadata +240 -0
@@ -0,0 +1,93 @@
1
+ require 'spec_helper'
2
+
3
+ module Refinery
4
+ describe Api::V1::ImagesController, type: :controller do
5
+ render_views
6
+
7
+ let!(:attributes_new) { [ { "image" => [] }, "image_size", "image_title", "image_alt" ] }
8
+ let!(:attributes) { [ "image", "image_size", "image_title", "image_alt" ] }
9
+
10
+ before do
11
+ stub_authentication!
12
+ end
13
+
14
+ context "as an admin" do
15
+ sign_in_as_admin!
16
+
17
+ it "can learn how to create a new image" do
18
+ api_get :new
19
+ expect(json_response["attributes"]).to eq(attributes_new)
20
+ required_attributes = json_response["required_attributes"]
21
+ expect(required_attributes).to include("image")
22
+ end
23
+
24
+ it "can upload a new image" do
25
+ expect do
26
+ api_post :create, image: { image: [upload_file('thinking-cat.jpg', 'image/jpg')] }
27
+ expect(response.status).to eq(201)
28
+ expect(json_response).to have_attributes(attributes)
29
+ end.to change(Image, :count).by(1)
30
+ end
31
+
32
+ it "can't upload a new image without attachment" do
33
+ api_post :create, image: {}
34
+ expect(response.status).to eq(422)
35
+ end
36
+
37
+ context "working with an existing image" do
38
+ let!(:image) { FactoryGirl.create(:image) }
39
+
40
+ it "can get a single image" do
41
+ api_get :show, id: image.id
42
+ expect(response.status).to eq(200)
43
+ expect(json_response).to have_attributes(attributes)
44
+ end
45
+
46
+ it "can get a list of images" do
47
+ api_get :index
48
+ expect(response.status).to eq(200)
49
+ expect(json_response).to have_key("images")
50
+ expect(json_response["images"].first).to have_attributes(attributes)
51
+ end
52
+
53
+ it "can update image data" do
54
+ expect(image.image_title).to eq(nil)
55
+ api_post :update, image: { image_title: "test" }, id: image.id
56
+ expect(response.status).to eq(200)
57
+ expect(json_response).to have_attributes(attributes)
58
+ expect(image.reload.image_title).to eq('test')
59
+ end
60
+
61
+ it "can't update a image without attachment" do
62
+ api_post :update,
63
+ image: {},
64
+ id: image.id
65
+ expect(response.status).to eq(422)
66
+ end
67
+
68
+ it "can delete an image" do
69
+ api_delete :destroy, id: image.id
70
+ expect(response.status).to eq(204)
71
+ expect { image.reload }.to raise_error(ActiveRecord::RecordNotFound)
72
+ end
73
+ end
74
+ end
75
+
76
+ context "as a non-admin" do
77
+ it "cannot create an image" do
78
+ api_post :create
79
+ assert_unauthorized!
80
+ end
81
+
82
+ it "cannot update an image" do
83
+ api_put :update, id: 1
84
+ assert_not_found!
85
+ end
86
+
87
+ it "cannot delete an image" do
88
+ api_delete :destroy, id: 1
89
+ assert_not_found!
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,126 @@
1
+ require 'spec_helper'
2
+
3
+ module Refinery
4
+ describe Api::V1::Inquiries::InquiriesController, type: :controller do
5
+ render_views
6
+
7
+ let!(:inquiry) { FactoryGirl.create(:inquiry) }
8
+
9
+ let!(:attributes) { [ "name", "phone", "message", "email"] }
10
+
11
+ before do
12
+ stub_authentication!
13
+ end
14
+
15
+ context "as a normal user" do
16
+ it "can get a list of inquiries" do
17
+ api_get :index
18
+
19
+ expect(response.status).to eq(200)
20
+ expect(json_response).to have_key("inquiries")
21
+ expect(json_response["inquiries"].first.keys).to eq(attributes)
22
+ end
23
+
24
+ # it "paginates through taxons" do
25
+ # new_taxon = create(:taxon, :name => "Go", :taxonomy => taxonomy)
26
+ # taxonomy.root.children << new_taxon
27
+ # expect(taxonomy.root.children.count).to eql(2)
28
+ # api_get :index, :taxonomy_id => taxonomy.id, :page => 1, :per_page => 1
29
+ # expect(json_response["count"]).to eql(1)
30
+ # expect(json_response["total_count"]).to eql(2)
31
+ # expect(json_response["current_page"]).to eql(1)
32
+ # expect(json_response["per_page"]).to eql(1)
33
+ # expect(json_response["pages"]).to eql(2)
34
+ # end
35
+
36
+ # describe 'searching' do
37
+ # context 'with a name' do
38
+ # before do
39
+ # api_get :index, :q => { :name_cont => name }
40
+ # end
41
+
42
+ # context 'with one result' do
43
+ # let(:name) { "Ruby" }
44
+
45
+ # it "returns an array including the matching taxon" do
46
+ # expect(json_response['taxons'].count).to eq(1)
47
+ # expect(json_response['taxons'].first['name']).to eq "Ruby"
48
+ # end
49
+ # end
50
+
51
+ # context 'with no results' do
52
+ # let(:name) { "Imaginary" }
53
+
54
+ # it 'returns an empty array of taxons' do
55
+ # expect(json_response.keys).to include('taxons')
56
+ # expect(json_response['taxons'].count).to eq(0)
57
+ # end
58
+ # end
59
+ # end
60
+
61
+ # context 'with no filters' do
62
+ # it "gets all taxons" do
63
+ # api_get :index
64
+
65
+ # expect(json_response['taxons'].first['name']).to eq taxonomy.root.name
66
+ # children = json_response['taxons'].first['taxons']
67
+ # expect(children.count).to eq 1
68
+ # expect(children.first['name']).to eq taxon.name
69
+ # expect(children.first['taxons'].count).to eq 1
70
+ # end
71
+ # end
72
+ # end
73
+
74
+ it "gets a single inquiry" do
75
+ api_get :show, id: inquiry.id
76
+
77
+ expect(json_response['name']).to eq inquiry.name
78
+ expect(json_response['inquiries']).to be_nil
79
+ end
80
+
81
+ it "can learn how to create a new inquiry" do
82
+ api_get :new
83
+ expect(json_response["attributes"]).to eq(attributes)
84
+ required_attributes = json_response["required_attributes"]
85
+ expect(required_attributes).to include("name")
86
+ end
87
+
88
+ it "cannot create a new inquiry if not an admin" do
89
+ api_post :create, inquiry: { name: "John Doe", message: "Hello world!", email: "refinery@example.org" }
90
+ assert_unauthorized!
91
+ end
92
+
93
+ it "cannot delete a inquiry" do
94
+ api_delete :destroy, id: inquiry.id
95
+ assert_unauthorized!
96
+ end
97
+ end
98
+
99
+ context "as an admin" do
100
+ sign_in_as_admin!
101
+
102
+ it "can create" do
103
+ expect do
104
+ api_post :create, inquiry: { name: "John Doe", message: "Hello world!", email: "refinery@example.org" }
105
+ expect(json_response.keys).to eq(attributes)
106
+ expect(response.status).to eq(201)
107
+ end.to change(Inquiries::Inquiry, :count).by(1)
108
+ end
109
+
110
+ it "cannot create a new inquiry with invalid attributes" do
111
+ api_post :create, inquiry: {}
112
+ expect(response.status).to eq(422)
113
+ expect(json_response["error"]).to eq("Invalid resource. Please fix errors and try again.")
114
+ errors = json_response["errors"]
115
+
116
+ expect(Inquiries::Inquiry.count).to eq 1
117
+ end
118
+
119
+ it "can destroy" do
120
+ api_delete :destroy, :id => inquiry.id
121
+ expect(response.status).to eq(204)
122
+ end
123
+ end
124
+
125
+ end
126
+ end
@@ -0,0 +1,150 @@
1
+ require 'spec_helper'
2
+
3
+ module Refinery
4
+ describe Api::V1::PagesController, type: :controller do
5
+ render_views
6
+
7
+ let(:page) { FactoryGirl.create(:page, :title => "Ruby") }
8
+ let(:page2) { FactoryGirl.create(:page, :title => "Rails") }
9
+ let(:page_with_page_part) { FactoryGirl.create(:page_with_page_part) }
10
+ let(:attributes) { ["browser_title", "draft", "link_url", "menu_title", "meta_description", "parent_id", "skip_to_first_child", "show_in_menu", "title", "view_template", "layout_template", "custom_slug", {"parts_attributes"=>["id", "title", "slug", "body", "position"]}] }
11
+
12
+ before do
13
+ stub_authentication!
14
+ page2.children << create(:page, title: "3.2.2")
15
+ page.children << page2
16
+ end
17
+
18
+ context "as a normal user" do
19
+ it "gets all pages" do
20
+ api_get :index
21
+
22
+ expect(json_response['pages'].first['title']).to eq page.title
23
+ children = json_response['pages'].first['pages']
24
+ expect(children.count).to eq 1
25
+ expect(children.first['title']).to eq page2.title
26
+ expect(children.first['pages'].count).to eq 1
27
+ end
28
+
29
+ it "does not include children when asked not to" do
30
+ api_get :index, without_children: 1
31
+
32
+ expect(json_response['pages'].first['title']).to eq(page.title)
33
+ expect(json_response['pages'].first['pages']).to be_nil
34
+ end
35
+
36
+ # it "paginates through taxons" do
37
+ # new_taxon = create(:taxon, :name => "Go", :taxonomy => taxonomy)
38
+ # taxonomy.root.children << new_taxon
39
+ # expect(taxonomy.root.children.count).to eql(2)
40
+ # api_get :index, :taxonomy_id => taxonomy.id, :page => 1, :per_page => 1
41
+ # expect(json_response["count"]).to eql(1)
42
+ # expect(json_response["total_count"]).to eql(2)
43
+ # expect(json_response["current_page"]).to eql(1)
44
+ # expect(json_response["per_page"]).to eql(1)
45
+ # expect(json_response["pages"]).to eql(2)
46
+ # end
47
+
48
+ # describe 'searching' do
49
+ # context 'with a name' do
50
+ # before do
51
+ # api_get :index, :q => { :name_cont => name }
52
+ # end
53
+
54
+ # context 'with one result' do
55
+ # let(:name) { "Ruby" }
56
+
57
+ # it "returns an array including the matching taxon" do
58
+ # expect(json_response['taxons'].count).to eq(1)
59
+ # expect(json_response['taxons'].first['name']).to eq "Ruby"
60
+ # end
61
+ # end
62
+
63
+ # context 'with no results' do
64
+ # let(:name) { "Imaginary" }
65
+
66
+ # it 'returns an empty array of taxons' do
67
+ # expect(json_response.keys).to include('taxons')
68
+ # expect(json_response['taxons'].count).to eq(0)
69
+ # end
70
+ # end
71
+ # end
72
+
73
+ # context 'with no filters' do
74
+ # it "gets all taxons" do
75
+ # api_get :index
76
+
77
+ # expect(json_response['taxons'].first['name']).to eq taxonomy.root.name
78
+ # children = json_response['taxons'].first['taxons']
79
+ # expect(children.count).to eq 1
80
+ # expect(children.first['name']).to eq taxon.name
81
+ # expect(children.first['taxons'].count).to eq 1
82
+ # end
83
+ # end
84
+ # end
85
+
86
+ it "gets a single page" do
87
+ api_get :show, id: page.id
88
+
89
+ expect(json_response['title']).to eq page.title
90
+ expect(json_response['pages']).to be_nil
91
+ end
92
+
93
+ it "can learn how to create a new page" do
94
+ api_get :new
95
+ expect(json_response["attributes"]).to eq(attributes)
96
+ required_attributes = json_response["required_attributes"]
97
+ expect(required_attributes).to include("title")
98
+ end
99
+
100
+ it "cannot create a new page if not an admin" do
101
+ api_post :create, page: { title: "Location" }
102
+ assert_unauthorized!
103
+ end
104
+
105
+ it "cannot update a page" do
106
+ api_put :update, id: page.id, page: { title: "I hacked your website!" }
107
+ assert_unauthorized!
108
+ end
109
+
110
+ it "cannot delete a page" do
111
+ api_delete :destroy, id: page.id
112
+ assert_unauthorized!
113
+ end
114
+ end
115
+
116
+ context "as an admin" do
117
+ sign_in_as_admin!
118
+
119
+ it "can create" do
120
+ expect do
121
+ api_post :create, page: { title: "Colors" }
122
+ # expect(json_response).to have_attributes(attributes)
123
+ expect(response.status).to eq(201)
124
+ end.to change(Page, :count).by(1)
125
+ end
126
+
127
+ it "can update the position in the list" do
128
+ page.root.children << page2
129
+ api_put :update, id: page.id, page: { parent_id: page.parent_id, child_index: 2 }
130
+ expect(response.status).to eq(200)
131
+ expect(page.reload.root.children[0]).to eql page2
132
+ end
133
+
134
+ it "cannot create a new page with invalid attributes" do
135
+ api_post :create, page: {}
136
+ expect(response.status).to eq(422)
137
+ expect(json_response["error"]).to eq("Invalid resource. Please fix errors and try again.")
138
+ errors = json_response["errors"]
139
+
140
+ expect(page.reload.root.children.count).to eq 1
141
+ end
142
+
143
+ it "can destroy" do
144
+ api_delete :destroy, :id => page.id
145
+ expect(response.status).to eq(204)
146
+ end
147
+ end
148
+
149
+ end
150
+ end
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+
3
+ module Refinery
4
+ describe Api::V1::ResourcesController, type: :controller do
5
+ render_views
6
+
7
+ let!(:attributes_new) { [ "resource_title", { "file" => [] } ] }
8
+ let!(:attributes) { [ "resource_title", "file" ] }
9
+
10
+ before do
11
+ stub_authentication!
12
+ end
13
+
14
+ context "as an admin" do
15
+ sign_in_as_admin!
16
+
17
+ it "can learn how to create a new resource" do
18
+ api_get :new
19
+ expect(json_response["attributes"]).to eq(attributes_new)
20
+ required_attributes = json_response["required_attributes"]
21
+ expect(required_attributes).to include("file")
22
+ end
23
+
24
+ it "can upload a new resource" do
25
+ pending "TODO: Find why i can't upload a new resource by the Rest API"
26
+ expect do
27
+ api_post :create, resource: { file: [upload_file('refinery_is_awesome.txt', 'text/html')] }
28
+ expect(response.status).to eq(201)
29
+ expect(json_response).to have_attributes(attributes)
30
+ end.to change(Resource, :count).by(1)
31
+ end
32
+
33
+ it "can't upload a new resource without attachment" do
34
+ api_post :create, resource: {}
35
+ expect(response.status).to eq(422)
36
+ end
37
+
38
+ context "working with an existing resource" do
39
+ let!(:resource) { FactoryGirl.create(:resource) }
40
+
41
+ it "can get a single resource" do
42
+ api_get :show, id: resource.id
43
+ expect(response.status).to eq(200)
44
+ expect(json_response).to have_attributes(attributes)
45
+ end
46
+
47
+ it "can get a list of resources" do
48
+ api_get :index
49
+ expect(response.status).to eq(200)
50
+ expect(json_response).to have_key("resources")
51
+ expect(json_response["resources"].first).to have_attributes(attributes)
52
+ end
53
+
54
+ it "can update resource data" do
55
+ expect(resource.resource_title).to eq(nil)
56
+ api_post :update, resource: { resource_title: "test" }, id: resource.id
57
+ expect(response.status).to eq(200)
58
+ expect(json_response).to have_attributes(attributes)
59
+ expect(resource.reload.resource_title).to eq('test')
60
+ end
61
+
62
+ it "can't update a resource without attachment" do
63
+ api_post :update,
64
+ resource: nil,
65
+ id: resource.id
66
+ expect(response.status).to eq(422)
67
+ end
68
+
69
+ it "can delete an resource" do
70
+ api_delete :destroy, id: resource.id
71
+ expect(response.status).to eq(204)
72
+ expect { resource.reload }.to raise_error(ActiveRecord::RecordNotFound)
73
+ end
74
+ end
75
+ end
76
+
77
+ context "as a non-admin" do
78
+ it "cannot create an resource" do
79
+ api_post :create
80
+ assert_unauthorized!
81
+ end
82
+
83
+ it "cannot update an resource" do
84
+ api_put :update, id: 1
85
+ assert_not_found!
86
+ end
87
+
88
+ it "cannot delete an resource" do
89
+ api_delete :destroy, id: 1
90
+ assert_not_found!
91
+ end
92
+ end
93
+ end
94
+ end