jotform_api 1.0.2 → 1.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 (5) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -0
  3. data/lib/jotform.rb +263 -39
  4. data/test/test_jotform.rb +422 -0
  5. metadata +3 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2d7a59b7e1b81d562b984e90fb08c775d2c9bcf2085a9b86bf0dfa189523c4b8
4
- data.tar.gz: 619750907ce1036a66cf99ab88b3132df96b79a1c11cfc1186d9f573f57c6c88
3
+ metadata.gz: 2a562f46c62e4e902cebd9545442c1aab0e72641a2b57310573dfedcf74b1bc2
4
+ data.tar.gz: d2102b85a9a35a9b245dee134bde51a8149b8e2a13d06f8ac4b4a8361da46447
5
5
  SHA512:
6
- metadata.gz: c75f1af49cb4bc3edd9812d29237bfa6a15536b3430431beef90bd6aea31b9e805e9431688c381b4f777e66b8e2bd893ce55d270a4bef6340c31f1618d79da5b
7
- data.tar.gz: 552a143cf340b8ab9aa54ed6f0db8714ca7b92c4282d1aeddccd3288c2b364092339b1041dea72c48dc12c66ea7c106075fe58aeb4b53511c83d8175ecc34a3f
6
+ metadata.gz: 76af3ce4b8ca2db51e05cbd74167a15afd759f124533610fd2e6b08c66c74d0f0a5d78710e05db5350d34e72187c35723aa8b918a2c5be25202d8ef034cc08fa
7
+ data.tar.gz: 0140e95bc600fdddb37b1f17dbaa38c8755a2b8f07095344e064afbb0adac15793f9ae49cd7804d7cadccdfcaf3ee6cc1088b6d9138dfd50a4d9c71d52d81c3d
data/Rakefile CHANGED
@@ -2,6 +2,7 @@ require 'rake/testtask'
2
2
 
3
3
  Rake::TestTask.new do |t|
4
4
  t.libs << 'test'
5
+ t.libs << 'lib'
5
6
  end
6
7
 
7
8
  desc "Run tests"
data/lib/jotform.rb CHANGED
@@ -5,124 +5,348 @@ class Jotform
5
5
 
6
6
  # Create the object
7
7
  def initialize(apiKey = nil, baseURL = "http://api.jotform.com", apiVersion = "v1")
8
- @apiKey = apiKey
9
- @baseURL = baseURL
10
- @apiVersion = apiVersion
8
+ @apiKey = apiKey
9
+ @baseURL = baseURL
10
+ @apiVersion = apiVersion
11
11
  end
12
12
 
13
13
  def _executeHTTPRequest(endpoint, parameters = nil, type = "GET")
14
- url = [@baseURL, @apiVersion, endpoint].join("/").concat('?apiKey='+@apiKey)
15
- url = URI.parse(url)
14
+ url = [@baseURL, @apiVersion, endpoint].join("/").concat('?apiKey='+@apiKey)
15
+ url = URI.parse(url)
16
16
 
17
- if type == "GET"
18
- response = Net::HTTP.get_response(url)
19
- elsif type == "POST"
20
- response = Net::HTTP.post_form(url, parameters)
21
- end
17
+ if type == "GET"
18
+ response = Net::HTTP.get_response(url)
19
+ elsif type == "POST"
20
+ response = Net::HTTP.post_form(url, parameters)
21
+ elsif type == "PUT" || type == "DELETE"
22
+ http = Net::HTTP.new(url.host, url.port)
23
+ http.use_ssl = (url.scheme == "https")
22
24
 
23
- if response.kind_of? Net::HTTPSuccess
24
- return JSON.parse(response.body)["content"]
25
+ if type == "PUT"
26
+ request = Net::HTTP::Put.new(url.request_uri)
27
+ if parameters
28
+ if parameters.is_a?(String)
29
+ request.body = parameters
30
+ else
31
+ request.body = JSON.generate(parameters)
32
+ end
33
+ request["Content-Type"] = "application/json"
34
+ end
25
35
  else
26
- puts JSON.parse(response.body)["message"]
27
- return nil
36
+ request = Net::HTTP::Delete.new(url.request_uri)
28
37
  end
38
+
39
+ response = http.request(request)
40
+ end
41
+
42
+ if response.kind_of? Net::HTTPSuccess
43
+ return JSON.parse(response.body)["content"]
44
+ else
45
+ puts JSON.parse(response.body)["message"]
46
+ return nil
47
+ end
29
48
  end
30
49
 
31
50
  def _executeGetRequest(endpoint, parameters = [])
32
- return _executeHTTPRequest(endpoint,parameters, "GET")
51
+ return _executeHTTPRequest(endpoint,parameters, "GET")
33
52
  end
34
53
 
