mongoid-history 0.8.1 → 0.8.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 3e9cb97f94a3cb084d92c85412f2e4cf2cc67895
4
- data.tar.gz: c61a511effb8ee2ebb559aad5a77c3ec800eff78
2
+ SHA256:
3
+ metadata.gz: 84ee622b782d764b3a15ea31bfac94cbedf3fa023d8ae0302022562d6a5a6ec2
4
+ data.tar.gz: abf09c6ed9db7126b9d7754f42a0f1b00317919ad6744f0486b4d970601eb3f4
5
5
  SHA512:
6
- metadata.gz: 0a6079af9f6834d5c65d38106fca027a243871087fd0669e1120b4b2c074dde16ddd5d992e01208c73cd4cd7959c0ef6d03e49af4de4b4fc8783a7445d9fac41
7
- data.tar.gz: 3dd2f512a2591d3e2123ae2fcbacd615d70be5983b9d955e393bf0f54463a18cb08fec3afb8259cabe87163e4d1baa384f7225e91d181492ce01954f92c022ad
6
+ metadata.gz: 484eb94fae5bba8b787ffda61403e65c95684f9e3a77c03daa56952e056c440d639d58d3a381760e7996ec1bec1415fe409f6688fab38ed24d6e0315f53c9369
7
+ data.tar.gz: f66b6abc4dcf17696bafea67faddbcd0b97f194e8b8b36c48f32461a31987b9867a6dbf204a8604a391654ebace4c94c76b4b745ac2511b74db8df26f886d54a
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2018-06-20 23:31:54 -0400 using RuboCop version 0.48.1.
3
+ # on 2019-06-09 13:41:12 +0200 using RuboCop version 0.60.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
@@ -8,16 +8,16 @@
8
8
 
9
9
  # Offense count: 7
10
10
  # Configuration parameters: Include.
11
- # Include: **/Gemfile, **/gems.rb
11
+ # Include: **/*.gemfile, **/Gemfile, **/gems.rb
12
12
  Bundler/DuplicatedGem:
13
13
  Exclude:
14
14
  - 'Gemfile'
15
15
 
16
16
  # Offense count: 1
17
17
  # Cop supports --auto-correct.
18
- # Configuration parameters: EnforcedStyleAlignWith, SupportedStylesAlignWith, AutoCorrect.
18
+ # Configuration parameters: EnforcedStyleAlignWith, AutoCorrect, Severity.
19
19
  # SupportedStylesAlignWith: keyword, variable, start_of_line
20
- Lint/EndAlignment:
20
+ Layout/EndAlignment:
21
21
  Exclude:
22
22
  - 'lib/mongoid/history/options.rb'
23
23
 
@@ -32,44 +32,47 @@ Lint/ParenthesesAsGroupedExpression:
32
32
  - 'spec/integration/integration_spec.rb'
33
33
  - 'spec/integration/nested_embedded_polymorphic_documents_spec.rb'
34
34
 
35
- # Offense count: 21
35
+ # Offense count: 22
36
36
  Metrics/AbcSize:
37
37
  Max: 52
38
38
 
39
- # Offense count: 117
39
+ # Offense count: 122
40
40
  # Configuration parameters: CountComments, ExcludedMethods.
41
+ # ExcludedMethods: refine
41
42
  Metrics/BlockLength:
42
- Max: 820
43
+ Max: 837
43
44
 
44
45
  # Offense count: 1
45
46
  # Configuration parameters: CountComments.
46
47
  Metrics/ClassLength:
47
- Max: 114
48
+ Max: 125
48
49
 
49
50
  # Offense count: 6
50
51
  Metrics/CyclomaticComplexity:
51
52
  Max: 13
52
53
 
53
- # Offense count: 392
54
- # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
55
- # URISchemes: http, https
56
- Metrics/LineLength:
57
- Max: 688
58
-
59
- # Offense count: 15
60
- # Configuration parameters: CountComments.
54
+ # Offense count: 17
55
+ # Configuration parameters: CountComments, ExcludedMethods.
61
56
  Metrics/MethodLength:
62
57
  Max: 23
63
58
 
64
59
  # Offense count: 2
65
60
  # Configuration parameters: CountComments.
66
61
  Metrics/ModuleLength:
67
- Max: 182
62
+ Max: 191
68
63
 
69
64
  # Offense count: 6
70
65
  Metrics/PerceivedComplexity:
71
66
  Max: 15
72
67
 
68
+ # Offense count: 1
69
+ # Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms.
70
+ # AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS
71
+ Naming/FileName:
72
+ Exclude:
73
+ - 'Dangerfile'
74
+ - 'lib/mongoid-history.rb'
75
+
73
76
  # Offense count: 12
74
77
  Style/Documentation:
75
78
  Exclude:
@@ -91,15 +94,13 @@ Style/EachWithObject:
91
94
  - 'lib/mongoid/history/trackable.rb'
92
95
  - 'lib/mongoid/history/tracker.rb'
93
96
 
94
- # Offense count: 2
95
- # Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms.
96
- # AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS
97
- Style/FileName:
98
- Exclude:
99
- - 'Dangerfile'
100
- - 'lib/mongoid-history.rb'
101
-
102
97
  # Offense count: 1
103
98
  Style/MultilineBlockChain:
104
99
  Exclude:
105
100
  - 'lib/mongoid/history/tracker.rb'
101
+
102
+ # Offense count: 404
103
+ # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
104
+ # URISchemes: http, https
105
+ Metrics/LineLength:
106
+ Max: 688
@@ -16,7 +16,7 @@ env:
16
16
  - MONGOID_VERSION=HEAD
17
17
 
18
18
  rvm:
19
- - 2.3.1
19
+ - 2.3
20
20
 
21
21
  before_install:
22
22
  - gem update bundler
