deepl-rb 3.9.0 → 3.10.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 (237) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab-ci.yml +70 -52
  3. data/.rubocop.yml +26 -0
  4. data/CHANGELOG.md +429 -18
  5. data/Gemfile +4 -0
  6. data/README.md +981 -223
  7. data/Rakefile +18 -5
  8. data/VERSION +1 -1
  9. data/deepl-rb.gemspec +6 -6
  10. data/lib/deepl/admin_client.rb +183 -0
  11. data/lib/deepl/api.rb +30 -6
  12. data/lib/deepl/app_info.rb +20 -0
  13. data/lib/deepl/client.rb +969 -0
  14. data/lib/deepl/configuration.rb +56 -10
  15. data/lib/deepl/constants/admin_usage_group_by.rb +13 -0
  16. data/lib/deepl/constants/custom_tag_usage_aggregate_by.rb +13 -0
  17. data/lib/deepl/constants/document_status_code.rb +17 -0
  18. data/lib/deepl/constants/language_include.rb +17 -0
  19. data/lib/deepl/constants/language_resource_name.rb +21 -0
  20. data/lib/deepl/constants/tag_handling_version.rb +14 -0
  21. data/lib/deepl/deprecation.rb +42 -0
  22. data/lib/deepl/document_api.rb +41 -22
  23. data/lib/deepl/exceptions/bad_request.rb +1 -3
  24. data/lib/deepl/exceptions/connection_error.rb +37 -0
  25. data/lib/deepl/exceptions/document_not_ready_error.rb +17 -0
  26. data/lib/deepl/exceptions/document_translation_error.rb +17 -1
  27. data/lib/deepl/exceptions/error.rb +13 -1
  28. data/lib/deepl/exceptions/not_found.rb +8 -3
  29. data/lib/deepl/exceptions/not_supported.rb +6 -0
  30. data/lib/deepl/exceptions/request_error.rb +19 -2
  31. data/lib/deepl/exceptions/server_error.rb +7 -1
  32. data/lib/deepl/exceptions/validation_error.rb +14 -0
  33. data/lib/deepl/requests/admin/base.rb +94 -0
  34. data/lib/deepl/requests/admin/create_developer_key.rb +38 -0
  35. data/lib/deepl/requests/admin/custom_tag_usage_analytics.rb +38 -0
  36. data/lib/deepl/requests/admin/list_developer_keys.rb +28 -0
  37. data/lib/deepl/requests/admin/update_developer_key.rb +35 -0
  38. data/lib/deepl/requests/admin/usage_analytics.rb +36 -0
  39. data/lib/deepl/requests/base.rb +229 -59
  40. data/lib/deepl/requests/correct.rb +57 -0
  41. data/lib/deepl/requests/document/download.rb +11 -3
  42. data/lib/deepl/requests/document/get_status.rb +2 -2
  43. data/lib/deepl/requests/document/upload.rb +43 -10
  44. data/lib/deepl/requests/glossary/create.rb +6 -2
  45. data/lib/deepl/requests/glossary/language_pairs.rb +20 -4
  46. data/lib/deepl/requests/language_resources.rb +41 -0
  47. data/lib/deepl/requests/languages.rb +28 -4
  48. data/lib/deepl/requests/languages_for_resource.rb +54 -0
  49. data/lib/deepl/requests/multilingual_glossary/create.rb +37 -0
  50. data/lib/deepl/requests/multilingual_glossary/destroy.rb +36 -0
  51. data/lib/deepl/requests/multilingual_glossary/destroy_dictionary.rb +51 -0
  52. data/lib/deepl/requests/multilingual_glossary/entries.rb +66 -0
  53. data/lib/deepl/requests/multilingual_glossary/find.rb +35 -0
  54. data/lib/deepl/requests/multilingual_glossary/helpers.rb +63 -0
  55. data/lib/deepl/requests/multilingual_glossary/list.rb +39 -0
  56. data/lib/deepl/requests/multilingual_glossary/replace_dictionary.rb +41 -0
  57. data/lib/deepl/requests/multilingual_glossary/update.rb +40 -0
  58. data/lib/deepl/requests/rephrase.rb +5 -9
  59. data/lib/deepl/requests/spoken_terms/create.rb +37 -0
  60. data/lib/deepl/requests/spoken_terms/destroy.rb +36 -0
  61. data/lib/deepl/requests/spoken_terms/destroy_term_list.rb +41 -0
  62. data/lib/deepl/requests/spoken_terms/entries.rb +46 -0
  63. data/lib/deepl/requests/spoken_terms/find.rb +35 -0
  64. data/lib/deepl/requests/spoken_terms/helpers.rb +67 -0
  65. data/lib/deepl/requests/spoken_terms/list.rb +35 -0
  66. data/lib/deepl/requests/spoken_terms/replace_term_list.rb +41 -0
  67. data/lib/deepl/requests/spoken_terms/update.rb +40 -0
  68. data/lib/deepl/requests/style_profile/base.rb +83 -0
  69. data/lib/deepl/requests/style_profile/create.rb +35 -0
  70. data/lib/deepl/requests/style_profile/destroy.rb +34 -0
  71. data/lib/deepl/requests/style_profile/find.rb +33 -0
  72. data/lib/deepl/requests/style_profile/list.rb +43 -0
  73. data/lib/deepl/requests/style_profile/update.rb +35 -0
  74. data/lib/deepl/requests/style_rule/create.rb +1 -1
  75. data/lib/deepl/requests/style_rule/create_custom_instruction.rb +4 -2
  76. data/lib/deepl/requests/style_rule/destroy.rb +4 -2
  77. data/lib/deepl/requests/style_rule/destroy_custom_instruction.rb +5 -3
  78. data/lib/deepl/requests/style_rule/find.rb +4 -2
  79. data/lib/deepl/requests/style_rule/find_custom_instruction.rb +5 -3
  80. data/lib/deepl/requests/style_rule/helpers.rb +35 -0
  81. data/lib/deepl/requests/style_rule/list.rb +1 -1
  82. data/lib/deepl/requests/style_rule/update.rb +4 -2
  83. data/lib/deepl/requests/style_rule/update_configured_rules.rb +4 -2
  84. data/lib/deepl/requests/style_rule/update_custom_instruction.rb +5 -3
  85. data/lib/deepl/requests/translate.rb +52 -20
  86. data/lib/deepl/requests/translation_memory/base.rb +1 -4
  87. data/lib/deepl/requests/translation_memory/create_export.rb +1 -1
  88. data/lib/deepl/requests/translation_memory/create_import.rb +1 -1
  89. data/lib/deepl/requests/translation_memory/destroy.rb +1 -1
  90. data/lib/deepl/requests/translation_memory/download_export.rb +4 -0
  91. data/lib/deepl/requests/translation_memory/find.rb +1 -1
  92. data/lib/deepl/requests/translation_memory/find_job.rb +1 -1
  93. data/lib/deepl/requests/translation_memory/list.rb +2 -1
  94. data/lib/deepl/requests/translation_memory/segments.rb +3 -2
  95. data/lib/deepl/requests/translation_memory/storage_base.rb +40 -8
  96. data/lib/deepl/requests/translation_memory/upload_file.rb +1 -1
  97. data/lib/deepl/requests/usage.rb +28 -1
  98. data/lib/deepl/requests/write_improvements.rb +35 -0
  99. data/lib/deepl/resources/admin_usage_report.rb +73 -0
  100. data/lib/deepl/resources/custom_tag_usage_report.rb +59 -0
  101. data/lib/deepl/resources/developer_key.rb +57 -0
  102. data/lib/deepl/resources/document_handle.rb +24 -25
  103. data/lib/deepl/resources/document_translation_status.rb +23 -4
  104. data/lib/deepl/resources/language.rb +10 -2
  105. data/lib/deepl/resources/language_resource.rb +57 -0
  106. data/lib/deepl/resources/language_support.rb +56 -0
  107. data/lib/deepl/resources/multilingual_glossary.rb +112 -0
  108. data/lib/deepl/resources/spoken_terms.rb +61 -0
  109. data/lib/deepl/resources/style_profile.rb +44 -0
  110. data/lib/deepl/resources/style_rule.rb +3 -0
  111. data/lib/deepl/resources/text.rb +18 -2
  112. data/lib/deepl/resources/translation_memory.rb +8 -2
  113. data/lib/deepl/resources/translation_memory_import.rb +1 -1
  114. data/lib/deepl/resources/translation_memory_job.rb +23 -3
  115. data/lib/deepl/resources/translation_memory_segments.rb +8 -6
  116. data/lib/deepl/resources/usage.rb +93 -4
  117. data/lib/deepl/style_rule_api.rb +11 -0
  118. data/lib/deepl/translation_memory_api.rb +104 -24
  119. data/lib/deepl/utils/client_builder.rb +54 -0
  120. data/lib/deepl/utils/document_poller.rb +70 -0
  121. data/lib/deepl/utils/exception_builder.rb +3 -2
  122. data/lib/deepl/utils/http_client_builder.rb +79 -0
  123. data/lib/deepl/utils/number_parser.rb +34 -0
  124. data/lib/deepl/utils/term_validator.rb +33 -0
  125. data/lib/deepl/utils/time_parser.rb +14 -0
  126. data/lib/deepl.rb +166 -41
  127. data/lib/http_client_options.rb +21 -1
  128. data/lib/version.rb +1 -1
  129. data/spec/fixtures.rb +33 -0
  130. data/spec/offline/admin_client_spec.rb +551 -0
  131. data/spec/offline/client_spec.rb +273 -0
  132. data/spec/{api → offline}/configuration_spec.rb +45 -3
  133. data/spec/{constants → offline}/constants_spec.rb +23 -1
  134. data/spec/offline/correct_text_spec.rb +50 -0
  135. data/spec/offline/deprecation_spec.rb +32 -0
  136. data/spec/offline/errors_spec.rb +92 -0
  137. data/spec/offline/glossaries_spec.rb +98 -0
  138. data/spec/offline/http_client_spec.rb +319 -0
  139. data/spec/offline/languages_spec.rb +155 -0
  140. data/spec/offline/module_methods_spec.rb +13 -0
  141. data/spec/offline/multilingual_glossaries_spec.rb +358 -0
  142. data/spec/offline/offline_helper.rb +71 -0
  143. data/spec/offline/rephrase_text_spec.rb +73 -0
  144. data/spec/offline/spoken_terms_spec.rb +215 -0
  145. data/spec/offline/style_profiles_spec.rb +266 -0
  146. data/spec/offline/style_rules_spec.rb +318 -0
  147. data/spec/offline/translate_document_spec.rb +606 -0
  148. data/spec/offline/translate_text_spec.rb +286 -0
  149. data/spec/offline/translation_memories_client_spec.rb +256 -0
  150. data/spec/offline/translation_memories_spec.rb +463 -0
  151. data/spec/offline/usage_spec.rb +151 -0
  152. data/spec/real_api/admin_client_spec.rb +77 -0
  153. data/spec/real_api/correct_text_spec.rb +20 -0
  154. data/spec/real_api/glossaries_spec.rb +28 -0
  155. data/spec/real_api/languages_spec.rb +27 -0
  156. data/spec/real_api/multilingual_glossaries_spec.rb +53 -0
  157. data/spec/real_api/proxy_spec.rb +41 -0
  158. data/spec/real_api/real_api_helper.rb +65 -0
  159. data/spec/real_api/rephrase_text_spec.rb +16 -0
  160. data/spec/real_api/spoken_terms_spec.rb +56 -0
  161. data/spec/real_api/style_profiles_spec.rb +46 -0
  162. data/spec/real_api/style_rules_spec.rb +46 -0
  163. data/spec/real_api/translate_document_spec.rb +18 -0
  164. data/spec/real_api/translate_text_spec.rb +16 -0
  165. data/spec/real_api/translation_memories_spec.rb +56 -0
  166. data/spec/real_api/usage_spec.rb +20 -0
  167. data/spec/spec_helper.rb +1 -50
  168. metadata +116 -76
  169. data/.circleci/config.yml +0 -27
  170. data/.github/workflows/add_issues_to_kanban.yml +0 -16
  171. data/spec/api/api_spec.rb +0 -20
  172. data/spec/api/deepl_spec.rb +0 -262
  173. data/spec/integration_tests/document_api_spec.rb +0 -211
  174. data/spec/integration_tests/document_error_paths_spec.rb +0 -33
  175. data/spec/integration_tests/glossary_api_spec.rb +0 -114
  176. data/spec/integration_tests/glossary_error_paths_spec.rb +0 -107
  177. data/spec/integration_tests/integration_test_utils.rb +0 -178
  178. data/spec/integration_tests/languages_api_spec.rb +0 -54
  179. data/spec/integration_tests/languages_error_paths_spec.rb +0 -25
  180. data/spec/integration_tests/rephrase_api_spec.rb +0 -90
  181. data/spec/integration_tests/rephrase_error_paths_spec.rb +0 -53
  182. data/spec/integration_tests/smoke_test_spec.rb +0 -24
  183. data/spec/integration_tests/style_rule_api_spec.rb +0 -117
  184. data/spec/integration_tests/style_rule_error_paths_spec.rb +0 -45
  185. data/spec/integration_tests/translate_api_spec.rb +0 -117
  186. data/spec/integration_tests/translate_error_paths_spec.rb +0 -48
  187. data/spec/integration_tests/translation_memory_api_spec.rb +0 -244
  188. data/spec/integration_tests/translation_memory_error_paths_spec.rb +0 -87
  189. data/spec/integration_tests/usage_api_spec.rb +0 -29
  190. data/spec/integration_tests/usage_error_paths_spec.rb +0 -18
  191. data/spec/requests/document/upload_spec.rb +0 -130
  192. data/spec/requests/extra_body_parameters_types_spec.rb +0 -82
  193. data/spec/requests/glossary/create_spec.rb +0 -44
  194. data/spec/requests/glossary/destroy_spec.rb +0 -27
  195. data/spec/requests/glossary/entries_spec.rb +0 -27
  196. data/spec/requests/glossary/find_spec.rb +0 -28
  197. data/spec/requests/glossary/language_pairs_spec.rb +0 -27
  198. data/spec/requests/glossary/list_spec.rb +0 -27
  199. data/spec/requests/languages_spec.rb +0 -27
  200. data/spec/requests/rephrase_spec.rb +0 -46
  201. data/spec/requests/style_rule/create_custom_instruction_spec.rb +0 -30
  202. data/spec/requests/style_rule/create_spec.rb +0 -29
  203. data/spec/requests/style_rule/destroy_custom_instruction_spec.rb +0 -28
  204. data/spec/requests/style_rule/destroy_spec.rb +0 -27
  205. data/spec/requests/style_rule/find_custom_instruction_spec.rb +0 -29
  206. data/spec/requests/style_rule/find_spec.rb +0 -28
  207. data/spec/requests/style_rule/list_spec.rb +0 -27
  208. data/spec/requests/style_rule/update_configured_rules_spec.rb +0 -31
  209. data/spec/requests/style_rule/update_custom_instruction_spec.rb +0 -32
  210. data/spec/requests/style_rule/update_spec.rb +0 -29
  211. data/spec/requests/translate_spec.rb +0 -338
  212. data/spec/requests/translation_memory/create_export_spec.rb +0 -37
  213. data/spec/requests/translation_memory/create_import_spec.rb +0 -61
  214. data/spec/requests/translation_memory/destroy_spec.rb +0 -36
  215. data/spec/requests/translation_memory/download_export_spec.rb +0 -54
  216. data/spec/requests/translation_memory/find_job_spec.rb +0 -37
  217. data/spec/requests/translation_memory/find_spec.rb +0 -36
  218. data/spec/requests/translation_memory/list_spec.rb +0 -27
  219. data/spec/requests/translation_memory/segments_spec.rb +0 -58
  220. data/spec/requests/translation_memory/upload_file_spec.rb +0 -55
  221. data/spec/requests/usage_spec.rb +0 -27
  222. data/spec/resources/custom_instruction_spec.rb +0 -32
  223. data/spec/resources/glossary_spec.rb +0 -38
  224. data/spec/resources/language_pair_spec.rb +0 -23
  225. data/spec/resources/language_spec.rb +0 -45
  226. data/spec/resources/style_rule_spec.rb +0 -68
  227. data/spec/resources/text_spec.rb +0 -23
  228. data/spec/resources/translation_memory_export_spec.rb +0 -38
  229. data/spec/resources/translation_memory_import_spec.rb +0 -30
  230. data/spec/resources/translation_memory_job_spec.rb +0 -109
  231. data/spec/resources/translation_memory_segments_spec.rb +0 -78
  232. data/spec/resources/translation_memory_spec.rb +0 -52
  233. data/spec/resources/usage_spec.rb +0 -35
  234. data/spec/support/live_mock_server.rb +0 -12
  235. data/spec/support/managed_glossary.rb +0 -65
  236. data/spec/support/managed_style_rule.rb +0 -17
  237. data/spec/support/managed_translation_memory.rb +0 -55
