deepl-rb 3.6.0 → 3.7.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 (131) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +27 -0
  3. data/.github/workflows/add_issues_to_kanban.yml +16 -0
  4. data/.gitlab-ci.yml +177 -0
  5. data/.rubocop.yml +51 -0
  6. data/CHANGELOG.md +40 -3
  7. data/CODE_OF_CONDUCT.md +132 -0
  8. data/CONTRIBUTING.md +37 -0
  9. data/Gemfile +24 -0
  10. data/README.md +153 -22
  11. data/Rakefile +58 -0
  12. data/SECURITY.md +58 -0
  13. data/VERSION +1 -0
  14. data/deepl-rb.gemspec +167 -0
  15. data/lib/deepl/api.rb +22 -0
  16. data/lib/deepl/configuration.rb +59 -0
  17. data/lib/deepl/constants/base_constant.rb +18 -0
  18. data/lib/deepl/constants/formality.rb +16 -0
  19. data/lib/deepl/constants/model_type.rb +14 -0
  20. data/lib/deepl/constants/split_sentences.rb +14 -0
  21. data/lib/deepl/constants/tag_handling.rb +13 -0
  22. data/lib/deepl/constants/tone.rb +20 -0
  23. data/lib/deepl/constants/writing_style.rb +20 -0
  24. data/lib/deepl/document_api.rb +121 -0
  25. data/lib/deepl/exceptions/authorization_failed.rb +14 -0
  26. data/lib/deepl/exceptions/bad_request.rb +16 -0
  27. data/lib/deepl/exceptions/document_translation_error.rb +15 -0
  28. data/lib/deepl/exceptions/error.rb +14 -0
  29. data/lib/deepl/exceptions/limit_exceeded.rb +18 -0
  30. data/lib/deepl/exceptions/not_found.rb +16 -0
  31. data/lib/deepl/exceptions/not_supported.rb +14 -0
  32. data/lib/deepl/exceptions/quota_exceeded.rb +14 -0
  33. data/lib/deepl/exceptions/request_entity_too_large.rb +15 -0
  34. data/lib/deepl/exceptions/request_error.rb +21 -0
  35. data/lib/deepl/exceptions/server_error.rb +18 -0
  36. data/lib/deepl/glossary_api.rb +38 -0
  37. data/lib/deepl/requests/base.rb +212 -0
  38. data/lib/deepl/requests/document/download.rb +44 -0
  39. data/lib/deepl/requests/document/get_status.rb +44 -0
  40. data/lib/deepl/requests/document/upload.rb +75 -0
  41. data/lib/deepl/requests/glossary/create.rb +59 -0
  42. data/lib/deepl/requests/glossary/destroy.rb +37 -0
  43. data/lib/deepl/requests/glossary/entries.rb +37 -0
  44. data/lib/deepl/requests/glossary/find.rb +38 -0
  45. data/lib/deepl/requests/glossary/language_pairs.rb +38 -0
  46. data/lib/deepl/requests/glossary/list.rb +37 -0
  47. data/lib/deepl/requests/languages.rb +37 -0
  48. data/lib/deepl/requests/rephrase.rb +55 -0
  49. data/lib/deepl/requests/style_rule/create.rb +46 -0
  50. data/lib/deepl/requests/style_rule/create_custom_instruction.rb +45 -0
  51. data/lib/deepl/requests/style_rule/destroy.rb +39 -0
  52. data/lib/deepl/requests/style_rule/destroy_custom_instruction.rb +40 -0
  53. data/lib/deepl/requests/style_rule/find.rb +40 -0
  54. data/lib/deepl/requests/style_rule/find_custom_instruction.rb +41 -0
  55. data/lib/deepl/requests/style_rule/list.rb +59 -0
  56. data/lib/deepl/requests/style_rule/update.rb +42 -0
  57. data/lib/deepl/requests/style_rule/update_configured_rules.rb +41 -0
  58. data/lib/deepl/requests/style_rule/update_custom_instruction.rb +47 -0
  59. data/lib/deepl/requests/translate.rb +106 -0
  60. data/lib/deepl/requests/translation_memory/list.rb +58 -0
  61. data/lib/deepl/requests/usage.rb +33 -0
  62. data/lib/deepl/resources/base.rb +17 -0
  63. data/lib/deepl/resources/document_handle.rb +57 -0
  64. data/lib/deepl/resources/document_translation_status.rb +54 -0
  65. data/lib/deepl/resources/glossary.rb +28 -0
  66. data/lib/deepl/resources/language.rb +30 -0
  67. data/lib/deepl/resources/language_pair.rb +23 -0
  68. data/lib/deepl/resources/style_rule.rb +86 -0
  69. data/lib/deepl/resources/text.rb +24 -0
  70. data/lib/deepl/resources/translation_memory.rb +25 -0
  71. data/lib/deepl/resources/usage.rb +27 -0
  72. data/lib/deepl/style_rule_api.rb +61 -0
  73. data/lib/deepl/translation_memory_api.rb +17 -0
  74. data/lib/deepl/utils/backoff_timer.rb +46 -0
  75. data/lib/deepl/utils/exception_builder.rb +34 -0
  76. data/lib/deepl.rb +175 -0
  77. data/lib/http_client_options.rb +22 -0
  78. data/lib/version.rb +8 -0
  79. data/spec/api/api_spec.rb +20 -0
  80. data/spec/api/configuration_spec.rb +122 -0
  81. data/spec/api/deepl_spec.rb +460 -0
  82. data/spec/constants/constants_spec.rb +158 -0
  83. data/spec/fixtures/vcr_cassettes/deepl_document.yml +95 -0
  84. data/spec/fixtures/vcr_cassettes/deepl_document_download.yml +1214 -0
  85. data/spec/fixtures/vcr_cassettes/deepl_glossaries.yml +1163 -0
  86. data/spec/fixtures/vcr_cassettes/deepl_languages.yml +54 -0
  87. data/spec/fixtures/vcr_cassettes/deepl_rephrase.yml +87 -0
  88. data/spec/fixtures/vcr_cassettes/deepl_translate.yml +358 -0
  89. data/spec/fixtures/vcr_cassettes/deepl_usage.yml +129 -0
  90. data/spec/fixtures/vcr_cassettes/glossaries.yml +1702 -0
  91. data/spec/fixtures/vcr_cassettes/languages.yml +229 -0
  92. data/spec/fixtures/vcr_cassettes/rephrase_texts.yml +401 -0
  93. data/spec/fixtures/vcr_cassettes/style_rules.yml +92 -0
  94. data/spec/fixtures/vcr_cassettes/style_rules_crud.yml +926 -0
  95. data/spec/fixtures/vcr_cassettes/translate_texts.yml +10630 -0
  96. data/spec/fixtures/vcr_cassettes/translation_memories.yml +74 -0
  97. data/spec/fixtures/vcr_cassettes/usage.yml +171 -0
  98. data/spec/integration_tests/document_api_spec.rb +178 -0
  99. data/spec/integration_tests/integration_test_utils.rb +170 -0
  100. data/spec/integration_tests/style_rule_api_spec.rb +135 -0
  101. data/spec/integration_tests/translation_memory_api_spec.rb +70 -0
  102. data/spec/requests/extra_body_parameters_types_spec.rb +82 -0
  103. data/spec/requests/glossary/create_spec.rb +65 -0
  104. data/spec/requests/glossary/destroy_spec.rb +66 -0
  105. data/spec/requests/glossary/entries_spec.rb +62 -0
  106. data/spec/requests/glossary/find_spec.rb +68 -0
  107. data/spec/requests/glossary/language_pairs_spec.rb +40 -0
  108. data/spec/requests/glossary/list_spec.rb +54 -0
  109. data/spec/requests/languages_spec.rb +68 -0
  110. data/spec/requests/rephrase_spec.rb +172 -0
  111. data/spec/requests/style_rule/create_custom_instruction_spec.rb +54 -0
  112. data/spec/requests/style_rule/create_spec.rb +45 -0
  113. data/spec/requests/style_rule/destroy_custom_instruction_spec.rb +54 -0
  114. data/spec/requests/style_rule/destroy_spec.rb +54 -0
  115. data/spec/requests/style_rule/find_custom_instruction_spec.rb +56 -0
  116. data/spec/requests/style_rule/find_spec.rb +56 -0
  117. data/spec/requests/style_rule/list_spec.rb +58 -0
  118. data/spec/requests/style_rule/update_configured_rules_spec.rb +52 -0
  119. data/spec/requests/style_rule/update_custom_instruction_spec.rb +58 -0
  120. data/spec/requests/style_rule/update_spec.rb +48 -0
  121. data/spec/requests/translate_spec.rb +492 -0
  122. data/spec/requests/translation_memory/list_spec.rb +61 -0
  123. data/spec/requests/usage_spec.rb +43 -0
  124. data/spec/resources/glossary_spec.rb +38 -0
  125. data/spec/resources/language_pair_spec.rb +23 -0
  126. data/spec/resources/language_spec.rb +45 -0
  127. data/spec/resources/text_spec.rb +23 -0
  128. data/spec/resources/translation_memory_spec.rb +35 -0
  129. data/spec/resources/usage_spec.rb +35 -0
  130. data/spec/spec_helper.rb +92 -0
  131. metadata +130 -3