35
54
  def _executePostRequest(endpoint, parameters = [])
36
- return _executeHTTPRequest(endpoint,parameters, "POST")
55
+ return _executeHTTPRequest(endpoint,parameters, "POST")
56
+ end
57
+
58
+ def _executePutRequest(endpoint, parameters = [])
59
+ return _executeHTTPRequest(endpoint,parameters, "PUT")
60
+ end
61
+
62
+ def _executeDeleteRequest(endpoint, parameters = [])
63
+ return _executeHTTPRequest(endpoint,parameters, "DELETE")
37
64
  end
38
65
 
39
66
  def getUser
40
- return _executeGetRequest("user")
67
+ return _executeGetRequest("user")
41
68
  end
42
69
 
43
70
  def getUsage
44
- return _executeGetRequest("user/usage");
71
+ return _executeGetRequest("user/usage")
45
72
  end
46
73
 
47
74
  def getForms
48
- return _executeGetRequest("user/forms")
75
+ return _executeGetRequest("user/forms")
49
76
  end
50
77
 
51
78
  def getSubmissions
52
- return _executeGetRequest("user/submissions")
79
+ return _executeGetRequest("user/submissions")
53
80
  end
54
81
 
55
82
  def getSubusers
56
- return _executeGetRequest("user/subusers")
83
+ return _executeGetRequest("user/subusers")
57
84
  end
58
85
 
59
86
  def getFolders
60
- return _executeGetRequest("user/folders")
87
+ return _executeGetRequest("user/folders")
61
88
  end
62
89
 
63
90
  def getReports
64
- return _executeGetRequest("user/reports")
91
+ return _executeGetRequest("user/reports")
65
92
  end
66
93
 
67
94
  def getSettings
68
- return _executeGetRequest("user/settings")
95
+ return _executeGetRequest("user/settings")
96
+ end
97
+
98
+ def getUserSetting(settingKey)
99
+ return _executeGetRequest("user/settings/" + settingKey)
100
+ end
101
+
102
+ def updateSettings(settings)
103
+ return _executePostRequest("user/settings", settings)
69
104
  end
70
105
 
71
106
  def getHistory
72
- return _executeGetRequest("user/history")
107
+ return _executeGetRequest("user/history")
108
+ end
109
+
110
+ def getLabels
111
+ return _executeGetRequest("user/labels")
112
+ end
113
+
114
+ def getInvoices
115
+ return _executeGetRequest("user/invoices")
73
116
  end
74
117
 
75
118
  def getForm(formID)
76
- return _executeGetRequest("form/"+ formID)
119
+ return _executeGetRequest("form/"+ formID)
77
120
  end
78
121
 
79
122
  def getFormQuestions(formID)
80
- return _executeGetRequest("form/"+formID+"/questions")
123
+ return _executeGetRequest("form/"+formID+"/questions")
81
124
  end
82
125
 
83
126
  def getFormQuestion(formID, qid)
84
- return _executeGetRequest("form/"+formID+"/question/"+qid)
127
+ return _executeGetRequest("form/"+formID+"/question/"+qid)
85
128
  end
86
129
 
87
130
  def getFormProperties(formID)
88
- return _executeGetRequest("form/"+formID+"/properties")
131
+ return _executeGetRequest("form/"+formID+"/properties")
89
132
  end
90
133
 
91
134
  def getFormProperty(formID, propertyKey)
92
- return _executeGetRequest("form/"+formID+"/properties/"+propertyKey)
135
+ return _executeGetRequest("form/"+formID+"/properties/"+propertyKey)
93
136
  end
94
137
 
95
-
96
138
  def getFormSubmissions(formID)
97
- return _executeGetRequest("form/"+ formID +"/submissions")
139
+ return _executeGetRequest("form/" + formID + "/submissions")
98
140
  end
99
141
 
100
142
  def getFormFiles(formID)
101
- return _executeGetRequest("form/"+formID+"/files")
143
+ return _executeGetRequest("form/"+formID+"/files")
102
144
  end
103
145
 
104
146
  def getFormWebhooks(formID)
105
- return _executeGetRequest("form/"+formID+"/webhooks")
147
+ return _executeGetRequest("form/"+formID+"/webhooks")
148
+ end
149
+
150
+ def getFormReports(formID)
151
+ return _executeGetRequest("form/" + formID + "/reports")
106
152
  end
107
153
 
108
154
  def getSubmission(sid)
109
- return _executeGetRequest("submission/"+sid)
155
+ return _executeGetRequest("submission/"+sid)
110
156
  end
111
157
 
112
158
  def getReport(reportID)
113
- return _executeGetRequest("report/"+reportID)
159
+ return _executeGetRequest("report/"+reportID)
114
160
  end
115
161
 
116
162
  def getFolder(folderID)
