audited 4.10.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of audited might be problematic. Click here for more details.

Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.standard.yml +5 -0
  3. data/.travis.yml +25 -21
  4. data/Appraisals +10 -18
  5. data/CHANGELOG.md +29 -1
  6. data/Gemfile +1 -1
  7. data/README.md +16 -3
  8. data/Rakefile +6 -6
  9. data/lib/audited-rspec.rb +3 -1
  10. data/lib/audited.rb +25 -8
  11. data/lib/audited/audit.rb +24 -25
  12. data/lib/audited/auditor.rb +45 -39
  13. data/lib/audited/railtie.rb +16 -0
  14. data/lib/audited/rspec_matchers.rb +5 -3
  15. data/lib/audited/sweeper.rb +3 -10
  16. data/lib/audited/version.rb +3 -1
  17. data/lib/generators/audited/install_generator.rb +9 -7
  18. data/lib/generators/audited/migration.rb +2 -0
  19. data/lib/generators/audited/migration_helper.rb +3 -1
  20. data/lib/generators/audited/templates/add_association_to_audits.rb +2 -0
  21. data/lib/generators/audited/templates/add_comment_to_audits.rb +2 -0
  22. data/lib/generators/audited/templates/add_remote_address_to_audits.rb +2 -0
  23. data/lib/generators/audited/templates/add_request_uuid_to_audits.rb +2 -0
  24. data/lib/generators/audited/templates/add_version_to_auditable_index.rb +2 -0
  25. data/lib/generators/audited/templates/install.rb +2 -0
  26. data/lib/generators/audited/templates/rename_association_to_associated.rb +2 -0
  27. data/lib/generators/audited/templates/rename_changes_to_audited_changes.rb +2 -0
  28. data/lib/generators/audited/templates/rename_parent_to_association.rb +2 -0
  29. data/lib/generators/audited/templates/revert_polymorphic_indexes_order.rb +2 -0
  30. data/lib/generators/audited/upgrade_generator.rb +16 -14
  31. data/spec/audited/audit_spec.rb +67 -45
  32. data/spec/audited/auditor_spec.rb +284 -253
  33. data/spec/audited/sweeper_spec.rb +19 -19
  34. data/spec/audited_spec.rb +18 -0
  35. data/spec/audited_spec_helpers.rb +5 -7
  36. data/spec/rails_app/app/assets/config/manifest.js +2 -1
  37. data/spec/rails_app/config/application.rb +3 -3
  38. data/spec/rails_app/config/environment.rb +1 -1
  39. data/spec/rails_app/config/environments/test.rb +5 -5
  40. data/spec/rails_app/config/initializers/secret_token.rb +2 -2
  41. data/spec/spec_helper.rb +14 -14
  42. data/spec/support/active_record/models.rb +16 -12
  43. data/spec/support/active_record/postgres/1_change_audited_changes_type_to_json.rb +1 -2
  44. data/spec/support/active_record/postgres/2_change_audited_changes_type_to_jsonb.rb +1 -2
  45. data/spec/support/active_record/schema.rb +25 -19
  46. data/test/db/version_1.rb +2 -2
  47. data/test/db/version_2.rb +2 -2
  48. data/test/db/version_3.rb +2 -3
  49. data/test/db/version_4.rb +2 -3
  50. data/test/db/version_5.rb +0 -1
  51. data/test/db/version_6.rb +1 -1
  52. data/test/install_generator_test.rb +18 -19
  53. data/test/test_helper.rb +5 -5
  54. data/test/upgrade_generator_test.rb +13 -18
  55. metadata +20 -22
  56. data/.rubocop.yml +0 -25
  57. data/gemfiles/rails42.gemfile +0 -11
  58. data/spec/rails_app/app/controllers/application_controller.rb +0 -2
  59. data/spec/rails_app/config/environments/development.rb +0 -21
  60. data/spec/rails_app/config/environments/production.rb +0 -35
@@ -1,6 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
- SingleCov.covered! uncovered: 2 # 2 conditional on_load conditions
3
+ SingleCov.covered!
4
4
 
