txdb 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/ext/txgh/tx_resource.rb +18 -0
- data/lib/txdb.rb +2 -0
- data/lib/txdb/backends/globalize/backend.rb +8 -2
- data/lib/txdb/backends/globalize/helpers.rb +4 -0
- data/lib/txdb/backends/globalize/reader.rb +34 -1
- data/lib/txdb/backends/globalize/writer.rb +37 -11
- data/lib/txdb/downloader.rb +28 -2
- data/lib/txdb/handlers/hook_handler.rb +41 -13
- data/lib/txdb/handlers/triggers/handler.rb +5 -14
- data/lib/txdb/handlers/triggers/pull_handler.rb +8 -11
- data/lib/txdb/handlers/triggers/push_handler.rb +1 -4
- data/lib/txdb/table.rb +3 -12
- data/lib/txdb/tx_resource.rb +6 -40
- data/lib/txdb/uploader.rb +5 -3
- data/lib/txdb/version.rb +1 -1
- data/spec/backends/globalize/helpers_spec.rb +13 -1
- data/spec/backends/globalize/reader_spec.rb +20 -7
- data/spec/backends/globalize/writer_spec.rb +72 -18
- data/spec/downloader_spec.rb +24 -6
- data/spec/handlers/hook_handler_spec.rb +31 -19
- data/spec/handlers/triggers/pull_handler_spec.rb +17 -6
- data/spec/spec_helper.rb +2 -0
- data/spec/spec_helpers/test_backend.rb +22 -3
- data/spec/table_spec.rb +7 -28
- data/spec/test.sqlite3 +0 -0
- data/spec/uploader_spec.rb +3 -9
- metadata +3 -3
- data/spec/tx_resource_spec.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e59bfc3e60354b89d0a572dc8639ecc1bec5146
|
4
|
+
data.tar.gz: 05599e91b876f536edabd4f05163f769fbf2a2c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7903d1a0966bc7428dce7de537418ba437e06e48ec95032c4fb21bcc513c8703552c28183be6e23b6271b2f5b921d8ebe5eb4e27500c005c3316590daa84f7a2
|
7
|
+
data.tar.gz: 470a4c9d4d8df0a31f8d8c1275384dab4ba8c487266a6093ad44299ba42e12f61ea0b750e1c814a9b5c2e289204b1b110b83bf8aa5c93c204beb2d74cd3a21e4
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'txgh'
|
2
|
+
|
3
|
+
module Txgh
|
4
|
+
class TxResource
|
5
|
+
class << self
|
6
|
+
def from_api_response(project_slug, response)
|
7
|
+
new(
|
8
|
+
project_slug,
|
9
|
+
response['slug'],
|
10
|
+
response['i18n_type'],
|
11
|
+
response['source_language_code'],
|
12
|
+
response['name'],
|
13
|
+
'', nil
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/txdb.rb
CHANGED
@@ -3,13 +3,19 @@ module Txdb
|
|
3
3
|
module Globalize
|
4
4
|
|
5
5
|
class Backend
|
6
|
+
RESOURCE_TYPE = 'YML'
|
7
|
+
|
6
8
|
class << self
|
7
9
|
def read_content_from(table)
|
8
10
|
Reader.new(table).read_content
|
9
11
|
end
|
10
12
|
|
11
|
-
def write_content_to(table,
|
12
|
-
Writer.new(table).write_content(
|
13
|
+
def write_content_to(table, resource, locale)
|
14
|
+
Writer.new(table).write_content(resource, locale)
|
15
|
+
end
|
16
|
+
|
17
|
+
def owns_resource?(table, resource)
|
18
|
+
resource.resource_slug == Helpers.resource_slug_for(table)
|
13
19
|
end
|
14
20
|
end
|
15
21
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'txgh'
|
2
|
+
|
1
3
|
module Txdb
|
2
4
|
module Backends
|
3
5
|
module Globalize
|
@@ -12,11 +14,42 @@ module Txdb
|
|
12
14
|
end
|
13
15
|
|
14
16
|
def read_content
|
15
|
-
|
17
|
+
[Txdb::TxResource.new(resource, serialized_content)]
|
16
18
|
end
|
17
19
|
|
18
20
|
private
|
19
21
|
|
22
|
+
def resource
|
23
|
+
@resource ||= Txgh::TxResource.new(
|
24
|
+
project_slug, resource_slug, Globalize::Backend::RESOURCE_TYPE,
|
25
|
+
source_lang, source_file, nil, nil
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
def project_slug
|
30
|
+
table.database.transifex_project.project_slug
|
31
|
+
end
|
32
|
+
|
33
|
+
def resource_slug
|
34
|
+
resource_slug_for(table)
|
35
|
+
end
|
36
|
+
|
37
|
+
def source_lang
|
38
|
+
table.source_lang
|
39
|
+
end
|
40
|
+
|
41
|
+
def source_file
|
42
|
+
table.name
|
43
|
+
end
|
44
|
+
|
45
|
+
def serialized_content
|
46
|
+
YAML.dump(content)
|
47
|
+
end
|
48
|
+
|
49
|
+
def content
|
50
|
+
@content ||= { origin_table_name(table.name) => content_for_records }
|
51
|
+
end
|
52
|
+
|
20
53
|
def content_for_records
|
21
54
|
each_record.each_with_object({}) do |record, ret|
|
22
55
|
ret[record[:id]] = content_for_record(record)
|
@@ -13,22 +13,48 @@ module Txdb
|
|
13
13
|
@table = table
|
14
14
|
end
|
15
15
|
|
16
|
-
def write_content(
|
17
|
-
content
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
foreign_key.to_sym => id, locale: locale
|
23
|
-
)
|
24
|
-
else
|
25
|
-
row.update(fields)
|
26
|
-
end
|
16
|
+
def write_content(resource, locale)
|
17
|
+
content = deserialize_content(resource.content)
|
18
|
+
content = content.fetch(origin_table_name(table.name), {})
|
19
|
+
|
20
|
+
content.each_pair do |id, fields|
|
21
|
+
update_row(id, fields, locale)
|
27
22
|
end
|
28
23
|
end
|
29
24
|
|
30
25
|
private
|
31
26
|
|
27
|
+
def update_row(id, fields, locale)
|
28
|
+
row = table.db.where(foreign_key.to_sym => id, locale: locale)
|
29
|
+
|
30
|
+
if row.empty?
|
31
|
+
table.db << fields
|
32
|
+
.merge(foreign_key.to_sym => id, locale: locale)
|
33
|
+
.merge(created_at)
|
34
|
+
.merge(updated_at)
|
35
|
+
else
|
36
|
+
row.update(fields.merge(updated_at))
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def created_at
|
41
|
+
return {} unless table.db.columns.include?(:created_at)
|
42
|
+
{ created_at: get_utc_time }
|
43
|
+
end
|
44
|
+
|
45
|
+
def updated_at
|
46
|
+
return {} unless table.db.columns.include?(:updated_at)
|
47
|
+
{ updated_at: get_utc_time }
|
48
|
+
end
|
49
|
+
|
50
|
+
def get_utc_time
|
51
|
+
Time.now.utc
|
52
|
+
end
|
53
|
+
|
54
|
+
def deserialize_content(content)
|
55
|
+
YAML.load(content)
|
56
|
+
end
|
57
|
+
|
32
58
|
def foreign_key
|
33
59
|
@foreign_key ||= table.name.sub(/_translations/, '_id')
|
34
60
|
end
|
data/lib/txdb/downloader.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'txgh'
|
2
|
+
|
1
3
|
module Txdb
|
2
4
|
class Downloader
|
3
5
|
class << self
|
@@ -19,14 +21,38 @@ module Txdb
|
|
19
21
|
end
|
20
22
|
|
21
23
|
def download_table(table, locale)
|
22
|
-
|
23
|
-
|
24
|
+
resources.each do |tx_resource|
|
25
|
+
next unless process_resource?(tx_resource, table)
|
26
|
+
download_resource(tx_resource, table, locale)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def download_resource(tx_resource, table, locale)
|
31
|
+
content = transifex_api.download(tx_resource, locale)
|
32
|
+
resource = Txdb::TxResource.new(tx_resource, content)
|
33
|
+
table.write_content(resource, locale)
|
24
34
|
end
|
25
35
|
|
26
36
|
private
|
27
37
|
|
38
|
+
def process_resource?(resource, table)
|
39
|
+
database.backend.owns_resource?(table, resource)
|
40
|
+
end
|
41
|
+
|
42
|
+
def project_slug
|
43
|
+
database.transifex_project.project_slug
|
44
|
+
end
|
45
|
+
|
28
46
|
def transifex_api
|
29
47
|
database.transifex_api
|
30
48
|
end
|
49
|
+
|
50
|
+
def resources
|
51
|
+
@resources ||= transifex_api
|
52
|
+
.get_resources(project_slug)
|
53
|
+
.map do |resource_hash|
|
54
|
+
Txgh::TxResource.from_api_response(project_slug, resource_hash)
|
55
|
+
end
|
56
|
+
end
|
31
57
|
end
|
32
58
|
end
|
@@ -19,11 +19,8 @@ module Txdb
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def handle
|
22
|
-
|
23
|
-
|
24
|
-
table.write_content(content, locale)
|
25
|
-
end
|
26
|
-
|
22
|
+
return respond_with_error(401, 'Unauthorized') unless authentic_request?
|
23
|
+
downloader.download_resource(resource, table, locale)
|
27
24
|
respond_with(200, {})
|
28
25
|
rescue => e
|
29
26
|
respond_with_error(500, "Internal server error: #{e.message}", e)
|
@@ -31,23 +28,54 @@ module Txdb
|
|
31
28
|
|
32
29
|
private
|
33
30
|
|
34
|
-
def
|
35
|
-
|
31
|
+
def downloader
|
32
|
+
@downloader ||= Txdb::Downloader.new(database)
|
36
33
|
end
|
37
34
|
|
38
|
-
def
|
39
|
-
@
|
40
|
-
|
41
|
-
authentic_request?(table.database.transifex_project)
|
35
|
+
def database
|
36
|
+
@database ||= Txdb::Config.databases.find do |database|
|
37
|
+
database.transifex_project.project_slug == project_slug
|
42
38
|
end
|
43
39
|
end
|
44
40
|
|
45
|
-
def
|
41
|
+
def table
|
42
|
+
@table ||= database.tables.find do |table|
|
43
|
+
database.backend.owns_resource?(table, resource)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def resource
|
48
|
+
@resource ||= Txgh::TxResource.from_api_response(
|
49
|
+
project_slug, transifex_api.get_resource(project_slug, resource_slug)
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
def transifex_project
|
54
|
+
database.transifex_project
|
55
|
+
end
|
56
|
+
|
57
|
+
def authentic_request?
|
46
58
|
Txgh::TransifexRequestAuth.authentic_request?(
|
47
|
-
request,
|
59
|
+
request, transifex_project.webhook_secret
|
48
60
|
)
|
49
61
|
end
|
50
62
|
|
63
|
+
def transifex_api
|
64
|
+
database.transifex_api
|
65
|
+
end
|
66
|
+
|
67
|
+
def project_slug
|
68
|
+
payload['project']
|
69
|
+
end
|
70
|
+
|
71
|
+
def resource_slug
|
72
|
+
payload['resource']
|
73
|
+
end
|
74
|
+
|
75
|
+
def locale
|
76
|
+
payload['language']
|
77
|
+
end
|
78
|
+
|
51
79
|
def payload
|
52
80
|
@payload ||= begin
|
53
81
|
request.body.rewind
|
@@ -24,26 +24,17 @@ module Txdb
|
|
24
24
|
respond_with_error(500, "Internal server error: #{e.message}", e)
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
@
|
29
|
-
|
30
|
-
database.database == database_name
|
31
|
-
end
|
32
|
-
else
|
33
|
-
Txdb::Config.databases
|
27
|
+
def database
|
28
|
+
@database ||= Txdb::Config.databases.find do |database|
|
29
|
+
database.database == request.params['database']
|
34
30
|
end
|
35
31
|
end
|
36
32
|
|
37
|
-
def
|
38
|
-
@
|
33
|
+
def table
|
34
|
+
@table ||= database.tables.find do |table|
|
39
35
|
table.name == request.params['table']
|
40
36
|
end
|
41
37
|
end
|
42
|
-
|
43
|
-
def each_table_in(databases, &block)
|
44
|
-
return to_enum(__method__, databases) unless block_given?
|
45
|
-
databases.each { |database| database.tables.each(&block) }
|
46
|
-
end
|
47
38
|
end
|
48
39
|
end
|
49
40
|
end
|
@@ -5,10 +5,8 @@ module Txdb
|
|
5
5
|
class PullHandler < Handler
|
6
6
|
def handle
|
7
7
|
handle_safely do
|
8
|
-
|
9
|
-
|
10
|
-
Downloader.new(table.database).download_table(table, locale)
|
11
|
-
end
|
8
|
+
locales.each do |locale|
|
9
|
+
downloader.download_table(table, locale)
|
12
10
|
end
|
13
11
|
|
14
12
|
respond_with(200, {})
|
@@ -17,15 +15,14 @@ module Txdb
|
|
17
15
|
|
18
16
|
private
|
19
17
|
|
20
|
-
def
|
21
|
-
|
22
|
-
table.database.transifex_api
|
23
|
-
.get_languages(table.resource.project_slug)
|
24
|
-
.map { |locale| locale['language_code'] }
|
18
|
+
def downloader
|
19
|
+
@downloader ||= Downloader.new(database)
|
25
20
|
end
|
26
21
|
|
27
|
-
def
|
28
|
-
|
22
|
+
def locales
|
23
|
+
database.transifex_api
|
24
|
+
.get_languages(database.transifex_project.project_slug)
|
25
|
+
.map { |locale| locale['language_code'] }
|
29
26
|
end
|
30
27
|
end
|
31
28
|
|
data/lib/txdb/table.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'txgh'
|
2
|
-
require 'yaml'
|
3
2
|
|
4
3
|
module Txdb
|
5
4
|
class Table
|
@@ -17,20 +16,12 @@ module Txdb
|
|
17
16
|
database.db.from(name)
|
18
17
|
end
|
19
18
|
|
20
|
-
def resource
|
21
|
-
@resource ||= Txdb::TxResource.from_table(self)
|
22
|
-
end
|
23
|
-
|
24
19
|
def read_content
|
25
|
-
|
26
|
-
database.backend.read_content_from(self)
|
27
|
-
)
|
20
|
+
database.backend.read_content_from(self)
|
28
21
|
end
|
29
22
|
|
30
|
-
def write_content(
|
31
|
-
database.backend.write_content_to(
|
32
|
-
self, YAML.load(content), locale
|
33
|
-
)
|
23
|
+
def write_content(resource, locale)
|
24
|
+
database.backend.write_content_to(self, resource, locale)
|
34
25
|
end
|
35
26
|
end
|
36
27
|
end
|
data/lib/txdb/tx_resource.rb
CHANGED
@@ -1,52 +1,18 @@
|
|
1
|
-
require 'txgh'
|
2
|
-
|
3
1
|
module Txdb
|
4
2
|
class TxResource
|
5
|
-
|
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
|
3
|
+
attr_reader :original, :content
|
39
4
|
|
40
|
-
def initialize(
|
41
|
-
@
|
5
|
+
def initialize(original, content)
|
6
|
+
@original = original
|
7
|
+
@content = content
|
42
8
|
end
|
43
9
|
|
44
10
|
def respond_to?(method)
|
45
|
-
|
11
|
+
original.respond_to?(method)
|
46
12
|
end
|
47
13
|
|
48
14
|
def method_missing(method, *args, &block)
|
49
|
-
|
15
|
+
original.send(method, *args, &block)
|
50
16
|
end
|
51
17
|
end
|
52
18
|
end
|
data/lib/txdb/uploader.rb
CHANGED
@@ -19,9 +19,11 @@ module Txdb
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def upload_table(table)
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
table.read_content.each do |resource|
|
23
|
+
transifex_api.create_or_update(
|
24
|
+
resource.original, resource.content
|
25
|
+
)
|
26
|
+
end
|
25
27
|
end
|
26
28
|
|
27
29
|
private
|
data/lib/txdb/version.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'spec_helpers/test_db'
|
2
3
|
|
3
4
|
include Txdb::Backends
|
4
5
|
|
5
|
-
describe Globalize::Helpers do
|
6
|
+
describe Globalize::Helpers, test_db: true do
|
6
7
|
describe '.origin_table_name' do
|
7
8
|
it 'pluralizes and removes the translations suffix' do
|
8
9
|
origin = Globalize::Helpers.origin_table_name('widget_translations')
|
@@ -14,4 +15,15 @@ describe Globalize::Helpers do
|
|
14
15
|
expect(origin).to eq('oxen')
|
15
16
|
end
|
16
17
|
end
|
18
|
+
|
19
|
+
describe '#resource_slug_for' do
|
20
|
+
let(:database) { TestDb.database }
|
21
|
+
let(:table) { database.tables.first }
|
22
|
+
|
23
|
+
it 'constructs a slug from the database and table names' do
|
24
|
+
expect(Globalize::Helpers.resource_slug_for(table)).to eq(
|
25
|
+
'spec_test.sqlite3-my_table'
|
26
|
+
)
|
27
|
+
end
|
28
|
+
end
|
17
29
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'spec_helpers/globalize_db'
|
3
|
+
require 'yaml'
|
3
4
|
|
4
5
|
include Txdb::Backends
|
5
6
|
|
@@ -7,19 +8,31 @@ describe Globalize::Reader, globalize_db: true do
|
|
7
8
|
include_context :globalize
|
8
9
|
|
9
10
|
describe '#read_content' do
|
10
|
-
it 'reads data from the given table and
|
11
|
+
it 'reads data from the given table and returns an array of resources' do
|
11
12
|
sprocket_id = widgets.insert(name: 'sprocket')
|
12
13
|
flange_id = widgets.insert(name: 'flange')
|
13
14
|
widget_translations.insert(widget_id: sprocket_id, locale: 'es', name: 'sproqueta')
|
14
15
|
widget_translations.insert(widget_id: flange_id, locale: 'es', name: 'flango')
|
15
16
|
|
16
17
|
reader = Globalize::Reader.new(widget_translations_table)
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
resources = reader.read_content
|
19
|
+
expect(resources.size).to eq(1)
|
20
|
+
resource = resources.first
|
21
|
+
|
22
|
+
expect(resource.source_file).to eq(widget_translations_table.name)
|
23
|
+
expect(resource.project_slug).to eq(database.transifex_project.project_slug)
|
24
|
+
expect(resource.resource_slug).to(
|
25
|
+
eq(Globalize::Helpers.resource_slug_for(widget_translations_table))
|
26
|
+
)
|
27
|
+
|
28
|
+
expect(resource.content).to eq(
|
29
|
+
YAML.dump(
|
30
|
+
'widgets' => {
|
31
|
+
1 => { 'name' => 'sprocket' },
|
32
|
+
2 => { 'name' => 'flange' }
|
33
|
+
}
|
34
|
+
)
|
35
|
+
)
|
23
36
|
end
|
24
37
|
end
|
25
38
|
end
|
@@ -1,5 +1,8 @@
|
|
1
|
+
require 'active_support/core_ext/numeric/time'
|
1
2
|
require 'spec_helper'
|
2
3
|
require 'spec_helpers/globalize_db'
|
4
|
+
require 'timecop'
|
5
|
+
require 'yaml'
|
3
6
|
|
4
7
|
include Txdb::Backends
|
5
8
|
|
@@ -7,25 +10,74 @@ describe Globalize::Writer, globalize_db: true do
|
|
7
10
|
include_context :globalize
|
8
11
|
|
9
12
|
describe '#write_content' do
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
+
let(:base_resource) do
|
14
|
+
# project_slug, resource_slug, type, source_lang, source_file,
|
15
|
+
# lang_map, translation_file
|
16
|
+
Txgh::TxResource.new(
|
17
|
+
'project_slug', 'resource_slug', Globalize::Backend::RESOURCE_TYPE,
|
18
|
+
'source_lang', 'source_file', nil, nil
|
19
|
+
)
|
20
|
+
end
|
13
21
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
}
|
22
|
+
context 'with some content' do
|
23
|
+
before(:each) do
|
24
|
+
@sprocket_id = widgets.insert(name: 'sprocket')
|
25
|
+
@writer = Globalize::Writer.new(widget_translations_table)
|
19
26
|
|
20
|
-
|
21
|
-
|
22
|
-
|
27
|
+
@content = YAML.dump(
|
28
|
+
'widgets' => {
|
29
|
+
@sprocket_id => { name: 'sproqueta' }
|
30
|
+
}
|
31
|
+
)
|
23
32
|
|
24
|
-
|
33
|
+
@resource = Txdb::TxResource.new(base_resource, @content)
|
34
|
+
end
|
25
35
|
|
26
|
-
|
27
|
-
|
28
|
-
|
36
|
+
it 'inserts the translations into the database' do
|
37
|
+
expect { @writer.write_content(@resource, 'es') }.to(
|
38
|
+
change { widget_translations.count }.from(0).to(1)
|
39
|
+
)
|
40
|
+
|
41
|
+
translation = widget_translations.first
|
42
|
+
|
43
|
+
expect(translation).to include(
|
44
|
+
widget_id: @sprocket_id, name: 'sproqueta', locale: 'es'
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'with created_at and updated_at columns' do
|
49
|
+
before(:each) do
|
50
|
+
GlobalizeDb.db.alter_table(:widget_translations) do
|
51
|
+
add_column :created_at, Time
|
52
|
+
add_column :updated_at, Time
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'fills in the created_at and updated_at columns' do
|
57
|
+
Timecop.freeze(Time.now) do
|
58
|
+
@writer.write_content(@resource, 'es')
|
59
|
+
translation = widget_translations.first
|
60
|
+
expect(translation[:created_at].to_i).to eq(Time.now.utc.to_i)
|
61
|
+
expect(translation[:updated_at].to_i).to eq(Time.now.utc.to_i)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'updates the updated_at column if the record already exists' do
|
66
|
+
@writer.write_content(@resource, 'es')
|
67
|
+
|
68
|
+
today = Time.now + 1.day # groundhog day
|
69
|
+
|
70
|
+
Timecop.freeze(today) do
|
71
|
+
translation = widget_translations.first
|
72
|
+
expect(translation[:updated_at].to_i).to_not eq(today.utc.to_i)
|
73
|
+
|
74
|
+
# record already exists, so should get updated with new timestamp
|
75
|
+
@writer.write_content(@resource, 'es')
|
76
|
+
translation = widget_translations.first
|
77
|
+
expect(translation[:updated_at].to_i).to eq(today.utc.to_i)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
29
81
|
end
|
30
82
|
|
31
83
|
it 'updates the record if it already exists' do
|
@@ -36,13 +88,15 @@ describe Globalize::Writer, globalize_db: true do
|
|
36
88
|
|
37
89
|
writer = Globalize::Writer.new(widget_translations_table)
|
38
90
|
|
39
|
-
content =
|
91
|
+
content = YAML.dump(
|
40
92
|
'widgets' => {
|
41
93
|
sprocket_id => { name: 'sproqueta2' }
|
42
94
|
}
|
43
|
-
|
95
|
+
)
|
96
|
+
|
97
|
+
resource = Txdb::TxResource.new(base_resource, content)
|
44
98
|
|
45
|
-
expect { writer.write_content(
|
99
|
+
expect { writer.write_content(resource, 'es') }.to_not(
|
46
100
|
change { widget_translations.count }
|
47
101
|
)
|
48
102
|
|
data/spec/downloader_spec.rb
CHANGED
@@ -5,7 +5,7 @@ require 'spec_helpers/test_backend'
|
|
5
5
|
include Txdb
|
6
6
|
|
7
7
|
describe Downloader, test_db: true do
|
8
|
-
let(:database) {
|
8
|
+
let(:database) { TestDb.database }
|
9
9
|
let(:downloader) { Downloader.new(database) }
|
10
10
|
let(:transifex_api) { double(:transifex_api) }
|
11
11
|
|
@@ -17,20 +17,38 @@ describe Downloader, test_db: true do
|
|
17
17
|
|
18
18
|
describe '#download' do
|
19
19
|
it 'downloads translations from Transifex and writes them to the db' do
|
20
|
+
expect(transifex_api).to(
|
21
|
+
receive(:get_resources)
|
22
|
+
.with(database.transifex_project.project_slug)
|
23
|
+
.and_return([{
|
24
|
+
'slug' => 'fake_resource_slug',
|
25
|
+
'i18n_type' => 'fake_i18n_type',
|
26
|
+
'source_language_code' => 'en',
|
27
|
+
'name' => 'fake_name',
|
28
|
+
}])
|
29
|
+
)
|
30
|
+
|
31
|
+
content = YAML.dump({ foo: 'bar' })
|
32
|
+
|
20
33
|
expect(transifex_api).to receive(:download) do |resource, locale|
|
21
34
|
expect(resource.project_slug).to eq('myproject')
|
22
|
-
expect(resource.resource_slug).to eq('
|
35
|
+
expect(resource.resource_slug).to eq('fake_resource_slug')
|
23
36
|
expect(locale).to eq('es')
|
24
|
-
|
37
|
+
content
|
25
38
|
end
|
26
39
|
|
27
40
|
expect { downloader.download('es') }.to(
|
28
41
|
change { TestBackend.writes.size }.from(0).to(1)
|
29
42
|
)
|
30
43
|
|
31
|
-
|
32
|
-
|
33
|
-
)
|
44
|
+
write = TestBackend.writes.first
|
45
|
+
expect(write[:table]).to eq(database.tables.first.name)
|
46
|
+
expect(write[:locale]).to eq('es')
|
47
|
+
|
48
|
+
expect(write[:resource]).to be_a(Txdb::TxResource)
|
49
|
+
expect(write[:resource].project_slug).to eq('myproject')
|
50
|
+
expect(write[:resource].resource_slug).to eq('fake_resource_slug')
|
51
|
+
expect(write[:resource].content).to eq(content)
|
34
52
|
end
|
35
53
|
end
|
36
54
|
end
|
@@ -4,6 +4,7 @@ require 'spec_helpers/test_db'
|
|
4
4
|
require 'uri'
|
5
5
|
require 'yaml'
|
6
6
|
|
7
|
+
include Txdb
|
7
8
|
include Txdb::Handlers
|
8
9
|
|
9
10
|
describe HookHandler do
|
@@ -12,6 +13,16 @@ describe HookHandler do
|
|
12
13
|
let(:database) { TestDb.database }
|
13
14
|
let(:table) { database.tables.first }
|
14
15
|
let(:project) { database.transifex_project }
|
16
|
+
let(:resource) { TestBackend.resource }
|
17
|
+
|
18
|
+
let(:body) { URI.encode_www_form(params.to_a) }
|
19
|
+
let(:params) do
|
20
|
+
{
|
21
|
+
'project' => resource.project_slug,
|
22
|
+
'resource' => resource.resource_slug,
|
23
|
+
'language' => 'es'
|
24
|
+
}
|
25
|
+
end
|
15
26
|
|
16
27
|
def app
|
17
28
|
Txdb::Hooks
|
@@ -21,48 +32,49 @@ describe HookHandler do
|
|
21
32
|
allow(Txdb::Config).to receive(:databases).and_return([database])
|
22
33
|
end
|
23
34
|
|
24
|
-
def sign(body)
|
25
|
-
Txgh::TransifexRequestAuth.header_value(
|
26
|
-
body, project.webhook_secret
|
27
|
-
)
|
28
|
-
end
|
29
|
-
|
30
35
|
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
36
|
post '/transifex', body
|
34
37
|
|
35
|
-
expect(last_response.status).to eq(
|
36
|
-
expect(last_response.body).to eq('
|
38
|
+
expect(last_response.status).to eq(401)
|
39
|
+
expect(JSON.parse(last_response.body)).to eq([{ 'error' => 'Unauthorized' }])
|
37
40
|
|
38
41
|
expect(Txdb::TestBackend.writes).to be_empty
|
39
42
|
end
|
40
43
|
|
41
44
|
context 'with an authorized request' do
|
42
45
|
let(:content) { { 'phrase' => 'trans' } }
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
+
|
47
|
+
before(:each) do
|
48
|
+
header(
|
49
|
+
Txgh::TransifexRequestAuth::TRANSIFEX_HEADER,
|
50
|
+
Txgh::TransifexRequestAuth.header_value(body, project.webhook_secret)
|
51
|
+
)
|
52
|
+
end
|
46
53
|
|
47
54
|
it 'downloads and writes new content to the database' do
|
55
|
+
expect(project.api).to receive(:get_resource).and_return(resource.to_api_h)
|
48
56
|
expect(project.api).to receive(:download).and_return(YAML.dump(content))
|
49
57
|
|
50
|
-
expect { post('/transifex', body
|
58
|
+
expect { post('/transifex', body) }.to(
|
51
59
|
change { Txdb::TestBackend.writes.size }.from(0).to(1)
|
52
60
|
)
|
53
61
|
|
54
62
|
expect(last_response.status).to eq(200)
|
55
63
|
expect(last_response.body).to eq('{}')
|
56
64
|
|
57
|
-
|
58
|
-
|
59
|
-
)
|
65
|
+
write = Txdb::TestBackend.writes.first
|
66
|
+
|
67
|
+
expect(write[:locale]).to eq('es')
|
68
|
+
expect(write[:table]).to eq(table.name)
|
69
|
+
expect(write[:resource]).to be_a(Txdb::TxResource)
|
70
|
+
expect(write[:resource].project_slug).to eq(resource.project_slug)
|
71
|
+
expect(write[:resource].resource_slug).to eq(resource.resource_slug)
|
60
72
|
end
|
61
73
|
|
62
74
|
it 'reports errors' do
|
63
|
-
expect(project.api).to receive(:
|
75
|
+
expect(project.api).to receive(:get_resource).and_raise('jelly beans')
|
64
76
|
|
65
|
-
post '/transifex', body
|
77
|
+
post '/transifex', body
|
66
78
|
|
67
79
|
expect(last_response.status).to eq(500)
|
68
80
|
expect(JSON.parse(last_response.body)).to eq(
|
@@ -28,8 +28,12 @@ describe PullHandler do
|
|
28
28
|
it 'downloads the table for each locale' do
|
29
29
|
locales = [{ 'language_code' => 'es' }, { 'language_code' => 'ja' }]
|
30
30
|
content = { 'phrase' => 'trans' }
|
31
|
+
|
31
32
|
expect(database.transifex_api).to receive(:get_languages).and_return(locales)
|
32
33
|
allow(database.transifex_api).to receive(:download).and_return(YAML.dump(content))
|
34
|
+
expect(database.transifex_api).to receive(:get_resources).and_return(
|
35
|
+
[Txdb::TestBackend.resource.to_api_h]
|
36
|
+
)
|
33
37
|
|
34
38
|
expect { patch('/pull', params) }.to(
|
35
39
|
change { Txdb::TestBackend.writes.size }.from(0).to(2)
|
@@ -38,13 +42,20 @@ describe PullHandler do
|
|
38
42
|
expect(last_response.status).to eq(200)
|
39
43
|
expect(last_response.body).to eq('{}')
|
40
44
|
|
41
|
-
expect(Txdb::TestBackend.writes).to
|
42
|
-
|
43
|
-
)
|
45
|
+
expect(Txdb::TestBackend.writes.first[:locale]).to eq('es')
|
46
|
+
expect(Txdb::TestBackend.writes.last[:locale]).to eq('ja')
|
44
47
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
+
Txdb::TestBackend.writes.each do |write|
|
49
|
+
expect(write[:table]).to eq(table.name)
|
50
|
+
|
51
|
+
expect(write[:resource].project_slug).to(
|
52
|
+
eq(Txdb::TestBackend.resource.project_slug)
|
53
|
+
)
|
54
|
+
|
55
|
+
expect(write[:resource].resource_slug).to(
|
56
|
+
eq(Txdb::TestBackend.resource.resource_slug)
|
57
|
+
)
|
58
|
+
end
|
48
59
|
end
|
49
60
|
|
50
61
|
it 'reports errors' do
|
data/spec/spec_helper.rb
CHANGED
@@ -16,13 +16,32 @@ module Txdb
|
|
16
16
|
|
17
17
|
def read_content_from(table)
|
18
18
|
reads << { table: table.name }
|
19
|
-
|
19
|
+
[resource]
|
20
20
|
end
|
21
21
|
|
22
|
-
def write_content_to(table,
|
23
|
-
writes << { table: table.name,
|
22
|
+
def write_content_to(table, resource, locale)
|
23
|
+
writes << { table: table.name, resource: resource, locale: locale }
|
24
24
|
nil
|
25
25
|
end
|
26
|
+
|
27
|
+
def owns_resource?(table, resource)
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
def base_resource
|
32
|
+
@base_resource ||= Txgh::TxResource.new(
|
33
|
+
'myproject', 'resource_slug', 'type',
|
34
|
+
'source_lang', 'source_file', nil, nil
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
def content
|
39
|
+
@content ||= 'fake content'
|
40
|
+
end
|
41
|
+
|
42
|
+
def resource
|
43
|
+
@resource ||= Txdb::TxResource.new(base_resource, content)
|
44
|
+
end
|
26
45
|
end
|
27
46
|
end
|
28
47
|
end
|
data/spec/table_spec.rb
CHANGED
@@ -15,44 +15,23 @@ describe Table, test_db: true do
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
describe '#resource' do
|
19
|
-
it 'creates a TxResource from the table' do
|
20
|
-
resource = table.resource
|
21
|
-
expect(resource).to be_a(Txdb::TxResource)
|
22
|
-
expect(resource.project_slug).to eq('myproject')
|
23
|
-
expect(resource.resource_slug).to eq(
|
24
|
-
Txgh::Utils.slugify("#{database.database}-#{table.name}")
|
25
|
-
)
|
26
|
-
expect(resource.source_file).to eq(table.name)
|
27
|
-
expect(resource.source_lang).to eq('en')
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
18
|
describe '#read_content' do
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
expect(database.backend).to(
|
36
|
-
receive(:read_content_from).and_return(content)
|
37
|
-
)
|
38
|
-
|
39
|
-
expect(table.read_content).to eq(YAML.dump(content))
|
19
|
+
it 'proxies to the backend' do
|
20
|
+
expect(database.backend).to receive(:read_content_from)
|
21
|
+
table.read_content
|
40
22
|
end
|
41
23
|
end
|
42
24
|
|
43
25
|
describe '#write_content' do
|
44
|
-
|
45
|
-
let(:locale) { 'es' }
|
46
|
-
|
47
|
-
it 'parses and writes the content to the database' do
|
26
|
+
it 'proxies to the backend' do
|
48
27
|
expect(database.backend).to(
|
49
28
|
receive(:write_content_to) do |_, cont, loc|
|
50
|
-
expect(cont).to eq(content)
|
51
|
-
expect(loc).to eq(locale)
|
29
|
+
expect(cont).to eq(:content)
|
30
|
+
expect(loc).to eq(:locale)
|
52
31
|
end
|
53
32
|
)
|
54
33
|
|
55
|
-
table.write_content(
|
34
|
+
table.write_content(:content, :locale)
|
56
35
|
end
|
57
36
|
end
|
58
37
|
end
|
data/spec/test.sqlite3
CHANGED
Binary file
|
data/spec/uploader_spec.rb
CHANGED
@@ -5,7 +5,7 @@ require 'spec_helpers/test_backend'
|
|
5
5
|
include Txdb
|
6
6
|
|
7
7
|
describe Uploader, test_db: true do
|
8
|
-
let(:database) {
|
8
|
+
let(:database) { TestDb.database }
|
9
9
|
let(:uploader) { Uploader.new(database) }
|
10
10
|
let(:transifex_api) { double(:transifex_api) }
|
11
11
|
|
@@ -18,19 +18,13 @@ describe Uploader, test_db: true do
|
|
18
18
|
describe '#upload' do
|
19
19
|
it 'reads phrases from the database and uploads them to Transifex' do
|
20
20
|
expect(transifex_api).to receive(:create_or_update) do |resource, content|
|
21
|
-
expect(resource.project_slug).to eq(
|
22
|
-
expect(resource.resource_slug).to(
|
23
|
-
eq(Txgh::Utils.slugify("#{database.database}-#{database.tables.first.name}"))
|
24
|
-
)
|
21
|
+
expect(resource.project_slug).to eq(TestBackend.resource.project_slug)
|
22
|
+
expect(resource.resource_slug).to eq(TestBackend.resource.resource_slug)
|
25
23
|
end
|
26
24
|
|
27
25
|
expect { uploader.upload }.to(
|
28
26
|
change { TestBackend.reads.size }.from(0).to(1)
|
29
27
|
)
|
30
|
-
|
31
|
-
expect(TestBackend.reads.first).to eq(
|
32
|
-
table: database.tables.first.name
|
33
|
-
)
|
34
28
|
end
|
35
29
|
end
|
36
30
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: txdb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cameron Dutro
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-05-
|
11
|
+
date: 2016-05-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -61,6 +61,7 @@ extra_rdoc_files: []
|
|
61
61
|
files:
|
62
62
|
- LICENSE
|
63
63
|
- README.md
|
64
|
+
- lib/ext/txgh/tx_resource.rb
|
64
65
|
- lib/txdb.rb
|
65
66
|
- lib/txdb/app.rb
|
66
67
|
- lib/txdb/backends.rb
|
@@ -105,7 +106,6 @@ files:
|
|
105
106
|
- spec/table_spec.rb
|
106
107
|
- spec/test.sqlite3
|
107
108
|
- spec/transifex_project_spec.rb
|
108
|
-
- spec/tx_resource_spec.rb
|
109
109
|
- spec/uploader_spec.rb
|
110
110
|
- txdb.gemspec
|
111
111
|
homepage: https://github.com/lumoslabs/txdb
|
data/spec/tx_resource_spec.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'spec_helpers/test_db'
|
3
|
-
|
4
|
-
include Txdb
|
5
|
-
|
6
|
-
describe TxResource, test_db: true do
|
7
|
-
let(:database) { TestDb.database }
|
8
|
-
let(:table) { database.tables.first }
|
9
|
-
let(:resource) { table.resource }
|
10
|
-
|
11
|
-
it 'proxies methods to the underlying Txgh::TxResource' do
|
12
|
-
expect(resource.project_slug).to eq('myproject')
|
13
|
-
expect(resource.resource_slug).to(
|
14
|
-
eq(Txgh::Utils.slugify("#{database.database}-#{table.name}"))
|
15
|
-
)
|
16
|
-
end
|
17
|
-
end
|