wuparty 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/README.rdoc +7 -0
  3. data/lib/wuparty.rb +56 -274
  4. data/test/wuparty_test.rb +17 -12
  5. metadata +7 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '09a964df85dabf867074ea0b08ab6513a04d878c6e9dd6c1e8d0f35b40a0dd93'
4
- data.tar.gz: ab0a9f3fbc5c15d6a0bc8303be4e6c9f995d72f253d8dc8e5bf400b590dd8645
3
+ metadata.gz: 234b301e801407f22b72b131811d66f55a01a181caf57abbd38d8b910e5ba46b
4
+ data.tar.gz: 3ad467ad15196ba565133fd4c0aa229838e73f8fb1e682b1f3267837ff46bb06
5
5
  SHA512:
6
- metadata.gz: 6943a1829998b90acfe6c3f8b6de7f64942adc05b164f8ef82d6a251604d326c9b98f41883917f5feaf051253a892c68a2f0e67cbed1dacce9dc2566c1ef5921
7
- data.tar.gz: 5e13f8e94e47ae54dddc8e3e3c35e081d47c2be2bbc093bf7b6e9166d29e7556f33fe561bc488f197972299e1269b6f77bcf9ca9f41c2a04528689aa96561b09
6
+ metadata.gz: c51e66a8b3e8a39659932763c153633590eb339317bf552cf96103f1a7067155a5b6f09cb6061ca30b1099062069ccde5e2ea2156ed32ea4be0f6202f3ee58d1
7
+ data.tar.gz: c67eea8b6b4b0177ae6c3bff4d46f061daa11e96f24c64f779b8da7c78c67d42e77711836a86f599eb70f43349b88599dface3e93a05ee74933085691f9da4a6
@@ -32,8 +32,15 @@ Make sure you have latest version installed (1.0.0 or higher).
32
32
  API_KEY = 'AAAA-BBBB-CCCC-DDDD'
33
33
  FORM_ID = 'my-form-id'
34
34
 
35
+ ENDPOINT_DOMAIN = 'wufoo.com'
36
+ ENDPOINT_PREFIX = 'YourPrefix'
37
+
35
38
  wufoo = WuParty.new(ACCOUNT, API_KEY)
36
39
 
40
+ If your Wufoo domain is not "wufoo.com" (e.g. "wufoo.eu") and/or your account prefix does not match your account name, you can pass those in:
41
+
42
+ wufoo = WuParty.new(ACCOUNT, API_KEY, domain: 'wufoo.eu', account_prefix: 'myaccount')
43
+
37
44
  === Login
38
45
 
39
46
  result = WuParty.login(myIntegrationKey, users_email, users_password)
@@ -1,15 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'httparty'
2
- gem 'multipart-post'
3
- require 'net/http/post/multipart'
4
- gem 'mime-types'
5
- require 'mime/types'
4
+
5
+ require_relative './wuparty/entity'
6
+ require_relative './wuparty/form'
7
+ require_relative './wuparty/report'
8
+ require_relative './wuparty/user'
9
+ require_relative './wuparty/version'
6
10
 
7
11
  class WuParty
8
12
  include HTTParty
9
13
  format :json
10
14
 
11
- VERSION = '1.2.3'
12
-
13
15
  # Represents a general error connecting to the Wufoo service
14
16
  class ConnectionError < RuntimeError; end
15
17
 
@@ -24,58 +26,69 @@ class WuParty
24
26
  attr_reader :code
25
27
  end
26
28
 
27
- ENDPOINT = 'https://%s.wufoo.com/api/v3'
28
29
  API_VERSION = '3.0'
29
30
 
30
31
  # uses the Login API to fetch a user's API key
31
32
  def self.login(integration_key, email, password, account = nil)