@@ -1,3 +1,10 @@
1
+ ### 0.8.2 (2019/12/02)
2
+
3
+ * [#233](https://github.com/mongoid/mongoid-history/pull/233): Bug fix-Track ALL embedded relations when used with fields and filtered attributes on embedded objects - [@jagdeepsingh](https://github.com/jagdeepsingh).
4
+ * [#232](https://github.com/mongoid/mongoid-history/pull/232): Bug/187 track changes from embedded documents (not deeply nested) - [@Startouf](https://github.com/Startouf).
5
+ * [#227](https://github.com/mongoid/mongoid-history/pull/227): Store options in inheritable class attributes - [@jnfeinstein](https://github.com/jnfeinstein).
6
+ * [#229](https://github.com/mongoid/mongoid-history/pull/229), [#225](https://github.com/mongoid/mongoid-history/pull/225): Fixed inheritance of `history_trackable_options` - [@jnfeinstein](https://github.com/jnfeinstein).
7
+
1
8
  ### 0.8.1 (2018/06/28)
2
9
 
3
10
  * [#221](https://github.com/mongoid/mongoid-history/pull/221): Mongoid 7 support - [@dblock](https://github.com/dblock).
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011-2016 Aaron Qian & Contributors
1
+ Copyright (c) 2011-2018 Aaron Qian & Contributors
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -580,6 +580,6 @@ You're encouraged to contribute to this library. See [CONTRIBUTING](CONTRIBUTING
580
580
  Copyright
581
581
  ---------
582
582
 
583
- Copyright (c) 2011-2016 Aaron Qian and Contributors.
583
+ Copyright (c) 2011-2018 Aaron Qian and Contributors.
584
584
 
585
585
  MIT License. See [LICENSE.txt](LICENSE.txt) for further details.
@@ -15,7 +15,6 @@ module Mongoid
15
15
 
16
16
  class << self
17
17
  attr_accessor :tracker_class_name
18
- attr_accessor :trackable_class_options
19
18
  attr_accessor :trackable_settings
20
19
  attr_accessor :modifier_class_name
21
20
  attr_accessor :current_user_method
@@ -45,9 +44,19 @@ module Mongoid
45
44
 
46
45
  def reset!
47
46
  Mongoid::History.modifier_class_name = 'User'
48
- Mongoid::History.trackable_class_options = {}
49
47
  Mongoid::History.trackable_settings = {}
50
48
  Mongoid::History.current_user_method ||= :current_user
49
+
50
+ Mongoid.models.each do |model|
51
+ next unless model.included_modules.include? Mongoid::History::Trackable
52
+
53
+ model.singleton_class.class_eval do
54
+ # Inverse of class_attribute
55
+ %i[mongoid_history_options
56
+ mongoid_history_options=
57
+ mongoid_history_options?].each { |m| remove_possible_method(m) }
58
+ end
59
+ end
51
60
  end
52
61
  end
53
62
  end
@@ -2,33 +2,91 @@ module Mongoid
2
2
  module History
3
3
  module Attributes
4
4
  class Update < ::Mongoid::History::Attributes::Base
5
+ # @example when both an attribute `foo` and a child's attribute `nested_bar.baz` are changed
6
+ #
7
+ # {
8
+ # 'foo' => ['foo_before_changes', 'foo_after_changes']
9
+ # 'nested_bar.baz' => ['nested_bar_baz_before_changes', 'nested_bar_baz_after_changes']
10
+ # }
11
+ # }
12
+ #
13
+ # @return [Hash<String, Array<(?,?)>>] Hash of changes
5
14
  def attributes
6
- @attributes = {}
15
+ changes_from_parent.deep_merge(changes_from_children)
16
+ end
17
+
18
+ private
19
+
20
+ def changes_from_parent
21
+ parent_changes = {}
7
22
  changes.each do |k, v|
8
- if trackable_class.tracked_embeds_one?(k)
9
- insert_embeds_one_changes(k, v)
10
- elsif trackable_class.tracked_embeds_many?(k)
11
- insert_embeds_many_changes(k, v)
12
- elsif trackable_class.tracked?(k, :update)
13
- @attributes[k] = format_field(k, v) unless v.all?(&:blank?)
23
+ change_value = begin
24
+ if trackable_class.tracked_embeds_one?(k)
25
+ embeds_one_changes_from_parent(k, v)
26
+ elsif trackable_class.tracked_embeds_many?(k)
27
+ embeds_many_changes_from_parent(k, v)
28
+ elsif trackable_class.tracked?(k, :update)
29
+ { k => format_field(k, v) } unless v.all?(&:blank?)
30
+ end
14
31
  end
32
+ parent_changes.merge!(change_value) if change_value.present?
15
33
  end
16
- @attributes
34
+ parent_changes
17
35
  end
18
36
 
19
- private
37
+ def changes_from_children
38
+ embeds_one_changes_from_embedded_documents
39
+ end
40
+
41
+ # Retrieve the list of changes applied directly to the nested documents
42
+ #
43
+ # @example when a child's name is changed from "todd" to "mario"
44
+ #
45
+ # child = Child.new(name: 'todd')
46
+ # Parent.create(child: child)
47
+ # child.name = "Mario"
48
+ #
49
+ # embeds_one_changes_from_embedded_documents # when called from "Parent"
50
+ # # => { "child.name"=>["todd", "mario"] }
51
+ #
52
+ # @return [Hash<String, Array<(?,?)>] changes of embeds_ones from embedded documents
53
+ def embeds_one_changes_from_embedded_documents
54
+ embedded_doc_changes = {}
55
+ trackable_class.tracked_embeds_one.each do |rel|
56
+ rel_class = trackable_class.relation_class_of(rel)
57
+ paranoia_field = Mongoid::History.trackable_class_settings(rel_class)[:paranoia_field]
58
+ paranoia_field = rel_class.aliased_fields.key(paranoia_field) || paranoia_field
59
+ rel = aliased_fields.key(rel) || rel
60
+ obj = trackable.send(rel)
61
+ next if !obj || (obj.respond_to?(paranoia_field) && obj.public_send(paranoia_field).present?)
20
62
 
21
- def insert_embeds_one_changes(relation, value)
63
+ obj.changes.each do |k, v|
64
+ embedded_doc_changes["#{rel}.#{k}"] = [v.first, v.last]
65
+ end
66
+ end
67
+ embedded_doc_changes
68
+ end
69
+
70
+ # @param [String] relation
71
+ # @param [String] value
72
+ #
73
+ # @return [Hash<String, Array<(?,?)>>]
74
+ def embeds_one_changes_from_parent(relation, value)
22
75
  relation = trackable_class.database_field_name(relation)
23
76
  relation_class = trackable_class.relation_class_of(relation)
24
77
  paranoia_field = Mongoid::History.trackable_class_settings(relation_class)[:paranoia_field]
25
78
  original_value = value[0][paranoia_field].present? ? {} : format_embeds_one_relation(relation, value[0])
26
79
  modified_value = value[1][paranoia_field].present? ? {} : format_embeds_one_relation(relation, value[1])
27
80
  return if original_value == modified_value
28
- @attributes[relation] = [original_value, modified_value]
81
+
82
+ { relation => [original_value, modified_value] }
29
83
  end
30
84
 
31
- def insert_embeds_many_changes(relation, value)
85
+ # @param [String] relation
86
+ # @param [String] value
87
+ #
88
+ # @return [Hash<Array<(?,?)>>]
89
+ def embeds_many_changes_from_parent(relation, value)
32
90
  relation = trackable_class.database_field_name(relation)
33
91
  relation_class = trackable_class.relation_class_of(relation)
34
92
  paranoia_field = Mongoid::History.trackable_class_settings(relation_class)[:paranoia_field]
@@ -37,7 +95,8 @@ module Mongoid
37
95
  modified_value = value[1].reject { |rel| rel[paranoia_field].present? }
38
96
  .map { |v_attrs| format_embeds_many_relation(relation, v_attrs) }
39
97
  return if original_value == modified_value
40
- @attributes[relation] = [original_value, modified_value]
98
+
99
+ { relation => [original_value, modified_value] }
41
100
  end
42
101
  end
43
102
  end
@@ -95,12 +95,20 @@ module Mongoid
95
95
  @options[:relations] = { embeds_one: {}, embeds_many: {} }
96
96
 
97
97
  options[:on].each do |option|
98
- field = get_database_field_name(option)
99
- field_options = get_field_options(option)
100
- categorize_tracked_option(field, field_options)
98
+ if option.is_a?(Hash)
99
+ option.each { |k, v| split_and_categorize(k => v) }
100
+ else
101
+ split_and_categorize(option)
102
+ end
101
103
  end
102
104
  end
103
105
 
106
+ def split_and_categorize(field_and_options)
107
+ field = get_database_field_name(field_and_options)
108
+ field_options = get_field_options(field_and_options)
109
+ categorize_tracked_option(field, field_options)
110
+ end
111
+
104
112
  # Returns the database_field_name key for tracked option
105
113
  #
106
114
  # @param [ String | Symbol | Array | Hash ] option The field or relation name to track
@@ -29,8 +29,11 @@ module Mongoid
29
29
  around_create :track_create, callback_options if history_options.options[:track_create]
30
30
  around_destroy :track_destroy, callback_options if history_options.options[:track_destroy]
31
31
 
32
- Mongoid::History.trackable_class_options ||= {}
33
- Mongoid::History.trackable_class_options[history_options.scope] = history_options
32
+ unless respond_to? :mongoid_history_options
33
+ class_attribute :mongoid_history_options, instance_accessor: false
34
+ end
35
+
36
+ self.mongoid_history_options = history_options
34
37
  end
35
38
 
36
39
  def history_settings(options = {})
@@ -260,18 +263,43 @@ module Mongoid
260
263
  @history_tracks = nil
261
264
  end
262
265
 
266
+ # Transform hash of pair of changes into an `original` and `modified` hash
267
+ # Nested document keys (key name with dots) are expanded
268
+ #
269
+ # @param [Hash<Array>] changes
270
+ #
271
+ # @return [Array<Hash<?>,Hash<?>>] <description>
263
272
  def transform_changes(changes)
264
273
  original = {}
265
274
  modified = {}
266
- changes.each_pair do |k, v|
267
- o, m = v
268
- original[k] = o unless o.nil?
269
- modified[k] = m unless m.nil?
275
+ changes.each_pair do |k, modification_pair|
276
+ o, m = modification_pair
277
+ original.deep_merge!(expand_nested_document_key_value(k, o)) unless o.nil?
278
+ modified.deep_merge!(expand_nested_document_key_value(k, m)) unless m.nil?
270
279
  end
271
280
 
272
281
  [original, modified]
273
282
  end
274
283
 
284
+ # Handle nested document tracking of changes
285
+ #
286
+ # @example
287
+ #
288
+ # expand_nested_document_key('embedded.document.changed_field', 'old'])
289
+ # #=> { 'embedded' => {'document' => { 'changed_field' => 'old' }}}
290
+ #
291
+ # @param [String] document_key key with dots
292
+ # @param [?] value
293
+ #
294
+ # @return [Hash<String, ?>]
295
+ def expand_nested_document_key_value(document_key, value)
296
+ expanded_key = value
297
+ document_key.to_s.split('.').reverse.each do |key|
298
+ expanded_key = { key => expanded_key }
299
+ end
300
+ expanded_key
301
+ end
302
+
275
303
  def increment_current_version
276
304
  current_version = (send(history_trackable_options[:version_field]) || 0) + 1
277
305
  send("#{history_trackable_options[:version_field]}=", current_version)
@@ -287,7 +315,10 @@ module Mongoid
287
315
  def track_history_for_action(action)
288
316
  if track_history_for_action?(action)
289
317
  current_version = increment_current_version
290
- last_track = self.class.tracker_class.create!(history_tracker_attributes(action.to_sym).merge(version: current_version, action: action.to_s, trackable: self))
318
+ last_track = self.class.tracker_class.create!(
319
+ history_tracker_attributes(action.to_sym)
320
+ .merge(version: current_version, action: action.to_s, trackable: self)
321
+ )
291
322
  end
292
323
 
293
324
  clear_trackable_memoization
@@ -518,7 +549,7 @@ module Mongoid
518
549
  end
519
550
 
520
551
  def history_trackable_options
521
- @history_trackable_options ||= Mongoid::History.trackable_class_options[trackable_scope].prepared
552
+ @history_trackable_options ||= mongoid_history_options.prepared
522
553
  end
523
554
 
524
555
  def clear_trackable_memoization
@@ -1,5 +1,5 @@
1
1
  module Mongoid
2
2
  module History
3
- VERSION = '0.8.1'.freeze
3
+ VERSION = '0.8.2'.freeze
4
4
  end
5
5
  end
@@ -950,5 +950,27 @@ describe Mongoid::History do
950
950
  expect(sausage.reload.flavour).to eq('Guinness')
951
951
  end
952
952
  end
953
+
954
+ describe 'changing collection' do
955
+ before :each do
956
+ class Fish
957
+ include Mongoid::Document
958
+ include Mongoid::History::Trackable
959
+
960
+ track_history on: [:species], modifier_field_optional: true
961
+ store_in collection: :animals
962
+
963
+ field :species
964
+ end
965
+ end
966
+
967
+ after :each do
968
+ Object.send(:remove_const, :Fish)
969
+ end
970
+
971
+ it 'should track history' do
972
+ Fish.new.save!
973
+ end
974
+ end
953
975
  end
954
976
  end
@@ -0,0 +1,124 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mongoid::History::Tracker do
4
+ describe 'Tracking of changes from embedded documents' do
5
+ before :each do
6
+ # Child model (will be embedded in Parent)
7
+ class Child
8
+ include Mongoid::Document
9
+ include Mongoid::History::Trackable
10
+
11
+ field :name
12
+ embedded_in :parent, inverse_of: :child
13
+ embeds_one :child, inverse_of: :parent, class_name: 'NestedChild'
14
+ end
15
+
16
+ # NestedChild model (will be embedded in Child)
17
+ class NestedChild
18
+ include Mongoid::Document
19
+ include Mongoid::History::Trackable
20
+
21
+ field :name
22
+ embedded_in :parent, inverse_of: :child, class_name: 'Child'
23
+ end
24
+
25
+ # Parent model (embeds one Child)
26
+ class Parent
27
+ include Mongoid::Document
28
+ include Mongoid::History::Trackable
29
+
30
+ field :name, type: String
31
+ embeds_one :child
32
+
33
+ store_in collection: :parent
34
+
35
+ track_history(
36
+ on: %i[fields embedded_relations],
37
+ version_field: :version,
38
+ track_create: true,
39
+ track_update: true,
40
+ track_destroy: false,
41
+ modifier_field: nil
42
+ )
43
+ end
44
+ end
45
+
46
+ after :each do
47
+ Object.send(:remove_const, :Parent)
48
+ Object.send(:remove_const, :Child)
49
+ Object.send(:remove_const, :NestedChild)
50
+ end
51
+
52
+ context 'with a parent-child hierarchy' do
53
+ let(:parent) do
54
+ Parent.create!(name: 'bowser', child: Child.new(name: 'todd'))
55
+ end
56
+
57
+ it 'tracks history for the nested embedded documents in the parent' do
58
+ expect(parent.history_tracks.length).to eq(1)
59
+
60
+ aggregate_failures do
61
+ track = parent.history_tracks.last
62
+ expect(track.modified['name']).to eq('bowser')
63
+ expect(track.modified.dig('child', 'name')).to eq('todd')
64
+ end
65
+
66
+ parent.update_attributes(name: 'brow')
67
+ expect(parent.history_tracks.length).to eq(2)
68
+
69
+ parent.child.name = 'mario'
70
+ parent.save!
71
+ expect(parent.history_tracks.length).to eq(3)
72
+
73
+ aggregate_failures do
74
+ track = parent.history_tracks.last
75
+ expect(track.original.dig('child', 'name')).to eq('todd')
76
+ expect(track.modified.dig('child', 'name')).to eq('mario')
77
+ end
78
+ end
79
+ end
80
+
81
+ context 'with a deeply nested hierarchy' do
82
+ let(:parent) do
83
+ Parent.create!(
84
+ name: 'bowser',
85
+ child: Child.new(
86
+ name: 'todd',
87
+ child: NestedChild.new(name: 'peach')
88
+ )
89
+ )
90
+ end
91
+
92
+ it 'tracks history for deeply nested embedded documents in parent' do
93
+ pending('Figure out a way to track deeply nested relation changes')
94
+
95
+ expect(parent.history_tracks.length).to eq(1)
96
+
97
+ aggregate_failures do
98
+ track = parent.history_tracks.last
99
+ expect(track.modified['name']).to eq('bowser')
100
+ expect(track.modified.dig('child', 'name')).to eq('todd')
101
+ expect(track.modified.dig('child', 'child', 'name')).to eq('peach')
102
+ end
103
+
104
+ parent.name = 'brow'
105
+ parent.child.name = 'mario'
106
+ parent.child.child.name = 'luigi'
107
+ parent.save!
108
+ expect(parent.history_tracks.length).to eq(2)
109
+
110
+ aggregate_failures do
111
+ track = parent.history_tracks.last
112
+ expect(track.original['name']).to eq('bowser')
113
+ expect(track.modified['name']).to eq('brow')
114
+
115
+ expect(track.original['child']['name']).to eq('todd')
116
+ expect(track.modified['child']['name']).to eq('mario')
117
+
118
+ expect(track.original['child']['child']['name']).to eq('peach')
119
+ expect(track.modified['child']['child']['name']).to eq('luigi')
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -8,6 +8,5 @@ RSpec.configure do |config|
8
8
  end
9
9
  config.after :each do
10
10
  Mongoid::History.tracker_class_name = nil
11
- Mongoid::History.trackable_class_options = nil
12
11
  end
13
12
  end
@@ -34,4 +34,25 @@ describe Mongoid::History do
34
34
  it { expect(described_class.trackable_class_settings(ModelOne)).to eq(paranoia_field: 'deleted_at') }
35
35
  end
36
36
  end
37
+
38
+ describe '#reset!' do
39
+ before :each do
40
+ class ModelTwo
41
+ include Mongoid::Document
42
+ include Mongoid::History::Trackable
43
+
44
+ track_history
45
+ end
46
+ end
47
+
48
+ after :each do
49
+ Object.send(:remove_const, :ModelTwo)
50
+ end
51
+
52
+ it 'should remove all configurations' do
53
+ expect(ModelTwo).to have_attributes mongoid_history_options: be_a(Mongoid::History::Options)
54
+ Mongoid::History.reset!
55
+ expect(ModelTwo).to_not respond_to :mongoid_history_options
56
+ end
57
+ end
37
58
  end
@@ -275,6 +275,15 @@ describe Mongoid::History::Options do
275
275
  it { expect(subject[:relations][:embeds_many]).to eq('emb_threes' => %w[_id fmb]) }
276
276
  end
277
277
 
278
+ context 'with fields, and multiple embeds_one, and embeds_many relations' do
279
+ let(:options) { { on: [:foo, :bar, :emb_two, { emb_threes: %i[f_em_foo f_em_bar], emb_fours: :f_em_baz }] } }
280
+ it 'should categorize fields and associations correctly' do
281
+ expect(subject[:fields]).to eq(%w[foo b])
282
+ expect(subject[:relations][:embeds_one]).to eq('emtw' => %w[_id f_em_baz])
283
+ expect(subject[:relations][:embeds_many]).to eq('emb_threes' => %w[_id f_em_foo fmb], 'emfs' => %w[_id f_em_baz])
284
+ end
285
+ end
286
+
278
287
  context 'with field alias' do
279
288
  let(:options) { { on: :bar } }
280
289
  it { expect(subject[:fields]).to eq %w[b] }
@@ -37,12 +37,6 @@ describe Mongoid::History::Trackable do
37
37
  expect(MyModel).to respond_to :track_history
38
38
  end
39
39
 
40
- it 'should append trackable_class_options ONLY when #track_history is called' do
41
- expect(Mongoid::History.trackable_class_options).to be_blank
42
- MyModel.track_history
43
- expect(Mongoid::History.trackable_class_options.keys).to eq([:my_model])
44
- end
45
-
46
40
  describe '#track_history' do
47
41
  before :each do
48
42
  class MyModelWithNoModifier
@@ -85,7 +79,7 @@ describe Mongoid::History::Trackable do
85
79
  let(:reserved_fields) { %w[_id version modifier_id] }
86
80
 
87
81
  it 'should have default options' do
88
- expect(Mongoid::History.trackable_class_options[:my_model].prepared).to eq(expected_option)
82
+ expect(MyModel.mongoid_history_options.prepared).to eq(expected_option)
89
83
  end
90
84
 
91
85
  it 'should define callback function #track_update' do
@@ -266,7 +260,7 @@ describe Mongoid::History::Trackable do
266
260
  end
267
261
 
268
262
  it 'should have default options' do
269
- expect(Mongoid::History.trackable_class_options[:my_model].prepared).to eq(expected_option)
263
+ expect(MyModel.mongoid_history_options.prepared).to eq(expected_option)
270
264
  end
271
265
 
272
266
  it 'should define #history_trackable_options' do
@@ -784,4 +778,62 @@ describe Mongoid::History::Trackable do
784
778
  end.to change(Tracker, :count).by(0)
785
779
  end
786
780
  end
781
+
782
+ context 'changing collection' do
783
+ before :each do
784
+ class Fish
785
+ include Mongoid::Document
786
+ include Mongoid::History::Trackable
787
+
788
+ track_history on: [:species], modifier_field_optional: true
789
+ store_in collection: :animals
790
+
791
+ field :species
792
+ end
793
+ end
794
+
795
+ after :each do
796
+ Object.send(:remove_const, :Fish)
797
+ end
798
+
799
+ it 'should track history' do
800
+ expect do
801
+ expect { Fish.new.save! }.to_not raise_error
802
+ end.to change(Tracker, :count).by(1)
803
+ end
804
+ end
805
+
806
+ context "extending a #{described_class}" do
807
+ before :each do
808
+ MyModel.track_history
809
+
810
+ class CustomTracker < MyModel
811
+ field :key
812
+
813
+ track_history on: :key, changes_method: :my_changes, track_create: true
814
+
815
+ def my_changes
816
+ changes.merge('key' => "Save history-#{key}")
817
+ end
818
+ end
819
+
820
+ MyModel.history_trackable_options
821
+ end
822
+
823
+ after :each do
824
+ Object.send(:remove_const, :CustomTracker)
825
+ end
826
+
827
+ it 'should not override in parent class' do
828
+ expect(MyModel.history_trackable_options[:changes_method]).to eq :changes
829
+ expect(CustomTracker.history_trackable_options[:changes_method]).to eq :my_changes
830
+ end
831
+
832
+ it 'should default to :changes' do
833
+ m = MyModel.create!(modifier: user)
834
+ expect(m).to receive(:changes).exactly(3).times.and_call_original
835
+ expect(m).not_to receive(:my_changes)
836
+ m.save!
837
+ end
838
+ end
787
839
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid-history
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Qian
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2018-06-28 00:00:00.000000000 Z
13
+ date: 2019-12-02 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: easy_diff
@@ -117,6 +117,7 @@ files:
117
117
  - spec/integration/multi_relation_spec.rb
118
118
  - spec/integration/multiple_trackers_spec.rb
119
119
  - spec/integration/nested_embedded_documents_spec.rb
120
+ - spec/integration/nested_embedded_documents_tracked_in_parent_spec.rb
120
121
  - spec/integration/nested_embedded_polymorphic_documents_spec.rb
121
122
  - spec/integration/subclasses_spec.rb
122
123
  - spec/integration/track_history_order_spec.rb
@@ -157,8 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
157
158
  - !ruby/object:Gem::Version
158
159
  version: '0'
159
160
  requirements: []
160
- rubyforge_project:
161
- rubygems_version: 2.6.13
161
+ rubygems_version: 3.0.3
162
162
  signing_key:
163
163
  specification_version: 4
164
164
  summary: Track and audit, undo and redo changes on Mongoid documents.
@@ -168,6 +168,7 @@ test_files:
168
168
  - spec/integration/multi_relation_spec.rb
169
169
  - spec/integration/multiple_trackers_spec.rb
170
170
  - spec/integration/nested_embedded_documents_spec.rb
171
+ - spec/integration/nested_embedded_documents_tracked_in_parent_spec.rb
171
172
  - spec/integration/nested_embedded_polymorphic_documents_spec.rb
172
173
  - spec/integration/subclasses_spec.rb
173
174
  - spec/integration/track_history_order_spec.rb