txdb 1.0.1 → 1.1.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 +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
|