32
- result = self.post("https://wufoo.com/api/v3/login.json", { :body => { :integrationKey => integration_key, :email => email, :password => password, :subdomain => account }})
33
- if result.is_a?(String)
34
- raise ConnectionError, result
35
- elsif result['HTTPCode']
36
- raise HTTPError.new(result['HTTPCode'], result['Text'])
37
- else
38
- result
39
- end
33
+ result = post(
34
+ 'https://wufoo.com/api/v3/login.json',
35
+ body: {
36
+ integrationKey: integration_key,
37
+ email: email,
38
+ password: password,
39
+ subdomain: account
40
+ }
41
+ )
42
+ raise ConnectionError, result if result.is_a?(String)
43
+ raise HTTPError.new(result['HTTPCode'], result['Text']) if result['HTTPCode']
44
+ result
40
45
  end
41
46
 
42
47
  # Create a new WuParty object
43
- def initialize(account, api_key)
48
+ def initialize(account, api_key, domain: 'wufoo.com', account_prefix: nil)
44
49
  @account = account
45
50
  @api_key = api_key
51
+ @domain = domain
52
+ @account_prefix = account_prefix || @account
46
53
  @field_numbers = {}
47
54
  end
48
55
 
49
56
  # Returns list of forms and details accessible by the user account.
50
57
  def forms
51
58
  get(:forms)['Forms'].map do |details|
52
- Form.new(details['Url'], :party => self, :details => details)
59
+ Form.new(details['Url'], party: self, details: details)
53
60
  end
54
61
  end
55
62
 
56
63
  # Returns list of reports and details accessible by the user account.
57
64
  def reports
58
65
  get(:reports)['Reports'].map do |details|
59
- Report.new(details['Url'], :party => self, :details => details)
66
+ Report.new(details['Url'], party: self, details: details)
60
67
  end
61
68
  end
62
69
 
63
70
  # Returns list of users and details.
64
71
  def users
65
72
  get(:users)['Users'].map do |details|
66
- User.new(details['Url'], :party => self, :details => details)
73
+ User.new(details['Url'], party: self, details: details)
67
74
  end
68
75
  end
69
76
 
70
77
  # Returns details about the specified form.
71
78
  def form(form_id)
72
- if f = get("forms/#{form_id}")['Forms']
73
- Form.new(f.first['Url'], :party => self, :details => f.first)
74
- end
79
+ return unless (f = get("forms/#{form_id}")['Forms'])
80
+ Form.new(f.first['Url'], party: self, details: f.first)
75
81
  end
76
82
 
77
- def add_webhook(form_id, url, metadata = false, handshakeKey = "")
78
- put("forms/#{form_id}/webhooks", :body => {'url' => url, 'handshakeKey' => handshakeKey, 'metadata' => metadata})
83
+ def add_webhook(form_id, url, metadata = false, handshake_key = '')
84
+ put(
85
+ "forms/#{form_id}/webhooks",
86
+ body: {
87
+ 'url' => url,
88
+ 'handshakeKey' => handshake_key,
89
+ 'metadata' => metadata
90
+ }
91
+ )
79
92
  end
80
93
 
81
94
  def delete_webhook(form_id, webhook_hash)
@@ -84,274 +97,43 @@ class WuParty
84
97
 
85
98
  # Returns details about the specified report.
86
99
  def report(report_id)
87
- if r = get("reports/#{report_id}")['Reports']
88
- Report.new(r.first['Url'], :party => self, :details => r.first)
89
- end
100
+ return unless (r = get("reports/#{report_id}")['Reports'])
101
+ Report.new(r.first['Url'], party: self, details: r.first)
90
102
  end
91
103
 
92
- def get(method, options={}) # :nodoc:
104
+ def get(method, options = {}) # :nodoc:
93
105
  handle_http_verb(:get, method, options)
94
106
  end
95
107
 
96
- def post(method, options={}) # :nodoc:
108
+ def post(method, options = {}) # :nodoc:
97
109
  handle_http_verb(:post, method, options)
98
110
  end
99
111
 
100
- def put(method, options={}) # :nodoc:
112
+ def put(method, options = {}) # :nodoc:
101
113
  handle_http_verb(:put, method, options)
102
114
  end