5
5
  class AuditsController < ActionController::Base
6
6
  before_action :populate_user
@@ -13,7 +13,7 @@ class AuditsController < ActionController::Base
13
13
  end
14
14
 
15
15
  def update
16
- current_user.update!(password: 'foo')
16
+ current_user.update!(password: "foo")
17
17
  head :ok
18
18
  end
19
19
 
@@ -22,7 +22,8 @@ class AuditsController < ActionController::Base
22
22
  attr_accessor :current_user
23
23
  attr_accessor :custom_user
24
24
 
25
- def populate_user; end
25
+ def populate_user
26
+ end
26
27
  end
27
28
 
28
29
  describe AuditsController do
@@ -30,6 +31,7 @@ describe AuditsController do
30
31
  render_views
31
32
 
32
33
  before do
34
+ Audited::Railtie.initializers.each(&:run)
33
35
  Audited.current_user_method = :current_user
34
36
  end
35
37
 
@@ -40,7 +42,7 @@ describe AuditsController do
40
42
  controller.send(:current_user=, user)
41
43
  expect {
42
44
  post :create
43
- }.to change( Audited::Audit, :count )
45
+ }.to change(Audited::Audit, :count)
44
46
 
45
47
  expect(controller.company.audits.last.user).to eq(user)
46
48
  end
@@ -50,7 +52,7 @@ describe AuditsController do
50
52
  Audited.current_user_method = :nope
51
53
  expect {
52
54
  post :create
53
- }.to change( Audited::Audit, :count )
55
+ }.to change(Audited::Audit, :count)
54
56
  expect(controller.company.audits.last.user).to eq(nil)
55
57
  end
56
58
 
@@ -60,18 +62,18 @@ describe AuditsController do
60
62
 
61
63
  expect {
62
64
  post :create
63
- }.to change( Audited::Audit, :count )
65
+ }.to change(Audited::Audit, :count)
64
66
 
65
67
  expect(controller.company.audits.last.user).to eq(user)
66
68
  end
67
69
 
68
70
  it "should record the remote address responsible for the change" do
69
- request.env['REMOTE_ADDR'] = "1.2.3.4"
71
+ request.env["REMOTE_ADDR"] = "1.2.3.4"
70
72
  controller.send(:current_user=, user)
71
73
 
72
74
  post :create
73
75
 
74
- expect(controller.company.audits.last.remote_address).to eq('1.2.3.4')
76
+ expect(controller.company.audits.last.remote_address).to eq("1.2.3.4")
75
77
  end
76
78
 
77
79
  it "should record a UUID for the web request responsible for the change" do
@@ -90,7 +92,7 @@ describe AuditsController do
90
92
 
91
93
  expect {
92
94
  post :create
93
- }.to change( Audited::Audit, :count )
95
+ }.to change(Audited::Audit, :count)
94
96
 
95
97
  expect(controller.company.audits.last.user).to eq(user)
96
98
  end
@@ -101,33 +103,31 @@ describe AuditsController do
101
103
  controller.send(:current_user=, user)
102
104
 
103
105
  expect {
104
- params = Rails::VERSION::MAJOR == 4 ? {id: 123} : {params: {id: 123}}
105
- put :update, **params
106
- }.to_not change( Audited::Audit, :count )
106
+ put :update, params: {id: 123}
107
+ }.to_not change(Audited::Audit, :count)
107
108
  end
108
109
  end
109
110
  end
110
111
 
111
112
  describe Audited::Sweeper do
112
-
113
113
  it "should be thread-safe" do
114
114
  instance = Audited::Sweeper.new
115
115
 
116
116
  t1 = Thread.new do
117
117
  sleep 0.5
118
- instance.controller = 'thread1 controller instance'
119
- expect(instance.controller).to eq('thread1 controller instance')
118
+ instance.controller = "thread1 controller instance"
119
+ expect(instance.controller).to eq("thread1 controller instance")
120
120
  end
121
121
 
122
122
  t2 = Thread.new do
123
- instance.controller = 'thread2 controller instance'
123
+ instance.controller = "thread2 controller instance"
124
124
  sleep 1
