deepl-rb 2.5.3 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/add_issues_to_kanban.yml +16 -0
- data/.gitlab-ci.yml +135 -0
- data/.rubocop.yml +27 -0
- data/CHANGELOG.md +39 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/CONTRIBUTING.md +37 -0
- data/Gemfile +3 -1
- data/LICENSE.md +1 -0
- data/README.md +115 -5
- data/Rakefile +7 -5
- data/SECURITY.md +58 -0
- data/VERSION +1 -1
- data/deepl-rb.gemspec +36 -20
- data/lib/deepl/api.rb +11 -1
- data/lib/deepl/configuration.rb +34 -3
- data/lib/deepl/document_api.rb +121 -0
- data/lib/deepl/exceptions/authorization_failed.rb +3 -0
- data/lib/deepl/exceptions/bad_request.rb +3 -0
- data/lib/deepl/exceptions/document_translation_error.rb +15 -0
- data/lib/deepl/exceptions/error.rb +6 -0
- data/lib/deepl/exceptions/limit_exceeded.rb +7 -0
- data/lib/deepl/exceptions/not_found.rb +3 -0
- data/lib/deepl/exceptions/not_supported.rb +3 -0
- data/lib/deepl/exceptions/quota_exceeded.rb +3 -0
- data/lib/deepl/exceptions/request_entity_too_large.rb +3 -0
- data/lib/deepl/exceptions/request_error.rb +4 -2
- data/lib/deepl/exceptions/server_error.rb +18 -0
- data/lib/deepl/glossary_api.rb +3 -0
- data/lib/deepl/requests/base.rb +89 -34
- data/lib/deepl/requests/document/download.rb +44 -0
- data/lib/deepl/requests/document/get_status.rb +44 -0
- data/lib/deepl/requests/document/upload.rb +64 -0
- data/lib/deepl/requests/glossary/create.rb +15 -1
- data/lib/deepl/requests/glossary/destroy.rb +8 -1
- data/lib/deepl/requests/glossary/entries.rb +8 -1
- data/lib/deepl/requests/glossary/find.rb +8 -1
- data/lib/deepl/requests/glossary/language_pairs.rb +9 -2
- data/lib/deepl/requests/glossary/list.rb +9 -2
- data/lib/deepl/requests/languages.rb +9 -2
- data/lib/deepl/requests/translate.rb +33 -11
- data/lib/deepl/requests/usage.rb +9 -2
- data/lib/deepl/resources/base.rb +3 -0
- data/lib/deepl/resources/document_handle.rb +57 -0
- data/lib/deepl/resources/document_translation_status.rb +54 -0
- data/lib/deepl/resources/glossary.rb +3 -0
- data/lib/deepl/resources/language.rb +3 -0
- data/lib/deepl/resources/language_pair.rb +3 -0
- data/lib/deepl/resources/text.rb +3 -0
- data/lib/deepl/resources/usage.rb +3 -0
- data/lib/deepl/utils/backoff_timer.rb +46 -0
- data/lib/deepl/utils/exception_builder.rb +18 -13
- data/lib/deepl.rb +47 -0
- data/lib/http_client_options.rb +22 -0
- data/license_checker.sh +8 -0
- data/spec/api/api_spec.rb +8 -4
- data/spec/api/configuration_spec.rb +92 -18
- data/spec/api/deepl_spec.rb +225 -86
- data/spec/fixtures/vcr_cassettes/deepl_document.yml +95 -0
- data/spec/fixtures/vcr_cassettes/deepl_document_download.yml +1214 -0
- data/spec/fixtures/vcr_cassettes/deepl_glossaries.yml +812 -23
- data/spec/fixtures/vcr_cassettes/deepl_languages.yml +28 -17
- data/spec/fixtures/vcr_cassettes/deepl_translate.yml +161 -53
- data/spec/fixtures/vcr_cassettes/deepl_usage.yml +93 -3
- data/spec/fixtures/vcr_cassettes/glossaries.yml +1237 -15
- data/spec/fixtures/vcr_cassettes/languages.yml +159 -44
- data/spec/fixtures/vcr_cassettes/translate_texts.yml +9742 -12
- data/spec/fixtures/vcr_cassettes/usage.yml +134 -2
- data/spec/integration_tests/document_api_spec.rb +155 -0
- data/spec/integration_tests/integration_test_utils.rb +170 -0
- data/spec/requests/glossary/create_spec.rb +23 -13
- data/spec/requests/glossary/destroy_spec.rb +33 -17
- data/spec/requests/glossary/entries_spec.rb +31 -17
- data/spec/requests/glossary/find_spec.rb +31 -17
- data/spec/requests/glossary/language_pairs_spec.rb +17 -7
- data/spec/requests/glossary/list_spec.rb +21 -11
- data/spec/requests/languages_spec.rb +31 -21
- data/spec/requests/translate_spec.rb +125 -131
- data/spec/requests/usage_spec.rb +17 -7
- data/spec/resources/glossary_spec.rb +15 -12
- data/spec/resources/language_pair_spec.rb +10 -7
- data/spec/resources/language_spec.rb +21 -18
- data/spec/resources/text_spec.rb +10 -7
- data/spec/resources/usage_spec.rb +16 -13
- data/spec/spec_helper.rb +63 -6
- metadata +32 -9
@@ -14,7 +14,7 @@ http_interactions:
|
|
14
14
|
Accept:
|
15
15
|
- "*/*"
|
16
16
|
User-Agent:
|
17
|
-
-
|
17
|
+
- deepl-ruby/2.5.3 (darwin23) ruby/3.3.3
|
18
18
|
response:
|
19
19
|
status:
|
20
20
|
code: 200
|
@@ -36,4 +36,136 @@ http_interactions:
|
|
36
36
|
encoding: UTF-8
|
37
37
|
string: '{"character_count":353,"character_limit":500000}'
|
38
38
|
recorded_at: Mon, 17 May 2021 14:18:32 GMT
|
39
|
-
|
39
|
+
- request:
|
40
|
+
method: get
|
41
|
+
uri: https://api-free.deepl.com/v2/usage
|
42
|
+
body:
|
43
|
+
encoding: US-ASCII
|
44
|
+
string: ''
|
45
|
+
headers:
|
46
|
+
Authorization:
|
47
|
+
- DeepL-Auth-Key VALID_TOKEN
|
48
|
+
User-Agent:
|
49
|
+
- deepl-ruby/2.5.3(darwin23) ruby/3.3.3
|
50
|
+
Accept-Encoding:
|
51
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
52
|
+
Accept:
|
53
|
+
- "*/*"
|
54
|
+
response:
|
55
|
+
status:
|
56
|
+
code: 403
|
57
|
+
message: Forbidden
|
58
|
+
headers:
|
59
|
+
Date:
|
60
|
+
- Tue, 02 Jul 2024 13:54:07 GMT
|
61
|
+
Content-Type:
|
62
|
+
- application/json
|
63
|
+
Transfer-Encoding:
|
64
|
+
- chunked
|
65
|
+
Vary:
|
66
|
+
- Accept-Encoding
|
67
|
+
Access-Control-Allow-Origin:
|
68
|
+
- "*"
|
69
|
+
Strict-Transport-Security:
|
70
|
+
- max-age=63072000; includeSubDomains; preload
|
71
|
+
Server-Timing:
|
72
|
+
- l7_lb_tls;dur=101, l7_lb_idle;dur=0, l7_lb_receive;dur=0, l7_lb_total;dur=103
|
73
|
+
Access-Control-Expose-Headers:
|
74
|
+
- Server-Timing, X-Trace-ID
|
75
|
+
X-Trace-Id:
|
76
|
+
- 4dcf2a36b3f14ba89f107449f4b14919
|
77
|
+
body:
|
78
|
+
encoding: ASCII-8BIT
|
79
|
+
string: '{"message":"Wrong endpoint. Use https://api.deepl.com"}'
|
80
|
+
recorded_at: Tue, 02 Jul 2024 13:54:07 GMT
|
81
|
+
- request:
|
82
|
+
method: get
|
83
|
+
uri: https://api.deepl.com/v2/usage
|
84
|
+
body:
|
85
|
+
encoding: US-ASCII
|
86
|
+
string: ''
|
87
|
+
headers:
|
88
|
+
Authorization:
|
89
|
+
- DeepL-Auth-Key VALID_TOKEN
|
90
|
+
User-Agent:
|
91
|
+
- deepl-ruby/2.5.3 (darwin23) ruby/3.3.3
|
92
|
+
Accept-Encoding:
|
93
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
94
|
+
Accept:
|
95
|
+
- "*/*"
|
96
|
+
response:
|
97
|
+
status:
|
98
|
+
code: 200
|
99
|
+
message: OK
|
100
|
+
headers:
|
101
|
+
Date:
|
102
|
+
- Tue, 02 Jul 2024 14:52:05 GMT
|
103
|
+
Content-Type:
|
104
|
+
- application/json
|
105
|
+
Transfer-Encoding:
|
106
|
+
- chunked
|
107
|
+
Vary:
|
108
|
+
- Accept-Encoding
|
109
|
+
Access-Control-Allow-Origin:
|
110
|
+
- "*"
|
111
|
+
X-Cache-Status:
|
112
|
+
- MISS
|
113
|
+
Strict-Transport-Security:
|
114
|
+
- max-age=63072000; includeSubDomains; preload
|
115
|
+
Server-Timing:
|
116
|
+
- l7_lb_tls;dur=112, l7_lb_idle;dur=1, l7_lb_receive;dur=0, l7_lb_total;dur=115
|
117
|
+
Access-Control-Expose-Headers:
|
118
|
+
- Server-Timing, X-Trace-ID
|
119
|
+
X-Trace-Id:
|
120
|
+
- de53f558d38c43748bf83b27f4f0edc9
|
121
|
+
body:
|
122
|
+
encoding: ASCII-8BIT
|
123
|
+
string: '{"character_count":18593,"character_limit":1000000000000}'
|
124
|
+
recorded_at: Tue, 02 Jul 2024 14:52:05 GMT
|
125
|
+
- request:
|
126
|
+
method: get
|
127
|
+
uri: https://api.deepl.com/v2/usage
|
128
|
+
body:
|
129
|
+
encoding: UTF-8
|
130
|
+
string: "{}"
|
131
|
+
headers:
|
132
|
+
Authorization:
|
133
|
+
- DeepL-Auth-Key VALID_TOKEN
|
134
|
+
User-Agent:
|
135
|
+
- deepl-ruby/2.5.3 (darwin23) ruby/3.3.3
|
136
|
+
Content-Type:
|
137
|
+
- application/json
|
138
|
+
Accept-Encoding:
|
139
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
140
|
+
Accept:
|
141
|
+
- "*/*"
|
142
|
+
response:
|
143
|
+
status:
|
144
|
+
code: 200
|
145
|
+
message: OK
|
146
|
+
headers:
|
147
|
+
Date:
|
148
|
+
- Tue, 09 Jul 2024 01:35:37 GMT
|
149
|
+
Content-Type:
|
150
|
+
- application/json
|
151
|
+
Transfer-Encoding:
|
152
|
+
- chunked
|
153
|
+
Vary:
|
154
|
+
- Accept-Encoding
|
155
|
+
Access-Control-Allow-Origin:
|
156
|
+
- "*"
|
157
|
+
X-Cache-Status:
|
158
|
+
- MISS
|
159
|
+
Strict-Transport-Security:
|
160
|
+
- max-age=63072000; includeSubDomains; preload
|
161
|
+
Server-Timing:
|
162
|
+
- l7_lb_tls;dur=137, l7_lb_idle;dur=1, l7_lb_receive;dur=0, l7_lb_total;dur=140
|
163
|
+
Access-Control-Expose-Headers:
|
164
|
+
- Server-Timing, X-Trace-ID
|
165
|
+
X-Trace-Id:
|
166
|
+
- 543309f656244684bb59d30e9dc824b5
|
167
|
+
body:
|
168
|
+
encoding: ASCII-8BIT
|
169
|
+
string: '{"character_count":69328,"character_limit":1000000000000}'
|
170
|
+
recorded_at: Tue, 09 Jul 2024 01:35:37 GMT
|
171
|
+
recorded_with: VCR 6.2.0
|
@@ -0,0 +1,155 @@
|
|
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
|
+
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
|
+
default_lang_args = { source_lang: 'EN', target_lang: 'DE' }
|
20
|
+
include_context 'with temp dir'
|
21
|
+
|
22
|
+
describe '#translate_document' do
|
23
|
+
it 'Translates a document from a filepath' do
|
24
|
+
File.unlink(output_document_path)
|
25
|
+
source_lang = default_lang_args[:source_lang]
|
26
|
+
target_lang = default_lang_args[:target_lang]
|
27
|
+
example_doc_path = example_document_path(source_lang)
|
28
|
+
DeepL.document.translate_document(example_doc_path, output_document_path,
|
29
|
+
source_lang, target_lang, File.basename(example_doc_path),
|
30
|
+
{})
|
31
|
+
output_file_contents = File.read(output_document_path)
|
32
|
+
|
33
|
+
expect(example_document_translation(target_lang)).to eq(output_file_contents)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'Translates a document from a filepath without a filename' do
|
37
|
+
File.unlink(output_document_path)
|
38
|
+
source_lang = default_lang_args[:source_lang]
|
39
|
+
target_lang = default_lang_args[:target_lang]
|
40
|
+
example_doc_path = example_document_path(source_lang)
|
41
|
+
DeepL.document.translate_document(example_doc_path, output_document_path,
|
42
|
+
source_lang, target_lang)
|
43
|
+
output_file_contents = File.read(output_document_path)
|
44
|
+
|
45
|
+
expect(example_document_translation(target_lang)).to eq(output_file_contents)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'Translates a document using the lower-level methods and returns the correct status' do # rubocop:disable RSpec/ExampleLength
|
49
|
+
File.unlink(output_document_path)
|
50
|
+
source_lang = default_lang_args[:source_lang]
|
51
|
+
target_lang = default_lang_args[:target_lang]
|
52
|
+
example_doc_path = example_document_path(source_lang)
|
53
|
+
|
54
|
+
handle = DeepL.document.upload(example_doc_path, source_lang, target_lang,
|
55
|
+
File.basename(example_doc_path), {})
|
56
|
+
doc_status = handle.wait_until_document_translation_finished
|
57
|
+
DeepL.document.download(handle, output_document_path) if doc_status.status != 'error'
|
58
|
+
output_file_contents = File.read(output_document_path)
|
59
|
+
|
60
|
+
expect(example_document_translation(target_lang)).to eq(output_file_contents)
|
61
|
+
expect(doc_status.billed_characters).to eq(example_document_translation(source_lang).length)
|
62
|
+
expect(doc_status.status).to eq('done')
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'Translates a document after retrying the upload once' do # rubocop:disable RSpec/ExampleLength
|
66
|
+
skip 'Only runs on mock server' if real_server?
|
67
|
+
File.unlink(output_document_path)
|
68
|
+
source_lang = default_lang_args[:source_lang]
|
69
|
+
target_lang = default_lang_args[:target_lang]
|
70
|
+
example_doc_path = example_document_path(source_lang)
|
71
|
+
doc_status = nil
|
72
|
+
DeepL.with_session(DeepL::HTTPClientOptions.new({}, nil, enable_ssl_verification: false,
|
73
|
+
read_timeout: 1.0)) do |_session|
|
74
|
+
handle = DeepL.document.upload(example_doc_path, source_lang, target_lang,
|
75
|
+
File.basename(example_doc_path), {}, no_response_header(1))
|
76
|
+
doc_status = handle.wait_until_document_translation_finished
|
77
|
+
DeepL.document.download(handle, output_document_path) if doc_status.status != 'error'
|
78
|
+
end
|
79
|
+
output_file_contents = File.read(output_document_path)
|
80
|
+
|
81
|
+
expect(output_file_contents).to eq(example_document_translation(target_lang))
|
82
|
+
expect(doc_status.billed_characters).to eq(example_document_translation(source_lang).length)
|
83
|
+
expect(doc_status.status).to eq('done')
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'Translates a document after waiting' do # rubocop:disable RSpec/ExampleLength
|
88
|
+
skip 'Only runs on mock server' if real_server?
|
89
|
+
File.unlink(output_document_path)
|
90
|
+
source_lang = default_lang_args[:source_lang]
|
91
|
+
target_lang = default_lang_args[:target_lang]
|
92
|
+
example_doc_path = example_document_path(source_lang)
|
93
|
+
doc_status = nil
|
94
|
+
DeepL.with_session(DeepL::HTTPClientOptions.new({}, nil,
|
95
|
+
enable_ssl_verification: false)) do |_session|
|
96
|
+
handle = DeepL.document.upload(example_doc_path, source_lang, target_lang,
|
97
|
+
File.basename(example_doc_path), {},
|
98
|
+
doc_translation_queue_time_header(2000).merge(doc_translation_translation_time_header(2000))) # rubocop:disable Layout/LineLength
|
99
|
+
doc_status = handle.wait_until_document_translation_finished
|
100
|
+
DeepL.document.download(handle, output_document_path) if doc_status.status != 'error'
|
101
|
+
end
|
102
|
+
output_file_contents = File.read(output_document_path)
|
103
|
+
|
104
|
+
expect(output_file_contents).to eq(example_document_translation(target_lang))
|
105
|
+
expect(doc_status.billed_characters).to eq(example_document_translation(source_lang).length)
|
106
|
+
expect(doc_status.status).to eq('done')
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'Translates a large document' do # rubocop:disable RSpec/ExampleLength
|
110
|
+
skip 'Only runs on mock server' if real_server?
|
111
|
+
File.unlink(output_document_path)
|
112
|
+
source_lang = default_lang_args[:source_lang]
|
113
|
+
target_lang = default_lang_args[:target_lang]
|
114
|
+
example_doc_path = example_large_document_path(source_lang)
|
115
|
+
doc_status = nil
|
116
|
+
DeepL.with_session(DeepL::HTTPClientOptions.new({}, nil,
|
117
|
+
enable_ssl_verification: false)) do |_session|
|
118
|
+
handle = DeepL.document.upload(example_doc_path, source_lang, target_lang,
|
119
|
+
File.basename(example_doc_path), {})
|
120
|
+
doc_status = handle.wait_until_document_translation_finished
|
121
|
+
DeepL.document.download(handle, output_document_path) if doc_status.status != 'error'
|
122
|
+
end
|
123
|
+
output_file_contents = File.read(output_document_path)
|
124
|
+
|
125
|
+
expect(output_file_contents).to eq(example_large_document_translation(target_lang))
|
126
|
+
expect(doc_status.billed_characters).to eq(
|
127
|
+
example_large_document_translation(source_lang).length
|
128
|
+
)
|
129
|
+
expect(doc_status.status).to eq('done')
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'Translates a document with formality set' do # rubocop:disable RSpec/ExampleLength
|
133
|
+
skip 'Only runs on mock server' if real_server?
|
134
|
+
File.unlink(output_document_path)
|
135
|
+
source_lang = default_lang_args[:source_lang]
|
136
|
+
target_lang = default_lang_args[:target_lang]
|
137
|
+
example_doc_path = example_large_document_path(source_lang)
|
138
|
+
doc_status = nil
|
139
|
+
DeepL.with_session(DeepL::HTTPClientOptions.new({}, nil,
|
140
|
+
enable_ssl_verification: false)) do |_session|
|
141
|
+
handle = DeepL.document.upload(example_doc_path, source_lang, target_lang,
|
142
|
+
File.basename(example_doc_path),
|
143
|
+
{ 'formality' => 'prefer_more' })
|
144
|
+
doc_status = handle.wait_until_document_translation_finished
|
145
|
+
DeepL.document.download(handle, output_document_path) if doc_status.status != 'error'
|
146
|
+
end
|
147
|
+
output_file_contents = File.read(output_document_path)
|
148
|
+
|
149
|
+
expect(output_file_contents).to eq(example_large_document_translation(target_lang))
|
150
|
+
expect(doc_status.billed_characters).to eq(
|
151
|
+
example_large_document_translation(source_lang).length
|
152
|
+
)
|
153
|
+
expect(doc_status.status).to eq('done')
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,170 @@
|
|
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
|
+
def expect_proxy_header(response_count)
|
152
|
+
{ 'mock-server-session-expect-proxy' => response_count.to_s,
|
153
|
+
'mock-server-session' => SecureRandom.uuid }
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
shared_context 'with temp dir' do
|
158
|
+
around do |example|
|
159
|
+
Dir.mktmpdir('deepl-rspec-') do |dir|
|
160
|
+
@temp_dir = dir
|
161
|
+
example.run
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
attr_reader :temp_dir, :input_file_base_name, :input_file_extension
|
166
|
+
end
|
167
|
+
|
168
|
+
RSpec.configure do |c|
|
169
|
+
c.include IntegrationTestUtils
|
170
|
+
end
|
@@ -1,8 +1,21 @@
|
|
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.
|
1
4
|
# frozen_string_literal: true
|
2
5
|
|
3
6
|
require 'spec_helper'
|
4
7
|
|
5
8
|
describe DeepL::Requests::Glossary::Create do
|
9
|
+
subject(:create) do
|
10
|
+
described_class.new(api, name, source_lang, target_lang, entries, options)
|
11
|
+
end
|
12
|
+
|
13
|
+
around do |tests|
|
14
|
+
tmp_env = replace_env_preserving_deepl_vars_except_mock_server
|
15
|
+
tests.call
|
16
|
+
ENV.replace(tmp_env)
|
17
|
+
end
|
18
|
+
|
6
19
|
let(:api) { build_deepl_api }
|
7
20
|
let(:name) { 'Mi Glosario' }
|
8
21
|
let(:source_lang) { 'EN' }
|
@@ -15,19 +28,16 @@ describe DeepL::Requests::Glossary::Create do
|
|
15
28
|
end
|
16
29
|
let(:entries_format) { 'tsv' }
|
17
30
|
let(:options) { {} }
|
18
|
-
subject do
|
19
|
-
DeepL::Requests::Glossary::Create.new(api, name, source_lang, target_lang, entries, options)
|
20
|
-
end
|
21
31
|
|
22
32
|
describe '#initialize' do
|
23
|
-
context '
|
24
|
-
it '
|
25
|
-
expect(
|
33
|
+
context 'when building a request' do
|
34
|
+
it 'creates a request object' do
|
35
|
+
expect(create).to be_a(described_class)
|
26
36
|
end
|
27
37
|
|
28
|
-
it '
|
29
|
-
request =
|
30
|
-
|
38
|
+
it 'sets the default value for the entries format if not specified' do
|
39
|
+
request = described_class.new(api, name, source_lang, target_lang,
|
40
|
+
entries, options)
|
31
41
|
expect(request.entries_format).to eq('tsv')
|
32
42
|
end
|
33
43
|
end
|
@@ -38,11 +48,11 @@ describe DeepL::Requests::Glossary::Create do
|
|
38
48
|
VCR.use_cassette('glossaries') { example.call }
|
39
49
|
end
|
40
50
|
|
41
|
-
context '
|
42
|
-
it '
|
43
|
-
glossary =
|
51
|
+
context 'when performing a valid request with two glossary entries' do
|
52
|
+
it 'returns a glossaries object' do
|
53
|
+
glossary = create.request
|
44
54
|
expect(glossary).to be_a(DeepL::Resources::Glossary)
|
45
|
-
expect(glossary.id).to
|
55
|
+
expect(glossary.id).to be_a(String)
|
46
56
|
expect(glossary.name).to eq('Mi Glosario')
|
47
57
|
expect(glossary.ready).to be(true).or be(false)
|
48
58
|
expect(glossary.source_lang).to eq('en')
|
@@ -1,16 +1,26 @@
|
|
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.
|
1
4
|
# frozen_string_literal: true
|
2
5
|
|
3
6
|
require 'spec_helper'
|
4
7
|
|
5
8
|
describe DeepL::Requests::Glossary::Destroy do
|
9
|
+
subject(:destroy) { described_class.new(api, id) }
|
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
|
+
|
6
17
|
let(:api) { build_deepl_api }
|
7
|
-
let(:id) { '
|
8
|
-
subject { DeepL::Requests::Glossary::Destroy.new(api, id) }
|
18
|
+
let(:id) { '9ab5dac2-b7b2-4b4a-808a-e8e305df5ecb' }
|
9
19
|
|
10
20
|
describe '#initialize' do
|
11
|
-
context '
|
12
|
-
it '
|
13
|
-
expect(
|
21
|
+
context 'when building a request' do
|
22
|
+
it 'creates a request object' do
|
23
|
+
expect(destroy).to be_a(described_class)
|
14
24
|
end
|
15
25
|
end
|
16
26
|
end
|
@@ -20,30 +30,36 @@ describe DeepL::Requests::Glossary::Destroy do
|
|
20
30
|
VCR.use_cassette('glossaries') { example.call }
|
21
31
|
end
|
22
32
|
|
23
|
-
context '
|
33
|
+
context 'when performing a valid request' do
|
34
|
+
subject(:destroy) { described_class.new(api, new_glossary.id) }
|
35
|
+
|
24
36
|
let(:new_glossary) do
|
25
37
|
DeepL::Requests::Glossary::Create.new(api, 'fixture', 'EN', 'ES', [%w[Hello Hola]]).request
|
26
38
|
end
|
27
|
-
|
28
|
-
it '
|
29
|
-
response =
|
39
|
+
|
40
|
+
it 'returns an empty object' do
|
41
|
+
response = destroy.request
|
30
42
|
expect(response).to eq(new_glossary.id)
|
31
43
|
end
|
32
44
|
end
|
33
45
|
|
34
|
-
context '
|
46
|
+
context 'when deleting a non existing glossary with a valid id' do
|
47
|
+
subject(:destroy) { described_class.new(api, id) }
|
48
|
+
|
35
49
|
let(:id) { '00000000-0000-0000-0000-000000000000' }
|
36
|
-
|
37
|
-
it '
|
38
|
-
expect {
|
50
|
+
|
51
|
+
it 'raises a not found error' do
|
52
|
+
expect { destroy.request }.to raise_error(DeepL::Exceptions::NotFound)
|
39
53
|
end
|
40
54
|
end
|
41
55
|
|
42
|
-
context '
|
56
|
+
context 'when deleting a non existing glossary with an invalid id' do
|
57
|
+
subject(:destroy) { described_class.new(api, id) }
|
58
|
+
|
43
59
|
let(:id) { 'invalid-uuid' }
|
44
|
-
|
45
|
-
it '
|
46
|
-
expect {
|
60
|
+
|
61
|
+
it 'raises a bad request error' do
|
62
|
+
expect { destroy.request }.to raise_error(DeepL::Exceptions::BadRequest)
|
47
63
|
end
|
48
64
|
end
|
49
65
|
end
|