salestation 4.1.0 → 4.2.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/README.md +23 -0
- data/lib/salestation/rspec.rb +64 -0
- data/lib/salestation/rspec/failure_matcher.rb +125 -0
- data/lib/salestation/rspec/glia_input_validation_error_matcher.rb +49 -0
- data/salestation.gemspec +3 -1
- metadata +37 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 95319eaf34503c8cdbe7c7ebbaefbd23e92090417ee6588fe394714981c87efe
|
4
|
+
data.tar.gz: 9ec9d477a27876759501d401981a5dcdcacc00d543c3af954da325fce42a8b08
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85caaf8b2e31975fc302dff5492dabf42fb2affd681e4f038de544d48b9a3df4903a8eb11f2b2dbe3a244be13061a225e01f458ffcf5c6c008aab7ec0e61bef0
|
7
|
+
data.tar.gz: 11a0e53eea71d877032836b2b11762d4f20fabf42a86b2742ba4db6b8ad9b0ad26df3d3fadaa2d00231e0048bb9b288b118a2ef05f3d92ddf447cc8d7cca67ea
|
data/README.md
CHANGED
@@ -184,6 +184,29 @@ You can configure per-request tags by defining `salestation.statsd.tags` in sina
|
|
184
184
|
end
|
185
185
|
```
|
186
186
|
|
187
|
+
## RSpec helpers
|
188
|
+
|
189
|
+
|
190
|
+
To use Salestation RSpec matchers you first need to include them:
|
191
|
+
|
192
|
+
```
|
193
|
+
require 'salestation/rspec'
|
194
|
+
|
195
|
+
RSpec.configure do |config|
|
196
|
+
config.include Salestation::RSpec::Matchers
|
197
|
+
end
|
198
|
+
```
|
199
|
+
|
200
|
+
After that it's possible to match against error results like this:
|
201
|
+
|
202
|
+
```
|
203
|
+
expect(result).to be_failure
|
204
|
+
.with_conflict
|
205
|
+
.containing(message: 'Oh noes')
|
206
|
+
```
|
207
|
+
|
208
|
+
See lib/salestation/rspec.rb for more examples.
|
209
|
+
|
187
210
|
## Development
|
188
211
|
|
189
212
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rspec/expectations'
|
4
|
+
require 'salestation/app'
|
5
|
+
|
6
|
+
require_relative './rspec/failure_matcher'
|
7
|
+
require_relative './rspec/glia_input_validation_error_matcher'
|
8
|
+
|
9
|
+
module Salestation
|
10
|
+
module RSpec
|
11
|
+
# Usage:
|
12
|
+
#
|
13
|
+
# In your RSpec configuration first include the matchers:
|
14
|
+
#
|
15
|
+
# RSpec.configure do |config|
|
16
|
+
# config.include Salestation::RSpec::Matchers
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# Then you can use the matchers like this:
|
20
|
+
#
|
21
|
+
# expect(result).to be_failure
|
22
|
+
# .with_conflict
|
23
|
+
# .containing(message: 'Oh noes')
|
24
|
+
#
|
25
|
+
# or when using Glia Errors:
|
26
|
+
#
|
27
|
+
# expect(result).to be_failure
|
28
|
+
# .with_requested_resource_not_found
|
29
|
+
# .containing(Glia::Errors::ResourceNotFoundError.new(resource: :user))
|
30
|
+
#
|
31
|
+
# or when matching input errors from Glia Errors:
|
32
|
+
#
|
33
|
+
# expect(result).to be_failure
|
34
|
+
# .with_invalid_input
|
35
|
+
# .containing(glia_input_validation_error.on(:name).with_type(Glia::Errors::INVALID_VALUE_ERROR))
|
36
|
+
#
|
37
|
+
# or you could even match multiple input errors at the same time:
|
38
|
+
# expect(result).to be_failure
|
39
|
+
# .with_invalid_input
|
40
|
+
# .containing(
|
41
|
+
# glia_input_validation_error
|
42
|
+
# .on(:name).with_type(Glia::Errors::INVALID_VALUE_ERROR)
|
43
|
+
# .on(:email)
|
44
|
+
# .on(:phone_number).with_type(Glia::Errors::INVALID_FORMAT_ERROR)
|
45
|
+
# )
|
46
|
+
#
|
47
|
+
# Everything after be_failure is optional. You could also use `.containing`
|
48
|
+
# multiple times like this:
|
49
|
+
#
|
50
|
+
# expect(result).to be_failure
|
51
|
+
# .containing(Glia::Errors::ResourceNotFoundError.new(resource: :user))
|
52
|
+
# .containing(hash_including(message: 'Overriden message'))
|
53
|
+
#
|
54
|
+
module Matchers
|
55
|
+
def be_failure
|
56
|
+
FailureMatcher.new
|
57
|
+
end
|
58
|
+
|
59
|
+
def glia_input_validation_error
|
60
|
+
GliaInputValidationErrorMatcher.new
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rspec/expectations'
|
4
|
+
|
5
|
+
module Salestation
|
6
|
+
module RSpec
|
7
|
+
class FailureMatcher
|
8
|
+
include ::RSpec::Matchers::Composable
|
9
|
+
|
10
|
+
attr_reader :expected, :actual, :failure_message
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@contents_matchers = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def with(error_class)
|
17
|
+
@error_class = error_class
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
# From: active_support/inflector/methods.rb
|
22
|
+
def self.underscore(camel_cased_word)
|
23
|
+
return camel_cased_word unless /[A-Z-]|::/.match?(camel_cased_word)
|
24
|
+
word = camel_cased_word.to_s.gsub("::", "/")
|
25
|
+
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
26
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
27
|
+
word.tr!("-", "_")
|
28
|
+
word.downcase!
|
29
|
+
word
|
30
|
+
end
|
31
|
+
private_class_method :underscore
|
32
|
+
|
33
|
+
# Defined methods using error class names:
|
34
|
+
# with_conflict
|
35
|
+
# with_invalid_input
|
36
|
+
# ...
|
37
|
+
Salestation::App::Errors.constants.each do |class_name|
|
38
|
+
define_method(:"with_#{underscore(class_name.to_s)}") do
|
39
|
+
with(Salestation::App::Errors.const_get(class_name))
|
40
|
+
self
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def containing(matcher)
|
45
|
+
@contents_matchers << matcher
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
def matches?(actual)
|
50
|
+
check_failure(actual) &&
|
51
|
+
check_error_type(actual) &&
|
52
|
+
check_contents(actual)
|
53
|
+
end
|
54
|
+
|
55
|
+
def diffable?
|
56
|
+
true
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def check_failure(actual)
|
62
|
+
return true if actual.class == Deterministic::Result::Failure
|
63
|
+
|
64
|
+
@failure_message = "Expected Failure(...), but got #{actual.inspect}"
|
65
|
+
@expected = Deterministic::Result::Failure
|
66
|
+
@actual = actual.class
|
67
|
+
false
|
68
|
+
end
|
69
|
+
|
70
|
+
def check_error_type(actual)
|
71
|
+
return true unless @error_class
|
72
|
+
return true if actual.value.class == @error_class
|
73
|
+
|
74
|
+
@failure_message = "Expected failure to include #{@error_class}, but got #{actual.value.inspect}"
|
75
|
+
@expected = @error_class
|
76
|
+
@actual = actual.value.class
|
77
|
+
false
|
78
|
+
end
|
79
|
+
|
80
|
+
def check_contents(actual)
|
81
|
+
return true if @contents_matchers.empty?
|
82
|
+
|
83
|
+
has_error = @contents_matchers.detect do |contents_matcher|
|
84
|
+
if contents_matcher.is_a?(Hash) || rspec_matcher?(contents_matcher)
|
85
|
+
verify_contents_using_regular_matcher!(contents_matcher, actual)
|
86
|
+
else
|
87
|
+
verify_contents_using_base_error!(contents_matcher, actual)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
!has_error
|
92
|
+
end
|
93
|
+
|
94
|
+
# Returns true when error was detected
|
95
|
+
def verify_contents_using_regular_matcher!(contents_matcher, actual)
|
96
|
+
return false if values_match?(contents_matcher, actual.value.to_h)
|
97
|
+
|
98
|
+
@failure_message = "Contents in #{actual.value.class} do not match"
|
99
|
+
@expected = contents_matcher
|
100
|
+
@actual = actual.value.to_h
|
101
|
+
|
102
|
+
true
|
103
|
+
end
|
104
|
+
|
105
|
+
# Returns true when error was detected
|
106
|
+
def verify_contents_using_base_error!(contents_matcher, actual)
|
107
|
+
# Compare hashes if possible, otherwise expect it to respond to `#matches?`.
|
108
|
+
contents_matcher = contents_matcher.to_h if contents_matcher.respond_to?(:to_h)
|
109
|
+
|
110
|
+
return false if values_match?(contents_matcher, actual.value[:base_error])
|
111
|
+
|
112
|
+
@failure_message = "Expected failure to be based on #{contents_matcher}, but got #{actual.value.inspect}"
|
113
|
+
@expected = contents_matcher
|
114
|
+
@actual = actual.value[:base_error].to_h
|
115
|
+
|
116
|
+
true
|
117
|
+
end
|
118
|
+
|
119
|
+
def rspec_matcher?(matcher)
|
120
|
+
# Didn't find a better way to detect matchers like HashIncludingMatcher
|
121
|
+
matcher.class.to_s.start_with?('RSpec')
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rspec/expectations'
|
4
|
+
|
5
|
+
module Salestation
|
6
|
+
module RSpec
|
7
|
+
class GliaInputValidationErrorMatcher
|
8
|
+
include ::RSpec::Matchers::Composable
|
9
|
+
|
10
|
+
attr_reader :expected, :actual, :failure_message
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@fields = []
|
14
|
+
@field_error_types = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def on(field)
|
18
|
+
@fields << field
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def with_type(*types)
|
23
|
+
@field_error_types[@fields.last] = types
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def matches?(actual)
|
28
|
+
@fields.all? do |field|
|
29
|
+
check_field_exists(field, actual) &&
|
30
|
+
check_field_error_types(field, actual)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def check_field_exists(field, actual)
|
37
|
+
actual[:error_details].key?(field)
|
38
|
+
end
|
39
|
+
|
40
|
+
def check_field_error_types(field, actual)
|
41
|
+
return true unless @field_error_types[field]
|
42
|
+
|
43
|
+
actual_error_types = actual[:error_details].fetch(field).map { |f| f.fetch(:type) }
|
44
|
+
|
45
|
+
(@field_error_types[field] - actual_error_types).empty?
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/salestation.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "salestation"
|
7
|
-
spec.version = "4.
|
7
|
+
spec.version = "4.2.0"
|
8
8
|
spec.authors = ["Glia TechMovers"]
|
9
9
|
spec.email = ["techmovers@glia.com"]
|
10
10
|
|
@@ -23,6 +23,8 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_development_dependency "rake", "~> 13.0"
|
24
24
|
spec.add_development_dependency "rspec", "~> 3.0"
|
25
25
|
spec.add_development_dependency "pry", "~> 0.10.4"
|
26
|
+
spec.add_development_dependency "glia-errors", "~> 0.8"
|
27
|
+
spec.add_development_dependency "dry-validation"
|
26
28
|
|
27
29
|
spec.add_dependency 'deterministic'
|
28
30
|
spec.add_dependency 'dry-struct'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: salestation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Glia TechMovers
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-03-
|
11
|
+
date: 2021-03-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,6 +66,34 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 0.10.4
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: glia-errors
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.8'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.8'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: dry-validation
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
69
97
|
- !ruby/object:Gem::Dependency
|
70
98
|
name: deterministic
|
71
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,6 +156,9 @@ files:
|
|
128
156
|
- lib/salestation/app/input_verification.rb
|
129
157
|
- lib/salestation/app/request.rb
|
130
158
|
- lib/salestation/result_helper.rb
|
159
|
+
- lib/salestation/rspec.rb
|
160
|
+
- lib/salestation/rspec/failure_matcher.rb
|
161
|
+
- lib/salestation/rspec/glia_input_validation_error_matcher.rb
|
131
162
|
- lib/salestation/web.rb
|
132
163
|
- lib/salestation/web/active_record_connection_management.rb
|
133
164
|
- lib/salestation/web/error_mapper.rb
|
@@ -143,7 +174,7 @@ homepage: ''
|
|
143
174
|
licenses:
|
144
175
|
- MIT
|
145
176
|
metadata: {}
|
146
|
-
post_install_message:
|
177
|
+
post_install_message:
|
147
178
|
rdoc_options: []
|
148
179
|
require_paths:
|
149
180
|
- lib
|
@@ -158,8 +189,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
158
189
|
- !ruby/object:Gem::Version
|
159
190
|
version: '0'
|
160
191
|
requirements: []
|
161
|
-
rubygems_version: 3.0.
|
162
|
-
signing_key:
|
192
|
+
rubygems_version: 3.0.9
|
193
|
+
signing_key:
|
163
194
|
specification_version: 4
|
164
195
|
summary: ''
|
165
196
|
test_files: []
|