iknow_view_models 3.1.6 → 3.2.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 +4 -4
- data/.circleci/config.yml +6 -6
- data/.rubocop.yml +18 -0
- data/Appraisals +6 -6
- data/Gemfile +6 -2
- data/Rakefile +5 -5
- data/gemfiles/rails_5_2.gemfile +5 -5
- data/gemfiles/rails_6_0.gemfile +9 -0
- data/iknow_view_models.gemspec +40 -38
- data/lib/iknow_view_models.rb +9 -7
- data/lib/iknow_view_models/version.rb +1 -1
- data/lib/view_model.rb +31 -17
- data/lib/view_model/access_control.rb +5 -2
- data/lib/view_model/access_control/composed.rb +10 -9
- data/lib/view_model/access_control/open.rb +2 -0
- data/lib/view_model/access_control/read_only.rb +2 -0
- data/lib/view_model/access_control/tree.rb +11 -6
- data/lib/view_model/access_control_error.rb +4 -1
- data/lib/view_model/active_record.rb +13 -12
- data/lib/view_model/active_record/association_data.rb +3 -2
- data/lib/view_model/active_record/association_manipulation.rb +6 -4
- data/lib/view_model/active_record/cache.rb +114 -34
- data/lib/view_model/active_record/cache/cacheable_view.rb +2 -2
- data/lib/view_model/active_record/collection_nested_controller.rb +3 -3
- data/lib/view_model/active_record/controller.rb +68 -1
- data/lib/view_model/active_record/controller_base.rb +4 -1
- data/lib/view_model/active_record/nested_controller_base.rb +1 -0
- data/lib/view_model/active_record/update_context.rb +8 -6
- data/lib/view_model/active_record/update_data.rb +32 -30
- data/lib/view_model/active_record/update_operation.rb +17 -13
- data/lib/view_model/active_record/visitor.rb +0 -1
- data/lib/view_model/after_transaction_runner.rb +2 -2
- data/lib/view_model/callbacks.rb +3 -1
- data/lib/view_model/controller.rb +13 -3
- data/lib/view_model/deserialization_error.rb +15 -12
- data/lib/view_model/error.rb +12 -10
- data/lib/view_model/error_view.rb +3 -1
- data/lib/view_model/migratable_view.rb +78 -0
- data/lib/view_model/migration.rb +48 -0
- data/lib/view_model/migration/no_path_error.rb +26 -0
- data/lib/view_model/migration/one_way_error.rb +24 -0
- data/lib/view_model/migration/unspecified_version_error.rb +24 -0
- data/lib/view_model/migrator.rb +108 -0
- data/lib/view_model/record.rb +15 -14
- data/lib/view_model/reference.rb +3 -1
- data/lib/view_model/references.rb +8 -5
- data/lib/view_model/registry.rb +1 -1
- data/lib/view_model/schemas.rb +9 -4
- data/lib/view_model/serialization_error.rb +4 -1
- data/lib/view_model/serialize_context.rb +4 -4
- data/lib/view_model/test_helpers.rb +8 -3
- data/lib/view_model/test_helpers/arvm_builder.rb +21 -15
- data/lib/view_model/traversal_context.rb +2 -1
- data/nix/dependencies.nix +5 -0
- data/nix/gem/generate.rb +2 -1
- data/shell.nix +8 -3
- data/test/.rubocop.yml +14 -0
- data/test/helpers/arvm_test_models.rb +12 -9
- data/test/helpers/arvm_test_utilities.rb +5 -3
- data/test/helpers/controller_test_helpers.rb +55 -32
- data/test/helpers/match_enumerator.rb +1 -0
- data/test/helpers/query_logging.rb +2 -1
- data/test/helpers/test_access_control.rb +5 -3
- data/test/helpers/viewmodel_spec_helpers.rb +88 -22
- data/test/unit/view_model/access_control_test.rb +144 -144
- data/test/unit/view_model/active_record/alias_test.rb +15 -13
- data/test/unit/view_model/active_record/belongs_to_test.rb +40 -39
- data/test/unit/view_model/active_record/cache_test.rb +68 -31
- data/test/unit/view_model/active_record/cloner_test.rb +67 -63
- data/test/unit/view_model/active_record/controller_test.rb +113 -65
- data/test/unit/view_model/active_record/counter_test.rb +10 -9
- data/test/unit/view_model/active_record/customization_test.rb +59 -58
- data/test/unit/view_model/active_record/has_many_test.rb +112 -111
- data/test/unit/view_model/active_record/has_many_through_poly_test.rb +15 -14
- data/test/unit/view_model/active_record/has_many_through_test.rb +33 -38
- data/test/unit/view_model/active_record/has_one_test.rb +37 -36
- data/test/unit/view_model/active_record/migration_test.rb +161 -0
- data/test/unit/view_model/active_record/namespacing_test.rb +19 -17
- data/test/unit/view_model/active_record/poly_test.rb +44 -45
- data/test/unit/view_model/active_record/shared_test.rb +30 -28
- data/test/unit/view_model/active_record/version_test.rb +9 -7
- data/test/unit/view_model/active_record_test.rb +72 -72
- data/test/unit/view_model/callbacks_test.rb +19 -15
- data/test/unit/view_model/controller_test.rb +4 -2
- data/test/unit/view_model/record_test.rb +92 -97
- data/test/unit/view_model/traversal_context_test.rb +4 -5
- data/test/unit/view_model_test.rb +18 -16
- metadata +36 -12
- data/.travis.yml +0 -31
- data/appveyor.yml +0 -22
- data/gemfiles/rails_6_0_beta.gemfile +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a86b2b9fdc89ee421bcb155ae29e3ac4f2c809be4d40e483a405337f8729a7f9
|
4
|
+
data.tar.gz: 8fd1c498264a0eefe30d9c3c6a35c4f005a94aaf71b03d37044a23212cb90eb4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c2a2fd321cf605709eb398771cd6cc475869e80c59d5a4934a2cf5429cfa3e1a6a5e3e74f358227793ff2cc7ce10a1eff46fe3c4db20e859d49d54be306b4afb
|
7
|
+
data.tar.gz: cfb7009b02acbebce85d3ad41205549430370710633d51176ac8596acf6a83fb98f0e76132bf850baf37da36acfe402afc21d00c8996f66ca2a98f62a9380dc1
|
data/.circleci/config.yml
CHANGED
@@ -102,15 +102,15 @@ workflows:
|
|
102
102
|
build:
|
103
103
|
jobs:
|
104
104
|
- test:
|
105
|
-
name: 'ruby 2.6 rails 5.2 pg
|
105
|
+
name: 'ruby 2.6 rails 5.2 pg 12'
|
106
106
|
ruby-version: "2.6"
|
107
|
-
pg-version: "
|
107
|
+
pg-version: "12"
|
108
108
|
gemfile: gemfiles/rails_5_2.gemfile
|
109
109
|
- test:
|
110
|
-
name: 'ruby 2.
|
111
|
-
ruby-version: "2.
|
112
|
-
pg-version: "
|
113
|
-
gemfile: gemfiles/
|
110
|
+
name: 'ruby 2.7 rails 6.0 pg 12'
|
111
|
+
ruby-version: "2.7"
|
112
|
+
pg-version: "12"
|
113
|
+
gemfile: gemfiles/rails_6_0.gemfile
|
114
114
|
- publish:
|
115
115
|
filters:
|
116
116
|
branches:
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.7
|
3
|
+
Exclude:
|
4
|
+
- Appraisals
|
5
|
+
- Gemfile
|
6
|
+
- Rakefile
|
7
|
+
- 'gemfiles/*'
|
8
|
+
- 'nix/gem/**/*'
|
9
|
+
|
10
|
+
inherit_gem:
|
11
|
+
rubocop-iknow: rubocop.yml
|
12
|
+
|
13
|
+
Metrics/BlockNesting:
|
14
|
+
Enabled: false
|
15
|
+
Lint/IneffectiveAccessModifier:
|
16
|
+
Enabled: false
|
17
|
+
Lint/UselessAccessModifier:
|
18
|
+
Enabled: false
|
data/Appraisals
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
appraise
|
2
|
-
gem
|
3
|
-
gem
|
1
|
+
appraise 'rails-5-2' do
|
2
|
+
gem 'activerecord', '~> 5.2.0'
|
3
|
+
gem 'activesupport', '~> 5.2.0'
|
4
4
|
end
|
5
5
|
|
6
|
-
appraise
|
7
|
-
gem
|
8
|
-
gem
|
6
|
+
appraise 'rails-6-0' do
|
7
|
+
gem 'activerecord', '~> 6.0.0'
|
8
|
+
gem 'activesupport', '~> 6.0.0'
|
9
9
|
end
|
data/Gemfile
CHANGED
@@ -3,9 +3,13 @@ source 'https://rubygems.org'
|
|
3
3
|
# Specify your gem's dependencies in cerego_view_models.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
+
# Add our linter rules as a development dependency
|
7
|
+
gem 'rubocop'
|
8
|
+
gem 'rubocop-iknow'
|
9
|
+
|
6
10
|
# Test metadata collection for circleci
|
7
11
|
gem 'minitest-ci'
|
8
12
|
|
9
13
|
# Override gemspec for development version preferences
|
10
|
-
gem 'activerecord', '~>
|
11
|
-
gem 'activesupport', '~>
|
14
|
+
gem 'activerecord', '~> 6.0.0'
|
15
|
+
gem 'activesupport', '~> 6.0.0'
|
data/Rakefile
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rake/testtask'
|
3
3
|
|
4
4
|
Rake::TestTask.new do |t|
|
5
5
|
t.libs << 'test'
|
@@ -8,14 +8,14 @@ Rake::TestTask.new do |t|
|
|
8
8
|
t.verbose = true
|
9
9
|
end
|
10
10
|
|
11
|
-
desc
|
11
|
+
desc 'Open an IRB console with the test helpers'
|
12
12
|
task :test_console do
|
13
13
|
ruby %{-r bundler/setup -Ilib -e 'load "test/helpers/arvm_test_models.rb"' -r irb -e 'IRB.start(__FILE__)'}
|
14
14
|
end
|
15
15
|
|
16
|
-
desc
|
16
|
+
desc 'Open a Pry console with the test helpers'
|
17
17
|
task 'test_console:pry' do
|
18
|
-
ruby %
|
18
|
+
ruby %(-r bundler/setup -Ilib -e 'load "test/helpers/arvm_test_models.rb"' -r pry -e 'Pry.start')
|
19
19
|
end
|
20
20
|
|
21
21
|
task :default => :test
|
data/gemfiles/rails_5_2.gemfile
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# This file was generated by Appraisal
|
2
2
|
|
3
|
-
source
|
3
|
+
source 'https://rubygems.org'
|
4
4
|
|
5
|
-
gem
|
6
|
-
gem
|
7
|
-
gem
|
5
|
+
gem 'minitest-ci'
|
6
|
+
gem 'activerecord', '~> 5.2.0'
|
7
|
+
gem 'activesupport', '~> 5.2.0'
|
8
8
|
|
9
|
-
gemspec path:
|
9
|
+
gemspec path: '../'
|
data/iknow_view_models.gemspec
CHANGED
@@ -1,50 +1,52 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
# coding: utf-8
|
3
2
|
|
4
|
-
lib = File.expand_path('
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
5
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
6
5
|
require 'iknow_view_models/version'
|
7
6
|
|
8
7
|
Gem::Specification.new do |spec|
|
9
|
-
spec.name =
|
8
|
+
spec.name = 'iknow_view_models'
|
10
9
|
spec.version = IknowViewModels::VERSION
|
11
|
-
spec.authors = [
|
12
|
-
spec.email = [
|
13
|
-
spec.summary =
|
14
|
-
spec.description =
|
15
|
-
spec.homepage =
|
16
|
-
spec.license =
|
10
|
+
spec.authors = ['iKnow Team']
|
11
|
+
spec.email = ['edge@iknow.jp']
|
12
|
+
spec.summary = 'ViewModels provide a means of encapsulating a collection of related data and specifying its JSON serialization.'
|
13
|
+
spec.description = ''
|
14
|
+
spec.homepage = 'https://github.com/iknow/cerego_view_models'
|
15
|
+
spec.license = 'MIT'
|
17
16
|
|
18
17
|
spec.files = `git ls-files -z`.split("\x0")
|
19
18
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
|
-
spec.require_paths = [
|
22
|
-
|
23
|
-
spec.
|
24
|
-
|
25
|
-
|
26
|
-
spec.add_dependency
|
27
|
-
|
28
|
-
spec.add_dependency
|
29
|
-
spec.add_dependency
|
30
|
-
spec.add_dependency
|
31
|
-
spec.add_dependency
|
32
|
-
|
33
|
-
spec.add_dependency
|
34
|
-
|
35
|
-
spec.add_dependency
|
36
|
-
spec.add_dependency
|
37
|
-
spec.add_dependency
|
38
|
-
spec.add_dependency
|
39
|
-
|
40
|
-
spec.
|
41
|
-
spec.
|
42
|
-
|
43
|
-
spec.add_development_dependency
|
44
|
-
spec.add_development_dependency
|
45
|
-
spec.add_development_dependency
|
46
|
-
spec.add_development_dependency
|
47
|
-
spec.add_development_dependency
|
48
|
-
spec.add_development_dependency
|
49
|
-
spec.add_development_dependency
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
spec.required_ruby_version = 2.6
|
23
|
+
|
24
|
+
spec.add_dependency 'activerecord', '>= 5.0'
|
25
|
+
spec.add_dependency 'activesupport', '>= 5.0'
|
26
|
+
|
27
|
+
spec.add_dependency 'acts_as_manual_list'
|
28
|
+
spec.add_dependency 'deep_preloader', '>= 1.0.1'
|
29
|
+
spec.add_dependency 'iknow_cache'
|
30
|
+
spec.add_dependency 'iknow_params', '~> 2.2.0'
|
31
|
+
spec.add_dependency 'keyword_builder'
|
32
|
+
spec.add_dependency 'safe_values'
|
33
|
+
|
34
|
+
spec.add_dependency 'concurrent-ruby'
|
35
|
+
spec.add_dependency 'jbuilder'
|
36
|
+
spec.add_dependency 'json_schema'
|
37
|
+
spec.add_dependency 'lazily'
|
38
|
+
spec.add_dependency 'oj'
|
39
|
+
spec.add_dependency 'renum'
|
40
|
+
spec.add_dependency 'rgl'
|
41
|
+
|
42
|
+
spec.add_development_dependency 'appraisal'
|
43
|
+
spec.add_development_dependency 'bundler'
|
44
|
+
spec.add_development_dependency 'byebug'
|
45
|
+
spec.add_development_dependency 'method_source'
|
46
|
+
spec.add_development_dependency 'minitest-hooks'
|
47
|
+
spec.add_development_dependency 'pg'
|
48
|
+
spec.add_development_dependency 'pry'
|
49
|
+
spec.add_development_dependency 'rake'
|
50
|
+
spec.add_development_dependency 'rspec-expectations'
|
51
|
+
spec.add_development_dependency 'sqlite3'
|
50
52
|
end
|
data/lib/iknow_view_models.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'iknow_view_models/version'
|
4
|
+
require 'view_model'
|
5
|
+
require 'view_model/controller'
|
6
|
+
require 'view_model/active_record'
|
7
|
+
require 'view_model/active_record/controller'
|
8
|
+
require 'view_model/active_record/singular_nested_controller'
|
9
|
+
require 'view_model/active_record/collection_nested_controller'
|
8
10
|
|
9
11
|
module IknowViewModels
|
10
12
|
end
|
data/lib/view_model.rb
CHANGED
@@ -6,14 +6,19 @@ require 'jbuilder'
|
|
6
6
|
require 'deep_preloader'
|
7
7
|
|
8
8
|
class ViewModel
|
9
|
-
REFERENCE_ATTRIBUTE =
|
10
|
-
ID_ATTRIBUTE =
|
11
|
-
TYPE_ATTRIBUTE =
|
12
|
-
VERSION_ATTRIBUTE =
|
13
|
-
NEW_ATTRIBUTE =
|
14
|
-
|
15
|
-
|
16
|
-
|
9
|
+
REFERENCE_ATTRIBUTE = '_ref'
|
10
|
+
ID_ATTRIBUTE = 'id'
|
11
|
+
TYPE_ATTRIBUTE = '_type'
|
12
|
+
VERSION_ATTRIBUTE = '_version'
|
13
|
+
NEW_ATTRIBUTE = '_new'
|
14
|
+
|
15
|
+
# Migrations leave a metadata attribute _migrated on any views that they
|
16
|
+
# alter. This attribute is accessible as metadata when deserializing migrated
|
17
|
+
# input, and is included in the output serialization sent to clients.
|
18
|
+
MIGRATED_ATTRIBUTE = '_migrated'
|
19
|
+
|
20
|
+
Metadata = Struct.new(:id, :view_name, :schema_version, :new, :migrated) do
|
21
|
+
alias_method :new?, :new
|
17
22
|
end
|
18
23
|
|
19
24
|
class << self
|
@@ -23,6 +28,7 @@ class ViewModel
|
|
23
28
|
attr_writer :view_name
|
24
29
|
|
25
30
|
def inherited(subclass)
|
31
|
+
super
|
26
32
|
subclass.initialize_as_viewmodel
|
27
33
|
end
|
28
34
|
|
@@ -38,6 +44,7 @@ class ViewModel
|
|
38
44
|
# try to auto-detect based on class name
|
39
45
|
match = /(.*)View$/.match(self.name)
|
40
46
|
raise ArgumentError.new("Could not auto-determine ViewModel name from class name '#{self.name}'") if match.nil?
|
47
|
+
|
41
48
|
ViewModel::Registry.default_view_name(match[1])
|
42
49
|
end
|
43
50
|
end
|
@@ -72,6 +79,7 @@ class ViewModel
|
|
72
79
|
end
|
73
80
|
|
74
81
|
attr_accessor attr
|
82
|
+
|
75
83
|
define_method("deserialize_#{attr}") do |value, references: {}, deserialize_context: self.class.new_deserialize_context|
|
76
84
|
self.public_send("#{attr}=", value)
|
77
85
|
end
|
@@ -99,8 +107,9 @@ class ViewModel
|
|
99
107
|
type_name = hash.delete(ViewModel::TYPE_ATTRIBUTE)
|
100
108
|
schema_version = hash.delete(ViewModel::VERSION_ATTRIBUTE)
|
101
109
|
new = hash.delete(ViewModel::NEW_ATTRIBUTE) { false }
|
110
|
+
migrated = hash.delete(ViewModel::MIGRATED_ATTRIBUTE) { false }
|
102
111
|
|
103
|
-
Metadata.new(id, type_name, schema_version, new)
|
112
|
+
Metadata.new(id, type_name, schema_version, new, migrated)
|
104
113
|
end
|
105
114
|
|
106
115
|
def extract_reference_only_metadata(hash)
|
@@ -108,7 +117,7 @@ class ViewModel
|
|
108
117
|
id = hash.delete(ViewModel::ID_ATTRIBUTE)
|
109
118
|
type_name = hash.delete(ViewModel::TYPE_ATTRIBUTE)
|
110
119
|
|
111
|
-
Metadata.new(id, type_name, nil, false)
|
120
|
+
Metadata.new(id, type_name, nil, false, false)
|
112
121
|
end
|
113
122
|
|
114
123
|
def extract_reference_metadata(hash)
|
@@ -116,7 +125,7 @@ class ViewModel
|
|
116
125
|
hash.delete(ViewModel::REFERENCE_ATTRIBUTE)
|
117
126
|
end
|
118
127
|
|
119
|
-
def is_update_hash?(hash)
|
128
|
+
def is_update_hash?(hash) # rubocop:disable Naming/PredicateName
|
120
129
|
ViewModel::Schemas.verify_schema!(ViewModel::Schemas::VIEWMODEL_UPDATE, hash)
|
121
130
|
hash.has_key?(ViewModel::ID_ATTRIBUTE) &&
|
122
131
|
!hash.fetch(ViewModel::ActiveRecord::NEW_ATTRIBUTE, false)
|
@@ -192,12 +201,12 @@ class ViewModel
|
|
192
201
|
end
|
193
202
|
|
194
203
|
member_names.each do |attr|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
204
|
+
next unless view_hash.has_key?(attr)
|
205
|
+
|
206
|
+
viewmodel.public_send("deserialize_#{attr}",
|
207
|
+
view_hash[attr],
|
208
|
+
references: references,
|
209
|
+
deserialize_context: deserialize_context)
|
201
210
|
end
|
202
211
|
|
203
212
|
deserialize_context.run_callback(ViewModel::Callbacks::Hook::BeforeValidate, viewmodel)
|
@@ -234,6 +243,11 @@ class ViewModel
|
|
234
243
|
schema_version == self.schema_version
|
235
244
|
end
|
236
245
|
|
246
|
+
def schema_hash(schema_versions)
|
247
|
+
version_string = schema_versions.to_a.sort.join(',')
|
248
|
+
Base64.urlsafe_encode64(Digest::MD5.digest(version_string))
|
249
|
+
end
|
250
|
+
|
237
251
|
def preload_for_serialization(viewmodels, serialize_context: new_serialize_context, include_referenced: true, lock: nil)
|
238
252
|
Array.wrap(viewmodels).group_by(&:class).each do |type, views|
|
239
253
|
DeepPreloader.preload(views.map(&:model),
|
@@ -13,11 +13,12 @@ require 'view_model/access_control_error'
|
|
13
13
|
class ViewModel::AccessControl
|
14
14
|
Result = Struct.new(:permit, :error) do
|
15
15
|
def initialize(permit, error: nil)
|
16
|
-
raise ArgumentError.new(
|
16
|
+
raise ArgumentError.new('Successful AccessControl::Result may not have an error') if permit && error
|
17
|
+
|
17
18
|
super(permit, error)
|
18
19
|
end
|
19
20
|
|
20
|
-
|
21
|
+
alias_method :permit?, :permit
|
21
22
|
|
22
23
|
# Merge this result with another access control result. Takes a block
|
23
24
|
# returning a result, and returns a combined result for both tests. Access
|
@@ -129,6 +130,7 @@ class ViewModel::AccessControl
|
|
129
130
|
if @initial_editability_store.has_key?(view.object_id)
|
130
131
|
raise RuntimeError.new("Access control data already recorded for view #{view.to_reference}")
|
131
132
|
end
|
133
|
+
|
132
134
|
@initial_editability_store[view.object_id] = initial_editability
|
133
135
|
end
|
134
136
|
|
@@ -136,6 +138,7 @@ class ViewModel::AccessControl
|
|
136
138
|
unless @initial_editability_store.has_key?(view.object_id)
|
137
139
|
raise RuntimeError.new("No access control data recorded for view #{view.to_reference}")
|
138
140
|
end
|
141
|
+
|
139
142
|
@initial_editability_store.delete(view.object_id)
|
140
143
|
end
|
141
144
|
|
@@ -8,8 +8,9 @@
|
|
8
8
|
class ViewModel::AccessControl::Composed < ViewModel::AccessControl
|
9
9
|
ComposedResult = Struct.new(:allow, :veto, :allow_error, :veto_error) do
|
10
10
|
def initialize(allow, veto, allow_error, veto_error)
|
11
|
-
raise ArgumentError.new(
|
12
|
-
raise ArgumentError.new(
|
11
|
+
raise ArgumentError.new('Non-vetoing result may not have a veto error') if veto_error && !veto
|
12
|
+
raise ArgumentError.new('Allowing result may not have a allow error') if allow_error && allow
|
13
|
+
|
13
14
|
super
|
14
15
|
end
|
15
16
|
|
@@ -64,7 +65,7 @@ class ViewModel::AccessControl::Composed < ViewModel::AccessControl
|
|
64
65
|
attr_reader :reasons
|
65
66
|
|
66
67
|
def initialize(nodes, reasons)
|
67
|
-
super(
|
68
|
+
super('Action not permitted because none of the possible conditions were met.', nodes)
|
68
69
|
@reasons = reasons
|
69
70
|
end
|
70
71
|
|
@@ -92,7 +93,7 @@ class ViewModel::AccessControl::Composed < ViewModel::AccessControl
|
|
92
93
|
end
|
93
94
|
|
94
95
|
def initialize_as_composed_access_control
|
95
|
-
@included_checkers
|
96
|
+
@included_checkers = []
|
96
97
|
|
97
98
|
@edit_valid_ifs = []
|
98
99
|
@edit_valid_unlesses = []
|
@@ -152,15 +153,16 @@ class ViewModel::AccessControl::Composed < ViewModel::AccessControl
|
|
152
153
|
@included_checkers.each do |ancestor|
|
153
154
|
next unless visited.add?(ancestor)
|
154
155
|
next if include_ancestor && !include_ancestor.call(ancestor)
|
156
|
+
|
155
157
|
ancestor.each_check(check_name) { |x| yield x }
|
156
158
|
end
|
157
159
|
end
|
158
160
|
|
159
161
|
def inspect
|
160
|
-
s = super +
|
161
|
-
s += inspect_checks.join(
|
162
|
+
s = super + '('
|
163
|
+
s += inspect_checks.join(', ')
|
162
164
|
s += " includes checkers: #{@included_checkers.inspect}" if @included_checkers.present?
|
163
|
-
s +=
|
165
|
+
s += ')'
|
164
166
|
s
|
165
167
|
end
|
166
168
|
|
@@ -174,7 +176,6 @@ class ViewModel::AccessControl::Composed < ViewModel::AccessControl
|
|
174
176
|
checks << "edit_valid_unless: #{@edit_valid_unlesses.map(&:reason)}" if @edit_valid_unlesses.present?
|
175
177
|
checks
|
176
178
|
end
|
177
|
-
|
178
179
|
end
|
179
180
|
|
180
181
|
# final
|
@@ -199,7 +200,7 @@ class ViewModel::AccessControl::Composed < ViewModel::AccessControl
|
|
199
200
|
|
200
201
|
veto = vetoed_checker.present?
|
201
202
|
if veto
|
202
|
-
veto_error = vetoed_checker.error_type.new(
|
203
|
+
veto_error = vetoed_checker.error_type.new('Action not permitted because: ' +
|
203
204
|
vetoed_checker.reason,
|
204
205
|
env.view.blame_reference)
|
205
206
|
end
|