virtuous 0.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/.github/workflows/test.yml +26 -0
- data/.gitignore +5 -0
- data/.reek.yml +36 -0
- data/.rubocop.yml +87 -0
- data/.ruby-version +1 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +18 -0
- data/Gemfile +17 -0
- data/LICENSE +21 -0
- data/README.md +54 -0
- data/Rakefile +24 -0
- data/lib/virtuous/client/contact.rb +220 -0
- data/lib/virtuous/client/contact_address.rb +78 -0
- data/lib/virtuous/client/gift.rb +394 -0
- data/lib/virtuous/client/gift_designation.rb +59 -0
- data/lib/virtuous/client/individual.rb +125 -0
- data/lib/virtuous/client/recurring_gift.rb +86 -0
- data/lib/virtuous/client.rb +272 -0
- data/lib/virtuous/error.rb +54 -0
- data/lib/virtuous/helpers/hash_helper.rb +28 -0
- data/lib/virtuous/helpers/string_helper.rb +31 -0
- data/lib/virtuous/parse_oj.rb +24 -0
- data/lib/virtuous/version.rb +5 -0
- data/lib/virtuous.rb +12 -0
- data/logo/virtuous.svg +1 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/support/client_factory.rb +10 -0
- data/spec/support/fixtures/contact.json +112 -0
- data/spec/support/fixtures/contact_address.json +20 -0
- data/spec/support/fixtures/contact_addresses.json +42 -0
- data/spec/support/fixtures/contact_gifts.json +80 -0
- data/spec/support/fixtures/gift.json +55 -0
- data/spec/support/fixtures/gift_designation_query_options.json +2701 -0
- data/spec/support/fixtures/gift_designations.json +175 -0
- data/spec/support/fixtures/gifts.json +112 -0
- data/spec/support/fixtures/import.json +0 -0
- data/spec/support/fixtures/individual.json +46 -0
- data/spec/support/fixtures/recurring_gift.json +26 -0
- data/spec/support/fixtures_helper.rb +5 -0
- data/spec/support/virtuous_mock.rb +101 -0
- data/spec/virtuous/client_spec.rb +270 -0
- data/spec/virtuous/error_spec.rb +74 -0
- data/spec/virtuous/resources/contact_address_spec.rb +75 -0
- data/spec/virtuous/resources/contact_spec.rb +137 -0
- data/spec/virtuous/resources/gift_designation_spec.rb +70 -0
- data/spec/virtuous/resources/gift_spec.rb +249 -0
- data/spec/virtuous/resources/individual_spec.rb +95 -0
- data/spec/virtuous/resources/recurring_gift_spec.rb +67 -0
- data/spec/virtuous_spec.rb +7 -0
- data/virtuous.gemspec +25 -0
- metadata +121 -0
@@ -0,0 +1,270 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Virtuous::Client do
|
4
|
+
let(:attrs) { { api_key: 'test_api_key' } }
|
5
|
+
let(:attrs_without_authentication) { { api_key: nil } }
|
6
|
+
|
7
|
+
subject(:client) { described_class.new(**attrs) }
|
8
|
+
|
9
|
+
shared_examples 'param request' do |verb|
|
10
|
+
let(:endpoint) { "#{verb}_test" }
|
11
|
+
let(:url) { "https://api.virtuoussoftware.com/#{endpoint}" }
|
12
|
+
|
13
|
+
before do
|
14
|
+
stub_request(:any, /_test/).to_return(body: response_body.to_json)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'requests at `path` argument' do
|
18
|
+
client.public_send(verb, endpoint)
|
19
|
+
|
20
|
+
expect(WebMock).to have_requested(verb, url)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'passes request parameters' do
|
24
|
+
client.public_send(verb, endpoint, request_params)
|
25
|
+
|
26
|
+
expect(WebMock).to have_requested(verb, url).with(query: request_params)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'returns parsed response body' do
|
30
|
+
expect(client.public_send(verb, endpoint)).to eq(response_body)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
shared_examples 'body request' do |verb|
|
35
|
+
let(:body) { { 'test' => 123 } }
|
36
|
+
let(:endpoint) { "#{verb}_test" }
|
37
|
+
let(:url) { "https://api.virtuoussoftware.com/#{endpoint}" }
|
38
|
+
|
39
|
+
let(:do_request) { client.public_send(verb, endpoint, body) }
|
40
|
+
|
41
|
+
before do
|
42
|
+
stub_request(:any, /_test/).to_return(body: body.to_json)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'requests at `path` argument' do
|
46
|
+
do_request
|
47
|
+
|
48
|
+
expect(WebMock).to have_requested(verb, url)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'passes request body' do
|
52
|
+
do_request
|
53
|
+
|
54
|
+
expect(WebMock)
|
55
|
+
.to have_requested(verb, url)
|
56
|
+
.with(body: body)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'returns parsed response body' do
|
60
|
+
expect(do_request).to eq(body)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
shared_examples 'api key auth' do
|
65
|
+
let(:path) { '/api/Contact/1' }
|
66
|
+
let(:url) { "https://api.virtuoussoftware.com#{path}" }
|
67
|
+
|
68
|
+
it 'doesn\'t request an access token' do
|
69
|
+
client.get(path)
|
70
|
+
|
71
|
+
expect(WebMock).not_to have_requested(:post, 'https://api.virtuoussoftware.com/Token')
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'uses the key in requests' do
|
75
|
+
client.get(path)
|
76
|
+
|
77
|
+
expect(WebMock).to have_requested(:get, url)
|
78
|
+
.with(headers: { 'Authorization' => "Bearer #{api_key}" })
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
shared_examples 'valid access token auth' do
|
83
|
+
let(:path) { '/api/Contact/1' }
|
84
|
+
let(:url) { "https://api.virtuoussoftware.com#{path}" }
|
85
|
+
|
86
|
+
it 'doesn\'t request an access token' do
|
87
|
+
client.get(path)
|
88
|
+
|
89
|
+
expect(WebMock).not_to have_requested(:post, 'https://api.virtuoussoftware.com/Token')
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'uses the access token in requests' do
|
93
|
+
client.get(path)
|
94
|
+
|
95
|
+
expect(WebMock).to have_requested(:get, url)
|
96
|
+
.with(headers: { 'Authorization' => "Bearer #{access_token}" })
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
shared_examples 'expired access token auth' do
|
101
|
+
let(:path) { '/api/Contact/1' }
|
102
|
+
let(:url) { "https://api.virtuoussoftware.com#{path}" }
|
103
|
+
|
104
|
+
it 'doesn\'t request an access token before doing a request' do
|
105
|
+
client
|
106
|
+
|
107
|
+
expect(WebMock).not_to have_requested(:post, 'https://api.virtuoussoftware.com/Token')
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'requests a new access token before doing a request' do
|
111
|
+
client.get(path)
|
112
|
+
|
113
|
+
body = URI.encode_www_form({ grant_type: 'refresh_token', refresh_token: refresh_token })
|
114
|
+
|
115
|
+
expect(WebMock).to have_requested(:post, 'https://api.virtuoussoftware.com/Token')
|
116
|
+
.with(body: body)
|
117
|
+
|
118
|
+
expect(client.refresh_token).to eq('new_refresh_token')
|
119
|
+
expect(client.access_token).to eq('new_access_token')
|
120
|
+
expect(client.expires_at).to be > Time.now
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'doesn\'t request an access token a second time' do
|
124
|
+
client.get(path)
|
125
|
+
|
126
|
+
WebMock.reset_executed_requests!
|
127
|
+
|
128
|
+
client.get(path)
|
129
|
+
|
130
|
+
expect(WebMock).not_to have_requested(:post, 'https://api.virtuoussoftware.com/Token')
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'uses the new access token in requests' do
|
134
|
+
client.get(path)
|
135
|
+
|
136
|
+
expect(WebMock).to have_requested(:get, url)
|
137
|
+
.with(headers: { 'Authorization' => 'Bearer new_access_token' })
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context 'with api key' do
|
142
|
+
let(:api_key) { 'test_api_key' }
|
143
|
+
let(:attrs) { { api_key: api_key } }
|
144
|
+
|
145
|
+
it_behaves_like 'api key auth'
|
146
|
+
end
|
147
|
+
|
148
|
+
context 'with access token' do
|
149
|
+
let(:access_token) { 'test_access_token' }
|
150
|
+
let(:attrs) { { access_token: access_token } }
|
151
|
+
|
152
|
+
it_behaves_like 'valid access token auth'
|
153
|
+
end
|
154
|
+
|
155
|
+
context 'with non expired access token' do
|
156
|
+
let(:access_token) { 'test_access_token' }
|
157
|
+
let(:refresh_token) { 'test_refresh_token' }
|
158
|
+
let(:attrs) do
|
159
|
+
{ access_token: access_token, refresh_token: refresh_token, expires_at: Time.now + 1_295_999 }
|
160
|
+
end
|
161
|
+
|
162
|
+
it_behaves_like 'valid access token auth'
|
163
|
+
end
|
164
|
+
|
165
|
+
context 'with expired access token' do
|
166
|
+
let(:access_token) { 'test_access_token' }
|
167
|
+
let(:refresh_token) { 'test_refresh_token' }
|
168
|
+
let(:attrs) do
|
169
|
+
{
|
170
|
+
access_token: access_token, refresh_token: refresh_token, expires_at: Time.new(2023, 12, 11)
|
171
|
+
}
|
172
|
+
end
|
173
|
+
|
174
|
+
it_behaves_like 'expired access token auth'
|
175
|
+
end
|
176
|
+
|
177
|
+
context 'with no access token' do
|
178
|
+
let(:refresh_token) { 'test_refresh_token' }
|
179
|
+
let(:attrs) { { refresh_token: refresh_token } }
|
180
|
+
|
181
|
+
it_behaves_like 'expired access token auth'
|
182
|
+
end
|
183
|
+
|
184
|
+
context 'with password auth' do
|
185
|
+
let(:attrs) { {} }
|
186
|
+
let(:access_token) { 'new_access_token' }
|
187
|
+
|
188
|
+
before :each do
|
189
|
+
client.authenticate('user@email.com', 'password')
|
190
|
+
WebMock.reset_executed_requests!
|
191
|
+
end
|
192
|
+
|
193
|
+
it_behaves_like 'valid access token auth'
|
194
|
+
end
|
195
|
+
|
196
|
+
describe '#authenticate(email, password, otp = nil)' do
|
197
|
+
let(:email) { 'user@email.com' }
|
198
|
+
let(:password) { 'test_password' }
|
199
|
+
let(:attrs) { {} }
|
200
|
+
|
201
|
+
it 'sends a request to retrieve a token' do
|
202
|
+
client.authenticate(email, password)
|
203
|
+
|
204
|
+
body = URI.encode_www_form({ grant_type: 'password', username: email, password: password })
|
205
|
+
|
206
|
+
expect(WebMock).to have_requested(:post, 'https://api.virtuoussoftware.com/Token')
|
207
|
+
.with(body: body)
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'sets the new token' do
|
211
|
+
client.authenticate(email, password)
|
212
|
+
|
213
|
+
expect(client.refresh_token).to eq('new_refresh_token')
|
214
|
+
expect(client.access_token).to eq('new_access_token')
|
215
|
+
expect(client.expires_at).to be > Time.now
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'returns the new token values' do
|
219
|
+
response = client.authenticate(email, password)
|
220
|
+
|
221
|
+
expect(response[:refresh_token]).to eq(client.refresh_token)
|
222
|
+
expect(response[:access_token]).to eq(client.access_token)
|
223
|
+
expect(response[:expires_at]).to eq(client.expires_at)
|
224
|
+
end
|
225
|
+
|
226
|
+
context 'with otp' do
|
227
|
+
let(:email) { 'otp@user.com' }
|
228
|
+
|
229
|
+
it 'returns requires_otp if otp is not set' do
|
230
|
+
response = client.authenticate(email, password)
|
231
|
+
|
232
|
+
expect(response[:requires_otp]).to eq(true)
|
233
|
+
end
|
234
|
+
|
235
|
+
it 'sets the new token' do
|
236
|
+
client.authenticate(email, password, '111111')
|
237
|
+
|
238
|
+
expect(client.refresh_token).to eq('new_refresh_token')
|
239
|
+
expect(client.access_token).to eq('new_access_token')
|
240
|
+
expect(client.expires_at).to be > Time.now
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
describe '#get(path, options = {})' do
|
246
|
+
let(:request_params) { { 'test' => 123 } }
|
247
|
+
let(:response_body) { request_params }
|
248
|
+
|
249
|
+
include_examples 'param request', :get
|
250
|
+
end
|
251
|
+
|
252
|
+
describe '#delete(path, options = {})' do
|
253
|
+
let(:request_params) { { 'test' => 123 } }
|
254
|
+
let(:response_body) { {} }
|
255
|
+
|
256
|
+
include_examples 'param request', :delete
|
257
|
+
end
|
258
|
+
|
259
|
+
describe '#patch(path, options = {})' do
|
260
|
+
include_examples 'body request', :patch
|
261
|
+
end
|
262
|
+
|
263
|
+
describe '#post(path, options = {})' do
|
264
|
+
include_examples 'body request', :post
|
265
|
+
end
|
266
|
+
|
267
|
+
describe '#put(path, options = {})' do
|
268
|
+
include_examples 'body request', :put
|
269
|
+
end
|
270
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rack/utils'
|
3
|
+
|
4
|
+
CODES = Rack::Utils::HTTP_STATUS_CODES.keys.freeze
|
5
|
+
|
6
|
+
RSpec.describe Virtuous::Error do
|
7
|
+
let(:client) do
|
8
|
+
Virtuous::Client.new(
|
9
|
+
base_url: 'http://some-virtuous-uri.com',
|
10
|
+
api_key: 'test_api_key'
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
def stub(code, body)
|
15
|
+
stub_request(:any, /virtuous/).to_return(status: code, body: body)
|
16
|
+
end
|
17
|
+
|
18
|
+
def expect_failure(code, body)
|
19
|
+
url = 'http://some-virtuous-uri.com/anything'
|
20
|
+
|
21
|
+
expect do
|
22
|
+
client.get('anything')
|
23
|
+
end.to raise_error(Virtuous::Error, /#{code}: #{url} #{body}/)
|
24
|
+
end
|
25
|
+
|
26
|
+
def expect_success
|
27
|
+
expect { client.get('anything') }.to_not raise_error
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'informational responses' do
|
31
|
+
CODES.grep(100..199).each do |code|
|
32
|
+
it "does not raise error for #{code}" do
|
33
|
+
stub(code, '{}')
|
34
|
+
expect_success
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'success responses' do
|
40
|
+
CODES.grep(200..299).each do |code|
|
41
|
+
it "does not raise error for #{code}" do
|
42
|
+
stub(code, '{}')
|
43
|
+
expect_success
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'redirection responses' do
|
49
|
+
CODES.grep(300..399).each do |code|
|
50
|
+
it "does not raise error for #{code}" do
|
51
|
+
stub(code, '')
|
52
|
+
expect_success
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'client error responses' do
|
58
|
+
CODES.grep(400..499).each do |code|
|
59
|
+
it "raises exception for #{code}" do
|
60
|
+
stub(code, 'test client error')
|
61
|
+
expect_failure(code, 'test client error')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'server error responses' do
|
67
|
+
CODES.grep(500..599).each do |code|
|
68
|
+
it "raises exception for #{code}" do
|
69
|
+
stub(code, 'test client error')
|
70
|
+
expect_failure(code, 'test client error')
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Virtuous::Client::ContactAddress, type: :model do
|
4
|
+
include_context 'resource specs'
|
5
|
+
|
6
|
+
describe '#get_contact_addresses(contact_id)' do
|
7
|
+
subject(:resource) { client.get_contact_addresses(1) }
|
8
|
+
|
9
|
+
it 'returns a list of addresses' do
|
10
|
+
expect(subject).to be_a(Array)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'passes options' do
|
14
|
+
expect(client).to receive(:get)
|
15
|
+
.with('api/ContactAddress/ByContact/1')
|
16
|
+
.and_call_original
|
17
|
+
resource
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#create_contact_address(data)' do
|
22
|
+
subject(:resource) do
|
23
|
+
client.create_contact_address(
|
24
|
+
contact_id: 1, label: 'Home address', address1: '324 Frank Island',
|
25
|
+
address2: 'Apt. 366', city: 'Antonioborough', state: 'Massachusetts', postal: '27516',
|
26
|
+
country: 'USA'
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'passes options' do
|
31
|
+
expect(client).to receive(:post)
|
32
|
+
.with(
|
33
|
+
'api/ContactAddress',
|
34
|
+
{
|
35
|
+
'contactId' => 1, 'label' => 'Home address', 'address1' => '324 Frank Island',
|
36
|
+
'address2' => 'Apt. 366', 'city' => 'Antonioborough', 'state' => 'Massachusetts',
|
37
|
+
'postal' => '27516', 'country' => 'USA'
|
38
|
+
}
|
39
|
+
)
|
40
|
+
.and_call_original
|
41
|
+
resource
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'returns a hash' do
|
45
|
+
expect(resource).to be_a(Hash)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe '#update_contact_address(id, data)' do
|
50
|
+
subject(:resource) do
|
51
|
+
client.update_contact_address(
|
52
|
+
1, label: 'Home address', address1: '324 Frank Island', address2: 'Apt. 366',
|
53
|
+
city: 'Antonioborough', state: 'Massachusetts', postal: '27516', country: 'USA'
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'passes options' do
|
58
|
+
expect(client).to receive(:put)
|
59
|
+
.with(
|
60
|
+
'api/ContactAddress/1',
|
61
|
+
{
|
62
|
+
'label' => 'Home address', 'address1' => '324 Frank Island', 'address2' => 'Apt. 366',
|
63
|
+
'city' => 'Antonioborough', 'state' => 'Massachusetts', 'postal' => '27516',
|
64
|
+
'country' => 'USA'
|
65
|
+
}
|
66
|
+
)
|
67
|
+
.and_call_original
|
68
|
+
resource
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'returns a hash' do
|
72
|
+
expect(resource).to be_a(Hash)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Virtuous::Client::Contact, type: :model do
|
4
|
+
include_context 'resource specs'
|
5
|
+
|
6
|
+
describe '#find_contact_by_email(email)' do
|
7
|
+
it 'returns a hash' do
|
8
|
+
expect(client.find_contact_by_email('email@test.com')).to be_a(Hash)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'queries contacts' do
|
12
|
+
expect(client).to receive(:get).with('api/Contact/Find',
|
13
|
+
{ email: 'email@test.com' }).and_call_original
|
14
|
+
|
15
|
+
resource = client.find_contact_by_email('email@test.com')
|
16
|
+
|
17
|
+
expect(resource[:id]).to eq(1)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#get_contact(id)' do
|
22
|
+
it 'returns a hash' do
|
23
|
+
expect(client.get_contact(1)).to be_a(Hash)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'queries contacts' do
|
27
|
+
expect(client).to receive(:get).with('api/Contact/1').and_call_original
|
28
|
+
|
29
|
+
resource = client.get_contact(1)
|
30
|
+
|
31
|
+
expect(resource[:id]).to eq(1)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#import_contact(data)' do
|
36
|
+
subject(:resource) do
|
37
|
+
client.import_contact(
|
38
|
+
reference_source: 'Test source',
|
39
|
+
reference_id: 123,
|
40
|
+
contact_type: 'Organization',
|
41
|
+
name: 'Test Org',
|
42
|
+
title: 'Mr',
|
43
|
+
first_name: 'Test',
|
44
|
+
last_name: 'Individual',
|
45
|
+
email: 'test_individual@email.com'
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'passes options' do
|
50
|
+
expect(client).to receive(:post)
|
51
|
+
.with(
|
52
|
+
'api/Contact/Transaction',
|
53
|
+
{
|
54
|
+
'referenceSource' => 'Test source',
|
55
|
+
'referenceId' => 123,
|
56
|
+
'contactType' => 'Organization',
|
57
|
+
'name' => 'Test Org',
|
58
|
+
'title' => 'Mr',
|
59
|
+
'firstName' => 'Test',
|
60
|
+
'lastName' => 'Individual',
|
61
|
+
'email' => 'test_individual@email.com'
|
62
|
+
}
|
63
|
+
)
|
64
|
+
.and_call_original
|
65
|
+
resource
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe '#create_contact(data)' do
|
70
|
+
subject(:resource) do
|
71
|
+
client.create_contact(
|
72
|
+
reference_source: 'Test source',
|
73
|
+
reference_id: 123,
|
74
|
+
contact_type: 'Organization',
|
75
|
+
name: 'Test Org',
|
76
|
+
contact_individuals: [{
|
77
|
+
first_name: 'Test',
|
78
|
+
last_name: 'Individual'
|
79
|
+
}]
|
80
|
+
)
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'passes options' do
|
84
|
+
expect(client).to receive(:post)
|
85
|
+
.with(
|
86
|
+
'api/Contact',
|
87
|
+
{
|
88
|
+
'referenceSource' => 'Test source',
|
89
|
+
'referenceId' => 123,
|
90
|
+
'contactType' => 'Organization',
|
91
|
+
'name' => 'Test Org',
|
92
|
+
'contactIndividuals' => [{
|
93
|
+
'firstName' => 'Test',
|
94
|
+
'lastName' => 'Individual'
|
95
|
+
}]
|
96
|
+
}
|
97
|
+
)
|
98
|
+
.and_call_original
|
99
|
+
resource
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'returns a hash' do
|
103
|
+
expect(resource).to be_a(Hash)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe '#update_contact(id, data)' do
|
108
|
+
subject(:resource) do
|
109
|
+
client.update_contact(
|
110
|
+
1,
|
111
|
+
reference_source: 'Test source',
|
112
|
+
reference_id: 123,
|
113
|
+
contact_type: 'Organization',
|
114
|
+
name: 'Test Org'
|
115
|
+
)
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'passes options' do
|
119
|
+
expect(client).to receive(:put)
|
120
|
+
.with(
|
121
|
+
'api/Contact/1',
|
122
|
+
{
|
123
|
+
'referenceSource' => 'Test source',
|
124
|
+
'referenceId' => 123,
|
125
|
+
'contactType' => 'Organization',
|
126
|
+
'name' => 'Test Org'
|
127
|
+
}
|
128
|
+
)
|
129
|
+
.and_call_original
|
130
|
+
resource
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'returns a hash' do
|
134
|
+
expect(resource).to be_a(Hash)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Virtuous::Client::Individual, type: :model do
|
4
|
+
include_context 'resource specs'
|
5
|
+
|
6
|
+
describe '#gift_designation_query_options' do
|
7
|
+
it 'returns a hash' do
|
8
|
+
expect(client.gift_designation_query_options).to be_a(Hash)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'queries options' do
|
12
|
+
expect(client).to receive(:get).with('api/GiftDesignation/QueryOptions').and_call_original
|
13
|
+
|
14
|
+
response = client.gift_designation_query_options
|
15
|
+
|
16
|
+
expect(response).to have_key(:options)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#query_gift_designations(**options)' do
|
21
|
+
it 'returns a list of designations' do
|
22
|
+
response = client.query_gift_designations
|
23
|
+
expect(response).to be_a(Hash)
|
24
|
+
|
25
|
+
expect(response).to have_key(:list)
|
26
|
+
expect(response).to have_key(:total)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'sends take as a query param' do
|
30
|
+
expect(client).to receive(:post).with(URI('api/GiftDesignation/Query?take=12'),
|
31
|
+
{}).and_call_original
|
32
|
+
|
33
|
+
client.query_gift_designations(take: 12)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'sends skip as a query param' do
|
37
|
+
expect(client).to receive(:post).with(URI('api/GiftDesignation/Query?skip=12'),
|
38
|
+
{}).and_call_original
|
39
|
+
|
40
|
+
client.query_gift_designations(skip: 12)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'sends sort_by in the body' do
|
44
|
+
expect(client).to receive(:post).with(URI('api/GiftDesignation/Query'), { 'sortBy' => 'Id' })
|
45
|
+
.and_call_original
|
46
|
+
|
47
|
+
client.query_gift_designations(sort_by: 'Id')
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'sends descending in the body' do
|
51
|
+
expect(client).to receive(:post).with(
|
52
|
+
URI('api/GiftDesignation/Query'), { 'descending' => true }
|
53
|
+
).and_call_original
|
54
|
+
|
55
|
+
client.query_gift_designations(descending: true)
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'sends conditions in the body' do
|
59
|
+
expect(client).to receive(:post).with(
|
60
|
+
URI('api/GiftDesignation/Query'), { 'groups' => [{ 'conditions' => [{
|
61
|
+
'parameter' => 'Gift Id', 'operator' => 'Is', 'value' => 102
|
62
|
+
}] }] }
|
63
|
+
).and_call_original
|
64
|
+
|
65
|
+
client.query_gift_designations(conditions: [{
|
66
|
+
parameter: 'Gift Id', operator: 'Is', value: 102
|
67
|
+
}])
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|