telnyx 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.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +4 -0
  3. data/.github/ISSUE_TEMPLATE.md +5 -0
  4. data/.gitignore +9 -0
  5. data/.rubocop.yml +32 -0
  6. data/.rubocop_todo.yml +50 -0
  7. data/.travis.yml +42 -0
  8. data/CHANGELOG.md +2 -0
  9. data/CONTRIBUTORS +0 -0
  10. data/Gemfile +40 -0
  11. data/Guardfile +8 -0
  12. data/LICENSE +22 -0
  13. data/README.md +173 -0
  14. data/Rakefile +28 -0
  15. data/VERSION +1 -0
  16. data/bin/telnyx-console +16 -0
  17. data/lib/telnyx.rb +151 -0
  18. data/lib/telnyx/api_operations/create.rb +12 -0
  19. data/lib/telnyx/api_operations/delete.rb +13 -0
  20. data/lib/telnyx/api_operations/list.rb +29 -0
  21. data/lib/telnyx/api_operations/nested_resource.rb +63 -0
  22. data/lib/telnyx/api_operations/request.rb +57 -0
  23. data/lib/telnyx/api_operations/save.rb +103 -0
  24. data/lib/telnyx/api_resource.rb +69 -0
  25. data/lib/telnyx/available_phone_number.rb +9 -0
  26. data/lib/telnyx/errors.rb +166 -0
  27. data/lib/telnyx/event.rb +9 -0
  28. data/lib/telnyx/list_object.rb +155 -0
  29. data/lib/telnyx/message.rb +9 -0
  30. data/lib/telnyx/messaging_phone_number.rb +10 -0
  31. data/lib/telnyx/messaging_profile.rb +32 -0
  32. data/lib/telnyx/messaging_sender_id.rb +12 -0
  33. data/lib/telnyx/messaging_short_code.rb +10 -0
  34. data/lib/telnyx/number_order.rb +11 -0
  35. data/lib/telnyx/number_reservation.rb +11 -0
  36. data/lib/telnyx/public_key.rb +7 -0
  37. data/lib/telnyx/singleton_api_resource.rb +24 -0
  38. data/lib/telnyx/telnyx_client.rb +545 -0
  39. data/lib/telnyx/telnyx_object.rb +521 -0
  40. data/lib/telnyx/telnyx_response.rb +50 -0
  41. data/lib/telnyx/util.rb +328 -0
  42. data/lib/telnyx/version.rb +5 -0
  43. data/lib/telnyx/webhook.rb +66 -0
  44. data/telnyx.gemspec +25 -0
  45. data/test/api_stub_helpers.rb +1 -0
  46. data/test/openapi/README.md +9 -0
  47. data/test/telnyx/api_operations_test.rb +85 -0
  48. data/test/telnyx/api_resource_test.rb +293 -0
  49. data/test/telnyx/available_phone_number_test.rb +14 -0
  50. data/test/telnyx/errors_test.rb +23 -0
  51. data/test/telnyx/list_object_test.rb +244 -0
  52. data/test/telnyx/message_test.rb +19 -0
  53. data/test/telnyx/messaging_phone_number_test.rb +33 -0
  54. data/test/telnyx/messaging_profile_test.rb +70 -0
  55. data/test/telnyx/messaging_sender_id_test.rb +46 -0
  56. data/test/telnyx/messaging_short_code_test.rb +33 -0
  57. data/test/telnyx/number_order_test.rb +39 -0
  58. data/test/telnyx/number_reservation_test.rb +12 -0
  59. data/test/telnyx/public_key_test.rb +13 -0
  60. data/test/telnyx/telnyx_client_test.rb +631 -0
  61. data/test/telnyx/telnyx_object_test.rb +497 -0
  62. data/test/telnyx/telnyx_response_test.rb +49 -0
  63. data/test/telnyx/util_test.rb +380 -0
  64. data/test/telnyx/webhook_test.rb +108 -0
  65. data/test/telnyx_mock.rb +78 -0
  66. data/test/telnyx_test.rb +40 -0
  67. data/test/test_data.rb +149 -0
  68. data/test/test_helper.rb +73 -0
  69. metadata +162 -0
