txdb 1.0.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 +7 -0
- data/LICENSE +202 -0
- data/README.md +39 -0
- data/lib/txdb.rb +32 -0
- data/lib/txdb/app.rb +36 -0
- data/lib/txdb/backends.rb +19 -0
- data/lib/txdb/backends/globalize.rb +10 -0
- data/lib/txdb/backends/globalize/backend.rb +19 -0
- data/lib/txdb/backends/globalize/helpers.rb +19 -0
- data/lib/txdb/backends/globalize/reader.rb +63 -0
- data/lib/txdb/backends/globalize/writer.rb +39 -0
- data/lib/txdb/config.rb +52 -0
- data/lib/txdb/connection_string.rb +18 -0
- data/lib/txdb/database.rb +40 -0
- data/lib/txdb/downloader.rb +32 -0
- data/lib/txdb/handlers.rb +6 -0
- data/lib/txdb/handlers/hook_handler.rb +59 -0
- data/lib/txdb/handlers/triggers.rb +9 -0
- data/lib/txdb/handlers/triggers/handler.rb +50 -0
- data/lib/txdb/handlers/triggers/pull_handler.rb +34 -0
- data/lib/txdb/handlers/triggers/push_handler.rb +19 -0
- data/lib/txdb/response.rb +11 -0
- data/lib/txdb/response_helpers.rb +26 -0
- data/lib/txdb/table.rb +36 -0
- data/lib/txdb/transifex_project.rb +17 -0
- data/lib/txdb/tx_resource.rb +52 -0
- data/lib/txdb/uploader.rb +33 -0
- data/lib/txdb/version.rb +3 -0
- data/spec/backends/globalize/helpers_spec.rb +17 -0
- data/spec/backends/globalize/reader_spec.rb +25 -0
- data/spec/backends/globalize/writer_spec.rb +53 -0
- data/spec/backends_spec.rb +30 -0
- data/spec/config_spec.rb +71 -0
- data/spec/connection_string_spec.rb +24 -0
- data/spec/database_spec.rb +33 -0
- data/spec/downloader_spec.rb +36 -0
- data/spec/handlers/hook_handler_spec.rb +73 -0
- data/spec/handlers/triggers/pull_handler_spec.rb +58 -0
- data/spec/handlers/triggers/push_handler_spec.rb +49 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/spec_helpers/env_helpers.rb +13 -0
- data/spec/spec_helpers/globalize_db.rb +60 -0
- data/spec/spec_helpers/test_backend.rb +28 -0
- data/spec/spec_helpers/test_db.rb +76 -0
- data/spec/table_spec.rb +58 -0
- data/spec/test.sqlite3 +0 -0
- data/spec/transifex_project_spec.rb +15 -0
- data/spec/tx_resource_spec.rb +17 -0
- data/spec/uploader_spec.rb +36 -0
- data/txdb.gemspec +22 -0
- metadata +134 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'txgh'
|
|
2
|
+
|
|
3
|
+
module Txdb
|
|
4
|
+
class TransifexProject
|
|
5
|
+
attr_reader :organization, :project_slug, :username, :password
|
|
6
|
+
attr_reader :webhook_secret, :api
|
|
7
|
+
|
|
8
|
+
def initialize(options = {})
|
|
9
|
+
@organization = options.fetch(:organization)
|
|
10
|
+
@project_slug = options.fetch(:project_slug)
|
|
11
|
+
@username = options.fetch(:username)
|
|
12
|
+
@password = options.fetch(:password)
|
|
13
|
+
@webhook_secret = options.fetch(:webhook_secret)
|
|
14
|
+
@api = Txgh::TransifexApi.create_from_credentials(username, password)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require 'txgh'
|
|
2
|
+
|
|
3
|
+
module Txdb
|
|
4
|
+
class TxResource
|
|
5
|
+
RESOURCE_TYPE = 'YML'
|
|
6
|
+
|
|
7
|
+
class << self
|
|
8
|
+
def from_table(table)
|
|
9
|
+
# project_slug, resource_slug, type, source_lang, source_file,
|
|
10
|
+
# lang_map, translation_file
|
|
11
|
+
new(
|
|
12
|
+
Txgh::TxResource.new(
|
|
13
|
+
project_slug(table), resource_slug(table), RESOURCE_TYPE,
|
|
14
|
+
source_lang(table), source_file(table), nil, nil
|
|
15
|
+
)
|
|
16
|
+
)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def project_slug(table)
|
|
22
|
+
table.database.transifex_project.project_slug
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def resource_slug(table)
|
|
26
|
+
Txgh::Utils.slugify("#{table.database.database}-#{table.name}")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def source_lang(table)
|
|
30
|
+
table.source_lang
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def source_file(table)
|
|
34
|
+
table.name
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
attr_reader :resource
|
|
39
|
+
|
|
40
|
+
def initialize(resource)
|
|
41
|
+
@resource = resource
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def respond_to?(method)
|
|
45
|
+
resource.respond_to?(method)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def method_missing(method, *args, &block)
|
|
49
|
+
resource.send(method, *args, &block)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Txdb
|
|
2
|
+
class Uploader
|
|
3
|
+
class << self
|
|
4
|
+
def upload(database)
|
|
5
|
+
new(database).upload
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
attr_reader :database
|
|
10
|
+
|
|
11
|
+
def initialize(database)
|
|
12
|
+
@database = database
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def upload
|
|
16
|
+
database.tables.each do |table|
|
|
17
|
+
upload_table(table)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def upload_table(table)
|
|
22
|
+
transifex_api.create_or_update(
|
|
23
|
+
table.resource, table.read_content
|
|
24
|
+
)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def transifex_api
|
|
30
|
+
database.transifex_api
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
data/lib/txdb/version.rb
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
include Txdb::Backends
|
|
4
|
+
|
|
5
|
+
describe Globalize::Helpers do
|
|
6
|
+
describe '.origin_table_name' do
|
|
7
|
+
it 'pluralizes and removes the translations suffix' do
|
|
8
|
+
origin = Globalize::Helpers.origin_table_name('widget_translations')
|
|
9
|
+
expect(origin).to eq('widgets')
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'handles unusual pluralizations (via ActiveSupport::Inflector)' do
|
|
13
|
+
origin = Globalize::Helpers.origin_table_name('ox_translations')
|
|
14
|
+
expect(origin).to eq('oxen')
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'spec_helpers/globalize_db'
|
|
3
|
+
|
|
4
|
+
include Txdb::Backends
|
|
5
|
+
|
|
6
|
+
describe Globalize::Reader, globalize_db: true do
|
|
7
|
+
include_context :globalize
|
|
8
|
+
|
|
9
|
+
describe '#read_content' do
|
|
10
|
+
it 'reads data from the given table and puts it into a hash' do
|
|
11
|
+
sprocket_id = widgets.insert(name: 'sprocket')
|
|
12
|
+
flange_id = widgets.insert(name: 'flange')
|
|
13
|
+
widget_translations.insert(widget_id: sprocket_id, locale: 'es', name: 'sproqueta')
|
|
14
|
+
widget_translations.insert(widget_id: flange_id, locale: 'es', name: 'flango')
|
|
15
|
+
|
|
16
|
+
reader = Globalize::Reader.new(widget_translations_table)
|
|
17
|
+
expect(reader.read_content).to eq({
|
|
18
|
+
'widgets' => {
|
|
19
|
+
1 => { 'name' => 'sprocket' },
|
|
20
|
+
2 => { 'name' => 'flange' }
|
|
21
|
+
}
|
|
22
|
+
})
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'spec_helpers/globalize_db'
|
|
3
|
+
|
|
4
|
+
include Txdb::Backends
|
|
5
|
+
|
|
6
|
+
describe Globalize::Writer, globalize_db: true do
|
|
7
|
+
include_context :globalize
|
|
8
|
+
|
|
9
|
+
describe '#write_content' do
|
|
10
|
+
it 'inserts the translations into the database' do
|
|
11
|
+
sprocket_id = widgets.insert(name: 'sprocket')
|
|
12
|
+
writer = Globalize::Writer.new(widget_translations_table)
|
|
13
|
+
|
|
14
|
+
content = {
|
|
15
|
+
'widgets' => {
|
|
16
|
+
sprocket_id => { name: 'sproqueta' }
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
expect { writer.write_content(content, 'es') }.to(
|
|
21
|
+
change { widget_translations.count }.from(0).to(1)
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
translation = widget_translations.first
|
|
25
|
+
|
|
26
|
+
expect(translation).to include(
|
|
27
|
+
widget_id: sprocket_id, name: 'sproqueta', locale: 'es'
|
|
28
|
+
)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'updates the record if it already exists' do
|
|
32
|
+
sprocket_id = widgets.insert(name: 'sprocket')
|
|
33
|
+
sprocket_trans_id = widget_translations.insert(
|
|
34
|
+
widget_id: sprocket_id, locale: 'es', name: 'sproqueta'
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
writer = Globalize::Writer.new(widget_translations_table)
|
|
38
|
+
|
|
39
|
+
content = {
|
|
40
|
+
'widgets' => {
|
|
41
|
+
sprocket_id => { name: 'sproqueta2' }
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
expect { writer.write_content(content, 'es') }.to_not(
|
|
46
|
+
change { widget_translations.count }
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
translation = widget_translations.where(id: sprocket_trans_id).first
|
|
50
|
+
expect(translation).to include(name: 'sproqueta2')
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
include Txdb
|
|
4
|
+
|
|
5
|
+
describe Backends do
|
|
6
|
+
around(:each) do |example|
|
|
7
|
+
old_backends = Backends.all.dup
|
|
8
|
+
Backends.all.clear
|
|
9
|
+
example.run
|
|
10
|
+
Backends.all.replace(old_backends)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe '.register' do
|
|
14
|
+
it 'adds a backend' do
|
|
15
|
+
Backends.register(:foo, :bar)
|
|
16
|
+
expect(Backends.all).to include(foo: :bar)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe '.get' do
|
|
21
|
+
it "looks up a backend by it's name" do
|
|
22
|
+
Backends.register(:foo, :bar)
|
|
23
|
+
expect(Backends.get(:foo)).to eq(:bar)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'returns nil if no backend can be found' do
|
|
27
|
+
expect(Backends.get(:foo)).to be_nil
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
data/spec/config_spec.rb
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'spec_helpers/test_db'
|
|
3
|
+
require 'tempfile'
|
|
4
|
+
require 'yaml'
|
|
5
|
+
|
|
6
|
+
describe Txdb::Config do
|
|
7
|
+
before(:each) do
|
|
8
|
+
# clear out config before each test
|
|
9
|
+
Txdb::Config.instance_variable_set(:@databases, nil)
|
|
10
|
+
Txdb::Config.instance_variable_set(:@raw_config, nil)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe '.databases' do
|
|
14
|
+
it 'loads config from a string' do
|
|
15
|
+
with_env('TXDB_CONFIG' => "raw://#{YAML.dump(TestDb.raw_config)}") do
|
|
16
|
+
expect(Txdb::Config.databases.size).to eq(1)
|
|
17
|
+
database = Txdb::Config.databases.first
|
|
18
|
+
|
|
19
|
+
expect(database.adapter).to eq('sqlite')
|
|
20
|
+
expect(database.transifex_project.organization).to eq('myorg')
|
|
21
|
+
expect(database.tables.size).to eq(1)
|
|
22
|
+
expect(database.tables.first.name).to eq('my_table')
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'loads config from a file' do
|
|
27
|
+
file = Tempfile.new('translations')
|
|
28
|
+
file.write(YAML.dump(TestDb.raw_config))
|
|
29
|
+
file.flush
|
|
30
|
+
|
|
31
|
+
with_env('TXDB_CONFIG' => "file://#{file.path}") do
|
|
32
|
+
expect(Txdb::Config.databases.size).to eq(1)
|
|
33
|
+
database = Txdb::Config.databases.first
|
|
34
|
+
|
|
35
|
+
expect(database.adapter).to eq('sqlite')
|
|
36
|
+
expect(database.transifex_project.organization).to eq('myorg')
|
|
37
|
+
expect(database.tables.size).to eq(1)
|
|
38
|
+
expect(database.tables.first.name).to eq('my_table')
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
file.close
|
|
42
|
+
file.unlink
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
describe '.each_table' do
|
|
47
|
+
it 'returns an enumerator' do
|
|
48
|
+
expect(Txdb::Config.each_table).to be_a(Enumerator)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'yields each table in each database' do
|
|
52
|
+
# set up another database with another table so we can make sure the
|
|
53
|
+
# method loops over more than one db, yielding tables from each
|
|
54
|
+
config = TestDb.raw_config.dup
|
|
55
|
+
config[:databases] = config[:databases].dup
|
|
56
|
+
config[:databases] << config[:databases].first.merge(
|
|
57
|
+
database: 'spec/test2.sqlite3',
|
|
58
|
+
tables: [
|
|
59
|
+
name: 'another_table',
|
|
60
|
+
source_lang: 'en',
|
|
61
|
+
columns: %w(col1 col2)
|
|
62
|
+
]
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
with_env('TXDB_CONFIG' => "raw://#{YAML.dump(config)}") do
|
|
66
|
+
result = Txdb::Config.each_table.to_a
|
|
67
|
+
expect(result.map(&:name)).to eq(%w(my_table another_table))
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
include Txdb
|
|
4
|
+
|
|
5
|
+
describe ConnectionString do
|
|
6
|
+
describe '#string' do
|
|
7
|
+
let(:options) do
|
|
8
|
+
{
|
|
9
|
+
username: 'janeway', password: 'borgsuck',
|
|
10
|
+
host: 'voyager', port: 3306, database: 'stellar_cartography'
|
|
11
|
+
}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'assembles the correct string for mysql2' do
|
|
15
|
+
string = ConnectionString.new(options.merge(adapter: 'mysql2')).string
|
|
16
|
+
expect(string).to eq('mysql2://janeway:borgsuck@voyager:3306/stellar_cartography')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'assembles the correct string for sqlite' do
|
|
20
|
+
string = ConnectionString.new(options.merge(adapter: 'sqlite')).string
|
|
21
|
+
expect(string).to eq('sqlite://stellar_cartography')
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'spec_helpers/test_db'
|
|
3
|
+
|
|
4
|
+
include Txdb
|
|
5
|
+
|
|
6
|
+
describe Database, test_db: true do
|
|
7
|
+
let(:database) { TestDb.database }
|
|
8
|
+
|
|
9
|
+
describe '#db' do
|
|
10
|
+
it 'provides access to the database connection' do
|
|
11
|
+
expect(database.db).to be_a(Sequel::SQLite::Database)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'sets the max number of connections as specified in the config' do
|
|
15
|
+
expect(database.db.pool.max_size).to eq(database.pool)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe '#from' do
|
|
20
|
+
it 'returns a data set to query the given table' do
|
|
21
|
+
set = database.from(:foo)
|
|
22
|
+
expect(set).to be_a(Sequel::Dataset)
|
|
23
|
+
expect(set.sql).to eq("SELECT * FROM `foo`")
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe '#transifex_api' do
|
|
28
|
+
it 'grabs the api instance from the transifex project' do
|
|
29
|
+
expect(database.transifex_api).to be_a(Txgh::TransifexApi)
|
|
30
|
+
expect(database.transifex_api).to eq(database.transifex_project.api)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'spec_helpers/test_db'
|
|
3
|
+
require 'spec_helpers/test_backend'
|
|
4
|
+
|
|
5
|
+
include Txdb
|
|
6
|
+
|
|
7
|
+
describe Downloader, test_db: true do
|
|
8
|
+
let(:database) { Txdb::Config.databases.first }
|
|
9
|
+
let(:downloader) { Downloader.new(database) }
|
|
10
|
+
let(:transifex_api) { double(:transifex_api) }
|
|
11
|
+
|
|
12
|
+
before(:each) do
|
|
13
|
+
allow(database.transifex_project).to(
|
|
14
|
+
receive(:api).and_return(transifex_api)
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe '#download' do
|
|
19
|
+
it 'downloads translations from Transifex and writes them to the db' do
|
|
20
|
+
expect(transifex_api).to receive(:download) do |resource, locale|
|
|
21
|
+
expect(resource.project_slug).to eq('myproject')
|
|
22
|
+
expect(resource.resource_slug).to eq('spec_test.sqlite3-my_table')
|
|
23
|
+
expect(locale).to eq('es')
|
|
24
|
+
YAML.dump('widgets')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
expect { downloader.download('es') }.to(
|
|
28
|
+
change { TestBackend.writes.size }.from(0).to(1)
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
expect(TestBackend.writes.first).to eq(
|
|
32
|
+
table: database.tables.first.name, locale: 'es', content: 'widgets'
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'spec_helpers/test_backend'
|
|
3
|
+
require 'spec_helpers/test_db'
|
|
4
|
+
require 'uri'
|
|
5
|
+
require 'yaml'
|
|
6
|
+
|
|
7
|
+
include Txdb::Handlers
|
|
8
|
+
|
|
9
|
+
describe HookHandler do
|
|
10
|
+
include Rack::Test::Methods
|
|
11
|
+
|
|
12
|
+
let(:database) { TestDb.database }
|
|
13
|
+
let(:table) { database.tables.first }
|
|
14
|
+
let(:project) { database.transifex_project }
|
|
15
|
+
|
|
16
|
+
def app
|
|
17
|
+
Txdb::Hooks
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
before(:each) do
|
|
21
|
+
allow(Txdb::Config).to receive(:databases).and_return([database])
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def sign(body)
|
|
25
|
+
Txgh::TransifexRequestAuth.header_value(
|
|
26
|
+
body, project.webhook_secret
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "doesn't write content when unauthorized" do
|
|
31
|
+
params = { 'resource' => table.resource.resource_slug, 'language' => 'es' }
|
|
32
|
+
body = URI.encode_www_form(params.to_a)
|
|
33
|
+
post '/transifex', body
|
|
34
|
+
|
|
35
|
+
expect(last_response.status).to eq(200)
|
|
36
|
+
expect(last_response.body).to eq('{}')
|
|
37
|
+
|
|
38
|
+
expect(Txdb::TestBackend.writes).to be_empty
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
context 'with an authorized request' do
|
|
42
|
+
let(:content) { { 'phrase' => 'trans' } }
|
|
43
|
+
let(:params) { { 'resource' => table.resource.resource_slug, 'language' => 'es' } }
|
|
44
|
+
let(:body) { URI.encode_www_form(params.to_a) }
|
|
45
|
+
let(:headers) { { Txgh::TransifexRequestAuth::RACK_HEADER => sign(body) } }
|
|
46
|
+
|
|
47
|
+
it 'downloads and writes new content to the database' do
|
|
48
|
+
expect(project.api).to receive(:download).and_return(YAML.dump(content))
|
|
49
|
+
|
|
50
|
+
expect { post('/transifex', body, headers) }.to(
|
|
51
|
+
change { Txdb::TestBackend.writes.size }.from(0).to(1)
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
expect(last_response.status).to eq(200)
|
|
55
|
+
expect(last_response.body).to eq('{}')
|
|
56
|
+
|
|
57
|
+
expect(Txdb::TestBackend.writes).to include(
|
|
58
|
+
locale: 'es', table: table.name, content: content
|
|
59
|
+
)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'reports errors' do
|
|
63
|
+
expect(project.api).to receive(:download).and_raise('jelly beans')
|
|
64
|
+
|
|
65
|
+
post '/transifex', body, headers
|
|
66
|
+
|
|
67
|
+
expect(last_response.status).to eq(500)
|
|
68
|
+
expect(JSON.parse(last_response.body)).to eq(
|
|
69
|
+
[{ 'error' => 'Internal server error: jelly beans' }]
|
|
70
|
+
)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|