deepl-rb 2.5.3 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 +34 -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 +120 -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 +143 -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
@@ -0,0 +1,54 @@
|
|
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
|
+
module DeepL
|
7
|
+
module Resources
|
8
|
+
class DocumentTranslationStatus < Base
|
9
|
+
attr_reader :document_id, :status, :seconds_remaining, :billed_characters, :error_message
|
10
|
+
|
11
|
+
def initialize(response, *args)
|
12
|
+
super(*args)
|
13
|
+
|
14
|
+
@document_id = response['document_id']
|
15
|
+
@status = response['status']
|
16
|
+
@seconds_remaining = response['seconds_remaining']
|
17
|
+
@billed_characters = response['billed_characters']
|
18
|
+
@error_message = response['error_message']
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
"DocumentTranslationStatus: ID: #{document_id} - Status: #{status} " \
|
23
|
+
"- Error message: #{error_message}"
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# Checks if the translation finished successfully
|
28
|
+
#
|
29
|
+
# @return [true] if so
|
30
|
+
|
31
|
+
def successful?
|
32
|
+
status == 'done'
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Checks if there was an error during translation
|
37
|
+
#
|
38
|
+
# @return [true] if so
|
39
|
+
|
40
|
+
def error?
|
41
|
+
status == 'error'
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Checks if the translation process terminated. Note that this could be due to an error as
|
46
|
+
# well, but means no further waiting is necessary.
|
47
|
+
#
|
48
|
+
# @return [true] if so
|
49
|
+
def finished?
|
50
|
+
successful? || error?
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/deepl/resources/text.rb
CHANGED
@@ -0,0 +1,46 @@
|
|
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
|
+
module DeepL
|
7
|
+
module Utils
|
8
|
+
class BackoffTimer
|
9
|
+
# Implements exponential-backoff strategy.
|
10
|
+
# This strategy is based on the GRPC Connection Backoff Protocol:
|
11
|
+
# https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md
|
12
|
+
|
13
|
+
BACKOFF_INITIAL = 1.0
|
14
|
+
BACKOFF_MAX = 120.0
|
15
|
+
BACKOFF_JITTER = 0.23
|
16
|
+
BACKOFF_MULTIPLIER = 1.6
|
17
|
+
|
18
|
+
attr_reader :num_retries
|
19
|
+
|
20
|
+
def initialize(min_connection_timeout = 10.0)
|
21
|
+
@num_retries = 0
|
22
|
+
@backoff = BACKOFF_INITIAL
|
23
|
+
@deadline = Time.now.to_f + @backoff
|
24
|
+
@min_connection_timeout = min_connection_timeout
|
25
|
+
end
|
26
|
+
|
27
|
+
def current_request_timeout
|
28
|
+
[time_until_deadline, @min_connection_timeout].max
|
29
|
+
end
|
30
|
+
|
31
|
+
def time_until_deadline
|
32
|
+
[@deadline - Time.now.to_f, 0.0].max
|
33
|
+
end
|
34
|
+
|
35
|
+
def sleep_until_deadline
|
36
|
+
sleep(time_until_deadline)
|
37
|
+
# Apply multiplier to current backoff time
|
38
|
+
@backoff = [@backoff * BACKOFF_MULTIPLIER, BACKOFF_MAX].min
|
39
|
+
# Get deadline by applying jitter as a proportion of backoff:
|
40
|
+
# if jitter is 0.1, then multiply backoff by random value in [0.9, 1.1]
|
41
|
+
@deadline = Time.now.to_f + (@backoff * (1 + (BACKOFF_JITTER * rand(-1.0..1.0))))
|
42
|
+
@num_retries += 1
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -1,3 +1,6 @@
|
|
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
|
module DeepL
|
@@ -5,24 +8,26 @@ module DeepL
|
|
5
8
|
class ExceptionBuilder
|
6
9
|
attr_reader :request, :response
|
7
10
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
def self.error_class_from_response_code(code) # rubocop:disable Metrics/CyclomaticComplexity
|
12
|
+
case code
|
13
|
+
when 400 then Exceptions::BadRequest
|
14
|
+
when 401, 403 then Exceptions::AuthorizationFailed
|
15
|
+
when 404 then Exceptions::NotFound
|
16
|
+
when 413 then Exceptions::RequestEntityTooLarge
|
17
|
+
when 429 then Exceptions::LimitExceeded
|
18
|
+
when 456 then Exceptions::QuotaExceeded
|
19
|
+
when 500..599 then Exceptions::ServerError
|
20
|
+
else Exceptions::RequestError
|
21
|
+
end
|
22
|
+
end
|
17
23
|
|
18
|
-
def initialize(
|
19
|
-
@request = request
|
24
|
+
def initialize(response)
|
20
25
|
@response = response
|
21
26
|
end
|
22
27
|
|
23
28
|
def build
|
24
|
-
error_class =
|
25
|
-
error_class.new(
|
29
|
+
error_class = self.class.error_class_from_response_code(response.code.to_i)
|
30
|
+
error_class.new(response)
|
26
31
|
end
|
27
32
|
end
|
28
33
|
end
|
data/lib/deepl.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
# Copyright 2018 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
|
# -- Dependencies
|
@@ -14,9 +17,14 @@ require 'deepl/exceptions/quota_exceeded'
|
|
14
17
|
require 'deepl/exceptions/not_found'
|
15
18
|
require 'deepl/exceptions/not_supported'
|
16
19
|
require 'deepl/exceptions/request_entity_too_large'
|
20
|
+
require 'deepl/exceptions/document_translation_error'
|
21
|
+
require 'deepl/exceptions/server_error'
|
17
22
|
|
18
23
|
# -- Requests
|
19
24
|
require 'deepl/requests/base'
|
25
|
+
require 'deepl/requests/document/download'
|
26
|
+
require 'deepl/requests/document/get_status'
|
27
|
+
require 'deepl/requests/document/upload'
|
20
28
|
require 'deepl/requests/glossary/create'
|
21
29
|
require 'deepl/requests/glossary/destroy'
|
22
30
|
require 'deepl/requests/glossary/entries'
|
@@ -29,6 +37,8 @@ require 'deepl/requests/usage'
|
|
29
37
|
|
30
38
|
# -- Responses and resources
|
31
39
|
require 'deepl/resources/base'
|
40
|
+
require 'deepl/resources/document_handle'
|
41
|
+
require 'deepl/resources/document_translation_status'
|
32
42
|
require 'deepl/resources/glossary'
|
33
43
|
require 'deepl/resources/language'
|
34
44
|
require 'deepl/resources/language_pair'
|
@@ -37,10 +47,15 @@ require 'deepl/resources/usage'
|
|
37
47
|
|
38
48
|
# -- Utils
|
39
49
|
require 'deepl/utils/exception_builder'
|
50
|
+
require 'deepl/utils/backoff_timer'
|
51
|
+
|
52
|
+
# -- HTTP Utils
|
53
|
+
require 'http_client_options'
|
40
54
|
|
41
55
|
# -- Other wrappers
|
42
56
|
require 'deepl/api'
|
43
57
|
require 'deepl/configuration'
|
58
|
+
require 'deepl/document_api'
|
44
59
|
require 'deepl/glossary_api'
|
45
60
|
|
46
61
|
# -- Gem interface
|
@@ -62,6 +77,11 @@ module DeepL
|
|
62
77
|
Requests::Translate.new(api, text, source_lang, target_lang, options).request
|
63
78
|
end
|
64
79
|
|
80
|
+
def document(options = {})
|
81
|
+
configure if @configuration.nil?
|
82
|
+
DocumentApi.new(api, options)
|
83
|
+
end
|
84
|
+
|
65
85
|
def glossaries(options = {})
|
66
86
|
configure if @configuration.nil?
|
67
87
|
GlossaryApi.new(api, options)
|
@@ -72,6 +92,33 @@ module DeepL
|
|
72
92
|
Requests::Usage.new(api, options).request
|
73
93
|
end
|
74
94
|
|
95
|
+
def http_client
|
96
|
+
@http_client
|
97
|
+
end
|
98
|
+
|
99
|
+
def with_session(client_options = HTTPClientOptions.new()) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
100
|
+
raise ArgumentError 'This method requires a block to be passed in which contains the actual API calls, see README for example usage.' unless block_given? # rubocop:disable Layout/LineLength
|
101
|
+
|
102
|
+
has_proxy = client_options.proxy.key?('proxy_addr') and client_options.proxy.key?('proxy_port')
|
103
|
+
begin
|
104
|
+
uri = URI(configuration.host)
|
105
|
+
http = Net::HTTP.new(uri.host, uri.port, has_proxy ? client_options.proxy['proxy_addr'] : nil,
|
106
|
+
has_proxy ? client_options.proxy['proxy_port'] : nil)
|
107
|
+
http.use_ssl = client_options.enable_ssl_verification
|
108
|
+
http.ca_file = client_options.cert_path if client_options.cert_path
|
109
|
+
http.open_timeout = client_options.open_timeout unless client_options.open_timeout.nil?
|
110
|
+
http.read_timeout = client_options.read_timeout unless client_options.read_timeout.nil?
|
111
|
+
http.write_timeout = client_options.write_timeout unless client_options.write_timeout.nil?
|
112
|
+
http.ssl_timeout = client_options.ssl_timeout unless client_options.ssl_timeout.nil?
|
113
|
+
http.start
|
114
|
+
@http_client = http
|
115
|
+
api.update_http_client(http)
|
116
|
+
yield
|
117
|
+
ensure
|
118
|
+
http.finish
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
75
122
|
# -- Configuration
|
76
123
|
|
77
124
|
def configuration
|
@@ -0,0 +1,22 @@
|
|
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
|
+
module DeepL
|
7
|
+
class HTTPClientOptions
|
8
|
+
attr_reader :proxy, :send_platform_info, :enable_ssl_verification, :cert_path, :open_timeout,
|
9
|
+
:read_timeout, :write_timeout, :ssl_timeout
|
10
|
+
|
11
|
+
def initialize(proxy, cert_path, enable_ssl_verification: true, open_timeout: nil, # rubocop:disable Metrics/ParameterLists
|
12
|
+
read_timeout: nil, write_timeout: nil, ssl_timeout: nil)
|
13
|
+
@proxy = proxy
|
14
|
+
@enable_ssl_verification = enable_ssl_verification
|
15
|
+
@cert_path = cert_path
|
16
|
+
@open_timeout = open_timeout
|
17
|
+
@read_timeout = read_timeout
|
18
|
+
@write_timeout = write_timeout
|
19
|
+
@ssl_timeout = ssl_timeout
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/license_checker.sh
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
# Usage: ./license_checker.sh source_code_pattern
|
4
|
+
# Example: ./license_checker.sh '*.rb'
|
5
|
+
# This will search all .rb files, ignoring anything not tracked in your git tree
|
6
|
+
|
7
|
+
git ls-files -z $1 | xargs -0 -n 10 -I{} sh -c 'RES=$(head -n 3 "{}" | grep "Copyright 20[0-9][0-9] DeepL SE (https://www.deepl.com)\|Copyright 20[0-9][0-9] Daniel Herzog"); if [ ! "${RES}" ] ; then echo "Lacking copyright header in" "{}" ; fi'
|
8
|
+
|
data/spec/api/api_spec.rb
CHANGED
@@ -1,15 +1,19 @@
|
|
1
|
+
# Copyright 2018 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::API do
|
9
|
+
subject(:api) { described_class.new(configuration) }
|
10
|
+
|
6
11
|
let(:configuration) { DeepL::Configuration.new }
|
7
|
-
subject { DeepL::API.new(configuration) }
|
8
12
|
|
9
13
|
describe '#initialize' do
|
10
|
-
context '
|
11
|
-
it '
|
12
|
-
expect(
|
14
|
+
context 'when building an API object' do
|
15
|
+
it 'saves the configuration' do
|
16
|
+
expect(api.configuration).to be(configuration)
|
13
17
|
end
|
14
18
|
end
|
15
19
|
end
|
@@ -1,27 +1,101 @@
|
|
1
|
+
# Copyright 2018 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
|
|
6
|
+
require 'logger'
|
3
7
|
require 'spec_helper'
|
4
8
|
|
5
9
|
describe DeepL::Configuration do
|
10
|
+
subject(:config) { described_class.new(attributes) }
|
11
|
+
|
6
12
|
let(:attributes) { {} }
|
7
|
-
|
13
|
+
|
14
|
+
around do |tests|
|
15
|
+
tmp_env = ENV.to_hash
|
16
|
+
ENV.clear
|
17
|
+
tests.call
|
18
|
+
ENV.replace(tmp_env)
|
19
|
+
end
|
8
20
|
|
9
21
|
describe '#initialize' do
|
10
|
-
context '
|
11
|
-
it '
|
12
|
-
expect(
|
13
|
-
expect(
|
14
|
-
expect(
|
22
|
+
context 'when using default configuration attributes' do
|
23
|
+
it 'uses default attributes' do
|
24
|
+
expect(config.auth_key).to eq(ENV.fetch('DEEPL_AUTH_KEY', nil))
|
25
|
+
expect(config.host).to eq('https://api.deepl.com')
|
26
|
+
expect(config.max_doc_status_queries).to be_nil
|
27
|
+
expect(config.version).to eq('v2')
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'sends platform information' do
|
31
|
+
expect(config.user_agent).to include('deepl-ruby/')
|
32
|
+
expect(config.user_agent).to include('(')
|
33
|
+
expect(config.user_agent).to include(')')
|
34
|
+
expect(config.user_agent).to include(' ruby/')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'when using custom configuration attributes' do
|
39
|
+
let(:logger) { Logger.new($stdout) }
|
40
|
+
let(:attributes) { { auth_key: 'SAMPLE', host: 'https://api-free.deepl.com', logger: logger, max_doc_status_queries: 42, max_network_retries: 43, version: 'v1' } }
|
41
|
+
|
42
|
+
it 'uses custom attributes' do
|
43
|
+
expect(config.auth_key).to eq(attributes[:auth_key])
|
44
|
+
expect(config.host).to eq(attributes[:host])
|
45
|
+
expect(config.max_doc_status_queries).to eq(attributes[:max_doc_status_queries])
|
46
|
+
expect(config.max_network_retries).to eq(attributes[:max_network_retries])
|
47
|
+
expect(config.version).to eq(attributes[:version])
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'when using a free key' do
|
52
|
+
let(:attributes) { { auth_key: '123e4567-e89b-12d3-a456-426614174000:fx' } }
|
53
|
+
|
54
|
+
it 'uses the free API URL' do
|
55
|
+
expect(config.host).to eq('https://api-free.deepl.com')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'when using a pro key' do
|
60
|
+
let(:attributes) { { auth_key: '123e4567-e89b-12d3-a456-426614174000' } }
|
61
|
+
|
62
|
+
it 'uses the pro API URL' do
|
63
|
+
expect(config.host).to eq('https://api.deepl.com')
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'when opting out of sending platform info' do
|
68
|
+
subject(:config) { described_class.new(attributes, nil, nil, false) }
|
69
|
+
|
70
|
+
it 'does not send platform information' do
|
71
|
+
expect(config.user_agent).to include('deepl-ruby/')
|
72
|
+
expect(config.user_agent).not_to include('(')
|
73
|
+
expect(config.user_agent).not_to include(')')
|
74
|
+
expect(config.user_agent).not_to include(' ruby/')
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'when registering an app and sending platform info' do
|
79
|
+
subject(:config) { described_class.new(attributes, 'MyTestApp', '0.1.3', true) }
|
80
|
+
|
81
|
+
it 'sends platform and app info' do
|
82
|
+
expect(config.user_agent).to include('deepl-ruby/')
|
83
|
+
expect(config.user_agent).to include('(')
|
84
|
+
expect(config.user_agent).to include(')')
|
85
|
+
expect(config.user_agent).to include(' ruby/')
|
86
|
+
expect(config.user_agent).to include('MyTestApp/0.1.3')
|
15
87
|
end
|
16
88
|
end
|
17
89
|
|
18
|
-
context '
|
19
|
-
|
90
|
+
context 'when registering an app and not sending platform info' do
|
91
|
+
subject(:config) { described_class.new(attributes, 'MyTestApp', '0.1.3', false) }
|
20
92
|
|
21
|
-
it '
|
22
|
-
expect(
|
23
|
-
expect(
|
24
|
-
expect(
|
93
|
+
it 'sends app, but not platform info' do
|
94
|
+
expect(config.user_agent).to include('deepl-ruby/')
|
95
|
+
expect(config.user_agent).not_to include('(')
|
96
|
+
expect(config.user_agent).not_to include(')')
|
97
|
+
expect(config.user_agent).not_to include(' ruby/')
|
98
|
+
expect(config.user_agent).to include('MyTestApp/0.1.3')
|
25
99
|
end
|
26
100
|
end
|
27
101
|
end
|
@@ -29,19 +103,19 @@ describe DeepL::Configuration do
|
|
29
103
|
describe '#validate!' do
|
30
104
|
let(:auth_message) { 'auth_key not provided' }
|
31
105
|
|
32
|
-
context '
|
106
|
+
context 'when providing a valid auth key' do
|
33
107
|
let(:attributes) { { auth_key: '' } }
|
34
108
|
|
35
|
-
it '
|
36
|
-
expect {
|
109
|
+
it 'raises an error' do
|
110
|
+
expect { config.validate! }.to raise_error(DeepL::Exceptions::Error, auth_message)
|
37
111
|
end
|
38
112
|
end
|
39
113
|
|
40
|
-
context '
|
114
|
+
context 'when providing an invalid auth key' do
|
41
115
|
let(:attributes) { { auth_key: 'not-empty' } }
|
42
116
|
|
43
|
-
it '
|
44
|
-
expect {
|
117
|
+
it 'does not raise an error' do
|
118
|
+
expect { config.validate! }.not_to raise_error
|
45
119
|
end
|
46
120
|
end
|
47
121
|
end
|