cathode 0.0.1 → 0.1.0

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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +346 -125
  3. data/Rakefile +1 -0
  4. data/app/controllers/cathode/base_controller.rb +28 -45
  5. data/app/models/cathode/token.rb +21 -0
  6. data/config/routes.rb +16 -0
  7. data/db/migrate/20140425164100_create_cathode_tokens.rb +11 -0
  8. data/lib/cathode.rb +0 -13
  9. data/lib/cathode/_version.rb +2 -1
  10. data/lib/cathode/action.rb +197 -39
  11. data/lib/cathode/action_dsl.rb +60 -0
  12. data/lib/cathode/base.rb +81 -12
  13. data/lib/cathode/create_request.rb +21 -0
  14. data/lib/cathode/custom_request.rb +5 -0
  15. data/lib/cathode/debug.rb +25 -0
  16. data/lib/cathode/destroy_request.rb +13 -0
  17. data/lib/cathode/engine.rb +9 -0
  18. data/lib/cathode/exceptions.rb +20 -0
  19. data/lib/cathode/index_request.rb +40 -0
  20. data/lib/cathode/object_collection.rb +49 -0
  21. data/lib/cathode/query.rb +24 -0
  22. data/lib/cathode/railtie.rb +21 -0
  23. data/lib/cathode/request.rb +139 -7
  24. data/lib/cathode/resource.rb +50 -19
  25. data/lib/cathode/resource_dsl.rb +46 -0
  26. data/lib/cathode/show_request.rb +13 -0
  27. data/lib/cathode/update_request.rb +26 -0
  28. data/lib/cathode/version.rb +112 -23
  29. data/lib/tasks/cathode_tasks.rake +5 -4
  30. data/spec/dummy/app/api/api.rb +0 -0
  31. data/spec/dummy/app/models/payment.rb +3 -0
  32. data/spec/dummy/app/models/product.rb +1 -0
  33. data/spec/dummy/app/models/sale.rb +5 -0
  34. data/spec/dummy/app/models/salesperson.rb +3 -0
  35. data/spec/dummy/db/development.sqlite3 +0 -0
  36. data/spec/dummy/db/migrate/20140409183635_create_sales.rb +11 -0
  37. data/spec/dummy/db/migrate/20140423172419_create_salespeople.rb +11 -0
  38. data/spec/dummy/db/migrate/20140424181343_create_payments.rb +10 -0
  39. data/spec/dummy/db/schema.rb +31 -1
  40. data/spec/dummy/db/test.sqlite3 +0 -0
  41. data/spec/dummy/log/development.log +1167 -0
  42. data/spec/dummy/log/test.log +180602 -0
  43. data/spec/dummy/spec/factories/payments.rb +8 -0
  44. data/spec/dummy/spec/factories/products.rb +1 -1
  45. data/spec/dummy/spec/factories/sales.rb +9 -0
  46. data/spec/dummy/spec/factories/salespeople.rb +7 -0
  47. data/spec/dummy/spec/requests/requests_spec.rb +434 -0
  48. data/spec/lib/cathode/action_spec.rb +136 -0
  49. data/spec/lib/cathode/base_spec.rb +34 -0
  50. data/spec/lib/cathode/create_request_spec.rb +40 -0
  51. data/spec/lib/cathode/custom_request_spec.rb +31 -0
  52. data/spec/lib/cathode/debug_spec.rb +25 -0
  53. data/spec/lib/cathode/destroy_request_spec.rb +28 -0
  54. data/spec/lib/cathode/index_request_spec.rb +62 -0
  55. data/spec/lib/cathode/object_collection_spec.rb +66 -0
  56. data/spec/lib/cathode/query_spec.rb +28 -0
  57. data/spec/lib/cathode/request_spec.rb +58 -0
  58. data/spec/lib/cathode/resource_spec.rb +482 -0
  59. data/spec/lib/cathode/show_request_spec.rb +23 -0
  60. data/spec/lib/cathode/update_request_spec.rb +41 -0
  61. data/spec/lib/cathode/version_spec.rb +416 -0
  62. data/spec/models/cathode/token_spec.rb +62 -0
  63. data/spec/spec_helper.rb +8 -2
  64. data/spec/support/factories/payments.rb +3 -0
  65. data/spec/support/factories/sale.rb +3 -0
  66. data/spec/support/factories/salespeople.rb +3 -0
  67. data/spec/support/factories/token.rb +3 -0
  68. data/spec/support/helpers.rb +13 -2
  69. metadata +192 -47
  70. data/app/helpers/cathode/application_helper.rb +0 -4
  71. data/spec/dummy/app/api/dummy_api.rb +0 -4
  72. data/spec/integration/api_spec.rb +0 -88
  73. data/spec/lib/action_spec.rb +0 -140
  74. data/spec/lib/base_spec.rb +0 -28
  75. data/spec/lib/request_spec.rb +0 -5
  76. data/spec/lib/resources_spec.rb +0 -78
  77. data/spec/lib/versioning_spec.rb +0 -104
