dune-api 1.0.1
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 +35 -0
- data/.gitmodules +3 -0
- data/.rspec +2 -0
- data/.travis.yml +19 -0
- data/CHANGELOG.md +48 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +601 -0
- data/LICENSE.txt +22 -0
- data/README.md +19 -0
- data/README.md.backup +61 -0
- data/Rakefile +2 -0
- data/apiary.apib +1769 -0
- data/app/constraints/dune/api/api_constraint.rb +17 -0
- data/app/controllers/dune/api/base_controller.rb +68 -0
- data/app/controllers/dune/api/v1/channels/members_controller.rb +33 -0
- data/app/controllers/dune/api/v1/channels_controller.rb +73 -0
- data/app/controllers/dune/api/v1/investments_controller.rb +70 -0
- data/app/controllers/dune/api/v1/press_assets_controller.rb +38 -0
- data/app/controllers/dune/api/v1/projects_controller.rb +76 -0
- data/app/controllers/dune/api/v1/rewards_controller.rb +9 -0
- data/app/controllers/dune/api/v1/sessions_controller.rb +27 -0
- data/app/controllers/dune/api/v1/tags_controller.rb +37 -0
- data/app/controllers/dune/api/v1/users_controller.rb +26 -0
- data/app/models/dune/api/access_token.rb +24 -0
- data/app/models/dune/api/investment.rb +14 -0
- data/app/models/dune/api/project.rb +23 -0
- data/app/models/dune/api/user_concern.rb +11 -0
- data/app/serializers/channel_member_serializer.rb +7 -0
- data/app/serializers/channel_serializer.rb +34 -0
- data/app/serializers/dune/api/investment_serializer.rb +44 -0
- data/app/serializers/dune/api/project_serializer.rb +86 -0
- data/app/serializers/press_asset_serializer.rb +11 -0
- data/app/serializers/reward_serializer.rb +13 -0
- data/app/serializers/tag_serializer.rb +10 -0
- data/app/serializers/user_serializer.rb +46 -0
- data/bin/rails +8 -0
- data/config/initializers/mime_types.rb +1 -0
- data/config/routes.rb +42 -0
- data/db/migrate/20140624141405_create_dune_api_access_tokens.rb +11 -0
- data/dune-api.gemspec +28 -0
- data/lib/dune/api.rb +12 -0
- data/lib/dune/api/engine.rb +11 -0
- data/lib/dune/api/paginated_controller.rb +19 -0
- data/lib/dune/api/version.rb +5 -0
- data/spec/constraints/neighborly/api/api_constraint_spec.rb +50 -0
- data/spec/controllers/neighborly/api/v1/channels/members_controller_spec.rb +82 -0
- data/spec/controllers/neighborly/api/v1/channels_controller_spec.rb +188 -0
- data/spec/controllers/neighborly/api/v1/investments_controller_spec.rb +178 -0
- data/spec/controllers/neighborly/api/v1/press_assets_controller_spec.rb +129 -0
- data/spec/controllers/neighborly/api/v1/projects_controller_spec.rb +317 -0
- data/spec/controllers/neighborly/api/v1/rewards_controller_spec.rb +28 -0
- data/spec/controllers/neighborly/api/v1/sessions_controller_spec.rb +67 -0
- data/spec/controllers/neighborly/api/v1/tags_controller_spec.rb +143 -0
- data/spec/controllers/neighborly/api/v1/users_controller_spec.rb +43 -0
- data/spec/factories.rb +78 -0
- data/spec/fixtures/image.png +0 -0
- data/spec/models/neighborly/api/investment_spec.rb +33 -0
- data/spec/models/neighborly/api/user_concern_spec.rb +33 -0
- data/spec/spec_helper.rb +43 -0
- data/spec/support/shared_examples.rb +96 -0
- metadata +219 -0
data/lib/dune/api.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Dune
|
2
|
+
module Api
|
3
|
+
module PaginatedController
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
has_scope :page, default: 1
|
8
|
+
end
|
9
|
+
|
10
|
+
def respond_with_pagination(collection)
|
11
|
+
render json: collection, meta: {
|
12
|
+
page: collection.current_page,
|
13
|
+
total: collection.total_count,
|
14
|
+
total_pages: collection.total_pages
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dune::Api::ApiConstraint do
|
4
|
+
let(:request) { double :request }
|
5
|
+
|
6
|
+
describe '#matches?' do
|
7
|
+
let(:revision) { 1 }
|
8
|
+
|
9
|
+
def header_for_revision(revision)
|
10
|
+
"revision=#{revision}"
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'when default is false' do
|
14
|
+
subject(:constraint) { described_class.new(revision: revision) }
|
15
|
+
|
16
|
+
|
17
|
+
it 'matches requests including the versioned vendor mime type' do
|
18
|
+
headers = { accept: header_for_revision(revision) }
|
19
|
+
allow(request).to receive(:headers).and_return(headers)
|
20
|
+
|
21
|
+
expect(constraint.matches?(request)).to eq true
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'does not match requests for other revisions' do
|
25
|
+
headers = { accept: header_for_revision(revision + 1) }
|
26
|
+
allow(request).to receive(:headers).and_return(headers)
|
27
|
+
|
28
|
+
expect(constraint.matches?(request)).to eq false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'when default is true' do
|
33
|
+
subject(:constraint) { described_class.new(revision: revision, default: true) }
|
34
|
+
|
35
|
+
it 'matches requests including the versioned vendor mime type' do
|
36
|
+
headers = { accept: header_for_revision(revision) }
|
37
|
+
allow(request).to receive(:headers).and_return(headers)
|
38
|
+
|
39
|
+
expect(constraint.matches?(request)).to eq true
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'matches requests when default is true' do
|
43
|
+
headers = { accept: header_for_revision(revision + 1) }
|
44
|
+
allow(request).to receive(:headers).and_return(headers)
|
45
|
+
|
46
|
+
expect(constraint.matches?(request)).to eq true
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dune::Api::V1::Channels::MembersController do
|
4
|
+
routes { Dune::Api::Engine.routes }
|
5
|
+
let(:parsed_response) { JSON.parse(response.body) }
|
6
|
+
let!(:channel) { FactoryGirl.create(:channel) }
|
7
|
+
let!(:member) { FactoryGirl.create(:channel_member, channel: channel) }
|
8
|
+
|
9
|
+
let(:records_returned) do
|
10
|
+
parsed_response.fetch('users').map { |t| t['id'] }
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#index', authorized: true, admin: true do
|
14
|
+
let(:do_request) { get :index, channel_id: channel.id, format: :json }
|
15
|
+
|
16
|
+
it 'returns the members list' do
|
17
|
+
do_request
|
18
|
+
expect(records_returned.count).to eq 1
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#create', authorized: true, admin: true do
|
23
|
+
let(:new_user) { FactoryGirl.create(:user) }
|
24
|
+
|
25
|
+
let(:do_request) do
|
26
|
+
post :create,
|
27
|
+
channel_id: channel.id,
|
28
|
+
channel_member: { user_id: new_user.id },
|
29
|
+
format: :json
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'creates the record' do
|
33
|
+
expect{ do_request }.to change{ channel.channel_members.count }.from(1).to(2)
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'on success' do
|
37
|
+
it 'returns a success http status' do
|
38
|
+
do_request
|
39
|
+
expect(response.status).to eq(201)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'returns the user' do
|
43
|
+
do_request
|
44
|
+
expect(parsed_response.fetch('user').fetch('id')).to eq new_user.id
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'on failure' do
|
49
|
+
let(:do_request) do
|
50
|
+
post :create,
|
51
|
+
channel_id: channel.id,
|
52
|
+
channel_member: { user_id: nil },
|
53
|
+
format: :json
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'returns a unprocessable entity http status' do
|
57
|
+
do_request
|
58
|
+
expect(response.status).to eq(422)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'returns a json with errors' do
|
62
|
+
do_request
|
63
|
+
|
64
|
+
expect(parsed_response.count).to eq(1)
|
65
|
+
expect(parsed_response['errors']['user_id']).not_to be_empty
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe 'destroy', authorized: true, admin: true do
|
71
|
+
let(:do_request) do
|
72
|
+
delete :destroy, id: member.user.id, channel_id: channel.id, format: :json
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'returns a success http status' do
|
76
|
+
do_request
|
77
|
+
expect(response.status).to eq(204)
|
78
|
+
expect{ member.reload }.to raise_error
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
@@ -0,0 +1,188 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dune::Api::V1::ChannelsController do
|
4
|
+
routes { Dune::Api::Engine.routes }
|
5
|
+
let(:parsed_response) { JSON.parse(response.body) }
|
6
|
+
let!(:channel) { FactoryGirl.create(:channel) }
|
7
|
+
|
8
|
+
let(:channels_returned) do
|
9
|
+
parsed_response.fetch('channels').map { |t| t['id'] }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#index', authorized: true do
|
13
|
+
let(:do_request) { get :index, format: :json }
|
14
|
+
|
15
|
+
it_behaves_like 'paginating results'
|
16
|
+
|
17
|
+
it 'applies the policy scope' do
|
18
|
+
expect(controller).to receive(:policy_scope).with(Channel).and_call_original
|
19
|
+
do_request
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'filters by query' do
|
23
|
+
FactoryGirl.create(:channel, name: 'Ordinary channel')
|
24
|
+
channel = FactoryGirl.create(:channel, name: 'Wonderful channel')
|
25
|
+
get :index, format: :json, query: 'wonderful'
|
26
|
+
expect(channels_returned).to eql([channel.id])
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'filter by state' do
|
30
|
+
let!(:draft_channel) do
|
31
|
+
FactoryGirl.create(:channel, state: :draft, user: user)
|
32
|
+
end
|
33
|
+
|
34
|
+
Channel.state_names.each do |state|
|
35
|
+
it "filters by state #{state}" do
|
36
|
+
channel = FactoryGirl.create(:channel, state: state, user: user)
|
37
|
+
expected_ids = if state.eql?(:draft)
|
38
|
+
[channel.id, draft_channel.id]
|
39
|
+
else
|
40
|
+
[channel.id]
|
41
|
+
end
|
42
|
+
|
43
|
+
get :index, format: :json, state => '1'
|
44
|
+
expect(channels_returned).to include(*expected_ids)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#create', authorized: true, admin: true do
|
51
|
+
let(:do_request) do
|
52
|
+
post :create,
|
53
|
+
channel: FactoryGirl.build(:channel).attributes,
|
54
|
+
format: :json
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'creates the record' do
|
58
|
+
expect{ do_request }.to change{ Channel.count }.from(1).to(2)
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'on success' do
|
62
|
+
it 'returns a success http status' do
|
63
|
+
do_request
|
64
|
+
expect(response.status).to eq(201)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'on failure' do
|
69
|
+
let(:do_request) do
|
70
|
+
post :create,
|
71
|
+
channel: { name: nil },
|
72
|
+
format: :json
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'returns a unprocessable entity http status' do
|
76
|
+
do_request
|
77
|
+
expect(response.status).to eq(422)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'returns a json with errors' do
|
81
|
+
do_request
|
82
|
+
|
83
|
+
expect(parsed_response.count).to eq(1)
|
84
|
+
expect(parsed_response['errors']['name']).not_to be_empty
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe '#update', authorized: true do
|
90
|
+
let(:user) { channel.user }
|
91
|
+
|
92
|
+
let(:do_request) do
|
93
|
+
put :update,
|
94
|
+
id: channel.id,
|
95
|
+
channel: { name: 'foo bar' },
|
96
|
+
format: :json
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'updates the record' do
|
100
|
+
expect(Channel).to receive(:update)
|
101
|
+
.with(channel.id.to_s, { 'name' => 'foo bar' })
|
102
|
+
|
103
|
+
do_request
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'on success' do
|
107
|
+
it 'returns a no content http status' do
|
108
|
+
do_request
|
109
|
+
expect(response.status).to eq(204)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context 'on failure' do
|
114
|
+
let(:do_request) do
|
115
|
+
put :update,
|
116
|
+
id: channel.id,
|
117
|
+
channel: { name: nil },
|
118
|
+
format: :json
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'returns a unprocessable entity http status' do
|
122
|
+
do_request
|
123
|
+
expect(response.status).to eq(422)
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'returns a json with errors' do
|
127
|
+
do_request
|
128
|
+
|
129
|
+
expect(parsed_response.count).to eq(1)
|
130
|
+
expect(parsed_response['errors']['name']).not_to be_empty
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe '#show', authorized: true do
|
136
|
+
let(:do_request) { get :show, id: channel.id, format: :json }
|
137
|
+
|
138
|
+
it 'responds with 200' do
|
139
|
+
do_request
|
140
|
+
expect(response.status).to eql(200)
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'has a top level element called channel' do
|
144
|
+
do_request
|
145
|
+
expect(parsed_response.fetch('channel')).to be_a(Hash)
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'responds with data of the given channel' do
|
149
|
+
do_request
|
150
|
+
expect(
|
151
|
+
parsed_response.fetch('channel')
|
152
|
+
).to have_key('id')
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
describe 'destroy', authorized: true, admin: true do
|
157
|
+
let(:do_request) { delete :destroy, id: channel.id, format: :json }
|
158
|
+
|
159
|
+
it 'returns a success http status' do
|
160
|
+
do_request
|
161
|
+
expect(response.status).to eq(204)
|
162
|
+
expect{ channel.reload }.to raise_error
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
[:push_to_draft, :push_to_online].each do |name|
|
167
|
+
describe "#{name}", authorized: true, admin: true do
|
168
|
+
let(:user) { FactoryGirl.create(:user, admin: true) }
|
169
|
+
let(:channel) { FactoryGirl.create(:channel, state: 'draft') }
|
170
|
+
let(:do_request) { put name, id: channel.id, format: :json }
|
171
|
+
|
172
|
+
it 'returns a success http status' do
|
173
|
+
do_request
|
174
|
+
expect(response.status).to eq(204)
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'authorizes the resource' do
|
178
|
+
expect(controller).to receive(:authorize).with(channel)
|
179
|
+
do_request
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'calls the state machine helper to change the state' do
|
183
|
+
expect_any_instance_of(Channel).to receive("#{name}!")
|
184
|
+
do_request
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dune::Api::V1::InvestmentsController do
|
4
|
+
routes { Dune::Api::Engine.routes }
|
5
|
+
let!(:investment) { FactoryGirl.create(:investment) }
|
6
|
+
|
7
|
+
let(:investments_returned) do
|
8
|
+
parsed_response.fetch('investments').map { |t| t['id'] }
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:parsed_response) { JSON.parse(response.body) }
|
12
|
+
|
13
|
+
describe '#index', authorized: true, admin: true do
|
14
|
+
let(:do_request) { get :index, format: :json }
|
15
|
+
|
16
|
+
it_behaves_like 'paginating results'
|
17
|
+
|
18
|
+
it 'filters by query' do
|
19
|
+
investment = FactoryGirl.create(:investment, payment_method: 'balanced')
|
20
|
+
FactoryGirl.create(:investment, payment_method: 'paypal')
|
21
|
+
get :index, format: :json, query: 'balanced'
|
22
|
+
expect(investments_returned).to eql([investment.id])
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'filtering by between_values' do
|
26
|
+
before do
|
27
|
+
@investment_30 = FactoryGirl.create(:investment, value: 30)
|
28
|
+
@investment_35 = FactoryGirl.create(:investment, value: 35)
|
29
|
+
FactoryGirl.create(:investment, value: 40)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'returns just those investments in the given range' do
|
33
|
+
get :index, format: :json,
|
34
|
+
between_values: {
|
35
|
+
initial: 30,
|
36
|
+
final: 35
|
37
|
+
}
|
38
|
+
expect(investments_returned).to eql([@investment_35.id, @investment_30.id])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'filter by state' do
|
43
|
+
let!(:pending_investment) do
|
44
|
+
FactoryGirl.create(:investment, state: :pending)
|
45
|
+
end
|
46
|
+
|
47
|
+
Investment.state_names.each do |state|
|
48
|
+
it "filters by state #{state}" do
|
49
|
+
investment = FactoryGirl.create(:investment, state: state)
|
50
|
+
expected_ids = if state.eql?(:pending)
|
51
|
+
[investment.id, pending_investment.id]
|
52
|
+
else
|
53
|
+
[investment.id]
|
54
|
+
end
|
55
|
+
|
56
|
+
get :index, format: :json, state => '1'
|
57
|
+
expect(investments_returned).to include(*expected_ids)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe 'filter by project id' do
|
63
|
+
let(:first_project) { FactoryGirl.create(:project, state: 'online') }
|
64
|
+
let(:second_project) { FactoryGirl.create(:project, state: 'online') }
|
65
|
+
|
66
|
+
before do
|
67
|
+
@investment = FactoryGirl.create(:investment, value: 10, project: first_project)
|
68
|
+
FactoryGirl.create(:investment, value: 10, project: second_project)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'returns just those investments in the given project id' do
|
72
|
+
get :index, project_id: first_project.id, format: :json
|
73
|
+
expect(investments_returned).to eql([@investment.id])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#show', authorized: true, admin: true do
|
79
|
+
let(:do_request) { get :show, id: investment.id, format: :json }
|
80
|
+
|
81
|
+
it 'responds with 200' do
|
82
|
+
do_request
|
83
|
+
expect(response.status).to eql(200)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'has a top level element called investment' do
|
87
|
+
do_request
|
88
|
+
expect(parsed_response.fetch('investment')).to be_a(Hash)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'responds with data of the given investment' do
|
92
|
+
do_request
|
93
|
+
expect(
|
94
|
+
parsed_response.fetch('investment')
|
95
|
+
).to have_key('id')
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe '#update', authorized: true, admin: true do
|
100
|
+
let(:do_request) do
|
101
|
+
put :update,
|
102
|
+
id: investment.id,
|
103
|
+
investment: { value: 15 },
|
104
|
+
format: :json
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'updates the record' do
|
108
|
+
expect(::Investment).to receive(:update)
|
109
|
+
.with(investment.id.to_s, { 'value' => 15 })
|
110
|
+
|
111
|
+
do_request
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'on success' do
|
115
|
+
it 'returns a no content http status' do
|
116
|
+
do_request
|
117
|
+
expect(response.status).to eq(204)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'on failure' do
|
122
|
+
let(:do_request) do
|
123
|
+
put :update,
|
124
|
+
id: investment.id,
|
125
|
+
investment: { value: nil },
|
126
|
+
format: :json
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'returns a unprocessable entity http status' do
|
130
|
+
do_request
|
131
|
+
expect(response.status).to eq(422)
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'returns a json with errors' do
|
135
|
+
do_request
|
136
|
+
|
137
|
+
expect(parsed_response.count).to eq(1)
|
138
|
+
expect(parsed_response['errors']['value']).not_to be_empty
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe 'destroy', authorized: true, admin: true do
|
144
|
+
let(:do_request) { delete :destroy, id: investment.id, format: :json }
|
145
|
+
|
146
|
+
it 'returns a success http status' do
|
147
|
+
do_request
|
148
|
+
expect(response.status).to eq(204)
|
149
|
+
expect(investment.reload.deleted?).to be_truthy
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
[:confirm, :pendent, :refund, :hide, :cancel].each do |name|
|
154
|
+
describe "#{name}", authorized: true, admin: true do
|
155
|
+
let(:user) { FactoryGirl.create(:user, admin: true) }
|
156
|
+
let(:investment) do
|
157
|
+
state = (name == :refund) ? 'confirmed' : 'deleted'
|
158
|
+
FactoryGirl.create(:investment, state: state)
|
159
|
+
end
|
160
|
+
let(:do_request) { put name, id: investment.id, format: :json }
|
161
|
+
|
162
|
+
it 'returns a success http status' do
|
163
|
+
do_request
|
164
|
+
expect(response.status).to eq(204)
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'authorizes the resource' do
|
168
|
+
expect(controller).to receive(:authorize).with(investment)
|
169
|
+
do_request
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'calls the state machine helper to change the state' do
|
173
|
+
expect_any_instance_of(Investment).to receive("#{name}!")
|
174
|
+
do_request
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|