coupler 0.0.7-java → 0.0.8-java
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/coupler.gemspec +11 -2
- data/db/migrate/024_add_error_msg_to_jobs.rb +5 -0
- data/db/migrate/025_add_notifications.rb +16 -0
- data/db/migrate/026_add_status_to_resources.rb +7 -0
- data/db/migrate/027_add_notification_id_to_jobs.rb +8 -0
- data/lib/coupler.rb +6 -2
- data/lib/coupler/base.rb +1 -0
- data/lib/coupler/extensions.rb +3 -1
- data/lib/coupler/extensions/imports.rb +11 -14
- data/lib/coupler/extensions/notifications.rb +26 -0
- data/lib/coupler/models.rb +1 -0
- data/lib/coupler/models/comparison.rb +0 -1
- data/lib/coupler/models/connection.rb +0 -1
- data/lib/coupler/models/field.rb +6 -6
- data/lib/coupler/models/import.rb +9 -3
- data/lib/coupler/models/job.rb +64 -20
- data/lib/coupler/models/matcher.rb +0 -1
- data/lib/coupler/models/notification.rb +7 -0
- data/lib/coupler/models/project.rb +0 -1
- data/lib/coupler/models/resource.rb +52 -31
- data/lib/coupler/models/result.rb +0 -1
- data/lib/coupler/models/scenario.rb +0 -1
- data/lib/coupler/models/transformation.rb +2 -3
- data/lib/coupler/models/transformer.rb +0 -1
- data/lib/coupler/scheduler.rb +8 -0
- data/tasks/db.rake +2 -2
- data/test/functional/test_imports.rb +21 -13
- data/test/functional/test_notifications.rb +38 -0
- data/test/integration/test_import.rb +25 -1
- data/test/unit/models/test_field.rb +2 -13
- data/test/unit/models/test_import.rb +4 -0
- data/test/unit/models/test_job.rb +59 -6
- data/test/unit/models/test_notification.rb +17 -0
- data/test/unit/models/test_resource.rb +114 -29
- data/test/unit/models/test_transformation.rb +4 -4
- data/test/unit/test_base.rb +1 -1
- data/test/unit/test_scheduler.rb +11 -0
- data/webroot/public/css/style.css +23 -0
- data/webroot/public/js/application.js +31 -10
- data/webroot/views/jobs/list.erb +2 -0
- data/webroot/views/layout.erb +3 -1
- data/webroot/views/notifications/index.erb +16 -0
- data/webroot/views/resources/list.erb +12 -7
- data/webroot/views/sidebar.erb +2 -0
- metadata +11 -2
@@ -1,4 +1,3 @@
|
|
1
|
-
pp caller
|
2
1
|
module Coupler
|
3
2
|
module Models
|
4
3
|
class Transformation < Sequel::Model
|
@@ -93,7 +92,7 @@ module Coupler
|
|
93
92
|
|
94
93
|
def after_save
|
95
94
|
super
|
96
|
-
resource.
|
95
|
+
resource.transformations_updated!
|
97
96
|
end
|
98
97
|
|
99
98
|
def before_destroy
|
@@ -111,7 +110,7 @@ module Coupler
|
|
111
110
|
if result_field && result_field.is_generated && self.class.filter(:result_field_id => result_field.id).count == 0
|
112
111
|
result_field.destroy
|
113
112
|
end
|
114
|
-
resource.
|
113
|
+
resource.transformations_updated! if resource
|
115
114
|
end
|
116
115
|
end
|
117
116
|
end
|
data/lib/coupler/scheduler.rb
CHANGED
@@ -23,6 +23,14 @@ module Coupler
|
|
23
23
|
})
|
24
24
|
end
|
25
25
|
|
26
|
+
def schedule_import_job(import)
|
27
|
+
Models::Job.create({
|
28
|
+
:name => "import",
|
29
|
+
:import => import,
|
30
|
+
:status => "scheduled"
|
31
|
+
})
|
32
|
+
end
|
33
|
+
|
26
34
|
def run_jobs
|
27
35
|
@mutex.synchronize do
|
28
36
|
count = Models::Job.filter(:status => 'running').count
|
data/tasks/db.rake
CHANGED
@@ -16,7 +16,7 @@ namespace :db do
|
|
16
16
|
desc "Run migrations"
|
17
17
|
task :migrate => :environment do
|
18
18
|
version = ENV['VERSION']
|
19
|
-
Coupler::Database.
|
19
|
+
Coupler::Database.migrate!(version ? version.to_i : nil)
|
20
20
|
end
|
21
21
|
|
22
22
|
namespace :migrate do
|
@@ -26,7 +26,7 @@ namespace :db do
|
|
26
26
|
|
27
27
|
desc "Roll the database back a version"
|
28
28
|
task :rollback => [:start, :environment] do
|
29
|
-
Coupler::Database.
|
29
|
+
Coupler::Database.rollback!
|
30
30
|
end
|
31
31
|
|
32
32
|
desc "Reset and bootstrap the database"
|
@@ -33,12 +33,16 @@ module CouplerFunctionalTests
|
|
33
33
|
find('label[for="resource-type-csv"]').click
|
34
34
|
attach_file('data', fixture_path('people.csv'))
|
35
35
|
|
36
|
+
job_count = Job.count
|
37
|
+
resource_count = Resource.count
|
36
38
|
click_button('Begin Importing')
|
37
|
-
assert_match %r{^/projects/#{@project[:id]}/resources
|
39
|
+
assert_match %r{^/projects/#{@project[:id]}/resources$}, page.current_path
|
40
|
+
assert_equal resource_count + 1, Resource.count
|
41
|
+
assert_equal job_count + 1, Job.count
|
38
42
|
end
|
39
43
|
|
40
44
|
attribute(:javascript, true)
|
41
|
-
test "create with invalid import" do
|
45
|
+
test "create with invalid import, fix, and continue" do
|
42
46
|
visit "/projects/#{@project.id}/resources/new"
|
43
47
|
find('label[for="resource-type-csv"]').click
|
44
48
|
attach_file('data', fixture_path('people.csv'))
|
@@ -47,30 +51,34 @@ module CouplerFunctionalTests
|
|
47
51
|
click_button('Begin Importing')
|
48
52
|
|
49
53
|
assert page.has_selector?("div.errors")
|
54
|
+
|
55
|
+
fill_in('name', :with => 'Foo Bar')
|
56
|
+
click_button('Begin Importing')
|
57
|
+
assert_match %r{^/projects/#{@project[:id]}/resources$}, page.current_path
|
50
58
|
end
|
51
59
|
|
52
60
|
attribute(:javascript, true)
|
53
|
-
test "
|
54
|
-
|
55
|
-
|
56
|
-
attach_file('data', fixture_path('duplicate-keys.csv'))
|
57
|
-
click_button('Begin Importing')
|
61
|
+
test "editing import with duplicate keys" do
|
62
|
+
import = Import.create(:data => fixture_file_upload("duplicate-keys.csv"), :project => @project)
|
63
|
+
import.import!
|
58
64
|
|
65
|
+
visit "/projects/#{@project.id}/imports/#{import.id}/edit"
|
59
66
|
assert find("h2").has_content?("Duplicate Keys")
|
60
|
-
assert_match %r{^/projects/#{@project.id}/imports/\d+/edit$}, page.current_path
|
61
67
|
end
|
62
68
|
|
63
69
|
attribute(:javascript, true)
|
64
70
|
test "update import with duplicate keys" do
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
click_button('Begin Importing')
|
71
|
+
import = Import.create(:data => fixture_file_upload("duplicate-keys.csv"), :project => @project)
|
72
|
+
resource = Resource.create(:name => import.name, :project => @project, :status => 'pending', :import => import)
|
73
|
+
import.import!
|
69
74
|
|
75
|
+
visit "/projects/#{@project.id}/imports/#{import.id}/edit"
|
70
76
|
find('input[name="delete[2][]"][value="1"]').click
|
71
77
|
click_button('Submit')
|
72
78
|
|
73
|
-
|
79
|
+
resource.refresh
|
80
|
+
assert_equal "ok", resource.status
|
81
|
+
assert_match %r{^/projects/#{@project[:id]}/resources/#{resource.id}$}, page.current_path
|
74
82
|
end
|
75
83
|
end
|
76
84
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module CouplerFunctionalTests
|
4
|
+
class TestNotifications < Coupler::Test::FunctionalTest
|
5
|
+
|
6
|
+
test "empty index" do
|
7
|
+
visit "/notifications"
|
8
|
+
assert_equal 200, page.status_code
|
9
|
+
end
|
10
|
+
|
11
|
+
test "index" do
|
12
|
+
n1 = Notification.create(:message => "Test!")
|
13
|
+
n2 = Notification.create(:message => "Another Test!", :url => "/projects")
|
14
|
+
n3 = Notification.create(:message => "Foo", :seen => true)
|
15
|
+
n4 = Notification.create(:message => "Bar", :url => "/connections", :seen => true)
|
16
|
+
visit "/notifications"
|
17
|
+
assert_equal 200, page.status_code
|
18
|
+
end
|
19
|
+
|
20
|
+
test "flags notifications as seen when url is visited" do
|
21
|
+
n = Notification.create(:message => "Foo bar", :url => "/connections")
|
22
|
+
visit "/connections"
|
23
|
+
n.reload
|
24
|
+
assert n.seen
|
25
|
+
end
|
26
|
+
|
27
|
+
test "unseen json" do
|
28
|
+
now = DateTime.now
|
29
|
+
Timecop.freeze(now) do
|
30
|
+
n1 = Notification.create(:message => "Foo bar", :url => "/connections")
|
31
|
+
n2 = Notification.create(:message => "Seen foo bar", :url => "/projects", :seen => true)
|
32
|
+
end
|
33
|
+
page.driver.get "/notifications/unseen.json"
|
34
|
+
result = JSON.parse(page.driver.response.body)
|
35
|
+
assert_equal([{'id' => n1.id, 'message' => 'Foo bar', 'url' => '/connections', 'created_at' => now.to_s}], result)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -5,7 +5,13 @@ class TestImport < Coupler::Test::IntegrationTest
|
|
5
5
|
test "import!" do
|
6
6
|
project = Project.create(:name => "foo")
|
7
7
|
import = Import.create(:data => fixture_file_upload("people.csv"), :project => project)
|
8
|
-
|
8
|
+
|
9
|
+
total = import.data.file.size
|
10
|
+
completed = 0
|
11
|
+
import.import! do |pos|
|
12
|
+
assert pos > completed
|
13
|
+
completed = pos
|
14
|
+
end
|
9
15
|
assert_not_nil import.occurred_at
|
10
16
|
|
11
17
|
project.local_database do |db|
|
@@ -22,6 +28,24 @@ class TestImport < Coupler::Test::IntegrationTest
|
|
22
28
|
end
|
23
29
|
end
|
24
30
|
|
31
|
+
test "import job" do
|
32
|
+
project = Project.create(:name => "foo")
|
33
|
+
|
34
|
+
tempfile = Tempfile.new('coupler-import')
|
35
|
+
tempfile.write("id,foo,bar\n1,2,3\n4,5,6\n7,8,9\n2,3,4\n5,6,7\n8,9,0\n")
|
36
|
+
tempfile.close
|
37
|
+
import = Import.create(:data => file_upload(tempfile.path), :project => project)
|
38
|
+
resource = Resource.create(:name => 'foo', :status => 'pending', :project => project, :import => import)
|
39
|
+
|
40
|
+
job = Job.create(:name => 'import', :import => import, :status => "scheduled")
|
41
|
+
job.execute
|
42
|
+
|
43
|
+
project.local_database do |db|
|
44
|
+
name = :"import_#{import.id}"
|
45
|
+
assert db.tables.include?(name)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
25
49
|
test "flags duplicate primary keys" do
|
26
50
|
tempfile = Tempfile.new('coupler-import')
|
27
51
|
tempfile.write("id,foo,bar\n1,abc,def\n2,ghi,jkl\n2,mno,pqr")
|
@@ -46,17 +46,6 @@ module CouplerUnitTests
|
|
46
46
|
assert field_2.is_selected
|
47
47
|
end
|
48
48
|
|
49
|
-
test "original_column_options" do
|
50
|
-
field = new_field({
|
51
|
-
:local_type => 'integer',
|
52
|
-
:local_db_type => 'int(11)',
|
53
|
-
})
|
54
|
-
assert_equal({
|
55
|
-
:name => 'foo', :type => 'varchar(255)',
|
56
|
-
:primary_key => false
|
57
|
-
}, field.original_column_options)
|
58
|
-
end
|
59
|
-
|
60
49
|
test "local_column_options" do
|
61
50
|
field_1 = new_field({
|
62
51
|
:type => 'integer', :db_type => 'int(11)',
|
@@ -69,11 +58,11 @@ module CouplerUnitTests
|
|
69
58
|
})
|
70
59
|
|
71
60
|
assert_equal({
|
72
|
-
:name => 'foo', :type =>
|
61
|
+
:name => 'foo', :type => String, :size => 255,
|
73
62
|
:primary_key => false
|
74
63
|
}, field_1.local_column_options)
|
75
64
|
assert_equal({
|
76
|
-
:name => 'foo', :type =>
|
65
|
+
:name => 'foo', :type => Integer,
|
77
66
|
:primary_key => false
|
78
67
|
}, field_2.local_column_options)
|
79
68
|
end
|
@@ -31,6 +31,10 @@ module CouplerUnitTests
|
|
31
31
|
assert_respond_to Models::Import.new, :project
|
32
32
|
end
|
33
33
|
|
34
|
+
test "one to one resource" do
|
35
|
+
assert_respond_to Models::Import.new, :resource
|
36
|
+
end
|
37
|
+
|
34
38
|
test "gets name from original filename" do
|
35
39
|
import = new_import
|
36
40
|
assert_equal "People", import.name
|
@@ -11,13 +11,20 @@ module CouplerUnitTests
|
|
11
11
|
if attribs[:scenario]
|
12
12
|
j.stubs(:scenario_dataset).returns(stub({:all => [attribs[:scenario]]}))
|
13
13
|
end
|
14
|
+
if attribs[:import]
|
15
|
+
j.stubs(:import_dataset).returns(stub({:all => [attribs[:import]]}))
|
16
|
+
end
|
14
17
|
j
|
15
18
|
end
|
16
19
|
|
17
20
|
def setup
|
18
21
|
super
|
22
|
+
@project = stub('project', :pk => 1, :id => 1, :associations => {})
|
19
23
|
@resource = stub('resource', :pk => 456, :id => 456, :associations => {})
|
20
24
|
@scenario = stub('scenario', :pk => 456, :id => 456, :associations => {})
|
25
|
+
@import = stub('import', :pk => 123, :id => 123, :associations => {}, :project_id => 1, :project => @project, :name => 'foo')
|
26
|
+
@notification = stub('notification', :pk => 222, :id => 222, :associations => {})
|
27
|
+
Coupler::Models::Notification.stubs(:create).returns(@notification)
|
21
28
|
end
|
22
29
|
|
23
30
|
test "sequel model" do
|
@@ -33,6 +40,14 @@ module CouplerUnitTests
|
|
33
40
|
assert_respond_to Job.new, :scenario
|
34
41
|
end
|
35
42
|
|
43
|
+
test "belongs to import" do
|
44
|
+
assert_respond_to Job.new, :import
|
45
|
+
end
|
46
|
+
|
47
|
+
test "belongs to notification" do
|
48
|
+
assert_respond_to Job.new, :notification
|
49
|
+
end
|
50
|
+
|
36
51
|
test "percent completed" do
|
37
52
|
job = new_job(:name => 'transform', :resource => @resource, :total => 200, :completed => 54)
|
38
53
|
assert_equal 27, job.percent_completed
|
@@ -48,7 +63,9 @@ module CouplerUnitTests
|
|
48
63
|
seq = sequence("update")
|
49
64
|
job.expects(:update).with(:status => 'running', :total => 12345, :started_at => now).in_sequence(seq)
|
50
65
|
@resource.expects(:transform!).in_sequence(seq)
|
51
|
-
job.expects(:
|
66
|
+
job.expects(:status=).with('done').in_sequence(seq)
|
67
|
+
job.expects(:completed_at=).with(now).in_sequence(seq)
|
68
|
+
job.expects(:save).in_sequence(seq)
|
52
69
|
Timecop.freeze(now) { job.execute }
|
53
70
|
end
|
54
71
|
|
@@ -60,8 +77,9 @@ module CouplerUnitTests
|
|
60
77
|
seq = sequence("update")
|
61
78
|
job.expects(:update).with(:status => 'running', :total => 12345, :started_at => now).in_sequence(seq)
|
62
79
|
fake_exception_klass = Class.new(Exception)
|
63
|
-
|
64
|
-
|
80
|
+
exception = fake_exception_klass.new("someone set us up the bomb")
|
81
|
+
@resource.expects(:transform!).raises(exception).in_sequence(seq)
|
82
|
+
job.expects(:update).with(has_entries(:status => 'failed', :completed_at => now, :error_msg => kind_of(String))).in_sequence(seq)
|
65
83
|
|
66
84
|
Timecop.freeze(now) do
|
67
85
|
begin
|
@@ -78,7 +96,9 @@ module CouplerUnitTests
|
|
78
96
|
seq = sequence("update")
|
79
97
|
job.expects(:update).with(:status => 'running', :started_at => now).in_sequence(seq)
|
80
98
|
@scenario.expects(:run!).in_sequence(seq)
|
81
|
-
job.expects(:
|
99
|
+
job.expects(:status=).with('done').in_sequence(seq)
|
100
|
+
job.expects(:completed_at=).with(now).in_sequence(seq)
|
101
|
+
job.expects(:save).in_sequence(seq)
|
82
102
|
|
83
103
|
Timecop.freeze(now) { job.execute }
|
84
104
|
end
|
@@ -90,8 +110,9 @@ module CouplerUnitTests
|
|
90
110
|
seq = sequence("update")
|
91
111
|
job.expects(:update).with(:status => 'running', :started_at => now).in_sequence(seq)
|
92
112
|
fake_exception_klass = Class.new(Exception)
|
93
|
-
|
94
|
-
|
113
|
+
exception = fake_exception_klass.new("someone set us up the bomb")
|
114
|
+
@scenario.expects(:run!).raises(exception).in_sequence(seq)
|
115
|
+
job.expects(:update).with(has_entries(:status => 'failed', :completed_at => now, :error_msg => kind_of(String))).in_sequence(seq)
|
95
116
|
|
96
117
|
Timecop.freeze(now) do
|
97
118
|
begin
|
@@ -110,6 +131,38 @@ module CouplerUnitTests
|
|
110
131
|
Timecop.freeze(now ) { job_4 = new_job(:name => "run_scenario", :scenario => @scenario).save! }
|
111
132
|
assert_equal [job_4, job_3, job_2], Job.recently_accessed
|
112
133
|
end
|
134
|
+
|
135
|
+
test "import job" do
|
136
|
+
job = new_job(:name => 'import', :import => @import).save!
|
137
|
+
|
138
|
+
now = Time.now
|
139
|
+
seq = sequence("update")
|
140
|
+
@import.expects(:data).returns(mock(:file => mock(:size => 12345)))
|
141
|
+
job.expects(:update).with(:status => 'running', :total => 12345, :started_at => now).in_sequence(seq)
|
142
|
+
@import.expects(:import!).returns(true).in_sequence(seq)
|
143
|
+
@import.expects(:resource).returns(mock({:id => 456, :activate! => nil})).in_sequence(seq)
|
144
|
+
Notification.expects(:create).with(:message => "Import finished successfully", :url => "/projects/1/resources/456").returns(@notification).in_sequence(seq)
|
145
|
+
job.expects(:notification=).with(@notification).in_sequence(seq)
|
146
|
+
job.expects(:status=).with('done').in_sequence(seq)
|
147
|
+
job.expects(:completed_at=).with(now).in_sequence(seq)
|
148
|
+
job.expects(:save).in_sequence(seq)
|
149
|
+
Timecop.freeze(now) { job.execute }
|
150
|
+
end
|
151
|
+
|
152
|
+
test "import job with more interaction needed" do
|
153
|
+
job = new_job(:name => 'import', :import => @import).save!
|
154
|
+
|
155
|
+
now = Time.now
|
156
|
+
seq = sequence("update")
|
157
|
+
@import.expects(:data).returns(mock(:file => mock(:size => 12345)))
|
158
|
+
job.expects(:update).with(:status => 'running', :total => 12345, :started_at => now).in_sequence(seq)
|
159
|
+
@import.expects(:import!).returns(false).in_sequence(seq)
|
160
|
+
Notification.expects(:create).with(:message => "Import finished, but with errors", :url => "/projects/1/imports/123/edit").returns(@notification)
|
161
|
+
job.expects(:status=).with('done').in_sequence(seq)
|
162
|
+
job.expects(:completed_at=).with(now).in_sequence(seq)
|
163
|
+
job.expects(:save).in_sequence(seq)
|
164
|
+
Timecop.freeze(now) { job.execute }
|
165
|
+
end
|
113
166
|
end
|
114
167
|
end
|
115
168
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module TestModels
|
4
|
+
class TestNotification < Coupler::Test::UnitTest
|
5
|
+
include Coupler::Models
|
6
|
+
Coupler::Models::Notification # force load
|
7
|
+
|
8
|
+
test "sequel model" do
|
9
|
+
assert_equal ::Sequel::Model, Notification.superclass
|
10
|
+
assert_equal :notifications, Notification.table_name
|
11
|
+
end
|
12
|
+
|
13
|
+
test "common model" do
|
14
|
+
assert Notification.ancestors.include?(CommonModel)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -29,8 +29,15 @@ module CouplerUnitTests
|
|
29
29
|
:connection => @connection
|
30
30
|
}.update(attribs)
|
31
31
|
r = Resource.new(values)
|
32
|
-
|
33
|
-
|
32
|
+
if values[:project]
|
33
|
+
r.stubs(:project_dataset).returns(stub({:all => [values[:project]]}))
|
34
|
+
end
|
35
|
+
if values[:connection]
|
36
|
+
r.stubs(:connection_dataset).returns(stub({:all => [values[:connection]]}))
|
37
|
+
end
|
38
|
+
if values[:import]
|
39
|
+
r.stubs(:import_dataset).returns(stub({:all => [values[:import]]}))
|
40
|
+
end
|
34
41
|
r
|
35
42
|
end
|
36
43
|
|
@@ -311,23 +318,27 @@ module CouplerUnitTests
|
|
311
318
|
assert_equal dataset, resource.local_dataset
|
312
319
|
end
|
313
320
|
|
314
|
-
test "
|
321
|
+
test "transformations_updated!" do
|
315
322
|
resource = new_resource.save!
|
316
323
|
field_1 = stub("id field", :id => 1)
|
317
324
|
field_2 = stub("first_name field", :id => 2)
|
318
325
|
field_3 = stub("last_name field", :id => 3)
|
319
326
|
|
327
|
+
now = Time.now
|
320
328
|
transformation_1 = stub("transformation 1", {
|
329
|
+
:id => 1, :updated_at => now,
|
321
330
|
:source_field_id => 2, :result_field_id => 2,
|
322
331
|
:field_changes => {2 => {:type => :integer, :db_type => 'int(11)'}},
|
323
332
|
:source_field => field_2
|
324
333
|
})
|
325
334
|
transformation_2 = stub("transformation 2", {
|
335
|
+
:id => 2, :updated_at => now,
|
326
336
|
:source_field_id => 3, :result_field_id => 3,
|
327
337
|
:field_changes => {3 => {:type => :integer, :db_type => 'int(11)'}},
|
328
338
|
:source_field => field_3
|
329
339
|
})
|
330
340
|
transformation_3 = stub("transformation 3", {
|
341
|
+
:id => 3, :updated_at => now,
|
331
342
|
:source_field_id => 3, :result_field_id => 3,
|
332
343
|
:field_changes => {3 => {:type => :datetime, :db_type => 'datetime'}},
|
333
344
|
:source_field => field_3
|
@@ -349,10 +360,10 @@ module CouplerUnitTests
|
|
349
360
|
:local_type => :datetime, :local_db_type => 'datetime'
|
350
361
|
}).in_sequence(seq)
|
351
362
|
|
352
|
-
resource.
|
363
|
+
resource.transformations_updated!
|
353
364
|
end
|
354
365
|
|
355
|
-
test "
|
366
|
+
test "transformations_updated does not change newly created result field" do
|
356
367
|
resource = new_resource.save!
|
357
368
|
field_1 = stub("id field", :id => 1)
|
358
369
|
field_2 = stub("first_name field", :id => 2)
|
@@ -360,6 +371,7 @@ module CouplerUnitTests
|
|
360
371
|
new_field = stub("new field", :id => 4)
|
361
372
|
|
362
373
|
transformation = stub("transformation 1", {
|
374
|
+
:id => 1, :updated_at => Time.now,
|
363
375
|
:source_field_id => 2, :result_field_id => 4,
|
364
376
|
:field_changes => {2 => {:type => :integer, :db_type => 'int(11)'}},
|
365
377
|
:source_field => field_2
|
@@ -373,10 +385,10 @@ module CouplerUnitTests
|
|
373
385
|
field_2.expects(:update).never
|
374
386
|
new_field.expects(:update).never
|
375
387
|
|
376
|
-
resource.
|
388
|
+
resource.transformations_updated!
|
377
389
|
end
|
378
390
|
|
379
|
-
test "
|
391
|
+
test "transformations_updated resets local_type and local_db_type" do
|
380
392
|
resource = new_resource.save!
|
381
393
|
|
382
394
|
resource.expects(:fields_dataset).returns(mock {
|
@@ -386,7 +398,7 @@ module CouplerUnitTests
|
|
386
398
|
td.expects(:order).with(:position).returns(td)
|
387
399
|
resource.expects(:transformations_dataset).returns(td)
|
388
400
|
|
389
|
-
resource.
|
401
|
+
resource.transformations_updated!
|
390
402
|
end
|
391
403
|
|
392
404
|
test "initial status" do
|
@@ -396,39 +408,108 @@ module CouplerUnitTests
|
|
396
408
|
|
397
409
|
test "status after adding first transformation" do
|
398
410
|
resource = new_resource.save!
|
399
|
-
|
411
|
+
|
412
|
+
field_1 = stub("id field", :id => 1, :update => nil)
|
413
|
+
transformation_1 = stub("transformation 1", {
|
414
|
+
:id => 1, :updated_at => Time.now,
|
415
|
+
:source_field_id => 1, :result_field_id => 1,
|
416
|
+
:field_changes => {1 => {:type => :integer, :db_type => 'int(11)'}},
|
417
|
+
:source_field => field_1
|
418
|
+
})
|
419
|
+
resource.stubs(:fields_dataset).returns(stub(:update => nil))
|
420
|
+
td = [transformation_1]
|
421
|
+
td.expects(:order).with(:position).returns(td)
|
422
|
+
resource.expects(:transformations_dataset).returns(td)
|
423
|
+
|
424
|
+
resource.transformations_updated!
|
400
425
|
assert_equal "out_of_date", resource.status
|
401
426
|
end
|
402
427
|
|
403
428
|
test "status when new transformation is created since transforming" do
|
404
|
-
|
405
|
-
resource
|
429
|
+
now = Time.now
|
430
|
+
resource = new_resource(:transformed_with => "1", :transformed_at => now - 5).save!
|
431
|
+
|
432
|
+
field_1 = stub("id field", :id => 1, :update => nil)
|
433
|
+
transformation_1 = stub("transformation 1", {
|
434
|
+
:id => 1, :updated_at => now - 10,
|
435
|
+
:source_field_id => 1, :result_field_id => 1,
|
436
|
+
:field_changes => {1 => {:type => :integer, :db_type => 'int(11)'}},
|
437
|
+
:source_field => field_1
|
438
|
+
})
|
439
|
+
transformation_2 = stub("transformation 2", {
|
440
|
+
:id => 2, :updated_at => now,
|
441
|
+
:source_field_id => 1, :result_field_id => 1,
|
442
|
+
:field_changes => {1 => {:type => :integer, :db_type => 'int(11)'}},
|
443
|
+
:source_field => field_1
|
444
|
+
})
|
445
|
+
resource.stubs(:fields_dataset).returns(stub(:update => nil))
|
446
|
+
td = [transformation_1, transformation_2]
|
447
|
+
td.expects(:order).with(:position).returns(td)
|
448
|
+
resource.expects(:transformations_dataset).returns(td)
|
449
|
+
|
450
|
+
resource.transformations_updated!
|
406
451
|
assert_equal "out_of_date", resource.status
|
407
452
|
end
|
408
453
|
|
409
454
|
test "status when transformation is updated since transforming" do
|
410
455
|
now = Time.now
|
411
|
-
resource = new_resource(
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
456
|
+
resource = new_resource({
|
457
|
+
:transformed_with => "1",
|
458
|
+
:transformed_at => now - 20
|
459
|
+
}).save!
|
460
|
+
field_1 = stub("id field", :id => 1, :update => nil)
|
461
|
+
|
462
|
+
transformation_1 = stub("transformation 1", {
|
463
|
+
:id => 1, :updated_at => now,
|
464
|
+
:source_field_id => 1, :result_field_id => 1,
|
465
|
+
:field_changes => {1 => {:type => :integer, :db_type => 'int(11)'}},
|
466
|
+
:source_field => field_1
|
416
467
|
})
|
468
|
+
|
469
|
+
resource.stubs(:fields_dataset).returns(stub(:update => nil))
|
470
|
+
td = [transformation_1]
|
471
|
+
td.expects(:order).with(:position).returns(td)
|
472
|
+
resource.expects(:transformations_dataset).returns(td)
|
473
|
+
|
474
|
+
resource.transformations_updated!
|
417
475
|
assert_equal "out_of_date", resource.status
|
418
476
|
end
|
419
477
|
|
420
478
|
test "status when transformation is removed since transforming" do
|
421
479
|
now = Time.now
|
422
|
-
resource = new_resource(
|
423
|
-
|
480
|
+
resource = new_resource({
|
481
|
+
:transformed_with => "1",
|
482
|
+
:transformed_at => now - 20
|
483
|
+
}).save!
|
484
|
+
td = []
|
485
|
+
td.stubs(:order).returns(td)
|
486
|
+
resource.stubs(:transformations_dataset).returns(td)
|
487
|
+
|
488
|
+
resource.transformations_updated!
|
424
489
|
assert_equal "out_of_date", resource.status
|
425
490
|
end
|
426
491
|
|
427
492
|
test "status when new transformation is removed before transforming" do
|
428
493
|
resource = new_resource.save!
|
429
|
-
|
494
|
+
|
495
|
+
field_1 = stub("id field", :id => 1, :update => nil)
|
496
|
+
transformation_1 = stub("transformation 1", {
|
497
|
+
:id => 1, :updated_at => Time.now,
|
498
|
+
:source_field_id => 1, :result_field_id => 1,
|
499
|
+
:field_changes => {1 => {:type => :integer, :db_type => 'int(11)'}},
|
500
|
+
:source_field => field_1
|
501
|
+
})
|
502
|
+
resource.stubs(:fields_dataset).returns(stub(:update => nil))
|
503
|
+
td = [transformation_1]
|
504
|
+
td.expects(:order).with(:position).returns(td)
|
505
|
+
resource.expects(:transformations_dataset).returns(td)
|
506
|
+
resource.transformations_updated!
|
430
507
|
assert_equal "out_of_date", resource.status
|
431
|
-
|
508
|
+
|
509
|
+
td = []
|
510
|
+
td.stubs(:order).returns(td)
|
511
|
+
resource.stubs(:transformations_dataset).returns(td)
|
512
|
+
resource.transformations_updated!
|
432
513
|
assert_equal "ok", resource.status
|
433
514
|
end
|
434
515
|
|
@@ -511,18 +592,21 @@ module CouplerUnitTests
|
|
511
592
|
resource.destroy
|
512
593
|
end
|
513
594
|
|
514
|
-
test "creating resource
|
595
|
+
test "creating pending resource" do
|
596
|
+
resource = Resource.new(:name => "People", :project => @project, :status => 'pending')
|
597
|
+
assert resource.valid?
|
598
|
+
resource.save!
|
599
|
+
end
|
600
|
+
|
601
|
+
test "activate pending resource" do
|
515
602
|
import = stub("import", {
|
516
603
|
:id => 123, :pk => 123, :project => @project,
|
517
|
-
:name => "People"
|
604
|
+
:name => "People", :project_id => @project.id,
|
605
|
+
:associations => {}
|
518
606
|
})
|
519
|
-
resource =
|
520
|
-
|
521
|
-
assert_equal @project, resource.project
|
522
|
-
assert_equal "import_123", resource.table_name
|
523
|
-
assert resource.valid?
|
607
|
+
resource = new_resource(:name => 'People', :status => 'pending', :import => import)
|
608
|
+
resource.save!
|
524
609
|
|
525
|
-
# import.import! would happen here
|
526
610
|
@local_database.stubs({
|
527
611
|
:tables => [:import_123],
|
528
612
|
:schema => [
|
@@ -531,9 +615,10 @@ module CouplerUnitTests
|
|
531
615
|
[:bar, {:primary_key => false, :type => :string, :db_type => "VARCHAR"}]
|
532
616
|
]
|
533
617
|
})
|
534
|
-
resource.
|
618
|
+
resource.activate!
|
535
619
|
assert_equal "id", resource.primary_key_name
|
536
620
|
assert_equal "integer", resource.primary_key_type
|
621
|
+
assert_equal "ok", resource.status
|
537
622
|
end
|
538
623
|
|
539
624
|
test "source_dataset count" do
|