117
- return _executeGetRequest("folder/"+folderID)
163
+ return _executeGetRequest("folder/"+folderID)
164
+ end
165
+
166
+ def getSystemPlan(planName)
167
+ return _executeGetRequest("system/plan/"+planName)
168
+ end
169
+
170
+ def getLabel(labelID)
171
+ return _executeGetRequest("label/"+labelID)
172
+ end
173
+
174
+ def getLabelResources(labelID)
175
+ return _executeGetRequest("label/"+labelID+"/resources")
118
176
  end
119
177
 
120
178
  def createFormWebhook(formID, webhookURL)
121
- return _executePostRequest("form/"+formID+"/webhooks",{"webhookURL" => webhookURL} );
179
+ return _executePostRequest("form/"+formID+"/webhooks",{"webhookURL" => webhookURL} )
122
180
  end
123
181
 
124
182
  def createFormSubmissions(formID, submission)
125
- return _executePostRequest("form/"+ formID +"/submissions", submission);
183
+ return _executePostRequest("form/" + formID + "/submissions", submission)
184
+ end
185
+
186
+ def createFormSubmission(formID, submission)
187
+ formatted_submission = {}
188
+ submission.each do |key, value|
189
+ key_string = key.to_s
190
+ if key_string.include?("_")
191
+ qid, field_type = key_string.split("_", 2)
192
+ formatted_submission["submission[#{qid}][#{field_type}]"] = value
193
+ else
194
+ formatted_submission["submission[#{key_string}]"] = value
195
+ end
196
+ end
197
+
198
+ return _executePostRequest("form/" + formID + "/submissions", formatted_submission)
199
+ end
200
+
201
+ def createLabel(labelProperties)
202
+ return _executePostRequest("label", labelProperties)
203
+ end
204
+
205
+ def updateLabel(labelID, labelProperties)
206
+ return _executePutRequest("label/" + labelID, labelProperties)
207
+ end
208
+
209
+ def addResourcesToLabel(labelID, resources)
210
+ return _executePutRequest("label/" + labelID + "/add-resources", { "resources" => resources })
211
+ end
212
+
213
+ def removeResourcesFromLabel(labelID, resources)
214
+ return _executePutRequest("label/" + labelID + "/remove-resources", { "resources" => resources })
215
+ end
216
+
217
+ def deleteLabel(labelID)
218
+ return _executeDeleteRequest("label/" + labelID)
219
+ end
220
+
221
+ def createFolder(folderProperties)
222
+ return _executePostRequest("folder", folderProperties)
223
+ end
224
+
225
+ def updateFolder(folderID, folderProperties)
226
+ return _executePutRequest("folder/" + folderID, folderProperties)
227
+ end
228
+
229
+ def deleteFolder(folderID)
230
+ return _executeDeleteRequest("folder/" + folderID)
231
+ end
232
+
233
+ def addFormsToFolder(folderID, formIDs)
234
+ return updateFolder(folderID, { "forms" => formIDs })
235
+ end
236
+
237
+ def addFormToFolder(folderID, formID)
238
+ return addFormsToFolder(folderID, [formID])
239
+ end
240
+
241
+ def deleteFormWebhook(formID, webhookID)
242
+ return _executeDeleteRequest("form/" + formID + "/webhooks/" + webhookID)
243
+ end
244
+
245
+ def deleteSubmission(submissionID)
246
+ return _executeDeleteRequest("submission/" + submissionID)
247
+ end
248
+
249
+ def editSubmission(submissionID, submission)
250
+ formatted_submission = {}
251
+ submission.each do |key, value|
252
+ key_string = key.to_s
253
+ if key_string.include?("_") && key_string != "created_at"
254
+ qid, field_type = key_string.split("_", 2)
255
+ formatted_submission["submission[#{qid}][#{field_type}]"] = value
256
+ else
257
+ formatted_submission["submission[#{key_string}]"] = value
258
+ end
259
+ end
260
+
261
+ return _executePostRequest("submission/" + submissionID, formatted_submission)
262
+ end
263
+
264
+ def cloneForm(formID)
265
+ return _executePostRequest("form/" + formID + "/clone", nil)
266
+ end
267
+
268
+ def deleteFormQuestion(formID, qid)
269
+ return _executeDeleteRequest("form/" + formID + "/question/" + qid)
270
+ end
271
+
272
+ def createFormQuestion(formID, question)
273
+ formatted_question = {}
274
+ question.each do |key, value|
275
+ formatted_question["question[#{key}]"] = value
276
+ end
277
+
278
+ return _executePostRequest("form/" + formID + "/questions", formatted_question)
279
+ end
280
+
281
+ def createFormQuestions(formID, questions)
282
+ return _executePutRequest("form/" + formID + "/questions", questions)
283
+ end
284
+
285
+ def editFormQuestion(formID, qid, questionProperties)
286
+ formatted_question = {}
287
+ questionProperties.each do |key, value|
288
+ formatted_question["question[#{key}]"] = value
289
+ end
290
+
291
+ return _executePostRequest("form/" + formID + "/question/" + qid, formatted_question)
292
+ end
293
+
294
+ def setFormProperties(formID, formProperties)
295
+ formatted_properties = {}
296
+ formProperties.each do |key, value|
297
+ formatted_properties["properties[#{key}]"] = value
298
+ end
299
+
300
+ return _executePostRequest("form/" + formID + "/properties", formatted_properties)
301
+ end
302
+
303
+ def setMultipleFormProperties(formID, formProperties)
304
+ return _executePutRequest("form/" + formID + "/properties", formProperties)
305
+ end
306
+
307
+ def createForm(form)
308
+ formatted_form = {}
309
+ form.each do |section, values|
310
+ values.each do |key, value|
311
+ if section.to_s == "properties"
312
+ formatted_form["#{section}[#{key}]"] = value
313
+ else
314
+ value.each do |sub_key, sub_value|
315
+ formatted_form["#{section}[#{key}][#{sub_key}]"] = sub_value
316
+ end
317
+ end
318
+ end
319
+ end
320
+
321
+ return _executePostRequest("user/forms", formatted_form)
322
+ end
323
+
324
+ def createForms(forms)
325
+ return _executePutRequest("user/forms", forms)
326
+ end
327
+
328
+ def deleteForm(formID)
329
+ return _executeDeleteRequest("form/" + formID)
330
+ end
331
+
332
+ def registerUser(userDetails)
333
+ return _executePostRequest("user/register", userDetails)
334
+ end
335
+
336
+ def loginUser(credentials)
337
+ return _executePostRequest("user/login", credentials)
338
+ end
339
+
340
+ def logoutUser
341
+ return _executeGetRequest("user/logout")
342
+ end
343
+
344
+ def createReport(formID, report)
345
+ return _executePostRequest("form/" + formID + "/reports", report)
346
+ end
347
+
348
+ def deleteReport(reportID)
349
+ return _executeDeleteRequest("report/" + reportID)
126
350
  end
