onlyoffice-docs_integration_sdk 0.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 (31) hide show
  1. checksums.yaml +7 -0
  2. data/lib/onlyoffice/docs_integration_sdk/document_editor/config.rb +1479 -0
  3. data/lib/onlyoffice/docs_integration_sdk/document_editor/config_test.rb +1713 -0
  4. data/lib/onlyoffice/docs_integration_sdk/document_editor.rb +29 -0
  5. data/lib/onlyoffice/docs_integration_sdk/document_server/client/command.rb +417 -0
  6. data/lib/onlyoffice/docs_integration_sdk/document_server/client/command_test.rb +672 -0
  7. data/lib/onlyoffice/docs_integration_sdk/document_server/client/conversion.rb +477 -0
  8. data/lib/onlyoffice/docs_integration_sdk/document_server/client/conversion_test.rb +682 -0
  9. data/lib/onlyoffice/docs_integration_sdk/document_server/client/healthcheck.rb +101 -0
  10. data/lib/onlyoffice/docs_integration_sdk/document_server/client/healthcheck_test.rb +209 -0
  11. data/lib/onlyoffice/docs_integration_sdk/document_server/client/jwt.rb +116 -0
  12. data/lib/onlyoffice/docs_integration_sdk/document_server/client/jwt_test.rb +70 -0
  13. data/lib/onlyoffice/docs_integration_sdk/document_server/client/response.rb +73 -0
  14. data/lib/onlyoffice/docs_integration_sdk/document_server/client/response_test.rb +49 -0
  15. data/lib/onlyoffice/docs_integration_sdk/document_server/client/service.rb +44 -0
  16. data/lib/onlyoffice/docs_integration_sdk/document_server/client/ua.rb +31 -0
  17. data/lib/onlyoffice/docs_integration_sdk/document_server/client/ua_test.rb +35 -0
  18. data/lib/onlyoffice/docs_integration_sdk/document_server/client.rb +321 -0
  19. data/lib/onlyoffice/docs_integration_sdk/document_server/client_test.rb +1259 -0
  20. data/lib/onlyoffice/docs_integration_sdk/document_server.rb +29 -0
  21. data/lib/onlyoffice/docs_integration_sdk/document_storage/callback.rb +276 -0
  22. data/lib/onlyoffice/docs_integration_sdk/document_storage/callback_test.rb +291 -0
  23. data/lib/onlyoffice/docs_integration_sdk/document_storage.rb +29 -0
  24. data/lib/onlyoffice/docs_integration_sdk/jwt.rb +448 -0
  25. data/lib/onlyoffice/docs_integration_sdk/jwt_test.rb +598 -0
  26. data/lib/onlyoffice/docs_integration_sdk/test_test.rb +113 -0
  27. data/lib/onlyoffice/docs_integration_sdk/version.rb +26 -0
  28. data/lib/onlyoffice/docs_integration_sdk/version_test.rb +33 -0
  29. data/lib/onlyoffice/docs_integration_sdk.rb +31 -0
  30. data/lib/onlyoffice.rb +21 -0
  31. metadata +283 -0
