acts_as_archival 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/.gitignore +10 -0
  2. data/.rvmrc +1 -0
  3. data/CHANGELOG.md +5 -0
  4. data/Gemfile +2 -0
  5. data/Gemfile.lock +44 -0
  6. data/LICENSE +22 -0
  7. data/README.md +112 -0
  8. data/Rakefile +13 -0
  9. data/acts_as_archival.gemspec +47 -0
  10. data/init.rb +3 -0
  11. data/lib/acts_as_archival.rb +7 -0
  12. data/lib/acts_as_archival/version.rb +3 -0
  13. data/lib/expected_behavior/acts_as_archival.rb +141 -0
  14. data/lib/expected_behavior/acts_as_archival_active_record_methods.rb +20 -0
  15. data/test/ambiguous_table_test.rb +12 -0
  16. data/test/associations_test.rb +102 -0
  17. data/test/basic_test.rb +64 -0
  18. data/test/column_test.rb +15 -0
  19. data/test/database.yml +8 -0
  20. data/test/deep_nesting_test.rb +29 -0
  21. data/test/fixtures/archival.rb +15 -0
  22. data/test/fixtures/archival_grandkid.rb +4 -0
  23. data/test/fixtures/archival_kid.rb +5 -0
  24. data/test/fixtures/exploder.rb +5 -0
  25. data/test/fixtures/independent_archival.rb +9 -0
  26. data/test/fixtures/mass_attribute_protected.rb +4 -0
  27. data/test/fixtures/missing_archive_number.rb +3 -0
  28. data/test/fixtures/missing_archived_at.rb +3 -0
  29. data/test/fixtures/plain.rb +5 -0
  30. data/test/fixtures/poly.rb +9 -0
  31. data/test/fixtures/readonly_when_archived.rb +3 -0
  32. data/test/mass_attribute_test.rb +18 -0
  33. data/test/polymorphic_test.rb +25 -0
  34. data/test/readonly_when_archived_test.rb +22 -0
  35. data/test/responds_test.rb +13 -0
  36. data/test/schema.rb +67 -0
  37. data/test/scope_test.rb +50 -0
  38. data/test/script/db_setup +57 -0
  39. data/test/test_helper.rb +60 -0
  40. data/test/through_association_test.rb +25 -0
  41. data/test/transaction_test.rb +32 -0
  42. metadata +235 -0