@@ -1,211 +0,0 @@
1
- # Copyright 2024 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
9
- include_context 'with temp dir'
10
-
11
- let(:default_lang_args) { { source_lang: 'EN', target_lang: 'DE' } }
12
-
13
- describe '#translate_document' do
14
- it 'Translates a document from a filepath' do
15
- File.unlink(output_document_path)
16
- source_lang = default_lang_args[:source_lang]
17
- target_lang = default_lang_args[:target_lang]
18
- example_doc_path = example_document_path(source_lang)
19
- DeepL.document.translate_document(example_doc_path, output_document_path,
20
- source_lang, target_lang, File.basename(example_doc_path),
21
- {})
22
- output_file_contents = File.read(output_document_path)
23
-
24
- expect(example_document_translation(target_lang)).to eq(output_file_contents)
25
- end
26
-
27
- it 'Translates a document from a filepath without a filename' do
28
- File.unlink(output_document_path)
29
- source_lang = default_lang_args[:source_lang]
30
- target_lang = default_lang_args[:target_lang]
31
- example_doc_path = example_document_path(source_lang)
32
- DeepL.document.translate_document(example_doc_path, output_document_path,
33
- source_lang, target_lang)
34
- output_file_contents = File.read(output_document_path)
35
-
36
- expect(example_document_translation(target_lang)).to eq(output_file_contents)
37
- end
38
-
39
- it 'Translates a document using the lower-level methods and returns the correct status' do # rubocop:disable RSpec/ExampleLength
40
- File.unlink(output_document_path)
41
- source_lang = default_lang_args[:source_lang]
42
- target_lang = default_lang_args[:target_lang]
43
- example_doc_path = example_document_path(source_lang)
44
-
45
- handle = DeepL.document.upload(example_doc_path, source_lang, target_lang,
46
- File.basename(example_doc_path), {})
47
- doc_status = handle.wait_until_document_translation_finished
48
- DeepL.document.download(handle, output_document_path) if doc_status.status != 'error'
49
- output_file_contents = File.read(output_document_path)
50
-
51
- expect(example_document_translation(target_lang)).to eq(output_file_contents)
52
- expect(doc_status.billed_characters).to eq(example_document_translation(source_lang).length)
53
- expect(doc_status.status).to eq('done')
54
- end
55
-
56
- it 'Translates a document after retrying the upload once', :mock_server_only do # rubocop:disable RSpec/ExampleLength
57
- File.unlink(output_document_path)
58
- source_lang = default_lang_args[:source_lang]
59
- target_lang = default_lang_args[:target_lang]
60
- example_doc_path = example_document_path(source_lang)
61
- doc_status = nil
62
- DeepL.with_session(DeepL::HTTPClientOptions.new({}, nil, enable_ssl_verification: false,
63
- read_timeout: 1.0)) do |_session|
64
- handle = DeepL.document.upload(example_doc_path, source_lang, target_lang,
65
- File.basename(example_doc_path), {}, no_response_header(1))
66
- doc_status = handle.wait_until_document_translation_finished
67
- DeepL.document.download(handle, output_document_path) if doc_status.status != 'error'
68
- end
69
- output_file_contents = File.read(output_document_path)
70
-
71
- expect(output_file_contents).to eq(example_document_translation(target_lang))
72
- expect(doc_status.billed_characters).to eq(example_document_translation(source_lang).length)
73
- expect(doc_status.status).to eq('done')
74
- end
75
- end
76
-
77
- it 'Translates a document after waiting', :mock_server_only do # rubocop:disable RSpec/ExampleLength
78
- File.unlink(output_document_path)
79
- source_lang = default_lang_args[:source_lang]
80
- target_lang = default_lang_args[:target_lang]
81
- example_doc_path = example_document_path(source_lang)
82
- doc_status = nil
83
- DeepL.with_session(DeepL::HTTPClientOptions.new({}, nil,
84
- enable_ssl_verification: false)) do |_session|
85
- handle = DeepL.document.upload(example_doc_path, source_lang, target_lang,
86
- File.basename(example_doc_path), {},
87
- doc_translation_queue_time_header(2000).merge(doc_translation_translation_time_header(2000))) # rubocop:disable Layout/LineLength
88
- doc_status = handle.wait_until_document_translation_finished
89
- DeepL.document.download(handle, output_document_path) if doc_status.status != 'error'
90
- end
91
- output_file_contents = File.read(output_document_path)
92
-
93
- expect(output_file_contents).to eq(example_document_translation(target_lang))
94
- expect(doc_status.billed_characters).to eq(example_document_translation(source_lang).length)
95
- expect(doc_status.status).to eq('done')
96
- end
97
-
98
- it 'Translates a large document', :mock_server_only do # rubocop:disable RSpec/ExampleLength
99
- File.unlink(output_document_path)
100
- source_lang = default_lang_args[:source_lang]
101
- target_lang = default_lang_args[:target_lang]
102
- example_doc_path = example_large_document_path(source_lang)
103
- doc_status = nil
104
- DeepL.with_session(DeepL::HTTPClientOptions.new({}, nil,
105
- enable_ssl_verification: false)) do |_session|
106
- handle = DeepL.document.upload(example_doc_path, source_lang, target_lang,
107
- File.basename(example_doc_path), {})
108
- doc_status = handle.wait_until_document_translation_finished
109
- DeepL.document.download(handle, output_document_path) if doc_status.status != 'error'
110
- end
111
- output_file_contents = File.read(output_document_path)
112
-
113
- expect(output_file_contents).to eq(example_large_document_translation(target_lang))
114
- expect(doc_status.billed_characters).to eq(
115
- example_large_document_translation(source_lang).length
116
- )
117
- expect(doc_status.status).to eq('done')
118
- end
119
-
120
- it 'Translates a document with formality set', :mock_server_only do # rubocop:disable RSpec/ExampleLength
121
- File.unlink(output_document_path)
122
- source_lang = default_lang_args[:source_lang]
123
- target_lang = default_lang_args[:target_lang]
124
- example_doc_path = example_large_document_path(source_lang)
125
- doc_status = nil
126
- DeepL.with_session(DeepL::HTTPClientOptions.new({}, nil,
127
- enable_ssl_verification: false)) do |_session|
128
- handle = DeepL.document.upload(example_doc_path, source_lang, target_lang,
129
- File.basename(example_doc_path),
130
- { 'formality' => 'prefer_more' })
131
- doc_status = handle.wait_until_document_translation_finished
132
- DeepL.document.download(handle, output_document_path) if doc_status.status != 'error'
133
- end
134
- output_file_contents = File.read(output_document_path)
135
-
136
- expect(output_file_contents).to eq(example_large_document_translation(target_lang))
137
- expect(doc_status.billed_characters).to eq(
138
- example_large_document_translation(source_lang).length
139
- )
140
- expect(doc_status.status).to eq('done')
141
- end
142
-
143
- it 'Translates a document with a style_id set', :mock_server_only do # rubocop:disable RSpec/ExampleLength
144
- File.unlink(output_document_path)
145
- # Mock's default style rule (dca2e053...) has language `en`, so the target
146
- # language must be English.
147
- source_lang = 'DE'
148
- target_lang = 'EN-US'
149
- example_doc_path = example_document_path(source_lang)
150
- style_id = 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4'
151
- doc_status = nil
152
- DeepL.with_session(DeepL::HTTPClientOptions.new({}, nil,
153
- enable_ssl_verification: false)) do |_session|
154
- handle = DeepL.document.upload(example_doc_path, source_lang, target_lang,
155
- File.basename(example_doc_path),
156
- { style_rule: style_id })
157
- doc_status = handle.wait_until_document_translation_finished
158
- DeepL.document.download(handle, output_document_path) if doc_status.status != 'error'
159
- end
160
- output_file_contents = File.read(output_document_path)
161
-
162
- expect(example_document_translation(target_lang)).to eq(output_file_contents)
163
- expect(doc_status.status).to eq('done')
164
- end
165
-
166
- it 'Translates a document with a translation_memory_id set', :mock_server_only do # rubocop:disable RSpec/ExampleLength
167
- File.unlink(output_document_path)
168
- # Mock's default translation memory (a74d88fb...) has source `de` and
169
- # targets `en`/`es`/`fr`, so translate DE -> EN-US.
170
- source_lang = 'DE'
171
- target_lang = 'EN-US'
172
- example_doc_path = example_document_path(source_lang)
173
- translation_memory_id = 'a74d88fb-ed2a-4943-a664-a4512398b994'
174
- doc_status = nil
175
- DeepL.with_session(DeepL::HTTPClientOptions.new({}, nil,
176
- enable_ssl_verification: false)) do |_session|
177
- handle = DeepL.document.upload(example_doc_path, source_lang, target_lang,
178
- File.basename(example_doc_path),
179
- { translation_memory: translation_memory_id,
180
- translation_memory_threshold: 80 })
181
- doc_status = handle.wait_until_document_translation_finished
182
- DeepL.document.download(handle, output_document_path) if doc_status.status != 'error'
183
- end
184
- output_file_contents = File.read(output_document_path)
185
-
186
- expect(example_document_translation(target_lang)).to eq(output_file_contents)
187
- expect(doc_status.status).to eq('done')
188
- end
189
-
190
- it 'Translates a document with extra_body_parameters' do # rubocop:disable RSpec/ExampleLength
191
- File.unlink(output_document_path)
192
- source_lang = default_lang_args[:source_lang]
193
- target_lang = default_lang_args[:target_lang]
194
- example_doc_path = example_document_path(source_lang)
195
-
196
- handle = DeepL.document.upload(example_doc_path, source_lang, target_lang,
197
- File.basename(example_doc_path),
198
- {
199
- extra_body_parameters: {
200
- target_lang: 'FR',
201
- debug: '1'
202
- }
203
- })
204
- doc_status = handle.wait_until_document_translation_finished
205
- DeepL.document.download(handle, output_document_path) if doc_status.status != 'error'
206
- output_file_contents = File.read(output_document_path)
207
-
208
- expect(example_document_translation('FR')).to eq(output_file_contents)
209
- expect(doc_status.status).to eq('done')
210
- end
211
- end
@@ -1,33 +0,0 @@
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
@@ -1,114 +0,0 @@
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::GlossaryApi do
9
- let(:default_glossary_args) do
10
- {
11
- name: 'Integration Test Glossary',
12
- source_lang: 'en',
13
- target_lang: 'de',
14
- entries: [%w[Hello Hallo], %w[World Welt]]
15
- }
16
- end
17
-
18
- describe 'happy path lifecycle' do
19
- it 'creates, lists, and finds a glossary' do # rubocop:disable RSpec/ExampleLength,RSpec/MultipleExpectations
20
- with_managed_glossary(**default_glossary_args) do |glossary|
21
- expect(glossary).to be_a(DeepL::Resources::Glossary)
22
- expect(glossary.id).to be_a(String)
23
- expect(glossary.name).to eq(default_glossary_args[:name])
24
- expect(glossary.entry_count).to eq(2)
25
- expect(glossary.source_lang).to eq(default_glossary_args[:source_lang])
26
- expect(glossary.target_lang).to eq(default_glossary_args[:target_lang])
27
- expect(glossary.ready).to be(true).or be(false)
28
- expect { Time.iso8601(glossary.creation_time) }.not_to raise_error
29
-
30
- listed = DeepL.glossaries.list
31
- expect(listed).to be_an(Array)
32
- expect(listed.map(&:id)).to include(glossary.id)
33
-
34
- found = DeepL.glossaries.find(glossary.id)
35
- expect(found).to be_a(DeepL::Resources::Glossary)
36
- expect(found.id).to eq(glossary.id)
37
- expect(found.name).to eq(glossary.name)
38
- end
39
- end
40
- end
41
-
42
- describe '#language_pairs' do
43
- it 'returns a non-empty list of supported source/target combos' do
44
- pairs = DeepL.glossaries.language_pairs
45
- expect(pairs).to be_an(Array)
46
- expect(pairs).not_to be_empty
47
- expect(pairs.first).to be_a(DeepL::Resources::LanguagePair)
48
- expect(pairs.first.source_lang).to be_a(String)
49
- expect(pairs.first.target_lang).to be_a(String)
50
- end
51
- end
52
-
53
- describe 'error handling' do
54
- it 'raises when creating a glossary with an invalid source language code' do
55
- expect do
56
- DeepL.glossaries.create(
57
- 'Invalid Lang Glossary',
58
- 'zz',
59
- 'de',
60
- [%w[Hello Hallo]]
61
- )
62
- end.to raise_error(DeepL::Exceptions::RequestError)
63
- end
64
- end
65
-
66
- describe '#destroy' do
67
- it 'returns the id of the destroyed glossary' do
68
- glossary = DeepL.glossaries.create(
69
- default_glossary_args[:name],
70
- default_glossary_args[:source_lang],
71
- default_glossary_args[:target_lang],
72
- default_glossary_args[:entries]
73
- )
74
-
75
- expect(DeepL.glossaries.destroy(glossary.id)).to eq(glossary.id)
76
- end
77
- end
78
-
79
- describe '#entries' do
80
- it 'returns the glossary entries as an array of [source, target] pairs' do # rubocop:disable RSpec/ExampleLength
81
- with_managed_glossary(**default_glossary_args) do |glossary|
82
- entries = DeepL.glossaries.entries(glossary.id)
83
-
84
- expect(entries).to be_an(Array)
85
- expect(entries).to all(be_an(Array))
86
- expect(entries.size).to eq(default_glossary_args[:entries].size)
87
- entries.each do |entry|
88
- expect(entry.size).to eq(2)
89
- expect(entry.first).to be_a(String)
90
- expect(entry.last).to be_a(String)
91
- end
92
- end
93
- end
94
- end
95
-
96
- describe 'edge cases' do
97
- it 'accepts Unicode keys and values in glossary entries' do # rubocop:disable RSpec/ExampleLength
98
- unicode_entries = [
99
- ['Schöne Grüße', 'Best regards'],
100
- ['🚀 rocket', '🚀 fusée'],
101
- ['日本語', 'Japanese'],
102
- ['café', 'kafē']
103
- ]
104
- args = default_glossary_args.merge(
105
- name: 'Unicode Glossary',
106
- entries: unicode_entries
107
- )
108
-
109
- with_managed_glossary(**args) do |glossary|
110
- expect(glossary.entry_count).to eq(unicode_entries.length)
111
- end
112
- end
113
- end
114
- end
@@ -1,107 +0,0 @@
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::GlossaryApi do # rubocop:disable RSpec/SpecFilePathFormat
9
- include_context 'with a live mock server'
10
-
11
- let(:nonexistent_glossary_id) { '00000000-0000-0000-0000-000000000000' }
12
-
13
- let(:valid_glossary_args) do
14
- {
15
- name: 'Error Path Test Glossary',
16
- source_lang: 'en',
17
- target_lang: 'de',
18
- entries: [%w[Hello Hallo]]
19
- }
20
- end
21
-
22
- describe 'AuthorizationFailed (401/403)' do
23
- let(:unauthorized_glossaries) { described_class.new(unauthorized_api) }
24
-
25
- it 'is raised by #list when the auth key is invalid' do
26
- expect { unauthorized_glossaries.list }
27
- .to raise_error(DeepL::Exceptions::AuthorizationFailed)
28
- end
29
-
30
- it 'is raised by #language_pairs when the auth key is invalid' do
31
- expect { unauthorized_glossaries.language_pairs }
32
- .to raise_error(DeepL::Exceptions::AuthorizationFailed)
33
- end
34
-
35
- it 'is raised by #create when the auth key is invalid' do
36
- expect do
37
- unauthorized_glossaries.create(
38
- valid_glossary_args[:name],
39
- valid_glossary_args[:source_lang],
40
- valid_glossary_args[:target_lang],
41
- valid_glossary_args[:entries]
42
- )
43
- end.to raise_error(DeepL::Exceptions::AuthorizationFailed)
44
- end
45
-
46
- it 'is raised by #find when the auth key is invalid' do
47
- expect { unauthorized_glossaries.find(nonexistent_glossary_id) }
48
- .to raise_error(DeepL::Exceptions::AuthorizationFailed)
49
- end
50
-
51
- it 'is raised by #destroy when the auth key is invalid' do
52
- expect { unauthorized_glossaries.destroy(nonexistent_glossary_id) }
53
- .to raise_error(DeepL::Exceptions::AuthorizationFailed)
54
- end
55
- end
56
-
57
- describe 'NotFound (404)' do
58
- it 'is raised by #find for a well-formed but unknown glossary id' do
59
- expect { DeepL.glossaries.find(nonexistent_glossary_id) }
60
- .to raise_error(DeepL::Exceptions::NotFound)
61
- end
62
-
63
- it 'is raised by #destroy for a well-formed but unknown glossary id' do
64
- expect { DeepL.glossaries.destroy(nonexistent_glossary_id) }
65
- .to raise_error(DeepL::Exceptions::NotFound)
66
- end
67
- end
68
-
69
- describe 'BadRequest (400) from #create' do
70
- it 'is raised for an invalid source language code' do
71
- expect do
72
- DeepL.glossaries.create(
73
- valid_glossary_args[:name],
74
- 'zz',
75
- valid_glossary_args[:target_lang],
76
- valid_glossary_args[:entries]
77
- )
78
- end.to raise_error(DeepL::Exceptions::BadRequest)
79
- end
80
- end
81
-
82
- describe 'BadRequest (400) from a malformed glossary id' do
83
- let(:malformed_uuid) { 'invalid-uuid' }
84
-
85
- it 'is raised by #find for a malformed glossary id' do
86
- expect { DeepL.glossaries.find(malformed_uuid) }
87
- .to raise_error(DeepL::Exceptions::BadRequest)
88
- end
89
-
90
- it 'is raised by #destroy for a malformed glossary id' do
91
- expect { DeepL.glossaries.destroy(malformed_uuid) }
92
- .to raise_error(DeepL::Exceptions::BadRequest)
93
- end
94
-
95
- it 'is raised by #entries for a malformed glossary id' do
96
- expect { DeepL.glossaries.entries(malformed_uuid) }
97
- .to raise_error(DeepL::Exceptions::BadRequest)
98
- end
99
- end
100
-
101
- describe 'NotFound (404) from #entries' do
102
- it 'is raised for a well-formed but unknown glossary id' do
103
- expect { DeepL.glossaries.entries(nonexistent_glossary_id) }
104
- .to raise_error(DeepL::Exceptions::NotFound)
105
- end
106
- end
107
- end
@@ -1,178 +0,0 @@
1
- # Copyright 2024 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 'securerandom'
7
- require 'tempfile'
8
-
9
- module IntegrationTestUtils # rubocop:disable Metrics/ModuleLength
10
- EXAMPLE_TEXT = {
11
- 'BG' => 'протонен лъч',
12
- 'CS' => 'protonový paprsek',
13
- 'DA' => 'protonstråle',
14
- 'DE' => 'Protonenstrahl',
15
- 'EL' => 'δέσμη πρωτονίων',
16
- 'EN' => 'proton beam',
17
- 'EN-US' => 'proton beam',
18
- 'EN-GB' => 'proton beam',
19
- 'ES' => 'haz de protones',
20
- 'ET' => 'prootonikiirgus',
21
- 'FI' => 'protonisäde',
22
- 'FR' => 'faisceau de protons',
23
- 'HU' => 'protonnyaláb',
24
- 'ID' => 'berkas proton',
25
- 'IT' => 'fascio di protoni',
26
- 'JA' => '陽子ビーム',
27
- 'KO' => '양성자 빔',
28
- 'LT' => 'protonų spindulys',
29
- 'LV' => 'protonu staru kūlis',
30
- 'NB' => 'protonstråle',
31
- 'NL' => 'protonenbundel',
32
- 'PL' => 'wiązka protonów',
33
- 'PT' => 'feixe de prótons',
34
- 'PT-BR' => 'feixe de prótons',
35
- 'PT-PT' => 'feixe de prótons',
36
- 'RO' => 'fascicul de protoni',
37
- 'RU' => 'протонный луч',
38
- 'SK' => 'protónový lúč',
39
- 'SL' => 'protonski žarek',
40
- 'SV' => 'protonstråle',
41
- 'TR' => 'proton ışını',
42
- 'UK' => 'протонний пучок',
43
- 'ZH' => '质子束'
44
- }.freeze
45
-
46
- def mock_server?
47
- ENV.key?('DEEPL_MOCK_SERVER_PORT')
48
- end
49
-
50
- def mock_proxy_server?
51
- ENV.key?('DEEPL_MOCK_PROXY_SERVER_PORT')
52
- end
53
-
54
- def real_server?
55
- !mock_server?
56
- end
57
-
58
- def setup
59
- @input_file = nil
60
- @input_file_extension = nil
61
- @output_file = nil
62
- DeepL.configure do |config|
63
- config.auth_key = 'your-api-token'
64
- end
65
- end
66
-
67
- def teardown
68
- unless @input_file.nil?
69
- @input_file.close
70
- @input_file.unlink
71
- end
72
- return if @output_file.nil?
73
-
74
- @output_file.close
75
- @output_file.unlink
76
- end
77
-
78
- def example_document_path(document_language)
79
- setup_example_document(EXAMPLE_TEXT[document_language])
80
- end
81
-
82
- def example_large_document_path(document_language)
83
- setup_example_document("#{EXAMPLE_TEXT[document_language]}\n" * 1000)
84
- end
85
-
86
- def setup_example_document(file_content)
87
- @input_file_base_name = 'example_input_document' if @input_file_base_name.nil?
88
- @input_file_extension = '.txt' if @input_file_extension.nil?
89
- if @input_file.nil?
90
- @input_file = Tempfile.new([@input_file_base_name, @input_file_extension])
91
- @input_file.write(file_content)
92
- @input_file.close
93
- end
94
- @input_file.path
95
- end
96
-
97
- def example_document_translation(document_language)
98
- EXAMPLE_TEXT[document_language]
99
- end
100
-
101
- def example_large_document_translation(document_language)
102
- "#{EXAMPLE_TEXT[document_language]}\n" * 1000
103
- end
104
-
105
- def output_document_path
106
- @output_file = Tempfile.new('example_output_document') if @output_file.nil?
107
- @output_file.path
108
- end
109
-
110
- # For detailed explanations of these header, check the deepl-mock README.md
111
- def no_response_header(no_response_count)
112
- { 'mock-server-session-no-response-count' => no_response_count.to_s,
113
- 'mock-server-session' => SecureRandom.uuid }
114
- end
115
-
116
- def respond_with_429_header(response_count)
117
- { 'mock-server-session-429-count' => response_count.to_s,
118
- 'mock-server-session' => SecureRandom.uuid }
119
- end
120
-
121
- def set_character_limit_header(response_count) # rubocop:disable Naming/AccessorMethodName
122
- { 'mock-server-session-init-character-limit' => response_count.to_s,
123
- 'mock-server-session' => SecureRandom.uuid }
124
- end
125
-
126
- def set_document_limit_header(response_count) # rubocop:disable Naming/AccessorMethodName
127
- { 'mock-server-session-init-document-limit' => response_count.to_s,
128
- 'mock-server-session' => SecureRandom.uuid }
129
- end
130
-
131
- def set_team_document_limit_header(response_count) # rubocop:disable Naming/AccessorMethodName
132
- { 'mock-server-session-init-team-document-limit' => response_count.to_s,
133
- 'mock-server-session' => SecureRandom.uuid }
134
- end
135
-
136
- def fail_docs_header(response_count)
137
- { 'mock-server-session-doc-failure' => response_count.to_s,
138
- 'mock-server-session' => SecureRandom.uuid }
139
- end
140
-
141
- def doc_translation_queue_time_header(response_count)
142
- { 'mock-server-session-doc-queue-time' => response_count.to_s,
143
- 'mock-server-session' => SecureRandom.uuid }
144
- end
145
-
146
- def doc_translation_translation_time_header(response_count)
147
- { 'mock-server-session-doc-translate-time' => response_count.to_s,
148
- 'mock-server-session' => SecureRandom.uuid }
149
- end
150
-
151
- # Makes a translation memory import or export job report its non-terminal status, such as
152
- # `awaiting_input` for an uploaded import, for the given number of status queries before it
153
- # completes. Without it a job completes on the first query.
154
- def tm_job_processing_polls_header(poll_count)
155
- { 'mock-server-session-tm-job-processing-polls' => poll_count.to_s,
156
- 'mock-server-session' => SecureRandom.uuid }
157
- end
158
-
159
- def expect_proxy_header(response_count)
160
- { 'mock-server-session-expect-proxy' => response_count.to_s,
161
- 'mock-server-session' => SecureRandom.uuid }
162
- end
163
- end
164
-
165
- shared_context 'with temp dir' do
166
- around do |example|
167
- Dir.mktmpdir('deepl-rspec-') do |dir|
168
- @temp_dir = dir
169
- example.run
170
- end
171
- end
172
-
173
- attr_reader :temp_dir, :input_file_base_name, :input_file_extension
174
- end
175
-
176
- RSpec.configure do |c|
177
- c.include IntegrationTestUtils
178
- end