@@ -0,0 +1,68 @@
1
+ # Copyright 2021 Daniel Herzog
2
+ # Use of this source code is governed by an MIT
3
+ # license that can be found in the LICENSE.md file.
4
+ # frozen_string_literal: true
5
+
6
+ require 'spec_helper'
7
+
8
+ describe DeepL::Requests::Languages do
9
+ subject(:languages_obj) { described_class.new(api, options) }
10
+
11
+ around do |tests|
12
+ tmp_env = replace_env_preserving_deepl_vars_except_mock_server
13
+ tests.call
14
+ ENV.replace(tmp_env)
15
+ end
16
+
17
+ let(:api) { build_deepl_api }
18
+ let(:options) { {} }
19
+
20
+ describe '#initialize' do
21
+ context 'when building a request' do
22
+ it 'creates a request object' do
23
+ expect(languages_obj).to be_a(described_class)
24
+ end
25
+ end
26
+ end
27
+
28
+ describe '#request' do
29
+ around do |example|
30
+ VCR.use_cassette('languages') { example.call }
31
+ end
32
+
33
+ context 'when requesting source languages' do
34
+ it 'returns a valid list of source languages' do
35
+ languages = languages_obj.request
36
+
37
+ expect(languages).to be_an(Array)
38
+ expect(languages.size).to eq(29)
39
+ expect(languages).to(be_any { |l| l.code == 'EN' && l.name == 'English' })
40
+ expect(languages).to(be_any { |l| l.code == 'ES' && l.name == 'Spanish' })
41
+ end
42
+ end
43
+
44
+ context 'when requesting target languages' do
45
+ let(:options) { { type: :target } }
46
+
47
+ it 'returns a valid list of target languages' do
48
+ languages = languages_obj.request
49
+
50
+ expect(languages).to be_an(Array)
51
+ expect(languages.size).to eq(31)
52
+ expect(languages).not_to(be_any { |l| l.code == 'EN' && l.name == 'English' })
53
+ expect(languages).to(be_any { |l| l.code == 'ES' && l.name == 'Spanish' })
54
+ expect(languages)
55
+ .to(be_any { |l| l.code == 'EN-US' && l.name == 'English (American)' })
56
+ end
57
+ end
58
+
59
+ context 'when using an invalid type' do
60
+ let(:options) { { type: :invalid } }
61
+
62
+ it 'returns an usage object' do
63
+ message = "Parameter 'type' is invalid. 'source' and 'target' are valid values."
64
+ expect { languages_obj.request }.to raise_error(DeepL::Exceptions::BadRequest, message)
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,172 @@
1
+ # Copyright 2025 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.md file.
4
+ # frozen_string_literal: true
5
+
6
+ require 'spec_helper'
7
+
8
+ describe DeepL::Requests::Rephrase do
9
+ subject(:rephrase) { described_class.new(api, text, target_lang, writing_style, tone, options) }
10
+
11
+ around do |tests|
12
+ tmp_env = replace_env_preserving_deepl_vars_except_mock_server
13
+ tests.call
14
+ ENV.replace(tmp_env)
15
+ end
16
+
17
+ let(:api) { build_deepl_api }
18
+ let(:text) do
19
+ 'As Gregor Samsa awoke one morning from uneasy dreams he found himself transformed.'
20
+ end
21
+ let(:target_lang) { 'EN' }
22
+ let(:writing_style) { nil }
23
+ let(:tone) { nil }
24
+ let(:options) { {} }
25
+
26
+ describe '#request' do
27
+ around do |example|
28
+ VCR.use_cassette('rephrase_texts') { example.call }
29
+ end
30
+
31
+ context 'without a style or tone applied' do
32
+ context 'with a string as input' do
33
+ it 'returns a valid response as a DeepL Text resource' do
34
+ original_length = text.length
35
+ response_text = rephrase.request
36
+
37
+ expect(response_text).to be_a(DeepL::Resources::Text)
38
+ expect(response_text.text.length).not_to eq(original_length)
39
+ expect(response_text.detected_source_language.upcase).to eq('EN')
40
+ end
41
+ end
42
+
43
+ context 'with an array of texts as input' do
44
+ let(:text) do
45
+ [
46
+ 'As Gregor Samsa awoke one morning from uneasy dreams he found himself transformed.',
47
+ 'He lay on his armour-like back, and if he lifted his head a little'
48
+ ]
49
+ end
50
+
51
+ it 'returns a valid response as an array of DeepL Text resources' do
52
+ response_texts = rephrase.request
53
+
54
+ expect(response_texts).to all(be_a(DeepL::Resources::Text))
55
+ response_texts.each_with_index do |response_text, index|
56
+ expect(response_text.text.length).not_to eq(text[index].length)
57
+ expect(response_text.detected_source_language.upcase).to eq('EN')
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ context 'with a valid tone applied' do
64
+ let(:tone) { 'friendly' }
65
+
66
+ context 'with a string as input' do
67
+ it 'returns a valid response with a string as text input' do
68
+ original_length = text.length
69
+ response_text = rephrase.request
70
+
71
+ expect(response_text).to be_a(DeepL::Resources::Text)
72
+ expect(response_text.text.length).not_to eq(original_length)
73
+ expect(response_text.detected_source_language.upcase).to eq('EN')
74
+ end
75
+ end
76
+
77
+ context 'with an array of texts as input' do
78
+ let(:text) do
79
+ [
80
+ 'As Gregor Samsa awoke one morning from uneasy dreams he found himself transformed.',
81
+ 'He lay on his armour-like back, and if he lifted his head a little'
82
+ ]
83
+ end
84
+
85
+ it 'returns an array of valid text objects' do
86
+ response_texts = rephrase.request
87
+
88
+ expect(response_texts).to all(be_a(DeepL::Resources::Text))
89
+ response_texts.each_with_index do |response_text, index|
90
+ expect(response_text.text.length).not_to eq(text[index].length)
91
+ expect(response_text.detected_source_language.upcase).to eq('EN')
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ context 'with a valid writing style applied' do
98
+ let(:writing_style) { 'business' }
99
+
100
+ context 'with a string as input' do
101
+ it 'returns a valid response with a string as text input' do
102
+ original_length = text.length
103
+ response_text = rephrase.request
104
+
105
+ expect(response_text).to be_a(DeepL::Resources::Text)
106
+ expect(response_text.text.length).not_to eq(original_length)
107
+ expect(response_text.detected_source_language.upcase).to eq('EN')
108
+ end
109
+ end
110
+
111
+ context 'with an array of texts as input' do
112
+ let(:text) do
113
+ [
114
+ 'As Gregor Samsa awoke one morning from uneasy dreams he found himself transformed.',
115
+ 'He lay on his armour-like back, and if he lifted his head a little'
116
+ ]
117
+ end
118
+
119
+ it 'returns an array of valid text objects' do
120
+ response_texts = rephrase.request
121
+
122
+ expect(response_texts).to all(be_a(DeepL::Resources::Text))
123
+ response_texts.each_with_index do |response_text, index|
124
+ expect(response_text.text.length).not_to eq(text[index].length)
125
+ expect(response_text.detected_source_language.upcase).to eq('EN')
126
+ end
127
+ end
128
+ end
129
+ end
130
+
131
+ context 'with a writing style or tone from the provided constants applied' do
132
+ let(:writing_style) { DeepL::Constants::WritingStyle::BUSINESS }
133
+ let(:tone) { DeepL::Constants::Tone::FRIENDLY }
134
+
135
+ it 'has the correct writing style and tone applied' do
136
+ expect(rephrase.writing_style).to eq('business')
137
+ expect(rephrase.tone).to eq('friendly')
138
+ end
139
+ end
140
+
141
+ context 'with an invalid writing style applied' do
142
+ let(:writing_style) { 'angry' }
143
+
144
+ it 'raises a bad request error' do
145
+ expect { rephrase.request }.to raise_error(DeepL::Exceptions::BadRequest)
146
+ end
147
+ end
148
+
149
+ context 'when both writing style and tone are applied' do
150
+ let(:writing_style) { 'business' }
151
+ let(:tone) { 'friendly' }
152
+
153
+ it 'raises a bad request error' do
154
+ expect { rephrase.request }.to raise_error(DeepL::Exceptions::BadRequest)
155
+ end
156
+ end
157
+
158
+ context 'when performing a bad request' do
159
+ context 'when using an invalid token' do
160
+ let(:api) do
161
+ api = build_deepl_api
162
+ api.configuration.auth_key = 'invalid'
163
+ api
164
+ end
165
+
166
+ it 'raises an unauthorized error' do
167
+ expect { rephrase.request }.to raise_error(DeepL::Exceptions::AuthorizationFailed)
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,54 @@
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.md file.
4
+ # frozen_string_literal: true
5
+
6
+ require 'spec_helper'
7
+
8
+ describe DeepL::Requests::StyleRule::CreateCustomInstruction do
9
+ subject(:create_instruction) { described_class.new(api, style_id, label, prompt, nil, options) }
10
+
11
+ around do |tests|
12
+ tmp_env = replace_env_preserving_deepl_vars_except_mock_server
13
+ tests.call
14
+ ENV.replace(tmp_env)
15
+ end
16
+
17
+ let(:api) { build_deepl_api }
18
+ let(:style_id) { 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4' }
19
+ let(:label) { 'Test Instruction' }
20
+ let(:prompt) { 'Always use formal language' }
21
+ let(:options) { {} }
22
+
23
+ describe '#initialize' do
24
+ context 'when building a request' do
25
+ it 'creates a request object' do
26
+ expect(create_instruction).to be_a(described_class)
27
+ end
28
+ end
29
+ end
30
+
31
+ describe '#request' do
32
+ around do |example|
33
+ VCR.use_cassette('style_rules_crud') { example.call }
34
+ end
35
+
36
+ context 'when performing a valid request' do
37
+ subject(:create_instruction) do
38
+ described_class.new(api, new_rule.style_id, label, prompt)
39
+ end
40
+
41
+ let(:new_rule) do
42
+ DeepL::Requests::StyleRule::Create.new(api, 'Instruction Test', 'en').request
43
+ end
44
+
45
+ it 'returns a custom instruction object' do
46
+ instruction = create_instruction.request
47
+ expect(instruction).to be_a(DeepL::Resources::CustomInstruction)
48
+ expect(instruction.id).to be_a(String)
49
+ expect(instruction.label).to eq('Test Instruction')
50
+ expect(instruction.prompt).to eq('Always use formal language')
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,45 @@
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.md file.
4
+ # frozen_string_literal: true
5
+
6
+ require 'spec_helper'
7
+
8
+ describe DeepL::Requests::StyleRule::Create do
9
+ subject(:create) { described_class.new(api, name, language, options) }
10
+
11
+ around do |tests|
12
+ tmp_env = replace_env_preserving_deepl_vars_except_mock_server
13
+ tests.call
14
+ ENV.replace(tmp_env)
15
+ end
16
+
17
+ let(:api) { build_deepl_api }
18
+ let(:name) { 'Test Style Rule' }
19
+ let(:language) { 'en' }
20
+ let(:options) { {} }
21
+
22
+ describe '#initialize' do
23
+ context 'when building a request' do
24
+ it 'creates a request object' do
25
+ expect(create).to be_a(described_class)
26
+ end
27
+ end
28
+ end
29
+
30
+ describe '#request' do
31
+ around do |example|
32
+ VCR.use_cassette('style_rules_crud') { example.call }
33
+ end
34
+
35
+ context 'when performing a valid request' do
36
+ it 'returns a style rule object' do
37
+ style_rule = create.request
38
+ expect(style_rule).to be_a(DeepL::Resources::StyleRule)
39
+ expect(style_rule.style_id).to be_a(String)
40
+ expect(style_rule.name).to eq('Test Style Rule')
41
+ expect(style_rule.language).to eq('en')
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,54 @@
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.md file.
4
+ # frozen_string_literal: true
5
+
6
+ require 'spec_helper'
7
+
8
+ describe DeepL::Requests::StyleRule::DestroyCustomInstruction do
9
+ subject(:destroy_instruction) { described_class.new(api, style_id, instruction_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
+
17
+ let(:api) { build_deepl_api }
18
+ let(:style_id) { 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4' }
19
+ let(:instruction_id) { 'test-instruction-id' }
20
+
21
+ describe '#initialize' do
22
+ context 'when building a request' do
23
+ it 'creates a request object' do
24
+ expect(destroy_instruction).to be_a(described_class)
25
+ end
26
+ end
27
+ end
28
+
29
+ describe '#request' do
30
+ around do |example|
31
+ VCR.use_cassette('style_rules_crud') { example.call }
32
+ end
33
+
34
+ context 'when performing a valid request' do
35
+ subject(:destroy_instruction) do
36
+ described_class.new(api, new_rule.style_id, new_instruction.id)
37
+ end
38
+
39
+ let(:new_rule) do
40
+ DeepL::Requests::StyleRule::Create.new(api, 'Destroy Instruction Test', 'en').request
41
+ end
42
+ let(:new_instruction) do
43
+ DeepL::Requests::StyleRule::CreateCustomInstruction.new(
44
+ api, new_rule.style_id, 'To Delete', 'Delete me'
45
+ ).request
46
+ end
47
+
48
+ it 'returns the deleted instruction id' do
49
+ response = destroy_instruction.request
50
+ expect(response).to eq(new_instruction.id)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,54 @@
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.md file.
4
+ # frozen_string_literal: true
5
+
6
+ require 'spec_helper'
7
+
8
+ describe DeepL::Requests::StyleRule::Destroy do
9
+ subject(:destroy) { described_class.new(api, style_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
+
17
+ let(:api) { build_deepl_api }
18
+ let(:style_id) { 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4' }
19
+
20
+ describe '#initialize' do
21
+ context 'when building a request' do
22
+ it 'creates a request object' do
23
+ expect(destroy).to be_a(described_class)
24
+ end
25
+ end
26
+ end
27
+
28
+ describe '#request' do
29
+ around do |example|
30
+ VCR.use_cassette('style_rules_crud') { example.call }
31
+ end
32
+
33
+ context 'when performing a valid request' do
34
+ subject(:destroy) { described_class.new(api, new_rule.style_id) }
35
+
36
+ let(:new_rule) do
37
+ DeepL::Requests::StyleRule::Create.new(api, 'Destroy Test', 'en').request
38
+ end
39
+
40
+ it 'returns the deleted style rule id' do
41
+ response = destroy.request
42
+ expect(response).to eq(new_rule.style_id)
43
+ end
44
+ end
45
+
46
+ context 'when deleting a non existing style rule with an invalid id' do
47
+ let(:style_id) { 'invalid-uuid' }
48
+
49
+ it 'raises an error' do
50
+ expect { destroy.request }.to raise_error(DeepL::Exceptions::Error)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,56 @@
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.md file.
4
+ # frozen_string_literal: true
5
+
6
+ require 'spec_helper'
7
+
8
+ describe DeepL::Requests::StyleRule::FindCustomInstruction do
9
+ subject(:find_instruction) { described_class.new(api, style_id, instruction_id, options) }
10
+
11
+ around do |tests|
12
+ tmp_env = replace_env_preserving_deepl_vars_except_mock_server
13
+ tests.call
14
+ ENV.replace(tmp_env)
15
+ end
16
+
17
+ let(:api) { build_deepl_api }
18
+ let(:style_id) { 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4' }
19
+ let(:instruction_id) { 'test-instruction-id' }
20
+ let(:options) { {} }
21
+
22
+ describe '#initialize' do
23
+ context 'when building a request' do
24
+ it 'creates a request object' do
25
+ expect(find_instruction).to be_a(described_class)
26
+ end
27
+ end
28
+ end
29
+
30
+ describe '#request' do
31
+ around do |example|
32
+ VCR.use_cassette('style_rules_crud') { example.call }
33
+ end
34
+
35
+ context 'when performing a valid request' do
36
+ subject(:find_instruction) do
37
+ described_class.new(api, new_rule.style_id, new_instruction.id)
38
+ end
39
+
40
+ let(:new_rule) do
41
+ DeepL::Requests::StyleRule::Create.new(api, 'Find Instruction Test', 'en').request
42
+ end
43
+ let(:new_instruction) do
44
+ DeepL::Requests::StyleRule::CreateCustomInstruction.new(
45
+ api, new_rule.style_id, 'Test', 'Test prompt'
46
+ ).request
47
+ end
48
+
49
+ it 'returns a custom instruction object' do
50
+ instruction = find_instruction.request
51
+ expect(instruction).to be_a(DeepL::Resources::CustomInstruction)
52
+ expect(instruction.id).to eq(new_instruction.id)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,56 @@
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.md file.
4
+ # frozen_string_literal: true
5
+
6
+ require 'spec_helper'
7
+
8
+ describe DeepL::Requests::StyleRule::Find do
9
+ subject(:style_rule_find) { described_class.new(api, style_id, options) }
10
+
11
+ around do |tests|
12
+ tmp_env = replace_env_preserving_deepl_vars_except_mock_server
13
+ tests.call
14
+ ENV.replace(tmp_env)
15
+ end
16
+
17
+ let(:api) { build_deepl_api }
18
+ let(:style_id) { 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4' }
19
+ let(:options) { {} }
20
+
21
+ describe '#initialize' do
22
+ context 'when building a request' do
23
+ it 'creates a request object' do
24
+ expect(style_rule_find).to be_a(described_class)
25
+ end
26
+ end
27
+ end
28
+
29
+ describe '#request' do
30
+ around do |example|
31
+ VCR.use_cassette('style_rules_crud') { example.call }
32
+ end
33
+
34
+ context 'when performing a valid request' do
35
+ subject(:style_rule_find) do
36
+ new_rule = DeepL::Requests::StyleRule::Create.new(api, 'Find Test', 'en').request
37
+ described_class.new(api, new_rule.style_id, options)
38
+ end
39
+
40
+ it 'returns a style rule object' do
41
+ style_rule = style_rule_find.request
42
+ expect(style_rule).to be_a(DeepL::Resources::StyleRule)
43
+ expect(style_rule.style_id).to be_a(String)
44
+ expect(style_rule.name).to be_a(String)
45
+ end
46
+ end
47
+
48
+ context 'when requesting a non existing style rule with an invalid id' do
49
+ let(:style_id) { 'invalid-uuid' }
50
+
51
+ it 'raises an error' do
52
+ expect { style_rule_find.request }.to raise_error(DeepL::Exceptions::Error)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,58 @@
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.md file.
4
+ # frozen_string_literal: true
5
+
6
+ require 'spec_helper'
7
+
8
+ describe DeepL::Requests::StyleRule::List do
9
+ subject(:style_rule_list) { described_class.new(api, options) }
10
+
11
+ around do |tests|
12
+ tmp_env = replace_env_preserving_deepl_vars_except_mock_server
13
+ tests.call
14
+ ENV.replace(tmp_env)
15
+ end
16
+
17
+ let(:api) { build_deepl_api }
18
+ let(:options) { {} }
19
+
20
+ describe '#initialize' do
21
+ context 'when building a request' do
22
+ it 'creates a request object' do
23
+ expect(style_rule_list).to be_a(described_class)
24
+ end
25
+ end
26
+ end
27
+
28
+ describe '#request' do
29
+ around do |example|
30
+ VCR.use_cassette('style_rules') { example.call }
31
+ end
32
+
33
+ context 'when requesting a list of all style rules' do
34
+ it 'returns an array of style rules' do
35
+ style_rules = style_rule_list.request
36
+ expect(style_rules).to be_an(Array)
37
+ expect(style_rules).not_to be_empty
38
+ expect(style_rules.first).to be_a(DeepL::Resources::StyleRule)
39
+ expect(style_rules.first.style_id).to be_a(String)
40
+ expect(style_rules.first.name).to be_a(String)
41
+ end
42
+ end
43
+
44
+ context 'when performing a bad request' do
45
+ context 'when using an invalid token' do
46
+ let(:api) do
47
+ api = build_deepl_api
48
+ api.configuration.auth_key = 'invalid'
49
+ api
50
+ end
51
+
52
+ it 'raises an authorization failed error' do
53
+ expect { style_rule_list.request }.to raise_error(DeepL::Exceptions::AuthorizationFailed)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,52 @@
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.md file.
4
+ # frozen_string_literal: true
5
+
6
+ require 'spec_helper'
7
+
8
+ describe DeepL::Requests::StyleRule::UpdateConfiguredRules do
9
+ subject(:update_configured_rules) do
10
+ described_class.new(api, style_id, configured_rules, 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
+
19
+ let(:api) { build_deepl_api }
20
+ let(:style_id) { 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4' }
21
+ let(:configured_rules) { { 'dates_and_times' => { 'calendar_era' => 'use_bc_and_ad' } } }
22
+ let(:options) { {} }
23
+
24
+ describe '#initialize' do
25
+ context 'when building a request' do
26
+ it 'creates a request object' do
27
+ expect(update_configured_rules).to be_a(described_class)
28
+ end
29
+ end
30
+ end
31
+
32
+ describe '#request' do
33
+ around do |example|
34
+ VCR.use_cassette('style_rules_crud') { example.call }
35
+ end
36
+
37
+ context 'when performing a valid request' do
38
+ subject(:update_configured_rules) do
39
+ described_class.new(api, new_rule.style_id, configured_rules)
40
+ end
41
+
42
+ let(:new_rule) do
43
+ DeepL::Requests::StyleRule::Create.new(api, 'Configured Rules Test', 'en').request
44
+ end
45
+
46
+ it 'returns a style rule object' do
47
+ style_rule = update_configured_rules.request
48
+ expect(style_rule).to be_a(DeepL::Resources::StyleRule)
49
+ end
50
+ end
51
+ end
52
+ end