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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 51610845d38e64996c61cf4079ba3a41125cd848
4
- data.tar.gz: 5587fd9b799ed26f04f81358e19ee4eb64cb59a5
3
+ metadata.gz: 0e59bfc3e60354b89d0a572dc8639ecc1bec5146
4
+ data.tar.gz: 05599e91b876f536edabd4f05163f769fbf2a2c5
5
5
  SHA512:
6
- metadata.gz: efae7ded7c1f025b5fb2df089f83e93b4015028f6cf9c9a8653e3cb0c330e1e9a37477fdb0067dba5e3ee46b04cac6aa7cd6186d50df1d3220c3a91e24778820
7
- data.tar.gz: 77b6edd9f4d7ec885727216b7a8fe57da44556d3681203862cdcef389b5af080bcf9c97a38f4d32f6b7edc8cf9973db10168e20b0c810ad315e12a362854a79f
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
@@ -1,3 +1,5 @@
1
+ require 'ext/txgh/tx_resource'
2
+
1
3
  module Txdb
2
4
  autoload :Application, 'txdb/app'
3
5
  autoload :Backends, 'txdb/backends'
@@ -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, content, locale)
12
- Writer.new(table).write_content(content, locale)
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
@@ -10,6 +10,10 @@ module Txdb
10
10
  table_name.sub(/_translations\z/, '')
11
11
  )
12
12
  end
13
+
14
+ def resource_slug_for(table)
15
+ Txgh::Utils.slugify("#{table.database.database}-#{table.name}")
16
+ end
13
17
  end
14
18
 
15
19
  Helpers.extend(Helpers)
@@ -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
- { origin_table_name(table.name) => content_for_records }
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(content, locale)
17
- content[origin_table_name(table.name)].each_pair do |id, fields|
18
- row = table.db.where(foreign_key.to_sym => id, locale: locale)
19
-
20
- if row.empty?
21
- table.db << fields.merge(
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
@@ -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
- content = transifex_api.download(table.resource, locale)
23
- table.write_content(content, locale)
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
- tables.each do |table|
23
- content = table.database.transifex_api.download(table.resource, locale)
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 locale
35
- payload['language']
31
+ def downloader
32
+ @downloader ||= Txdb::Downloader.new(database)
36
33
  end
37
34
 
38
- def tables
39
- @tables ||= Txdb::Config.each_table.select do |table|
40
- table.resource.resource_slug == payload['resource'] &&
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 authentic_request?(project)
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, project.webhook_secret
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 databases
28
- @databases ||= if database_name = request.params['database']
29
- Txdb::Config.databases.select do |database|
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 tables
38
- @tables ||= each_table_in(databases).select do |table|
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
- tables.each do |table|
9
- locales_for(table).each do |locale|
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 locales_for(table)
21
- locale_cache[table.resource.project_slug] ||=
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 locale_cache
28
- @locale_cache ||= {}
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
 
@@ -5,10 +5,7 @@ module Txdb
5
5
  class PushHandler < Handler
6
6
  def handle
7
7
  handle_safely do
8
- tables.each do |table|
9
- Uploader.new(table.database).upload_table(table)
10
- end
11
-
8
+ Uploader.new(database).upload_table(table)
12
9
  respond_with(200, {})
13
10
  end
14
11
  end
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
- YAML.dump(
26
- database.backend.read_content_from(self)
27
- )
20
+ database.backend.read_content_from(self)
28
21
  end
29
22
 
30
- def write_content(content, locale)
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
@@ -1,52 +1,18 @@
1
- require 'txgh'
2
-
3
1
  module Txdb
4
2
  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
3
+ attr_reader :original, :content
39
4
 
40
- def initialize(resource)
41
- @resource = resource
5
+ def initialize(original, content)
6
+ @original = original
7
+ @content = content
42
8
  end
43
9
 
44
10
  def respond_to?(method)
45
- resource.respond_to?(method)
11
+ original.respond_to?(method)
46
12
  end
47
13
 
48
14
  def method_missing(method, *args, &block)
49
- resource.send(method, *args, &block)
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
- transifex_api.create_or_update(
23
- table.resource, table.read_content
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,3 +1,3 @@
1
1
  module Txdb
2
- VERSION = '1.0.1'
2
+ VERSION = '1.1.0'
3
3
  end
@@ -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 puts it into a hash' do
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
- expect(reader.read_content).to eq({
18
- 'widgets' => {
19
- 1 => { 'name' => 'sprocket' },
20
- 2 => { 'name' => 'flange' }
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
- it 'inserts the translations into the database' do
11
- sprocket_id = widgets.insert(name: 'sprocket')
12
- writer = Globalize::Writer.new(widget_translations_table)
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
- content = {
15
- 'widgets' => {
16
- sprocket_id => { name: 'sproqueta' }
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
- expect { writer.write_content(content, 'es') }.to(
21
- change { widget_translations.count }.from(0).to(1)
22
- )
27
+ @content = YAML.dump(
28
+ 'widgets' => {
29
+ @sprocket_id => { name: 'sproqueta' }
30
+ }
31
+ )
23
32
 
24
- translation = widget_translations.first
33
+ @resource = Txdb::TxResource.new(base_resource, @content)
34
+ end
25
35
 
26
- expect(translation).to include(
27
- widget_id: sprocket_id, name: 'sproqueta', locale: 'es'
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(content, 'es') }.to_not(
99
+ expect { writer.write_content(resource, 'es') }.to_not(
46
100
  change { widget_translations.count }
47
101
  )
48
102
 
@@ -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) { Txdb::Config.databases.first }
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('spec_test.sqlite3-my_table')
35
+ expect(resource.resource_slug).to eq('fake_resource_slug')
23
36
  expect(locale).to eq('es')
24
- YAML.dump('widgets')
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
- expect(TestBackend.writes.first).to eq(
32
- table: database.tables.first.name, locale: 'es', content: 'widgets'
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(200)
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
- 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
+ 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, headers) }.to(
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
- expect(Txdb::TestBackend.writes).to include(
58
- locale: 'es', table: table.name, content: content
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(:download).and_raise('jelly beans')
75
+ expect(project.api).to receive(:get_resource).and_raise('jelly beans')
64
76
 
65
- post '/transifex', body, headers
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 include(
42
- locale: 'es', table: table.name, content: content
43
- )
45
+ expect(Txdb::TestBackend.writes.first[:locale]).to eq('es')
46
+ expect(Txdb::TestBackend.writes.last[:locale]).to eq('ja')
44
47
 
45
- expect(Txdb::TestBackend.writes).to include(
46
- locale: 'ja', table: table.name, content: content
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
@@ -9,6 +9,8 @@ require 'txdb'
9
9
  require 'spec_helpers/env_helpers'
10
10
  require 'spec_helpers/test_backend'
11
11
 
12
+ Sequel.default_timezone = :utc
13
+
12
14
  RSpec.configure do |config|
13
15
  config.before(:each) do
14
16
  Txdb::TestBackend.reset
@@ -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, content, locale)
23
- writes << { table: table.name, content: content, locale: locale }
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
- let(:content) { { foo: 'bar' } }
33
-
34
- it 'dumps the content in YAML format' do
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
- let(:content) { { foo: 'bar' } }
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(YAML.dump(content), locale)
34
+ table.write_content(:content, :locale)
56
35
  end
57
36
  end
58
37
  end
data/spec/test.sqlite3 CHANGED
Binary file
@@ -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) { Txdb::Config.databases.first }
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('myproject')
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.1
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-17 00:00:00.000000000 Z
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
@@ -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