125
- expect(instance.controller).to eq('thread2 controller instance')
125
+ expect(instance.controller).to eq("thread2 controller instance")
126
126
  end
127
127
 
128
- t1.join; t2.join
128
+ t1.join
129
+ t2.join
129
130
 
130
131
  expect(instance.controller).to be_nil
131
132
  end
132
-
133
133
  end
@@ -0,0 +1,18 @@
1
+ require "spec_helper"
2
+
3
+ describe Audited do
4
+ describe "#store" do
5
+ describe "maintains state of store" do
6
+ let(:current_user) { "current_user" }
7
+ before { Audited.store[:current_user] = current_user }
8
+
9
+ it "when executed without fibers" do
10
+ expect(Audited.store[:current_user]).to eq(current_user)
11
+ end
12
+
13
+ it "when executed with Fibers" do
14
+ Fiber.new { expect(Audited.store[:current_user]).to eq(current_user) }.resume
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,15 +1,14 @@
1
1
  module AuditedSpecHelpers
2
-
3
2
  def create_user(attrs = {})
4
- Models::ActiveRecord::User.create({name: 'Brandon', username: 'brandon', password: 'password', favourite_device: 'Android Phone'}.merge(attrs))
3
+ Models::ActiveRecord::User.create({name: "Brandon", username: "brandon", password: "password", favourite_device: "Android Phone"}.merge(attrs))
5
4
  end
6
5
 
7
6
  def build_user(attrs = {})
8
- Models::ActiveRecord::User.new({name: 'darth', username: 'darth', password: 'noooooooo'}.merge(attrs))
7
+ Models::ActiveRecord::User.new({name: "darth", username: "darth", password: "noooooooo"}.merge(attrs))
9
8
  end
10
9
 
11
10
  def create_versions(n = 2, attrs = {})
12
- Models::ActiveRecord::User.create(name: 'Foobar 1', **attrs).tap do |u|
11
+ Models::ActiveRecord::User.create(name: "Foobar 1", **attrs).tap do |u|
13
12
  (n - 1).times do |i|
14
13
  u.update_attribute :name, "Foobar #{i + 2}"
15
14
  end
@@ -18,9 +17,9 @@ module AuditedSpecHelpers
18
17
  end
19
18
 
20
19
  def run_migrations(direction, migrations_paths, target_version = nil)
21
- if rails_below?('5.2.0.rc1')
20
+ if rails_below?("5.2.0.rc1")
22
21
  ActiveRecord::Migrator.send(direction, migrations_paths, target_version)
23
- elsif rails_below?('6.0.0.rc1')
22
+ elsif rails_below?("6.0.0.rc1")
24
23
  ActiveRecord::MigrationContext.new(migrations_paths).send(direction, target_version)
25
24
  else
26
25
  ActiveRecord::MigrationContext.new(migrations_paths, ActiveRecord::SchemaMigration).send(direction, target_version)
@@ -30,5 +29,4 @@ module AuditedSpecHelpers
30
29
  def rails_below?(rails_version)
31
30
  Gem::Version.new(Rails::VERSION::STRING) < Gem::Version.new(rails_version)
32
31
  end
33
-
34
32
  end
@@ -1 +1,2 @@
1
- {}
1
+ //= link application.js
2
+ //= link application.css
@@ -1,13 +1,13 @@
1
- require 'rails/all'
1
+ require "active_record/railtie"
2
2
 
3
3
  module RailsApp
4
4
  class Application < Rails::Application
5
- config.root = File.expand_path('../../', __FILE__)
5
+ config.root = File.expand_path("../../", __FILE__)
6
6
  config.i18n.enforce_available_locales = true
7
7
  end
8
8
  end
9
9
 
10
- require 'active_record/connection_adapters/sqlite3_adapter'
10
+ require "active_record/connection_adapters/sqlite3_adapter"
11
11
  if ActiveRecord::ConnectionAdapters::SQLite3Adapter.respond_to?(:represent_boolean_as_integer)
12
12
  ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer = true
13
13
  end
@@ -1,5 +1,5 @@
1
1
  # Load the rails application
2
- require File.expand_path('../application', __FILE__)
2
+ require File.expand_path("../application", __FILE__)
3
3
 
4
4
  # Initialize the rails application
5
5
  RailsApp::Application.initialize!
@@ -15,14 +15,14 @@ RailsApp::Application.configure do
15
15
  # Configure static file server for tests with Cache-Control for performance.
16
16
  if config.respond_to?(:public_file_server)
17
17
  config.public_file_server.enabled = true
18
- config.public_file_server.headers = { 'Cache-Control' => 'public, max-age=3600' }
18
+ config.public_file_server.headers = {"Cache-Control" => "public, max-age=3600"}
19
19
  else
20
- config.static_cache_control = 'public, max-age=3600'
21
- config.serve_static_files = true
20
+ config.static_cache_control = "public, max-age=3600"
21
+ config.serve_static_files = true
22
22
  end
23
23
 
24
24
  # Show full error reports and disable caching.
25
- config.consider_all_requests_local = true
25
+ config.consider_all_requests_local = true
26
26
  # config.action_controller.perform_caching = false
27
27
 
28
28
  # Raise exceptions instead of rendering exception templates.
@@ -34,7 +34,7 @@ RailsApp::Application.configure do
34
34
  # Tell Action Mailer not to deliver emails to the real world.
35
35
  # The :test delivery method accumulates sent emails in the
36
36
  # ActionMailer::Base.deliveries array.
37
- config.action_mailer.delivery_method = :test
37
+ # config.action_mailer.delivery_method = :test
38
38
 
39
39
  # Randomize the order test cases are executed.
40
40
  config.active_support.test_order = :random
@@ -1,3 +1,3 @@
1
- Rails.application.config.secret_token = 'ea942c41850d502f2c8283e26bdc57829f471bb18224ddff0a192c4f32cdf6cb5aa0d82b3a7a7adbeb640c4b06f3aa1cd5f098162d8240f669b39d6b49680571'
1
+ Rails.application.config.secret_token = "ea942c41850d502f2c8283e26bdc57829f471bb18224ddff0a192c4f32cdf6cb5aa0d82b3a7a7adbeb640c4b06f3aa1cd5f098162d8240f669b39d6b49680571"
2
2
  Rails.application.config.session_store :cookie_store, key: "_my_app"
3
- Rails.application.config.secret_key_base = 'secret value'
3
+ Rails.application.config.secret_key_base = "secret value"
data/spec/spec_helper.rb CHANGED
@@ -1,24 +1,24 @@
1
- ENV['RAILS_ENV'] = 'test'
2
- require 'bundler/setup'
3
- require 'single_cov'
1
+ ENV["RAILS_ENV"] = "test"
2
+ require "bundler/setup"
3
+ require "single_cov"
4
4
  SingleCov.setup :rspec
5
5
 
6
- if Bundler.definition.dependencies.map(&:name).include?('protected_attributes')
7
- require 'protected_attributes'
6
+ if Bundler.definition.dependencies.map(&:name).include?("protected_attributes")
7
+ require "protected_attributes"
8
8
  end
9
- require 'rails_app/config/environment'
10
- require 'rspec/rails'
11
- require 'audited'
12
- require 'audited-rspec'
13
- require 'audited_spec_helpers'
14
- require 'support/active_record/models'
9
+ require "rails_app/config/environment"
10
+ require "rspec/rails"
11
+ require "audited"
12
+ require "audited-rspec"
13
+ require "audited_spec_helpers"
14
+ require "support/active_record/models"
15
15
 
16
- SPEC_ROOT = Pathname.new(File.expand_path('../', __FILE__))
16
+ SPEC_ROOT = Pathname.new(File.expand_path("../", __FILE__))
17
17
 
18
- Dir[SPEC_ROOT.join('support/*.rb')].each{|f| require f }
18
+ Dir[SPEC_ROOT.join("support/*.rb")].sort.each { |f| require f }
19
19
 
20
20
  RSpec.configure do |config|
21
21
  config.include AuditedSpecHelpers