127
351
  end
128
352
 
data/test/test_jotform.rb CHANGED
@@ -1,5 +1,427 @@
1
1
  require 'test/unit'
2
+ require 'stringio'
2
3
  require 'jotform'
3
4
 
4
5
  class JotformTest < Test::Unit::TestCase
6
+ class FakeSuccessResponse < Net::HTTPSuccess
7
+ attr_reader :body
8
+
9
+ def initialize(body)
10
+ @body = body
11
+ end
12
+ end
13
+
14
+ class FakeErrorResponse < Net::HTTPServerError
15
+ attr_reader :body
16
+
17
+ def initialize(body)
18
+ @body = body
19
+ end
20
+ end
21
+
22
+ def setup
23
+ @jotform = Jotform.new("test-api-key", "http://example.com", "v9")
24
+ @net_http_singleton = class << Net::HTTP; self; end
25
+ end
26
+
27
+ def teardown
28
+ restore_net_http_method(:get_response)
29
+ restore_net_http_method(:post_form)
30
+ restore_net_http_method(:new)
31
+ end
32
+
33
+ def test_get_user_calls_expected_endpoint_and_returns_content
34
+ captured_uri = nil
35
+
36
+ stub_net_http_method(:get_response) do |uri|
37
+ captured_uri = uri
38
+ FakeSuccessResponse.new({ "content" => { "username" => "marcelo" } }.to_json)
39
+ end
40
+
41
+ result = @jotform.getUser
42
+
43
+ assert_equal("http://example.com/v9/user?apiKey=test-api-key", captured_uri.to_s)
44
+ assert_equal({ "username" => "marcelo" }, result)
45
+ end
46
+
47
+ def test_initialize_sets_default_values
48
+ jotform = Jotform.new
49
+
50
+ assert_nil(jotform.apiKey)
51
+ assert_equal("http://api.jotform.com", jotform.baseURL)
52
+ assert_equal("v1", jotform.apiVersion)
53
+ end
54
+
55
+ def test_get_forms_calls_expected_endpoint_and_returns_content
56
+ captured_uri = nil
57
+
58
+ stub_net_http_method(:get_response) do |uri|
59
+ captured_uri = uri
60
+ FakeSuccessResponse.new({ "content" => [{ "id" => "f1" }] }.to_json)
61
+ end
62
+
63
+ result = @jotform.getForms
64
+
65
+ assert_equal("http://example.com/v9/user/forms?apiKey=test-api-key", captured_uri.to_s)
66
+ assert_equal([{ "id" => "f1" }], result)
67
+ end
68
+
69
+ def test_get_submission_calls_expected_endpoint_and_returns_content
70
+ captured_uri = nil
71
+
72
+ stub_net_http_method(:get_response) do |uri|
73
+ captured_uri = uri
74
+ FakeSuccessResponse.new({ "content" => { "id" => "s1" } }.to_json)
75
+ end
76
+
77
+ result = @jotform.getSubmission("s1")
78
+
79
+ assert_equal("http://example.com/v9/submission/s1?apiKey=test-api-key", captured_uri.to_s)
80
+ assert_equal({ "id" => "s1" }, result)
81
+ end
82
+
83
+ def test_create_form_webhook_posts_payload_and_returns_content
84
+ captured_uri = nil
85
+ captured_params = nil
86
+
87
+ stub_net_http_method(:post_form) do |uri, params|
88
+ captured_uri = uri
89
+ captured_params = params
90
+ FakeSuccessResponse.new({ "content" => { "id" => "wh_1" } }.to_json)
91
+ end
92
+
93
+ result = @jotform.createFormWebhook("123", "https://callback.test/hook")
94
+
95
+ assert_equal("http://example.com/v9/form/123/webhooks?apiKey=test-api-key", captured_uri.to_s)
96
+ assert_equal({ "webhookURL" => "https://callback.test/hook" }, captured_params)
97
+ assert_equal({ "id" => "wh_1" }, result)
98
+ end
99
+
100
+ def test_create_form_submissions_posts_payload_and_returns_content
101
+ captured_uri = nil
102
+ captured_params = nil
103
+ submission_payload = { "submission[3]" => "Marcelo" }
104
+
105
+ stub_net_http_method(:post_form) do |uri, params|
106
+ captured_uri = uri
107
+ captured_params = params
108
+ FakeSuccessResponse.new({ "content" => { "submissionID" => "sub_1" } }.to_json)
109
+ end
110
+
111
+ result = @jotform.createFormSubmissions("123", submission_payload)
112
+
113
+ assert_equal("http://example.com/v9/form/123/submissions?apiKey=test-api-key", captured_uri.to_s)
114
+ assert_equal(submission_payload, captured_params)
115
+ assert_equal({ "submissionID" => "sub_1" }, result)
116
+ end
117
+
118
+ def test_post_endpoint_wrappers_call_expected_paths
119
+ cases = [
120
+ [:updateSettings, [{ "language" => "en" }], "user/settings"],
121
+ [:registerUser, [{ "username" => "john", "password" => "secret" }], "user/register"],
122
+ [:loginUser, [{ "username" => "john", "password" => "secret", "appName" => "app", "access" => "readOnly" }], "user/login"],
123
+ [:cloneForm, ["123"], "form/123/clone"],
124
+ [:createReport, ["123", { "title" => "My Report", "list_type" => "grid" }], "form/123/reports"],
125
+ [:createFolder, [{ "name" => "Ops", "color" => "#FFFFFF" }], "folder"],
126
+ [:createFormWebhook, ["123", "https://callback.test/hook"], "form/123/webhooks"]
127
+ ]
128
+
129
+ cases.each do |method_name, args, path|
130
+ captured_uri = nil
131
+ captured_params = nil
132
+
133
+ stub_net_http_method(:post_form) do |uri, params|
134
+ captured_uri = uri
135
+ captured_params = params
136
+ FakeSuccessResponse.new({ "content" => { "endpoint" => path } }.to_json)
137
+ end
138
+
139
+ result = @jotform.send(method_name, *args)
140
+
141
+ assert_equal("http://example.com/v9/#{path}?apiKey=test-api-key", captured_uri.to_s)
142
+ assert_not_nil(captured_params) unless method_name == :cloneForm
143
+ assert_equal({ "endpoint" => path }, result)
144
+
145
+ restore_net_http_method(:post_form)
146
+ end
147
+ end
148
+
149
+ def test_submission_and_form_payload_transformations
150
+ captured_uri = nil
151
+ captured_params = nil
152
+
153
+ stub_net_http_method(:post_form) do |uri, params|
154
+ captured_uri = uri
155
+ captured_params = params
156
+ FakeSuccessResponse.new({ "content" => { "ok" => true } }.to_json)
157
+ end
158
+
159
+ @jotform.createFormSubmission("100", { "1" => "A", "2_first" => "John", "3_last" => "Doe" })
160
+ assert_equal("http://example.com/v9/form/100/submissions?apiKey=test-api-key", captured_uri.to_s)
161
+ assert_equal(
162
+ {
163
+ "submission[1]" => "A",
164
+ "submission[2][first]" => "John",
165
+ "submission[3][last]" => "Doe"
166
+ },
167
+ captured_params
168
+ )
169
+
170
+ @jotform.editSubmission("sub_1", { "2_first" => "Jane", "created_at" => "2025-01-01" })
171
+ assert_equal("http://example.com/v9/submission/sub_1?apiKey=test-api-key", captured_uri.to_s)
172
+ assert_equal(
173
+ {
174
+ "submission[2][first]" => "Jane",
175
+ "submission[created_at]" => "2025-01-01"
176
+ },
177
+ captured_params
178
+ )
179
+
180
+ @jotform.createFormQuestion("100", { "type" => "control_head", "text" => "Header" })
181
+ assert_equal("http://example.com/v9/form/100/questions?apiKey=test-api-key", captured_uri.to_s)
182
+ assert_equal({ "question[type]" => "control_head", "question[text]" => "Header" }, captured_params)
183
+
184
+ @jotform.editFormQuestion("100", "7", { "text" => "Updated" })
185
+ assert_equal("http://example.com/v9/form/100/question/7?apiKey=test-api-key", captured_uri.to_s)
186
+ assert_equal({ "question[text]" => "Updated" }, captured_params)
187
+
188
+ @jotform.setFormProperties("100", { "thankurl" => "https://example.com/thanks", "formWidth" => "650" })
189
+ assert_equal("http://example.com/v9/form/100/properties?apiKey=test-api-key", captured_uri.to_s)
190
+ assert_equal(
191
+ {
192
+ "properties[thankurl]" => "https://example.com/thanks",
193
+ "properties[formWidth]" => "650"
194
+ },
195
+ captured_params
196
+ )
197
+
198
+ form_payload = {
199
+ "questions" => { "0" => { "type" => "control_head", "text" => "Form Title" } },
200
+ "properties" => { "title" => "New Form" },
201
+ "emails" => { "0" => { "type" => "notification", "to" => "noreply@jotform.com" } }
202
+ }
203
+ @jotform.createForm(form_payload)
204
+ assert_equal("http://example.com/v9/user/forms?apiKey=test-api-key", captured_uri.to_s)
205
+ assert_equal(
206
+ {
207
+ "questions[0][type]" => "control_head",
208
+ "questions[0][text]" => "Form Title",
209
+ "properties[title]" => "New Form",
210
+ "emails[0][type]" => "notification",
211
+ "emails[0][to]" => "noreply@jotform.com"
212
+ },
213
+ captured_params
214
+ )
215
+ end
216
+
217
+ def test_create_label_posts_payload_and_returns_content
218
+ captured_uri = nil
219
+ captured_params = nil
220
+ payload = { "name" => "IT Operations", "color" => "#FFDC7B" }
221
+
222
+ stub_net_http_method(:post_form) do |uri, params|
223
+ captured_uri = uri
224
+ captured_params = params
225
+ FakeSuccessResponse.new({ "content" => { "id" => "lbl_1" } }.to_json)
226
+ end
227
+
228
+ result = @jotform.createLabel(payload)
229
+
230
+ assert_equal("http://example.com/v9/label?apiKey=test-api-key", captured_uri.to_s)
231
+ assert_equal(payload, captured_params)
232
+ assert_equal({ "id" => "lbl_1" }, result)
233
+ end
234
+
235
+ def test_put_and_delete_label_requests_use_expected_paths_and_payloads
236
+ captured = {}
237
+
238
+ stub_net_http_method(:new) do |host, port|
239
+ captured[:host] = host
240
+ captured[:port] = port
241
+
242
+ http = Object.new
243
+ http.define_singleton_method(:use_ssl=) do |value|
244
+ captured[:use_ssl] = value
245
+ end
246
+ http.define_singleton_method(:request) do |request|
247
+ captured[:request] = request
248
+ FakeSuccessResponse.new({ "content" => { "ok" => true } }.to_json)
249
+ end
250
+ http
251
+ end
252
+
253
+ update_payload = { "name" => "Workplace Operations", "color" => "#23FFDD" }
254
+ update_result = @jotform.updateLabel("label_1", update_payload)
255
+
256
+ assert_equal("example.com", captured[:host])
257
+ assert_equal(80, captured[:port])
258
+ assert_equal(false, captured[:use_ssl])
259
+ assert_kind_of(Net::HTTP::Put, captured[:request])
260
+ assert_equal("/v9/label/label_1?apiKey=test-api-key", captured[:request].path)
261
+ assert_equal(update_payload.to_json, captured[:request].body)
262
+ assert_equal("application/json", captured[:request]["Content-Type"])
263
+ assert_equal({ "ok" => true }, update_result)
264
+
265
+ resources = [{ "id" => "251464995493876", "type" => "form" }]
266
+ add_result = @jotform.addResourcesToLabel("label_1", resources)
267
+ assert_equal("/v9/label/label_1/add-resources?apiKey=test-api-key", captured[:request].path)
268
+ assert_equal({ "resources" => resources }.to_json, captured[:request].body)
269
+ assert_equal({ "ok" => true }, add_result)
270
+
271
+ remove_result = @jotform.removeResourcesFromLabel("label_1", resources)
272
+ assert_equal("/v9/label/label_1/remove-resources?apiKey=test-api-key", captured[:request].path)
273
+ assert_equal({ "resources" => resources }.to_json, captured[:request].body)
274
+ assert_equal({ "ok" => true }, remove_result)
275
+
276
+ @jotform.updateFolder("folder_1", { "name" => "My Folder" })
277
+ assert_equal("/v9/folder/folder_1?apiKey=test-api-key", captured[:request].path)
278
+ assert_equal({ "name" => "My Folder" }.to_json, captured[:request].body)
279
+
280
+ @jotform.addFormsToFolder("folder_1", ["f1", "f2"])
281
+ assert_equal("/v9/folder/folder_1?apiKey=test-api-key", captured[:request].path)
282
+ assert_equal({ "forms" => ["f1", "f2"] }.to_json, captured[:request].body)
283
+
284
+ @jotform.addFormToFolder("folder_1", "f3")
285
+ assert_equal("/v9/folder/folder_1?apiKey=test-api-key", captured[:request].path)
286
+ assert_equal({ "forms" => ["f3"] }.to_json, captured[:request].body)
287
+
288
+ @jotform.createForms([{ "properties" => { "title" => "Bulk" } }])
289
+ assert_equal("/v9/user/forms?apiKey=test-api-key", captured[:request].path)
290
+ assert_equal([{ "properties" => { "title" => "Bulk" } }].to_json, captured[:request].body)
291
+
292
+ @jotform.createFormQuestions("100", { "questions" => {} })
293
+ assert_equal("/v9/form/100/questions?apiKey=test-api-key", captured[:request].path)
294
+ assert_equal({ "questions" => {} }.to_json, captured[:request].body)
295
+
296
+ @jotform.setMultipleFormProperties("100", { "properties" => { "labelWidth" => "150" } })
297
+ assert_equal("/v9/form/100/properties?apiKey=test-api-key", captured[:request].path)
298
+ assert_equal({ "properties" => { "labelWidth" => "150" } }.to_json, captured[:request].body)
299
+
300
+ raw_payload = '{"name":"Raw Label"}'
301
+ raw_result = @jotform.updateLabel("label_1", raw_payload)
302
+ assert_equal("/v9/label/label_1?apiKey=test-api-key", captured[:request].path)
303
+ assert_equal(raw_payload, captured[:request].body)
304
+ assert_equal("application/json", captured[:request]["Content-Type"])
305
+ assert_equal({ "ok" => true }, raw_result)
306
+
307
+ delete_result = @jotform.deleteLabel("label_1")
308
+ assert_kind_of(Net::HTTP::Delete, captured[:request])
309
+ assert_equal("/v9/label/label_1?apiKey=test-api-key", captured[:request].path)
310
+ assert_equal({ "ok" => true }, delete_result)
311
+
312
+ @jotform.deleteFolder("folder_1")
313
+ assert_kind_of(Net::HTTP::Delete, captured[:request])
314
+ assert_equal("/v9/folder/folder_1?apiKey=test-api-key", captured[:request].path)
315
+
316
+ @jotform.deleteFormWebhook("100", "wh_1")
317
+ assert_kind_of(Net::HTTP::Delete, captured[:request])
318
+ assert_equal("/v9/form/100/webhooks/wh_1?apiKey=test-api-key", captured[:request].path)
319
+
320
+ @jotform.deleteSubmission("sub_1")
321
+ assert_kind_of(Net::HTTP::Delete, captured[:request])
322
+ assert_equal("/v9/submission/sub_1?apiKey=test-api-key", captured[:request].path)
323
+
324
+ @jotform.deleteFormQuestion("100", "7")
325
+ assert_kind_of(Net::HTTP::Delete, captured[:request])
326
+ assert_equal("/v9/form/100/question/7?apiKey=test-api-key", captured[:request].path)
327
+
328
+ @jotform.deleteForm("100")
329
+ assert_kind_of(Net::HTTP::Delete, captured[:request])
330
+ assert_equal("/v9/form/100?apiKey=test-api-key", captured[:request].path)
331
+
332
+ @jotform.deleteReport("rep_1")
333
+ assert_kind_of(Net::HTTP::Delete, captured[:request])
334
+ assert_equal("/v9/report/rep_1?apiKey=test-api-key", captured[:request].path)
335
+ end
336
+
337
+ def test_get_endpoint_wrappers_call_expected_paths
338
+ cases = [
339
+ [:getUsage, [], "user/usage"],
340
+ [:getLabels, [], "user/labels"],
341
+ [:getInvoices, [], "user/invoices"],
342
+ [:getSubmissions, [], "user/submissions"],
343
+ [:getSubusers, [], "user/subusers"],
344
+ [:getFolders, [], "user/folders"],
345
+ [:getReports, [], "user/reports"],
346
+ [:getSettings, [], "user/settings"],
347
+ [:getUserSetting, ["language"], "user/settings/language"],
348
+ [:getHistory, [], "user/history"],
349
+ [:logoutUser, [], "user/logout"],
350
+ [:getSystemPlan, ["FREE"], "system/plan/FREE"],
351
+ [:getForm, ["123"], "form/123"],
352
+ [:getFormQuestions, ["123"], "form/123/questions"],
353
+ [:getFormQuestion, ["123", "7"], "form/123/question/7"],
354
+ [:getFormProperties, ["123"], "form/123/properties"],
355
+ [:getFormProperty, ["123", "title"], "form/123/properties/title"],
356
+ [:getFormSubmissions, ["123"], "form/123/submissions"],
357
+ [:getFormFiles, ["123"], "form/123/files"],
358
+ [:getFormWebhooks, ["123"], "form/123/webhooks"],
359
+ [:getFormReports, ["123"], "form/123/reports"],
360
+ [:getReport, ["r1"], "report/r1"],
361
+ [:getFolder, ["fld1"], "folder/fld1"],
362
+ [:getLabel, ["lbl1"], "label/lbl1"],
363
+ [:getLabelResources, ["lbl1"], "label/lbl1/resources"]
364
+ ]
365
+
366
+ cases.each do |method_name, args, path|
367
+ captured_uri = nil
368
+ expected_content = { "endpoint" => path }
369
+
370
+ stub_net_http_method(:get_response) do |uri|
371
+ captured_uri = uri
372
+ FakeSuccessResponse.new({ "content" => expected_content }.to_json)
373
+ end
374
+
375
+ result = @jotform.send(method_name, *args)
376
+
377
+ assert_equal("http://example.com/v9/#{path}?apiKey=test-api-key", captured_uri.to_s)
378
+ assert_equal(expected_content, result)
379
+
380
+ restore_net_http_method(:get_response)
381
+ end
382
+ end
383
+
384
+ def test_error_response_returns_nil_and_prints_api_message
385
+ stub_net_http_method(:get_response) do |_uri|
386
+ FakeErrorResponse.new({ "message" => "Invalid API key" }.to_json)
387
+ end
388
+
389
+ original_stdout = $stdout
390
+ output = StringIO.new
391
+ $stdout = output
392
+
393
+ result = @jotform.getUser
394
+
395
+ assert_nil(result)
396
+ assert_match(/Invalid API key/, output.string)
397
+ ensure
398
+ $stdout = original_stdout
399
+ end
400
+
401
+ private
402
+
403
+ def stub_net_http_method(method_name, &block)
404
+ original_name = "__original_#{method_name}".to_sym
405
+ return if @net_http_singleton.method_defined?(original_name)
406
+
407
+ verbose = $VERBOSE
408
+ @net_http_singleton.send(:alias_method, original_name, method_name)
409
+ @net_http_singleton.send(:remove_method, method_name)
410
+ $VERBOSE = nil
411
+ @net_http_singleton.send(:define_method, method_name, &block)
412
+ ensure
413
+ $VERBOSE = verbose
414
+ end
415
+
416
+ def restore_net_http_method(method_name)
417
+ original_name = "__original_#{method_name}".to_sym
418
+ return unless @net_http_singleton.method_defined?(original_name)
419
+
420
+ verbose = $VERBOSE
421
+ $VERBOSE = nil
422
+ @net_http_singleton.send(:alias_method, method_name, original_name)
423
+ @net_http_singleton.send(:remove_method, original_name)
424
+ ensure
425
+ $VERBOSE = verbose
426
+ end
5
427
  end
metadata CHANGED
@@ -1,11 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jotform_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcelo Miqueles
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
10
  date: 2023-08-01 00:00:00.000000000 Z
@@ -22,9 +21,8 @@ files:
22
21
  - test/test_jotform.rb
23
22
  homepage: https://github.com/marceloomiqueles/jotform_api
24
23
  licenses:
25
- - MIT
24
+ - Apache-2.0
26
25
  metadata: {}
27
- post_install_message:
28
26
  rdoc_options: []
29
27
  require_paths:
30
28
  - lib
@@ -39,8 +37,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
39
37
  - !ruby/object:Gem::Version
40
38
  version: '0'
41
39
  requirements: []
42
- rubygems_version: 3.4.17
43
- signing_key:
40
+ rubygems_version: 3.6.2
44
41
  specification_version: 3
45
42
  summary: jotform!
46
43
  test_files: