deepl-rb 3.6.0 → 3.6.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 (103) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +27 -0
  3. data/.github/workflows/add_issues_to_kanban.yml +16 -0
  4. data/.gitlab-ci.yml +172 -0
  5. data/.rubocop.yml +51 -0
  6. data/CHANGELOG.md +22 -3
  7. data/CODE_OF_CONDUCT.md +132 -0
  8. data/CONTRIBUTING.md +37 -0
  9. data/Gemfile +24 -0
  10. data/Rakefile +56 -0
  11. data/SECURITY.md +58 -0
  12. data/VERSION +1 -0
  13. data/deepl-rb.gemspec +140 -0
  14. data/lib/deepl/api.rb +22 -0
  15. data/lib/deepl/configuration.rb +59 -0
  16. data/lib/deepl/constants/base_constant.rb +18 -0
  17. data/lib/deepl/constants/formality.rb +16 -0
  18. data/lib/deepl/constants/model_type.rb +14 -0
  19. data/lib/deepl/constants/split_sentences.rb +14 -0
  20. data/lib/deepl/constants/tag_handling.rb +13 -0
  21. data/lib/deepl/constants/tone.rb +20 -0
  22. data/lib/deepl/constants/writing_style.rb +20 -0
  23. data/lib/deepl/document_api.rb +121 -0
  24. data/lib/deepl/exceptions/authorization_failed.rb +14 -0
  25. data/lib/deepl/exceptions/bad_request.rb +16 -0
  26. data/lib/deepl/exceptions/document_translation_error.rb +15 -0
  27. data/lib/deepl/exceptions/error.rb +14 -0
  28. data/lib/deepl/exceptions/limit_exceeded.rb +18 -0
  29. data/lib/deepl/exceptions/not_found.rb +16 -0
  30. data/lib/deepl/exceptions/not_supported.rb +14 -0
  31. data/lib/deepl/exceptions/quota_exceeded.rb +14 -0
  32. data/lib/deepl/exceptions/request_entity_too_large.rb +15 -0
  33. data/lib/deepl/exceptions/request_error.rb +21 -0
  34. data/lib/deepl/exceptions/server_error.rb +18 -0
  35. data/lib/deepl/glossary_api.rb +38 -0
  36. data/lib/deepl/requests/base.rb +196 -0
  37. data/lib/deepl/requests/document/download.rb +44 -0
  38. data/lib/deepl/requests/document/get_status.rb +44 -0
  39. data/lib/deepl/requests/document/upload.rb +74 -0
  40. data/lib/deepl/requests/glossary/create.rb +59 -0
  41. data/lib/deepl/requests/glossary/destroy.rb +37 -0
  42. data/lib/deepl/requests/glossary/entries.rb +37 -0
  43. data/lib/deepl/requests/glossary/find.rb +38 -0
  44. data/lib/deepl/requests/glossary/language_pairs.rb +38 -0
  45. data/lib/deepl/requests/glossary/list.rb +37 -0
  46. data/lib/deepl/requests/languages.rb +37 -0
  47. data/lib/deepl/requests/rephrase.rb +55 -0
  48. data/lib/deepl/requests/style_rule/list.rb +59 -0
  49. data/lib/deepl/requests/translate.rb +93 -0
  50. data/lib/deepl/requests/usage.rb +33 -0
  51. data/lib/deepl/resources/base.rb +17 -0
  52. data/lib/deepl/resources/document_handle.rb +57 -0
  53. data/lib/deepl/resources/document_translation_status.rb +54 -0
  54. data/lib/deepl/resources/glossary.rb +28 -0
  55. data/lib/deepl/resources/language.rb +30 -0
  56. data/lib/deepl/resources/language_pair.rb +23 -0
  57. data/lib/deepl/resources/style_rule.rb +85 -0
  58. data/lib/deepl/resources/text.rb +24 -0
  59. data/lib/deepl/resources/usage.rb +27 -0
  60. data/lib/deepl/style_rule_api.rb +17 -0
  61. data/lib/deepl/utils/backoff_timer.rb +46 -0
  62. data/lib/deepl/utils/exception_builder.rb +34 -0
  63. data/lib/deepl.rb +158 -0
  64. data/lib/http_client_options.rb +22 -0
  65. data/lib/version.rb +8 -0
  66. data/spec/api/api_spec.rb +20 -0
  67. data/spec/api/configuration_spec.rb +122 -0
  68. data/spec/api/deepl_spec.rb +460 -0
  69. data/spec/constants/constants_spec.rb +158 -0
  70. data/spec/fixtures/vcr_cassettes/deepl_document.yml +95 -0
  71. data/spec/fixtures/vcr_cassettes/deepl_document_download.yml +1214 -0
  72. data/spec/fixtures/vcr_cassettes/deepl_glossaries.yml +1163 -0
  73. data/spec/fixtures/vcr_cassettes/deepl_languages.yml +54 -0
  74. data/spec/fixtures/vcr_cassettes/deepl_rephrase.yml +87 -0
  75. data/spec/fixtures/vcr_cassettes/deepl_translate.yml +358 -0
  76. data/spec/fixtures/vcr_cassettes/deepl_usage.yml +129 -0
  77. data/spec/fixtures/vcr_cassettes/glossaries.yml +1702 -0
  78. data/spec/fixtures/vcr_cassettes/languages.yml +229 -0
  79. data/spec/fixtures/vcr_cassettes/rephrase_texts.yml +401 -0
  80. data/spec/fixtures/vcr_cassettes/style_rules.yml +92 -0
  81. data/spec/fixtures/vcr_cassettes/translate_texts.yml +10630 -0
  82. data/spec/fixtures/vcr_cassettes/usage.yml +171 -0
  83. data/spec/integration_tests/document_api_spec.rb +178 -0
  84. data/spec/integration_tests/integration_test_utils.rb +170 -0
  85. data/spec/integration_tests/style_rule_api_spec.rb +79 -0
  86. data/spec/requests/extra_body_parameters_types_spec.rb +82 -0
  87. data/spec/requests/glossary/create_spec.rb +65 -0
  88. data/spec/requests/glossary/destroy_spec.rb +66 -0
  89. data/spec/requests/glossary/entries_spec.rb +62 -0
  90. data/spec/requests/glossary/find_spec.rb +68 -0
  91. data/spec/requests/glossary/language_pairs_spec.rb +40 -0
  92. data/spec/requests/glossary/list_spec.rb +54 -0
  93. data/spec/requests/languages_spec.rb +68 -0
  94. data/spec/requests/rephrase_spec.rb +172 -0
  95. data/spec/requests/translate_spec.rb +493 -0
  96. data/spec/requests/usage_spec.rb +43 -0
  97. data/spec/resources/glossary_spec.rb +38 -0
  98. data/spec/resources/language_pair_spec.rb +23 -0
  99. data/spec/resources/language_spec.rb +45 -0
  100. data/spec/resources/text_spec.rb +23 -0
  101. data/spec/resources/usage_spec.rb +35 -0
  102. data/spec/spec_helper.rb +92 -0
  103. metadata +102 -2
