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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 02b78ecae0b5dbf76599249606858c5b24e31fc9826f8795feb34abac9d5ffb4
4
- data.tar.gz: b7bc51d45b689181ae0d3d5366f507ae0e43c878c4ab55979ba54d7089eb49f7
3
+ metadata.gz: d8c05601cd8f8684c1523aa4b92d87d10afad700c50d197e40b6886fd4bc9412
4
+ data.tar.gz: ddc3d0616655b4bda4a40ecf1a96af9c17c5ef54d7c372a05bdf9eb29c2dcdee
5
5
  SHA512:
6
- metadata.gz: 838ddae7af99842dbc4a7ce900c8b02a07571ff9c561e642e3bac6f92dbaabd9132f775b0ff1877ffd18fc20c1bf84ec3f7792139bad0c9fc97dec1d03389e64
7
- data.tar.gz: 79c0314752c8e48b552eb78c564d24da0cd14fa41b1195909d8d06ca81913322fefa56a696f3c20d1c53c51aa16feb731c85f6fdd860242c98ad8b018b9c68ae
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
- [![Gem Version](https://badge.fury.io/rb/lokalise_rails.svg)](https://badge.fury.io/rb/lokalise_rails)
4
- [![Build Status](https://travis-ci.org/bodrovis/lokalise_rails.svg?branch=master)](https://travis-ci.org/bodrovis/lokalise_rails)
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',
@@ -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
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LokaliseRails
4
+ class Error < StandardError
5
+ # Initializes a new Error object
6
+ def initialize(message = '')
7
+ super(message)
8
+ end
9
+ end
10
+ end
@@ -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 opt_errors
28
+ def check_options_errors!
29
29
  errors = []
30
- errors << 'Project ID is not set! Aborting...' if LokaliseRails.project_id.nil? || LokaliseRails.project_id.empty?
31
- errors << 'Lokalise API token is not set! Aborting...' if LokaliseRails.api_token.nil? || LokaliseRails.api_token.empty?
32
- errors
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
- errors = opt_errors
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 << api_client.upload_file(
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
- $stdout.puts "Error while trying to upload #{full_path}: #{e.inspect}"
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
- errors = opt_errors
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
- $stdout.puts "There was an error when trying to download files: #{e.inspect}"
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
- $stdout.puts "Error when trying to process #{zip_entry&.name}: #{e.inspect}"
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LokaliseRails
4
- VERSION = '1.2.0'
4
+ VERSION = '2.0.0.rc1'
5
5
  end
@@ -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
@@ -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', '~> 3.1'
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.1'
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.3'
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.0.0'
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 '.opt_errors' do
38
- it 'returns an error when the API key is not set' do
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
- errors = described_class.opt_errors
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
- errors = described_class.opt_errors
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 output(/API token is not set/).to_stdout
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 output(/Project ID is not set/).to_stdout
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 'rescues from export errors' do
150
+ it 're-raises export errors' do
111
151
  allow_project_id
112
152
 
113
- processes = VCR.use_cassette('upload_files_error') do
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 'rescues from errors during file processing' do
7
+ it 're-raises errors during file processing' do
8
8
  expect(-> { described_class.open_and_process_zip(faulty_trans) }).
9
- to output(/Psych::DisallowedClass/).to_stdout
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 '189934715f57a162257d74.88352370' do
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('189934715f57a162257d74.88352370')
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 'rescues from errors during file download' do
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 output(/Lokalise::Error::BadRequest/).to_stdout
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 output(/API token is not set/).to_stdout
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 output(/Project ID is not set/).to_stdout
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
- File.open("#{Rails.root}/config/locales/nested/en.yml", 'w+:UTF-8') do |f|
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
- File.open("#{Rails.root}/config/locales/ru.yml", 'w+:UTF-8') do |f|
36
- f.write ru_data
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
- File.open("#{Rails.root}/config/lokalise_rails.rb", 'w+:UTF-8') do |f|
50
- f.write data
51
- end
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
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SpecAddons
4
- def allow_project_id(value = ENV['LOKALISE_PROJECT_ID'])
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: 1.2.0
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: 2020-11-11 00:00:00.000000000 Z
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: '3.1'
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: '3.1'
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.1'
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.1'
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.3
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.3
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.0.0
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.0.0
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: '0'
260
+ version: 1.3.1
260
261
  requirements: []
261
- rubygems_version: 3.1.4
262
+ rubygems_version: 3.2.25
262
263
  signing_key:
263
264
  specification_version: 4
264
265
  summary: Lokalise integration for Ruby on Rails