acts_as_archival 0.4.0

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 (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