wufoo_party 0.1.1 → 1.0.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 (4) hide show
  1. data/README.rdoc +68 -20
  2. data/lib/wufoo_party.rb +314 -56
  3. data/test/wufoo_party_test.rb +87 -28
  4. metadata +59 -10
data/README.rdoc CHANGED
@@ -1,44 +1,92 @@
1
1
  = WufooParty
2
2
 
3
- Lightweight wrapper for Wufoo API over HTTP using HTTParty.
3
+ WufooParty is a fairly lightweight wrapper for Wufoo's REST API[http://wufoo.com/docs/api/v3]
4
+ using HTTParty[http://httparty.rubyforge.org].
4
5
 
5
- == About
6
+ == API Support
6
7
 
7
- This is a very simple class that utilizes HTTParty -- a wonderful gem for
8
- consuming REST APIs.
8
+ Wufoo's REST API supports viewing and submitting entries, filtering entries,
9
+ viewing reports, and viewing users.
9
10
 
10
- This lib supports both Wufoo's query and submit api version 2.0.
11
+ This library supports all methods of Wufoo's API version 3.0.
12
+
13
+ There is an older version of this library (version 0.1.x) that only supports version 2 of Wufoo's API.
14
+ Make sure you have latest version installed (1.0.0 or higher).
15
+
16
+ == Source & Download
17
+
18
+ * {Homepage & Demo}[http://wufooparty.71m.us]
19
+ * {Source Code}[http://github.com/seven1m/wufoo_party]
20
+ * {RDoc Documentation}[http://seven1m.github.com/wufoo_party]
11
21
 
12
22
  == Installation
13
23
 
14
- sudo gem install wufoo_party
24
+ gem install wufoo_party
15
25
 
16
26
  == Usage
17
27
 
18
28
  require 'wufoo_party'
19
-
29
+
20
30
  ACCOUNT = 'accountname'
21
31
  API_KEY = 'AAAA-BBBB-CCCC-DDDD'
22
32
  FORM_ID = 'my-form-id'
23
-
33
+
24
34
  wufoo = WufooParty.new(ACCOUNT, API_KEY)
25
- # you must use field numbers, shown on the 'API Information' page in Wufoo
26
- wufoo.submit(FORM_ID, {
27
- '1' => 'Tim',
28
- '2' => 'Morgan'
35
+
36
+ wufoo.forms # list all accessible forms and details
37
+ form = wufoo.form(FORM_ID) # or details for a specific form
38
+
39
+ # query all entries
40
+ form.entries
41
+
42
+ # ...or filter entries (see http://wufoo.com/docs/api/v3/entries/get/#filter)
43
+ form.entries([['Field1', 'Is_equal_to', 'Tim']])
44
+
45
+ # To submit, use field numbers shown on the 'API Information' page in Wufoo
46
+ result = wufoo.submit(
47
+ 'Field1' => 'Tim',
48
+ 'Field2' => 'Morgan'
29
49
  })
30
- result = wufoo.query(FORM_ID)
31
- pp result['form']['Entries'].last['Pretty']
32
- # {"Last"=>"Morgan",
33
- # "Name"=>"Tim"}
50
+ if result['Success'] == 0
51
+ puts result['ErrorText']
52
+ end
34
53
 
35
54
  == Feedback
36
55
 
37
- I’d love to hear from you if you have suggestions for improvement, bug fixes, or whatever. Email me at tim@timmorgan.org or fork the project and send a pull request.
56
+ I’d love to hear from you if you have suggestions for improvement, bug fixes, or whatever.
57
+ Email me at mailto:tim@timmorgan.org or fork the project[http://github.com/seven1m/wufoo_party] and send a pull request.
58
+
59
+ http://timmorgan.org
38
60
 
39
- To run the tests, do this:
61
+ == Tests
62
+
63
+ To run the tests, you must create a form called "Test Form" and pass in its id via the
64
+ ENV variable WUFOO_FORM_ID. Give the form a standard name and address field.
65
+ Make the name field required. Then run:
40
66
 
41
67
  WUFOO_ACCOUNT=accountname \
42
68
  WUFOO_API_KEY=AAAA-BBBB-CCCC-DDDD \
43
- WUFOO_FORM_ID=my-form-id \
44
- ruby -rrubygems test/wufoo_party_test.rb
69
+ WUFOO_FORM_ID=test-form \
70
+ ruby -rrubygems test/wufoo_party_test.rb
71
+
72
+ == License
73
+
74
+ Copyright (c) 2010 Tim Morgan
75
+
76
+ Permission is hereby granted, free of charge, to any person obtaining a copy
77
+ of this software and associated documentation files (the "Software"), to deal
78
+ in the Software without restriction, including without limitation the rights
79
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
80
+ copies of the Software, and to permit persons to whom the Software is
81
+ furnished to do so, subject to the following conditions:
82
+
83
+ The above copyright notice and this permission notice shall be included in
84
+ all copies or substantial portions of the Software.
85
+
86
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
87
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
88
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
89
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
90
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
91
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
92
+ THE SOFTWARE.
data/lib/wufoo_party.rb CHANGED
@@ -1,79 +1,337 @@
1
1
  require 'httparty'
2
+ gem 'multipart-post'
3
+ require 'net/http/post/multipart'
4
+ gem 'mime-types'
5
+ require 'mime/types'
6
+
7
+ # multipart POST support from David Balater's fork of HTTParty:
8
+ # http://github.com/dbalatero/httparty
9
+ # :stopdoc:
10
+ module HTTParty
11
+ module ClassMethods
12
+ def post(path, options={})
13
+ klass = options[:multipart] ? Net::HTTP::Post::Multipart : Net::HTTP::Post
14
+ perform_request klass, path, options
15
+ end
16
+ end
17
+ class Request
18
+ SupportedHTTPMethods << Net::HTTP::Post::Multipart
19
+ private
20
+ def setup_raw_request
21
+ if multipart?
22
+ @file_handles = []
23
+ io_objects = {}
24
+
25
+ options[:multipart].each do |field_name, info|
26
+ fp = File.open(info[:path])
27
+ @file_handles << fp
28
+
29
+ io_objects[field_name] = UploadIO.new(fp,
30
+ info[:type],
31
+ info[:path])
32
+ end
33
+
34
+ options[:body].each do |field_name, value|
35
+ io_objects[field_name] = value
36
+ end
37
+
38
+ @raw_request = http_method.new(uri.request_uri,
39
+ io_objects)
40
+
41
+ # We have to duplicate and merge the headers set by the
42
+ # multipart object to make sure that Net::HTTP
43
+ # doesn't override them down the line when it calls
44
+ # initialize_http_header.
45
+ #
46
+ # Otherwise important headers like Content-Length,
47
+ # Accept, and Content-Type will be deleted.
48
+ original_headers = {}
49
+ @raw_request.each do |key, value|
50
+ original_headers[key] = value
51
+ end
52
+
53
+ options[:headers] ||= {}
54
+ original_headers.merge!(options[:headers])
55
+ options[:headers] = original_headers
56
+ else
57
+ @raw_request = http_method.new(uri.request_uri)
58
+ @raw_request.body = body if body
59
+ end
60
+
61
+ @raw_request.initialize_http_header options[:headers]
62
+ @raw_request.basic_auth(username, password) if options[:basic_auth]
63
+ end
64
+ def multipart?
65
+ Net::HTTP::Post::Multipart == http_method
66
+ end
67
+ end
68
+ end
69
+ # :startdoc:
2
70
 
3
71
  class WufooParty
4
72
  include HTTParty
5
73
  format :json
6
-
7
- QUERY_ENDPOINT = 'http://%s.wufoo.com/api/query/'
8
- SUBMIT_ENDPOINT = 'http://%s.wufoo.com/api/insert/'
9
- API_VERSION = '2.0'
10
-
74
+
75
+ VERSION = '1.0.0'
76
+
77
+ # Represents a general error connecting to the Wufoo service
78
+ class ConnectionError < RuntimeError; end
79
+
80
+ # Represents a specific error returned from Wufoo.
81
+ class HTTPError < RuntimeError
82
+ def initialize(code, message) # :nodoc:
83
+ @code = code
84
+ super(message)
85
+ end
86
+
87
+ # Error code
88
+ attr_reader :code
89
+ end
90
+
91
+ ENDPOINT = 'https://%s.wufoo.com/api/v3'
92
+ API_VERSION = '3.0'
93
+
11
94
  # Create a new WufooParty object
12
95
  def initialize(account, api_key)
13
96
  @account = account
14
97
  @api_key = api_key
15
98
  @field_numbers = {}
16
99
  end
17
-
18
- # Perform a query on a specific form_id.
19
- # Returns details about the form, as well as individual form submission details.
20
- def query(form_id)
21
- args = {
22
- 'w_api_key' => @api_key,
23
- 'w_version' => API_VERSION,
24
- 'w_form' => form_id
25
- }
26
- result = self.class.post(QUERY_ENDPOINT % @account, :body => args)
27
- add_title_to_fields!(result)
28
- result
100
+
101
+ # Returns list of forms and details accessible by the user account.
102
+ def forms
103
+ get(:forms)['Forms'].map do |details|
104
+ Form.new(details['Url'], :party => self, :details => details)
105
+ end
29
106
  end
30
-
31
- # Perform a submission to a specific form_id.
32
- # Returns status of operation.
33
- def submit(form_id, data={})
34
- args = {
35
- 'w_api_key' => @api_key,
36
- 'w_form' => form_id
37
- }.merge(data)
38
- self.class.post(SUBMIT_ENDPOINT % @account, :body => args)
107
+
108
+ # Returns list of reports and details accessible by the user account.
109
+ def reports
110
+ get(:reports)['Reports'].map do |details|
111
+ Report.new(details['Url'], :party => self, :details => details)
112
+ end
39
113
  end
40
-
41
- # Queries a form to get its field details
42
- def field_details(form_id)
43
- query(form_id)['form']['Fields']
114
+
115
+ # Returns list of users and details.
116
+ def users
117
+ get(:users)['Users'].map do |details|
118
+ User.new(details['Url'], :party => self, :details => details)
119
+ end
44
120
  end
45
-
46
- # Queries a form to get its field numbers and names and types
47
- def field_numbers_and_names_and_types(form_id)
48
- get_field_numbers(field_details(form_id))
121
+
122
+ # Returns details about the specified form.
123
+ def form(form_id)
124
+ if f = get("forms/#{form_id}")['Forms']
125
+ Form.new(f.first['Url'], :party => self, :details => f.first)
126
+ end
127
+ end
128
+
129
+ # Returns details about the specified report.
130
+ def report(report_id)
131
+ if r = get("reports/#{report_id}")['Reports']
132
+ Form.new(r.first['Url'], :party => self, :details => r.first)
133
+ end
134
+ end
135
+
136
+ def get(method, options={}) # :nodoc:
137
+ options.merge!(:basic_auth => {:username => @api_key})
138
+ url = "#{base_url}/#{method}.json"
139
+ result = self.class.get(url, options)
140
+ if result.is_a?(String)
141
+ raise ConnectionError, result
142
+ elsif result['HTTPCode']
143
+ raise HTTPError.new(result['HTTPCode'], result['Text'])
144
+ else
145
+ result
146
+ end
49
147
  end
50
-
51
- # Converts an array of field specs (returned by Wufoo) into a simple hash of <tt>{FIELDNUM => [FIELDNAME, FIELDTYPE]}</tt>
52
- def get_field_numbers(field_data, is_sub_fields=false, typeof=nil)
53
- field_data.inject({}) do |hash, field|
54
- if field['SubFields']
55
- hash.merge!(get_field_numbers(field['SubFields'], :is_sub_fields, field['Typeof']))
56
- elsif field['ColumnId'] =~ /^\d+$/
57
- title = is_sub_fields && field['ChoicesText'] ? field['ChoicesText'] : field['Title']
58
- hash[field['ColumnId']] = [title, field['Typeof'] || typeof]
148
+
149
+ def post(method, options={}) # :nodoc:
150
+ options.merge!(:basic_auth => {:username => @api_key})
151
+ url = "#{base_url}/#{method}.json"
152
+ result = self.class.post(url, options)
153
+ if result.is_a?(String)
154
+ raise ConnectionError, result
155
+ elsif result['HTTPCode']
156
+ raise HTTPError.new(result['HTTPCode'], result['Text'])
157
+ else
158
+ result
159
+ end
160
+ end
161
+
162
+ private
163
+
164
+ def base_url
165
+ ENDPOINT % @account
166
+ end
167
+
168
+ public
169
+
170
+ # ----------
171
+
172
+ class Entity # :nodoc:
173
+ include HTTParty
174
+ format :json
175
+
176
+ def initialize(id, options)
177
+ @id = id
178
+ if options[:party]
179
+ @party = options[:party]
180
+ elsif options[:account] and options[:api_key]
181
+ @party = WufooParty.new(options[:account], options[:api_key])
182
+ else
183
+ raise WufooParty::InitializationException, "You must either specify a :party object or pass the :account and :api_key options. Please see the README."
59
184
  end
60
- hash
185
+ @details = options[:details]
61
186
  end
187
+
188
+ attr_accessor :details
62
189
  end
63
-
64
- # Given the result of a query, adds a 'Pretty' key to each form entry
65
- # that includes the field titles.
66
- def add_title_to_fields!(query_result)
67
- if query_result['form'] and query_result['form']['Entries']
68
- nums = get_field_numbers(query_result['form']['Fields'])
69
- query_result['form']['Entries'].each do |entry|
70
- entry['Pretty'] = {}
71
- entry.keys.each do |key|
72
- if key =~ /^Field(\d+)$/ and title = nums[$1]
73
- entry['Pretty'][title] = entry[key]
190
+
191
+ # Wraps an individual Wufoo Form.
192
+ # == Instantiation
193
+ # There are two ways to instantiate a Form object:
194
+ # 1. Via the parent WufooParty object that represents the account.
195
+ # 2. Via the WufooParty::Form class directly.
196
+ # wufoo = WufooParty.new(ACCOUNT, API_KEY)
197
+ # form = wufoo.form(FORM_ID)
198
+ # # or...
199
+ # form = WufooParty::Form.new(FORM_ID, :account => ACCOUNT, :api_key => API_KEY)
200
+ # The first technique makes a call to the Wufoo API to get the form details,
201
+ # while the second technique lazily loads the form details, once something is accessed via [].
202
+ # == \Form Details
203
+ # Access form details like it is a Hash, e.g.:
204
+ # form['Name']
205
+ # form['RedirectMessage']
206
+ class Form < Entity
207
+ # Returns field details for the form.
208
+ def fields
209
+ @party.get("forms/#{@id}/fields")['Fields']
210
+ end
211
+
212
+ # Access form details.
213
+ def [](id)
214
+ @details ||= @party.form(@id)
215
+ @details[id]
216
+ end
217
+
218
+ # Returns fields and subfields, as a flattened array, e.g.
219
+ # [{'ID' => 'Field1', 'Title' => 'Name - First', 'Type' => 'shortname', 'Required' => true }, # (subfield)
220
+ # {'ID' => 'Field2', 'Title' => 'Name - Last', 'Type' => 'shortname', 'Required' => true }, # (subfield)
221
+ # {'ID' => 'Field3', 'Title' => 'Birthday', 'Type' => 'date', 'Required' => flase}] # (field)
222
+ # By default, only fields that can be submitted are returned. Pass *true* as the first arg to return all fields.
223
+ def flattened_fields(all=false)
224
+ flattened = []
225
+ fields.each do |field|
226
+ next unless all or field['ID'] =~ /^Field/
227
+ if field['SubFields']
228
+ field['SubFields'].each do |sub_field|
229
+ flattened << {'ID' => sub_field['ID'], 'Title' => field['Title'] + ' - ' + sub_field['Label'], 'Type' => field['Type'], 'Required' => field['IsRequired'] == '1'}
74
230
  end
231
+ else
232
+ flattened << {'ID' => field['ID'], 'Title' => field['Title'], 'Type' => field['Type'], 'Required' => field['IsRequired'] == '1'}
233
+ end
234
+ end
235
+ flattened
236
+ end
237
+
238
+ # Return entries already submitted to the form.
239
+ #
240
+ # If you need to filter entries, pass an array as the first argument:
241
+ # entries([[field_id, operator, value], ...])
242
+ # e.g.:
243
+ # entries([['EntryId', 'Is_after', 12], ['EntryId', 'Is_before', 17]])
244
+ # entries([['Field1', 'Is_equal', 'Tim']])
245
+ # The second arg is the match parameter (AND/OR) and defaults to 'AND', e.g.
246
+ # entries([['Field2', 'Is_equal', 'Morgan'], ['Field2', 'Is_equal', 'Smith']], 'OR')
247
+ # See http://wufoo.com/docs/api/v3/entries/get/#filter for details
248
+ def entries(filters=[], filter_match='AND')
249
+ if filters.any?
250
+ options = {'match' => filter_match}
251
+ filters.each_with_index do |filter, index|
252
+ options["Filter#{index+1}"] = filter.join(' ')
253
+ end
254
+ options = {:query => options}
255
+ else
256
+ options = {}
257
+ end
258
+ @party.get("forms/#{@id}/entries", options)['Entries']
259
+ end
260
+
261
+ # Submit form data to the form.
262
+ # Pass data as a hash, with field ids as the hash keys, e.g.
263
+ # submit('Field1' => 'Tim', 'Field2' => 'Morgan')
264
+ # Return value is a Hash that includes the following keys:
265
+ # * Status
266
+ # * ErrorText
267
+ # * FieldErrors
268
+ # You must submit values for required fields (including all sub fields),
269
+ # and dates must be formatted as <tt>YYYYMMDD</tt>.
270
+ def submit(data)
271
+ options = {}
272
+ data.each do |key, value|
273
+ if value.is_a?(Hash)
274
+ type = MIME::Types.of(value[:path]).first.content_type rescue 'application/octet-stream'
275
+ options[:multipart] ||= {}
276
+ options[:multipart][key] = {:type => type, :path => value[:path]}
277
+ else
278
+ options[:body] ||= {}
279
+ options[:body][key] = value
75
280
  end
76
281
  end
282
+ @party.post("forms/#{@id}/entries", options)
283
+ end
284
+
285
+ # Returns comment details for the form.
286
+ # See Wufoo API documentation for possible options,
287
+ # e.g. to filter comments for a specific form entry:
288
+ # form.comments('entryId' => 123)
289
+ def comments(options={})
290
+ options = {:query => options} if options.any?
291
+ @party.get("forms/#{@id}/comments", options)['Comments']
292
+ end
293
+ end
294
+
295
+ # Wraps an individual Wufoo Report.
296
+ # == Instantiation
297
+ # There are two ways to instantiate a Report object:
298
+ # 1. Via the parent WufooParty object that represents the account.
299
+ # 2. Via the WufooParty::Report class directly.
300
+ # wufoo = WufooParty.new(ACCOUNT, API_KEY)
301
+ # report = wufoo.report(REPORT_ID)
302
+ # # or...
303
+ # report = WufooParty::Report.new(REPORT_ID, :account => ACCOUNT, :api_key => API_KEY)
304
+ # The first technique makes a call to the Wufoo API to get the report details,
305
+ # while the second technique lazily loads the report details, once something is accessed via [].
306
+ # == \Report Details
307
+ # Access report details like it is a Hash, e.g.:
308
+ # report['Name']
309
+ class Report < Entity
310
+ # Access report details.
311
+ def [](id)
312
+ @details ||= @party.report(@id)
313
+ @details[id]
77
314
  end
315
+
316
+ # Returns field details for the report
317
+ def fields
318
+ @party.get("reports/#{@id}/fields")['Fields']
319
+ end
320
+
321
+ # Returns widget details for the report
322
+ def widgets
323
+ @party.get("reports/#{@id}/widgets")['Widgets']
324
+ end
325
+ end
326
+
327
+ # Wraps an individual Wufoo User.
328
+ class User < Entity
329
+
330
+ # Access user details.
331
+ def [](id)
332
+ @details ||= @party.report(@id)
333
+ @details[id]
334
+ end
335
+
78
336
  end
79
- end
337
+ end
@@ -2,7 +2,12 @@ require File.dirname(__FILE__) + '/../lib/wufoo_party'
2
2
  require 'test/unit'
3
3
 
4
4
  class WufooPartyTest < Test::Unit::TestCase
5
-
5
+
6
+ # Must create a form called "Test Form" and pass in its id
7
+ # via the ENV variable WUFOO_FORM_ID.
8
+ # Give the form standard name and address fields.
9
+ # Make the name field required.
10
+
6
11
  def setup
7
12
  if ENV['WUFOO_ACCOUNT'] and ENV['WUFOO_API_KEY'] and ENV['WUFOO_FORM_ID']
8
13
  @wufoo = WufooParty.new(ENV['WUFOO_ACCOUNT'], ENV['WUFOO_API_KEY'])
@@ -12,30 +17,84 @@ class WufooPartyTest < Test::Unit::TestCase
12
17
  exit(1)
13
18
  end
14
19
  end
15
-
16
- def test_connection
17
- assert @wufoo.query(@form_id)['form']
18
- end
19
-
20
- def test_submission
21
- start_count = @wufoo.query(@form_id)['form']['EntryCount'].to_i
22
- result = @wufoo.submit(@form_id) # blank submission - only works if no required fields
23
- assert_equal 'true', result['wufoo_submit'][0]['success']
24
- end_count = @wufoo.query(@form_id)['form']['EntryCount'].to_i
25
- assert_equal start_count+1, end_count
26
- end
27
-
28
- def test_get_field_numbers
29
- assert_equal(
30
- {'1' => ['Name', 'shortname'], '2' => ['Last', 'shortname'], '3' => ['Foo', 'date']},
31
- @wufoo.get_field_numbers([
32
- {"Title" => "Name", "Typeof" => "shortname", "SubFields" => [
33
- {"Title" => "Name", "ColumnId" => "1"},
34
- {"Title" => "Last", "ColumnId" => "2"}
35
- ]},
36
- {"Title" => "Foo", "ColumnId" => "3", "Typeof" => "date"}
37
- ])
38
- )
39
- end
40
-
41
- end
20
+
21
+ def test_forms
22
+ assert @wufoo.forms
23
+ end
24
+
25
+ def test_form
26
+ form = @wufoo.form(@form_id)
27
+ assert form
28
+ assert_equal 'Test Form', form['Name']
29
+ end
30
+
31
+ def test_form_by_hash
32
+ hash = @wufoo.form(@form_id)['Hash']
33
+ assert @wufoo.form(hash)
34
+ end
35
+
36
+ def test_form_directly
37
+ form = WufooParty::Form.new(@form_id, :account => ENV['WUFOO_ACCOUNT'], :api_key => ENV['WUFOO_API_KEY'])
38
+ assert_equal 'Test Form', form['Name']
39
+ end
40
+
41
+ def test_non_existent_form
42
+ assert_raise WufooParty::HTTPError do
43
+ @wufoo.form('does-not-exist')
44
+ end
45
+ end
46
+
47
+ def test_reports
48
+ assert @wufoo.reports
49
+ end
50
+
51
+ def test_users
52
+ assert @wufoo.users
53
+ end
54
+
55
+ def test_form_fields
56
+ form = @wufoo.form(@form_id)
57
+ field_names = form.fields.map { |f| f['Title'] }
58
+ assert field_names.include?('Name')
59
+ assert field_names.include?('Address')
60
+ end
61
+
62
+ def test_form_submit
63
+ form = @wufoo.form(@form_id)
64
+ result = form.submit('Field1' => 'Tim', 'Field2' => 'Morgan', 'Field3' => '4010 W. New Orleans', 'Field5' => 'Broken Arrow', 'Field6' => 'OK', 'Field7' => '74011')
65
+ assert_equal 1, result['Success']
66
+ assert result['EntryId']
67
+ assert result['EntryLink']
68
+ end
69
+
70
+ def test_form_submit_error
71
+ form = @wufoo.form(@form_id)
72
+ # test a form error -- non-existent field
73
+ result = form.submit('Field1' => 'Tim', 'Field2' => 'Morgan', 'Field100' => 'Foobar')
74
+ assert_equal 0, result['Success']
75
+ assert result['ErrorText']
76
+ assert_equal [], result['FieldErrors']
77
+ # test a field error -- nothing in a required field
78
+ result = form.submit('Field2' => 'Morgan')
79
+ assert_equal 0, result['Success']
80
+ assert_equal 1, result['FieldErrors'].length
81
+ error = result['FieldErrors'].first
82
+ assert_equal 'Field1', error['ID']
83
+ assert_match /required/i, error['ErrorText']
84
+ end
85
+
86
+ def test_entries
87
+ form = @wufoo.form(@form_id)
88
+ form.submit('Field1' => 'Tim', 'Field2' => 'Morgan')
89
+ assert form.entries.last['Field1'].any?
90
+ end
91
+
92
+ def test_filtering_entries
93
+ form = @wufoo.form(@form_id)
94
+ form.submit('Field1' => 'Tim', 'Field2' => 'Morgan')
95
+ id = form.submit('Field1' => 'Jane', 'Field2' => 'Smith')['EntryId']
96
+ assert form.entries([['Field2', 'Is_equal_to', 'Morgan']]).any?
97
+ assert_equal 1, form.entries([['EntryId', 'Is_equal_to', id]]).length
98
+ end
99
+
100
+ end
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wufoo_party
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
5
11
  platform: ruby
6
12
  authors:
7
13
  - Tim Morgan
@@ -9,19 +15,56 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2010-02-15 00:00:00 -06:00
18
+ date: 2010-08-29 00:00:00 -05:00
13
19
  default_executable:
14
20
  dependencies:
15
21
  - !ruby/object:Gem::Dependency
16
22
  name: httparty
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 5
30
+ segments:
31
+ - 0
32
+ - 6
33
+ - 1
34
+ version: 0.6.1
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: multipart-post
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 21
46
+ segments:
47
+ - 1
48
+ - 0
49
+ - 1
50
+ version: 1.0.1
17
51
  type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: mime-types
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
20
58
  requirements:
21
59
  - - ">="
22
60
  - !ruby/object:Gem::Version
23
- version: "0"
24
- version:
61
+ hash: 47
62
+ segments:
63
+ - 1
64
+ - 16
65
+ version: "1.16"
66
+ type: :runtime
67
+ version_requirements: *id003
25
68
  description:
26
69
  email: tim@timmorgan.org
27
70
  executables: []
@@ -44,23 +87,29 @@ rdoc_options: []
44
87
  require_paths:
45
88
  - lib
46
89
  required_ruby_version: !ruby/object:Gem::Requirement
90
+ none: false
47
91
  requirements:
48
92
  - - ">="
49
93
  - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
50
97
  version: "0"
51
- version:
52
98
  required_rubygems_version: !ruby/object:Gem::Requirement
99
+ none: false
53
100
  requirements:
54
101
  - - ">="
55
102
  - !ruby/object:Gem::Version
103
+ hash: 3
104
+ segments:
105
+ - 0
56
106
  version: "0"
57
- version:
58
107
  requirements: []
59
108
 
60
109
  rubyforge_project:
61
- rubygems_version: 1.3.5
110
+ rubygems_version: 1.3.7
62
111
  signing_key:
63
112
  specification_version: 3
64
- summary: Lightweight wrapper for Wufoo API over HTTP using HTTParty
113
+ summary: Ruby wrapper for Wufoo's REST API v3.
65
114
  test_files: []
66
115