103
115
 
104
- def delete(method, options={}) # :nodoc:
116
+ def delete(method, options = {}) # :nodoc:
105
117
  handle_http_verb(:delete, method, options)
106
118
  end
107
119
 
108
120
  private
109
121
 
110
- def base_url
111
- ENDPOINT % @account
112
- end
113
-
114
- def handle_http_verb(verb, action, options={})
115
- options.merge!(:basic_auth => {:username => @api_key})
116
- url = "#{base_url}/#{action}.json"
117
- result = self.class.send(verb, url, options)
118
- begin
119
- result.to_s # trigger parse error if possible
120
- rescue MultiJson::DecodeError => e
121
- raise HTTPError.new(500, e.message)
122
- end
123
- if result.is_a?(String)
124
- raise ConnectionError, result
125
- elsif result['HTTPCode']
126
- raise HTTPError.new(result['HTTPCode'], result['Text'])
127
- else
128
- result
129
- end
130
- end
131
-
132
- public
133
-
134
- # ----------
135
-
136
- class Entity # :nodoc:
137
- include HTTParty
138
- format :json
139
-
140
- def initialize(id, options)
141
- @id = id
142
- if options[:party]
143
- @party = options[:party]
144
- elsif options[:account] and options[:api_key]
145
- @party = WuParty.new(options[:account], options[:api_key])
146
- else
147
- raise WuParty::InitializationException, "You must either specify a :party object or pass the :account and :api_key options. Please see the README."
148
- end
149
- @details = options[:details]
150
- end
151
-
152
- attr_reader :id
153
- attr_accessor :details
154
- end
155
-
156
- # Wraps an individual Wufoo Form.
157
- # == Instantiation
158
- # There are two ways to instantiate a Form object:
159
- # 1. Via the parent WuParty object that represents the account.
160
- # 2. Via the WuParty::Form class directly.
161
- # wufoo = WuParty.new(ACCOUNT, API_KEY)
162
- # form = wufoo.form(FORM_ID)
163
- # # or...
164
- # form = WuParty::Form.new(FORM_ID, :account => ACCOUNT, :api_key => API_KEY)
165
- # The first technique makes a call to the Wufoo API to get the form details,
166
- # while the second technique lazily loads the form details, once something is accessed via [].
167
- # == \Form Details
168
- # Access form details like it is a Hash, e.g.:
169
- # form['Name']
170
- # form['RedirectMessage']
171
- class Form < Entity
172
- # Returns field details for the form.
173
- def fields
174
- @party.get("forms/#{@id}/fields")['Fields']
175
- end
176
-
177
- # Access form details.
178
- def [](id)
179
- @details ||= @party.form(@id)
180
- @details[id]
181
- end
182
-
183
- def add_webhook(url, metadata = false, handshakeKey = "")
184
- @party.add_webhook(@details["Hash"], url, metadata, handshakeKey)
185
- end
186
-
187
- def delete_webhook(webhook_id)
188
- @party.delete_webhook(@details["Hash"], webhook_id)
189
- end
190
-
191
- # Returns fields and subfields, as a flattened array, e.g.
192
- # [{'ID' => 'Field1', 'Title' => 'Name - First', 'Type' => 'shortname', 'Required' => true }, # (subfield)
193
- # {'ID' => 'Field2', 'Title' => 'Name - Last', 'Type' => 'shortname', 'Required' => true }, # (subfield)
194
- # {'ID' => 'Field3', 'Title' => 'Birthday', 'Type' => 'date', 'Required' => flase}] # (field)
195
- # By default, only fields that can be submitted are returned. Pass *true* as the first arg to return all fields.
196
- def flattened_fields(all=false)
197
- flattened = []
198
- fields.each do |field|
199
- next unless all or field['ID'] =~ /^Field/
200
- if field['SubFields']
201
- field['SubFields'].each do |sub_field|
202
- flattened << {'ID' => sub_field['ID'], 'Title' => field['Title'] + ' - ' + sub_field['Label'], 'Type' => field['Type'], 'Required' => field['IsRequired'] == '1'}
203
- end
204
- else
205
- flattened << {'ID' => field['ID'], 'Title' => field['Title'], 'Type' => field['Type'], 'Required' => field['IsRequired'] == '1'}
206
- end
207
- end
208
- flattened
209
- end
210
-
211
- # Return entries already submitted to the form.
212
- #
213
- # Supports:
214
- # - filtering:
215
- # entries(:filters => [['Field1', 'Is_equal_to', 'Tim']])
216
- # entries(:filters => [['Field1', 'Is_equal_to', 'Tim'], ['Field2', 'Is_equal_to', 'Morgan']], :filter_match => 'OR')
217
- #
218
- # - sorting:
219
- # entries(:sort => 'EntryId DESC')
220
- #
221
- # - limiting:
222
- # entries(:limit => 5)
223
- #
224
- # See http://wufoo.com/docs/api/v3/entries/get/#filter for details
225
- def entries(options={})
226
- query = {}
227
-
228
- if options[:filters]
229
- query['match'] = options[:filter_match] || 'AND'
230
- options[:filters].each_with_index do |filter, index|
231
- query["Filter#{ index + 1 }"] = filter.join(' ')
232
- end
233
- end
234
-
235
- if options[:limit]
236
- query[:pageSize] = options[:limit]
237
- end
238
-
239
- if options[:pageStart]
240
- query[:pageStart] = options[:pageStart]
241
- end
242
-
243
- if options[:system]
244
- query[:system] = true
245
- end
246
-
247
- if options[:sort]
248
- field, direction = options[:sort].split(' ')
249
- query[:sort] = field
250
- query[:sortDirection] = direction || 'ASC'
251
- end
252
-
253
- @party.get("forms/#{@id}/entries", :query => query)['Entries']
254
- end
255
-
256
- # Return entries already submitted to the form.
257
- #
258
- # Supports:
259
- # Same as Entries above with filtering.
260
- # form.count(:filters => [['Field1', 'Is_equal_to', 'Tim']])
261
- #
262
- # See http://wufoo.com/docs/api/v3/entries/get/#filter for details
263
- def count(options={})
264
- query = {}
265
-
266
- if options[:filters]
267
- query['match'] = options[:filter_match] || 'AND'
268
- options[:filters].each_with_index do |filter, index|
269
- query["Filter#{ index + 1 }"] = filter.join(' ')
270
- end
271
- end
272
-
273
- if options[:system]
274
- query[:system] = true
275
- end
276
-
277
- @party.get("forms/#{@id}/entries/count", :query => query)['EntryCount']
278
- end
279
-
280
-
281
- # Submit form data to the form.
282
- # Pass data as a hash, with field ids as the hash keys, e.g.
283
- # submit('Field1' => 'Tim', 'Field2' => 'Morgan')
284
- # Return value is a Hash that includes the following keys:
285
- # * Status
286
- # * ErrorText
287
- # * FieldErrors
288
- # You must submit values for required fields (including all sub fields),
289
- # and dates must be formatted as <tt>YYYYMMDD</tt>.
290
- def submit(data)
291
- options = {}
292
- data.each do |key, value|
293
- if value.is_a?(Hash)
294
- type = MIME::Types.of(value[:path]).first.content_type rescue 'application/octet-stream'
295
- options[:multipart] ||= {}
296
- options[:multipart][key] = {:type => type, :path => value[:path]}
297
- else
298
- options[:body] ||= {}
299
- options[:body][key] = value
300
- end
301
- end
302
- @party.post("forms/#{@id}/entries", options)
303
- end
304
-
305
- # Returns comment details for the form.
306
- # See Wufoo API documentation for possible options,
307
- # e.g. to filter comments for a specific form entry:
308
- # form.comments('entryId' => 123)
309
- def comments(options={})
310
- options = {:query => options} if options.any?
311
- @party.get("forms/#{@id}/comments", options)['Comments']
312
- end
122
+ def base_url
123
+ "https://#{@account_prefix}.#{@domain}/api/v3"
313
124
  end