@@ -0,0 +1,497 @@
1
+ # frozen_string_literal: true
2
+
3
+ require ::File.expand_path("../../test_helper", __FILE__)
4
+
5
+ module Telnyx
6
+ class TelnyxObjectTest < Test::Unit::TestCase
7
+ should "implement #==" do
8
+ obj1 = Telnyx::TelnyxObject.construct_from(id: 1, foo: "bar")
9
+ obj2 = Telnyx::TelnyxObject.construct_from(id: 1, foo: "bar")
10
+ obj3 = Telnyx::TelnyxObject.construct_from(id: 1, foo: "rab")
11
+
12
+ assert obj1 == obj2
13
+ refute obj1 == obj3
14
+ end
15
+
16
+ should "implement #deleted?" do
17
+ obj = Telnyx::TelnyxObject.construct_from({})
18
+ refute obj.deleted?
19
+
20
+ obj = Telnyx::TelnyxObject.construct_from(deleted: false)
21
+ refute obj.deleted?
22
+
23
+ obj = Telnyx::TelnyxObject.construct_from(deleted: true)
24
+ assert obj.deleted?
25
+ end
26
+
27
+ should "implement #respond_to" do
28
+ obj = Telnyx::TelnyxObject.construct_from(id: 1, foo: "bar")
29
+ assert obj.respond_to?(:id)
30
+ assert obj.respond_to?(:foo)
31
+ assert !obj.respond_to?(:baz)
32
+ end
33
+
34
+ should "marshal be insensitive to strings vs. symbols when constructin" do
35
+ obj = Telnyx::TelnyxObject.construct_from(:id => 1, "name" => "Telnyx")
36
+ assert_equal 1, obj[:id]
37
+ assert_equal "Telnyx", obj[:name]
38
+ end
39
+
40
+ context "#deep_copy" do
41
+ should "produce a deep copy" do
42
+ opts = {
43
+ api_base: Telnyx.api_base,
44
+ api_key: "apikey",
45
+ }
46
+ values = {
47
+ id: 1,
48
+ name: "Telnyx",
49
+ arr: [
50
+ TelnyxObject.construct_from({ id: "index0" }, opts),
51
+ "index1",
52
+ 2,
53
+ ],
54
+ map: {
55
+ :"0" => TelnyxObject.construct_from({ id: "index0" }, opts),
56
+ :"1" => "index1",
57
+ :"2" => 2,
58
+ },
59
+ }
60
+
61
+ # it's not good to test methods with `#send` like this, but I've done
62
+ # it in the interest of trying to keep `.deep_copy` as internal as
63
+ # possible
64
+ copy_values = Telnyx::TelnyxObject.send(:deep_copy, values)
65
+
66
+ # we can't compare the hashes directly because they have embedded
67
+ # objects which are different from each other
68
+ assert_equal values[:id], copy_values[:id]
69
+ assert_equal values[:name], copy_values[:name]
70
+
71
+ assert_equal values[:arr].length, copy_values[:arr].length
72
+
73
+ # internal values of the copied TelnyxObject should be the same
74
+ # (including opts), but the object itself should be new (hence the
75
+ # refutation of equality on #object_id)
76
+ assert_equal values[:arr][0][:id], copy_values[:arr][0][:id]
77
+ refute_equal values[:arr][0].object_id, copy_values[:arr][0].object_id
78
+ assert_equal values[:arr][0].instance_variable_get(:@opts),
79
+ copy_values[:arr][0].instance_variable_get(:@opts)
80
+
81
+ # scalars however, can be compared
82
+ assert_equal values[:arr][1], copy_values[:arr][1]
83
+ assert_equal values[:arr][2], copy_values[:arr][2]
84
+
85
+ # and a similar story with the hash
86
+ assert_equal values[:map].keys, copy_values[:map].keys
87
+ assert_equal values[:map][:"0"][:id], copy_values[:map][:"0"][:id]
88
+ refute_equal values[:map][:"0"].object_id, copy_values[:map][:"0"].object_id
89
+ assert_equal values[:map][:"0"].instance_variable_get(:@opts),
90
+ copy_values[:map][:"0"].instance_variable_get(:@opts)
91
+ assert_equal values[:map][:"1"], copy_values[:map][:"1"]
92
+ assert_equal values[:map][:"2"], copy_values[:map][:"2"]
93
+ end
94
+
95
+ should "not copy a client" do
96
+ opts = {
97
+ api_key: "apikey",
98
+ client: TelnyxClient.active_client,
99
+ }
100
+ values = { id: 1, name: "Telnyx" }
101
+
102
+ obj = Telnyx::TelnyxObject.construct_from(values, opts)
103
+ copy_obj = Telnyx::TelnyxObject.send(:deep_copy, obj)
104
+
105
+ assert_equal values, copy_obj.instance_variable_get(:@values)
106
+ assert_equal opts.reject { |k, _v| k == :client },
107
+ copy_obj.instance_variable_get(:@opts)
108
+ end
109
+
110
+ should "return an instance of the same class" do
111
+ class TestObject < Telnyx::TelnyxObject; end
112
+
113
+ obj = TestObject.construct_from(id: 1)
114
+ copy_obj = obj.class.send(:deep_copy, obj)
115
+
116
+ assert_equal obj.class, copy_obj.class
117
+ end
118
+ end
119
+
120
+ context "#eql?" do
121
+ should "produce true for two equivalent Telnyx objects" do
122
+ obj1 = Telnyx::TelnyxObject.construct_from(id: 1, name: "Telnyx")
123
+ obj2 = Telnyx::TelnyxObject.construct_from(id: 1, name: "Telnyx")
124
+ assert obj1.eql?(obj2)
125
+ end
126
+
127
+ should "produce false for non-equivalent Telnyx objects" do
128
+ obj1 = Telnyx::TelnyxObject.construct_from(id: 1, name: "Telnyx")
129
+ obj2 = Telnyx::TelnyxObject.construct_from(id: 2, name: "Telnyx")
130
+ refute obj1.eql?(obj2)
131
+ end
132
+
133
+ should "produce false for different types" do
134
+ obj1 = Telnyx::TelnyxObject.construct_from(id: 1, name: "Telnyx")
135
+ obj2 = 7
136
+ refute obj1.eql?(obj2)
137
+ end
138
+ end
139
+
140
+ context "#hash" do
141
+ should "produce the same hash for two equivalent Telnyx objects" do
142
+ obj1 = Telnyx::TelnyxObject.construct_from(id: 1, name: "Telnyx")
143
+ obj2 = Telnyx::TelnyxObject.construct_from(id: 1, name: "Telnyx")
144
+ assert_equal obj1.hash, obj2.hash
145
+ end
146
+
147
+ should "produce different hashes for non-equivalent Telnyx objects" do
148
+ obj1 = Telnyx::TelnyxObject.construct_from(id: 1, name: "Telnyx")
149
+ obj2 = Telnyx::TelnyxObject.construct_from(id: 2, name: "Telnyx")
150
+ refute_equal obj1.hash, obj2.hash
151
+ end
152
+
153
+ should "produce different hashes for different types" do
154
+ obj1 = Telnyx::TelnyxObject.construct_from(id: 1, name: "Telnyx")
155
+ obj2 = 7
156
+ refute_equal obj1.hash, obj2.hash
157
+ end
158
+ end
159
+
160
+ context "#to_hash" do
161
+ should "skip calling to_hash on nil" do
162
+ begin
163
+ module NilWithToHash
164
+ def to_hash
165
+ raise "Can't call to_hash on nil"
166
+ end
167
+ end
168
+ ::NilClass.include NilWithToHash
169
+
170
+ hash_with_nil = { id: 3, foo: nil }
171
+ obj = TelnyxObject.construct_from(hash_with_nil)
172
+ expected_hash = { id: 3, foo: nil }
173
+ assert_equal expected_hash, obj.to_hash
174
+ ensure
175
+ ::NilClass.send(:undef_method, :to_hash)
176
+ end
177
+ end
178
+
179
+ should "recursively call to_hash on its values" do
180
+ # deep nested hash (when contained in an array) or TelnyxObject
181
+ nested_hash = { id: 7, foo: "bar" }
182
+ nested = Telnyx::TelnyxObject.construct_from(nested_hash)
183
+
184
+ obj = Telnyx::TelnyxObject.construct_from(id: 1,
185
+ # simple hash that contains a TelnyxObject to help us test deep
186
+ # recursion
187
+ nested: { data: [nested] },
188
+ list: [nested])
189
+
190
+ expected_hash = {
191
+ id: 1,
192
+ nested: { data: [nested_hash] },
193
+ list: [nested_hash],
194
+ }
195
+ assert_equal expected_hash, obj.to_hash
196
+ end
197
+ end
198
+
199
+ should "assign question mark accessors for booleans" do
200
+ obj = Telnyx::TelnyxObject.construct_from(id: 1, bool: true, not_bool: "bar")
201
+ assert obj.respond_to?(:bool?)
202
+ assert obj.bool?
203
+ refute obj.respond_to?(:not_bool?)
204
+ end
205
+
206
+ should "assign question mark accessors for booleans added after initialization" do
207
+ obj = Telnyx::TelnyxObject.new
208
+ obj.bool = true
209
+ assert obj.respond_to?(:bool?)
210
+ assert obj.bool?
211
+ end
212
+
213
+ should "mass assign values with #update_attributes" do
214
+ obj = Telnyx::TelnyxObject.construct_from(id: 1, name: "Telnyx")
215
+ obj.update_attributes(name: "telnyx")
216
+ assert_equal "telnyx", obj.name
217
+
218
+ # unfortunately, we even assign unknown properties to duplicate the
219
+ # behavior that we currently have via magic accessors with
220
+ # method_missing
221
+ obj.update_attributes(unknown: "foo")
222
+ assert_equal "foo", obj.unknown
223
+ end
224
+
225
+ should "#update_attributes with a hash" do
226
+ obj = Telnyx::TelnyxObject.construct_from({})
227
+ obj.update_attributes(metadata: { foo: "bar" })
228
+ assert_equal Telnyx::TelnyxObject, obj.metadata.class
229
+ end
230
+
231
+ should "create accessors when #update_attributes is called" do
232
+ obj = Telnyx::TelnyxObject.construct_from({})
233
+ assert_equal false, obj.send(:metaclass).method_defined?(:foo)
234
+ obj.update_attributes(foo: "bar")
235
+ assert_equal true, obj.send(:metaclass).method_defined?(:foo)
236
+ end
237
+
238
+ should "pass opts down to children when initializing" do
239
+ opts = { custom: "opts" }
240
+
241
+ # messaging_profile comes with a `sources` list that makes a convenient object to
242
+ # perform tests on
243
+ obj = Telnyx::TelnyxObject.construct_from({
244
+ sources: [
245
+ {},
246
+ ],
247
+ }, opts)
248
+
249
+ source = obj.sources.first
250
+ # Pulling `@opts` as an instance variable here is not ideal, but it's
251
+ # important enough argument that the test here is worth it. we should
252
+ # consider exposing it publicly on a future pull (and possibly renaming
253
+ # it to something more useful).
254
+ assert_equal opts, source.instance_variable_get(:@opts)
255
+ end
256
+
257
+ should "#serialize_params on an empty object" do
258
+ obj = Telnyx::TelnyxObject.construct_from({})
259
+ assert_equal({}, obj.serialize_params)
260
+ end
261
+
262
+ should "#serialize_params on a new object with a subobject" do
263
+ obj = Telnyx::TelnyxObject.new
264
+ obj.metadata = { foo: "bar" }
265
+ assert_equal({ metadata: { foo: "bar" } },
266
+ obj.serialize_params)
267
+ end
268
+
269
+ should "#serialize_params on a basic object" do
270
+ obj = Telnyx::TelnyxObject.construct_from(foo: nil)
271
+ obj.update_attributes(foo: "bar")
272
+ assert_equal({ foo: "bar" }, obj.serialize_params)
273
+ end
274
+
275
+ should "#serialize_params on a more complex object" do
276
+ obj = Telnyx::TelnyxObject.construct_from(foo: Telnyx::TelnyxObject.construct_from(bar: nil,
277
+ baz: nil))
278
+ obj.foo.bar = "newbar"
279
+ assert_equal({ foo: { bar: "newbar" } },
280
+ obj.serialize_params)
281
+ end
282
+
283
+ should "#serialize_params on an array" do
284
+ obj = Telnyx::TelnyxObject.construct_from(foo: nil)
285
+ obj.foo = ["new-value"]
286
+ assert_equal({ foo: ["new-value"] },
287
+ obj.serialize_params)
288
+ end
289
+
290
+ should "#serialize_params on an array that shortens" do
291
+ obj = Telnyx::TelnyxObject.construct_from(foo: ["0-index", "1-index", "2-index"])
292
+ obj.foo = ["new-value"]
293
+ assert_equal({ foo: ["new-value"] },
294
+ obj.serialize_params)
295
+ end
296
+
297
+ should "#serialize_params on an array that lengthens" do
298
+ obj = Telnyx::TelnyxObject.construct_from(foo: ["0-index", "1-index", "2-index"])
299
+ obj.foo = ["new-value"] * 4
300
+ assert_equal({ foo: ["new-value"] * 4 },
301
+ obj.serialize_params)
302
+ end
303
+
304
+ should "#serialize_params on an array of hashes" do
305
+ obj = Telnyx::TelnyxObject.construct_from(foo: nil)
306
+ obj.foo = [
307
+ Telnyx::TelnyxObject.construct_from(bar: nil),
308
+ ]
309
+ obj.foo[0].bar = "baz"
310
+ assert_equal({ foo: [{ bar: "baz" }] },
311
+ obj.serialize_params)
312
+ end
313
+
314
+ should "#serialize_params doesn't include unchanged values" do
315
+ obj = Telnyx::TelnyxObject.construct_from(foo: nil)
316
+ assert_equal({}, obj.serialize_params)
317
+ end
318
+
319
+ should "#serialize_params on an array that is unchanged" do
320
+ obj = Telnyx::TelnyxObject.construct_from(foo: ["0-index", "1-index", "2-index"])
321
+ obj.foo = ["0-index", "1-index", "2-index"]
322
+ assert_equal({}, obj.serialize_params)
323
+ end
324
+
325
+ should "#serialize_params with a TelnyxObject" do
326
+ obj = Telnyx::TelnyxObject.construct_from({})
327
+
328
+ # using an #update_attributes will end up converting a Hash into a
329
+ # TelnyxObject
330
+ obj.metadata =
331
+ Telnyx::TelnyxObject.construct_from(foo: "bar")
332
+
333
+ serialized = obj.serialize_params
334
+ assert_equal({ foo: "bar" }, serialized[:metadata])
335
+ end
336
+
337
+ should "#serialize_params with TelnyxObject that's been replaced" do
338
+ obj = Telnyx::TelnyxObject.construct_from(source: Telnyx::TelnyxObject.construct_from(bar: "foo"))
339
+
340
+ # Here we replace the object wholesale.
341
+ obj.source =
342
+ Telnyx::TelnyxObject.construct_from(baz: "foo")
343
+
344
+ serialized = obj.serialize_params
345
+ assert_equal({ baz: "foo" }, serialized[:source])
346
+ end
347
+
348
+ should "#serialize_params with TelnyxObject that's been replaced which is `metadata`" do
349
+ class WithAdditiveObjectParam < Telnyx::TelnyxObject
350
+ additive_object_param :metadata
351
+ end
352
+
353
+ obj = WithAdditiveObjectParam.construct_from(metadata: Telnyx::TelnyxObject.construct_from(bar: "foo"))
354
+
355
+ # Here we replace the object wholesale. Because it's `metadata`, the
356
+ # client must be able to blank out the values that were in the old
357
+ # object, but which are no longer present in the new one.
358
+ obj.metadata =
359
+ Telnyx::TelnyxObject.construct_from(baz: "foo")
360
+
361
+ serialized = obj.serialize_params
362
+ assert_equal({ bar: "", baz: "foo" }, serialized[:metadata])
363
+ end
364
+
365
+ should "#serialize_params with an array of TelnyxObjects" do
366
+ obj = Telnyx::TelnyxObject.construct_from({})
367
+ obj.metadata = [
368
+ Telnyx::TelnyxObject.construct_from(foo: "bar"),
369
+ ]
370
+
371
+ serialized = obj.serialize_params
372
+ assert_equal([{ foo: "bar" }], serialized[:metadata])
373
+ end
374
+
375
+ should "#serialize_params and embed an API resource that's been set and has an ID" do
376
+ messaging_profile = MessagingProfile.construct_from(id: "123")
377
+ obj = Telnyx::TelnyxObject.construct_from({})
378
+
379
+ # the key here is that the property is set explicitly (and therefore
380
+ # marked as unsaved), which is why it gets included below
381
+ obj.messaging_profile = messaging_profile
382
+
383
+ serialized = obj.serialize_params
384
+ assert_equal({ messaging_profile: messaging_profile }, serialized)
385
+ end
386
+
387
+ should "#serialize_params and not include API resources that have not been set" do
388
+ messaging_profile = MessagingProfile.construct_from(id: "123")
389
+ obj = Telnyx::TelnyxObject.construct_from(messaging_profile: messaging_profile)
390
+
391
+ serialized = obj.serialize_params
392
+ assert_equal({}, serialized)
393
+ end
394
+
395
+ should "#serialize_params serializes API resources flagged with save_with_parent" do
396
+ c = MessagingProfile.construct_from({})
397
+ c.save_with_parent = true
398
+
399
+ obj = Telnyx::TelnyxObject.construct_from(messaging_profile: c)
400
+
401
+ serialized = obj.serialize_params
402
+ assert_equal({ messaging_profile: {} }, serialized)
403
+ end
404
+
405
+ should "#serialize_params should raise an error on other embedded API resources" do
406
+ # This messaging_profile doesn't have an ID and therefore the library doesn't know
407
+ # what to do with it and throws an ArgumentError because it's probably
408
+ # not what the user expected to happen.
409
+ messaging_profile = MessagingProfile.construct_from({})
410
+
411
+ obj = Telnyx::TelnyxObject.construct_from({})
412
+ obj.messaging_profile = messaging_profile
413
+
414
+ e = assert_raises(ArgumentError) do
415
+ obj.serialize_params
416
+ end
417
+ assert_equal "Cannot save property `messaging_profile` containing " \
418
+ "an API resource. It doesn't appear to be persisted and is " \
419
+ "not marked as `save_with_parent`.", e.message
420
+ end
421
+
422
+ should "#serialize_params takes a force option" do
423
+ obj = Telnyx::TelnyxObject.construct_from(id: "id",
424
+ meta: Telnyx::TelnyxObject.construct_from(foo: "bar"))
425
+
426
+ serialized = obj.serialize_params(force: true)
427
+ assert_equal({ id: "id", meta: { foo: "bar" } }, serialized)
428
+ end
429
+
430
+ should "#dirty! forces an object and its subobjects to be saved" do
431
+ obj = Telnyx::TelnyxObject.construct_from(id: "id",
432
+ meta: Telnyx::TelnyxObject.construct_from(foo: "bar"))
433
+
434
+ # note that `force` and `dirty!` are for different things, but are
435
+ # functionally equivalent
436
+ obj.dirty!
437
+
438
+ serialized = obj.serialize_params
439
+ assert_equal({ id: "id", meta: { foo: "bar" } }, serialized)
440
+ end
441
+
442
+ should "#to_s will call to_s for all embedded telnyx objects" do
443
+ obj = Telnyx::TelnyxObject.construct_from(id: "id",
444
+ # embedded list object
445
+ refunds: Telnyx::ListObject.construct_from(data: [
446
+ # embedded object in list
447
+ Telnyx::TelnyxObject.construct_from(id: "id",
448
+ # embedded object in an object in a list object
449
+ meta: Telnyx::TelnyxObject.construct_from(foo: "bar")),
450
+ ]),
451
+ # embedded telnyx object
452
+ meta: Telnyx::TelnyxObject.construct_from(foo: "bar"))
453
+ expected = JSON.pretty_generate(id: "id",
454
+ refunds: {
455
+ data: [
456
+ { id: "id", meta: { foo: "bar" } },
457
+ ],
458
+ },
459
+ meta: { foo: "bar" })
460
+
461
+ assert_equal(expected, obj.to_s)
462
+ end
463
+
464
+ should "error on setting a property to an empty string" do
465
+ obj = Telnyx::TelnyxObject.construct_from(foo: "bar")
466
+ e = assert_raises ArgumentError do
467
+ obj.foo = ""
468
+ end
469
+ assert_match(/\(object\).foo = nil/, e.message)
470
+ end
471
+
472
+ should "marshal and unmarshal using custom encoder and decoder" do
473
+ obj = Telnyx::TelnyxObject.construct_from(
474
+ { id: 1, name: "Telnyx" },
475
+ api_key: "apikey",
476
+ client: TelnyxClient.active_client
477
+ )
478
+ m = Marshal.load(Marshal.dump(obj))
479
+ assert_equal 1, m.id
480
+ assert_equal "Telnyx", m.name
481
+ expected_hash = { api_key: "apikey" }
482
+ assert_equal expected_hash, m.instance_variable_get("@opts")
483
+ end
484
+
485
+ context "#method" do
486
+ should "act as a getter if no arguments are provided" do
487
+ obj = Telnyx::TelnyxObject.construct_from(id: 1, method: "foo")
488
+ assert_equal "foo", obj.method
489
+ end
490
+
491
+ should "call Object#method if an argument is provided" do
492
+ obj = Telnyx::TelnyxObject.construct_from(id: 1, method: "foo")
493
+ assert obj.method(:id).is_a?(Method)
494
+ end
495
+ end
496
+ end
497
+ end