deepl-rb 3.6.1 → 3.8.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 (89) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab-ci.yml +8 -1
  3. data/CHANGELOG.md +35 -1
  4. data/Gemfile +0 -2
  5. data/README.md +165 -34
  6. data/Rakefile +2 -0
  7. data/VERSION +1 -1
  8. data/deepl-rb.gemspec +52 -20
  9. data/lib/deepl/requests/base.rb +16 -0
  10. data/lib/deepl/requests/document/upload.rb +6 -5
  11. data/lib/deepl/requests/rephrase.rb +3 -2
  12. data/lib/deepl/requests/style_rule/create.rb +46 -0
  13. data/lib/deepl/requests/style_rule/create_custom_instruction.rb +45 -0
  14. data/lib/deepl/requests/style_rule/destroy.rb +39 -0
  15. data/lib/deepl/requests/style_rule/destroy_custom_instruction.rb +40 -0
  16. data/lib/deepl/requests/style_rule/find.rb +40 -0
  17. data/lib/deepl/requests/style_rule/find_custom_instruction.rb +41 -0
  18. data/lib/deepl/requests/style_rule/update.rb +42 -0
  19. data/lib/deepl/requests/style_rule/update_configured_rules.rb +41 -0
  20. data/lib/deepl/requests/style_rule/update_custom_instruction.rb +47 -0
  21. data/lib/deepl/requests/translate.rb +17 -4
  22. data/lib/deepl/requests/translation_memory/list.rb +58 -0
  23. data/lib/deepl/resources/style_rule.rb +2 -1
  24. data/lib/deepl/resources/translation_memory.rb +25 -0
  25. data/lib/deepl/style_rule_api.rb +44 -0
  26. data/lib/deepl/translation_memory_api.rb +17 -0
  27. data/lib/deepl.rb +75 -55
  28. data/lib/version.rb +1 -1
  29. data/spec/api/deepl_spec.rb +134 -332
  30. data/spec/integration_tests/document_api_spec.rb +4 -18
  31. data/spec/integration_tests/document_error_paths_spec.rb +33 -0
  32. data/spec/integration_tests/glossary_api_spec.rb +114 -0
  33. data/spec/integration_tests/glossary_error_paths_spec.rb +107 -0
  34. data/spec/integration_tests/languages_api_spec.rb +54 -0
  35. data/spec/integration_tests/languages_error_paths_spec.rb +25 -0
  36. data/spec/integration_tests/rephrase_api_spec.rb +90 -0
  37. data/spec/integration_tests/rephrase_error_paths_spec.rb +53 -0
  38. data/spec/integration_tests/smoke_test_spec.rb +24 -0
  39. data/spec/integration_tests/style_rule_api_spec.rb +55 -17
  40. data/spec/integration_tests/style_rule_error_paths_spec.rb +45 -0
  41. data/spec/integration_tests/translate_api_spec.rb +98 -0
  42. data/spec/integration_tests/translate_error_paths_spec.rb +48 -0
  43. data/spec/integration_tests/translation_memory_api_spec.rb +54 -0
  44. data/spec/integration_tests/translation_memory_error_paths_spec.rb +19 -0
  45. data/spec/integration_tests/usage_api_spec.rb +29 -0
  46. data/spec/integration_tests/usage_error_paths_spec.rb +18 -0
  47. data/spec/requests/glossary/create_spec.rb +0 -21
  48. data/spec/requests/glossary/destroy_spec.rb +0 -39
  49. data/spec/requests/glossary/entries_spec.rb +0 -35
  50. data/spec/requests/glossary/find_spec.rb +0 -40
  51. data/spec/requests/glossary/language_pairs_spec.rb +0 -13
  52. data/spec/requests/glossary/list_spec.rb +0 -27
  53. data/spec/requests/languages_spec.rb +0 -41
  54. data/spec/requests/rephrase_spec.rb +13 -139
  55. data/spec/requests/style_rule/create_custom_instruction_spec.rb +30 -0
  56. data/spec/requests/style_rule/create_spec.rb +29 -0
  57. data/spec/requests/style_rule/destroy_custom_instruction_spec.rb +28 -0
  58. data/spec/requests/style_rule/destroy_spec.rb +27 -0
  59. data/spec/requests/style_rule/find_custom_instruction_spec.rb +29 -0
  60. data/spec/requests/style_rule/find_spec.rb +28 -0
  61. data/spec/requests/style_rule/list_spec.rb +27 -0
  62. data/spec/requests/style_rule/update_configured_rules_spec.rb +31 -0
  63. data/spec/requests/style_rule/update_custom_instruction_spec.rb +32 -0
  64. data/spec/requests/style_rule/update_spec.rb +29 -0
  65. data/spec/requests/translate_spec.rb +8 -218
  66. data/spec/requests/translation_memory/list_spec.rb +27 -0
  67. data/spec/requests/usage_spec.rb +0 -16
  68. data/spec/resources/custom_instruction_spec.rb +32 -0
  69. data/spec/resources/style_rule_spec.rb +68 -0
  70. data/spec/resources/translation_memory_spec.rb +35 -0
  71. data/spec/spec_helper.rb +15 -45
  72. data/spec/support/live_mock_server.rb +12 -0
  73. data/spec/support/managed_glossary.rb +17 -0
  74. data/spec/support/managed_style_rule.rb +17 -0
  75. data/spec/support/managed_translation_memory.rb +7 -0
  76. metadata +48 -19
  77. data/spec/fixtures/vcr_cassettes/deepl_document.yml +0 -95
  78. data/spec/fixtures/vcr_cassettes/deepl_document_download.yml +0 -1214
  79. data/spec/fixtures/vcr_cassettes/deepl_glossaries.yml +0 -1163
  80. data/spec/fixtures/vcr_cassettes/deepl_languages.yml +0 -54
  81. data/spec/fixtures/vcr_cassettes/deepl_rephrase.yml +0 -87
  82. data/spec/fixtures/vcr_cassettes/deepl_translate.yml +0 -358
  83. data/spec/fixtures/vcr_cassettes/deepl_usage.yml +0 -129
  84. data/spec/fixtures/vcr_cassettes/glossaries.yml +0 -1702
  85. data/spec/fixtures/vcr_cassettes/languages.yml +0 -229
  86. data/spec/fixtures/vcr_cassettes/rephrase_texts.yml +0 -401
  87. data/spec/fixtures/vcr_cassettes/style_rules.yml +0 -92
  88. data/spec/fixtures/vcr_cassettes/translate_texts.yml +0 -10630
  89. data/spec/fixtures/vcr_cassettes/usage.yml +0 -171
