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.
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