314
125
 
315
- # Wraps an individual Wufoo Report.
316
- # == Instantiation
317
- # There are two ways to instantiate a Report object:
318
- # 1. Via the parent WuParty object that represents the account.
319
- # 2. Via the WuParty::Report class directly.
320
- # wufoo = WuParty.new(ACCOUNT, API_KEY)
321
- # report = wufoo.report(REPORT_ID)
322
- # # or...
323
- # report = WuParty::Report.new(REPORT_ID, :account => ACCOUNT, :api_key => API_KEY)
324
- # The first technique makes a call to the Wufoo API to get the report details,
325
- # while the second technique lazily loads the report details, once something is accessed via [].
326
- # == \Report Details
327
- # Access report details like it is a Hash, e.g.:
328
- # report['Name']
329
- class Report < Entity
330
- # Access report details.
331
- def [](id)
332
- @details ||= @party.report(@id)
333
- @details[id]
126
+ def handle_http_verb(verb, action, options = {})
127
+ options[:basic_auth] = { username: @api_key }
128
+ url = "#{base_url}/#{action}.json"
129
+ result = self.class.send(verb, url, options)
130
+ begin
131
+ result.to_s # trigger parse error if possible
132
+ rescue MultiJson::DecodeError => e
133
+ raise HTTPError.new(500, e.message)
334
134
  end
