ruby-lokalise-api 4.1.0 → 4.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61d306f7be49970786734ed94a006a6fd37d54e6919c19eb61390f78ad5acff8
4
- data.tar.gz: ea3a5594f544a876386ffa1d50c1a7ff2a842966ca00811df33f54d9e304106e
3
+ metadata.gz: f15e541afdd5e50a0e9317640b872bb04144dcaa717b2390887546b694e308fd
4
+ data.tar.gz: f34bb8a44f1e8552a0bc83b3f4c15d604500d56ecea503260d6423b047b36dcc
5
5
  SHA512:
6
- metadata.gz: 356f32428e0732321e27bc47f2c63022bea36990fb69886fa2daff9d2016bee3f9b80795c326ef4c090f280e58de51d65e8b5e9c6711b3de2be6bb37ae2b2c01
7
- data.tar.gz: 4d5eb8f4fac05abf181fe793d94b2ec5ca759c004d865bbbd085252e4ac49d5abded9056fe0535bb428e1a1308c858a760d4fedd3a05afa7aebb2c8ec1e8ff3f
6
+ metadata.gz: dbbc75876ec0e0c9f5a611d54520585759d77cb4f13a81126d7f9a45c89852331801054ec973f94a6c0b4e58c0a8ea8c6cb88167e5b4a4b3ac9521531b911a87
7
+ data.tar.gz: 2687c66c1fb1ef0012cac50329b87a7c48118cff98a890e06b7764ccce828a850750b6896d5ace0a6810e8cebb86658bbd333794e6bc94cde725c957b1c968f6
@@ -4,7 +4,7 @@
4
4
  2. [Create a topic branch.][branch]
5
5
  3. Implement your feature or bug fix.
6
6
  4. Don't forget to add specs and make sure they pass by running `rspec .`.
7
- 5. Make sure your code complies with the style guide by running `rubocop`. `rubocop -a` can automatically fix most issues for you.
7
+ 5. Make sure your code complies with the style guide by running `rubocop`. `rubocop -a` can automatically fix most issues for you. Run `rubocop -A` to make it more aggressive.
8
8
  6. If necessary, add documentation for your feature or bug fix.
9
9
  7. Commit and push your changes.
10
10
  8. [Submit a pull request.][pr]