@@ -0,0 +1,493 @@
1
+ # Copyright 2018 Daniel Herzog
2
+ # Use of this source code is governed by an MIT
3
+ # license that can be found in the LICENSE.md file.
4
+ # frozen_string_literal: true
5
+
6
+ require 'spec_helper'
7
+
8
+ describe DeepL::Requests::Translate do
9
+ subject(:translate) { described_class.new(api, text, source_lang, target_lang, options) }
10
+
11
+ around do |tests|
12
+ tmp_env = replace_env_preserving_deepl_vars_except_mock_server
13
+ tests.call
14
+ ENV.replace(tmp_env)
15
+ end
16
+
17
+ let(:tags_str) { 'p,strong,span' }
18
+ let(:tags_array) { %w[p strong span] }
19
+
20
+ let(:api) { build_deepl_api }
21
+ let(:text) { 'Sample text' }
22
+ let(:source_lang) { 'EN' }
23
+ let(:target_lang) { 'ES' }
24
+ let(:options) { {} }
25
+
26
+ describe '#initialize' do
27
+ context 'when building a request' do
28
+ it 'creates a request object' do
29
+ expect(translate).to be_a(described_class)
30
+ end
31
+ end
32
+
33
+ context 'when using `splitting_tags` options' do
34
+ it 'works with a nil values' do
35
+ request = described_class.new(api, nil, nil, nil, splitting_tags: nil)
36
+ expect(request.options[:splitting_tags]).to be_nil
37
+ end
38
+
39
+ it 'works with a blank list' do
40
+ request = described_class.new(api, nil, nil, nil, splitting_tags: '')
41
+ expect(request.options[:splitting_tags]).to eq([])
42
+ end
43
+
44
+ it 'works with a comma-separated list and converts strings to an array' do
45
+ request = described_class.new(api, nil, nil, nil, splitting_tags: tags_str)
46
+ expect(request.options[:splitting_tags]).to eq(tags_array)
47
+ end
48
+
49
+ it 'works with an array of tags and leaves it as is' do
50
+ request = described_class.new(api, nil, nil, nil, splitting_tags: tags_array)
51
+ expect(request.options[:splitting_tags]).to eq(tags_array)
52
+ end
53
+ end
54
+
55
+ context 'when using `non_splitting_tags` options' do
56
+ it 'works with a nil values' do
57
+ request = described_class.new(api, nil, nil, nil, non_splitting_tags: nil)
58
+ expect(request.options[:non_splitting_tags]).to be_nil
59
+ end
60
+
61
+ it 'works with a blank list' do
62
+ request = described_class.new(api, nil, nil, nil, non_splitting_tags: '')
63
+ expect(request.options[:non_splitting_tags]).to eq([])
64
+ end
65
+
66
+ it 'works with a comma-separated list and converts strings to an array' do
67
+ request = described_class.new(api, nil, nil, nil, non_splitting_tags: tags_str)
68
+ expect(request.options[:non_splitting_tags]).to eq(tags_array)
69
+ end
70
+
71
+ it 'works with an array and leaves it as it is' do
72
+ request = described_class.new(api, nil, nil, nil, non_splitting_tags: tags_array)
73
+ expect(request.options[:non_splitting_tags]).to eq(tags_array)
74
+ end
75
+ end
76
+
77
+ context 'when using `ignore_tags` options' do
78
+ it 'works with a nil values' do
79
+ request = described_class.new(api, nil, nil, nil, ignore_tags: nil)
80
+ expect(request.options[:ignore_tags]).to be_nil
81
+ end
82
+
83
+ it 'works with a blank list' do
84
+ request = described_class.new(api, nil, nil, nil, ignore_tags: '')
85
+ expect(request.options[:ignore_tags]).to eq([])
86
+ end
87
+
88
+ it 'works with a comma-separated list and converts a string to an array' do
89
+ request = described_class.new(api, nil, nil, nil, ignore_tags: tags_str)
90
+ expect(request.options[:ignore_tags]).to eq(tags_array)
91
+ end
92
+
93
+ it 'works with an array and leaves it as it is' do
94
+ request = described_class.new(api, nil, nil, nil, ignore_tags: tags_array)
95
+ expect(request.options[:ignore_tags]).to eq(tags_array)
96
+ end
97
+ end
98
+
99
+ context 'when using `split_sentences` options' do
100
+ it 'converts `true` to `1`' do
101
+ request = described_class.new(api, nil, nil, nil, split_sentences: true)
102
+ expect(request.options[:split_sentences]).to eq('1')
103
+ end
104
+
105
+ it 'converts `false` to `0`' do
106
+ request = described_class.new(api, nil, nil, nil, split_sentences: false)
107
+ expect(request.options[:split_sentences]).to eq('0')
108
+ end
109
+
110
+ it 'leaves `0` as is' do
111
+ request = described_class.new(api, nil, nil, nil, split_sentences: '0')
112
+ expect(request.options[:split_sentences]).to eq('0')
113
+ end
114
+
115
+ it 'leaves `nonewlines` as is' do
116
+ request = described_class.new(api, nil, nil, nil, split_sentences: 'nonewlines')
117
+ expect(request.options[:split_sentences]).to eq('nonewlines')
118
+ end
119
+
120
+ it 'leaves `1` as is' do
121
+ request = described_class.new(api, nil, nil, nil, split_sentences: '1')
122
+ expect(request.options[:split_sentences]).to eq('1')
123
+ end
124
+
125
+ it 'works with provided constants' do
126
+ request = described_class.new(
127
+ api,
128
+ nil,
129
+ nil,
130
+ nil,
131
+ split_sentences: DeepL::Constants::SplitSentences::SPLIT_ON_PUNCTUATION_AND_NEWLINES
132
+ )
133
+ expect(request.options[:split_sentences]).to eq('1')
134
+ end
135
+ end
136
+
137
+ context 'when using `preserve_formatting` options' do
138
+ it 'leaves `true` as is' do
139
+ request = described_class.new(api, nil, nil, nil, preserve_formatting: true)
140
+ expect(request.options[:preserve_formatting]).to be(true)
141
+ end
142
+
143
+ it 'leaves `false` as is' do
144
+ request = described_class.new(api, nil, nil, nil, preserve_formatting: false)
145
+ expect(request.options[:preserve_formatting]).to be(false)
146
+ end
147
+
148
+ it 'converts `0` to `false`' do
149
+ request = described_class.new(api, nil, nil, nil, preserve_formatting: '0')
150
+ expect(request.options[:preserve_formatting]).to be(false)
151
+ end
152
+
153
+ it 'converts `1` to `true`' do
154
+ request = described_class.new(api, nil, nil, nil, preserve_formatting: '1')
155
+ expect(request.options[:preserve_formatting]).to be(true)
156
+ end
157
+ end
158
+
159
+ context 'when using `outline_detection` options' do
160
+ it 'leaves `true` as is' do
161
+ request = described_class.new(api, nil, nil, nil, outline_detection: true)
162
+ expect(request.options[:outline_detection]).to be(true)
163
+ end
164
+
165
+ it 'leaves `false` as is' do
166
+ request = described_class.new(api, nil, nil, nil, outline_detection: false)
167
+ expect(request.options[:outline_detection]).to be(false)
168
+ end
169
+
170
+ it 'converts `0` to `false`' do
171
+ request = described_class.new(api, nil, nil, nil, outline_detection: '0')
172
+ expect(request.options[:outline_detection]).to be(false)
173
+ end
174
+
175
+ it 'converts `1` to `true`' do
176
+ request = described_class.new(api, nil, nil, nil, outline_detection: '1')
177
+ expect(request.options[:outline_detection]).to be(true)
178
+ end
179
+ end
180
+
181
+ context 'when using `glossary_id` options' do
182
+ it 'works with a nil values' do
183
+ request = described_class.new(api, nil, nil, nil, glossary_id: nil)
184
+ expect(request.options[:glossary_id]).to be_nil
185
+ end
186
+
187
+ it 'works with a string' do
188
+ request = described_class.new(api, nil, nil, nil, glossary_id: 'sample_id')
189
+ expect(request.options[:glossary_id]).to eq('sample_id')
190
+ end
191
+ end
192
+
193
+ context 'when using `formality` options' do
194
+ it 'works with a nil values' do
195
+ request = described_class.new(api, nil, nil, nil, formality: nil)
196
+ expect(request.options[:formality]).to be_nil
197
+ end
198
+
199
+ it 'works with a string' do
200
+ request = described_class.new(api, nil, nil, nil, formality: 'more')
201
+ expect(request.options[:formality]).to eq('more')
202
+ end
203
+
204
+ it 'works with provided constants' do
205
+ request = described_class.new(api, nil, nil, nil,
206
+ formality: DeepL::Constants::Formality::MORE)
207
+ expect(request.options[:formality]).to eq('more')
208
+ end
209
+ end
210
+
211
+ context 'when using `tag_handling_version` options' do
212
+ it 'works with a nil value' do
213
+ request = described_class.new(api, nil, nil, nil, tag_handling_version: nil)
214
+ expect(request.options[:tag_handling_version]).to be_nil
215
+ end
216
+
217
+ it 'works with v1' do
218
+ request = described_class.new(api, nil, nil, nil, tag_handling_version: 'v1')
219
+ expect(request.options[:tag_handling_version]).to eq('v1')
220
+ end
221
+
222
+ it 'works with v2' do
223
+ request = described_class.new(api, nil, nil, nil, tag_handling_version: 'v2')
224
+ expect(request.options[:tag_handling_version]).to eq('v2')
225
+ end
226
+ end
227
+
228
+ context 'when using `model_type` options' do
229
+ it 'works with a nil value' do
230
+ request = described_class.new(api, nil, nil, nil, model_type: nil)
231
+ expect(request.options[:model_type]).to be_nil
232
+ end
233
+
234
+ it 'works with a string' do
235
+ request = described_class.new(api, nil, nil, nil, model_type: 'latency_optimized')
236
+ expect(request.options[:model_type]).to eq('latency_optimized')
237
+ end
238
+
239
+ it 'works with provided constants' do
240
+ request = described_class.new(api, nil, nil, nil,
241
+ model_type: DeepL::Constants::ModelType::LATENCY_OPTIMIZED)
242
+ expect(request.options[:model_type]).to eq('latency_optimized')
243
+ end
244
+ end
245
+
246
+ context 'when using `custom_instructions` options' do
247
+ it 'works with a nil value' do
248
+ request = described_class.new(api, nil, nil, nil, custom_instructions: nil)
249
+ expect(request.options[:custom_instructions]).to be_nil
250
+ end
251
+
252
+ it 'works with an array of strings' do
253
+ instructions = ['Use informal language', 'Be concise']
254
+ request = described_class.new(api, nil, nil, nil, custom_instructions: instructions)
255
+ expect(request.options[:custom_instructions]).to eq(instructions)
256
+ end
257
+
258
+ it 'works with a single string' do
259
+ request = described_class.new(api, nil, nil, nil, custom_instructions: ['Be concise'])
260
+ expect(request.options[:custom_instructions]).to eq(['Be concise'])
261
+ end
262
+
263
+ it 'works with a single string and converts it to an array' do
264
+ instructions = 'Use informal language,Be concise'
265
+ request = described_class.new(api, nil, nil, nil, custom_instructions: instructions)
266
+ expect(request.options[:custom_instructions]).to eq(['Use informal language', 'Be concise'])
267
+ end
268
+ end
269
+ end
270
+
271
+ describe '#request' do
272
+ around do |example|
273
+ VCR.use_cassette('translate_texts') { example.call }
274
+ end
275
+
276
+ context 'when performing a valid request with one text' do
277
+ it 'returns a text object' do
278
+ text = translate.request
279
+
280
+ expect(text).to be_a(DeepL::Resources::Text)
281
+ expect(text.text).to eq('Texto de muestra')
282
+ expect(text.detected_source_language).to eq('EN')
283
+ end
284
+ end
285
+
286
+ context 'when performing a valid request with multiple texts' do
287
+ let(:text) { %w[Sample Word] }
288
+
289
+ it 'returns a text object' do
290
+ texts = translate.request
291
+
292
+ expect(texts).to be_a(Array)
293
+ expect(texts.first.text).to eq('Muestra')
294
+ expect(texts.first.detected_source_language).to eq('EN')
295
+
296
+ expect(texts.last.text).to eq('Palabra')
297
+ expect(texts.last.detected_source_language).to eq('EN')
298
+ end
299
+ end
300
+
301
+ context 'when performing a valid request with tag handling' do
302
+ let(:text) { '<p>Sample text</p>' }
303
+ let(:options) { { tag_handling: 'xml' } }
304
+
305
+ it 'returns a text object' do
306
+ text = translate.request
307
+
308
+ expect(text).to be_a(DeepL::Resources::Text)
309
+ expect(text.text).to eq('<p>Texto de muestra</p>')
310
+ expect(text.detected_source_language).to eq('EN')
311
+ end
312
+ end
313
+
314
+ context 'when performing a valid request and passing a variable' do
315
+ let(:text) { 'Welcome and <code>Hello great World</code> Good Morning!' }
316
+ let(:options) { { tag_handling: 'xml', ignore_tags: %w[code span] } }
317
+
318
+ it 'returns a text object' do
319
+ text = translate.request
320
+
321
+ expect(text).to be_a(DeepL::Resources::Text)
322
+ expect(text.text).to eq('Bienvenido y <code>Hello great World</code> ¡Buenos días!')
323
+ expect(text.detected_source_language).to eq('EN')
324
+ end
325
+ end
326
+
327
+ context 'when performing a valid request with an HTML document' do
328
+ let(:text) do
329
+ <<~XML
330
+ <document>
331
+ <meta>
332
+ <title>A document's title</title>
333
+ </meta>
334
+ <content>
335
+ <par>This is the first sentence. Followed by a second one.</par>
336
+ <par>This is the third sentence.</par>
337
+ </content>
338
+ </document>
339
+ XML
340
+ end
341
+ let(:options) do
342
+ {
343
+ tag_handling: 'xml',
344
+ split_sentences: 'nonewlines',
345
+ outline_detection: false,
346
+ splitting_tags: %w[title par]
347
+ }
348
+ end
349
+
350
+ it 'returns a text object' do
351
+ text = translate.request
352
+
353
+ expect(text).to be_a(DeepL::Resources::Text)
354
+ expect(text.text).to eq(
355
+ <<~XML
356
+ <document>
357
+ <meta>
358
+ <title>Título de un documento</title>
359
+ </meta>
360
+ <content>
361
+ <par>Es la primera frase. Seguido de una segunda.</par>
362
+ <par>Esta es la tercera frase.</par>
363
+ </content>
364
+ </document>
365
+ XML
366
+ )
367
+ expect(text.detected_source_language).to eq('EN')
368
+ end
369
+ end
370
+
371
+ context 'when performing a valid request with context' do
372
+ let(:text) { 'That is hot!' }
373
+
374
+ context 'when context is empty' do
375
+ let(:options) { { context: '' } }
376
+
377
+ it 'translates correctly with empty context' do
378
+ res = translate.request
379
+ expect(res).to be_a(DeepL::Resources::Text)
380
+ expect(res.text).to eq('¡Eso está caliente!')
381
+ end
382
+ end
383
+
384
+ context 'when context is set' do
385
+ let(:options) { { context: 'He did not like the jalapenos in his meal.' } }
386
+
387
+ it 'translates correctly with context taken into account' do
388
+ res = translate.request
389
+ expect(res).to be_a(DeepL::Resources::Text)
390
+ expect(res.text).to eq('¡Eso es picante!')
391
+ end
392
+ end
393
+ end
394
+
395
+ context 'when performing a request with a model type' do
396
+ let(:target_lang) { 'DE' }
397
+
398
+ %w[quality_optimized latency_optimized prefer_quality_optimized].each do |model_type_str|
399
+ it "translates correctly with #{model_type_str} models" do
400
+ options = { model_type: model_type_str }
401
+ translate = described_class.new(api, text, source_lang, target_lang, options)
402
+ res = translate.request
403
+ expect(res).to be_a(DeepL::Resources::Text)
404
+ expected_model_type = model_type_str.sub(/^prefer_/, '')
405
+ expect(res.model_type_used).to eq(expected_model_type)
406
+ end
407
+ end
408
+ end
409
+
410
+ context 'when performing a request with extra_body_parameters' do
411
+ it 'allows extra parameters to override standard parameters' do
412
+ extra_options = { extra_body_parameters: { target_lang: 'FR', debug: '1' } }
413
+ translate = described_class.new(api, text, source_lang, target_lang, extra_options)
414
+ res = translate.request
415
+
416
+ expect(res).to be_a(DeepL::Resources::Text)
417
+ expect(res.text).to eq('Texte modèle')
418
+ expect(res.detected_source_language).to eq('EN')
419
+ end
420
+ end
421
+
422
+ context 'when performing a request with custom_instructions' do
423
+ let(:text) { 'Hello world' }
424
+ let(:target_lang) { 'DE' }
425
+
426
+ it 'includes custom_instructions in the payload' do
427
+ options = { custom_instructions: ['Use formal language', 'Be concise'] }
428
+ translate = described_class.new(api, text, source_lang, target_lang, options)
429
+
430
+ # Verify the options are properly stored
431
+ expect(translate.options[:custom_instructions]).to eq(['Use formal language', 'Be concise'])
432
+ end
433
+ end
434
+
435
+ context 'when performing a request with tag_handling_version' do
436
+ let(:text) { '<p>Hello world</p>' }
437
+ let(:target_lang) { 'DE' }
438
+
439
+ %w[v1 v2].each do |version|
440
+ it "translates correctly with tag_handling_version #{version}" do
441
+ options = { tag_handling: 'html', tag_handling_version: version }
442
+ translate = described_class.new(api, text, source_lang, target_lang, options)
443
+ res = translate.request
444
+
445
+ expect(res).to be_a(DeepL::Resources::Text)
446
+ expect(res.text).not_to be_nil
447
+ expect(res.text).not_to be_empty
448
+ end
449
+ end
450
+ end
451
+
452
+ context 'when performing a bad request' do
453
+ context 'when using an invalid token' do
454
+ let(:api) do
455
+ api = build_deepl_api
456
+ api.configuration.auth_key = 'invalid'
457
+ api
458
+ end
459
+
460
+ it 'raises an unauthorized error' do
461
+ expect { translate.request }.to raise_error(DeepL::Exceptions::AuthorizationFailed)
462
+ end
463
+ end
464
+
465
+ context 'when using an invalid text' do
466
+ let(:text) { nil }
467
+
468
+ it 'raises a bad request error' do
469
+ message = "Invalid request: Expected 'text' parameter to be an array of strings"
470
+ expect { translate.request }.to raise_error(DeepL::Exceptions::BadRequest, message)
471
+ end
472
+ end
473
+
474
+ context 'when using an invalid target language' do
475
+ let(:target_lang) { nil }
476
+
477
+ it 'raises a bad request error' do
478
+ message = "Value for 'target_lang' not supported."
479
+ expect { translate.request }.to raise_error(DeepL::Exceptions::BadRequest, message)
480
+ end
481
+ end
482
+ end
483
+
484
+ context 'when performing a request with too many texts' do
485
+ let(:text) { Array.new(10_000) { |i| "This is the sentence number #{i}" } }
486
+
487
+ it 'raises a request entity too large error' do
488
+ expect { translate.request }.to raise_error(DeepL::Exceptions::RequestEntityTooLarge,
489
+ /request size has reached the supported limit/)
490
+ end
491
+ end
492
+ end
493
+ end
@@ -0,0 +1,43 @@
1
+ # Copyright 2018 Daniel Herzog
2
+ # Use of this source code is governed by an MIT
3
+ # license that can be found in the LICENSE.md file.
4
+ # frozen_string_literal: true
5
+
6
+ require 'spec_helper'
7
+
8
+ describe DeepL::Requests::Usage do
9
+ subject(:usage_req) { described_class.new(api, options) }
10
+
11
+ around do |tests|
12
+ tmp_env = replace_env_preserving_deepl_vars_except_mock_server
13
+ tests.call
14
+ ENV.replace(tmp_env)
15
+ end
16
+
17
+ let(:api) { build_deepl_api }
18
+ let(:options) { {} }
19
+
20
+ describe '#initialize' do
21
+ context 'when building a request' do
22
+ it 'creates a request object' do
23
+ expect(usage_req).to be_a(described_class)
24
+ end
25
+ end
26
+ end
27
+
28
+ describe '#request' do
29
+ around do |example|
30
+ VCR.use_cassette('usage') { example.call }
31
+ end
32
+
33
+ context 'when performing a valid request' do
34
+ it 'returns an usage object' do
35
+ usage = usage_req.request
36
+
37
+ expect(usage).to be_a(DeepL::Resources::Usage)
38
+ expect(usage.character_count).to be_a(Numeric)
39
+ expect(usage.character_limit).to be_a(Numeric)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,38 @@
1
+ # Copyright 2022 Daniel Herzog
2
+ # Use of this source code is governed by an MIT
3
+ # license that can be found in the LICENSE.md file.
4
+ # frozen_string_literal: true
5
+
6
+ require 'spec_helper'
7
+
8
+ describe DeepL::Resources::Glossary do
9
+ subject(:glossary) do
10
+ described_class.new({
11
+ 'glossary_id' => 'def3a26b-3e84-45b3-84ae-0c0aaf3525f7',
12
+ 'name' => 'Mein Glossar',
13
+ 'ready' => true,
14
+ 'source_lang' => 'EN',
15
+ 'target_lang' => 'DE',
16
+ 'creation_time' => '2021-08-03T14:16:18.329Z',
17
+ 'entry_count' => 1
18
+ }, nil, nil)
19
+ end
20
+
21
+ describe '#initialize' do
22
+ context 'when building a basic object' do
23
+ it 'creates a resource' do
24
+ expect(glossary).to be_a(described_class)
25
+ end
26
+
27
+ it 'assigns the attributes' do
28
+ expect(glossary.id).to eq('def3a26b-3e84-45b3-84ae-0c0aaf3525f7')
29
+ expect(glossary.name).to eq('Mein Glossar')
30
+ expect(glossary.ready).to be(true)
31
+ expect(glossary.source_lang).to eq('EN')
32
+ expect(glossary.target_lang).to eq('DE')
33
+ expect(glossary.creation_time).to eq('2021-08-03T14:16:18.329Z')
34
+ expect(glossary.entry_count).to eq(1)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,23 @@
1
+ # Copyright 2022 Daniel Herzog
2
+ # Use of this source code is governed by an MIT
3
+ # license that can be found in the LICENSE.md file.
4
+ # frozen_string_literal: true
5
+
6
+ require 'spec_helper'
7
+
8
+ describe DeepL::Resources::LanguagePair do
9
+ subject(:language_pair) { described_class.new('en', 'de', nil, nil) }
10
+
11
+ describe '#initialize' do
12
+ context 'when building a basic object' do
13
+ it 'creates a resource' do
14
+ expect(language_pair).to be_a(described_class)
15
+ end
16
+
17
+ it 'assigns the attributes' do
18
+ expect(language_pair.source_lang).to eq('en')
19
+ expect(language_pair.target_lang).to eq('de')
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,45 @@
1
+ # Copyright 2021 Daniel Herzog
2
+ # Use of this source code is governed by an MIT
3
+ # license that can be found in the LICENSE.md file.
4
+ # frozen_string_literal: true
5
+
6
+ require 'spec_helper'
7
+
8
+ describe DeepL::Resources::Language do
9
+ subject(:language) { described_class.new('EN', 'English', nil, nil, nil) }
10
+
11
+ describe '#initialize' do
12
+ context 'when building a basic object' do
13
+ it 'creates a resource' do
14
+ expect(language).to be_a(described_class)
15
+ end
16
+
17
+ it 'assigns the attributes' do
18
+ expect(language.code).to eq('EN')
19
+ expect(language.name).to eq('English')
20
+ end
21
+
22
+ it 'does not define the supports formality method' do
23
+ expect { language.supports_formality? }.to raise_error(DeepL::Exceptions::NotSupported)
24
+ end
25
+ end
26
+
27
+ context 'when building a target language object' do
28
+ subject(:language) { described_class.new('EN', 'English', true, nil, nil) }
29
+
30
+ it 'creates a resource' do
31
+ expect(language).to be_a(described_class)
32
+ end
33
+
34
+ it 'assigns the attributes' do
35
+ expect(language.code).to eq('EN')
36
+ expect(language.name).to eq('English')
37
+ end
38
+
39
+ it 'includes the supports formality method' do
40
+ expect { language.supports_formality? }.not_to raise_error
41
+ expect(language).to be_supports_formality
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,23 @@
1
+ # Copyright 2018 Daniel Herzog
2
+ # Use of this source code is governed by an MIT
3
+ # license that can be found in the LICENSE.md file.
4
+ # frozen_string_literal: true
5
+
6
+ require 'spec_helper'
7
+
8
+ describe DeepL::Resources::Text do
9
+ subject(:text) { described_class.new('Target', 'es', nil, nil, nil) }
10
+
11
+ describe '#initialize' do
12
+ context 'when building a basic object' do
13
+ it 'creates a resource' do
14
+ expect(text).to be_a(described_class)
15
+ end
16
+
17
+ it 'assigns the attributes' do
18
+ expect(text.text).to eq('Target')
19
+ expect(text.detected_source_language).to eq('es')
20
+ end
21
+ end
22
+ end
23
+ end