22
- config.use_transactional_fixtures = false if Rails.version.start_with?('4.')
22
+ config.use_transactional_fixtures = false if Rails.version.start_with?("4.")
23
23
  config.use_transactional_tests = false if config.respond_to?(:use_transactional_tests=)
24
24
  end
@@ -1,13 +1,14 @@
1
- require 'cgi'
2
- require File.expand_path('../schema', __FILE__)
1
+ require "cgi"
2
+ require File.expand_path("../schema", __FILE__)
3
3
 
4
4
  module Models
5
5
  module ActiveRecord
6
6
  class User < ::ActiveRecord::Base
7
7
  audited except: :password
8
- attribute :non_column_attr if Rails.version >= '5.1'
8
+ attribute :non_column_attr if Rails.version >= "5.1"
9
9
  attr_protected :logins if respond_to?(:attr_protected)
10
- enum status: { active: 0, reliable: 1, banned: 2 }
10
+ enum status: {active: 0, reliable: 1, banned: 2}
11
+ serialize :phone_numbers, Array
11
12
 
12
13
  def name=(val)
13
14
  write_attribute(:name, CGI.escapeHTML(val))
@@ -21,7 +22,7 @@ module Models
21
22
 
22
23
  class UserOnlyPassword < ::ActiveRecord::Base
23
24
  self.table_name = :users
24
- attribute :non_column_attr if Rails.version >= '5.1'
25
+ attribute :non_column_attr if Rails.version >= "5.1"
25
26
  audited only: :password
26
27
  end
27
28
 
@@ -42,7 +43,7 @@ module Models
42
43
 
43
44
  class CommentRequiredUser < ::ActiveRecord::Base
44
45
  self.table_name = :users
45
- audited comment_required: true
46
+ audited except: :password, comment_required: true
46
47
  end
47
48
 
48
49
  class OnCreateCommentRequiredUser < ::ActiveRecord::Base
@@ -111,36 +112,39 @@ module Models
111
112
  end
112
113
 
113
114
  class Owner < ::ActiveRecord::Base
114
- self.table_name = 'users'
115
+ self.table_name = "users"
115
116
  audited
116
117
  has_associated_audits
117
118
  has_many :companies, class_name: "OwnedCompany", dependent: :destroy
118
119
  end
119
120
 
120
121
  class OwnedCompany < ::ActiveRecord::Base
121
- self.table_name = 'companies'
122
+ self.table_name = "companies"
122
123
  belongs_to :owner, class_name: "Owner"
123
124
  attr_accessible :name, :owner if respond_to?(:attr_accessible) # declare attr_accessible before calling aaa
124
125
  audited associated_with: :owner
125
126
  end
126
127
 
128
+ class OwnedCompany::STICompany < OwnedCompany
129
+ end
130
+
127
131
  class OnUpdateDestroy < ::ActiveRecord::Base
128
- self.table_name = 'companies'
132
+ self.table_name = "companies"
129
133
  audited on: [:update, :destroy]
130
134
  end
131
135
 
132
136
  class OnCreateDestroy < ::ActiveRecord::Base
133
- self.table_name = 'companies'
137
+ self.table_name = "companies"
134
138
  audited on: [:create, :destroy]
135
139
  end
136
140
 
137
141
  class OnCreateDestroyExceptName < ::ActiveRecord::Base
138
- self.table_name = 'companies'
142
+ self.table_name = "companies"
139
143
  audited except: :name, on: [:create, :destroy]
140
144
  end
141
145
 
142
146
  class OnCreateUpdate < ::ActiveRecord::Base
143
- self.table_name = 'companies'
147
+ self.table_name = "companies"
144
148
  audited on: [:create, :update]
145
149
  end
146
150
  end
@@ -1,5 +1,4 @@
1
- parent = Rails::VERSION::MAJOR == 4 ? ActiveRecord::Migration : ActiveRecord::Migration[4.2]
2
- class ChangeAuditedChangesTypeToJson < parent
1
+ class ChangeAuditedChangesTypeToJson < ActiveRecord::Migration[5.0]
3
2
  def self.up
