checkability 0.7.0 → 2.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d691bd54ab262dd07d0bdf1120d632a71003cfdc730002275d10333e21045526
4
- data.tar.gz: 104e1558d7867413f25e838d3db9aaf54d2a7f96b412dd1121149e9528c9f95d
3
+ metadata.gz: b338934af7b685f8c2737d5e96daa3913ca6040afdcfe65f2d45d05dfacc5b86
4
+ data.tar.gz: 8fd02d3a5b7394641d4dd371771197c6646be3285df8265fbad3634eb2101778
5
5
  SHA512:
6
- metadata.gz: 42816cf5985cfcc1d0f680496f0fdde3fd3263f87a4b12010f9d3f33694481703c8ed3785531914cfd5143982001c6fbe2977a52de789d7c559720048d3657ec
7
- data.tar.gz: 00e84b4caa4c5fae3eea6ae4e7e1fb0c3550e29948c81df7a85aaf4ea8ae98bf1083e3559b1583d28243faecdd477ebdbb8b7eab33318cd6571f15b5a08b52a0
6
+ metadata.gz: c7f287a23f6ad83c3c305991dbac396efae4011bd8142a795e22992346922d34bf3b696b149d48a5d82f6aaa393f4f9d57fd725285a8bd523b3828b795bf3925
7
+ data.tar.gz: 6cd5eb1a4e0c25f415c7dd3237ae5022ce1b87f6a626c01dd74da4627dd7eee23921143c0d943ab61b782c83d711ae829e1f68c22aeccf2d862f960d16f02fc3
data/README.md CHANGED
@@ -12,12 +12,12 @@ How to use my plugin.
12
12
  inside of any rails model do
13
13
  ```ruby
14
14
  class SomeModel
15
- acts_as_checkable strategy: proc { |a, b, c| a && (b || c) },
16
- checkers: uk_postcode_checkers
15
+ extend UKPostcodeCheckersConf
16
+ acts_as_checkable uk_postcode_checkers_conf
17
17
  end
18
18
  ```
19
19
  where `uk_postcode_checkers` is method which returns hash with configurations
20
- https://github.com/azazelo/postcode_checker/blob/master/app/models/concerns/u_k_postcode_checkers.rb
20
+ https://github.com/azazelo/postcode_checker/blob/master/app/models/concerns/u_k_postcode_checkers_conf.rb
21
21
  then in your controller:
22
22
  ```ruby
23
23
  class ChecksController < ApplicationController
@@ -30,7 +30,7 @@ class ChecksController < ApplicationController
30
30
  message, alert_class =
31
31
  if @check.valid?
32
32
  @check.perform_check
33
- [@check.messages.join('<br/>'), _alert_class(@check.allowed)]
33
+ [@check.ch_messages.join('<br/>'), _alert_class(@check.ch_allowed)]
34
34
  else
35
35
  [@check.errors.full_messages.join('<br/>'), _alert_class(false)]
36
36
  end
data/lib/checkability.rb CHANGED
@@ -9,7 +9,6 @@ require_relative 'checkability/external_api_checker'
9
9
  require_relative 'checkability/external_api_connector'
10
10
  require_relative 'checkability/validator'
11
11
  require_relative 'checkability/acts_as_checkable'
12
- require_relative 'checkability/checker'
13
- require_relative 'checkability/abstract_checker'
12
+ require_relative 'checkability/base_checker'
14
13
 
15
14
  ActiveRecord::Base.include Checkability::ActsAsCheckable
@@ -17,19 +17,24 @@ module Checkability
17
17
  "Hash expected, got #{options.class.name}"
18
18
  end
19
19
 
20
- class_attribute :checkable_conf
20
+ class_attribute :ch_conf
21
21
 
22
- self.checkable_conf = options
22
+ self.ch_conf = options
23
23
  end
24
24
  end
25
25
 
26
- attr_accessor :allowed, :messages
26
+ attr_accessor :ch_allowed, :ch_messages, :ch_conf
27
+
28
+ def initialize(params)
29
+ @ch_messages = []
30
+ @ch_allowed = nil
31
+ super(params)
32
+ end
27
33
 
28
34
  def perform_check
29
- self.allowed = nil
30
- self.messages = []
31
- self.allowed = Checkability::Checkable.new(self).check(checkable_conf)
32
- messages << "#{allowed}::'#{_value}' is #{_allowness}. "
35
+ @ch_conf = ch_conf
36
+ Checkability::Checkable.new(self).check
37
+ ch_messages << "#{ch_allowed}:::'#{_value}' is #{_allowness}. "
33
38
  end
34
39
 
35
40
  private
@@ -39,13 +44,11 @@ module Checkability
39
44
  end
40
45
 
41
46
  def _attr_name
42
- checkable_conf[:attr_name] || :value
47
+ ch_conf[:attr_name] || :value
43
48
  end
44
49
 
45
- def _setup; end
46
-
47
50
  def _allowness
48
- allowed ? 'ALLOWED' : 'NOT allowed'
51
+ ch_allowed ? 'ALLOWED' : 'NOT allowed'
49
52
  end
50
53
  end
51
54
  end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'checker'
4
+
5
+ module Checkability
6
+ # @abstract
7
+ class BaseChecker < Checker
8
+ # @return [Handler]
9
+ attr_reader :stop_process_on_success, :stop_process_on_failure,
10
+ :success_message, :failure_message
11
+
12
+ def initialize(opts = {})
13
+ @stop_process_on_failure = opts[:stop_process_on_failure] || false
14
+ @stop_process_on_success = opts[:stop_process_on_success] || false
15
+ @success_message = opts[:success_message] || 'Success.'
16
+ @failure_message = opts[:failure_message] || 'Failed.'
17
+
18
+ @next_handler = nil
19
+ post_initialize(opts) # implemented in subclass
20
+ end
21
+
22
+ # subclass should implement
23
+ def post_initialize(_opts)
24
+ nil
25
+ end
26
+
27
+ # @param [Handler] handler
28
+ #
29
+ # @return [Handler]
30
+ def next_handler(handler)
31
+ @next_handler = handler
32
+
33
+ handler
34
+ end
35
+
36
+ # @abstract
37
+ #
38
+ # @param [String] request
39
+ #
40
+ # @return [Boolean, nil]
41
+ def handle(check_obj)
42
+ res, mess = result_and_message(check_obj)
43
+ check_obj.ch_messages << mess
44
+ check_obj.ch_allowed = res
45
+
46
+ return if _stop_here?(res)
47
+
48
+ @next_handler&.handle(check_obj) if @next_handler
49
+ end
50
+
51
+ def result_and_message(check_obj = nil)
52
+ res = result(check_obj)
53
+
54
+ str = res ? success_message : failure_message
55
+ [res, message(res, str)]
56
+ rescue StandardError => e
57
+ [false, message(false, e)]
58
+ end
59
+
60
+ # subclass should implement
61
+ def result(_check_obj)
62
+ raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
63
+ end
64
+
65
+ # subclass may override
66
+ def message(res, str)
67
+ "#{res}:::#{str}"
68
+ end
69
+
70
+ private
71
+
72
+ def _stop_here?(res)
73
+ (res && stop_process_on_success) || (!res && stop_process_on_failure)
74
+ end
75
+ end
76
+ end
@@ -1,55 +1,60 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'forwardable'
4
+
3
5
  module Checkability
4
6
  # Implements check method to Iterate on chechers
5
7
  # Possible to implemet as Iterator in future
6
8
  #
7
9
  class Checkable
8
- attr_reader :checkable
10
+ attr_accessor :check_obj, :handler_confs
11
+
12
+ extend Forwardable
13
+ def_delegators :@check_obj, :ch_messages, :ch_allowed, :ch_conf
9
14
 
10
- def initialize(checkable)
11
- @checkable = checkable
12
- @checkable.messages = []
15
+ def initialize(check_obj)
16
+ @check_obj = check_obj
13
17
  end
14
18
 
15
19
  # As in result handlers should behave like this:
16
- # validator .set_next(storage)
17
- # storage .set_next(api_validator)
18
- # api_validator.set_next(api_finder)
19
- # api_validator.set_next(nil)
20
+ # validator .next_handler(storage)
21
+ # storage .next_handler(api_validator)
22
+ # api_validator.next_handler(api_finder)
23
+ # api_validator.next_handler(nil)
20
24
  #
21
25
  # validator.handle(request)
22
26
  #
23
- def check(opts)
24
- handler_confs = opts[:handler_confs]
25
- first_handler_name = opts[:first_handler]
26
- first_handler = _handlers(handler_confs)[first_handler_name]
27
-
28
- first_handler.handle(checkable)
29
- # rescue StandardError => e
30
- # checkable.messages << "false::#{e}: #{opts}."
31
- # false
27
+ # ChainOfResponsibilty
28
+ #
29
+ def check
30
+ _first_handler.handle(check_obj)
31
+ rescue StandardError => e
32
+ check_obj.ch_messages << "false:::#{e}: #{handler_confs}."
33
+ false
32
34
  end
33
35
 
34
36
  private
35
37
 
36
- def _handlers(handler_confs)
37
- handlers = _make_handlers(handler_confs)
38
- handlers.each do |handler_name, handler|
39
- next_handler_name = handler_confs[handler_name][:next_handler]
38
+ def _first_handler
39
+ _handlers[ch_conf.keys.first]
40
+ end
41
+
42
+ def _handlers
43
+ handlers = _make_handlers
44
+ handlers.each_value.with_index do |handler, i|
45
+ next_handler_name = handlers.keys[i + 1]
40
46
  handler.next_handler(handlers[next_handler_name]) if handlers[next_handler_name]
41
47
  end
48
+ handlers
42
49
  end
43
50
 
44
- def _make_handlers(handler_confs)
45
- handler_confs.transform_values do |handler_conf|
46
- _make_handler(handler_conf)
47
- end
51
+ def _make_handlers
52
+ ch_conf.transform_values { |conf| _make_handler(conf) }
48
53
  end
49
54
 
50
55
  def _make_handler(conf)
51
- k = Checkability.const_get conf[:name].to_s.camelize
52
- k.new(conf)
56
+ Checkability.const_get(conf[:name].to_s.camelize)
57
+ .new(conf)
53
58
  end
54
59
  end
55
60
  end
@@ -3,6 +3,16 @@
3
3
  module Checkability
4
4
  # @abstract
5
5
  class Checker
6
+ # hook method to initialize concreet attributes
7
+ # @abstract
8
+ #
9
+ # @param [Hash]
10
+ #
11
+ # @return new object
12
+ def post_initialize(_opts)
13
+ raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
14
+ end
15
+
6
16
  # @abstract
7
17
  #
8
18
  # @param [Handler] handler
@@ -23,17 +33,26 @@ module Checkability
23
33
  #
24
34
  # @param [String] request
25
35
  #
26
- # @return [Boolean, true|false]
27
- def check_value(_request)
36
+ # @return Array [ [Boolean, true|false], String, message] ]
37
+ def result_and_message(_object)
28
38
  raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
29
39
  end
30
40
 
31
41
  # @abstract
32
42
  #
33
- # @param [String] request
43
+ # @param [Checkable object] request
34
44
  #
35
45
  # @return [Boolean, true|false]
36
- def result_and_message(_object)
46
+ def result(_object)
47
+ raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
48
+ end
49
+
50
+ # @abstract
51
+ #
52
+ # @params [Boolean], [String]
53
+ #
54
+ # @return [String]
55
+ def message(_res, _str)
37
56
  raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
38
57
  end
39
58
  end
@@ -1,43 +1,45 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'faraday'
4
- require 'net/http'
5
- require 'net/https'
6
- require 'json'
7
-
8
- # frozen_string_literal: true
3
+ require 'forwardable'
9
4
 
10
5
  module Checkability
11
6
  # Checks if postcode exists in external API
12
7
  #
13
- class ExternalApiChecker < AbstractChecker
14
- attr_reader :path, :path_suffix, :check_method, :connection, :http_verb,
15
- :failure_message, :success_message
8
+ class ExternalApiChecker < BaseChecker
9
+ attr_reader :path, :path_suffix, :check_method, :connector, :http_verb
10
+
11
+ extend Forwardable
12
+ def_delegators :@connector, :connection
16
13
 
17
14
  def post_initialize(conf = {})
18
15
  @path = conf[:path]
19
16
  @http_verb = conf[:http_verb] || :get
20
17
  @path_suffix = conf[:path_suffix] || ''
21
18
  @check_method = conf[:check_method]
22
- @connection = Checkability::ExternalApiConnector.new(conf)
19
+ @connector = conf[:connector] ||
20
+ Checkability::ExternalApiConnector.new(conf[:path])
21
+ @resp = nil
23
22
  end
24
23
 
25
- private
24
+ def result(check_obj)
25
+ return false unless resp(check_obj).status == 200
26
26
 
27
- def _result(checkable)
28
- resp = connection
29
- .connect
30
- .send(http_verb, "#{checkable.value.delete(' ')}#{path_suffix}")
31
- return false unless resp.status == 200
27
+ check_method.call(_parsed(resp(check_obj)))
28
+ end
32
29
 
33
- check_method.call(_parsed(resp))
30
+ def resp(check_obj)
31
+ @resp ||= connection
32
+ .send(http_verb,
33
+ "#{check_obj.value.delete(' ')}#{path_suffix}")
34
+ # .get('SE17QD')
34
35
  end
35
36
 
36
- def message(str, res)
37
- str = "#{path}: #{str}"
38
- super(str, res)
37
+ def message(res, str = nil)
38
+ "#{res}:::#{path}: #{str}"
39
39
  end
40
40
 
41
+ private
42
+
41
43
  def _parsed(resp)
42
44
  JSON.parse(resp.body)
43
45
  end
@@ -1,16 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'faraday'
4
+
3
5
  module Checkability
4
6
  # Create connection
5
7
  #
6
8
  class ExternalApiConnector
7
9
  attr_reader :path
8
10
 
9
- def initialize(conf)
10
- @path = conf[:path]
11
+ def initialize(path)
12
+ @path = path
11
13
  end
12
14
 
13
- def connect
15
+ def connection
14
16
  Faraday.new(url: path) do |faraday|
15
17
  faraday.headers['Content-Type'] = 'application/json'
16
18
  faraday.adapter Faraday.default_adapter
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'abstract_checker'
3
+ require_relative 'base_checker'
4
4
  module Checkability
5
5
  # Checks if postcode exists in Storage
6
6
  #
7
- class StorageChecker < AbstractChecker
7
+ class StorageChecker < BaseChecker
8
8
  attr_reader :storage_class, :attr_name
9
9
 
10
10
  def post_initialize(conf = {})
@@ -12,18 +12,17 @@ module Checkability
12
12
  @attr_name = conf[:attr_name] || :value
13
13
  end
14
14
 
15
- private
16
-
17
- def _result(checkable)
15
+ def result(checkable)
18
16
  value = _normalize_value(checkable.send(attr_name))
19
17
  storage_class.where(attr_name => value).present?
20
18
  end
21
19
 
22
- def message(str, res)
23
- str = "Allowed #{storage_class}s list: #{str}"
24
- super(str, res)
20
+ def message(res, str = nil)
21
+ "#{res}:::Allowed #{storage_class}s list: #{str}"
25
22
  end
26
23
 
24
+ private
25
+
27
26
  def _normalize_value(value)
28
27
  value.delete(' ').upcase
29
28
  end
@@ -3,16 +3,14 @@
3
3
  module Checkability
4
4
  # Checks if postcode comply with regex
5
5
  #
6
- class Validator < AbstractChecker
6
+ class Validator < BaseChecker
7
7
  attr_reader :format
8
8
 
9
9
  def post_initialize(conf = {})
10
10
  @format = conf[:format]
11
11
  end
12
12
 
13
- private
14
-
15
- def _result(checkable)
13
+ def result(checkable)
16
14
  !(checkable.value.delete(' ') =~ format[:regex]).nil?
17
15
  end
18
16
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Checkability
4
- VERSION = '0.7.0'
4
+ VERSION = '2.0.3'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: checkability
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 2.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey Eremeev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-03 00:00:00.000000000 Z
11
+ date: 2021-04-06 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Provide Checkers functionality.
14
14
  email:
@@ -23,8 +23,8 @@ files:
23
23
  - Rakefile
24
24
  - bin/checkability
25
25
  - lib/checkability.rb
26
- - lib/checkability/abstract_checker.rb
27
26
  - lib/checkability/acts_as_checkable.rb
27
+ - lib/checkability/base_checker.rb
28
28
  - lib/checkability/checkable.rb
29
29
  - lib/checkability/checker.rb
30
30
  - lib/checkability/external_api_checker.rb
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'checker'
4
-
5
- module Checkability
6
- # @abstract
7
- class AbstractChecker < Checker
8
- # @return [Handler]
9
- attr_reader :stop_process_on_failure, :stop_process_on_success
10
- attr_accessor :success_message, :failure_message, :handler
11
-
12
- def initialize(opts = {})
13
- @stop_process_on_failure = opts[:stop_process_on_failure] || false
14
- @stop_process_on_success = opts[:stop_process_on_success] || false
15
- @success_message = opts[:success_message] || 'Success.'
16
- @failure_message = opts[:failure_message] || 'Failed.'
17
-
18
- @next_handler = nil
19
- post_initialize(opts) # implemented in subclass
20
- end
21
-
22
- # @param [Handler] handler
23
- #
24
- # @return [Handler]
25
- def next_handler(handler)
26
- @handler = handler if handler
27
-
28
- handler
29
- end
30
-
31
- # @abstract
32
- #
33
- # @param [String] request
34
- #
35
- # @return [Boolean, nil]
36
- def handle(request)
37
- check = check_value(request) # imlemented in subclass
38
-
39
- return true if check && stop_process_on_success
40
-
41
- return false if !check && stop_process_on_failure
42
-
43
- handler&.handle(request)
44
- end
45
-
46
- def check_value(checkable)
47
- result, message = result_and_message(checkable)
48
- checkable.messages << message
49
- result
50
- end
51
-
52
- def result_and_message(checkable)
53
- result = _result(checkable)
54
- str = result ? success_message : failure_message
55
- [result, message(str, result)]
56
- rescue StandardError => e
57
- [false, message(e, false)]
58
- end
59
-
60
- def _result; end
61
-
62
- def message(str, res)
63
- "#{res}::#{str}"
64
- end
65
- end
66
- end