webvalve 1.3.1 → 2.0.1

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: 94d2cb2a5a975fb3dc734272460423bb27c6909d49a80b807161da8b95a97da1
4
- data.tar.gz: cc3df67e4361e88d496937ec37dc65619b96371c8ae52c6f4c217e434a7edddc
3
+ metadata.gz: 054cda33811053395720beb1e8a45483cdccc799a08f004037e4a7615ae02937
4
+ data.tar.gz: 0c0fc79dbaf76655e85b7f9db8c7d2d5b60fd593e28b7d1d60a9c6382082dc64
5
5
  SHA512:
6
- metadata.gz: 6c9202365a83879f8df5123ef802d075c4f6dc8ae475a76258035bbecbc9031e8c9fef27c0e4eb343448530d174ef47f8507f1711683918fa4ad2b749f27bfda
7
- data.tar.gz: c0a15038e8064bcd8bcfae0b2f13560a05e86b4d3df96a29a0a77366f985a86640ccc3a65b0d7350bd991fbe46f7c578c565b180ecfccbc572c2a352c90ff262
6
+ metadata.gz: be473c39535e024f1116c43abc52864474c167b59a0f99d68776a6133195af7a7bba19150078497353bf6e3ab8dc92f9ae90f09f6149b90bb183b9602c903307
7
+ data.tar.gz: '08f675b36775db66937b927b22f7c54b55ab0a488a1a37c357dd476fb301aa08516535391a2a442ecf109ee5294d1ca73ee0a93239ea64c4bb50e5aae4a40d17'
data/CHANGELOG.md CHANGED
@@ -9,6 +9,15 @@ and this project aims to adhere to [Semantic Versioning](http://semver.org/spec/
9
9
  ### Added
10
10
  ### Removed
11
11
 
12
+ ## [2.0.1] - 2024-05-21
13
+ ### Changed
14
+ - Remove constraint on sinatra < 3 to allow for newer rack and sinatra
15
+ usages (https://github.com/Betterment/webvalve/pull/65) (thanks @co-vladimir-ya)
16
+
17
+ ## [2.0.0] - 2023-07-20
18
+ ### Added
19
+ - Dynamic URL support via wildcards, Regexps, and Addressable::Templates
20
+
12
21
  ## [1.3.1] - 2023-07-20
13
22
  ### Changed
14
23
  - Replace usage of deprecated `File.exists?` in generator
data/README.md CHANGED
@@ -218,6 +218,43 @@ WebValve.register FakeBank, url: ENV.fetch("SOME_CUSTOM_API_URL")
218
218
  WebValve.register FakeBank, url: "https://some-service.com"
219
219
  ```
220
220
 
221
+ ## Dynamic URLs
222
+
223
+ If the service you are interacting with contains dynamic elements, e.g.
224
+ an instance-specific subdomain, you can specify a wildcard in your url
225
+ with the `*` character to match a series of zero or more characters
226
+ within the same URL segment. For example:
227
+
228
+ ```bash
229
+ export BANK_API_URL=https://*.mybank.com/
230
+ ```
231
+
232
+ or
233
+
234
+ ```ruby
235
+ WebValve.register FakeBank, url: "https://*.mybank.com"
236
+ ```
237
+
238
+ Note: unlike filesystem globbing, `?` isn't respected to mean "exactly
239
+ one character" because it's a URL delimiter character. Only `*` works
240
+ for WebValve URL wildcards.
241
+
242
+ Alternatively you can use `Addressable::Template`s or `Regexp`s to
243
+ specify dynamic URLs if they for some reason aren't a good fit for the
244
+ wildcard syntax. Note that there is no `ENV` var support for these
245
+ formats because there is no detection logic to determine a URL string is
246
+ actually meant to represent a URL template or regexp. For example:
247
+
248
+ ```ruby
249
+ WebValve.register FakeBank, url: Addressable::Template.new("http://mybank.com{/path*}{?query}")
250
+ ```
251
+
252
+ or
253
+
254
+ ```ruby
255
+ WebValve.register FakeBank, url: %r{\Ahttp://mybank.com(/.*)?\z}
256
+ ```
257
+
221
258
  ## What's in a `FakeService`?
222
259
 
223
260
  The definition of `FakeService` is really simple. It's just a
@@ -1,6 +1,7 @@
1
1
  require 'webmock'
2
2
  require 'singleton'
3
3
  require 'set'
4
+ require 'webvalve/service_url_converter'
4
5
 
5
6
  module WebValve
6
7
  ALWAYS_ENABLED_ENVS = %w(development test).freeze
@@ -148,7 +149,7 @@ module WebValve
148
149
  end
149
150
 
150
151
  def url_to_regexp(url)
151
- %r(\A#{Regexp.escape url})
152
+ ServiceUrlConverter.new(url: url).regexp
152
153
  end
153
154
 
154
155
  def ensure_non_duplicate_stub(config)
@@ -0,0 +1,24 @@
1
+ module WebValve
2
+ class ServiceUrlConverter
3
+ TOKEN_BOUNDARY_CHARS = Regexp.escape('.:/?#@&=').freeze
4
+ WILDCARD_SUBSTITUTION = ('[^' + TOKEN_BOUNDARY_CHARS + ']*').freeze
5
+ URL_PREFIX_BOUNDARY = ('[' + TOKEN_BOUNDARY_CHARS + ']').freeze
6
+ URL_SUFFIX_PATTERN = ('((' + URL_PREFIX_BOUNDARY + '|(?<=' + URL_PREFIX_BOUNDARY + ')).*)?\z').freeze
7
+
8
+ attr_reader :url
9
+
10
+ def initialize(url:)
11
+ @url = url
12
+ end
13
+
14
+ def regexp
15
+ if url.is_a?(String)
16
+ regexp_string = Regexp.escape(url)
17
+ substituted_regexp_string = regexp_string.gsub('\*', WILDCARD_SUBSTITUTION)
18
+ %r(\A#{substituted_regexp_string}#{URL_SUFFIX_PATTERN})
19
+ else
20
+ url
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,3 +1,3 @@
1
1
  module WebValve
2
- VERSION = "1.3.1"
2
+ VERSION = "2.0.1"
3
3
  end
data/spec/examples.txt CHANGED
@@ -1,103 +1,100 @@
1
- example_id | status | run_time |
2
- ------------------------------------------------------- | ------- | --------------- |
3
- ./spec/webvalve/fake_service_config_spec.rb[1:1:1] | passed | 0.00004 seconds |
4
- ./spec/webvalve/fake_service_config_spec.rb[1:1:2] | passed | 0.00006 seconds |
5
- ./spec/webvalve/fake_service_config_spec.rb[1:2:1] | passed | 0.00004 seconds |
6
- ./spec/webvalve/fake_service_config_spec.rb[1:2:2] | passed | 0.00006 seconds |
7
- ./spec/webvalve/fake_service_config_spec.rb[1:3:1] | passed | 0.00007 seconds |
8
- ./spec/webvalve/fake_service_config_spec.rb[1:3:2] | passed | 0.0001 seconds |
9
- ./spec/webvalve/fake_service_config_spec.rb[1:3:3] | passed | 0.00005 seconds |
10
- ./spec/webvalve/fake_service_config_spec.rb[1:4:1] | passed | 0.00005 seconds |
11
- ./spec/webvalve/fake_service_config_spec.rb[1:4:2] | passed | 0.00007 seconds |
12
- ./spec/webvalve/fake_service_config_spec.rb[1:4:3] | passed | 0.00006 seconds |
13
- ./spec/webvalve/fake_service_spec.rb[1:1] | passed | 0.00135 seconds |
14
- ./spec/webvalve/fake_service_spec.rb[1:2:1:1] | passed | 0.00098 seconds |
15
- ./spec/webvalve/fake_service_spec.rb[1:2:1:2] | passed | 0.00092 seconds |
16
- ./spec/webvalve/fake_service_spec.rb[1:2:2:1] | passed | 0.00182 seconds |
17
- ./spec/webvalve/fake_service_spec.rb[1:2:2:2] | passed | 0.01508 seconds |
18
- ./spec/webvalve/manager_spec.rb[1:1] | passed | 0.00003 seconds |
19
- ./spec/webvalve/manager_spec.rb[1:2:1] | passed | 0.00085 seconds |
20
- ./spec/webvalve/manager_spec.rb[1:3:1] | passed | 0.0001 seconds |
21
- ./spec/webvalve/manager_spec.rb[1:4:1] | passed | 0.00013 seconds |
22
- ./spec/webvalve/manager_spec.rb[1:5:1:1] | passed | 0.00451 seconds |
23
- ./spec/webvalve/manager_spec.rb[1:5:2:1] | failed | 0.0255 seconds |
24
- ./spec/webvalve/manager_spec.rb[1:5:2:2] | passed | 0.00018 seconds |
25
- ./spec/webvalve/manager_spec.rb[1:5:2:3] | passed | 0.00028 seconds |
26
- ./spec/webvalve/manager_spec.rb[1:5:2:4] | passed | 0.00028 seconds |
27
- ./spec/webvalve/manager_spec.rb[1:5:2:5] | passed | 0.00033 seconds |
28
- ./spec/webvalve/manager_spec.rb[1:5:2:6] | passed | 0.00397 seconds |
29
- ./spec/webvalve/manager_spec.rb[1:5:2:7] | passed | 0.00016 seconds |
30
- ./spec/webvalve/manager_spec.rb[1:5:2:8] | passed | 0.00056 seconds |
31
- ./spec/webvalve/manager_spec.rb[1:5:3:1:1] | passed | 0.00012 seconds |
32
- ./spec/webvalve/manager_spec.rb[1:5:3:2:1] | passed | 0.00024 seconds |
33
- ./spec/webvalve/manager_spec.rb[1:5:3:2:2] | passed | 0.00036 seconds |
34
- ./spec/webvalve/manager_spec.rb[1:5:3:2:3] | passed | 0.00009 seconds |
35
- ./spec/webvalve/manager_spec.rb[1:5:4:1] | passed | 0.00029 seconds |
36
- ./spec/webvalve/manager_spec.rb[1:5:4:2] | passed | 0.00046 seconds |
37
- ./spec/webvalve/manager_spec.rb[1:6:1:1] | passed | 0.00004 seconds |
38
- ./spec/webvalve/manager_spec.rb[1:6:1:2] | passed | 0.00023 seconds |
39
- ./spec/webvalve/manager_spec.rb[1:6:2:1] | passed | 0.00004 seconds |
40
- ./spec/webvalve/manager_spec.rb[1:6:2:2] | passed | 0.00521 seconds |
41
- ./spec/webvalve/manager_spec.rb[1:6:2:3] | passed | 0.00006 seconds |
42
- ./spec/webvalve/manager_spec.rb[1:6:3:1] | passed | 0.00004 seconds |
43
- ./spec/webvalve/manager_spec.rb[1:6:3:2] | passed | 0.00008 seconds |
44
- ./spec/webvalve/manager_spec.rb[1:6:3:3] | passed | 0.00005 seconds |
45
- ./spec/webvalve/manager_spec.rb[1:6:3:4] | passed | 0.00004 seconds |
46
- ./spec/webvalve/manager_spec.rb[1:6:3:5] | passed | 0.00005 seconds |
47
- ./spec/webvalve/manager_spec.rb[1:7:1:1] | passed | 0.00004 seconds |
48
- ./spec/webvalve/manager_spec.rb[1:7:1:2] | passed | 0.0002 seconds |
49
- ./spec/webvalve/manager_spec.rb[1:7:2:1] | passed | 0.00003 seconds |
50
- ./spec/webvalve/manager_spec.rb[1:7:2:2] | passed | 0.0002 seconds |
51
- ./spec/webvalve/manager_spec.rb[1:7:2:3] | passed | 0.00004 seconds |
52
- ./spec/webvalve/manager_spec.rb[1:7:3:1] | passed | 0.00004 seconds |
53
- ./spec/webvalve/manager_spec.rb[1:7:3:2] | passed | 0.00004 seconds |
54
- ./spec/webvalve/manager_spec.rb[1:7:3:3] | passed | 0.00005 seconds |
55
- ./spec/webvalve/manager_spec.rb[1:7:3:4] | passed | 0.00005 seconds |
56
- ./spec/webvalve/manager_spec.rb[1:7:3:5] | passed | 0.00005 seconds |
57
- ./spec/webvalve/manager_spec.rb[1:8:1:1] | passed | 0.00523 seconds |
58
- ./spec/webvalve/manager_spec.rb[1:8:1:2] | passed | 0.00018 seconds |
59
- ./spec/webvalve/manager_spec.rb[1:8:1:3] | unknown | |
60
- ./spec/webvalve/manager_spec.rb[1:8:2:1] | passed | 0.00027 seconds |
61
- ./spec/webvalve/manager_spec.rb[1:8:2:2] | passed | 0.00018 seconds |
62
- ./spec/webvalve/manager_spec.rb[1:8:3:1] | passed | 0.00004 seconds |
63
- ./spec/webvalve/manager_spec.rb[1:8:3:2] | passed | 0.00007 seconds |
64
- ./spec/webvalve/manager_spec.rb[1:8:3:3] | passed | 0.00004 seconds |
65
- ./spec/webvalve/manager_spec.rb[1:8:3:4] | passed | 0.00004 seconds |
66
- ./spec/webvalve/service_url_converter_spec.rb[1:1:1] | unknown | |
67
- ./spec/webvalve/service_url_converter_spec.rb[1:1:2:1] | unknown | |
68
- ./spec/webvalve/service_url_converter_spec.rb[1:1:3:1] | unknown | |
69
- ./spec/webvalve/service_url_converter_spec.rb[1:1:4:1] | unknown | |
70
- ./spec/webvalve/service_url_converter_spec.rb[1:1:5:1] | unknown | |
71
- ./spec/webvalve/service_url_converter_spec.rb[1:1:5:2] | failed | 0.00892 seconds |
72
- ./spec/webvalve/service_url_converter_spec.rb[1:1:5:3] | unknown | |
73
- ./spec/webvalve/service_url_converter_spec.rb[1:1:6:1] | unknown | |
74
- ./spec/webvalve/service_url_converter_spec.rb[1:1:7:1] | unknown | |
75
- ./spec/webvalve/service_url_converter_spec.rb[1:1:7:2] | unknown | |
76
- ./spec/webvalve/service_url_converter_spec.rb[1:1:8:1] | unknown | |
77
- ./spec/webvalve/service_url_converter_spec.rb[1:1:8:2] | unknown | |
78
- ./spec/webvalve/service_url_converter_spec.rb[1:1:8:3] | unknown | |
79
- ./spec/webvalve/service_url_converter_spec.rb[1:1:8:4] | unknown | |
80
- ./spec/webvalve/service_url_converter_spec.rb[1:1:9:1] | unknown | |
81
- ./spec/webvalve/service_url_converter_spec.rb[1:1:9:2] | unknown | |
82
- ./spec/webvalve/service_url_converter_spec.rb[1:1:10:1] | unknown | |
83
- ./spec/webvalve/service_url_converter_spec.rb[1:1:10:2] | unknown | |
84
- ./spec/webvalve/service_url_converter_spec.rb[1:1:11:1] | unknown | |
85
- ./spec/webvalve/service_url_converter_spec.rb[1:1:12:1] | unknown | |
86
- ./spec/webvalve/service_url_converter_spec.rb[1:1:12:2] | unknown | |
87
- ./spec/webvalve/service_url_converter_spec.rb[1:1:13:1] | unknown | |
88
- ./spec/webvalve/service_url_converter_spec.rb[1:1:13:2] | unknown | |
89
- ./spec/webvalve/service_url_converter_spec.rb[1:1:13:3] | unknown | |
90
- ./spec/webvalve/service_url_converter_spec.rb[1:1:14:1] | unknown | |
91
- ./spec/webvalve/service_url_converter_spec.rb[1:1:14:2] | unknown | |
92
- ./spec/webvalve/service_url_converter_spec.rb[1:1:15:1] | unknown | |
93
- ./spec/webvalve/service_url_converter_spec.rb[1:1:15:2] | unknown | |
94
- ./spec/webvalve/service_url_converter_spec.rb[1:1:15:3] | unknown | |
95
- ./spec/webvalve/service_url_converter_spec.rb[1:1:16:1] | unknown | |
96
- ./spec/webvalve/service_url_converter_spec.rb[1:1:16:2] | unknown | |
97
- ./spec/webvalve/service_url_converter_spec.rb[1:1:16:3] | unknown | |
98
- ./spec/webvalve/service_url_converter_spec.rb[1:1:17:1] | unknown | |
99
- ./spec/webvalve/service_url_converter_spec.rb[1:1:17:2] | unknown | |
100
- ./spec/webvalve_spec.rb[1:1] | passed | 0.00003 seconds |
101
- ./spec/webvalve_spec.rb[1:2] | passed | 0.00004 seconds |
102
- ./spec/webvalve_spec.rb[1:3] | passed | 0.00003 seconds |
103
- ./spec/webvalve_spec.rb[1:4] | passed | 0.00067 seconds |
1
+ example_id | status | run_time |
2
+ ------------------------------------------------------- | ------ | --------------- |
3
+ ./spec/webvalve/fake_service_config_spec.rb[1:1:1] | passed | 0.00073 seconds |
4
+ ./spec/webvalve/fake_service_config_spec.rb[1:1:2] | passed | 0.00007 seconds |
5
+ ./spec/webvalve/fake_service_config_spec.rb[1:2:1] | passed | 0.00102 seconds |
6
+ ./spec/webvalve/fake_service_config_spec.rb[1:2:2] | passed | 0.0001 seconds |
7
+ ./spec/webvalve/fake_service_config_spec.rb[1:3:1] | passed | 0.00008 seconds |
8
+ ./spec/webvalve/fake_service_config_spec.rb[1:3:2] | passed | 0.00005 seconds |
9
+ ./spec/webvalve/fake_service_config_spec.rb[1:3:3] | passed | 0.00088 seconds |
10
+ ./spec/webvalve/fake_service_config_spec.rb[1:4:1] | passed | 0.00011 seconds |
11
+ ./spec/webvalve/fake_service_config_spec.rb[1:4:2] | passed | 0.00082 seconds |
12
+ ./spec/webvalve/fake_service_config_spec.rb[1:4:3] | passed | 0.00214 seconds |
13
+ ./spec/webvalve/fake_service_spec.rb[1:1] | passed | 0.00149 seconds |
14
+ ./spec/webvalve/fake_service_spec.rb[1:2:1:1] | passed | 0.00077 seconds |
15
+ ./spec/webvalve/fake_service_spec.rb[1:2:1:2] | passed | 0.00067 seconds |
16
+ ./spec/webvalve/fake_service_spec.rb[1:2:2:1] | passed | 0.00893 seconds |
17
+ ./spec/webvalve/fake_service_spec.rb[1:2:2:2] | passed | 0.00762 seconds |
18
+ ./spec/webvalve/manager_spec.rb[1:1] | passed | 0.00006 seconds |
19
+ ./spec/webvalve/manager_spec.rb[1:2:1] | passed | 0.00303 seconds |
20
+ ./spec/webvalve/manager_spec.rb[1:3:1] | passed | 0.00008 seconds |
21
+ ./spec/webvalve/manager_spec.rb[1:4:1] | passed | 0.00053 seconds |
22
+ ./spec/webvalve/manager_spec.rb[1:5:1:1] | passed | 0.00011 seconds |
23
+ ./spec/webvalve/manager_spec.rb[1:5:2:1] | passed | 0.0001 seconds |
24
+ ./spec/webvalve/manager_spec.rb[1:5:2:2] | passed | 0.00024 seconds |
25
+ ./spec/webvalve/manager_spec.rb[1:5:2:3] | passed | 0.00018 seconds |
26
+ ./spec/webvalve/manager_spec.rb[1:5:2:4] | passed | 0.0003 seconds |
27
+ ./spec/webvalve/manager_spec.rb[1:5:2:5] | passed | 0.00025 seconds |
28
+ ./spec/webvalve/manager_spec.rb[1:5:2:6] | passed | 0.00017 seconds |
29
+ ./spec/webvalve/manager_spec.rb[1:5:2:7] | passed | 0.00014 seconds |
30
+ ./spec/webvalve/manager_spec.rb[1:5:2:8] | passed | 0.00037 seconds |
31
+ ./spec/webvalve/manager_spec.rb[1:5:3:1:1] | passed | 0.00012 seconds |
32
+ ./spec/webvalve/manager_spec.rb[1:5:3:2:1] | passed | 0.0003 seconds |
33
+ ./spec/webvalve/manager_spec.rb[1:5:3:2:2] | passed | 0.00045 seconds |
34
+ ./spec/webvalve/manager_spec.rb[1:5:3:2:3] | passed | 0.00117 seconds |
35
+ ./spec/webvalve/manager_spec.rb[1:5:4:1] | passed | 0.00018 seconds |
36
+ ./spec/webvalve/manager_spec.rb[1:5:4:2] | passed | 0.00046 seconds |
37
+ ./spec/webvalve/manager_spec.rb[1:6:1:1] | passed | 0.00004 seconds |
38
+ ./spec/webvalve/manager_spec.rb[1:6:1:2] | passed | 0.00013 seconds |
39
+ ./spec/webvalve/manager_spec.rb[1:6:2:1] | passed | 0.00004 seconds |
40
+ ./spec/webvalve/manager_spec.rb[1:6:2:2] | passed | 0.00017 seconds |
41
+ ./spec/webvalve/manager_spec.rb[1:6:2:3] | passed | 0.00004 seconds |
42
+ ./spec/webvalve/manager_spec.rb[1:6:3:1] | passed | 0.00003 seconds |
43
+ ./spec/webvalve/manager_spec.rb[1:6:3:2] | passed | 0.00005 seconds |
44
+ ./spec/webvalve/manager_spec.rb[1:6:3:3] | passed | 0.00005 seconds |
45
+ ./spec/webvalve/manager_spec.rb[1:6:3:4] | passed | 0.00004 seconds |
46
+ ./spec/webvalve/manager_spec.rb[1:6:3:5] | passed | 0.00005 seconds |
47
+ ./spec/webvalve/manager_spec.rb[1:7:1:1] | passed | 0.00006 seconds |
48
+ ./spec/webvalve/manager_spec.rb[1:7:1:2] | passed | 0.004 seconds |
49
+ ./spec/webvalve/manager_spec.rb[1:7:2:1] | passed | 0.00005 seconds |
50
+ ./spec/webvalve/manager_spec.rb[1:7:2:2] | passed | 0.00015 seconds |
51
+ ./spec/webvalve/manager_spec.rb[1:7:2:3] | passed | 0.00007 seconds |
52
+ ./spec/webvalve/manager_spec.rb[1:7:3:1] | passed | 0.00003 seconds |
53
+ ./spec/webvalve/manager_spec.rb[1:7:3:2] | passed | 0.00006 seconds |
54
+ ./spec/webvalve/manager_spec.rb[1:7:3:3] | passed | 0.00005 seconds |
55
+ ./spec/webvalve/manager_spec.rb[1:7:3:4] | passed | 0.00005 seconds |
56
+ ./spec/webvalve/manager_spec.rb[1:7:3:5] | passed | 0.00005 seconds |
57
+ ./spec/webvalve/manager_spec.rb[1:8:1:1] | passed | 0.00004 seconds |
58
+ ./spec/webvalve/manager_spec.rb[1:8:1:2] | passed | 0.00013 seconds |
59
+ ./spec/webvalve/manager_spec.rb[1:8:2:1] | passed | 0.00004 seconds |
60
+ ./spec/webvalve/manager_spec.rb[1:8:2:2] | passed | 0.00014 seconds |
61
+ ./spec/webvalve/manager_spec.rb[1:8:3:1] | passed | 0.00005 seconds |
62
+ ./spec/webvalve/manager_spec.rb[1:8:3:2] | passed | 0.00004 seconds |
63
+ ./spec/webvalve/manager_spec.rb[1:8:3:3] | passed | 0.00004 seconds |
64
+ ./spec/webvalve/manager_spec.rb[1:8:3:4] | passed | 0.00004 seconds |
65
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:1] | passed | 0.0003 seconds |
66
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:2:1] | passed | 0.00043 seconds |
67
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:3:1] | passed | 0.00004 seconds |
68
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:3:2] | passed | 0.00008 seconds |
69
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:3:3] | passed | 0.00004 seconds |
70
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:4:1] | passed | 0.00088 seconds |
71
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:5:1] | passed | 0.00004 seconds |
72
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:5:2] | passed | 0.00004 seconds |
73
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:6:1] | passed | 0.0008 seconds |
74
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:6:2] | passed | 0.00004 seconds |
75
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:6:3] | passed | 0.00081 seconds |
76
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:6:4] | passed | 0.00004 seconds |
77
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:7:1] | passed | 0.00004 seconds |
78
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:7:2] | passed | 0.00004 seconds |
79
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:7:3] | passed | 0.00112 seconds |
80
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:8:1] | passed | 0.00066 seconds |
81
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:8:2] | passed | 0.00005 seconds |
82
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:9:1] | passed | 0.00004 seconds |
83
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:10:1] | passed | 0.00004 seconds |
84
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:10:2] | passed | 0.00005 seconds |
85
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:11:1] | passed | 0.00004 seconds |
86
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:11:2] | passed | 0.00004 seconds |
87
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:11:3] | passed | 0.00004 seconds |
88
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:12:1] | passed | 0.00006 seconds |
89
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:12:2] | passed | 0.00005 seconds |
90
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:13:1] | passed | 0.00009 seconds |
91
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:13:2] | passed | 0.00034 seconds |
92
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:13:3] | passed | 0.00004 seconds |
93
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:14:1] | passed | 0.00005 seconds |
94
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:14:2] | passed | 0.00004 seconds |
95
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:15:1] | passed | 0.00003 seconds |
96
+ ./spec/webvalve/service_url_converter_spec.rb[1:1:15:2] | passed | 0.00004 seconds |
97
+ ./spec/webvalve_spec.rb[1:1] | passed | 0.00065 seconds |
98
+ ./spec/webvalve_spec.rb[1:2] | passed | 0.00003 seconds |
99
+ ./spec/webvalve_spec.rb[1:3] | passed | 0.00004 seconds |
100
+ ./spec/webvalve_spec.rb[1:4] | passed | 0.00005 seconds |
@@ -38,6 +38,9 @@ RSpec.describe WebValve::Manager do
38
38
  end
39
39
 
40
40
  describe '#setup' do
41
+ let(:wildcard_substitution) { WebValve::ServiceUrlConverter::WILDCARD_SUBSTITUTION }
42
+ let(:url_suffix_pattern) { WebValve::ServiceUrlConverter::URL_SUFFIX_PATTERN }
43
+
41
44
  context 'when WebValve is disabled' do
42
45
  around do |ex|
43
46
  with_rails_env 'production' do
@@ -94,10 +97,17 @@ RSpec.describe WebValve::Manager do
94
97
 
95
98
  it 'allowlists configured urls in webmock' do
96
99
  allow(WebMock).to receive(:disable_net_connect!)
97
- results = [%r{\Ahttp://foo\.dev}, %r{\Ahttp://bar\.dev}]
100
+ results = [
101
+ %r{\Ahttp://foo\.dev#{url_suffix_pattern}},
102
+ %r{\Ahttp://bar\.dev#{url_suffix_pattern}},
103
+ %r{\Ahttp://bar\.#{wildcard_substitution}\.dev#{url_suffix_pattern}},
104
+ %r{\Ahttp://bar\.dev/\?foo=bar#{url_suffix_pattern}}
105
+ ]
98
106
 
99
107
  subject.allow_url 'http://foo.dev'
100
108
  subject.allow_url 'http://bar.dev'
109
+ subject.allow_url 'http://bar.*.dev'
110
+ subject.allow_url 'http://bar.dev/?foo=bar'
101
111
 
102
112
  subject.setup
103
113
 
@@ -115,7 +125,7 @@ RSpec.describe WebValve::Manager do
115
125
  subject.setup
116
126
  end
117
127
 
118
- expect(WebMock).to have_received(:stub_request).with(:any, %r{\Ahttp://something\.dev})
128
+ expect(WebMock).to have_received(:stub_request).with(:any, %r{\Ahttp://something\.dev#{url_suffix_pattern}})
119
129
  expect(web_mock_stubble).to have_received(:to_rack)
120
130
  end
121
131
 
@@ -153,7 +163,7 @@ RSpec.describe WebValve::Manager do
153
163
  subject.register other_disabled_service.name
154
164
 
155
165
  expect { subject.setup }.to_not raise_error
156
- expect(WebMock).to have_received(:stub_request).with(:any, %r{\Ahttp://something\.dev}).twice
166
+ expect(WebMock).to have_received(:stub_request).with(:any, %r{\Ahttp://something\.dev#{url_suffix_pattern}}).twice
157
167
  end
158
168
  end
159
169
  end
@@ -208,8 +218,8 @@ RSpec.describe WebValve::Manager do
208
218
  subject.setup
209
219
  end
210
220
 
211
- expect(WebMock).to have_received(:stub_request).with(:any, %r{\Ahttp://something\.dev})
212
- expect(WebMock).not_to have_received(:stub_request).with(:any, %r{\Ahttp://other\.dev})
221
+ expect(WebMock).to have_received(:stub_request).with(:any, %r{\Ahttp://something\.dev#{url_suffix_pattern}})
222
+ expect(WebMock).not_to have_received(:stub_request).with(:any, %r{\Ahttp://other\.dev#{url_suffix_pattern}})
213
223
  expect(web_mock_stubble).to have_received(:to_rack).once
214
224
  end
215
225
 
@@ -261,9 +271,9 @@ RSpec.describe WebValve::Manager do
261
271
  subject.setup
262
272
  end
263
273
 
264
- expect(WebMock).to have_received(:stub_request).with(:any, %r{\Ahttp://something\.dev})
265
- expect(WebMock).to have_received(:stub_request).with(:any, %r{\Ahttp://something\-else\.dev})
266
- expect(WebMock).to have_received(:stub_request).with(:any, %r{\Ahttp://other\.dev})
274
+ expect(WebMock).to have_received(:stub_request).with(:any, %r{\Ahttp://something\.dev#{url_suffix_pattern}})
275
+ expect(WebMock).to have_received(:stub_request).with(:any, %r{\Ahttp://something\-else\.dev#{url_suffix_pattern}})
276
+ expect(WebMock).to have_received(:stub_request).with(:any, %r{\Ahttp://other\.dev#{url_suffix_pattern}})
267
277
  expect(web_mock_stubble).to have_received(:to_rack).exactly(3).times
268
278
  end
269
279
  end
@@ -0,0 +1,194 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe WebValve::ServiceUrlConverter do
4
+ let(:url) { "http://bar.com" }
5
+
6
+ subject { described_class.new(url: url) }
7
+
8
+ describe '#regexp' do
9
+ it "returns a regexp" do
10
+ expect(subject.regexp).to be_a(Regexp)
11
+ end
12
+
13
+ context "with a regexp" do
14
+ let(:url) { %r{\Ahttp://foo\.com} }
15
+
16
+ it "returns the same object" do
17
+ expect(subject.regexp).to be_a(Regexp)
18
+ expect(subject.regexp).to equal(url)
19
+ end
20
+ end
21
+
22
+ context "with an empty url" do
23
+ let(:url) { "" }
24
+
25
+ it "matches empty string" do
26
+ expect("").to match(subject.regexp)
27
+ end
28
+
29
+ it "matches a string starting with a URL delimiter because the rest is just interpreted as suffix" do
30
+ expect(":do:do:dodo:do:do").to match(subject.regexp)
31
+ end
32
+
33
+ it "doesn't match a string that doesn't start with a delimiter" do
34
+ expect("jamietart:do:do:dodo:do:do").not_to match(subject.regexp)
35
+ end
36
+ end
37
+
38
+ context "with a boundary char on the end" do
39
+ let(:url) { "http://bar.com/" }
40
+
41
+ it "matches arbitrary suffixes" do
42
+ expect("http://bar.com/baz/bump/beep").to match(subject.regexp)
43
+ end
44
+ end
45
+
46
+ context "with multiple asterisks" do
47
+ let(:url) { "http://bar.com/**/bump" }
48
+
49
+ it "matches like a single asterisk" do
50
+ expect("http://bar.com/foo/bump").to match(subject.regexp)
51
+ end
52
+
53
+ it "doesn't match like a filesystem glob" do
54
+ expect("http://bar.com/foo/bar/bump").not_to match(subject.regexp)
55
+ end
56
+ end
57
+
58
+ context "with a trailing *" do
59
+ let(:url) { "http://bar.com/*" }
60
+
61
+ it "matches when empty" do
62
+ expect("http://bar.com/").to match(subject.regexp)
63
+ end
64
+
65
+ it "matches when existing" do
66
+ expect("http://bar.com/foobaloo").to match(subject.regexp)
67
+ end
68
+
69
+ it "matches with additional tokens" do
70
+ expect("http://bar.com/foobaloo/wink").to match(subject.regexp)
71
+ end
72
+
73
+ it "doesn't match when missing the trailing slash tho" do
74
+ expect("http://bar.com").not_to match(subject.regexp)
75
+ end
76
+ end
77
+
78
+ context "with a totally wildcarded protocol" do
79
+ let(:url) { "*://bar.com" }
80
+
81
+ it "matches http" do
82
+ expect("http://bar.com/").to match(subject.regexp)
83
+ end
84
+
85
+ it "matches anything else" do
86
+ expect("gopher://bar.com/").to match(subject.regexp)
87
+ end
88
+
89
+ it "matches empty" do
90
+ expect("://bar.com").to match(subject.regexp)
91
+ end
92
+ end
93
+
94
+ context "with a wildcarded partial protocol" do
95
+ let(:url) { "http*://bar.com" }
96
+
97
+ it "matches empty" do
98
+ expect("http://bar.com/").to match(subject.regexp)
99
+ end
100
+
101
+ it "matches full" do
102
+ expect("https://bar.com/").to match(subject.regexp)
103
+ end
104
+ end
105
+
106
+ context "with a TLD that is a substring of another TLD" do
107
+ let(:url) { "http://bar.co" }
108
+
109
+ it "doesn't match a different TLD when extending" do
110
+ expect("http://bar.com").not_to match(subject.regexp)
111
+ end
112
+ end
113
+
114
+ context "with a wildcard subdomain" do
115
+ let(:url) { "http://*.bar.com" }
116
+
117
+ it "matches" do
118
+ expect("http://foo.bar.com").to match(subject.regexp)
119
+ end
120
+
121
+ it "doesn't match when too many subdomains" do
122
+ expect("http://beep.foo.bar.com").not_to match(subject.regexp)
123
+ end
124
+ end
125
+
126
+ context "with a partial postfix wildcard subdomain" do
127
+ let(:url) { "http://foo*.bar.com" }
128
+
129
+ it "matches when present" do
130
+ expect("http://foobaz.bar.com").to match(subject.regexp)
131
+ end
132
+
133
+ it "matches when empty" do
134
+ expect("http://foo.bar.com").to match(subject.regexp)
135
+ end
136
+
137
+ it "doesn't match when out of order" do
138
+ expect("http://bazfoo.bar.com").not_to match(subject.regexp)
139
+ end
140
+ end
141
+
142
+ context "with a partial prefix wildcard subdomain" do
143
+ let(:url) { "http://*baz.bar.com" }
144
+
145
+ it "matches when present" do
146
+ expect("http://foobaz.bar.com").to match(subject.regexp)
147
+ end
148
+
149
+ it "matches when empty" do
150
+ expect("http://baz.bar.com").to match(subject.regexp)
151
+ end
152
+ end
153
+
154
+ context "with a wildcarded basic auth url" do
155
+ let(:url) { "http://*:*@bar.com" }
156
+
157
+ it "matches when present" do
158
+ expect("http://bilbo:baggins@bar.com").to match(subject.regexp)
159
+ end
160
+
161
+ it "doesn't match when malformed" do
162
+ expect("http://bilbobaggins@bar.com").not_to match(subject.regexp)
163
+ end
164
+
165
+ it "doesn't match when missing password part" do
166
+ expect("http://bilbo@bar.com").not_to match(subject.regexp)
167
+ end
168
+ end
169
+
170
+ context "with a wildcarded path" do
171
+ let(:url) { "http://bar.com/*/whatever" }
172
+
173
+ it "matches with arbitrarily spicy but legal, non-URL-significant characters" do
174
+ expect("http://bar.com/a0-_~[]!$'(),;%+/whatever").to match(subject.regexp)
175
+ end
176
+
177
+ it "doesn't match when you throw a URL-significant char in there" do
178
+ expect("http://bar.com/life=love/whatever").not_to match(subject.regexp)
179
+ end
180
+ end
181
+
182
+ context "with a wildcarded query param" do
183
+ let(:url) { "http://bar.com/whatever?foo=*&bar=bump" }
184
+
185
+ it "matches when present" do
186
+ expect("http://bar.com/whatever?foo=baz&bar=bump").to match(subject.regexp)
187
+ end
188
+
189
+ it "doesn't match when you throw a URL-significant char in there" do
190
+ expect("http://bar.com/whatever?foo=baz#&bar=bump").not_to match(subject.regexp)
191
+ end
192
+ end
193
+ end
194
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webvalve
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Moore
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-20 00:00:00.000000000 Z
11
+ date: 2024-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -31,9 +31,6 @@ dependencies:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.4'
34
- - - "<"
35
- - !ruby/object:Gem::Version
36
- version: '3'
37
34
  type: :runtime
38
35
  prerelease: false
39
36
  version_requirements: !ruby/object:Gem::Requirement
@@ -41,9 +38,6 @@ dependencies:
41
38
  - - ">="
42
39
  - !ruby/object:Gem::Version
43
40
  version: '1.4'
44
- - - "<"
45
- - !ruby/object:Gem::Version
46
- version: '3'
47
41
  - !ruby/object:Gem::Dependency
48
42
  name: sinatra-contrib
49
43
  requirement: !ruby/object:Gem::Requirement
@@ -51,9 +45,6 @@ dependencies:
51
45
  - - ">="
52
46
  - !ruby/object:Gem::Version
53
47
  version: '1.4'
54
- - - "<"
55
- - !ruby/object:Gem::Version
56
- version: '3'
57
48
  type: :runtime
58
49
  prerelease: false
59
50
  version_requirements: !ruby/object:Gem::Requirement
@@ -61,9 +52,6 @@ dependencies:
61
52
  - - ">="
62
53
  - !ruby/object:Gem::Version
63
54
  version: '1.4'
64
- - - "<"
65
- - !ruby/object:Gem::Version
66
- version: '3'
67
55
  - !ruby/object:Gem::Dependency
68
56
  name: webmock
69
57
  requirement: !ruby/object:Gem::Requirement
@@ -173,6 +161,7 @@ files:
173
161
  - lib/webvalve/monkey_patches.rb
174
162
  - lib/webvalve/railtie.rb
175
163
  - lib/webvalve/rspec.rb
164
+ - lib/webvalve/service_url_converter.rb
176
165
  - lib/webvalve/version.rb
177
166
  - spec/dummy/config/application.rb
178
167
  - spec/examples.txt
@@ -182,13 +171,28 @@ files:
182
171
  - spec/webvalve/fake_service_config_spec.rb
183
172
  - spec/webvalve/fake_service_spec.rb
184
173
  - spec/webvalve/manager_spec.rb
174
+ - spec/webvalve/service_url_converter_spec.rb
185
175
  - spec/webvalve_spec.rb
186
176
  homepage: https://github.com/Betterment/webvalve
187
177
  licenses:
188
178
  - MIT
189
179
  metadata:
190
180
  rubygems_mfa_required: 'true'
191
- post_install_message:
181
+ post_install_message: |
182
+ Thanks for installing WebValve!
183
+
184
+ Note for upgraders: If you're upgrading from a version less than 2.0, service
185
+ URL behavior has changed. Please verify that your app isn't relying on the
186
+ previous behavior:
187
+
188
+ 1. `*` characters are now interpreted as wildcards, enabling dynamic URL
189
+ segments. In the unlikely event that your URLs use `*` literals, you'll need
190
+ to URL encode them (`%2A`) both in your URL spec and at runtime.
191
+
192
+ 2. URL suffix matching is now strict. For example, `BAR_URL=http://bar.co` will
193
+ no longer match `https://bar.com`, but it will match `http://bar.co/foo`. If
194
+ you need to preserve the previous behavior, you can add a trailing `*` to
195
+ your URL spec, e.g. `BAR_URL=http://bar.co*`.
192
196
  rdoc_options: []
193
197
  require_paths:
194
198
  - lib
@@ -203,7 +207,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
203
207
  - !ruby/object:Gem::Version
204
208
  version: '0'
205
209
  requirements: []
206
- rubygems_version: 3.4.17
210
+ rubygems_version: 3.4.10
207
211
  signing_key:
208
212
  specification_version: 4
209
213
  summary: A library for faking http service integrations in development and test
@@ -216,4 +220,5 @@ test_files:
216
220
  - spec/webvalve/fake_service_config_spec.rb
217
221
  - spec/webvalve/fake_service_spec.rb
218
222
  - spec/webvalve/manager_spec.rb
223
+ - spec/webvalve/service_url_converter_spec.rb
219
224
  - spec/webvalve_spec.rb