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.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/add_issues_to_kanban.yml +16 -0
  3. data/.gitlab-ci.yml +135 -0
  4. data/.rubocop.yml +27 -0
  5. data/CHANGELOG.md +39 -0
  6. data/CODE_OF_CONDUCT.md +132 -0
  7. data/CONTRIBUTING.md +37 -0
  8. data/Gemfile +3 -1
  9. data/LICENSE.md +1 -0
  10. data/README.md +115 -5
  11. data/Rakefile +7 -5
  12. data/SECURITY.md +58 -0
  13. data/VERSION +1 -1
  14. data/deepl-rb.gemspec +36 -20
  15. data/lib/deepl/api.rb +11 -1
  16. data/lib/deepl/configuration.rb +34 -3
  17. data/lib/deepl/document_api.rb +121 -0
  18. data/lib/deepl/exceptions/authorization_failed.rb +3 -0
  19. data/lib/deepl/exceptions/bad_request.rb +3 -0
  20. data/lib/deepl/exceptions/document_translation_error.rb +15 -0
  21. data/lib/deepl/exceptions/error.rb +6 -0
  22. data/lib/deepl/exceptions/limit_exceeded.rb +7 -0
  23. data/lib/deepl/exceptions/not_found.rb +3 -0
  24. data/lib/deepl/exceptions/not_supported.rb +3 -0
  25. data/lib/deepl/exceptions/quota_exceeded.rb +3 -0
  26. data/lib/deepl/exceptions/request_entity_too_large.rb +3 -0
  27. data/lib/deepl/exceptions/request_error.rb +4 -2
  28. data/lib/deepl/exceptions/server_error.rb +18 -0
  29. data/lib/deepl/glossary_api.rb +3 -0
  30. data/lib/deepl/requests/base.rb +89 -34
  31. data/lib/deepl/requests/document/download.rb +44 -0
  32. data/lib/deepl/requests/document/get_status.rb +44 -0
  33. data/lib/deepl/requests/document/upload.rb +64 -0
  34. data/lib/deepl/requests/glossary/create.rb +15 -1
  35. data/lib/deepl/requests/glossary/destroy.rb +8 -1
  36. data/lib/deepl/requests/glossary/entries.rb +8 -1
  37. data/lib/deepl/requests/glossary/find.rb +8 -1
  38. data/lib/deepl/requests/glossary/language_pairs.rb +9 -2
  39. data/lib/deepl/requests/glossary/list.rb +9 -2
  40. data/lib/deepl/requests/languages.rb +9 -2
  41. data/lib/deepl/requests/translate.rb +33 -11
  42. data/lib/deepl/requests/usage.rb +9 -2
  43. data/lib/deepl/resources/base.rb +3 -0
  44. data/lib/deepl/resources/document_handle.rb +57 -0
  45. data/lib/deepl/resources/document_translation_status.rb +54 -0
  46. data/lib/deepl/resources/glossary.rb +3 -0
  47. data/lib/deepl/resources/language.rb +3 -0
  48. data/lib/deepl/resources/language_pair.rb +3 -0
  49. data/lib/deepl/resources/text.rb +3 -0
  50. data/lib/deepl/resources/usage.rb +3 -0
  51. data/lib/deepl/utils/backoff_timer.rb +46 -0
  52. data/lib/deepl/utils/exception_builder.rb +18 -13
  53. data/lib/deepl.rb +47 -0
  54. data/lib/http_client_options.rb +22 -0
  55. data/license_checker.sh +8 -0
  56. data/spec/api/api_spec.rb +8 -4
  57. data/spec/api/configuration_spec.rb +92 -18
  58. data/spec/api/deepl_spec.rb +225 -86
  59. data/spec/fixtures/vcr_cassettes/deepl_document.yml +95 -0
  60. data/spec/fixtures/vcr_cassettes/deepl_document_download.yml +1214 -0
  61. data/spec/fixtures/vcr_cassettes/deepl_glossaries.yml +812 -23
  62. data/spec/fixtures/vcr_cassettes/deepl_languages.yml +28 -17
  63. data/spec/fixtures/vcr_cassettes/deepl_translate.yml +161 -53
  64. data/spec/fixtures/vcr_cassettes/deepl_usage.yml +93 -3
  65. data/spec/fixtures/vcr_cassettes/glossaries.yml +1237 -15
  66. data/spec/fixtures/vcr_cassettes/languages.yml +159 -44
  67. data/spec/fixtures/vcr_cassettes/translate_texts.yml +9742 -12
  68. data/spec/fixtures/vcr_cassettes/usage.yml +134 -2
  69. data/spec/integration_tests/document_api_spec.rb +155 -0
  70. data/spec/integration_tests/integration_test_utils.rb +170 -0
  71. data/spec/requests/glossary/create_spec.rb +23 -13
  72. data/spec/requests/glossary/destroy_spec.rb +33 -17
  73. data/spec/requests/glossary/entries_spec.rb +31 -17
  74. data/spec/requests/glossary/find_spec.rb +31 -17
  75. data/spec/requests/glossary/language_pairs_spec.rb +17 -7
  76. data/spec/requests/glossary/list_spec.rb +21 -11
  77. data/spec/requests/languages_spec.rb +31 -21
  78. data/spec/requests/translate_spec.rb +125 -131
  79. data/spec/requests/usage_spec.rb +17 -7
  80. data/spec/resources/glossary_spec.rb +15 -12
  81. data/spec/resources/language_pair_spec.rb +10 -7
  82. data/spec/resources/language_spec.rb +21 -18
  83. data/spec/resources/text_spec.rb +10 -7
  84. data/spec/resources/usage_spec.rb +16 -13
  85. data/spec/spec_helper.rb +63 -6
  86. metadata +32 -9
@@ -14,7 +14,7 @@ http_interactions:
14
14
  Accept:
15
15
  - "*/*"
16
16
  User-Agent:
17
- - Ruby
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
- recorded_with: VCR 6.0.0
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 'When building a request' do
24
- it 'should create a request object' do
25
- expect(subject).to be_a(described_class)
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 'should set the default value for the entries format if not specified' do
29
- request = DeepL::Requests::Glossary::Create.new(api, name, source_lang, target_lang,
30
- entries, options)
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 'When performing a valid request with two glossary entries' do
42
- it 'should return a glossaries object' do
43
- glossary = subject.request
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 be_kind_of(String)
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) { '367eef44-b533-4d95-be19-74950c7760e9' }
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 'When building a request' do
12
- it 'should create a request object' do
13
- expect(subject).to be_a(described_class)
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 'When performing a valid request' do
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
- subject { DeepL::Requests::Glossary::Destroy.new(api, new_glossary.id) }
28
- it 'should return an empty object' do
29
- response = subject.request
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 'When deleting a non existing glossary with a valid id' do
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
- subject { DeepL::Requests::Glossary::Destroy.new(api, id) }
37
- it 'should raise a not found error' do
38
- expect { subject.request }.to raise_error(DeepL::Exceptions::NotFound)
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 'When deleting a non existing glossary with an invalid id' do
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
- subject { DeepL::Requests::Glossary::Destroy.new(api, id) }
45
- it 'should raise a bad request error' do
46
- expect { subject.request }.to raise_error(DeepL::Exceptions::BadRequest)
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