paper_trail 7.0.3 → 7.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CONTRIBUTING.md +21 -27
  3. data/.gitignore +4 -4
  4. data/.rubocop.yml +2 -2
  5. data/CHANGELOG.md +17 -0
  6. data/README.md +31 -2
  7. data/Rakefile +4 -1
  8. data/lib/paper_trail.rb +2 -0
  9. data/lib/paper_trail/serializers/json.rb +9 -0
  10. data/lib/paper_trail/version_concern.rb +1 -1
  11. data/lib/paper_trail/version_number.rb +2 -2
  12. data/paper_trail.gemspec +2 -3
  13. data/spec/controllers/widgets_controller_spec.rb +85 -0
  14. data/{test/dummy → spec/dummy_app}/Rakefile +0 -0
  15. data/{test/dummy → spec/dummy_app}/app/controllers/application_controller.rb +0 -0
  16. data/{test/dummy → spec/dummy_app}/app/controllers/articles_controller.rb +0 -0
  17. data/{test/dummy → spec/dummy_app}/app/controllers/test_controller.rb +0 -0
  18. data/{test/dummy → spec/dummy_app}/app/controllers/widgets_controller.rb +0 -0
  19. data/{test/dummy → spec/dummy_app}/app/models/animal.rb +0 -0
  20. data/{test/dummy → spec/dummy_app}/app/models/article.rb +1 -0
  21. data/{test/dummy → spec/dummy_app}/app/models/authorship.rb +0 -0
  22. data/{test/dummy → spec/dummy_app}/app/models/bar_habtm.rb +0 -0
  23. data/{test/dummy → spec/dummy_app}/app/models/book.rb +0 -0
  24. data/{test/dummy → spec/dummy_app}/app/models/boolit.rb +0 -0
  25. data/{test/dummy → spec/dummy_app}/app/models/callback_modifier.rb +0 -0
  26. data/{test/dummy → spec/dummy_app}/app/models/car.rb +0 -0
  27. data/{test/dummy → spec/dummy_app}/app/models/cat.rb +0 -0
  28. data/{test/dummy → spec/dummy_app}/app/models/chapter.rb +0 -0
  29. data/{test/dummy → spec/dummy_app}/app/models/citation.rb +0 -0
  30. data/{test/dummy → spec/dummy_app}/app/models/custom_primary_key_record.rb +0 -0
  31. data/{test/dummy → spec/dummy_app}/app/models/customer.rb +0 -0
  32. data/spec/dummy_app/app/models/document.rb +8 -0
  33. data/{test/dummy → spec/dummy_app}/app/models/dog.rb +0 -0
  34. data/{test/dummy → spec/dummy_app}/app/models/editor.rb +0 -0
  35. data/{test/dummy → spec/dummy_app}/app/models/editorship.rb +0 -0
  36. data/{test/dummy → spec/dummy_app}/app/models/elephant.rb +0 -0
  37. data/{test/dummy → spec/dummy_app}/app/models/fluxor.rb +0 -0
  38. data/{test/dummy → spec/dummy_app}/app/models/foo_habtm.rb +0 -0
  39. data/{test/dummy → spec/dummy_app}/app/models/foo_widget.rb +0 -0
  40. data/{test/dummy → spec/dummy_app}/app/models/fruit.rb +0 -0
  41. data/{test/dummy → spec/dummy_app}/app/models/gadget.rb +0 -0
  42. data/{test/dummy → spec/dummy_app}/app/models/kitchen/banana.rb +0 -0
  43. data/spec/dummy_app/app/models/legacy_widget.rb +6 -0
  44. data/{test/dummy → spec/dummy_app}/app/models/line_item.rb +0 -0
  45. data/{test/dummy → spec/dummy_app}/app/models/not_on_update.rb +0 -0
  46. data/{test/dummy → spec/dummy_app}/app/models/on/create.rb +0 -0
  47. data/{test/dummy → spec/dummy_app}/app/models/on/destroy.rb +0 -0
  48. data/{test/dummy → spec/dummy_app}/app/models/on/empty_array.rb +0 -0
  49. data/{test/dummy → spec/dummy_app}/app/models/on/update.rb +0 -0
  50. data/{test/dummy → spec/dummy_app}/app/models/order.rb +0 -0
  51. data/{test/dummy → spec/dummy_app}/app/models/paragraph.rb +0 -0
  52. data/{test/dummy → spec/dummy_app}/app/models/person.rb +0 -0
  53. data/{test/dummy → spec/dummy_app}/app/models/post.rb +0 -0
  54. data/{test/dummy → spec/dummy_app}/app/models/post_with_status.rb +0 -0
  55. data/{test/dummy → spec/dummy_app}/app/models/quotation.rb +0 -0
  56. data/{test/dummy → spec/dummy_app}/app/models/section.rb +0 -0
  57. data/{test/dummy → spec/dummy_app}/app/models/skipper.rb +0 -0
  58. data/{test/dummy → spec/dummy_app}/app/models/song.rb +0 -0
  59. data/{test/dummy → spec/dummy_app}/app/models/thing.rb +0 -0
  60. data/spec/dummy_app/app/models/translation.rb +11 -0
  61. data/{test/dummy → spec/dummy_app}/app/models/truck.rb +0 -0
  62. data/{test/dummy → spec/dummy_app}/app/models/vehicle.rb +0 -0
  63. data/{test/dummy → spec/dummy_app}/app/models/whatchamajigger.rb +0 -0
  64. data/{test/dummy → spec/dummy_app}/app/models/widget.rb +0 -0
  65. data/{test/dummy → spec/dummy_app}/app/models/wotsit.rb +0 -0
  66. data/{test/dummy → spec/dummy_app}/app/versions/custom_primary_key_record_version.rb +0 -0
  67. data/{test/dummy → spec/dummy_app}/app/versions/joined_version.rb +0 -0
  68. data/{test/dummy → spec/dummy_app}/app/versions/json_version.rb +0 -0
  69. data/{test/dummy → spec/dummy_app}/app/versions/kitchen/banana_version.rb +0 -0
  70. data/{test/dummy → spec/dummy_app}/app/versions/post_version.rb +0 -0
  71. data/{test/dummy → spec/dummy_app}/config.ru +0 -0
  72. data/{test/dummy → spec/dummy_app}/config/application.rb +0 -0
  73. data/{test/dummy → spec/dummy_app}/config/boot.rb +0 -0
  74. data/{test/dummy → spec/dummy_app}/config/database.mysql.yml +0 -0
  75. data/{test/dummy → spec/dummy_app}/config/database.postgres.yml +0 -0
  76. data/{test/dummy → spec/dummy_app}/config/database.sqlite.yml +0 -0
  77. data/{test/dummy → spec/dummy_app}/config/environment.rb +0 -0
  78. data/{test/dummy → spec/dummy_app}/config/environments/development.rb +0 -0
  79. data/{test/dummy → spec/dummy_app}/config/environments/production.rb +0 -0
  80. data/{test/dummy → spec/dummy_app}/config/environments/test.rb +0 -0
  81. data/{test/dummy → spec/dummy_app}/config/initializers/backtrace_silencers.rb +0 -0
  82. data/{test/dummy → spec/dummy_app}/config/initializers/inflections.rb +0 -0
  83. data/{test/dummy → spec/dummy_app}/config/initializers/mime_types.rb +0 -0
  84. data/{test/dummy → spec/dummy_app}/config/initializers/paper_trail.rb +0 -0
  85. data/{test/dummy → spec/dummy_app}/config/initializers/secret_token.rb +0 -0
  86. data/{test/dummy → spec/dummy_app}/config/initializers/session_store.rb +0 -0
  87. data/{test/dummy → spec/dummy_app}/config/locales/en.yml +0 -0
  88. data/{test/dummy → spec/dummy_app}/config/routes.rb +0 -0
  89. data/{test/dummy → spec/dummy_app}/db/migrate/20110208155312_set_up_test_tables.rb +0 -0
  90. data/{test/dummy → spec/dummy_app}/db/schema.rb +0 -0
  91. data/spec/models/article_spec.rb +186 -0
  92. data/spec/models/document_spec.rb +41 -5
  93. data/spec/models/legacy_widget_spec.rb +40 -0
  94. data/spec/models/on/create_spec.rb +27 -0
  95. data/spec/models/on/destroy_spec.rb +27 -0
  96. data/spec/models/on/empty_array_spec.rb +30 -0
  97. data/spec/models/on/update_spec.rb +27 -0
  98. data/spec/models/translation_spec.rb +70 -0
  99. data/spec/models/version_spec.rb +7 -3
  100. data/spec/paper_trail/config_spec.rb +12 -0
  101. data/spec/paper_trail/model_spec.rb +0 -429
  102. data/spec/paper_trail/serializers/custom_json_serializer_spec.rb +18 -0
  103. data/spec/paper_trail/thread_safety_spec.rb +44 -0
  104. data/spec/paper_trail_spec.rb +9 -0
  105. data/spec/spec_helper.rb +6 -10
  106. metadata +178 -179
  107. data/test/dummy/app/models/document.rb +0 -6
  108. data/test/dummy/app/models/legacy_widget.rb +0 -3
  109. data/test/dummy/app/models/translation.rb +0 -6
  110. data/test/functional/controller_test.rb +0 -90
  111. data/test/functional/thread_safety_test.rb +0 -46
  112. data/test/test_helper.rb +0 -68
  113. data/test/unit/serializers/mixin_json_test.rb +0 -39
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,8 @@
1
+ # Demonstrates a "custom versions association name". Instead of the assication
2
+ # being named `versions`, it will be named `paper_trail_versions`.
3
+ class Document < ActiveRecord::Base
4
+ has_paper_trail(
5
+ versions: :paper_trail_versions,
6
+ on: %i[create update]
7
+ )
8
+ end
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,6 @@
1
+ # The `legacy_widgets` table has a `version` column that would conflict with our
2
+ # `version` method. It is configured to define a method named `custom_version`
3
+ # instead.
4
+ class LegacyWidget < ActiveRecord::Base
5
+ has_paper_trail ignore: :version, version: "custom_version"
6
+ end
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,11 @@
1
+ # Demonstrates the `if` and `unless` configuration options.
2
+ class Translation < ActiveRecord::Base
3
+ # Has a `type` column, but it's not used for STI.
4
+ # TODO: rename column
5
+ self.inheritance_column = nil
6
+
7
+ has_paper_trail(
8
+ if: proc { |t| t.language_code == "US" },
9
+ unless: proc { |t| t.type == "DRAFT" }
10
+ )
11
+ end
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,186 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe Article, type: :model, versioning: true do
4
+ describe ".create" do
5
+ it "also creates a version record" do
6
+ expect { described_class.create }.to(
7
+ change { PaperTrail::Version.count }.by(+1)
8
+ )
9
+ end
10
+ end
11
+
12
+ context "which updates an ignored column" do
13
+ it "not change the number of versions" do
14
+ article = described_class.create
15
+ article.update_attributes(title: "My first title")
16
+ expect(PaperTrail::Version.count).to(eq(1))
17
+ end
18
+ end
19
+
20
+ context "which updates an ignored column with truly Proc" do
21
+ it "not change the number of versions" do
22
+ article = described_class.create
23
+ article.update_attributes(abstract: "ignore abstract")
24
+ expect(PaperTrail::Version.count).to(eq(1))
25
+ end
26
+ end
27
+
28
+ context "which updates an ignored column with falsy Proc" do
29
+ it "change the number of versions" do
30
+ article = described_class.create
31
+ article.update_attributes(abstract: "do not ignore abstract!")
32
+ expect(PaperTrail::Version.count).to(eq(2))
33
+ end
34
+ end
35
+
36
+ context "which updates an ignored column, ignored with truly Proc and a selected column" do
37
+ it "change the number of versions" do
38
+ article = described_class.create
39
+ article.update_attributes(
40
+ title: "My first title",
41
+ content: "Some text here.",
42
+ abstract: "ignore abstract"
43
+ )
44
+ expect(PaperTrail::Version.count).to(eq(2))
45
+ expect(article.versions.size).to(eq(2))
46
+ end
47
+
48
+ it "have stored only non-ignored attributes" do
49
+ article = described_class.create
50
+ article.update_attributes(
51
+ title: "My first title",
52
+ content: "Some text here.",
53
+ abstract: "ignore abstract"
54
+ )
55
+ expected = { "content" => [nil, "Some text here."] }
56
+ expect(article.versions.last.changeset).to(eq(expected))
57
+ end
58
+ end
59
+
60
+ context "which updates an ignored column, ignored with falsy Proc and a selected column" do
61
+ it "change the number of versions" do
62
+ article = described_class.create
63
+ article.update_attributes(
64
+ title: "My first title",
65
+ content: "Some text here.",
66
+ abstract: "do not ignore abstract"
67
+ )
68
+ expect(PaperTrail::Version.count).to(eq(2))
69
+ expect(article.versions.size).to(eq(2))
70
+ end
71
+
72
+ it "stores only non-ignored attributes" do
73
+ article = described_class.create
74
+ article.update_attributes(
75
+ title: "My first title",
76
+ content: "Some text here.",
77
+ abstract: "do not ignore abstract"
78
+ )
79
+ expected = {
80
+ "content" => [nil, "Some text here."],
81
+ "abstract" => [nil, "do not ignore abstract"]
82
+ }
83
+ expect(article.versions.last.changeset).to(eq(expected))
84
+ end
85
+ end
86
+
87
+ context "which updates a selected column" do
88
+ it "change the number of versions" do
89
+ article = described_class.create
90
+ article.update_attributes(content: "Some text here.")
91
+ expect(PaperTrail::Version.count).to(eq(2))
92
+ expect(article.versions.size).to(eq(2))
93
+ end
94
+ end
95
+
96
+ context "which updates a non-ignored and non-selected column" do
97
+ it "not change the number of versions" do
98
+ article = described_class.create
99
+ article.update_attributes(abstract: "Other abstract")
100
+ expect(PaperTrail::Version.count).to(eq(1))
101
+ end
102
+ end
103
+
104
+ context "which updates a skipped column" do
105
+ it "not change the number of versions" do
106
+ article = described_class.create
107
+ article.update_attributes(file_upload: "Your data goes here")
108
+ expect(PaperTrail::Version.count).to(eq(1))
109
+ end
110
+ end
111
+
112
+ context "which updates a skipped column and a selected column" do
113
+ it "change the number of versions" do
114
+ article = described_class.create
115
+ article.update_attributes(
116
+ file_upload: "Your data goes here",
117
+ content: "Some text here."
118
+ )
119
+ expect(PaperTrail::Version.count).to(eq(2))
120
+ end
121
+
122
+ it "show the new version in the model's `versions` association" do
123
+ article = described_class.create
124
+ article.update_attributes(
125
+ file_upload: "Your data goes here",
126
+ content: "Some text here."
127
+ )
128
+ expect(article.versions.size).to(eq(2))
129
+ end
130
+
131
+ it "have stored only non-skipped attributes" do
132
+ article = described_class.create
133
+ article.update_attributes(
134
+ file_upload: "Your data goes here",
135
+ content: "Some text here."
136
+ )
137
+ expect(
138
+ article.versions.last.changeset
139
+ ).to(eq("content" => [nil, "Some text here."]))
140
+ end
141
+
142
+ context "and when updated again" do
143
+ it "have removed the skipped attributes when saving the previous version" do
144
+ article = described_class.create
145
+ article.update_attributes(
146
+ file_upload: "Your data goes here",
147
+ content: "Some text here."
148
+ )
149
+ article.update_attributes(
150
+ file_upload: "More data goes here",
151
+ content: "More text here."
152
+ )
153
+ old_article = article.versions.last
154
+ expect(
155
+ PaperTrail.serializer.load(old_article.object)["file_upload"]
156
+ ).to(be_nil)
157
+ end
158
+
159
+ it "have kept the non-skipped attributes in the previous version" do
160
+ article = described_class.create
161
+ article.update_attributes(
162
+ file_upload: "Your data goes here",
163
+ content: "Some text here."
164
+ )
165
+ article.update_attributes(
166
+ file_upload: "More data goes here",
167
+ content: "More text here."
168
+ )
169
+ old_article = article.versions.last
170
+ expect(
171
+ PaperTrail.serializer.load(old_article.object)["content"]
172
+ ).to(eq("Some text here."))
173
+ end
174
+ end
175
+ end
176
+
177
+ context "#destroy" do
178
+ it "creates a version record" do
179
+ article = described_class.create
180
+ article.destroy
181
+ expect(PaperTrail::Version.count).to(eq(2))
182
+ expect(article.versions.size).to(eq(2))
183
+ expect(article.versions.map(&:event)).to(match_array(%w[create destroy]))
184
+ end
185
+ end
186
+ end
@@ -1,21 +1,57 @@
1
1
  require "spec_helper"