335
-
336
- # Returns field details for the report
337
- def fields
338
- @party.get("reports/#{@id}/fields")['Fields']
339
- end
340
-
341
- # Returns widget details for the report
342
- def widgets
343
- @party.get("reports/#{@id}/widgets")['Widgets']
344
- end
345
- end
346
-
347
- # Wraps an individual Wufoo User.
348
- class User < Entity
349
-
350
- # Access user details.
351
- def [](id)
352
- @details ||= @party.report(@id)
353
- @details[id]
354
- end
355
-
135
+ raise ConnectionError, result if result.is_a?(String)
136
+ raise HTTPError.new(result['HTTPCode'], result['Text']) if result['HTTPCode']
137
+ result
356
138
  end
357
139
  end
@@ -2,14 +2,13 @@ require './lib/wuparty'
2
2
  require 'test/unit'
3
3
 
4
4
  class WuPartyTest < Test::Unit::TestCase
5
-
6
5
  # Must create a form called "Test Form" and pass in its id
7
6
  # via the ENV variable WUFOO_FORM_ID.
8
7
  # Give the form standard name and address fields.
9
8
  # Make the name field required.
10
9
 
11
10
  def setup
12
- if ENV['WUFOO_ACCOUNT'] and ENV['WUFOO_API_KEY'] and ENV['WUFOO_FORM_ID']
11
+ if ENV['WUFOO_ACCOUNT'] && ENV['WUFOO_API_KEY'] && ENV['WUFOO_FORM_ID']
13
12
  @wufoo = WuParty.new(ENV['WUFOO_ACCOUNT'], ENV['WUFOO_API_KEY'])
14
13
  @form_id = ENV['WUFOO_FORM_ID']
15
14
  else
@@ -29,7 +28,7 @@ class WuPartyTest < Test::Unit::TestCase
29
28
  end
30
29
 
31
30
  def test_get_form_id
32
- assert_equal 1, @wufoo.forms.select {|f| f.id == 'test-form'}.length
31
+ assert_equal 1, @wufoo.forms.select { |f| f.id == 'test-form' }.length
33
32
  end
34
33
 
35
34
  def test_form_by_hash
@@ -38,7 +37,7 @@ class WuPartyTest < Test::Unit::TestCase
38
37
  end
39
38
 
40
39
  def test_form_directly
41
- form = WuParty::Form.new(@form_id, :account => ENV['WUFOO_ACCOUNT'], :api_key => ENV['WUFOO_API_KEY'])
40
+ form = WuParty::Form.new(@form_id, account: ENV['WUFOO_ACCOUNT'], api_key: ENV['WUFOO_API_KEY'])
42
41
  assert_equal 'Test Form', form['Name']