@@ -0,0 +1,136 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cathode::Action do
4
+ describe '.create' do
5
+ subject { Cathode::Action.create(action, Cathode::Resource.new(:products), try(:params) || {}, &block) }
6
+
7
+ context 'with a default action' do
8
+ let(:action) { :index }
9
+
10
+ context 'with an override' do
11
+ let(:block) { proc { override { Product.last } } }
12
+
13
+ it 'sets the override block' do
14
+ expect(subject.override_block.call).to eq(Product.last)
15
+ end
16
+ end
17
+
18
+ context 'with a replacement' do
19
+ let(:block) { proc { replace { Product.last } } }
20
+
21
+ it 'sets the replacement as the action block' do
22
+ expect(subject.action_block.call).to eq(Product.last)
23
+ end
24
+ end
25
+ end
26
+
27
+ context 'with a custom action' do
28
+ let(:action) { :custom }
29
+ let(:block) { proc { Product.last } }
30
+
31
+ context 'with method' do
32
+ let(:params) { { method: :get } }
33
+
34
+ it 'creates a CustomAction' do
35
+ expect(subject.class).to eq(Cathode::CustomAction)
36
+ end
37
+
38
+ it 'sets the block as the action block' do
39
+ expect(subject.action_block.call).to eq(Product.last)
40
+ end
41
+
42
+ it 'sets the HTTP method' do
43
+ expect(subject.http_method).to eq(:get)
44
+ end
45
+ end
46
+
47
+ context 'without method' do
48
+ let(:params) { {} }
49
+
50
+ it 'raises an error' do
51
+ expect { subject }.to raise_error(
52
+ Cathode::RequestMethodMissingError,
53
+ "You must specify an HTTP method (get, put, post, delete) for action `custom'"
54
+ )
55
+ end
56
+ end
57
+ end
58
+
59
+ context 'with :index' do
60
+ let(:action) { :index }
61
+ let(:block) { nil }
62
+
63
+ it 'creates an IndexAction' do
64
+ expect(subject.class).to eq(Cathode::IndexAction)
65
+ end
66
+ end
67
+
68
+ context 'with :show' do
69
+ let(:action) { :show }
70
+ let(:block) { nil }
71
+
72
+ it 'creates a ShowAction' do
73
+ expect(subject.class).to eq(Cathode::ShowAction)
74
+ end
75
+ end
76
+
77
+ context 'with :create' do
78
+ let(:action) { :create }
79
+
80
+ context 'when attributes specified' do
81
+ let(:block) do
82
+ proc { attributes { params.require(:product) } }
83
+ end
84
+
85
+ it 'creates a CreateAction' do
86
+ expect(subject.after_resource_initialized.class).to eq(Cathode::CreateAction)
87
+ end
88
+ end
89
+
90
+ context 'when attributes not specified' do
91
+ let(:block) { nil }
92
+
93
+ it 'raises an error' do
94
+ expect { subject.after_resource_initialized }.to raise_error(
95
+ Cathode::UnknownAttributesError,
96
+ "An attributes block was not specified for `create' action on resource `products'"
97
+ )
98
+ end
99
+ end
100
+ end
101
+
102
+ context 'with :update' do
103
+ let(:action) { :update }
104
+
105
+ context 'when attributes specified' do
106
+ let(:block) do
107
+ proc { attributes { params.require(:product) } }
108
+ end
109
+
110
+ it 'creates an UpdateAction' do
111
+ expect(subject.after_resource_initialized.class).to eq(Cathode::UpdateAction)
112
+ end
113
+ end
114
+
115
+ context 'when attributes not specified' do
116
+ let(:block) { nil }
117
+
118
+ it 'raises an error' do
119
+ expect { subject.after_resource_initialized }.to raise_error(
120
+ Cathode::UnknownAttributesError,
121
+ "An attributes block was not specified for `update' action on resource `products'"
122
+ )
123
+ end
124
+ end
125
+ end
126
+
127
+ context 'with :destroy' do
128
+ let(:action) { :destroy }
129
+ let(:block) { nil }
130
+
131
+ it 'creates a DestroyAction' do
132
+ expect(subject.class).to eq(Cathode::DestroyAction)
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cathode::Base do
4
+ describe '#version' do
5
+ subject do
6
+ Cathode::Base.version 1.5 do
7
+ resources :products
8
+ end
9
+ end
10
+
11
+ it 'creates a new version' do
12
+ expect(subject.version).to eq('1.5.0')
13
+ end
14
+
15
+ it 'contains the resources' do
16
+ expect(subject._resources.names).to eq([:products])
17
+ end
18
+ end
19
+
20
+ describe '#define' do
21
+ context 'with resource name' do
22
+ subject do
23
+ Cathode::Base.define do
24
+ resources :products
25
+ end
26
+ end
27
+
28
+ it 'initializes version 1.0.0' do
29
+ subject
30
+ expect(Cathode::Version.find('1.0.0')._resources.find(:products)).to_not be_nil
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cathode::CreateRequest do
4
+ subject do
5
+ Cathode::CreateRequest.new(context_stub(params: ActionController::Parameters.new(params.merge(controller: 'products', action: 'create'))))
6
+ end
7
+ before do
8
+ use_api do
9
+ resources :products, actions: [:create] do
10
+ attributes do
11
+ params.require(:product).permit(:title)
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ context 'with valid attributes' do
18
+ let(:params) { { product: { title: 'cool product' } } }
19
+
20
+ it 'sets status as ok' do
21
+ expect(subject._status).to eq(:ok)
22
+ end
23
+
24
+ it 'sets body as the new record' do
25
+ expect(subject._body.title).to eq('cool product')
26
+ end
27
+ end
28
+
29
+ context 'with invalid attributes' do
30
+ let(:params) { { title: 'cool product' } }
31
+
32
+ it 'sets status as bad request' do
33
+ expect(subject._status).to eq(:bad_request)
34
+ end
35
+
36
+ it 'sets body as error message' do
37
+ expect(subject._body).to eq('param is missing or the value is empty: product')
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cathode::CustomRequest do
4
+ subject do
5
+ Cathode::CustomRequest.new(context_stub(
6
+ params: ActionController::Parameters.new(params.merge(controller: 'products', action: 'custom')),
7
+ path: 'products/custom'
8
+ ))
9
+ end
10
+
11
+ before do
12
+ use_api do
13
+ resources :products do
14
+ get :custom do
15
+ body Product.last
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ let!(:products) { create_list(:product, 3) }
22
+ let(:params) { {} }
23
+
24
+ it 'sets status as ok' do
25
+ expect(subject._status).to eq(:ok)
26
+ end
27
+
28
+ it 'sets body' do
29
+ expect(subject._body).to eq(Product.last)
30
+ end
31
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cathode::Debug do
4
+ before do
5
+ use_api do
6
+ resources :products, actions: [:index]
7
+ version 2 do
8
+ resources :sales, actions: :all do
9
+ attributes do
10
+ params.require(:sale)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ describe '.info' do
18
+ subject { Cathode::Debug.info }
19
+
20
+ it 'returns the info' do
21
+ puts subject
22
+ # expect(subject).to eq("Version 1.0.0\n\tproducts")
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cathode::DestroyRequest do
4
+ subject do
5
+ Cathode::DestroyRequest.new(context_stub(params: ActionController::Parameters.new(params.merge(controller: 'products', action: 'destroy'))))
6
+ end
7
+ before do
8
+ use_api do
9
+ resources :products, actions: [:destroy]
10
+ end
11
+ end
12
+
13
+ let(:action) { 'destroy' }
14
+ let(:params) { { id: product.id } }
15
+ let!(:product) { create(:product) }
16
+
17
+ it 'sets status as ok' do
18
+ expect(subject._status).to eq(:ok)
19
+ end
20
+
21
+ it 'sets body as empty' do
22
+ expect(subject._body).to be_empty
23
+ end
24
+
25
+ it 'removes the record' do
26
+ expect { subject }.to change { Product.count }.by(-1)
27
+ end
28
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cathode::IndexRequest do
4
+ subject do
5
+ Cathode::IndexRequest.new(context_stub(params: ActionController::Parameters.new(params.merge(controller: resource, action: 'index'))))
6
+ end
7
+ let!(:products) { create_list(:product, 5) }
8
+ before do
9
+ use_api do
10
+ resources :products do
11
+ action :index do
12
+ allows :paging
13
+ end
14
+ end
15
+
16
+ resources :sales, actions: [:index]
17
+ end
18
+ end
19
+
20
+ describe 'with no params' do
21
+ let(:params) { {} }
22
+ let(:resource) { 'products' }
23
+ let(:block) { nil }
24
+
25
+ it 'sets status as ok' do
26
+ expect(subject._status).to eq(:ok)
27
+ end
28
+
29
+ it 'sets body as all resource records' do
30
+ expect(subject._body).to eq(Product.all)
31
+ end
32
+ end
33
+
34
+ context 'with paging' do
35
+ let(:params) { { page: 2, per_page: 2 } }
36
+
37
+ context 'when allowed' do
38
+ let(:resource) { 'products' }
39
+
40
+ it 'sets status as ok' do
41
+ expect(subject._status).to eq(:ok)
42
+ end
43
+
44
+ it 'sets body as the paged results' do
45
+ expect(subject._body).to eq(products[2..3])
46
+ end
47
+ end
48
+
49
+ context 'when not allowed' do
50
+ let(:resource) { 'sales' }
51
+ let!(:sales) { create_list(:sale, 5) }
52
+
53
+ it 'sets status as ok' do
54
+ expect(subject._status).to eq(:ok)
55
+ end
56
+
57
+ it 'sets body as all records' do
58
+ expect(subject._body).to eq(sales)
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cathode::ObjectCollection do
4
+ let(:collection) { Cathode::ObjectCollection.new }
5
+ let(:obj_struct) { Struct.new(:name) }
6
+ let(:battery) { obj_struct.new(:battery) }
7
+ let(:charger) { obj_struct.new(:charger) }
8
+ before do
9
+ collection << battery
10
+ collection << charger
11
+ end
12
+
13
+ describe '#find' do
14
+ subject { collection.find(:battery) }
15
+
16
+ it 'returns the item with the matching name' do
17
+ expect(subject).to eq(battery)
18
+ end
19
+ end
20
+
21
+ describe '#add' do
22
+ subject { collection.add(items) }
23
+ let(:cord) { obj_struct.new(:cord) }
24
+ let(:connector) { obj_struct.new(:connector) }
25
+
26
+ context 'with single item' do
27
+ let(:items) { cord }
28
+
29
+ it 'adds the item to the objects' do
30
+ expect(subject.objects).to match_array([battery, charger, cord])
31
+ end
32
+ end
33
+
34
+ context 'with an array of items' do
35
+ let(:items) { [cord, connector] }
36
+
37
+ it 'adds the items to the objects' do
38
+ expect(subject.objects).to match_array([battery, charger, cord, connector])
39
+ end
40
+ end
41
+ end
42
+
43
+ describe '#delete' do
44
+ subject { collection.delete(:battery) }
45
+
46
+ it 'deletes the object from the collection' do
47
+ expect(subject.objects).to match_array([charger])
48
+ end
49
+ end
50
+
51
+ describe '#names' do
52
+ subject { collection.names }
53
+
54
+ it 'returns the objects mapped to their names' do
55
+ expect(subject).to match_array([:battery, :charger])
56
+ end
57
+ end
58
+
59
+ describe 'array methods' do
60
+ subject { collection.each { |i| i } }
61
+
62
+ it 'delegates to the object array' do
63
+ expect(subject).to match_array([battery, charger])
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cathode::Query do
4
+ describe '.new' do
5
+ subject { Cathode::Query.new(Product, query) }
6
+ let!(:product1) { create(:product, cost: 500) }
7
+ let!(:product2) { create(:product, cost: 700) }
8
+ let!(:product3) { create(:product, cost: 1000) }
9
+
10
+ describe 'where' do
11
+ context 'explicit' do
12
+ let(:query) { 'where cost > 500' }
13
+
14
+ it 'returns the records' do
15
+ expect(subject.results).to match_array([product2, product3])
16
+ end
17
+ end
18
+
19
+ context 'implicit' do
20
+ let(:query) { 'cost > 500' }
21
+
22
+ it 'returns the records' do
23
+ expect(subject.results).to match_array([product2, product3])
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end