webvalve 1.3.1 → 2.0.1

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 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