43
42
  end
44
43
 
@@ -65,7 +64,14 @@ class WuPartyTest < Test::Unit::TestCase
65
64
 
66
65
  def test_form_submit
67
66
  form = @wufoo.form(@form_id)
68
- result = form.submit('Field1' => 'Tim', 'Field2' => 'Morgan', 'Field3' => '4010 W. New Orleans', 'Field5' => 'Broken Arrow', 'Field6' => 'OK', 'Field7' => '74011')
67
+ result = form.submit(
68
+ 'Field1' => 'Tim',
69
+ 'Field2' => 'Morgan',
70
+ 'Field3' => '4010 W. New Orleans',
71
+ 'Field5' => 'Broken Arrow',
72
+ 'Field6' => 'OK',
73
+ 'Field7' => '74011'
74
+ )
69
75
  assert_equal 1, result['Success']
70
76
  assert result['EntryId']
71
77
  assert result['EntryLink']
@@ -84,7 +90,7 @@ class WuPartyTest < Test::Unit::TestCase
84
90
  assert_equal 1, result['FieldErrors'].length
85
91
  error = result['FieldErrors'].first
86
92
  assert_equal 'Field1', error['ID']
87
- assert_match /required/i, error['ErrorText']
93
+ assert_match(/required/i, error['ErrorText'])
88
94
  end
89
95
 
90
96
  def test_entries
@@ -97,17 +103,16 @@ class WuPartyTest < Test::Unit::TestCase
97
103
  form = @wufoo.form(@form_id)
98
104
  form.submit('Field1' => 'Tim', 'Field2' => 'Morgan')
99
105
  id = form.submit('Field1' => 'Jane', 'Field2' => 'Smith')['EntryId']
100
- assert form.entries(:filters => [['Field2', 'Is_equal_to', 'Morgan']]).any?
101
- assert_equal 1, form.entries(:filters => [['EntryId', 'Is_equal_to', id]]).length
106
+ assert form.entries(filters: [%w[Field2 Is_equal_to Morgan]]).any?
107
+ assert_equal 1, form.entries(filters: [['EntryId', 'Is_equal_to', id]]).length
102
108
  end
103
109
 
104
110
  def test_add_webhook
105
111
  # test with optional parameters
106
- response = @wufoo.add_webhook(@form_id, "http://#{ENV['WUFOO_ACCOUNT']}.com/#{@form_id}", true, "handshakeKey01")
107
- assert_match /[a-z0-9]{6}/i, response['WebHookPutResult']['Hash']
112
+ response = @wufoo.add_webhook(@form_id, "http://#{ENV['WUFOO_ACCOUNT']}.com/#{@form_id}", true, 'handshakeKey01')
113
+ assert_match(/[a-z0-9]{6}/i, response['WebHookPutResult']['Hash'])
108
114
  # test without optional parameters
109
115
  response = @wufoo.add_webhook(@form_id, "http://#{ENV['WUFOO_ACCOUNT']}.com/#{@form_id}-2")
110
- assert_match /[a-z0-9]{6}/i, response['WebHookPutResult']['Hash']
116
+ assert_match(/[a-z0-9]{6}/i, response['WebHookPutResult']['Hash'])
111
117
  end
112
-
113
118
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wuparty
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Morgan
@@ -25,33 +25,33 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.16.0
27
27
  - !ruby/object:Gem::Dependency
28
- name: multipart-post
28
+ name: mime-types
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 1.0.1
33
+ version: '1.16'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 1.0.1
40
+ version: '1.16'
41
41
  - !ruby/object:Gem::Dependency
42
- name: mime-types
42
+ name: multipart-post
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '1.16'
47
+ version: 1.0.1
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '1.16'
54
+ version: 1.0.1
55
55
  description:
56
56
  email: tim@timmorgan.org
57
57
  executables: []