data/lib/version.rb CHANGED
@@ -4,5 +4,5 @@
4
4
  # frozen_string_literal: true
5
5
 
6
6
  module DeepL
7
- VERSION = '3.6.1'
7
+ VERSION = '3.8.0'
8
8
  end
@@ -4,9 +4,9 @@
4
4
  # frozen_string_literal: true
5
5
 
6
6
  require 'spec_helper'
7
- require 'tempfile'
8
7
 
9
- describe DeepL do
8
+ # rubocop:disable RSpec/StubbedMock
9
+ describe DeepL do # rubocop:disable RSpec/SpecFilePathFormat
10
10
  subject(:deepl) { described_class.dup }
11
11
 
12
12
  around do |tests|
@@ -56,405 +56,207 @@ describe DeepL do
56
56
  end
57
57
 
58
58
  describe '#translate' do
59
- let(:input) { 'Sample' }
60
- let(:source_lang) { 'EN' }
61
- let(:target_lang) { 'ES' }
62
- let(:options) { { param: 'fake' } }
63
-
64
- around do |example|
65
- deepl.configure
66
- VCR.use_cassette('deepl_translate') { example.call }
67
- end
68
-
69
- context 'when translating a text' do
70
- it 'creates and call a request object' do
71
- expect(DeepL::Requests::Translate).to receive(:new)
72
- .with(deepl.api, input, source_lang, target_lang, options).and_call_original
73
-
74
- text = deepl.translate(input, source_lang, target_lang, options)
75
- expect(text).to be_a(DeepL::Resources::Text)
76
- end
77
- end
78
-
79
- context 'when translating a text using a glossary' do
80
- before do
81
- @glossary = deepl.glossaries.create('fixture', 'EN', 'ES', [%w[car auto]])
82
- end
83
-
84
- let(:input) { 'I wish we had a car.' }
85
- # rubocop:disable RSpec/InstanceVariable
86
- let(:options) { { glossary_id: @glossary.id } }
59
+ let(:request) { instance_double(DeepL::Requests::Translate, request: 'result') }
87
60
 