data/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  Official opinionated Ruby interface for the [Lokalise API](https://app.lokalise.com/api2docs/curl/) that represents returned data as Ruby objects.
9
9
 
10
- Looking for a Rails integration? Try the new [lokalise_rails gem](https://github.com/bodrovis/lokalise_rails).
10
+ Looking for a Rails integration? Try the [lokalise_rails gem](https://github.com/bodrovis/lokalise_rails). Also you can use a [lokalise_manager gem](https://github.com/bodrovis/lokalise_manager) which allows to exchange translation files between Lokalise and *any* Ruby script.
11
11
 
12
12
  ## Quickstart
13
13
 
@@ -39,6 +39,12 @@ process = @client.upload_file project_id,
39
39
  process.status
40
40
  ```
41
41
 
42
+ Alternatively instantiate your client with an [OAuth2 token](http://docs.lokalise.com/en/articles/5574713-oauth-2):
43
+
44
+ ```ruby
45
+ @client = Lokalise.oauth_client 'YOUR_OAUTH_TOKEN_HERE'
46
+ ```
47
+
42
48
  ## Usage
43
49
 
44
50
  Detailed documentation can be found at [lokalise.github.io/ruby-lokalise-api](https://lokalise.github.io/ruby-lokalise-api/).
@@ -47,4 +53,4 @@ Detailed documentation can be found at [lokalise.github.io/ruby-lokalise-api](ht
47
53
 
48
54
  This gem is licensed under the [BSD 3 Clause license](https://github.com/lokalise/ruby-lokalise-api/blob/master/LICENSE). Prior to version 4 the license type was MIT.
49
55
 
50
- Copyright (c) [Lokalise team](http://lokalise.co), [Ilya Bodrov](http://bodrovis.tech)
56
+ Copyright (c) [Lokalise team](http://lokalise.co) and [Ilya Bodrov](http://bodrovis.tech)
@@ -23,13 +23,15 @@ require 'ruby-lokalise-api/rest/webhooks'
23
23
 
24
24
  module Lokalise
25
25
  class Client
26
- attr_reader :token
27
- attr_accessor :timeout, :open_timeout
26
+ attr_reader :token, :token_header
27
+ attr_accessor :timeout, :open_timeout, :enable_compression
28
28
 
29
29
  def initialize(token, params = {})
30
30
  @token = token
31
31
  @timeout = params.fetch(:timeout, nil)
32
32
  @open_timeout = params.fetch(:open_timeout, nil)
33
+ @enable_compression = params.fetch(:enable_compression, false)
34
+ @token_header = 'x-api-token'
33
35
  end
34
36
 
35
37
  # rubocop:disable Metrics/ParameterLists
@@ -19,11 +19,12 @@ module Lokalise
19
19
  def initialize(response, params = {})
20
20
  produce_collection_for response
21
21
  populate_pagination_data_for response
22
+ content = response['content']
22
23
  # Project, team id, user id, and branch may not be present in some cases
23
- @project_id = response['content']['project_id']
24
- @team_id = response['content']['team_id']
25
- @user_id = response['content']['user_id']
26
- @branch = response['content']['branch']
24
+ @project_id = content['project_id']
25
+ @team_id = content['team_id']
26
+ @user_id = content['user_id']
27
+ @branch = content['branch']
27
28
  @request_params = params
28
29
  @client = response['client']
29
30
  @path = response['path']
@@ -5,19 +5,25 @@ module Lokalise
5
5
  BASE_URL = 'https://api.lokalise.com/api2/'
6
6
 
7
7
  def connection(client)
8
- options = {
8
+ Faraday.new(options(client), request_params_for(client)) do |faraday|
9
+ faraday.use(:gzip) if client.enable_compression
10
+ faraday.adapter Faraday.default_adapter
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def options(client)
17
+ {
9
18
  headers: {
10
19
  accept: 'application/json',
11
20
  user_agent: "ruby-lokalise-api gem/#{Lokalise::VERSION}",
12
- 'x-api-token': client.token
21
+ client.token_header => client.token
13
22
  },
14
23
  url: BASE_URL
15
24
  }
16
- Faraday.new(options, request_params_for(client)) { |faraday| faraday.adapter Faraday.default_adapter }
17
25
  end
18
26
 
19
- private
20
-
21
27
  # Allows to customize request params per-client
22
28
  def request_params_for(client)
23
29
  {request: {timeout: client.timeout, open_timeout: client.open_timeout}}
@@ -210,7 +210,8 @@
210
210
  "is_fuzzy",
211
211
  "is_reviewed",
212
212
  "words",
213
- "custom_translation_statuses"
213
+ "custom_translation_statuses",
214
+ "task_id"
214
215
  ],
215
216
  "translation_provider": [
216
217
  "provider_id",
@@ -39,7 +39,8 @@ module Lokalise
39
39
  class << self
40
40
  # Create a new error from an HTTP response
41
41
  def from_response(body)
42
- new body['error']['message'].to_s
42
+ msg = body.key?('error') ? body['error']['message'] : body['message']
43
+ new msg.to_s
43
44
  end
44
45
  end
45
46
 
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lokalise
4
+ class OAuthClient < Client
5
+ def initialize(token, params = {})
6
+ super(token, params)
7
+ @token_header = 'Authorization'
8
+ @token = "Bearer #{@token}"
9
+ end
10
+ end
11
+ end
@@ -58,7 +58,8 @@ module Lokalise
58
58
  def respond_with(response, client)
59
59
  body = custom_load response.body
60
60
  uri = Addressable::URI.parse response.env.url
61
- respond_with_error(response.status, body) if body.respond_to?(:has_key?) && body.key?('error')
61
+ status = response.status
62
+ respond_with_error status, body if status.between?(400, 599) || (body.respond_to?(:has_key?) && body.key?('error'))
62
63
  extract_headers_from(response).
63
64
  merge('content' => body,
64
65
  'client' => client,
@@ -74,7 +75,7 @@ module Lokalise
74
75
  end
75
76
 
76
77
  def respond_with_error(code, body)
77
- raise(Lokalise::Error, body['error']) unless Lokalise::Error::ERRORS.key? code
78
+ raise(Lokalise::Error, body['error'] || body) unless Lokalise::Error::ERRORS.key? code
78
79
 
79
80
  raise Lokalise::Error::ERRORS[code].from_response(body)
80
81
  end
@@ -107,10 +107,11 @@ module Lokalise
107
107
  end
108
108
 
109
109
  def produce_resource(model_class, response)
110
+ content = response['content']
110
111
  data_key_singular = data_key_for model_class: model_class
111
- if response['content'].key? data_key_singular
112
- data = response['content'].delete data_key_singular
113
- response['content'].merge! data
112
+ if content.key? data_key_singular
113
+ data = content.delete data_key_singular
114
+ content.merge! data
114
115
  end
115
116
 
116
117
  new response
@@ -156,9 +157,10 @@ module Lokalise
156
157
  # Sometimes there is an `id_key` but it has a value of `null`
157
158
  # (for example when we do not place the actual order but only check its price).
158
159
  # Therefore we must explicitly check if the key is present
159
- return response['content'][id_key] if response['content'].key?(id_key)
160
+ content = response['content']
161
+ return content[id_key] if content.key?(id_key)
160
162
 
161
- response['content'][data_key][id_key]
163
+ content[data_key][id_key]
162
164
  end
163
165
 
164
166
  # Store all resources attributes under the corresponding instance variables.
@@ -6,7 +6,8 @@ module Lokalise
6
6
  supports :update, :destroy, [:reload_data, '', :find]
7
7
 
8
8
  def merge(params = {})
9
- self.class.merge @client, self.class.endpoint(project_id, branch_id, :merge), params
9
+ klass = self.class
10
+ klass.merge @client, klass.endpoint(project_id, branch_id, :merge), params
10
11
  end
11
12
 
12
13
  class << self
@@ -22,7 +22,8 @@ module Lokalise
22
22
  c_r Lokalise::Resources::File, :download, [project_id, 'download'], params
23
23
  end
24
24
 
25
- # Imports translation file to the given project. File data must base64-encoded
25
+ # Imports translation file to the given project. File data must base64-encoded.
26
+ # To encode your data in Base64, use `Base64.strict_encode64()` method.
26
27
  #
27
28
  # @see https://app.lokalise.com/api2docs/curl/#transition-upload-a-file-post
28
29
  # @return [Hash]
@@ -47,9 +47,7 @@ module Lokalise
47
47
  #
48
48
  # @return [Array<String>]
49
49
  def attributes_for(klass)
50
- @attributes ||= begin
51
- YAML.load_file(File.expand_path('../data/attributes.json', __dir__)).freeze
52
- end
50
+ @attributes ||= YAML.load_file(File.expand_path('../data/attributes.json', __dir__)).freeze
53
51
 
54
52
  name = unify klass.name.snakecase
55
53
  @attributes[name]
@@ -22,6 +22,6 @@ class String
22
22
  end
23
23
 
24
24
  def remove_trailing_slash
25
- gsub %r{/\z}, ''
25
+ delete_suffix '/'
26
26
  end
27
27
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Lokalise
4
- VERSION = '4.1.0'
4
+ VERSION = '4.4.0'
5
5
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'faraday'
4
+ require 'faraday_middleware'
4
5
  require 'yaml'
5
6
  require 'addressable'
6
7
 
@@ -62,6 +63,7 @@ require 'ruby-lokalise-api/collections/custom_translation_status'
62
63
  require 'ruby-lokalise-api/collections/webhook'
63
64
 
64
65
  require 'ruby-lokalise-api/client'
66
+ require 'ruby-lokalise-api/oauth_client'
65
67
 
66
68
  module Lokalise
67
69
  class << self
@@ -78,5 +80,19 @@ module Lokalise
78
80
  def reset_client!
79
81
  @client = nil
80
82
  end
83
+
84
+ # Initializes a new OAuthClient object
85
+ #
86
+ # @return [Lokalise::OAuthClient]
87
+ # @param token [String]
88
+ # @param params [Hash]
89
+ def oauth_client(token, params = {})
90
+ @oauth_client ||= Lokalise::OAuthClient.new token, params
91
+ end
92
+
93
+ # Reset the currently set OAuth client
94
+ def reset_oauth_client!
95
+ @oauth_client = nil
96
+ end
81
97
  end
82
98
  end
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.add_dependency 'addressable', '~> 2.5'
26
26
  spec.add_dependency 'faraday', '~> 1.0'
27
+ spec.add_dependency 'faraday_middleware', '~> 1.0'
27
28
  spec.add_dependency 'json', '>= 1.8.0'
28
29
 
29
30
  spec.add_development_dependency 'codecov', '~> 0.1'
@@ -3,6 +3,9 @@
3
3
  RSpec.describe Lokalise::Connection do
4
4
  include described_class
5
5
 
6
+ let(:project_id) { '803826145ba90b42d5d860.46800099' }
7
+ let(:key_id) { 44_596_059 }
8
+
6
9
  before { Lokalise.reset_client! }
7
10
 
8
11
  after do
@@ -10,11 +13,18 @@ RSpec.describe Lokalise::Connection do
10
13
  Faraday.default_adapter = :net_http
11
14
  end
12
15
 
13
- it 'timeouts should not be set by default but the token must be present' do
16
+ it 'Authorization header must be present for OAuth client' do
17
+ conn = connection test_oauth_client
18
+ expect(conn.headers['Authorization']).to eq("Bearer #{test_client.token}")
19
+ expect(conn.headers['X-api-token']).to be_nil
20
+ end
21
+
22
+ it 'timeouts and compression should not be set by default but the token must be present' do
14
23
  conn = connection test_client
15
24
  expect(conn.options.timeout).to be_nil
16
25
  expect(conn.options.open_timeout).to be_nil
17
26
  expect(conn.headers['X-api-token']).to eq(test_client.token)
27
+ expect(conn.builder.handlers).not_to include(FaradayMiddleware::Gzip)
18
28
  end
19
29
 
20
30
  it 'allows to customize timeouts' do
@@ -42,4 +52,38 @@ RSpec.describe Lokalise::Connection do
42
52
  expect(another_conn.builder.adapter).to eq(Faraday::Adapter::Excon)
43
53
  expect(conn.builder.adapter).to eq(Faraday::Adapter::NetHttp)
44
54
  end
55
+
56
+ it 'allows to customize compression' do
57
+ custom_client = Lokalise.client(ENV['LOKALISE_API_TOKEN'], enable_compression: true)
58
+ conn = connection custom_client
59
+ expect(conn.headers['X-api-token']).to eq(custom_client.token)
60
+ expect(conn.builder.handlers).to include(FaradayMiddleware::Gzip)
61
+ end
62
+
63
+ it 'is possible to enable gzip compression' do
64
+ gzip_client = Lokalise.client(ENV['LOKALISE_API_TOKEN'], enable_compression: true)
65
+ keys = VCR.use_cassette('all_keys_gzip') do
66
+ gzip_client.keys project_id
67
+ end.collection
68
+
69
+ expect(keys.first.key_id).to eq(key_id)
70
+ end
71
+
72
+ it 'is possible to disable gzip compression' do
73
+ no_gzip_client = Lokalise.client(ENV['LOKALISE_API_TOKEN'], enable_compression: false)
74
+ keys = VCR.use_cassette('all_keys_no_gzip') do
75
+ no_gzip_client.keys project_id
76
+ end.collection
77
+
78
+ expect(keys.first.key_id).to eq(key_id)
79
+ end
80
+
81
+ it 'gzip compression is off by default' do
82
+ default_gzip_client = Lokalise.client(ENV['LOKALISE_API_TOKEN'])
83
+ keys = VCR.use_cassette('all_keys_default_gzip') do
84
+ default_gzip_client.keys project_id
85
+ end.collection
86
+
87
+ expect(keys.first.key_id).to eq(key_id)
88
+ end
45
89
  end
@@ -15,6 +15,14 @@ RSpec.describe Lokalise::Error do
15
15
  end.to raise_error(described_class)
16
16
  end
17
17
 
18
+ it 'handles an exception when the response does not contain an error key' do
19
+ expect do
20
+ VCR.use_cassette('error_no_error_key') do
21
+ get 'projects', Lokalise.client('invalid')
22
+ end
23
+ end.to raise_error(Lokalise::Error::BadRequest)
24
+ end
25
+
18
26
  it 'raises BadRequest when API token is invalid' do
19
27
  expect do
20
28
  VCR.use_cassette('error_invalid_token') do
@@ -59,26 +59,27 @@ RSpec.describe Lokalise::Client do
59
59
 
60
60
  specify '#translation' do
61
61
  translation = VCR.use_cassette('translation') do
62
- test_client.translation project_id, translation_id
62
+ test_client.translation project_id, 304_581_218
63
63
  end
64
64
 
65
- expect(translation.translation_id).to eq(translation_id)
66
- expect(translation.key_id).to eq(15_571_975)
67
- expect(translation.language_iso).to eq('en')
68
- expect(translation.modified_at).to eq('2019-03-26 16:41:31 (Etc/UTC)')
69
- expect(translation.modified_at_timestamp).to eq(1_553_618_491)
65
+ expect(translation.translation_id).to eq(304_581_218)
66
+ expect(translation.key_id).to eq(44_596_059)
67
+ expect(translation.language_iso).to eq('ru')
68
+ expect(translation.modified_at).to eq('2020-05-15 10:44:42 (Etc/UTC)')
69
+ expect(translation.modified_at_timestamp).to eq(1_589_539_482)
70
70
  expect(translation.modified_by).to eq(20_181)
71
71
  expect(translation.modified_by_email).to eq('bodrovis@protonmail.com')
72
- expect(translation.translation).to eq('RSpec is a testing suite')
72
+ expect(translation.translation).to eq('Сообщение')
73
73
  expect(translation.is_fuzzy).to eq(false)
74
74
  expect(translation.is_reviewed).to eq(false)
75
- expect(translation.words).to eq(5)
75
+ expect(translation.words).to eq(1)
76
76
  expect(translation.custom_translation_statuses).to eq([])
77
+ expect(translation.task_id).to be_nil
77
78
  end
78
79
 
79
80
  specify '#reload_data' do
80
81
  translation = VCR.use_cassette('translation') do
81
- test_client.translation project_id, translation_id
82
+ test_client.translation project_id, 304_581_218
82
83
  end
83
84
 
84
85
  reloaded_translation = VCR.use_cassette('translation') do
@@ -6,6 +6,7 @@ RSpec.describe Lokalise do
6
6
  expect(test_client.token).to eq(ENV['LOKALISE_API_TOKEN'])
7
7
  expect(test_client.timeout).to be_nil
8
8
  expect(test_client.open_timeout).to be_nil
9
+ expect(test_client.enable_compression).to be false
9
10
  end
10
11
 
11
12
  specify '.reset_client!' do
@@ -15,6 +16,21 @@ RSpec.describe Lokalise do
15
16
  expect(current_client).to be_nil
16
17
  end
17
18
 
19
+ specify '.oauth_client' do
20
+ expect(test_oauth_client).to be_an_instance_of(Lokalise::OAuthClient)
21
+ expect(test_oauth_client.token).to eq("Bearer #{ENV['LOKALISE_API_TOKEN']}")
22
+ expect(test_oauth_client.timeout).to be_nil
23
+ expect(test_oauth_client.open_timeout).to be_nil
24
+ expect(test_oauth_client.enable_compression).to be false
25
+ end
26
+
27
+ specify '.reset_oauth_client!' do
28
+ expect(test_oauth_client).to be_an_instance_of(Lokalise::OAuthClient)
29
+ described_class.reset_oauth_client!
30
+ current_oauth_client = described_class.instance_variable_get '@oauth_client'
31
+ expect(current_oauth_client).to be_nil
32
+ end
33
+
18
34
  context 'with client params' do
19
35
  before { described_class.reset_client! }
20
36
 
@@ -29,5 +45,10 @@ RSpec.describe Lokalise do
29
45
  custom_client = described_class.client(ENV['LOKALISE_API_TOKEN'], open_timeout: 100)
30
46
  expect(custom_client.open_timeout).to eq(100)
31
47
  end
48
+
49
+ it 'is possible to customize compression' do
50
+ custom_client = described_class.client(ENV['LOKALISE_API_TOKEN'], enable_compression: true)
51
+ expect(custom_client.enable_compression).to be true
52
+ end
32
53
  end
33
54
  end
@@ -4,4 +4,8 @@ module TestClient
4
4
  def test_client(token = nil, params = {})
5
5
  Lokalise.client(token || ENV['LOKALISE_API_TOKEN'], params)
6
6
  end
7
+
8
+ def test_oauth_client(token = nil, params = {})
9
+ Lokalise.oauth_client(token || ENV['LOKALISE_API_TOKEN'], params)
10
+ end
7
11
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-lokalise-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.0
4
+ version: 4.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ilya Bodrov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-01 00:00:00.000000000 Z
11
+ date: 2021-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: faraday_middleware
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: json
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -238,6 +252,7 @@ files:
238
252
  - lib/ruby-lokalise-api/data/attributes.json
239
253
  - lib/ruby-lokalise-api/error.rb
240
254
  - lib/ruby-lokalise-api/json_handler.rb
255
+ - lib/ruby-lokalise-api/oauth_client.rb
241
256
  - lib/ruby-lokalise-api/request.rb
242
257
  - lib/ruby-lokalise-api/resources/base.rb
243
258
  - lib/ruby-lokalise-api/resources/branch.rb
@@ -334,7 +349,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
334
349
  - !ruby/object:Gem::Version
335
350
  version: '0'
336
351
  requirements: []
337
- rubygems_version: 3.2.11
352
+ rubygems_version: 3.2.26
338
353
  signing_key:
339
354
  specification_version: 4
340
355
  summary: Ruby interface to the Lokalise API
@@ -356,11 +371,11 @@ test_files:
356
371
  - spec/lib/ruby-lokalise-api/rest/screenshots_spec.rb
357
372
  - spec/lib/ruby-lokalise-api/rest/snapshots_spec.rb
358
373
  - spec/lib/ruby-lokalise-api/rest/tasks_spec.rb
359
- - spec/lib/ruby-lokalise-api/rest/teams_spec.rb
360
- - spec/lib/ruby-lokalise-api/rest/team_users_spec.rb
361
374
  - spec/lib/ruby-lokalise-api/rest/team_user_groups_spec.rb
362
- - spec/lib/ruby-lokalise-api/rest/translations_spec.rb
375
+ - spec/lib/ruby-lokalise-api/rest/team_users_spec.rb
376
+ - spec/lib/ruby-lokalise-api/rest/teams_spec.rb
363
377
  - spec/lib/ruby-lokalise-api/rest/translation_providers_spec.rb
378
+ - spec/lib/ruby-lokalise-api/rest/translations_spec.rb
364
379
  - spec/lib/ruby-lokalise-api/rest/webhooks_spec.rb
365
380
  - spec/lib/ruby-lokalise-api/utils/snakecase_spec.rb
366
381
  - spec/lib/ruby-lokalise-api_spec.rb