4
3
  remove_column :audits, :audited_changes
5
4
  add_column :audits, :audited_changes, :json
@@ -1,5 +1,4 @@
1
- parent = Rails::VERSION::MAJOR == 4 ? ActiveRecord::Migration : ActiveRecord::Migration[4.2]
2
- class ChangeAuditedChangesTypeToJsonb < parent
1
+ class ChangeAuditedChangesTypeToJsonb < ActiveRecord::Migration[5.0]
3
2
  def self.up
4
3
  remove_column :audits, :audited_changes
5
4
  add_column :audits, :audited_changes, :jsonb
@@ -1,28 +1,33 @@
1
- require 'active_record'
2
- require 'logger'
1
+ require "active_record"
2
+ require "logger"
3
3
 
4
4
  begin
5
- db_config = ActiveRecord::Base.configurations[Rails.env].clone
6
- db_type = db_config['adapter']
7
- db_name = db_config.delete('database')
8
- raise Exception.new('No database name specified.') if db_name.blank?
9
- if db_type == 'sqlite3'
10
- db_file = Pathname.new(__FILE__).dirname.join(db_name)
11
- db_file.unlink if db_file.file?
5
+ if ActiveRecord.version >= Gem::Version.new("6.1.0")
6
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).first
7
+ ActiveRecord::Tasks::DatabaseTasks.create(db_config)
12
8
  else
13
- if defined?(JRUBY_VERSION)
14
- db_config.symbolize_keys!
15
- db_config[:configure_connection] = false
9
+ db_config = ActiveRecord::Base.configurations[Rails.env].clone
10
+ db_type = db_config["adapter"]
11
+ db_name = db_config.delete("database")
12
+ raise StandardError.new("No database name specified.") if db_name.blank?
13
+ if db_type == "sqlite3"
14
+ db_file = Pathname.new(__FILE__).dirname.join(db_name)
15
+ db_file.unlink if db_file.file?
16
+ else
17
+ if defined?(JRUBY_VERSION)
18
+ db_config.symbolize_keys!
19
+ db_config[:configure_connection] = false
20
+ end
21
+ adapter = ActiveRecord::Base.send("#{db_type}_connection", db_config)
22
+ adapter.recreate_database db_name, db_config.slice("charset").symbolize_keys
23
+ adapter.disconnect!
16
24
  end
17
- adapter = ActiveRecord::Base.send("#{db_type}_connection", db_config)
18
- adapter.recreate_database db_name, db_config.slice('charset').symbolize_keys
19
- adapter.disconnect!
20
25
  end
21
26
  rescue => e
22
27
  Kernel.warn e
23
28
  end
24
29
 
25
- logfile = Pathname.new(__FILE__).dirname.join('debug.log')
30
+ logfile = Pathname.new(__FILE__).dirname.join("debug.log")
26
31
  logfile.unlink if logfile.file?
27
32
  ActiveRecord::Base.logger = Logger.new(logfile)
28
33
 
@@ -42,6 +47,7 @@ ActiveRecord::Schema.define do
42
47
  t.column :updated_at, :datetime
43
48
  t.column :favourite_device, :string
44
49
  t.column :ssn, :integer
50
+ t.column :phone_numbers, :string
45
51
  end
46
52
 
47
53
  create_table :companies do |t|
@@ -76,9 +82,9 @@ ActiveRecord::Schema.define do
76
82
  t.column :created_at, :datetime
77
83
  end
78
84
 
79
- add_index :audits, [:auditable_id, :auditable_type], name: 'auditable_index'
80
- add_index :audits, [:associated_id, :associated_type], name: 'associated_index'
81
- add_index :audits, [:user_id, :user_type], name: 'user_index'
85
+ add_index :audits, [:auditable_id, :auditable_type], name: "auditable_index"
86
+ add_index :audits, [:associated_id, :associated_type], name: "associated_index"
87
+ add_index :audits, [:user_id, :user_type], name: "user_index"
82
88
  add_index :audits, :request_uuid
83
89
  add_index :audits, :created_at
84
90
  end