@@ -0,0 +1,12 @@
1
+ require_relative "test_helper"
2
+
3
+ class AmbiguousTableTest < ActiveSupport::TestCase
4
+ # test against the problem fixed in http://github.com/DarkTatka/acts_as_archival/commit/63d0a2532a15d7a6ab41d081e1591108a5ea9b37
5
+ test "no ambiguous table problem" do
6
+ archival = Archival.create!(:name => "TEST")
7
+ child = archival.archivals.create!
8
+ child.archive
9
+
10
+ assert_equal 1, Archival.unarchived.count(:joins => :archivals)
11
+ end
12
+ end
@@ -0,0 +1,102 @@
1
+ require_relative "test_helper"
2
+
3
+ class ActsAsArchivalTest < ActiveSupport::TestCase
4
+ test "archive archives 'has_' associated archival objects that are dependent destroy" do
5
+ archival = Archival.create!
6
+ child = archival.archivals.create!
7
+ archival.archive
8
+
9
+ assert archival.reload.archived?
10
+ assert child.reload.archived?
11
+ end
12
+
13
+ test "archive acts on all objects in the 'has_' relationship" do
14
+ archival = Archival.create!
15
+ children = [archival.archivals.create!, archival.archivals.create!]
16
+ archival.archive
17
+
18
+ assert archival.reload.archived?
19
+ assert children.map(&:reload).all?(&:archived?)
20
+ end
21
+
22
+ test "archive does not act on already archived objects" do
23
+ archival = Archival.create!
24
+ child = archival.archivals.create!
25
+ prearchived_child = archival.archivals.create!
26
+ prearchived_child.archive
27
+ archival.archive
28
+
29
+ assert_not_equal archival.archive_number, prearchived_child.reload.archive_number
30
+ end
31
+
32
+ test "archive does not archive 'has_' associated archival objects that are not dependent destroy" do
33
+ archival = Archival.create!
34
+ non_dependent_child = archival.independent_archivals.create!
35
+ archival.archive
36
+
37
+ assert archival.reload.archived?
38
+ assert_not non_dependent_child.reload.archived?
39
+ end
40
+
41
+ test "archive doesn't do anything to associated dependent destroy models that are non-archival" do
42
+ archival = Archival.create!
43
+ plain = archival.plains.create!
44
+ archival.archive
45
+
46
+ assert archival.archived?
47
+ assert plain.reload
48
+ end
49
+
50
+ test "archive sets the object hierarchy to all have the same archive_number" do
51
+ archival = Archival.create!
52
+ child = archival.archivals.create!
53
+ archival.archive
54
+ expected_digest = Digest::MD5.hexdigest("Archival#{archival.id}")
55
+
56
+ assert_equal expected_digest, archival.archive_number
57
+ assert_equal expected_digest, child.reload.archive_number
58
+ end
59
+
60
+ test "unarchive acts on child objects" do
61
+ archival = Archival.create!
62
+ child = archival.archivals.create!
63
+ archival.archive
64
+ archival.unarchive
65
+
66
+ assert_not archival.archived?
67
+ assert_not child.reload.archived?
68
+ end
69
+
70
+ test "unarchive does not act on already archived objects" do
71
+ archival = Archival.create!
72
+ child = archival.archivals.create!
73
+ prearchived_child = archival.archivals.create!
74
+ prearchived_child.archive
75
+ archival.archive
76
+ archival.unarchive
77
+
78
+ assert_not archival.archived?
79
+ assert_not child.reload.archived?
80
+ assert prearchived_child.reload.archived?
81
+ end
82
+
83
+ test "unarchive acts on 'has_' associated non-dependent_destroy objects" do
84
+ archival = Archival.create!
85
+ independent = archival.independent_archivals.create!
86
+ archival.archive
87
+ independent.archive(archival.archive_number)
88
+ archival.unarchive
89
+
90
+ assert_not archival.reload.archived?
91
+ assert_not independent.reload.archived?
92
+ end
93
+
94
+ test "unarchive doesn't unarchive associated objects if the head object is already unarchived" do
95
+ archival = Archival.create!
96
+ prearchived_child = archival.archivals.create!
97
+ prearchived_child.archive
98
+ archival.unarchive
99
+
100
+ assert prearchived_child.reload.archived?
101
+ end
102
+ end
@@ -0,0 +1,64 @@
1
+ require_relative "test_helper"
2
+
3
+ class BasicTest < ActiveSupport::TestCase
4
+ test "archive archives the record" do
5
+ archival = Archival.create!
6
+
7
+ archival.archive
8
+ assert archival.archived?
9
+ end
10
+
11
+ test "unarchive unarchives archival records" do
12
+ archival = Archival.create!(:archived_at => Time.now, :archive_number => 1)
13
+ archival.unarchive
14
+
15
+ assert_not archival.archived?
16
+ end
17
+
18
+ test "archive returns true on success, false on failure" do
19
+ archival = Archival.create!
20
+ readonly = Archival.create!
21
+ readonly.readonly!
22
+
23
+ assert_equal true, archival.archive
24
+ assert_equal false, readonly.archive
25
+ end
26
+
27
+ test "unarchive returns true on success, false on failure" do
28
+ archived = Archival.create!(:archived_at => Time.now, :archive_number => "1")
29
+ readonly = Archival.create!(:archived_at => Time.now, :archive_number => "2")
30
+ readonly.readonly!
31
+
32
+ assert_equal true, archived.unarchive
33
+ assert_equal false, readonly.unarchive
34
+ end
35
+
36
+ test "archive sets archived_at to the time of archiving" do
37
+ archival = Archival.create!
38
+ before = DateTime.now
39
+ sleep(0.001)
40
+ archival.archive
41
+ sleep(0.001)
42
+ after = DateTime.now
43
+
44
+ assert_between before, after, archival.archived_at.to_datetime
45
+ end
46
+
47
+ test "archive sets the archive number to the md5 hexdigest for the model and id that is archived" do
48
+ archival = Archival.create!
49
+ archival.archive
50
+
51
+ expected_digest = Digest::MD5.hexdigest("#{archival.class.name}#{archival.id}")
52
+ assert_equal expected_digest, archival.archive_number
53
+ end
54
+
55
+ test "archive on archived object doesn't alter the archive_number" do
56
+ archived = Archival.create
57
+ archived.archive
58
+ initial_number = archived.archive_number
59
+ archived.reload.archive
60
+ second_number = archived.archive_number
61
+
62
+ assert_equal initial_number, second_number
63
+ end
64
+ end
@@ -0,0 +1,15 @@
1
+ require_relative "test_helper"
2
+
3
+ class ColumnTest < ActiveSupport::TestCase
4
+ test "acts_as_archival raises during create if missing archived_at column" do
5
+ assert_raises(ExpectedBehavior::ActsAsArchival::MissingArchivalColumnError) {
6
+ MissingArchivedAt.create!(:name => "foo-foo")
7
+ }
8
+ end
9
+
10
+ test "acts_as_archival raises during create if missing archive_number column" do
11
+ assert_raises(ExpectedBehavior::ActsAsArchival::MissingArchivalColumnError) {
12
+ MissingArchiveNumber.create!(:name => "rover")
13
+ }
14
+ end
15
+ end
data/test/database.yml ADDED
@@ -0,0 +1,8 @@
1
+ adapter: mysql2
2
+ encoding: utf8
3
+ reconnect: false
4
+ database: aaa_test
5
+ pool: 5
6
+ username: archival_tester
7
+ password: perspicacious
8
+ socket: /tmp/mysql.sock
@@ -0,0 +1,29 @@
1
+ require_relative "test_helper"
2
+
3
+ class DeepNestingTest < ActiveSupport::TestCase
4
+ test "archiving deeply nested items" do
5
+ archival = Archival.create!
6
+ child = archival.archivals.create!
7
+ grandchild = child.archivals.create!
8
+ archival.archive
9
+
10
+ assert archival.reload.archived?
11
+ assert child.reload.archived?
12
+ assert grandchild.reload.archived?
13
+ end
14
+
15
+ test "unarchiving deeply nested items doesn't blow up" do
16
+ archival_attributes = {
17
+ :archived_at => Time.now,
18
+ :archive_number => "test"
19
+ }
20
+ archival = Archival.create!(archival_attributes)
21
+ child = archival.archivals.create!(archival_attributes)
22
+ grandchild = child.archivals.create!(archival_attributes)
23
+ archival.unarchive
24
+
25
+ assert_not archival.reload.archived?
26
+ assert_not child.reload.archived?
27
+ assert_not grandchild.reload.archived?
28
+ end
29
+ end
@@ -0,0 +1,15 @@
1
+ # name - string
2
+ # archival_id - integer
3
+ # archive_number - string
4
+ # archived_at - datetime
5
+ class Archival < ActiveRecord::Base
6
+ acts_as_archival
7
+
8
+ has_many :archivals, :dependent => :destroy
9
+ has_many :archival_kids, :dependent => :destroy
10
+ has_many :archival_grandkids, :dependent => :destroy, :through => :archival_kids
11
+ has_many :exploders, :dependent => :destroy
12
+ has_many :plains, :dependent => :destroy
13
+ has_many :polys, :dependent => :destroy, :as => :archiveable
14
+ has_many :independent_archivals
15
+ end
@@ -0,0 +1,4 @@
1
+ class ArchivalGrandkid < ActiveRecord::Base
2
+ acts_as_archival
3
+ belongs_to :archival_kid
4
+ end
@@ -0,0 +1,5 @@
1
+ class ArchivalKid < ActiveRecord::Base
2
+ acts_as_archival
3
+ belongs_to :archival
4
+ has_many :archival_grandkids, :dependent => :destroy
5
+ end
@@ -0,0 +1,5 @@
1
+ class Exploder < ActiveRecord::Base
2
+ acts_as_archival
3
+
4
+ belongs_to :archival
5
+ end
@@ -0,0 +1,9 @@
1
+ # name - string
2
+ # archival_id - integer
3
+ # archive_number - string
4
+ # archived_at - datetime
5
+ class IndependentArchival < ActiveRecord::Base
6
+ acts_as_archival
7
+
8
+ belongs_to :archival
9
+ end
@@ -0,0 +1,4 @@
1
+ class MassAttributeProtected < ActiveRecord::Base
2
+ acts_as_archival
3
+ attr_accessible :name
4
+ end
@@ -0,0 +1,3 @@
1
+ class MissingArchiveNumber < ActiveRecord::Base
2
+ acts_as_archival
3
+ end
@@ -0,0 +1,3 @@
1
+ class MissingArchivedAt < ActiveRecord::Base
2
+ acts_as_archival
3
+ end
@@ -0,0 +1,5 @@
1
+ # name - string
2
+ # archival_id - integer
3
+ class Plain < ActiveRecord::Base
4
+ belongs_to :archival
5
+ end
@@ -0,0 +1,9 @@
1
+ # -*- coding: utf-8 -*-
2
+ # archiveable_id - integer
3
+ # archiveable_type - string
4
+ # archive_number - string
5
+ # archived_at - datetime
6
+ class Poly < ActiveRecord::Base
7
+ acts_as_archival
8
+ belongs_to :archiveable, :polymorphic => true
9
+ end
@@ -0,0 +1,3 @@
1
+ class ReadonlyWhenArchived < ActiveRecord::Base
2
+ acts_as_archival :readonly_when_archived => true
3
+ end
@@ -0,0 +1,18 @@
1
+ require_relative "test_helper"
2
+
3
+ class MassAttributeTest < ActiveSupport::TestCase
4
+ test "archive works when attr_accessible present" do
5
+ archival = MassAttributeProtected.create(:color => "pink")
6
+ archival.archive
7
+
8
+ assert archival.reload.archived?
9
+ end
10
+
11
+ test "unarchive works when attr_accessible present" do
12
+ archival = MassAttributeProtected.create(:color => "pink")
13
+ archival.archive
14
+ archival.unarchive
15
+
16
+ assert_not archival.reload.archived?
17
+ end
18
+ end
@@ -0,0 +1,25 @@
1
+ require_relative "test_helper"
2
+
3
+ class PolymorphicTest < ActiveSupport::TestCase
4
+ test "archive item with polymorphic association" do
5
+ archival = Archival.create!
6
+ poly = archival.polys.create!
7
+ archival.archive
8
+
9
+ assert archival.reload.archived?
10
+ assert poly.reload.archived?
11
+ end
12
+
13
+ test "unarchive item with polymorphic association" do
14
+ archive_attributes = {
15
+ :archive_number => "test",
16
+ :archived_at => Time.now
17
+ }
18
+ archival = Archival.create!(archive_attributes)
19
+ poly = archival.polys.create!(archive_attributes)
20
+ archival.unarchive
21
+
22
+ assert_not archival.reload.archived?
23
+ assert_not poly.reload.archived?
24
+ end
25
+ end
@@ -0,0 +1,22 @@
1
+ require_relative "test_helper"
2
+
3
+ class ReadonlyWhenArchivedTest < ActiveSupport::TestCase
4
+ test "acts_as_archival objects can normally be altered after archive" do
5
+ archival = Archival.create!(:name => "original")
6
+ archival.archive
7
+ archival.name = "updated"
8
+ archival.save!
9
+
10
+ assert_equal "updated", archival.reload.name
11
+ end
12
+
13
+ test "acts_as_archival marked as readonly_when_archived cannot be updated after archive" do
14
+ archival = ReadonlyWhenArchived.create!(:name => "original")
15
+ archival.archive
16
+ archival.name = "updated"
17
+
18
+ assert_not archival.save
19
+ assert_equal "Cannot modifify an archived record.",
20
+ archival.errors.full_messages.first
21
+ end
22
+ end
@@ -0,0 +1,13 @@
1
+ require_relative "test_helper"
2
+
3
+ class RespondsTest < ActiveSupport::TestCase
4
+ test "archival class responds correctly to 'is_archival?'" do
5
+ assert Archival.is_archival?
6
+ assert_not Plain.is_archival?
7
+ end
8
+
9
+ test "archival object responds correctly to 'is_archival?'" do
10
+ assert Archival.new.is_archival?
11
+ assert_not Plain.new.is_archival?
12
+ end
13
+ end
data/test/schema.rb ADDED
@@ -0,0 +1,67 @@
1
+ ActiveRecord::Schema.define(:version => 1) do
2
+
3
+ create_table :archivals, :force => true do |t|
4
+ t.column :name, :string
5
+ t.column :archival_id, :integer
6
+ t.column :archive_number, :string
7
+ t.column :archived_at, :datetime
8
+ end
9
+
10
+ create_table :archival_kids, :force => true do |t|
11
+ t.column :archival_id, :integer
12
+ t.column :archive_number, :string
13
+ t.column :archived_at, :datetime
14
+ end
15
+
16
+ create_table :archival_grandkids, :force => true do |t|
17
+ t.column :archival_kid_id, :integer
18
+ t.column :archive_number, :string
19
+ t.column :archived_at, :datetime
20
+ end
21
+
22
+ create_table :independent_archivals, :force => true do |t|
23
+ t.column :name, :string
24
+ t.column :archival_id, :integer
25
+ t.column :archive_number, :string
26
+ t.column :archived_at, :datetime
27
+ end
28
+
29
+ create_table :exploders, :force => true do |t|
30
+ t.column :archival_id, :integer
31
+ t.column :archive_number, :string
32
+ t.column :archived_at, :datetime
33
+ end
34
+
35
+ create_table :plains, :force => true do |t|
36
+ t.column :name, :string
37
+ t.column :archival_id, :integer
38
+ end
39
+
40
+ create_table :mass_attribute_protecteds, :force => true do |t|
41
+ t.column :name, :string
42
+ t.column :archive_number, :string
43
+ t.column :archived_at, :datetime
44
+ end
45
+
46
+ create_table :readonly_when_archiveds, :force => true do |t|
47
+ t.column :name, :string
48
+ t.column :archive_number, :string
49
+ t.column :archived_at, :datetime
50
+ end
51
+
52
+ create_table :missing_archived_ats, :force => true do |t|
53
+ t.column :name, :string
54
+ t.column :archive_number, :string
55
+ end
56
+
57
+ create_table :missing_archive_numbers, :force => true do |t|
58
+ t.column :name, :string
59
+ t.column :archived_at, :datetime
60
+ end
61
+
62
+ create_table :polys, :force => true do |t|
63
+ t.references :archiveable, :polymorphic => true
64
+ t.column :archive_number, :string
65
+ t.column :archived_at, :datetime
66
+ end
67
+ end