rivendell-import 0.0.1

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.
Files changed (67) hide show
  1. data/.gitignore +21 -0
  2. data/Gemfile +11 -0
  3. data/Guardfile +14 -0
  4. data/LICENSE +22 -0
  5. data/README.md +29 -0
  6. data/Rakefile +4 -0
  7. data/bin/rivendell-import +6 -0
  8. data/db/migrate/20120920712200_create_tasks.rb +21 -0
  9. data/db/migrate/20120927194300_create_notifiers.rb +14 -0
  10. data/db/migrate/20120927203600_create_notifications.rb +14 -0
  11. data/examples/.gitignore +2 -0
  12. data/examples/config.rb +31 -0
  13. data/features/manage_cart_attributes.feature +20 -0
  14. data/features/manage_file_matching.feature +44 -0
  15. data/features/step_definitions/import_steps.rb +38 -0
  16. data/features/support/env.rb +19 -0
  17. data/features/support/mock_xport.rb +34 -0
  18. data/lib/rivendell/import.rb +48 -0
  19. data/lib/rivendell/import/base.rb +57 -0
  20. data/lib/rivendell/import/cart.rb +67 -0
  21. data/lib/rivendell/import/carts_cache.rb +58 -0
  22. data/lib/rivendell/import/cli.rb +90 -0
  23. data/lib/rivendell/import/config.rb +13 -0
  24. data/lib/rivendell/import/context.rb +28 -0
  25. data/lib/rivendell/import/cut.rb +33 -0
  26. data/lib/rivendell/import/file.rb +57 -0
  27. data/lib/rivendell/import/notification.rb +16 -0
  28. data/lib/rivendell/import/notifier/base.rb +89 -0
  29. data/lib/rivendell/import/notifier/mail-body.erb +8 -0
  30. data/lib/rivendell/import/notifier/mail-subject.erb +11 -0
  31. data/lib/rivendell/import/notifier/mail.rb +104 -0
  32. data/lib/rivendell/import/notifiers.rb +24 -0
  33. data/lib/rivendell/import/task.rb +80 -0
  34. data/lib/rivendell/import/tasking/cart.rb +25 -0
  35. data/lib/rivendell/import/tasking/destination.rb +28 -0
  36. data/lib/rivendell/import/tasking/file.rb +20 -0
  37. data/lib/rivendell/import/tasking/status.rb +29 -0
  38. data/lib/rivendell/import/tasking/tags.rb +27 -0
  39. data/lib/rivendell/import/tasks.rb +23 -0
  40. data/lib/rivendell/import/version.rb +5 -0
  41. data/lib/rivendell/import/worker.rb +34 -0
  42. data/rivendell-import.gemspec +37 -0
  43. data/spec/fixtures/mail-body.erb +5 -0
  44. data/spec/rivendell/import/base_spec.rb +125 -0
  45. data/spec/rivendell/import/cart_spec.rb +132 -0
  46. data/spec/rivendell/import/carts_cache_spec.rb +110 -0
  47. data/spec/rivendell/import/cli_spec.rb +149 -0
  48. data/spec/rivendell/import/config_spec.rb +16 -0
  49. data/spec/rivendell/import/context_spec.rb +19 -0
  50. data/spec/rivendell/import/file_spec.rb +63 -0
  51. data/spec/rivendell/import/notifier/base_spec.rb +63 -0
  52. data/spec/rivendell/import/notifier/mail_spec.rb +110 -0
  53. data/spec/rivendell/import/task_spec.rb +217 -0
  54. data/spec/rivendell/import/tasks_spec.rb +30 -0
  55. data/spec/rivendell/import/worker_spec.rb +25 -0
  56. data/spec/rivendell/import_spec.rb +32 -0
  57. data/spec/spec_helper.rb +15 -0
  58. data/spec/support/database_cleaner.rb +17 -0
  59. data/spec/support/fixtures.rb +3 -0
  60. data/spec/support/mail.rb +3 -0
  61. data/spec/support/test_notifier.rb +15 -0
  62. data/tasks/ci.rake +2 -0
  63. data/tasks/cucumber.rake +4 -0
  64. data/tasks/database.rake +11 -0
  65. data/tasks/rdoc.rake +16 -0
  66. data/tasks/rspec.rake +2 -0
  67. metadata +399 -0
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rivendell::Import::Config do
4
+
5
+ describe "#to_prepare" do
6
+
7
+ let(:user_block) { Proc.new {} }
8
+
9
+ it "should define to_prepare proc with given block" do
10
+ subject.to_prepare(&user_block)
11
+ subject.to_prepare.should == user_block
12
+ end
13
+
14
+ end
15
+
16
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rivendell::Import::Context do
4
+
5
+ let(:file) { Rivendell::Import::File.new "dummy.wav" }
6
+ let(:task) { Rivendell::Import::Task.new :file => file }
7
+
8
+ subject { Rivendell::Import::Context.new task }
9
+
10
+ describe "#notify" do
11
+
12
+ it "should add the specified notifier to the task" do
13
+ subject.notify 'recipient@domain', :by => :email
14
+ subject.task.notifiers.first.to.should == 'recipient@domain'
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rivendell::Import::File do
4
+
5
+ subject { Rivendell::Import::File.new "/path/to/dummy.wav", :base_directory => "/path/to" }
6
+
7
+ describe "initialization" do
8
+
9
+ it "should use given base_directory to compute relative name" do
10
+ Rivendell::Import::File.new("/path/to/dummy.wav", :base_directory => "/path/to").name.should == "dummy.wav"
11
+ end
12
+
13
+ end
14
+
15
+ describe "#to_s" do
16
+
17
+ it "should use name" do
18
+ subject.to_s.should == subject.name
19
+ end
20
+
21
+ end
22
+
23
+ describe ".relative_filename" do
24
+
25
+ it "should return '/subdirectory/file' from '/base/subdirectory/file'" do
26
+ Rivendell::Import::File.relative_filename('/base/subdirectory/file', '/base').should == 'subdirectory/file'
27
+ end
28
+
29
+ end
30
+
31
+ describe "match" do
32
+
33
+ it "should match a given regexp" do
34
+ subject.stub :name => "dummy"
35
+ subject.should match(/^dum/)
36
+ end
37
+
38
+ it "should not return false when not match" do
39
+ subject.stub :name => "dummy"
40
+ subject.should_not match(/other/)
41
+ end
42
+
43
+ end
44
+
45
+ describe "#basename" do
46
+
47
+ it "should return 'dummy' for 'path/to/dummy.wav'" do
48
+ subject.stub :name => "path/to/dummy.wav"
49
+ subject.basename.should == "dummy"
50
+ end
51
+
52
+ end
53
+
54
+ describe "#extension" do
55
+
56
+ it "should 'wav' for 'path/to/dummy.wav'" do
57
+ subject.stub :name => "path/to/dummy.wav"
58
+ subject.extension.should == "wav"
59
+ end
60
+
61
+ end
62
+
63
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rivendell::Import::Notifier::Base do
4
+
5
+ subject { Rivendell::Import::Notifier::Test.new }
6
+
7
+ describe "#notify" do
8
+
9
+ let(:to_sent_notifications) { [mock(:task => mock)] }
10
+
11
+ before(:each) do
12
+ subject.stub_chain("notifications.to_sent").and_return(to_sent_notifications)
13
+ to_sent_notifications.stub :includes => to_sent_notifications, :update_all => true
14
+ end
15
+
16
+ it "should notify! tasks of notifications#to_sent" do
17
+ subject.should_receive(:notify!).with to_sent_notifications.map(&:task)
18
+ subject.notify
19
+ end
20
+
21
+ let(:now) { Time.now }
22
+
23
+ before(:each) do
24
+ Time.stub :now => now
25
+ end
26
+
27
+ it "should mark notifications as sent" do
28
+ to_sent_notifications.should_receive(:update_all).with(:sent_at => now)
29
+ subject.notify
30
+ end
31
+
32
+ end
33
+
34
+ describe ".notify" do
35
+
36
+ describe "'recipient@domain', :by => :email" do
37
+
38
+ subject { Rivendell::Import::Notifier::Base.notify 'recipient@domain', :by => :email }
39
+
40
+ it { should be_instance_of(Rivendell::Import::Notifier::Mail) }
41
+
42
+ end
43
+
44
+ it "should reuse an existing Notifier" do
45
+ notifier = Rivendell::Import::Notifier::Base.notify 'recipient@domain', :by => :email
46
+ other_notifier = Rivendell::Import::Notifier::Base.notify 'recipient@domain', :by => :email
47
+ other_notifier.should == notifier
48
+ end
49
+
50
+ end
51
+
52
+ describe "#key" do
53
+
54
+ it "should be defined with parameters hash by default" do
55
+ subject.key = nil
56
+ subject.stub :parameters => { :dummy => true }
57
+ subject.save!
58
+ subject.key.should == subject.parameters.hash
59
+ end
60
+
61
+ end
62
+
63
+ end
@@ -0,0 +1,110 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rivendell::Import::Notifier::Mail do
4
+
5
+ let(:mail_notifier) do
6
+ Rivendell::Import::Notifier::Mail.new.tap do |notifier|
7
+ notifier.from = "root@tryphon.eu"
8
+ notifier.to = "root@tryphon.eu"
9
+ end
10
+ end
11
+
12
+ subject { mail_notifier }
13
+
14
+ let(:tasks) { [ Rivendell::Import::Task.new ] }
15
+
16
+ describe "#template" do
17
+
18
+ let(:file) { fixture_file("mail-body.erb") }
19
+
20
+ it "should read file specified if exists" do
21
+ subject.template(file).should == File.read(file)
22
+ end
23
+
24
+ it "should return given text if not file" do
25
+ subject.template("dummy").should == "dummy"
26
+ end
27
+
28
+ end
29
+
30
+ describe "#create_message" do
31
+
32
+ it "should return a Rivendell::Import::Notifier::Mail::Message" do
33
+ subject.create_message(tasks).should be_instance_of(Rivendell::Import::Notifier::Mail::Message)
34
+ end
35
+
36
+ describe "returned Message" do
37
+
38
+ subject { mail_notifier.create_message(tasks) }
39
+
40
+ its(:from) { should == mail_notifier.from }
41
+
42
+ its(:to) { should == mail_notifier.to }
43
+
44
+ its(:body) { should == mail_notifier.template(mail_notifier.body) }
45
+
46
+ its(:subject) { should == mail_notifier.template(mail_notifier.subject) }
47
+
48
+ end
49
+
50
+ end
51
+
52
+ describe "#notify!" do
53
+
54
+ it "should deliver mail" do
55
+ subject.subject = subject.body = "Dummy"
56
+ subject.notify! tasks
57
+ Mail::TestMailer.deliveries.last.subject.should == subject.subject
58
+ end
59
+
60
+ end
61
+
62
+ describe "defaults" do
63
+
64
+ subject { Rivendell::Import::Notifier::Mail.new }
65
+
66
+ its(:body) { should == File.expand_path("../../../../../lib/rivendell/import/notifier/mail-body.erb", __FILE__) }
67
+
68
+ its(:subject) { should == File.expand_path("../../../../../lib/rivendell/import/notifier/mail-subject.erb", __FILE__) }
69
+
70
+ it "should use defined default from" do
71
+ Rivendell::Import::Notifier::Mail.from = "test@dummy"
72
+ subject.from.should == Rivendell::Import::Notifier::Mail.from
73
+ end
74
+
75
+ after(:each) do
76
+ Rivendell::Import::Notifier::Mail.from = nil
77
+ end
78
+
79
+ end
80
+
81
+ describe "reloaded" do
82
+
83
+ let(:original) { mail_notifier.save! ; mail_notifier }
84
+
85
+ subject { Rivendell::Import::Notifier::Mail.find(original) }
86
+
87
+ its(:from) { should == original.from }
88
+ its(:to) { should == original.to }
89
+ its(:subject) { should == original.subject }
90
+ its(:body) { should == original.body }
91
+
92
+ end
93
+
94
+ end
95
+
96
+ describe Rivendell::Import::Notifier::Mail::Message do
97
+
98
+ let(:tasks) { [ mock ] }
99
+
100
+ subject { Rivendell::Import::Notifier::Mail::Message.new(tasks) }
101
+
102
+ describe "#render" do
103
+
104
+ it "should render ERB template with Message context" do
105
+ subject.render("size: <%= tasks.size %>").should == "size: 1"
106
+ end
107
+
108
+ end
109
+
110
+ end
@@ -0,0 +1,217 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rivendell::Import::Task do
4
+
5
+ let(:file) { Rivendell::Import::File.new("dummy.wav") }
6
+ subject { Rivendell::Import::Task.new :file => file }
7
+
8
+ describe "#file" do
9
+
10
+ it "should return a file with specified path" do
11
+ Rivendell::Import::Task.new(:file => file).file.should == file
12
+ end
13
+
14
+ end
15
+
16
+ describe "#cart" do
17
+
18
+ it "should return a Cart associated to the task" do
19
+ subject.cart.task.should == subject
20
+ end
21
+
22
+ end
23
+
24
+ describe "#xport" do
25
+
26
+ it "should return a instance of Rivendell::API::Xport" do
27
+ subject.xport.should be_instance_of(Rivendell::API::Xport)
28
+ end
29
+
30
+ end
31
+
32
+ describe "#prepare" do
33
+
34
+ it "should return the Task" do
35
+ subject.prepare { |file| } .should == subject
36
+ end
37
+
38
+ it "should invoke the specified block with Task file" do
39
+ given_file = nil
40
+ subject.prepare do |file|
41
+ given_file = file
42
+ end
43
+ given_file.should == subject.file
44
+ end
45
+
46
+ end
47
+
48
+ describe "#run" do
49
+
50
+ before(:each) do
51
+ subject.stub :destination => "test"
52
+ subject.stub :cart => mock(:create => true, :import => true, :update => true, :number => 123, :to_json => '')
53
+ end
54
+
55
+ it "should create Cart" do
56
+ subject.cart.should_receive(:create)
57
+ subject.run
58
+ end
59
+
60
+ it "should import File in Cart" do
61
+ subject.cart.should_receive(:import).with(subject.file)
62
+ subject.run
63
+ end
64
+
65
+ it "should update Cart" do
66
+ subject.cart.should_receive(:update)
67
+ subject.run
68
+ end
69
+
70
+ it "should change the status to completed" do
71
+ subject.run
72
+ subject.status.should be_completed
73
+ end
74
+
75
+ it "should change the status to failed if an error is raised" do
76
+ subject.cart.stub(:create).and_raise("dummy")
77
+ subject.run
78
+ subject.status.should be_failed
79
+ end
80
+
81
+ end
82
+
83
+ describe "#destination" do
84
+
85
+ it "should return 'Cart in group :group' if cart#group is defined" do
86
+ subject.cart.group = 'dummy'
87
+ subject.destination.should == "Cart in group dummy"
88
+ end
89
+
90
+ it "should return 'Cart :number' if cart#number is defined" do
91
+ subject.cart.number = 123
92
+ subject.destination.should == "Cart 123"
93
+ end
94
+
95
+ end
96
+
97
+ describe "#tags" do
98
+
99
+ it "should be empty by default" do
100
+ subject.tags.should be_empty
101
+ end
102
+
103
+ end
104
+
105
+ describe "#tag" do
106
+
107
+ it "should add the given tag" do
108
+ subject.tag "dummy"
109
+ subject.tags.should == %w{dummy}
110
+ end
111
+
112
+ end
113
+
114
+ describe "storage" do
115
+
116
+ it "should store destination" do
117
+ subject.cart.number = 123
118
+ subject.save
119
+ subject.destination.should == Rivendell::Import::Task.find(subject).destination
120
+ end
121
+
122
+ it "should store tags separated with commas" do
123
+ subject.tags << "tag1" << "tag2"
124
+ subject.save
125
+ Rivendell::Import::Task.find(subject).raw_tags.should == "tag1,tag2"
126
+ end
127
+
128
+ it "should store cart" do
129
+ subject.cart.number = 123
130
+ subject.save
131
+ Rivendell::Import::Task.find(subject).cart.number.should == 123
132
+ end
133
+
134
+ end
135
+
136
+ describe "#status" do
137
+
138
+ it "should be include in pending, completed, failed" do
139
+ pending
140
+ # subject.should validate_inclusion_of(:status, :in => %w{pending running completed failed})
141
+ end
142
+
143
+ it "should be pending by default" do
144
+ subject.status.should be_pending
145
+ end
146
+
147
+ end
148
+
149
+ describe "#notifications" do
150
+
151
+ before(:each) do
152
+ subject.save!
153
+ end
154
+
155
+ it "should be empty by default" do
156
+ subject.notifications.should be_empty
157
+ end
158
+
159
+ end
160
+
161
+ describe "#notifiers" do
162
+
163
+ before(:each) do
164
+ subject.save!
165
+ end
166
+
167
+ let(:notifier) { Rivendell::Import::Notifier::Test.create! }
168
+
169
+ it "should create a Notification when a Notifier is added" do
170
+ subject.notifiers << notifier
171
+ subject.notifications.first.notifier.should == notifier
172
+ end
173
+
174
+ end
175
+
176
+ describe "#notify!" do
177
+
178
+ before(:each) do
179
+ subject.status = "completed"
180
+ subject.save!
181
+ subject.notifiers << notifier
182
+ end
183
+
184
+ let(:notifier) { Rivendell::Import::Notifier::Test.create! }
185
+
186
+ it "should notify task with all associated notifiers" do
187
+ subject.notify!
188
+ notifier.notified_tasks.should == [ subject ]
189
+ end
190
+
191
+ it "should mark notification as sent" do
192
+ subject.notify!
193
+ subject.notifications.first.should be_sent
194
+ end
195
+
196
+ end
197
+
198
+ describe "#change_status!" do
199
+
200
+ it "should update_attribute :status" do
201
+ subject.should_receive(:update_attribute).with(:status, "completed")
202
+ subject.change_status! :completed
203
+ end
204
+
205
+ it "should notify change when status is completed" do
206
+ subject.should_receive(:notify!)
207
+ subject.change_status! :completed
208
+ end
209
+
210
+ it "should notify change when status is failed" do
211
+ subject.should_receive(:notify!)
212
+ subject.change_status! :failed
213
+ end
214
+
215
+ end
216
+
217
+ end