88
- after do
89
- deepl.glossaries.destroy(@glossary.id)
90
- end
91
- # rubocop:enable RSpec/InstanceVariable
92
-
93
- it 'creates and call a request object' do
94
- expect(DeepL::Requests::Translate).to receive(:new)
95
- .with(deepl.api, input, source_lang, target_lang, options).and_call_original
96
- text = deepl.translate(input, source_lang, target_lang, options)
97
- expect(text).to be_a(DeepL::Resources::Text)
98
- expect(text.text).to eq('Ojalá tuviéramos auto.')
99
- end
100
- end
101
- end
61
+ before { deepl.configure }
102
62
 
103
- describe '#usage' do
104
- let(:options) { {} }
63
+ it 'delegates to DeepL::Requests::Translate with the given arguments' do
64
+ options = { formality: 'more' }
65
+ additional_headers = { 'X-DeepL-Reporting-Tag' => 'tag' }
66
+ expect(DeepL::Requests::Translate).to receive(:new)
67
+ .with(deepl.api, 'Sample', 'EN', 'ES', options, additional_headers)
68
+ .and_return(request)
105
69
 
106
- around do |example|
107
- deepl.configure
108
- VCR.use_cassette('deepl_usage') { example.call }
70
+ expect(deepl.translate('Sample', 'EN', 'ES', options, additional_headers)).to eq('result')
109
71
  end
110
72
 
111
- context 'when checking usage' do
112
- it 'creates and call a request object' do
113
- expect(DeepL::Requests::Usage).to receive(:new)
114
- .with(deepl.api, options).and_call_original
73
+ it 'defaults options and additional_headers to empty hashes' do
74
+ expect(DeepL::Requests::Translate).to receive(:new)
75
+ .with(deepl.api, 'Sample', 'EN', 'ES', {}, {})
76
+ .and_return(request)
115
77
 
116
- usage = deepl.usage(options)
117
- expect(usage).to be_a(DeepL::Resources::Usage)
118
- end
78
+ deepl.translate('Sample', 'EN', 'ES')
119
79
  end
120
80
  end
121
81
 