2
2
 
3
- RSpec.describe Document, type: :model do
4
- describe "`have_a_version_with` matcher", versioning: true do
3
+ RSpec.describe Document, type: :model, versioning: true do
4
+ describe "have_a_version_with matcher" do
5
5
  it "works with custom versions association" do
6
6
  document = Document.create!(name: "Foo")
7
7
  document.update_attributes!(name: "Bar")
8
-
9
8
  expect(document).to have_a_version_with(name: "Foo")
10
9
  end
11
10
  end
12
11
 
13
- describe "`have_a_version_with_changes` matcher", versioning: true do
12
+ describe "have_a_version_with_changes matcher" do
14
13
  it "works with custom versions association" do
15
14
  document = Document.create!(name: "Foo")
16
15
  document.update_attributes!(name: "Bar")
17
-
18
16
  expect(document).to have_a_version_with_changes(name: "Bar")
19
17
  end
20
18
  end
19
+
20
+ describe "#paper_trail.next_version" do
21
+ it "returns the expected document" do
22
+ doc = Document.create
23
+ doc.update_attributes(name: "Doc 1")
24
+ reified = doc.paper_trail_versions.last.reify
25
+ expect(doc.name).to(eq(reified.paper_trail.next_version.name))
26
+ end
27
+ end
28
+
29
+ describe "#paper_trail.previous_version" do
30
+ it "returns the expected document" do
31
+ doc = Document.create
32
+ doc.update_attributes(name: "Doc 1")
33
+ doc.update_attributes(name: "Doc 2")
34
+ expect(doc.paper_trail_versions.length).to(eq(3))
35
+ expect(doc.paper_trail.previous_version.name).to(eq("Doc 1"))
36
+ end
37
+ end
38
+
39
+ describe "#paper_trail_versions" do
40
+ it "returns the expected version records" do
41
+ doc = Document.create
42
+ doc.update_attributes(name: "Doc 1")
43
+ expect(doc.paper_trail_versions.length).to(eq(2))
44
+ expect(doc.paper_trail_versions.map(&:event)).to(
45
+ match_array(%w[create update])
46
+ )
47
+ end
48
+ end
49
+
50
+ describe "#versions" do
51
+ it "does not respond to versions method" do
52
+ doc = Document.create
53
+ doc.update_attributes(name: "Doc 1")
54
+ expect(doc).not_to respond_to(:versions)
55
+ end
56
+ end
21
57
  end