sequel_bitemporal 0.6.11 → 0.6.12
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.
- data/.travis.yml +3 -0
- data/lib/sequel/plugins/bitemporal.rb +134 -12
- data/sequel_bitemporal.gemspec +2 -1
- data/spec/bitemporal_date_spec.rb +3 -7
- data/spec/bitemporal_date_with_range_spec.rb +785 -0
- data/spec/bitemporal_serialization_spec.rb +0 -1
- data/spec/bitemporal_time_spec.rb +3 -6
- data/spec/bitemporal_time_with_range_spec.rb +496 -0
- data/spec/spec_helper.rb +22 -1
- data/spec/support/db.rb +11 -7
- metadata +52 -14
- checksums.yaml +0 -15
@@ -0,0 +1,785 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
if DbHelpers.pg?
|
3
|
+
describe "Sequel::Plugins::Bitemporal", "with ranges" do
|
4
|
+
before :all do
|
5
|
+
db_setup ranges: true
|
6
|
+
end
|
7
|
+
before do
|
8
|
+
Timecop.freeze 2009, 11, 28
|
9
|
+
end
|
10
|
+
after do
|
11
|
+
Timecop.return
|
12
|
+
end
|
13
|
+
it "checks version class is given" do
|
14
|
+
lambda{
|
15
|
+
@version_class.plugin :bitemporal
|
16
|
+
}.should raise_error Sequel::Error, "please specify version class to use for bitemporal plugin"
|
17
|
+
end
|
18
|
+
it "checks required columns are present" do
|
19
|
+
lambda{
|
20
|
+
@version_class.plugin :bitemporal, version_class: @master_class
|
21
|
+
}.should raise_error Sequel::Error, "bitemporal plugin requires the following missing columns on version class: master_id, valid_from, valid_to, created_at, expired_at"
|
22
|
+
end
|
23
|
+
it "propagates errors from version to master" do
|
24
|
+
master = @master_class.new
|
25
|
+
master.should be_valid
|
26
|
+
master.attributes = {name: "Single Standard"}
|
27
|
+
master.should_not be_valid
|
28
|
+
master.errors.should == {price: ["is required"]}
|
29
|
+
end
|
30
|
+
it "#update_attributes returns false instead of raising errors" do
|
31
|
+
master = @master_class.new
|
32
|
+
master.update_attributes(name: "Single Standard").should be_false
|
33
|
+
master.should be_new
|
34
|
+
master.errors.should == {price: ["is required"]}
|
35
|
+
master.update_attributes(price: 98).should be_true
|
36
|
+
end
|
37
|
+
it "allows creating a master and its first version in one step" do
|
38
|
+
master = @master_class.new
|
39
|
+
result = master.update_attributes name: "Single Standard", price: 98
|
40
|
+
result.should be_true
|
41
|
+
result.should == master
|
42
|
+
master.should_not be_new
|
43
|
+
master.should have_versions %Q{
|
44
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
45
|
+
| Single Standard | 98 | 2009-11-28 | | 2009-11-28 | MAX DATE | true |
|
46
|
+
}
|
47
|
+
end
|
48
|
+
it "allows creating a new version in the past" do
|
49
|
+
master = @master_class.new
|
50
|
+
master.update_attributes name: "Single Standard", price: 98, valid_from: Date.today-1
|
51
|
+
master.should have_versions %Q{
|
52
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
53
|
+
| Single Standard | 98 | 2009-11-28 | | 2009-11-27 | MAX DATE | true |
|
54
|
+
}
|
55
|
+
end
|
56
|
+
it "allows creating a new version in the future" do
|
57
|
+
master = @master_class.new
|
58
|
+
master.update_attributes name: "Single Standard", price: 98, valid_from: Date.today+1
|
59
|
+
master.should have_versions %Q{
|
60
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
61
|
+
| Single Standard | 98 | 2009-11-28 | | 2009-11-29 | MAX DATE | |
|
62
|
+
}
|
63
|
+
end
|
64
|
+
it "doesn't loose previous version in same-day update" do
|
65
|
+
master = @master_class.new
|
66
|
+
master.update_attributes name: "Single Standard", price: 98
|
67
|
+
master.update_attributes name: "Single Standard", price: 94
|
68
|
+
master.should have_versions %Q{
|
69
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
70
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | MAX DATE | |
|
71
|
+
| Single Standard | 94 | 2009-11-28 | | 2009-11-28 | MAX DATE | true |
|
72
|
+
}
|
73
|
+
end
|
74
|
+
it "allows partial updating based on current version" do
|
75
|
+
master = @master_class.new
|
76
|
+
master.update_attributes name: "Single Standard", price: 98
|
77
|
+
master.update_attributes price: 94
|
78
|
+
master.update_attributes name: "King Size"
|
79
|
+
master.should have_versions %Q{
|
80
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
81
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | MAX DATE | |
|
82
|
+
| Single Standard | 94 | 2009-11-28 | 2009-11-28 | 2009-11-28 | MAX DATE | |
|
83
|
+
| King Size | 94 | 2009-11-28 | | 2009-11-28 | MAX DATE | true |
|
84
|
+
}
|
85
|
+
end
|
86
|
+
it "expires previous version but keep it in history" do
|
87
|
+
master = @master_class.new
|
88
|
+
master.update_attributes name: "Single Standard", price: 98
|
89
|
+
Timecop.freeze Date.today+1
|
90
|
+
master.update_attributes price: 94
|
91
|
+
master.should have_versions %Q{
|
92
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
93
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | MAX DATE | |
|
94
|
+
| Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
|
95
|
+
| Single Standard | 94 | 2009-11-29 | | 2009-11-29 | MAX DATE | true |
|
96
|
+
}
|
97
|
+
end
|
98
|
+
it "doesn't expire no longer valid versions" do
|
99
|
+
master = @master_class.new
|
100
|
+
master.update_attributes name: "Single Standard", price: 98, valid_to: Date.today+1
|
101
|
+
Timecop.freeze Date.today+1
|
102
|
+
master.update_attributes(price: 94).should be_false
|
103
|
+
master.update_attributes name: "Single Standard", price: 94
|
104
|
+
master.should have_versions %Q{
|
105
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
106
|
+
| Single Standard | 98 | 2009-11-28 | | 2009-11-28 | 2009-11-29 | |
|
107
|
+
| Single Standard | 94 | 2009-11-29 | | 2009-11-29 | MAX DATE | true |
|
108
|
+
}
|
109
|
+
end
|
110
|
+
it "allows shortening validity (SEE COMMENTS FOR IMPROVEMENTS)" do
|
111
|
+
master = @master_class.new
|
112
|
+
master.update_attributes name: "Single Standard", price: 98
|
113
|
+
Timecop.freeze Date.today+1
|
114
|
+
master.update_attributes valid_to: Date.today+10
|
115
|
+
master.should have_versions %Q{
|
116
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
117
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | MAX DATE | |
|
118
|
+
| Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
|
119
|
+
| Single Standard | 98 | 2009-11-29 | | 2009-11-29 | 2009-12-09 | true |
|
120
|
+
}
|
121
|
+
# would be even better if it could be:
|
122
|
+
# | name | price | created_at | expired_at | valid_from | valid_to | current |
|
123
|
+
# | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
|
124
|
+
# | Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-12-09 | true |
|
125
|
+
end
|
126
|
+
it "allows extending validity (SEE COMMENTS FOR IMPROVEMENTS)" do
|
127
|
+
master = @master_class.new
|
128
|
+
master.update_attributes name: "Single Standard", price: 98, valid_to: Date.today+2
|
129
|
+
Timecop.freeze Date.today+1
|
130
|
+
master.should have_versions %Q{
|
131
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
132
|
+
| Single Standard | 98 | 2009-11-28 | | 2009-11-28 | 2009-11-30 | true |
|
133
|
+
}
|
134
|
+
master.update_attributes valid_to: nil
|
135
|
+
master.should have_versions %Q{
|
136
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
137
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
|
138
|
+
| Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
|
139
|
+
| Single Standard | 98 | 2009-11-29 | | 2009-11-29 | MAX DATE | true |
|
140
|
+
}
|
141
|
+
# would be even better if it could be:
|
142
|
+
# | name | price | created_at | expired_at | valid_from | valid_to | current |
|
143
|
+
# | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
|
144
|
+
# | Single Standard | 98 | 2009-11-29 | | 2009-11-28 | MAX DATE | true |
|
145
|
+
end
|
146
|
+
it "don't create any new version without change" do
|
147
|
+
master = @master_class.new
|
148
|
+
master.update_attributes name: "Single Standard", price: 98
|
149
|
+
master.update_attributes price: 98
|
150
|
+
master.update_attributes name: "Single Standard", price: 98
|
151
|
+
master.should have_versions %Q{
|
152
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
153
|
+
| Single Standard | 98 | 2009-11-28 | | 2009-11-28 | MAX DATE | true |
|
154
|
+
}
|
155
|
+
end
|
156
|
+
it "change in validity still creates a new version (SEE COMMENTS FOR IMPROVEMENTS)" do
|
157
|
+
master = @master_class.new
|
158
|
+
master.update_attributes name: "Single Standard", price: 98
|
159
|
+
Timecop.freeze Date.today+1
|
160
|
+
master.update_attributes price: 98, valid_from: Date.today-2
|
161
|
+
master.update_attributes price: 98, valid_from: Date.today+1
|
162
|
+
master.should have_versions %Q{
|
163
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
164
|
+
| Single Standard | 98 | 2009-11-28 | | 2009-11-28 | MAX DATE | true |
|
165
|
+
| Single Standard | 98 | 2009-11-29 | | 2009-11-27 | 2009-11-28 | |
|
166
|
+
}
|
167
|
+
# would be even better if it could be:
|
168
|
+
# | name | price | created_at | expired_at | valid_from | valid_to | current |
|
169
|
+
# | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | MAX DATE | |
|
170
|
+
# | Single Standard | 98 | 2009-11-29 | | 2009-11-27 | MAX DATE | true |
|
171
|
+
end
|
172
|
+
it "overrides no future versions" do
|
173
|
+
master = @master_class.new
|
174
|
+
master.update_attributes name: "Single Standard", price: 98, valid_to: Date.today+2
|
175
|
+
master.update_attributes name: "Single Standard", price: 94, valid_from: Date.today+2, valid_to: Date.today+4
|
176
|
+
master.update_attributes name: "Single Standard", price: 95, valid_from: Date.today+4, valid_to: Date.today+6
|
177
|
+
Timecop.freeze Date.today+1
|
178
|
+
master.update_attributes name: "King Size", valid_to: nil
|
179
|
+
master.should have_versions %Q{
|
180
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
181
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
|
182
|
+
| Single Standard | 94 | 2009-11-28 | | 2009-11-30 | 2009-12-02 | |
|
183
|
+
| Single Standard | 95 | 2009-11-28 | | 2009-12-02 | 2009-12-04 | |
|
184
|
+
| Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
|
185
|
+
| King Size | 98 | 2009-11-29 | | 2009-11-29 | 2009-11-30 | true |
|
186
|
+
}
|
187
|
+
end
|
188
|
+
it "overrides multiple future versions" do
|
189
|
+
master = @master_class.new
|
190
|
+
master.update_attributes name: "Single Standard", price: 98, valid_to: Date.today+2
|
191
|
+
master.update_attributes name: "Single Standard", price: 94, valid_from: Date.today+2, valid_to: Date.today+4
|
192
|
+
master.update_attributes name: "Single Standard", price: 95, valid_from: Date.today+4, valid_to: Date.today+6
|
193
|
+
Timecop.freeze Date.today+1
|
194
|
+
master.update_attributes name: "King Size", valid_to: Date.today+4
|
195
|
+
master.should have_versions %Q{
|
196
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
197
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
|
198
|
+
| Single Standard | 94 | 2009-11-28 | 2009-11-29 | 2009-11-30 | 2009-12-02 | |
|
199
|
+
| Single Standard | 95 | 2009-11-28 | 2009-11-29 | 2009-12-02 | 2009-12-04 | |
|
200
|
+
| Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
|
201
|
+
| Single Standard | 95 | 2009-11-29 | | 2009-12-03 | 2009-12-04 | |
|
202
|
+
| King Size | 98 | 2009-11-29 | | 2009-11-29 | 2009-12-03 | true |
|
203
|
+
}
|
204
|
+
end
|
205
|
+
it "overrides all future versions" do
|
206
|
+
master = @master_class.new
|
207
|
+
master.update_attributes name: "Single Standard", price: 98, valid_to: Date.today+2
|
208
|
+
master.update_attributes name: "Single Standard", price: 94, valid_from: Date.today+2, valid_to: Date.today+4
|
209
|
+
master.update_attributes name: "Single Standard", price: 95, valid_from: Date.today+4, valid_to: Date.today+6
|
210
|
+
Timecop.freeze Date.today+1
|
211
|
+
master.update_attributes name: "King Size", valid_to: Time.utc(9999)
|
212
|
+
master.should have_versions %Q{
|
213
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
214
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
|
215
|
+
| Single Standard | 94 | 2009-11-28 | 2009-11-29 | 2009-11-30 | 2009-12-02 | |
|
216
|
+
| Single Standard | 95 | 2009-11-28 | 2009-11-29 | 2009-12-02 | 2009-12-04 | |
|
217
|
+
| Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
|
218
|
+
| King Size | 98 | 2009-11-29 | | 2009-11-29 | MAX DATE | true |
|
219
|
+
}
|
220
|
+
end
|
221
|
+
it "allows deleting current version" do
|
222
|
+
master = @master_class.new
|
223
|
+
master.update_attributes name: "Single Standard", price: 92, valid_from: Date.today-2, valid_to: Date.today
|
224
|
+
master.update_attributes name: "Single Standard", price: 98
|
225
|
+
master.update_attributes name: "Single Standard", price: 94, valid_from: Date.today+2
|
226
|
+
Timecop.freeze Date.today+1
|
227
|
+
master.current_version.destroy.should be_true
|
228
|
+
master.should have_versions %Q{
|
229
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
230
|
+
| Single Standard | 92 | 2009-11-28 | | 2009-11-26 | 2009-11-28 | |
|
231
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | MAX DATE | |
|
232
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
|
233
|
+
| Single Standard | 94 | 2009-11-28 | | 2009-11-30 | MAX DATE | |
|
234
|
+
| Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
|
235
|
+
}
|
236
|
+
end
|
237
|
+
it "allows deleting current version to restore the previous one" do
|
238
|
+
master = @master_class.new
|
239
|
+
master.update_attributes name: "Single Standard", price: 92, valid_from: Date.today-2, valid_to: Date.today
|
240
|
+
master.update_attributes name: "Single Standard", price: 98
|
241
|
+
master.update_attributes name: "Single Standard", price: 94, valid_from: Date.today+2
|
242
|
+
Timecop.freeze Date.today+1
|
243
|
+
master.current_version.destroy(expand_previous_version: true).should be_true
|
244
|
+
master.should have_versions %Q{
|
245
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
246
|
+
| Single Standard | 92 | 2009-11-28 | | 2009-11-26 | 2009-11-28 | |
|
247
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | MAX DATE | |
|
248
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
|
249
|
+
| Single Standard | 94 | 2009-11-28 | | 2009-11-30 | MAX DATE | |
|
250
|
+
| Single Standard | 92 | 2009-11-29 | | 2009-11-29 | 2009-11-30 | true |
|
251
|
+
| Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
|
252
|
+
}
|
253
|
+
end
|
254
|
+
it "allows deleting a future version" do
|
255
|
+
master = @master_class.new
|
256
|
+
master.update_attributes name: "Single Standard", price: 98
|
257
|
+
master.update_attributes name: "Single Standard", price: 94, valid_from: Date.today+2
|
258
|
+
Timecop.freeze Date.today+1
|
259
|
+
master.versions.last.destroy.should be_true
|
260
|
+
master.should have_versions %Q{
|
261
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
262
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | MAX DATE | |
|
263
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
|
264
|
+
| Single Standard | 94 | 2009-11-28 | 2009-11-29 | 2009-11-30 | MAX DATE | |
|
265
|
+
| Single Standard | 98 | 2009-11-29 | | 2009-11-28 | MAX DATE | true |
|
266
|
+
}
|
267
|
+
end
|
268
|
+
it "allows deleting a future version without expanding the current one" do
|
269
|
+
master = @master_class.new
|
270
|
+
master.update_attributes name: "Single Standard", price: 98
|
271
|
+
master.update_attributes name: "Single Standard", price: 94, valid_from: Date.today+2
|
272
|
+
Timecop.freeze Date.today+1
|
273
|
+
master.versions.last.destroy(expand_previous_version: false).should be_true
|
274
|
+
master.should have_versions %Q{
|
275
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
276
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | MAX DATE | |
|
277
|
+
| Single Standard | 98 | 2009-11-28 | | 2009-11-28 | 2009-11-30 | true |
|
278
|
+
| Single Standard | 94 | 2009-11-28 | 2009-11-29 | 2009-11-30 | MAX DATE | |
|
279
|
+
}
|
280
|
+
end
|
281
|
+
it "allows deleting all versions" do
|
282
|
+
master = @master_class.new
|
283
|
+
master.update_attributes name: "Single Standard", price: 98
|
284
|
+
master.update_attributes name: "Single Standard", price: 94, valid_from: Date.today+2
|
285
|
+
Timecop.freeze Date.today+1
|
286
|
+
master.destroy.should be_true
|
287
|
+
master.should have_versions %Q{
|
288
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
289
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | MAX DATE | |
|
290
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
|
291
|
+
| Single Standard | 94 | 2009-11-28 | 2009-11-29 | 2009-11-30 | MAX DATE | |
|
292
|
+
}
|
293
|
+
end
|
294
|
+
it "allows simultaneous updates without information loss" do
|
295
|
+
master = @master_class.new
|
296
|
+
master.update_attributes name: "Single Standard", price: 98
|
297
|
+
Timecop.freeze Date.today+1
|
298
|
+
master2 = @master_class.find id: master.id
|
299
|
+
master.update_attributes name: "Single Standard", price: 94
|
300
|
+
master2.update_attributes name: "Single Standard", price: 95
|
301
|
+
master.should have_versions %Q{
|
302
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
303
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | MAX DATE | |
|
304
|
+
| Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
|
305
|
+
| Single Standard | 94 | 2009-11-29 | 2009-11-29 | 2009-11-29 | MAX DATE | |
|
306
|
+
| Single Standard | 95 | 2009-11-29 | | 2009-11-29 | MAX DATE | true |
|
307
|
+
}
|
308
|
+
end
|
309
|
+
it "allows simultaneous cumulative updates" do
|
310
|
+
master = @master_class.new
|
311
|
+
master.update_attributes name: "Single Standard", price: 98
|
312
|
+
Timecop.freeze Date.today+1
|
313
|
+
master2 = @master_class.find id: master.id
|
314
|
+
master.update_attributes price: 94
|
315
|
+
master2.update_attributes name: "King Size"
|
316
|
+
master.should have_versions %Q{
|
317
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
318
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | MAX DATE | |
|
319
|
+
| Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
|
320
|
+
| Single Standard | 94 | 2009-11-29 | 2009-11-29 | 2009-11-29 | MAX DATE | |
|
321
|
+
| King Size | 94 | 2009-11-29 | | 2009-11-29 | MAX DATE | true |
|
322
|
+
}
|
323
|
+
end
|
324
|
+
it "can expire invalid versions" do
|
325
|
+
master = @master_class.new.update_attributes name: "Single Standard", price: 98
|
326
|
+
master.current_version.price = nil
|
327
|
+
master.current_version.should_not be_valid
|
328
|
+
master.current_version.save validate: false
|
329
|
+
Timecop.freeze Date.today+1
|
330
|
+
master.update_attributes price: 94
|
331
|
+
master.should have_versions %Q{
|
332
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
333
|
+
| Single Standard | | 2009-11-28 | 2009-11-29 | 2009-11-28 | MAX DATE | |
|
334
|
+
| Single Standard | | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
|
335
|
+
| Single Standard | 94 | 2009-11-29 | | 2009-11-29 | MAX DATE | true |
|
336
|
+
}
|
337
|
+
end
|
338
|
+
it "can propagate changes to future versions per column" do
|
339
|
+
propagate_per_column = @master_class.propagate_per_column
|
340
|
+
begin
|
341
|
+
@master_class.instance_variable_set :@propagate_per_column, true
|
342
|
+
master = @master_class.new
|
343
|
+
master.update_attributes name: "Single Standard", price: 12, length: nil, width: 1
|
344
|
+
initial_today = Date.today
|
345
|
+
Timecop.freeze initial_today+1 do
|
346
|
+
master.update_attributes valid_from: initial_today+4, name: "King Size", price: 15, length: 2, width: 2
|
347
|
+
end
|
348
|
+
Timecop.freeze initial_today+2 do
|
349
|
+
master.update_attributes valid_from: initial_today+3, length: 1, width: 1
|
350
|
+
end
|
351
|
+
Timecop.freeze initial_today+3 do
|
352
|
+
master.update_attributes valid_from: initial_today+2, length: 3, width: 4
|
353
|
+
end
|
354
|
+
master.should have_versions %Q{
|
355
|
+
| name | price | length | width | created_at | expired_at | valid_from | valid_to | current |
|
356
|
+
| Single Standard | 12 | | 1 | 2009-11-28 | 2009-11-29 | 2009-11-28 | MAX DATE | true |
|
357
|
+
| Single Standard | 12 | | 1 | 2009-11-29 | 2009-11-30 | 2009-11-28 | 2009-12-02 | |
|
358
|
+
| King Size | 15 | 2 | 2 | 2009-11-29 | | 2009-12-02 | MAX DATE | |
|
359
|
+
| Single Standard | 12 | | 1 | 2009-11-30 | 2009-12-01 | 2009-11-28 | 2009-12-01 | |
|
360
|
+
| Single Standard | 12 | 1 | 1 | 2009-11-30 | 2009-12-01 | 2009-12-01 | 2009-12-02 | |
|
361
|
+
| Single Standard | 12 | | 1 | 2009-12-01 | | 2009-11-28 | 2009-11-30 | |
|
362
|
+
| Single Standard | 12 | 3 | 4 | 2009-12-01 | | 2009-11-30 | 2009-12-01 | |
|
363
|
+
| Single Standard | 12 | 1 | 4 | 2009-12-01 | | 2009-12-01 | 2009-12-02 | |
|
364
|
+
}
|
365
|
+
ensure
|
366
|
+
@master_class.instance_variable_set :@propagate_per_column, propagate_per_column
|
367
|
+
end
|
368
|
+
end
|
369
|
+
it "allows eager loading with conditions on current version" do
|
370
|
+
master = @master_class.new
|
371
|
+
master.update_attributes name: "Single Standard", price: 98
|
372
|
+
master.update_attributes name: "Single Standard", price: 94, valid_from: Date.today+2
|
373
|
+
@master_class.eager_graph(:current_version).where("rooms_current_version.id IS NOT NULL").first.should be
|
374
|
+
Timecop.freeze Date.today+1
|
375
|
+
master.destroy
|
376
|
+
@master_class.eager_graph(:current_version).where("rooms_current_version.id IS NOT NULL").first.should be_nil
|
377
|
+
end
|
378
|
+
it "allows loading masters with a current version" do
|
379
|
+
master_destroyed = @master_class.new
|
380
|
+
master_destroyed.update_attributes name: "Single Standard", price: 98
|
381
|
+
master_destroyed.destroy
|
382
|
+
master_with_current = @master_class.new
|
383
|
+
master_with_current.update_attributes name: "Single Standard", price: 94
|
384
|
+
master_with_future = @master_class.new
|
385
|
+
master_with_future.update_attributes name: "Single Standard", price: 94, valid_from: Date.today+2
|
386
|
+
@master_class.with_current_version.all.should have(1).item
|
387
|
+
end
|
388
|
+
it "gets pending or current version attributes" do
|
389
|
+
master = @master_class.new
|
390
|
+
master.attributes.should == {}
|
391
|
+
master.pending_version.should be_nil
|
392
|
+
master.current_version.should be_nil
|
393
|
+
master.name.should be_nil
|
394
|
+
|
395
|
+
master.pending_or_current_version.name.should be_nil
|
396
|
+
master.update_attributes name: "Single Standard", price: 98
|
397
|
+
master.attributes[:name].should == "Single Standard"
|
398
|
+
master.pending_version.should be_nil
|
399
|
+
master.pending_or_current_version.name.should == "Single Standard"
|
400
|
+
master.name.should == "Single Standard"
|
401
|
+
|
402
|
+
master.attributes = {name: "King Size"}
|
403
|
+
master.attributes[:name].should == "King Size"
|
404
|
+
master.pending_version.should be
|
405
|
+
master.pending_or_current_version.name.should == "King Size"
|
406
|
+
master.name.should == "King Size"
|
407
|
+
end
|
408
|
+
it "allows to go back in time" do
|
409
|
+
master = @master_class.new
|
410
|
+
master.update_attributes name: "Single Standard", price: 98, valid_to: Date.today+1
|
411
|
+
master.update_attributes name: "Single Standard", price: 95, valid_from: Date.today+1, valid_to: Date.today+2
|
412
|
+
master.update_attributes name: "Single Standard", price: 93, valid_from: Date.today+2, valid_to: Date.today+3
|
413
|
+
master.update_attributes name: "Single Standard", price: 91, valid_from: Date.today+3
|
414
|
+
Timecop.freeze Date.today+1
|
415
|
+
master.update_attributes price: 94
|
416
|
+
master.update_attributes price: 96, valid_from: Date.today+2
|
417
|
+
master.should have_versions %Q{
|
418
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
419
|
+
| Single Standard | 98 | 2009-11-28 | | 2009-11-28 | 2009-11-29 | |
|
420
|
+
| Single Standard | 95 | 2009-11-28 | 2009-11-29 | 2009-11-29 | 2009-11-30 | |
|
421
|
+
| Single Standard | 93 | 2009-11-28 | | 2009-11-30 | 2009-12-01 | |
|
422
|
+
| Single Standard | 91 | 2009-11-28 | 2009-11-29 | 2009-12-01 | MAX DATE | |
|
423
|
+
| Single Standard | 94 | 2009-11-29 | | 2009-11-29 | 2009-11-30 | true |
|
424
|
+
| Single Standard | 96 | 2009-11-29 | | 2009-12-01 | MAX DATE | |
|
425
|
+
}
|
426
|
+
master.current_version.price.should == 94
|
427
|
+
Sequel::Plugins::Bitemporal.at(Date.today-1) do
|
428
|
+
master.current_version(true).price.should == 98
|
429
|
+
end
|
430
|
+
Sequel::Plugins::Bitemporal.at(Date.today+1) do
|
431
|
+
master.current_version(true).price.should == 93
|
432
|
+
end
|
433
|
+
Sequel::Plugins::Bitemporal.at(Date.today+2) do
|
434
|
+
master.current_version(true).price.should == 96
|
435
|
+
end
|
436
|
+
Sequel::Plugins::Bitemporal.as_we_knew_it(Date.today-1) do
|
437
|
+
master.current_version(true).price.should == 95
|
438
|
+
master.current_version.should be_current
|
439
|
+
Sequel::Plugins::Bitemporal.at(Date.today-1) do
|
440
|
+
master.current_version(true).price.should == 98
|
441
|
+
end
|
442
|
+
Sequel::Plugins::Bitemporal.at(Date.today+1) do
|
443
|
+
master.current_version(true).price.should == 93
|
444
|
+
end
|
445
|
+
Sequel::Plugins::Bitemporal.at(Date.today+2) do
|
446
|
+
master.current_version(true).price.should == 91
|
447
|
+
end
|
448
|
+
end
|
449
|
+
end
|
450
|
+
it "correctly reset time if failure when going back in time" do
|
451
|
+
before = Sequel::Plugins::Bitemporal.now
|
452
|
+
lambda do
|
453
|
+
Sequel::Plugins::Bitemporal.at(Date.today+2) do
|
454
|
+
raise StandardError, "error during back in time"
|
455
|
+
end
|
456
|
+
end.should raise_error StandardError
|
457
|
+
Sequel::Plugins::Bitemporal.now.should == before
|
458
|
+
lambda do
|
459
|
+
Sequel::Plugins::Bitemporal.as_we_knew_it(Date.today+2) do
|
460
|
+
raise StandardError, "error during back in time"
|
461
|
+
end
|
462
|
+
end.should raise_error StandardError
|
463
|
+
Sequel::Plugins::Bitemporal.now.should == before
|
464
|
+
end
|
465
|
+
it "allows eager loading with conditions on current or future versions" do
|
466
|
+
master = @master_class.new
|
467
|
+
master.update_attributes name: "Single Standard", price: 98
|
468
|
+
Timecop.freeze Date.today+1
|
469
|
+
master.update_attributes name: "Single Standard", price: 99
|
470
|
+
master.update_attributes name: "Single Standard", price: 94, valid_from: Date.today+2
|
471
|
+
res = @master_class.eager_graph(:current_or_future_versions).where(Sequel.negate(current_or_future_versions__id: nil) & {price: 99}).all.first
|
472
|
+
res.should be
|
473
|
+
res.current_or_future_versions.should have(1).item
|
474
|
+
res.current_or_future_versions.first.price.should == 99
|
475
|
+
res = @master_class.eager_graph(:current_or_future_versions).where(Sequel.negate(current_or_future_versions__id: nil) & {price: 94}).all.first
|
476
|
+
res.should be
|
477
|
+
res.current_or_future_versions.should have(1).item
|
478
|
+
res.current_or_future_versions.first.price.should == 94
|
479
|
+
Timecop.freeze Date.today+1
|
480
|
+
master.destroy
|
481
|
+
@master_class.eager_graph(:current_or_future_versions).where(Sequel.negate(current_or_future_versions__id: nil)).all.should be_empty
|
482
|
+
end
|
483
|
+
it "allows loading masters with current or future versions" do
|
484
|
+
master_destroyed = @master_class.new
|
485
|
+
master_destroyed.update_attributes name: "Single Standard", price: 98
|
486
|
+
master_destroyed.destroy
|
487
|
+
master_with_current = @master_class.new
|
488
|
+
master_with_current.update_attributes name: "Single Standard", price: 94
|
489
|
+
master_with_future = @master_class.new
|
490
|
+
master_with_future.update_attributes name: "Single Standard", price: 94, valid_from: Date.today+2
|
491
|
+
@master_class.with_current_or_future_versions.all.should have(2).item
|
492
|
+
end
|
493
|
+
it "delegates attributes from master to pending_or_current_version" do
|
494
|
+
master = @master_class.new
|
495
|
+
master.name.should be_nil
|
496
|
+
master.update_attributes name: "Single Standard", price: 98
|
497
|
+
master.name.should == "Single Standard"
|
498
|
+
master.attributes = {name: "King Size"}
|
499
|
+
master.name.should == "King Size"
|
500
|
+
end
|
501
|
+
it "avoids delegation with option delegate: false" do
|
502
|
+
closure = @version_class
|
503
|
+
without_delegation_class = Class.new Sequel::Model do
|
504
|
+
set_dataset :rooms
|
505
|
+
plugin :bitemporal, version_class: closure, delegate: false
|
506
|
+
end
|
507
|
+
master = without_delegation_class.new
|
508
|
+
expect{ master.name }.to raise_error NoMethodError
|
509
|
+
end
|
510
|
+
it "get current_version association name from class name" do
|
511
|
+
class MyNameVersion < Sequel::Model
|
512
|
+
set_dataset :room_versions
|
513
|
+
end
|
514
|
+
class MyName < Sequel::Model
|
515
|
+
set_dataset :rooms
|
516
|
+
plugin :bitemporal, version_class: MyNameVersion
|
517
|
+
end
|
518
|
+
expect do
|
519
|
+
MyName.eager_graph(:current_version).where("my_name_current_version.id IS NOT NULL").first
|
520
|
+
end.not_to raise_error
|
521
|
+
Object.send :remove_const, :MyName
|
522
|
+
Object.send :remove_const, :MyNameVersion
|
523
|
+
end
|
524
|
+
it "can update master and current version at the same time" do
|
525
|
+
master = @master_class.new.update_attributes name: "Single Standard", price: 98
|
526
|
+
master.disabled = true
|
527
|
+
master.update_attributes price: 94
|
528
|
+
master.reload.disabled.should be_true
|
529
|
+
end
|
530
|
+
it "uses current version for partial_update even if valid_from is specified" do
|
531
|
+
master = @master_class.new
|
532
|
+
master.update_attributes name: "Single Standard", price: 98, valid_from: Date.today-2, valid_to: Date.today
|
533
|
+
master.update_attributes name: "Single Standard", price: 94
|
534
|
+
master.should have_versions %Q{
|
535
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
536
|
+
| Single Standard | 98 | 2009-11-28 | | 2009-11-26 | 2009-11-28 | |
|
537
|
+
| Single Standard | 94 | 2009-11-28 | | 2009-11-28 | MAX DATE | true |
|
538
|
+
}
|
539
|
+
master.update_attributes name: "King Size", valid_from: Date.today-2
|
540
|
+
master.should have_versions %Q{
|
541
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
542
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-26 | 2009-11-28 | |
|
543
|
+
| Single Standard | 94 | 2009-11-28 | | 2009-11-28 | MAX DATE | true |
|
544
|
+
| King Size | 94 | 2009-11-28 | | 2009-11-26 | 2009-11-28 | |
|
545
|
+
}
|
546
|
+
end
|
547
|
+
it "as_we_knew_it also allows creating and deleting at that time" do
|
548
|
+
master = @master_class.new
|
549
|
+
master.update_attributes name: "Single Standard", price: 98
|
550
|
+
Sequel::Plugins::Bitemporal.as_we_knew_it(Date.today+1) do
|
551
|
+
master.update_attributes name: "King Size"
|
552
|
+
end
|
553
|
+
master.should have_versions %Q{
|
554
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
555
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | MAX DATE | true |
|
556
|
+
| King Size | 98 | 2009-11-29 | | 2009-11-28 | MAX DATE | |
|
557
|
+
}
|
558
|
+
Sequel::Plugins::Bitemporal.as_we_knew_it(Date.today+2) do
|
559
|
+
master.current_version(true).destroy
|
560
|
+
end
|
561
|
+
master.should have_versions %Q{
|
562
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
563
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | MAX DATE | true |
|
564
|
+
| King Size | 98 | 2009-11-29 | 2009-11-30 | 2009-11-28 | MAX DATE | |
|
565
|
+
| King Size | 98 | 2009-11-30 | | 2009-11-28 | 2009-11-28 | |
|
566
|
+
}
|
567
|
+
end
|
568
|
+
it "combines as_we_knew_it and at to set valid_from" do
|
569
|
+
master = @master_class.new
|
570
|
+
master.update_attributes name: "Single Standard", price: 98, valid_from: Date.today-2, valid_to: Date.today
|
571
|
+
master.update_attributes name: "Single Standard", price: 94
|
572
|
+
master.should have_versions %Q{
|
573
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
574
|
+
| Single Standard | 98 | 2009-11-28 | | 2009-11-26 | 2009-11-28 | |
|
575
|
+
| Single Standard | 94 | 2009-11-28 | | 2009-11-28 | MAX DATE | true |
|
576
|
+
}
|
577
|
+
Sequel::Plugins::Bitemporal.as_we_knew_it(Date.today+1) do
|
578
|
+
Sequel::Plugins::Bitemporal.at(Date.today-1) do
|
579
|
+
master.update_attributes name: "King Size"
|
580
|
+
end
|
581
|
+
end
|
582
|
+
master.should have_versions %Q{
|
583
|
+
| name | price | created_at | expired_at | valid_from | valid_to | current |
|
584
|
+
| Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-26 | 2009-11-28 | |
|
585
|
+
| Single Standard | 94 | 2009-11-28 | | 2009-11-28 | MAX DATE | true |
|
586
|
+
| Single Standard | 98 | 2009-11-29 | | 2009-11-26 | 2009-11-27 | |
|
587
|
+
| King Size | 98 | 2009-11-29 | | 2009-11-27 | 2009-11-28 | |
|
588
|
+
}
|
589
|
+
end
|
590
|
+
context "#deleted?" do
|
591
|
+
subject{ @master_class.new }
|
592
|
+
it "is false unless persisted" do
|
593
|
+
subject.should_not be_deleted
|
594
|
+
end
|
595
|
+
it "is false when persisted with a current version" do
|
596
|
+
subject.update_attributes(name: "Single Standard", price: 94).should_not be_deleted
|
597
|
+
end
|
598
|
+
it "is true when persisted without a current version" do
|
599
|
+
subject.update_attributes(name: "Single Standard", price: 94, valid_from: Date.today+1).should be_deleted
|
600
|
+
end
|
601
|
+
end
|
602
|
+
context "#last_version" do
|
603
|
+
subject{ @master_class.new }
|
604
|
+
it "is nil unless persisted" do
|
605
|
+
subject.last_version.should be_nil
|
606
|
+
end
|
607
|
+
it "is current version when persisted with a current version" do
|
608
|
+
subject.update_attributes name: "Single Standard", price: 94
|
609
|
+
subject.last_version.should == subject.current_version
|
610
|
+
end
|
611
|
+
it "is nil with future version but no current version" do
|
612
|
+
subject.update_attributes name: "Single Standard", price: 94, valid_from: Date.today+1
|
613
|
+
subject.last_version.should be_nil
|
614
|
+
end
|
615
|
+
it "is last version with previous version but no current version" do
|
616
|
+
subject.update_attributes name: "Single Standard", price: 94, valid_from: Date.today-2, valid_to: Date.today-1
|
617
|
+
subject.current_version.should be_nil
|
618
|
+
subject.last_version.should == subject.versions.last
|
619
|
+
end
|
620
|
+
end
|
621
|
+
context "#restore" do
|
622
|
+
subject{ @master_class.new }
|
623
|
+
it "make last version current" do
|
624
|
+
subject.update_attributes name: "Single Standard", price: 94, valid_from: Date.today-2, valid_to: Date.today-1
|
625
|
+
subject.restore
|
626
|
+
subject.current_version.should == subject.last_version
|
627
|
+
end
|
628
|
+
it "can add additional attributes to apply" do
|
629
|
+
subject.update_attributes name: "Single Standard", price: 94, valid_from: Date.today-2, valid_to: Date.today-1
|
630
|
+
subject.restore name: "New Standard"
|
631
|
+
subject.current_version.name.should == "New Standard"
|
632
|
+
subject.current_version.price.should == 94
|
633
|
+
end
|
634
|
+
end
|
635
|
+
end
|
636
|
+
|
637
|
+
describe "Sequel::Plugins::Bitemporal", "with audit and ranges" do
|
638
|
+
before :all do
|
639
|
+
@audit_class = Class.new do
|
640
|
+
def self.audit(*args); end
|
641
|
+
end
|
642
|
+
db_setup audit_class: @audit_class, ranges: true
|
643
|
+
end
|
644
|
+
before do
|
645
|
+
Timecop.freeze 2009, 11, 28
|
646
|
+
end
|
647
|
+
after do
|
648
|
+
Timecop.return
|
649
|
+
end
|
650
|
+
let(:author){ mock :author, audit_kind: "user" }
|
651
|
+
it "generates a new audit on creation" do
|
652
|
+
master = @master_class.new
|
653
|
+
master.should_receive(:updated_by).and_return author
|
654
|
+
@audit_class.should_receive(:audit).with(
|
655
|
+
master,
|
656
|
+
{},
|
657
|
+
hash_including({name: "Single Standard", price: 98}),
|
658
|
+
Date.today,
|
659
|
+
author
|
660
|
+
)
|
661
|
+
master.update_attributes name: "Single Standard", price: 98
|
662
|
+
end
|
663
|
+
it "generates a new audit on full update" do
|
664
|
+
master = @master_class.new
|
665
|
+
master.should_receive(:updated_by).twice.and_return author
|
666
|
+
master.update_attributes name: "Single Standard", price: 98
|
667
|
+
@audit_class.should_receive(:audit).with(
|
668
|
+
master,
|
669
|
+
hash_including({name: "Single Standard", price: 98}),
|
670
|
+
hash_including({name: "King size", price: 98}),
|
671
|
+
Date.today,
|
672
|
+
author
|
673
|
+
)
|
674
|
+
master.update_attributes name: "King size", price: 98
|
675
|
+
end
|
676
|
+
it "generates a new audit on partial update" do
|
677
|
+
master = @master_class.new
|
678
|
+
master.should_receive(:updated_by).twice.and_return author
|
679
|
+
master.update_attributes name: "Single Standard", price: 98
|
680
|
+
@audit_class.should_receive(:audit).with(
|
681
|
+
master,
|
682
|
+
hash_including({name: "Single Standard", price: 98}),
|
683
|
+
hash_including({name: "King size", price: 98}),
|
684
|
+
Date.today,
|
685
|
+
author
|
686
|
+
)
|
687
|
+
master.update_attributes name: "King size", price: 98
|
688
|
+
end
|
689
|
+
it "generate a new audit for each future version update when propagating changes" do
|
690
|
+
propagate_per_column = @master_class.propagate_per_column
|
691
|
+
begin
|
692
|
+
@master_class.instance_variable_set :@propagate_per_column, true
|
693
|
+
master = @master_class.new
|
694
|
+
master.should_receive(:updated_by).exactly(8).times.and_return author
|
695
|
+
|
696
|
+
master.update_attributes name: "Single Standard", price: 12, length: nil, width: 1
|
697
|
+
initial_today = Date.today
|
698
|
+
Timecop.freeze initial_today+1 do
|
699
|
+
Sequel::Plugins::Bitemporal.at initial_today+4 do
|
700
|
+
master.update_attributes valid_from: initial_today+4, name: "King Size", price: 15, length: 2, width: 2
|
701
|
+
end
|
702
|
+
end
|
703
|
+
Timecop.freeze initial_today+2 do
|
704
|
+
Sequel::Plugins::Bitemporal.at initial_today+3 do
|
705
|
+
master.update_attributes valid_from: initial_today+3, length: 1, width: 1
|
706
|
+
end
|
707
|
+
end
|
708
|
+
@audit_class.should_receive(:audit).with(
|
709
|
+
master,
|
710
|
+
hash_including({name: "Single Standard", price: 12, length: nil, width: 1}),
|
711
|
+
hash_including({name: "Single Standard", price: 12, length: 3, width: 4}),
|
712
|
+
initial_today+2,
|
713
|
+
author
|
714
|
+
)
|
715
|
+
@audit_class.should_receive(:audit).with(
|
716
|
+
master,
|
717
|
+
hash_including({name: "Single Standard", price: 12, length: 1, width: 1}),
|
718
|
+
hash_including({name: "Single Standard", price: 12, length: 1, width: 4}),
|
719
|
+
initial_today+3,
|
720
|
+
author
|
721
|
+
)
|
722
|
+
Timecop.freeze initial_today+3 do
|
723
|
+
Sequel::Plugins::Bitemporal.at initial_today+2 do
|
724
|
+
master.update_attributes valid_from: initial_today+2, length: 3, width: 4
|
725
|
+
end
|
726
|
+
end
|
727
|
+
ensure
|
728
|
+
@master_class.instance_variable_set :@propagate_per_column, propagate_per_column
|
729
|
+
end
|
730
|
+
end
|
731
|
+
end
|
732
|
+
describe "Sequel::Plugins::Bitemporal", "with audit, ranges, specifying how to get the author" do
|
733
|
+
before :all do
|
734
|
+
@audit_class = Class.new do
|
735
|
+
def self.audit(*args); end
|
736
|
+
end
|
737
|
+
db_setup audit_class: @audit_class, audit_updated_by_method: :author, ranges: true
|
738
|
+
end
|
739
|
+
let(:author){ mock :author, audit_kind: "user" }
|
740
|
+
before do
|
741
|
+
Timecop.freeze 2009, 11, 28
|
742
|
+
end
|
743
|
+
after do
|
744
|
+
Timecop.return
|
745
|
+
end
|
746
|
+
it "generates a new audit on creation" do
|
747
|
+
master = @master_class.new
|
748
|
+
master.should_receive(:author).and_return author
|
749
|
+
@audit_class.should_receive(:audit).with(
|
750
|
+
master,
|
751
|
+
{},
|
752
|
+
hash_including({name: "Single Standard", price: 98}),
|
753
|
+
Date.today,
|
754
|
+
author
|
755
|
+
)
|
756
|
+
master.update_attributes name: "Single Standard", price: 98
|
757
|
+
end
|
758
|
+
it "generates a new audit on full update" do
|
759
|
+
master = @master_class.new
|
760
|
+
master.should_receive(:author).twice.and_return author
|
761
|
+
master.update_attributes name: "Single Standard", price: 98
|
762
|
+
@audit_class.should_receive(:audit).with(
|
763
|
+
master,
|
764
|
+
hash_including({name: "Single Standard", price: 98}),
|
765
|
+
hash_including({name: "King size", price: 98}),
|
766
|
+
Date.today,
|
767
|
+
author
|
768
|
+
)
|
769
|
+
master.update_attributes name: "King size", price: 98
|
770
|
+
end
|
771
|
+
it "generates a new audit on partial update" do
|
772
|
+
master = @master_class.new
|
773
|
+
master.should_receive(:author).twice.and_return author
|
774
|
+
master.update_attributes name: "Single Standard", price: 98
|
775
|
+
@audit_class.should_receive(:audit).with(
|
776
|
+
master,
|
777
|
+
hash_including({name: "Single Standard", price: 98}),
|
778
|
+
hash_including({name: "King size", price: 98}),
|
779
|
+
Date.today,
|
780
|
+
author
|
781
|
+
)
|
782
|
+
master.update_attributes name: "King size", price: 98
|
783
|
+
end
|
784
|
+
end
|
785
|
+
end
|