lokalise_rails 1.2.0 → 2.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -0
- data/README.md +5 -2
- data/lib/generators/templates/lokalise_rails_config.rb +3 -0
- data/lib/lokalise_rails.rb +7 -1
- data/lib/lokalise_rails/error.rb +10 -0
- data/lib/lokalise_rails/task_definition/base.rb +6 -5
- data/lib/lokalise_rails/task_definition/exporter.rb +18 -10
- data/lib/lokalise_rails/task_definition/importer.rb +5 -8
- data/lib/lokalise_rails/version.rb +1 -1
- data/lib/tasks/lokalise_rails_tasks.rake +4 -0
- data/lokalise_rails.gemspec +4 -4
- data/spec/dummy/config/environments/test.rb +1 -3
- data/spec/lib/lokalise_rails/task_definition/base_spec.rb +5 -9
- data/spec/lib/lokalise_rails/task_definition/exporter_spec.rb +45 -10
- data/spec/lib/lokalise_rails/task_definition/importer_spec.rb +14 -8
- data/spec/lib/lokalise_rails_spec.rb +5 -0
- data/spec/lib/tasks/export_task_spec.rb +37 -0
- data/spec/lib/tasks/import_task_spec.rb +13 -0
- data/spec/spec_helper.rb +0 -1
- data/spec/support/file_manager.rb +17 -9
- data/spec/support/spec_addons.rb +1 -1
- metadata +14 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8c05601cd8f8684c1523aa4b92d87d10afad700c50d197e40b6886fd4bc9412
|
4
|
+
data.tar.gz: ddc3d0616655b4bda4a40ecf1a96af9c17c5ef54d7c372a05bdf9eb29c2dcdee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1bfb463dbed7826bf9cad245c53cca76b5ec0c0bc35ddeb42c24c0e9789e93d77adf45e12c772dfcb764e60ffbe3724ecbebb0106bbead653030db1a458df275
|
7
|
+
data.tar.gz: aadd4c0108d6871683c90f4d0d8647f80f072a34e0d4597ec9d4fcb97a9e9494e085b6fe93481925d71a594e0a110ef6575d0499ede0e407d517727bdb0b9baf
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,32 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 2.0.0.rc1 (12-Aug-21)
|
4
|
+
|
5
|
+
* **Lokalise is introducing API rate limiting.** Access to all endpoints will be limited to 6 requests per second from 14 September, 2021. This limit is applied per API token and per IP address. If you exceed the limit, a 429 HTTP status code will be returned and a `Lokalise::Error::TooManyRequests` exception will be raised. Therefore, to overcome this issue LokaliseRails is introducing an exponential backoff mechanism for file exports. Why? Because if you have, say, 10 translation files, we'll have to send 10 separate API requests which will probably mean exceeding the limit (this is not the case with importing as we're always receiving a single archive). Thus, if the HTTP status code 429 was received, we'll do the following:
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
sleep 2 ** retries
|
9
|
+
retries += 1
|
10
|
+
```
|
11
|
+
|
12
|
+
* If the maximum number of retries has been reached LokaliseRails will re-raise the `Lokalise::Error::TooManyRequests` error and give up. By default, the maximum number of retries is set to `5` but you can control it using the `max_retries_export` option.
|
13
|
+
* Enabled compression for the API client.
|
14
|
+
|
15
|
+
## 1.4.0 (29-Jun-21)
|
16
|
+
|
17
|
+
* Re-worked exception handling. Now when something goes wrong during the import or export process, this gem will re-raise all such errors (previously it just printed out some errors to the `$stdout`). If you run a Rake task, it will exit with a status code `1` and the actual error message. If you run a task programattically, you'll get an exception.
|
18
|
+
* Dropped support for Ruby 2.5
|
19
|
+
* Test against Ruby 3
|
20
|
+
|
21
|
+
## 1.3.1 (01-Apr-21)
|
22
|
+
|
23
|
+
* A bit better exception handling
|
24
|
+
* Update dependencies
|
25
|
+
|
26
|
+
## 1.3.0 (02-Feb-21)
|
27
|
+
|
28
|
+
* Use ruby-lokalise-api v3
|
29
|
+
|
3
30
|
## 1.2.0 (11-Nov-20)
|
4
31
|
|
5
32
|
* New option `translations_loader`
|
data/README.md
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# LokaliseRails
|
2
2
|
|
3
|
-
|
4
|
-
[![Build Status](https://travis-ci.
|
3
|
+
![Gem](https://img.shields.io/gem/v/lokalise_rails)
|
4
|
+
[![Build Status](https://travis-ci.com/bodrovis/lokalise_rails.svg?branch=master)](https://travis-ci.com/github/bodrovis/lokalise_rails)
|
5
5
|
[![Test Coverage](https://codecov.io/gh/bodrovis/lokalise_rails/graph/badge.svg)](https://codecov.io/gh/bodrovis/lokalise_rails)
|
6
|
+
![Downloads total](https://img.shields.io/gem/dt/lokalise_rails)
|
6
7
|
|
7
8
|
This gem provides [Lokalise](http://lokalise.com) integration for Ruby on Rails and allows to exchange translation files easily. It relies on [ruby-lokalise-api](https://lokalise.github.io/ruby-lokalise-api) to send APIv2 requests.
|
8
9
|
|
@@ -133,6 +134,8 @@ en_US:
|
|
133
134
|
c.skip_file_export = ->(file) { f.split[1].to_s.include?('fr') }
|
134
135
|
```
|
135
136
|
|
137
|
+
* `max_retries_export` (`integer`) - this option is introduced to properly handle Lokalise API rate limiting during file exporting. If the HTTP status code 429 (too many requests) has been received, LokaliseRails will apply an exponential backoff mechanism with a very simple formula: `2 ** retries` (initially `retries` is `0`). If the maximum number of retries has been reached, a `Lokalise::Error::TooManyRequests` exception will be raised and the export operation will be halted. By default, LokaliseRails will make up to `5` retries which potentially means `1 + 2 + 4 + 8 + 16 + 32 = 63` seconds of waiting time. If the `max_retries_export` is less than `1`, LokaliseRails will not perform any retries and give up immediately after receiving error 429.
|
138
|
+
|
136
139
|
### Settings to work with formats other than YAML
|
137
140
|
|
138
141
|
If your translation files are not in YAML format, you will need to adjust the following options:
|
@@ -16,6 +16,9 @@ LokaliseRails.config do |c|
|
|
16
16
|
# Provide request timeouts for the Lokalise API client:
|
17
17
|
# c.timeouts = {open_timeout: nil, timeout: nil}
|
18
18
|
|
19
|
+
# Provide maximum number of retries for file exporting:
|
20
|
+
# c.max_retries_export = 5
|
21
|
+
|
19
22
|
# Import options have the following defaults:
|
20
23
|
# c.import_opts = {
|
21
24
|
# format: 'yaml',
|
data/lib/lokalise_rails.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'lokalise_rails/error'
|
3
4
|
require 'lokalise_rails/task_definition/base'
|
4
5
|
require 'lokalise_rails/task_definition/importer'
|
5
6
|
require 'lokalise_rails/task_definition/exporter'
|
@@ -9,7 +10,7 @@ module LokaliseRails
|
|
9
10
|
attr_accessor :api_token, :project_id
|
10
11
|
attr_writer :import_opts, :import_safe_mode, :export_opts, :locales_path,
|
11
12
|
:file_ext_regexp, :skip_file_export, :branch, :timeouts,
|
12
|
-
:translations_loader, :translations_converter, :lang_iso_inferer
|
13
|
+
:translations_loader, :translations_converter, :lang_iso_inferer, :max_retries_export
|
13
14
|
|
14
15
|
# Main interface to provide configuration options for rake tasks
|
15
16
|
def config
|
@@ -31,6 +32,11 @@ module LokaliseRails
|
|
31
32
|
@timeouts || {}
|
32
33
|
end
|
33
34
|
|
35
|
+
# Maximum number of retries for file exporting
|
36
|
+
def max_retries_export
|
37
|
+
@max_retries_export || 5
|
38
|
+
end
|
39
|
+
|
34
40
|
# Regular expression used to select translation files with proper extensions
|
35
41
|
def file_ext_regexp
|
36
42
|
@file_ext_regexp || /\.ya?ml\z/i
|
@@ -13,7 +13,7 @@ module LokaliseRails
|
|
13
13
|
#
|
14
14
|
# @return [Lokalise::Client]
|
15
15
|
def api_client
|
16
|
-
@api_client ||= ::Lokalise.client LokaliseRails.api_token, LokaliseRails.timeouts
|
16
|
+
@api_client ||= ::Lokalise.client LokaliseRails.api_token, {enable_compression: true}.merge(LokaliseRails.timeouts)
|
17
17
|
end
|
18
18
|
|
19
19
|
# Resets API client
|
@@ -25,11 +25,12 @@ module LokaliseRails
|
|
25
25
|
# Checks task options
|
26
26
|
#
|
27
27
|
# @return Array
|
28
|
-
def
|
28
|
+
def check_options_errors!
|
29
29
|
errors = []
|
30
|
-
errors << 'Project ID is not set!
|
31
|
-
errors << 'Lokalise API token is not set!
|
32
|
-
|
30
|
+
errors << 'Project ID is not set!' if LokaliseRails.project_id.nil? || LokaliseRails.project_id.empty?
|
31
|
+
errors << 'Lokalise API token is not set!' if LokaliseRails.api_token.nil? || LokaliseRails.api_token.empty?
|
32
|
+
|
33
|
+
raise(LokaliseRails::Error, errors.join(' ')) if errors.any?
|
33
34
|
end
|
34
35
|
|
35
36
|
private
|
@@ -10,20 +10,13 @@ module LokaliseRails
|
|
10
10
|
#
|
11
11
|
# @return [Array]
|
12
12
|
def export!
|
13
|
-
|
14
|
-
|
15
|
-
if errors.any?
|
16
|
-
errors.each { |e| $stdout.puts e }
|
17
|
-
return errors
|
18
|
-
end
|
13
|
+
check_options_errors!
|
19
14
|
|
20
15
|
queued_processes = []
|
21
16
|
each_file do |full_path, relative_path|
|
22
|
-
queued_processes <<
|
23
|
-
project_id_with_branch, opts(full_path, relative_path)
|
24
|
-
)
|
17
|
+
queued_processes << do_upload(full_path, relative_path)
|
25
18
|
rescue StandardError => e
|
26
|
-
|
19
|
+
raise e.class, "Error while trying to upload #{full_path}: #{e.message}"
|
27
20
|
end
|
28
21
|
|
29
22
|
$stdout.print 'Task complete!'
|
@@ -31,6 +24,21 @@ module LokaliseRails
|
|
31
24
|
queued_processes
|
32
25
|
end
|
33
26
|
|
27
|
+
# Performs the actual file uploading to Lokalise. If the API rate limit is exceeed,
|
28
|
+
# applies exponential backoff
|
29
|
+
def do_upload(f_path, r_path)
|
30
|
+
retries = 0
|
31
|
+
begin
|
32
|
+
api_client.upload_file project_id_with_branch, opts(f_path, r_path)
|
33
|
+
rescue Lokalise::Error::TooManyRequests => e
|
34
|
+
raise(e.class, "Gave up after #{retries} retries") if retries >= LokaliseRails.max_retries_export
|
35
|
+
|
36
|
+
sleep 2**retries
|
37
|
+
retries += 1
|
38
|
+
retry
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
34
42
|
# Processes each translation file in the specified directory
|
35
43
|
def each_file
|
36
44
|
return unless block_given?
|
@@ -13,12 +13,7 @@ module LokaliseRails
|
|
13
13
|
#
|
14
14
|
# @return [Boolean]
|
15
15
|
def import!
|
16
|
-
|
17
|
-
|
18
|
-
if errors.any?
|
19
|
-
errors.each { |e| $stdout.puts e }
|
20
|
-
return false
|
21
|
-
end
|
16
|
+
check_options_errors!
|
22
17
|
|
23
18
|
unless proceed_when_safe_mode?
|
24
19
|
$stdout.print 'Task cancelled!'
|
@@ -39,7 +34,7 @@ module LokaliseRails
|
|
39
34
|
|
40
35
|
api_client.download_files project_id_with_branch, opts
|
41
36
|
rescue StandardError => e
|
42
|
-
|
37
|
+
raise e.class, "There was an error when trying to download files: #{e.message}"
|
43
38
|
end
|
44
39
|
|
45
40
|
# Opens ZIP archive (local or remote) with translations and processes its entries
|
@@ -49,6 +44,8 @@ module LokaliseRails
|
|
49
44
|
Zip::File.open_buffer(open_file_or_remote(path)) do |zip|
|
50
45
|
fetch_zip_entries(zip) { |entry| process!(entry) }
|
51
46
|
end
|
47
|
+
rescue StandardError => e
|
48
|
+
raise e.class, "There was an error when trying to process the downloaded files: #{e.message}"
|
52
49
|
end
|
53
50
|
|
54
51
|
# Iterates over ZIP entries. Each entry may be a file or folder.
|
@@ -73,7 +70,7 @@ module LokaliseRails
|
|
73
70
|
f.write LokaliseRails.translations_converter.call(data)
|
74
71
|
end
|
75
72
|
rescue StandardError => e
|
76
|
-
|
73
|
+
raise e.class, "Error when trying to process #{zip_entry&.name}: #{e.message}"
|
77
74
|
end
|
78
75
|
|
79
76
|
# Checks whether the user wishes to proceed when safe mode is enabled and the target directory is not empty
|
@@ -6,9 +6,13 @@ require "#{Rails.root}/config/lokalise_rails"
|
|
6
6
|
namespace :lokalise_rails do
|
7
7
|
task :import do
|
8
8
|
LokaliseRails::TaskDefinition::Importer.import!
|
9
|
+
rescue StandardError => e
|
10
|
+
abort e.inspect
|
9
11
|
end
|
10
12
|
|
11
13
|
task :export do
|
12
14
|
LokaliseRails::TaskDefinition::Exporter.export!
|
15
|
+
rescue StandardError => e
|
16
|
+
abort e.inspect
|
13
17
|
end
|
14
18
|
end
|
data/lokalise_rails.gemspec
CHANGED
@@ -23,13 +23,13 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.extra_rdoc_files = ['README.md']
|
24
24
|
spec.require_paths = ['lib']
|
25
25
|
|
26
|
-
spec.add_dependency 'ruby-lokalise-api', '~>
|
26
|
+
spec.add_dependency 'ruby-lokalise-api', '~> 4.0'
|
27
27
|
spec.add_dependency 'rubyzip', '~> 2.3'
|
28
28
|
|
29
|
-
spec.add_development_dependency 'codecov', '~> 0.
|
29
|
+
spec.add_development_dependency 'codecov', '~> 0.2'
|
30
30
|
spec.add_development_dependency 'dotenv', '~> 2.5'
|
31
31
|
if ENV['TEST_RAILS_VERSION'].nil?
|
32
|
-
spec.add_development_dependency 'rails', '~> 6.0
|
32
|
+
spec.add_development_dependency 'rails', '~> 6.1.0'
|
33
33
|
else
|
34
34
|
spec.add_development_dependency 'rails', ENV['TEST_RAILS_VERSION'].to_s
|
35
35
|
end
|
@@ -37,7 +37,7 @@ Gem::Specification.new do |spec|
|
|
37
37
|
spec.add_development_dependency 'rspec', '~> 3.6'
|
38
38
|
spec.add_development_dependency 'rubocop', '~> 1.0'
|
39
39
|
spec.add_development_dependency 'rubocop-performance', '~> 1.5'
|
40
|
-
spec.add_development_dependency 'rubocop-rspec', '~> 2.
|
40
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 2.4.0'
|
41
41
|
spec.add_development_dependency 'simplecov', '~> 0.16'
|
42
42
|
spec.add_development_dependency 'vcr', '~> 6.0'
|
43
43
|
end
|
@@ -17,9 +17,7 @@ Rails.application.configure do
|
|
17
17
|
|
18
18
|
# Configure public file server for tests with Cache-Control for performance.
|
19
19
|
config.public_file_server.enabled = true
|
20
|
-
config.public_file_server.headers = {
|
21
|
-
'Cache-Control' => "public, max-age=#{1.hour.to_i}"
|
22
|
-
}
|
20
|
+
config.public_file_server.headers = {'Cache-Control' => 'public, max-age=3600'}
|
23
21
|
|
24
22
|
# Show full error reports and disable caching.
|
25
23
|
config.consider_all_requests_local = true
|
@@ -34,22 +34,18 @@ describe LokaliseRails::TaskDefinition::Base do
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
describe '.
|
38
|
-
it '
|
37
|
+
describe '.check_options_errors!' do
|
38
|
+
it 'raises an error when the API key is not set' do
|
39
39
|
allow(LokaliseRails).to receive(:api_token).and_return(nil)
|
40
|
-
|
40
|
+
|
41
|
+
expect(-> { described_class.check_options_errors! }).to raise_error(LokaliseRails::Error, /API token is not set/i)
|
41
42
|
|
42
43
|
expect(LokaliseRails).to have_received(:api_token)
|
43
|
-
expect(errors.length).to eq(1)
|
44
|
-
expect(errors.first).to include('API token is not set')
|
45
44
|
end
|
46
45
|
|
47
46
|
it 'returns an error when the project_id is not set' do
|
48
47
|
allow_project_id nil do
|
49
|
-
|
50
|
-
|
51
|
-
expect(errors.length).to eq(1)
|
52
|
-
expect(errors.first).to include('Project ID is not set')
|
48
|
+
expect(-> { described_class.check_options_errors! }).to raise_error(LokaliseRails::Error, /ID is not set/i)
|
53
49
|
end
|
54
50
|
end
|
55
51
|
end
|
@@ -7,6 +7,45 @@ describe LokaliseRails::TaskDefinition::Exporter do
|
|
7
7
|
let(:path) { "#{Rails.root}/config/locales/nested/#{filename}" }
|
8
8
|
let(:relative_name) { "nested/#{filename}" }
|
9
9
|
|
10
|
+
context 'with many translation files' do
|
11
|
+
let(:fake_class) { described_class }
|
12
|
+
|
13
|
+
before :all do
|
14
|
+
add_translation_files! with_ru: true, additional: 5
|
15
|
+
end
|
16
|
+
|
17
|
+
after :all do
|
18
|
+
rm_translation_files
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '.export!' do
|
22
|
+
it 'sends a proper API request and handles rate limiting' do
|
23
|
+
allow_project_id '672198945b7d72fc048021.15940510'
|
24
|
+
|
25
|
+
process = VCR.use_cassette('upload_files_multiple') do
|
26
|
+
described_class.export!
|
27
|
+
end.first
|
28
|
+
|
29
|
+
expect(process.project_id).to eq(LokaliseRails.project_id)
|
30
|
+
expect(process.status).to eq('queued')
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'handles too many requests' do
|
34
|
+
allow_project_id '672198945b7d72fc048021.15940510'
|
35
|
+
allow(LokaliseRails).to receive(:max_retries_export).and_return(2)
|
36
|
+
|
37
|
+
fake_client = double
|
38
|
+
allow(fake_client).to receive(:upload_file).and_raise(Lokalise::Error::TooManyRequests)
|
39
|
+
allow(fake_class).to receive(:api_client).and_return(fake_client)
|
40
|
+
|
41
|
+
expect(-> { fake_class.export! }).to raise_error(Lokalise::Error::TooManyRequests, /Gave up after 2 retries/i)
|
42
|
+
expect(LokaliseRails).to have_received(:max_retries_export).exactly(3).times
|
43
|
+
expect(fake_class).to have_received(:api_client).exactly(3).times
|
44
|
+
expect(fake_client).to have_received(:upload_file).exactly(3).times
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
10
49
|
context 'with one translation file' do
|
11
50
|
before :all do
|
12
51
|
add_translation_files!
|
@@ -26,6 +65,7 @@ describe LokaliseRails::TaskDefinition::Exporter do
|
|
26
65
|
|
27
66
|
expect(process.project_id).to eq(LokaliseRails.project_id)
|
28
67
|
expect(process.status).to eq('queued')
|
68
|
+
expect(LokaliseRails.max_retries_export).to eq(5)
|
29
69
|
end
|
30
70
|
|
31
71
|
it 'sends a proper API request when a different branch is provided' do
|
@@ -44,13 +84,13 @@ describe LokaliseRails::TaskDefinition::Exporter do
|
|
44
84
|
it 'halts when the API key is not set' do
|
45
85
|
allow(LokaliseRails).to receive(:api_token).and_return(nil)
|
46
86
|
|
47
|
-
expect(-> { described_class.export! }).to
|
87
|
+
expect(-> { described_class.export! }).to raise_error(LokaliseRails::Error, /API token is not set/i)
|
48
88
|
expect(LokaliseRails).to have_received(:api_token)
|
49
89
|
end
|
50
90
|
|
51
91
|
it 'halts when the project_id is not set' do
|
52
92
|
allow_project_id nil do
|
53
|
-
expect(-> { described_class.export! }).to
|
93
|
+
expect(-> { described_class.export! }).to raise_error(LokaliseRails::Error, /ID is not set/i)
|
54
94
|
end
|
55
95
|
end
|
56
96
|
end
|
@@ -107,17 +147,12 @@ describe LokaliseRails::TaskDefinition::Exporter do
|
|
107
147
|
end
|
108
148
|
|
109
149
|
describe '.export!' do
|
110
|
-
it '
|
150
|
+
it 're-raises export errors' do
|
111
151
|
allow_project_id
|
112
152
|
|
113
|
-
|
114
|
-
described_class.export!
|
153
|
+
VCR.use_cassette('upload_files_error') do
|
154
|
+
expect { described_class.export! }.to raise_error(Lokalise::Error::BadRequest, /Unknown `lang_iso`/)
|
115
155
|
end
|
116
|
-
|
117
|
-
expect(processes.length).to eq(1)
|
118
|
-
process = processes.first
|
119
|
-
expect(process.project_id).to eq(LokaliseRails.project_id)
|
120
|
-
expect(process.status).to eq('queued')
|
121
156
|
end
|
122
157
|
end
|
123
158
|
|
@@ -4,29 +4,35 @@ describe LokaliseRails::TaskDefinition::Importer do
|
|
4
4
|
describe '.open_and_process_zip' do
|
5
5
|
let(:faulty_trans) { "#{Rails.root}/public/faulty_trans.zip" }
|
6
6
|
|
7
|
-
it '
|
7
|
+
it 're-raises errors during file processing' do
|
8
8
|
expect(-> { described_class.open_and_process_zip(faulty_trans) }).
|
9
|
-
to
|
9
|
+
to raise_error(Psych::DisallowedClass, /Error when trying to process fail\.yml/)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 're-raises errors during file opening' do
|
13
|
+
expect(-> { described_class.open_and_process_zip('http://fake.url/wrong/path.zip') }).
|
14
|
+
to raise_error(SocketError, /Failed to open TCP connection/)
|
10
15
|
end
|
11
16
|
end
|
12
17
|
|
13
18
|
describe '.download_files' do
|
14
19
|
it 'returns a proper download URL' do
|
15
|
-
allow_project_id '
|
20
|
+
allow_project_id '672198945b7d72fc048021.15940510' do
|
16
21
|
response = VCR.use_cassette('download_files') do
|
17
22
|
described_class.download_files
|
18
23
|
end
|
19
24
|
|
20
|
-
expect(response['project_id']).to eq('
|
25
|
+
expect(response['project_id']).to eq('672198945b7d72fc048021.15940510')
|
21
26
|
expect(response['bundle_url']).to include('s3-eu-west-1.amazonaws.com')
|
27
|
+
expect(described_class.api_client.enable_compression).to eq(true)
|
22
28
|
end
|
23
29
|
end
|
24
30
|
|
25
|
-
it '
|
31
|
+
it 're-raises errors during file download' do
|
26
32
|
allow_project_id 'invalid'
|
27
33
|
VCR.use_cassette('download_files_error') do
|
28
34
|
expect(-> { described_class.download_files }).
|
29
|
-
to
|
35
|
+
to raise_error(Lokalise::Error::BadRequest, /Invalid `project_id` parameter/)
|
30
36
|
end
|
31
37
|
end
|
32
38
|
end
|
@@ -34,14 +40,14 @@ describe LokaliseRails::TaskDefinition::Importer do
|
|
34
40
|
describe '.import!' do
|
35
41
|
it 'halts when the API key is not set' do
|
36
42
|
allow(LokaliseRails).to receive(:api_token).and_return(nil)
|
37
|
-
expect(-> { described_class.import! }).to
|
43
|
+
expect(-> { described_class.import! }).to raise_error(LokaliseRails::Error, /API token is not set/i)
|
38
44
|
expect(LokaliseRails).to have_received(:api_token)
|
39
45
|
expect(count_translations).to eq(0)
|
40
46
|
end
|
41
47
|
|
42
48
|
it 'halts when the project_id is not set' do
|
43
49
|
allow_project_id nil do
|
44
|
-
expect(-> { described_class.import! }).to
|
50
|
+
expect(-> { described_class.import! }).to raise_error(LokaliseRails::Error, /ID is not set/i)
|
45
51
|
expect(count_translations).to eq(0)
|
46
52
|
end
|
47
53
|
end
|
@@ -58,6 +58,11 @@ describe LokaliseRails do
|
|
58
58
|
fake_class.import_safe_mode = true
|
59
59
|
end
|
60
60
|
|
61
|
+
it 'is possible to set max_retries_export' do
|
62
|
+
allow(fake_class).to receive(:max_retries_export=).with(10)
|
63
|
+
fake_class.max_retries_export = 10
|
64
|
+
end
|
65
|
+
|
61
66
|
it 'is possible to set api_token' do
|
62
67
|
allow(fake_class).to receive(:api_token=).with('abc')
|
63
68
|
fake_class.api_token = 'abc'
|
@@ -1,7 +1,44 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
RSpec.describe LokaliseRails do
|
4
|
+
it 'halts when the API key is not set' do
|
5
|
+
allow(described_class).to receive(:api_token).and_return(nil)
|
6
|
+
|
7
|
+
expect(export_executor).to raise_error(SystemExit, /API token is not set/i)
|
8
|
+
expect(described_class).to have_received(:api_token)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'halts when the project ID is not set' do
|
12
|
+
allow_project_id nil do
|
13
|
+
expect(export_executor).to raise_error(SystemExit, /ID is not set/i)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
4
17
|
it 'runs export rake task properly' do
|
5
18
|
expect(export_executor).to output(/complete!/).to_stdout
|
6
19
|
end
|
20
|
+
|
21
|
+
context 'with two translation files' do
|
22
|
+
let(:filename_ru) { 'ru.yml' }
|
23
|
+
let(:path_ru) { "#{Rails.root}/config/locales/#{filename_ru}" }
|
24
|
+
let(:relative_name_ru) { filename_ru }
|
25
|
+
|
26
|
+
before :all do
|
27
|
+
add_translation_files! with_ru: true
|
28
|
+
end
|
29
|
+
|
30
|
+
after :all do
|
31
|
+
rm_translation_files
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '.export!' do
|
35
|
+
it 're-raises export errors' do
|
36
|
+
allow_project_id
|
37
|
+
|
38
|
+
VCR.use_cassette('upload_files_error') do
|
39
|
+
expect(export_executor).to raise_error(SystemExit, /Unknown `lang_iso`/)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
7
44
|
end
|
@@ -7,6 +7,19 @@ RSpec.describe LokaliseRails do
|
|
7
7
|
let(:local_trans) { "#{Rails.root}/public/trans.zip" }
|
8
8
|
let(:remote_trans) { 'https://github.com/bodrovis/lokalise_rails/blob/master/spec/dummy/public/trans.zip?raw=true' }
|
9
9
|
|
10
|
+
it 'halts when the API key is not set' do
|
11
|
+
allow(described_class).to receive(:api_token).and_return(nil)
|
12
|
+
|
13
|
+
expect(import_executor).to raise_error(SystemExit, /API token is not set/i)
|
14
|
+
expect(described_class).to have_received(:api_token)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'halts when the project ID is not set' do
|
18
|
+
allow_project_id nil do
|
19
|
+
expect(import_executor).to raise_error(SystemExit, /ID is not set/i)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
10
23
|
context 'when directory is empty' do
|
11
24
|
before do
|
12
25
|
mkdir_locales
|
data/spec/spec_helper.rb
CHANGED
@@ -20,7 +20,6 @@ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].sort.each { |f| require f }
|
|
20
20
|
|
21
21
|
# Configure Rails Environment
|
22
22
|
ENV['RAILS_ENV'] = 'test'
|
23
|
-
|
24
23
|
require_relative '../spec/dummy/config/environment'
|
25
24
|
ENV['RAILS_ROOT'] ||= "#{File.dirname(__FILE__)}../../../spec/dummy"
|
26
25
|
|
@@ -24,16 +24,20 @@ module FileManager
|
|
24
24
|
locales_dir.count { |file| File.file?(file) }
|
25
25
|
end
|
26
26
|
|
27
|
-
def add_translation_files!(with_ru: false)
|
27
|
+
def add_translation_files!(with_ru: false, additional: nil)
|
28
28
|
FileUtils.mkdir_p "#{Rails.root}/config/locales/nested"
|
29
|
-
|
30
|
-
f.write en_data
|
31
|
-
end
|
29
|
+
open_and_write('config/locales/nested/en.yml') { |f| f.write en_data }
|
32
30
|
|
33
31
|
return unless with_ru
|
34
32
|
|
35
|
-
|
36
|
-
|
33
|
+
open_and_write('config/locales/ru.yml') { |f| f.write ru_data }
|
34
|
+
|
35
|
+
return unless additional
|
36
|
+
|
37
|
+
additional.times do |i|
|
38
|
+
data = {'en' => {"key_#{i}" => "value #{i}"}}
|
39
|
+
|
40
|
+
open_and_write("config/locales/en_#{i}.yml") { |f| f.write data.to_yaml }
|
37
41
|
end
|
38
42
|
end
|
39
43
|
|
@@ -46,9 +50,13 @@ module FileManager
|
|
46
50
|
end
|
47
51
|
DATA
|
48
52
|
|
49
|
-
|
50
|
-
|
51
|
-
|
53
|
+
open_and_write('config/lokalise_rails.rb') { |f| f.write data }
|
54
|
+
end
|
55
|
+
|
56
|
+
def open_and_write(rel_path, &block)
|
57
|
+
return unless block
|
58
|
+
|
59
|
+
File.open("#{Rails.root}/#{rel_path}", 'w+:UTF-8', &block)
|
52
60
|
end
|
53
61
|
|
54
62
|
def remove_config
|
data/spec/support/spec_addons.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module SpecAddons
|
4
|
-
def allow_project_id(value =
|
4
|
+
def allow_project_id(value = '189934715f57a162257d74.88352370')
|
5
5
|
allow(LokaliseRails).to receive(:project_id).and_return(value)
|
6
6
|
return unless block_given?
|
7
7
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lokalise_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ilya Bodrov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-08-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-lokalise-api
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '4.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '4.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rubyzip
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0.
|
47
|
+
version: '0.2'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0.
|
54
|
+
version: '0.2'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: dotenv
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,14 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 6.0
|
75
|
+
version: 6.1.0
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 6.0
|
82
|
+
version: 6.1.0
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rake
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -142,14 +142,14 @@ dependencies:
|
|
142
142
|
requirements:
|
143
143
|
- - "~>"
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: 2.
|
145
|
+
version: 2.4.0
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
150
|
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version: 2.
|
152
|
+
version: 2.4.0
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
154
|
name: simplecov
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -198,6 +198,7 @@ files:
|
|
198
198
|
- lib/generators/lokalise_rails/install_generator.rb
|
199
199
|
- lib/generators/templates/lokalise_rails_config.rb
|
200
200
|
- lib/lokalise_rails.rb
|
201
|
+
- lib/lokalise_rails/error.rb
|
201
202
|
- lib/lokalise_rails/railtie.rb
|
202
203
|
- lib/lokalise_rails/task_definition/base.rb
|
203
204
|
- lib/lokalise_rails/task_definition/exporter.rb
|
@@ -254,11 +255,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
254
255
|
version: 2.5.0
|
255
256
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
256
257
|
requirements:
|
257
|
-
- - "
|
258
|
+
- - ">"
|
258
259
|
- !ruby/object:Gem::Version
|
259
|
-
version:
|
260
|
+
version: 1.3.1
|
260
261
|
requirements: []
|
261
|
-
rubygems_version: 3.
|
262
|
+
rubygems_version: 3.2.25
|
262
263
|
signing_key:
|
263
264
|
specification_version: 4
|
264
265
|
summary: Lokalise integration for Ruby on Rails
|