122
- # rubocop:disable RSpec/InstanceVariable
123
- describe '#document' do
124
- describe '#document.upload' do
125
- before do
126
- @tmpfile = Tempfile.new('foo')
127
- @tmpfile.write("Geology for Beginners Report
128
- A test report for the DeepL API
129
- It is with great pleasure, that I, Urna Semper, write this fake document on geology.
130
- Geology is an excellent field that deals with how to extract oil from the earth.")
131
- @tmpfile.close
132
- end
133
-
134
- after do
135
- @tmpfile.unlink
136
- end
82
+ describe '#rephrase' do
83
+ let(:request) { instance_double(DeepL::Requests::Rephrase, request: 'result') }
137
84
 
138
- let(:input_file) { @tmpfile.path }
139
- let(:source_lang) { 'EN' }
140
- let(:target_lang) { 'ES' }
141
- let(:output_file) { 'test_translated_doc.txt' }
142
- let(:options) { { param: 'fake' } }
143
- let(:additional_headers) { { 'Fake-Header': 'fake_value' } }
85
+ before { deepl.configure }
144
86
 
145
- around do |example|
146
- deepl.configure
147
- VCR.use_cassette('deepl_document') { example.call }
148
- end
87
+ it 'delegates to DeepL::Requests::Rephrase with the given arguments' do
88
+ options = { foo: 'bar' }
89
+ additional_headers = { 'X-DeepL-Reporting-Tag' => 'tag' }
90
+ expect(DeepL::Requests::Rephrase).to receive(:new)
91
+ .with(deepl.api, 'Sample', 'DE', 'business', 'friendly', options, additional_headers)
92
+ .and_return(request)
149
93
 
150
- context 'when uploading a document' do
151
- it 'creates an upload object' do
152
- expect(DeepL::Requests::Document::Upload).to receive(:new)
153
- .with(deepl.api, input_file, source_lang, target_lang,
154
- "#{File.basename(@tmpfile.path)}.txt", options,
155
- additional_headers).and_call_original
156
- doc_handle = deepl.document.upload(input_file, source_lang, target_lang,
157
- "#{File.basename(@tmpfile.path)}.txt", options,
158
- additional_headers)
159
- expect(doc_handle).to be_a(DeepL::Resources::DocumentHandle)
160
- end
161
- end
94
+ result = deepl.rephrase('Sample', 'DE', 'business', 'friendly', options, additional_headers)
95
+ expect(result).to eq('result')
162
96
  end
163
- # rubocop:enable RSpec/InstanceVariable
164
-
165
- describe '#document.get_status' do
166
- let(:document_handle) do
167
- DeepL::Resources::DocumentHandle.new('9B7CB9418DCDEBF2C4C519F65A32B99F',
168
- 'EA637EA43BB3F8A52A2A25B76EF3E0C72CE9CD00C881148D1236CB584CB34815', # rubocop:disable Layout/LineLength
169
- nil,
170
- nil)
171
- end
172
- let(:options) { { param: 'fake' } }
173
- let(:additional_headers) { { 'Fake-Header': 'fake_value' } }
174
97
 
175
- around do |example|
176
- deepl.configure
177
- VCR.use_cassette('deepl_document') { example.call }
178
- end
98
+ it 'defaults the optional arguments' do
99
+ expect(DeepL::Requests::Rephrase).to receive(:new)
100
+ .with(deepl.api, 'Sample', nil, nil, nil, {}, {})
101
+ .and_return(request)
179
102
 
180
- context 'when querying the status of a document' do
181
- it 'creates a GetStatus object' do
182
- expect(DeepL::Requests::Document::GetStatus).to receive(:new)
183
- .with(
184
- deepl.api,
185
- document_handle.document_id,
186
- document_handle.document_key,
187
- options,
188
- additional_headers
189
- ).and_call_original
190
- status = deepl.document.get_status(document_handle, options, additional_headers)
191
- expect(status).to be_a(DeepL::Resources::DocumentTranslationStatus)
192
- end
193
- end
103
+ deepl.rephrase('Sample')
194
104
  end
105
+ end
195
106
 
196
- # rubocop:disable RSpec/InstanceVariable
197
- describe '#document.download' do
198
- before do
199
- @tmpfile = Tempfile.new('bar')
200
- end
107
+ describe '#usage' do
108
+ let(:request) { instance_double(DeepL::Requests::Usage, request: 'result') }
201
109
 
202
- after do
203
- @tmpfile.close
204
- @tmpfile.unlink
205
- end
110
+ before { deepl.configure }
206
111
 
207
- let(:document_handle) do
208
- DeepL::Resources::DocumentHandle.new('9B7CB9418DCDEBF2C4C519F65A32B99F',
209
- 'EA637EA43BB3F8A52A2A25B76EF3E0C72CE9CD00C881148D1236CB584CB34815', # rubocop:disable Layout/LineLength
210
- nil,
211
- nil)
212
- end
213
- let(:output_file_path) { @tmpfile.path }
214
- let(:options) { { param: 'fake' } }
112
+ it 'delegates to DeepL::Requests::Usage with the given options' do
113
+ options = { foo: 'bar' }
114
+ expect(DeepL::Requests::Usage).to receive(:new).with(deepl.api, options).and_return(request)
215
115
 
216
- around do |example|
217
- deepl.configure
218
- VCR.use_cassette('deepl_document_download', preserve_exact_body_bytes: true) do
219
- example.call
220
- end
221
- end
116
+ expect(deepl.usage(options)).to eq('result')
117
+ end
222
118
 
223
- context 'when downloading a document' do
224
- it 'creates an downloading object and writes to the output file' do # rubocop:disable RSpec/ExampleLength
225
- expect(DeepL::Requests::Document::Download).to receive(:new)
226
- .with(
227
- deepl.api,
228
- document_handle.document_id,
229
- document_handle.document_key,
230
- output_file_path
231
- ).and_call_original
232
- deepl.document.download(document_handle, output_file_path)
233
- file_contents = File.read(output_file_path)
234
- expect(file_contents).to be_a(String)
235
- expect(file_contents.length).to be > 200
236
- end
237
- end
119
+ it 'defaults options to an empty hash' do
120
+ expect(DeepL::Requests::Usage).to receive(:new).with(deepl.api, {}).and_return(request)
121
+
122
+ deepl.usage
238
123
  end
239
124
  end
240
- # rubocop:enable RSpec/InstanceVariable
241
125
 
242
126
  describe '#languages' do
243
- let(:options) { { type: :target } }
127
+ let(:request) { instance_double(DeepL::Requests::Languages, request: 'result') }
128
+
129
+ before { deepl.configure }
130
+
131
+ it 'delegates to DeepL::Requests::Languages with the given options' do
132
+ options = { type: :target }
133
+ expect(DeepL::Requests::Languages).to receive(:new).with(deepl.api, options)
134
+ .and_return(request)
244
135
 
245
- around do |example|
246
- deepl.configure
247
- VCR.use_cassette('deepl_languages') { example.call }
136
+ expect(deepl.languages(options)).to eq('result')
248
137
  end
249
138
 
250
- context 'when checking languages' do
251
- it 'creates and call a request object' do
252
- expect(DeepL::Requests::Languages).to receive(:new)
253
- .with(deepl.api, options).and_call_original
139
+ it 'defaults options to an empty hash' do
140
+ expect(DeepL::Requests::Languages).to receive(:new).with(deepl.api, {}).and_return(request)
254
141
 
255
- languages = deepl.languages(options)
256
- expect(languages).to be_an(Array)
257
- expect(languages).to(be_all { |l| l.is_a?(DeepL::Resources::Language) })
258
- end
142
+ deepl.languages
259
143
  end
260
144
  end
261
145
 
262
146
  describe '#glossaries' do
263
- describe '#glossaries.create' do
264
- let(:name) { 'Mi Glosario' }
265
- let(:source_lang) { 'EN' }
266
- let(:target_lang) { 'ES' }
267
- let(:entries) do
268
- [
269
- %w[Hello Hola],
270
- %w[World Mundo]
271
- ]
272
- end
273
- let(:options) { { param: 'fake', entries_format: 'tsv' } }
147
+ before { deepl.configure }
274
148
 
275
- around do |example|
276
- deepl.configure
277
- VCR.use_cassette('deepl_glossaries') { example.call }
278
- end
279
-
280
- context 'when creating a glossary' do
281
- it 'creates and call a request object' do
282
- expect(DeepL::Requests::Glossary::Create).to receive(:new)
283
- .with(deepl.api, name, source_lang, target_lang, entries, options).and_call_original
284
-
285
- glossary = deepl.glossaries.create(name, source_lang, target_lang, entries, options)
286
- expect(glossary).to be_a(DeepL::Resources::Glossary)
287
- end
288
- end
149
+ it 'returns a GlossaryApi instance built with the configured api' do
150
+ expect(deepl.glossaries).to be_a(DeepL::GlossaryApi)
289
151
  end
290
152
 
291
- describe '#glossaries.find' do
292
- let(:id) { 'e7a62637-7ef4-4959-a355-09ba61dd0126' }
293
- let(:options) { {} }
294
-
295
- around do |example|
296
- deepl.configure
297
- VCR.use_cassette('deepl_glossaries') { example.call }
298
- end
299
-
300
- context 'when fetching a glossary' do
301
- it 'creates and call a request object' do
302
- expect(DeepL::Requests::Glossary::Find).to receive(:new)
303
- .with(deepl.api, id, options).and_call_original
304
-
305
- glossary = deepl.glossaries.find(id, options)
306
- expect(glossary).to be_a(DeepL::Resources::Glossary)
307
- end
308
- end
309
-
310
- context 'when fetching a non existing glossary' do
311
- let(:id) { '00000000-0000-0000-0000-000000000000' }
153
+ describe 'GlossaryApi#create' do
154
+ it 'delegates to DeepL::Requests::Glossary::Create' do
155
+ request = instance_double(DeepL::Requests::Glossary::Create, request: 'result')
156
+ entries = [%w[Hello Hola]]
157
+ expect(DeepL::Requests::Glossary::Create).to receive(:new)
158
+ .with(deepl.api, 'Mi Glosario', 'EN', 'ES', entries, {})
159
+ .and_return(request)
312
160
 
313
- it 'raises an exception when the glossary does not exist' do
314
- expect(DeepL::Requests::Glossary::Find).to receive(:new)
315
- .with(deepl.api, id, options).and_call_original
316
- expect { deepl.glossaries.find(id, options) }
317
- .to raise_error(DeepL::Exceptions::NotFound)
318
- end
161
+ deepl.glossaries.create('Mi Glosario', 'EN', 'ES', entries)
319
162
  end
320
163
  end
321
164
 
322
- describe '#glossaries.list' do
323
- let(:options) { {} }
324
-
325
- around do |example|
326
- deepl.configure
327
- VCR.use_cassette('deepl_glossaries') { example.call }
328
- end
329
-
330
- context 'when fetching glossaries' do
331
- it 'creates and call a request object' do
332
- expect(DeepL::Requests::Glossary::List).to receive(:new)
333
- .with(deepl.api, options).and_call_original
165
+ describe 'GlossaryApi#find' do
166
+ it 'delegates to DeepL::Requests::Glossary::Find' do
167
+ request = instance_double(DeepL::Requests::Glossary::Find, request: 'result')
168
+ expect(DeepL::Requests::Glossary::Find).to receive(:new)
169
+ .with(deepl.api, 'glossary-id', {})
170
+ .and_return(request)
334
171
 
335
- glossaries = deepl.glossaries.list(options)
336
- expect(glossaries).to all(be_a(DeepL::Resources::Glossary))
337
- end
172
+ deepl.glossaries.find('glossary-id')
338
173
  end
339
174
  end
340
175
 
341
- describe '#glossaries.destroy' do
342
- let(:id) { 'e7a62637-7ef4-4959-a355-09ba61dd0126' }
343
- let(:options) { {} }
176
+ describe 'GlossaryApi#list' do
177
+ it 'delegates to DeepL::Requests::Glossary::List' do
178
+ request = instance_double(DeepL::Requests::Glossary::List, request: 'result')
179
+ expect(DeepL::Requests::Glossary::List).to receive(:new).with(deepl.api, {})
180
+ .and_return(request)
344
181
 
345
- around do |example|
346
- deepl.configure
347
- VCR.use_cassette('deepl_glossaries') { example.call }
348
- end
349
-
350
- context 'when destroy a glossary' do
351
- let(:new_glossary) do
352
- deepl.glossaries.create('fixture', 'EN', 'ES', [%w[Hello Hola]])
353
- end
354
-
355
- it 'creates and call a request object' do
356
- expect(DeepL::Requests::Glossary::Destroy).to receive(:new)
357
- .with(deepl.api, new_glossary.id, options).and_call_original
358
-
359
- glossary_id = deepl.glossaries.destroy(new_glossary.id, options)
360
- expect(glossary_id).to eq(new_glossary.id)
361
- end
182
+ deepl.glossaries.list
362
183
  end
184
+ end
363
185
 
364
- context 'when destroying a non existing glossary' do
365
- let(:id) { '00000000-0000-0000-0000-000000000000' }
186
+ describe 'GlossaryApi#destroy' do
187
+ it 'delegates to DeepL::Requests::Glossary::Destroy' do
188
+ request = instance_double(DeepL::Requests::Glossary::Destroy, request: 'result')
189
+ expect(DeepL::Requests::Glossary::Destroy).to receive(:new)
190
+ .with(deepl.api, 'glossary-id', {})
191
+ .and_return(request)
366
192
 
367
- it 'raises an exception when the glossary does not exist' do
368
- expect(DeepL::Requests::Glossary::Destroy).to receive(:new)
369
- .with(deepl.api, id, options).and_call_original
370
- expect { deepl.glossaries.destroy(id, options) }
371
- .to raise_error(DeepL::Exceptions::NotFound)
372
- end
193
+ deepl.glossaries.destroy('glossary-id')
373
194
  end
374
195
  end
375
196
 
376
- describe '#glossaries.entries' do
377
- let(:id) { 'e7a62637-7ef4-4959-a355-09ba61dd0126' }
378
- let(:options) { {} }
379
-
380
- around do |example|
381
- deepl.configure
382
- VCR.use_cassette('deepl_glossaries') { example.call }
383
- end
197
+ describe 'GlossaryApi#entries' do
198
+ it 'delegates to DeepL::Requests::Glossary::Entries' do
199
+ request = instance_double(DeepL::Requests::Glossary::Entries, request: 'result')
200
+ expect(DeepL::Requests::Glossary::Entries).to receive(:new)
201
+ .with(deepl.api, 'glossary-id', {})
202
+ .and_return(request)
384
203
 
385
- context 'when listing glossary entries' do
386
- it 'creates and call a request object' do
387
- expect(DeepL::Requests::Glossary::Entries).to receive(:new)
388
- .with(deepl.api, id, options).and_call_original
389
-
390
- entries = deepl.glossaries.entries(id, options)
391
- expect(entries).to all(be_a(Array))
392
- entries.each do |entry|
393
- expect(entry.size).to eq(2)
394
- expect(entry.first).to be_a(String)
395
- expect(entry.last).to be_a(String)
396
- end
397
- end
398
- end
399
-
400
- context 'when listing entries of a non existing glossary' do
401
- let(:id) { '00000000-0000-0000-0000-000000000000' }
402
-
403
- it 'raises an exception when the glossary does not exist' do
404
- expect(DeepL::Requests::Glossary::Entries).to receive(:new)
405
- .with(deepl.api, id, options).and_call_original
406
- expect { deepl.glossaries.entries(id, options) }
407
- .to raise_error(DeepL::Exceptions::NotFound)
408
- end
204
+ deepl.glossaries.entries('glossary-id')
409
205
  end
410
206
  end
411
207
 
412
- describe '#glossaries.language_pairs' do
413
- let(:options) { {} }
208
+ describe 'GlossaryApi#language_pairs' do
209
+ it 'delegates to DeepL::Requests::Glossary::LanguagePairs' do
210
+ request = instance_double(DeepL::Requests::Glossary::LanguagePairs, request: 'result')
211
+ expect(DeepL::Requests::Glossary::LanguagePairs).to receive(:new).with(deepl.api, {})
212
+ .and_return(request)
414
213
 
415
- around do |example|
416
- deepl.configure
417
- VCR.use_cassette('deepl_glossaries') { example.call }
214
+ deepl.glossaries.language_pairs
418
215
  end
216
+ end
217
+ end
419
218
 
420
- context 'when fetching language pairs supported by glossaries' do
421
- it 'creates and call a request object' do
422
- expect(DeepL::Requests::Glossary::LanguagePairs).to receive(:new)
423
- .with(deepl.api, options).and_call_original
219
+ describe '#document' do
220
+ before { deepl.configure }
424
221
 
425
- language_pairs = deepl.glossaries.language_pairs(options)
426
- expect(language_pairs).to all(be_a(DeepL::Resources::LanguagePair))
427
- end
428
- end
222
+ it 'returns a DocumentApi instance built with the configured api' do
223
+ expect(deepl.document).to be_a(DeepL::DocumentApi)
429
224
  end
430
- end
431
225
 
432
- describe '#rephrase' do
433
- let(:text) { 'Ih bin ei beispielsatz.' }
434
- let(:target_lang) { 'DE' }
435
- let(:options) { {} }
226
+ describe 'DocumentApi#upload' do
227
+ it 'delegates to DeepL::Requests::Document::Upload' do
228
+ request = instance_double(DeepL::Requests::Document::Upload, request: 'result')
229
+ expect(DeepL::Requests::Document::Upload).to receive(:new)
230
+ .with(deepl.api, 'path', 'EN', 'ES', 'file.txt', {}, {})
231
+ .and_return(request)
436
232
 
437
- around do |example|
438
- deepl.configure
439
- VCR.use_cassette('deepl_rephrase') { example.call }
233
+ deepl.document.upload('path', 'EN', 'ES', 'file.txt')
234
+ end
440
235
  end
441
236
 
442
- context 'when rephrasing text' do
443
- it 'creates and call a request object' do
444
- expect(DeepL::Requests::Rephrase).to receive(:new)
445
- .with(deepl.api, text, nil, nil, nil, {}).and_call_original
237
+ describe 'DocumentApi#get_status' do
238
+ it 'delegates to DeepL::Requests::Document::GetStatus' do
239
+ request = instance_double(DeepL::Requests::Document::GetStatus, request: 'result')
240
+ handle = DeepL::Resources::DocumentHandle.new('doc-id', 'doc-key', nil, nil)
241
+ expect(DeepL::Requests::Document::GetStatus).to receive(:new)
242
+ .with(deepl.api, 'doc-id', 'doc-key', {}, {})
243
+ .and_return(request)
446
244
 
447
- rephrased_text = deepl.rephrase(text)
448
- expect(rephrased_text).to be_a(DeepL::Resources::Text)
245
+ deepl.document.get_status(handle)
449
246
  end
247
+ end
450
248
 
451
- it 'creates and call a request object when passing options' do
452
- expect(DeepL::Requests::Rephrase).to receive(:new)
453
- .with(deepl.api, text, target_lang, nil, nil, options).and_call_original
249
+ describe 'DocumentApi#download' do
250
+ it 'delegates to DeepL::Requests::Document::Download' do
251
+ request = instance_double(DeepL::Requests::Document::Download, request: 'result')
252
+ handle = DeepL::Resources::DocumentHandle.new('doc-id', 'doc-key', nil, nil)
253
+ expect(DeepL::Requests::Document::Download).to receive(:new)
254
+ .with(deepl.api, 'doc-id', 'doc-key', 'output-path')
255
+ .and_return(request)
454
256
 
455
- rephrased_text = deepl.rephrase(text, target_lang, nil, nil, options)
456
- expect(rephrased_text).to be_a(DeepL::Resources::Text)
257
+ deepl.document.download(handle, 'output-path')
457
258
  end
458
259
  end
459
260
  end
460
261
  end
262
+ # rubocop:enable RSpec/StubbedMock
@@ -6,16 +6,6 @@
6
6
  require 'spec_helper'
7
7
 
8
8
  describe DeepL::DocumentApi do
9
- before do
10
- VCR.turn_off!
11
- WebMock.allow_net_connect!
12
- end
13
-
14
- after do
15
- VCR.turn_on!
16
- WebMock.disable_net_connect!
17
- end
18
-
19
9
  include_context 'with temp dir'
20
10
 
21
11
  let(:default_lang_args) { { source_lang: 'EN', target_lang: 'DE' } }
@@ -63,8 +53,7 @@ describe DeepL::DocumentApi do
63
53
  expect(doc_status.status).to eq('done')
64
54
  end
65
55
 
66
- it 'Translates a document after retrying the upload once' do # rubocop:disable RSpec/ExampleLength
67
- skip 'Only runs on mock server' if real_server?
56
+ it 'Translates a document after retrying the upload once', :mock_server_only do # rubocop:disable RSpec/ExampleLength
68
57
  File.unlink(output_document_path)
69
58
  source_lang = default_lang_args[:source_lang]
70
59
  target_lang = default_lang_args[:target_lang]
@@ -85,8 +74,7 @@ describe DeepL::DocumentApi do
85
74
  end
86
75
  end
87
76
 
88
- it 'Translates a document after waiting' do # rubocop:disable RSpec/ExampleLength
89
- skip 'Only runs on mock server' if real_server?
77
+ it 'Translates a document after waiting', :mock_server_only do # rubocop:disable RSpec/ExampleLength
90
78
  File.unlink(output_document_path)
91
79
  source_lang = default_lang_args[:source_lang]
92
80
  target_lang = default_lang_args[:target_lang]
@@ -107,8 +95,7 @@ describe DeepL::DocumentApi do
107
95
  expect(doc_status.status).to eq('done')
108
96
  end
109
97
 
110
- it 'Translates a large document' do # rubocop:disable RSpec/ExampleLength
111
- skip 'Only runs on mock server' if real_server?
98
+ it 'Translates a large document', :mock_server_only do # rubocop:disable RSpec/ExampleLength
112
99
  File.unlink(output_document_path)
113
100
  source_lang = default_lang_args[:source_lang]
114
101
  target_lang = default_lang_args[:target_lang]
@@ -130,8 +117,7 @@ describe DeepL::DocumentApi do
130
117
  expect(doc_status.status).to eq('done')
131
118
  end
132
119
 
133
- it 'Translates a document with formality set' do # rubocop:disable RSpec/ExampleLength
134
- skip 'Only runs on mock server' if real_server?
120
+ it 'Translates a document with formality set', :mock_server_only do # rubocop:disable RSpec/ExampleLength
135
121
  File.unlink(output_document_path)
136
122
  source_lang = default_lang_args[:source_lang]
137
123
  target_lang = default_lang_args[:target_lang]
@@ -0,0 +1,33 @@
1
+ # Copyright 2026 DeepL SE (https://www.deepl.com)
2
+ # Use of this source code is governed by an MIT
3
+ # license that can be found in the LICENSE file.
4
+ # frozen_string_literal: true
5
+
6
+ require 'spec_helper'
7
+
8
+ describe DeepL::DocumentApi do # rubocop:disable RSpec/SpecFilePathFormat
9
+ include_context 'with a live mock server'
10
+
11
+ let(:source_lang) { 'EN' }
12
+ let(:target_lang) { 'DE' }
13
+ let(:document_path) { example_document_path(source_lang) }
14
+
15
+ describe 'authorization failures' do
16
+ let(:unauthorized_documents) { described_class.new(unauthorized_api) }
17
+
18
+ it 'raises AuthorizationFailed when uploading with an invalid auth key' do
19
+ expect { unauthorized_documents.upload(document_path, source_lang, target_lang) }
20
+ .to raise_error(DeepL::Exceptions::AuthorizationFailed)
21
+ end
22
+ end
23
+
24
+ describe 'translation failures' do
25
+ it 'reports an error status when the server fails the document', :mock_server_only do
26
+ handle = DeepL.document.upload(document_path, source_lang, target_lang,
27
+ File.basename(document_path), {}, fail_docs_header(1))
28
+ status = handle.wait_until_document_translation_finished
29
+
30
+ expect(status.status).to eq('error')
31
+ end
32
+ end
33
+ end