@@ -0,0 +1,682 @@
1
+ #
2
+ # (c) Copyright Ascensio System SIA 2025
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ # typed: true
18
+ # frozen_string_literal: true
19
+
20
+ require "test/unit"
21
+ require_relative "../../jwt"
22
+ require_relative "../../test_test"
23
+ require_relative "../client_test"
24
+ require_relative "conversion"
25
+
26
+ module Onlyoffice
27
+ module DocsIntegrationSdk
28
+ module DocumentServer
29
+ class Client
30
+ class ConversionService
31
+ class ErrorTest < ::Test::Unit::TestCase
32
+ extend T::Sig
33
+ include Test::DescriptiveEnumMarshalling
34
+
35
+ sig {override.returns(T::Array[[Integer, String, Error]])}
36
+ def cases
37
+ [
38
+ [
39
+ -1,
40
+ "Unknown error",
41
+ Error::UnknownError,
42
+ ],
43
+ [
44
+ -2,
45
+ "Conversion timeout error",
46
+ Error::ConversionTimeout,
47
+ ],
48
+ [
49
+ -3,
50
+ "Conversion error",
51
+ Error::ConversionError,
52
+ ],
53
+ [
54
+ -4,
55
+ "Error while downloading the document file to be converted",
56
+ Error::DownloadError,
57
+ ],
58
+ [
59
+ -5,
60
+ "Incorrect password",
61
+ Error::IncorrectPassword,
62
+ ],
63
+ [
64
+ -6,
65
+ "Error while accessing the conversion result database",
66
+ Error::DatabaseError,
67
+ ],
68
+ [
69
+ -7,
70
+ "Input error",
71
+ Error::InputError,
72
+ ],
73
+ [
74
+ -8,
75
+ "Invalid token",
76
+ Error::InvalidToken,
77
+ ],
78
+ [
79
+ -9,
80
+ "The converter cannot automatically determine the output file format",
81
+ Error::UnknownFormat,
82
+ ],
83
+ [
84
+ -10,
85
+ "Size limit exceeded",
86
+ Error::SizeLimitExceeded,
87
+ ],
88
+ ]
89
+ end
90
+ end
91
+
92
+ class Request
93
+ class DelimiterTest < ::Test::Unit::TestCase
94
+ extend T::Sig
95
+ include Test::BasicEnumMarshalling
96
+
97
+ sig {override.returns(T::Array[[Integer, Delimiter]])}
98
+ def cases
99
+ [
100
+ [0, Delimiter::None],
101
+ [1, Delimiter::Tab],
102
+ [2, Delimiter::Semicolon],
103
+ [3, Delimiter::Colon],
104
+ [4, Delimiter::Comma],
105
+ [5, Delimiter::Space],
106
+ ]
107
+ end
108
+ end
109
+
110
+ class DocumentLayoutTest < ::Test::Unit::TestCase
111
+ extend T::Sig
112
+ include Test::StructMarshalling
113
+
114
+ sig {override.returns(T::Array[[T.untyped, DocumentLayout]])}
115
+ def cases
116
+ [
117
+ [
118
+ {},
119
+ DocumentLayout.new,
120
+ ],
121
+ [
122
+ {
123
+ "drawPlaceHolders" => true,
124
+ "drawFormHighlight" => true,
125
+ "isPrint" => true,
126
+ },
127
+ DocumentLayout.new(
128
+ draw_place_holders: true,
129
+ draw_form_highlight: true,
130
+ is_print: true,
131
+ ),
132
+ ],
133
+ ]
134
+ end
135
+ end
136
+
137
+ class DocumentRenderer
138
+ class TextAssociationTest < ::Test::Unit::TestCase
139
+ extend T::Sig
140
+ include Test::BasicEnumMarshalling
141
+
142
+ sig {override.returns(T::Array[[String, TextAssociation]])}
143
+ def cases
144
+ [
145
+ ["blockChar", TextAssociation::BlockChar],
146
+ ["blockLine", TextAssociation::BlockLine],
147
+ ["plainLine", TextAssociation::PlainLine],
148
+ ["plainParagraph", TextAssociation::PlainParagraph],
149
+ ]
150
+ end
151
+ end
152
+ end
153
+
154
+ class DocumentRendererTest < ::Test::Unit::TestCase
155
+ extend T::Sig
156
+ include Test::StructMarshalling
157
+
158
+ sig {override.returns(T::Array[[T.untyped, DocumentRenderer]])}
159
+ def cases
160
+ [
161
+ [
162
+ {},
163
+ DocumentRenderer.new,
164
+ ],
165
+ [
166
+ {
167
+ "textAssociation" => "blockChar",
168
+ },
169
+ DocumentRenderer.new(
170
+ text_association: DocumentRenderer::TextAssociation::BlockChar,
171
+ ),
172
+ ],
173
+ ]
174
+ end
175
+ end
176
+
177
+ class PdfTest < ::Test::Unit::TestCase
178
+ extend T::Sig
179
+ include Test::StructMarshalling
180
+
181
+ sig {override.returns(T::Array[[T.untyped, Pdf]])}
182
+ def cases
183
+ [
184
+ [
185
+ {},
186
+ Pdf.new,
187
+ ],
188
+ [
189
+ {
190
+ "form" => true,
191
+ },
192
+ Pdf.new(
193
+ form: true,
194
+ ),
195
+ ],
196
+ ]
197
+ end
198
+ end
199
+
200
+ class SpreadsheetLayout
201
+ class MarginsTest < ::Test::Unit::TestCase
202
+ extend T::Sig
203
+ include Test::StructMarshalling
204
+
205
+ sig {override.returns(T::Array[[T.untyped, Margins]])}
206
+ def cases
207
+ [
208
+ [
209
+ {},
210
+ Margins.new,
211
+ ],
212
+ [
213
+ {
214
+ "bottom" => "1mm",
215
+ "left" => "1mm",
216
+ "right" => "1mm",
217
+ "top" => "1mm",
218
+ },
219
+ Margins.new(
220
+ bottom: "1mm",
221
+ left: "1mm",
222
+ right: "1mm",
223
+ top: "1mm",
224
+ ),
225
+ ],
226
+ ]
227
+ end
228
+ end
229
+
230
+ class OrientationTest < ::Test::Unit::TestCase
231
+ extend T::Sig
232
+ include Test::BasicEnumMarshalling
233
+
234
+ sig {override.returns(T::Array[[String, Orientation]])}
235
+ def cases
236
+ [
237
+ ["landscape", Orientation::Landscape],
238
+ ["portrait", Orientation::Portrait],
239
+ ]
240
+ end
241
+ end
242
+
243
+ class PageSizeTest < ::Test::Unit::TestCase
244
+ extend T::Sig
245
+ include Test::StructMarshalling
246
+
247
+ sig {override.returns(T::Array[[T.untyped, PageSize]])}
248
+ def cases
249
+ [
250
+ [
251
+ {},
252
+ PageSize.new,
253
+ ],
254
+ [
255
+ {
256
+ "height" => "1mm",
257
+ "width" => "1mm",
258
+ },
259
+ PageSize.new(
260
+ height: "1mm",
261
+ width: "1mm",
262
+ ),
263
+ ],
264
+ ]
265
+ end
266
+ end
267
+ end
268
+
269
+ class SpreadsheetLayoutTest < ::Test::Unit::TestCase
270
+ extend T::Sig
271
+ include Test::StructMarshalling
272
+
273
+ sig {override.returns(T::Array[[T.untyped, SpreadsheetLayout]])}
274
+ def cases
275
+ [
276
+ [
277
+ {},
278
+ SpreadsheetLayout.new,
279
+ ],
280
+ [
281
+ {
282
+ "fitToHeight" => 1,
283
+ "fitToWidth" => 1,
284
+ "gridLines" => true,
285
+ "headings" => true,
286
+ "ignorePrintArea" => true,
287
+ "margins" => {
288
+ "bottom" => "1mm",
289
+ },
290
+ "orientation" => "landscape",
291
+ "pageSize" => {
292
+ "height" => "1mm",
293
+ },
294
+ "scale" => 1,
295
+ },
296
+ SpreadsheetLayout.new(
297
+ fit_to_height: 1,
298
+ fit_to_width: 1,
299
+ grid_lines: true,
300
+ headings: true,
301
+ ignore_print_area: true,
302
+ margins: SpreadsheetLayout::Margins.new(
303
+ bottom: "1mm",
304
+ ),
305
+ orientation: SpreadsheetLayout::Orientation::Landscape,
306
+ page_size: SpreadsheetLayout::PageSize.new(
307
+ height: "1mm",
308
+ ),
309
+ scale: 1,
310
+ ),
311
+ ],
312
+ ]
313
+ end
314
+ end
315
+
316
+ class Thumbnail
317
+ class AspectTest < ::Test::Unit::TestCase
318
+ extend T::Sig
319
+ include Test::BasicEnumMarshalling
320
+
321
+ sig {override.returns(T::Array[[Integer, Aspect]])}
322
+ def cases
323
+ [
324
+ [0, Aspect::Stretch],
325
+ [1, Aspect::Keep],
326
+ [2, Aspect::Page],
327
+ ]
328
+ end
329
+ end
330
+ end
331
+
332
+ class ThumbnailTest < ::Test::Unit::TestCase
333
+ extend T::Sig
334
+ include Test::StructMarshalling
335
+
336
+ sig {override.returns(T::Array[[T.untyped, Thumbnail]])}
337
+ def cases
338
+ [
339
+ [
340
+ {},
341
+ Thumbnail.new,
342
+ ],
343
+ [
344
+ {
345
+ "aspect" => 1,
346
+ "first" => true,
347
+ "height" => 1,
348
+ "width" => 1,
349
+ },
350
+ Thumbnail.new(
351
+ aspect: Thumbnail::Aspect::Keep,
352
+ first: true,
353
+ height: 1,
354
+ width: 1,
355
+ ),
356
+ ],
357
+ ]
358
+ end
359
+ end
360
+ end
361
+
362
+ class RequestTest < ::Test::Unit::TestCase
363
+ extend T::Sig
364
+ include Test::StructMarshalling
365
+
366
+ sig {override.returns(T::Array[[T.untyped, Request]])}
367
+ def cases
368
+ [
369
+ [
370
+ {},
371
+ Request.new,
372
+ ],
373
+ [
374
+ {
375
+ "async" => false,
376
+ "codePage" => 1,
377
+ "delimiter" => 1,
378
+ "documentLayout" => {
379
+ "drawPlaceHolders" => true,
380
+ },
381
+ "documentRenderer" => {
382
+ "textAssociation" => "blockChar",
383
+ },
384
+ "filetype" => "docx",
385
+ "key" => "***",
386
+ "outputtype" => "pdf",
387
+ "password" => "***",
388
+ "pdf" => {
389
+ "form" => true,
390
+ },
391
+ "region" => "en",
392
+ "spreadsheetLayout" => {
393
+ "fitToHeight" => 1,
394
+ },
395
+ "thumbnail" => {
396
+ "aspect" => 1,
397
+ },
398
+ "title" => "Title",
399
+ "url" => "http://example.com/",
400
+ },
401
+ Request.new(
402
+ async: false,
403
+ code_page: 1,
404
+ delimiter: Request::Delimiter::Tab,
405
+ document_layout: Request::DocumentLayout.new(
406
+ draw_place_holders: true,
407
+ ),
408
+ document_renderer: Request::DocumentRenderer.new(
409
+ text_association: Request::DocumentRenderer::TextAssociation::BlockChar,
410
+ ),
411
+ filetype: "docx",
412
+ key: "***",
413
+ outputtype: "pdf",
414
+ password: "***",
415
+ pdf: Request::Pdf.new(
416
+ form: true,
417
+ ),
418
+ region: "en",
419
+ spreadsheet_layout: Request::SpreadsheetLayout.new(
420
+ fit_to_height: 1,
421
+ ),
422
+ thumbnail: Request::Thumbnail.new(
423
+ aspect: Request::Thumbnail::Aspect::Keep,
424
+ ),
425
+ title: "Title",
426
+ url: "http://example.com/",
427
+ ),
428
+ ],
429
+ ]
430
+ end
431
+ end
432
+ end
433
+
434
+ class ConversionServiceTest < ::Test::Unit::TestCase
435
+ extend T::Sig
436
+ include Test::DocumentServer::Client
437
+
438
+ sig {returns(String)}
439
+ def req_s
440
+ '{"async":true}'
441
+ end
442
+
443
+ sig {returns(T::Hash[String, T.untyped])}
444
+ def req_h
445
+ {"async" => true}
446
+ end
447
+
448
+ sig {returns(ConversionService::Request)}
449
+ def req_o
450
+ req = ConversionService::Request.new(async: true)
451
+ end
452
+
453
+ sig {returns(String)}
454
+ def res_s
455
+ '{"endConvert":"true"}'
456
+ end
457
+
458
+ sig {returns(ConversionService::Result)}
459
+ def res_o
460
+ ConversionService::Result.new(end_convert: true)
461
+ end
462
+
463
+ def test_do_does
464
+ t = self
465
+
466
+ m = "POST"
467
+ u = T.cast(URI.parse("http://localhost:8080/"), URI::HTTP)
468
+ p = T.cast(URI.join(u.to_s, "ConvertService.ashx"), URI::HTTP)
469
+ h = T.let(Net::HTTP.new(u.hostname, u.port), Net::HTTP)
470
+
471
+ h.define_singleton_method(:request) do |req, body = nil, &block|
472
+ t.check_request_basics(m, p, req)
473
+ t.check_request_headers_with_content_type(m, u, req)
474
+ t.assert_equal(t.req_s, req.body)
475
+ t.assert_nil(body)
476
+ t.assert_nil(block)
477
+ t.create_ok(t.res_s)
478
+ end
479
+
480
+ c = Client.new(base_uri: u, http: h)
481
+
482
+ con, res = c.conversion.do(req_o)
483
+ assert_nil(res.error)
484
+
485
+ assert_equal(res_s, res.response.body)
486
+ # todo: assert_equal(res_o, con)
487
+ end
488
+
489
+ def test_do_does_with_the_subpath
490
+ t = self
491
+
492
+ m = "POST"
493
+ u = T.cast(URI.parse("http://localhost:8080/sub/"), URI::HTTP)
494
+ p = T.cast(URI.join(u.to_s, "ConvertService.ashx"), URI::HTTP)
495
+ h = T.let(Net::HTTP.new(u.hostname, u.port), Net::HTTP)
496
+
497
+ h.define_singleton_method(:request) do |req, body = nil, &block|
498
+ t.check_request_basics(m, p, req)
499
+ t.check_request_headers_with_content_type(m, u, req)
500
+ t.assert_equal(t.req_s, req.body)
501
+ t.assert_nil(body)
502
+ t.assert_nil(block)
503
+ t.create_ok(t.res_s)
504
+ end
505
+
506
+ c = Client.new(base_uri: u, http: h)
507
+
508
+ con, res = c.conversion.do(req_o)
509
+ assert_nil(res.error)
510
+
511
+ assert_equal(res_s, res.response.body)
512
+ # todo: assert_equal(res_o, con)
513
+ end
514
+
515
+ def test_do_does_with_the_user_agent
516
+ t = self
517
+
518
+ m = "POST"
519
+ u = T.cast(URI.parse("http://localhost:8080/"), URI::HTTP)
520
+ p = T.cast(URI.join(u.to_s, "ConvertService.ashx"), URI::HTTP)
521
+ h = T.let(Net::HTTP.new(u.hostname, u.port), Net::HTTP)
522
+
523
+ h.define_singleton_method(:request) do |req, body = nil, &block|
524
+ t.check_request_basics(m, p, req)
525
+ t.check_request_headers_with_content_type_and_custom_user_agent(m, u, "my-agent", req)
526
+ t.assert_equal(t.req_s, req.body)
527
+ t.assert_nil(body)
528
+ t.assert_nil(block)
529
+ t.create_ok(t.res_s)
530
+ end
531
+
532
+ c = Client.new(base_uri: u, http: h, user_agent: "my-agent")
533
+
534
+ con, res = c.conversion.do(req_o)
535
+ assert_nil(res.error)
536
+
537
+ assert_equal(res_s, res.response.body)
538
+ # todo: assert_equal(res_o, con)
539
+ end
540
+
541
+ def test_do_does_with_the_jwt
542
+ t = self
543
+
544
+ w = DocsIntegrationSdk::Jwt.new(secret: "***")
545
+ m = "POST"
546
+ u = T.cast(URI.parse("http://localhost:8080/"), URI::HTTP)
547
+ p = T.cast(URI.join(u.to_s, "ConvertService.ashx"), URI::HTTP)
548
+ h = T.let(Net::HTTP.new(u.hostname, u.port), Net::HTTP)
549
+
550
+ h.define_singleton_method(:request) do |req, body = nil, &block|
551
+ t.check_request_basics(m, p, req)
552
+ t.check_request_headers_with_jwt(m, u, w, t.req_h, req)
553
+ t.check_request_body_with_jwt(w, t.req_h, req)
554
+ t.assert_nil(body)
555
+ t.assert_nil(block)
556
+ t.create_ok(t.res_s)
557
+ end
558
+
559
+ j = Jwt.new(jwt: w)
560
+ c = Client.new(base_uri: u, http: h).with_jwt(j)
561
+
562
+ con, res = c.conversion.do(req_o)
563
+ assert_nil(res.error)
564
+
565
+ assert_equal(res_s, res.response.body)
566
+ # todo: assert_equal(res_o, con)
567
+ end
568
+
569
+ def test_do_returns_an_error_if_the_response_body_is_invalid_json
570
+ t = self
571
+
572
+ m = "POST"
573
+ u = T.cast(URI.parse("http://localhost:8080/"), URI::HTTP)
574
+ p = T.cast(URI.join(u.to_s, "ConvertService.ashx"), URI::HTTP)
575
+ h = T.let(Net::HTTP.new(u.hostname, u.port), Net::HTTP)
576
+
577
+ h.define_singleton_method(:request) do |req, body = nil, &block|
578
+ t.check_request_basics(m, p, req)
579
+ t.check_request_headers_with_content_type(m, u, req)
580
+ t.assert_equal(t.req_s, req.body)
581
+ t.assert_nil(body)
582
+ t.assert_nil(block)
583
+ t.create_ok("}")
584
+ end
585
+
586
+ c = Client.new(base_uri: u, http: h)
587
+
588
+ con, res = c.conversion.do(req_o)
589
+
590
+ err = T.cast(res.error, JSON::ParserError)
591
+ assert_equal("unexpected token at '}'", err.message)
592
+
593
+ assert_equal("}", res.response.body)
594
+ # todo: assert_equal(ConversionService::Result.new, con)
595
+ end
596
+
597
+ def test_do_returns_an_error_if_the_doing_fails
598
+ for v in ConversionService::Error.values
599
+ t = self
600
+
601
+ m = "POST"
602
+ u = T.cast(URI.parse("http://localhost:8080/"), URI::HTTP)
603
+ p = T.cast(URI.join(u.to_s, "ConvertService.ashx"), URI::HTTP)
604
+ h = T.let(Net::HTTP.new(u.hostname, u.port), Net::HTTP)
605
+
606
+ h.define_singleton_method(:request) do |req, body = nil, &block|
607
+ t.check_request_basics(m, p, req)
608
+ t.check_request_headers_with_content_type(m, u, req)
609
+ t.assert_equal(t.req_s, req.body)
610
+ t.assert_nil(body)
611
+ t.assert_nil(block)
612
+ t.create_ok("{\"error\":#{v.serialize}}")
613
+ end
614
+
615
+ c = Client.new(base_uri: u, http: h)
616
+
617
+ con, res = c.conversion.do(req_o)
618
+ assert_equal(v, res.error)
619
+
620
+ assert_equal("{\"error\":#{v.serialize}}", res.response.body)
621
+ # todo: assert_equal(ConversionService::Result.new, con)
622
+ end
623
+ end
624
+
625
+ def test_do_returns_an_error_if_the_doing_fails_with_an_unknown_error
626
+ t = self
627
+
628
+ m = "POST"
629
+ u = T.cast(URI.parse("http://localhost:8080/"), URI::HTTP)
630
+ p = T.cast(URI.join(u.to_s, "ConvertService.ashx"), URI::HTTP)
631
+ h = T.let(Net::HTTP.new(u.hostname, u.port), Net::HTTP)
632
+
633
+ h.define_singleton_method(:request) do |req, body = nil, &block|
634
+ t.check_request_basics(m, p, req)
635
+ t.check_request_headers_with_content_type(m, u, req)
636
+ t.assert_equal(t.req_s, req.body)
637
+ t.assert_nil(body)
638
+ t.assert_nil(block)
639
+ t.create_ok('{"error":9999}')
640
+ end
641
+
642
+ c = Client.new(base_uri: u, http: h)
643
+
644
+ con, res = c.conversion.do(req_o)
645
+
646
+ err = T.cast(res.error, KeyError)
647
+ assert_equal("Enum Onlyoffice::DocsIntegrationSdk::DocumentServer::Client::ConversionService::Error key not found: 9999", err.message)
648
+
649
+ assert_equal('{"error":9999}', res.response.body)
650
+ # todo: assert_equal(ConversionService::Result.new, con)
651
+ end
652
+
653
+ def test_do_ignores_unknown_keys_in_the_response
654
+ t = self
655
+
656
+ m = "POST"
657
+ u = T.cast(URI.parse("http://localhost:8080/"), URI::HTTP)
658
+ p = T.cast(URI.join(u.to_s, "ConvertService.ashx"), URI::HTTP)
659
+ h = T.let(Net::HTTP.new(u.hostname, u.port), Net::HTTP)
660
+
661
+ h.define_singleton_method(:request) do |req, body = nil, &block|
662
+ t.check_request_basics(m, p, req)
663
+ t.check_request_headers_with_content_type(m, u, req)
664
+ t.assert_equal(t.req_s, req.body)
665
+ t.assert_nil(body)
666
+ t.assert_nil(block)
667
+ t.create_ok('{"unknown":true}')
668
+ end
669
+
670
+ c = Client.new(base_uri: u, http: h)
671
+
672
+ con, res = c.conversion.do(req_o)
673
+ assert_nil(res.error)
674
+
675
+ assert_equal('{"unknown":true}', res.response.body)
676
+ # todo: assert_equal(ConversionService::Result.new, con)
677
+ end
678
+ end
679
+ end
680
+ end
681
+ end
682
+ end