paper_trail 7.0.3 → 7.1.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.
- checksums.yaml +4 -4
- data/.github/CONTRIBUTING.md +21 -27
- data/.gitignore +4 -4
- data/.rubocop.yml +2 -2
- data/CHANGELOG.md +17 -0
- data/README.md +31 -2
- data/Rakefile +4 -1
- data/lib/paper_trail.rb +2 -0
- data/lib/paper_trail/serializers/json.rb +9 -0
- data/lib/paper_trail/version_concern.rb +1 -1
- data/lib/paper_trail/version_number.rb +2 -2
- data/paper_trail.gemspec +2 -3
- data/spec/controllers/widgets_controller_spec.rb +85 -0
- data/{test/dummy → spec/dummy_app}/Rakefile +0 -0
- data/{test/dummy → spec/dummy_app}/app/controllers/application_controller.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/controllers/articles_controller.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/controllers/test_controller.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/controllers/widgets_controller.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/animal.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/article.rb +1 -0
- data/{test/dummy → spec/dummy_app}/app/models/authorship.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/bar_habtm.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/book.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/boolit.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/callback_modifier.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/car.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/cat.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/chapter.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/citation.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/custom_primary_key_record.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/customer.rb +0 -0
- data/spec/dummy_app/app/models/document.rb +8 -0
- data/{test/dummy → spec/dummy_app}/app/models/dog.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/editor.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/editorship.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/elephant.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/fluxor.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/foo_habtm.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/foo_widget.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/fruit.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/gadget.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/kitchen/banana.rb +0 -0
- data/spec/dummy_app/app/models/legacy_widget.rb +6 -0
- data/{test/dummy → spec/dummy_app}/app/models/line_item.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/not_on_update.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/on/create.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/on/destroy.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/on/empty_array.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/on/update.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/order.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/paragraph.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/person.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/post.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/post_with_status.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/quotation.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/section.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/skipper.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/song.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/thing.rb +0 -0
- data/spec/dummy_app/app/models/translation.rb +11 -0
- data/{test/dummy → spec/dummy_app}/app/models/truck.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/vehicle.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/whatchamajigger.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/widget.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/models/wotsit.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/versions/custom_primary_key_record_version.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/versions/joined_version.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/versions/json_version.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/versions/kitchen/banana_version.rb +0 -0
- data/{test/dummy → spec/dummy_app}/app/versions/post_version.rb +0 -0
- data/{test/dummy → spec/dummy_app}/config.ru +0 -0
- data/{test/dummy → spec/dummy_app}/config/application.rb +0 -0
- data/{test/dummy → spec/dummy_app}/config/boot.rb +0 -0
- data/{test/dummy → spec/dummy_app}/config/database.mysql.yml +0 -0
- data/{test/dummy → spec/dummy_app}/config/database.postgres.yml +0 -0
- data/{test/dummy → spec/dummy_app}/config/database.sqlite.yml +0 -0
- data/{test/dummy → spec/dummy_app}/config/environment.rb +0 -0
- data/{test/dummy → spec/dummy_app}/config/environments/development.rb +0 -0
- data/{test/dummy → spec/dummy_app}/config/environments/production.rb +0 -0
- data/{test/dummy → spec/dummy_app}/config/environments/test.rb +0 -0
- data/{test/dummy → spec/dummy_app}/config/initializers/backtrace_silencers.rb +0 -0
- data/{test/dummy → spec/dummy_app}/config/initializers/inflections.rb +0 -0
- data/{test/dummy → spec/dummy_app}/config/initializers/mime_types.rb +0 -0
- data/{test/dummy → spec/dummy_app}/config/initializers/paper_trail.rb +0 -0
- data/{test/dummy → spec/dummy_app}/config/initializers/secret_token.rb +0 -0
- data/{test/dummy → spec/dummy_app}/config/initializers/session_store.rb +0 -0
- data/{test/dummy → spec/dummy_app}/config/locales/en.yml +0 -0
- data/{test/dummy → spec/dummy_app}/config/routes.rb +0 -0
- data/{test/dummy → spec/dummy_app}/db/migrate/20110208155312_set_up_test_tables.rb +0 -0
- data/{test/dummy → spec/dummy_app}/db/schema.rb +0 -0
- data/spec/models/article_spec.rb +186 -0
- data/spec/models/document_spec.rb +41 -5
- data/spec/models/legacy_widget_spec.rb +40 -0
- data/spec/models/on/create_spec.rb +27 -0
- data/spec/models/on/destroy_spec.rb +27 -0
- data/spec/models/on/empty_array_spec.rb +30 -0
- data/spec/models/on/update_spec.rb +27 -0
- data/spec/models/translation_spec.rb +70 -0
- data/spec/models/version_spec.rb +7 -3
- data/spec/paper_trail/config_spec.rb +12 -0
- data/spec/paper_trail/model_spec.rb +0 -429
- data/spec/paper_trail/serializers/custom_json_serializer_spec.rb +18 -0
- data/spec/paper_trail/thread_safety_spec.rb +44 -0
- data/spec/paper_trail_spec.rb +9 -0
- data/spec/spec_helper.rb +6 -10
- metadata +178 -179
- data/test/dummy/app/models/document.rb +0 -6
- data/test/dummy/app/models/legacy_widget.rb +0 -3
- data/test/dummy/app/models/translation.rb +0 -6
- data/test/functional/controller_test.rb +0 -90
- data/test/functional/thread_safety_test.rb +0 -46
- data/test/test_helper.rb +0 -68
- data/test/unit/serializers/mixin_json_test.rb +0 -39
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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 "
|
|
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 "
|
|
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
|