1# frozen_string_literal: true
2
3require "simplecov"
4SimpleCov.start do
5 add_filter "/test/"
6 enable_coverage :branch
7 command_name ENV.fetch("COVERAGE_NAME", "tests")
8end
9
10require "minitest/autorun"
11require "webmock/minitest"
12
13MMS_PROXY = "https://proxy.test.example.com/"
14
15_saved_argv = ARGV.dup
16
17ARGV[0] = "component"
18ARGV[6] = MMS_PROXY
19
20require_relative "../sgx-bwmsgsv2"
21ARGV.replace(_saved_argv)
22
23def SGXbwmsgsv2.write_to_stream(s)
24 @written ||= []
25 @written << s
26end
27
28def reset_stanzas!
29 SGXbwmsgsv2.instance_variable_set(:@written, [])
30end
31
32def reset_redis!
33 REDIS.reset!
34 REDIS.set("catapult_jid-", "HERE")
35 REDIS.set("catapult_jid-+15550000000", "test@example.com")
36 REDIS.set("catapult_cred-test@example.com", [
37 'account', 'user', 'password', '+15550000000'
38 ])
39end
40
41def written
42 SGXbwmsgsv2.instance_variable_get(:@written)
43end
44
45def invoke_webhook(payload, extra_env: {})
46 with_stubs([
47 [
48 SGXbwmsgsv2,
49 :write,
50 ->(data) { SGXbwmsgsv2.write_to_stream(data) }
51 ]
52 ]) do
53 handler = WebhookHandler.new
54 env = {
55 "REQUEST_URI" => "/",
56 "REQUEST_METHOD" => "POST",
57 "params" => { "_json" => [payload] }
58 }.merge(extra_env)
59 handler.instance_variable_set(:@env, env)
60 def handler.params
61 @env["params"]
62 end
63 EMPromise.resolve(nil).then {
64 handler.response(env)
65 }.sync
66 end
67end
68
69begin
70 require "pry-byebug"
71
72 module Minitest
73 class Test
74 alias old_capture_exceptions capture_exceptions
75 def capture_exceptions
76 old_capture_exceptions do
77 yield
78 rescue Minitest::Skip => e
79 failures << e
80 end
81 end
82 end
83 end
84rescue LoadError, NameError
85 # Just helpers for dev, no big deal if missing
86 nil
87end
88
89
90$VERBOSE = nil
91
92class FakeRedis
93 def initialize(values={})
94 @values = values
95 end
96
97 def reset!(values={})
98 @values = values
99 end
100
101 def set(key, value, *)
102 @values[key] = value
103 EMPromise.resolve("OK")
104 end
105
106 def setex(key, _expiry, value)
107 set(key, value)
108 end
109
110 def del(*keys)
111 keys.each { |key| @values.delete(key) }
112 end
113
114 def mget(*keys)
115 EMPromise.all(keys.map(&method(:get)))
116 end
117
118 def get(key)
119 EMPromise.resolve(@values[key])
120 end
121
122 def getbit(key, bit)
123 get(key).then { |v| v.to_i.to_s(2)[bit].to_i }
124 end
125
126 def bitfield(key, *ops)
127 get(key).then do |v|
128 bits = v.to_i.to_s(2)
129 ops.each_slice(3).map do |(op, encoding, offset)|
130 raise "unsupported bitfield op" unless op == "GET"
131 raise "unsupported bitfield op" unless encoding == "u1"
132
133 bits[offset].to_i
134 end
135 end
136 end
137
138 def hget(key, field)
139 @values.dig(key, field)
140 end
141
142 def hincrby(key, field, incrby)
143 @values[key] ||= {}
144 @values[key][field] ||= 0
145 @values[key][field] += incrby
146 end
147
148 def sadd(key, member)
149 @values[key] ||= Set.new
150 @values[key] << member
151 end
152
153 def srem(key, member)
154 @values[key].delete(member)
155 end
156
157 def scard(key)
158 @values[key]&.size || 0
159 end
160
161 def expire(_, _); end
162
163 def exists(*keys)
164 EMPromise.resolve(
165 @values.select { |k, _| keys.include? k }.size.to_s
166 )
167 end
168
169 def lindex(key, index)
170 get(key).then { |v| v&.fetch(index) }
171 end
172
173 def lrange(key, sindex, eindex)
174 get(key).then { |v| v ? v[sindex..eindex] : [] }
175 end
176
177 def rpush(key, *values)
178 @values[key] ||= []
179 values.each { |v| @values[key].push(v) }
180 end
181
182 def multi
183 end
184
185 def exec
186 end
187
188 def discard
189 end
190
191 def xadd(stream, id, *args)
192 @values[stream] ||= []
193 entry_id = id == "*" ? "#{Time.now.to_i}-0" : id
194 fields = Hash[*args]
195 @values[stream] << { id: entry_id, fields: fields }
196 EMPromise.resolve(entry_id)
197 end
198
199 def stream_entries(stream)
200 EMPromise.resolve(@values[stream] || [])
201 end
202end
203
204REDIS = FakeRedis.new
205
206module Minitest
207 class Test
208 def with_stubs(stubs, &block)
209 if stubs.empty?
210 block.call
211 else
212 obj, method, value = stubs.first
213 obj.stub(method, value) do
214 with_stubs(stubs[1..], &block)
215 end
216 end
217 end
218
219 def self.em(m)
220 alias_method "raw_#{m}", m
221 define_method(m) do
222 $panic = nil
223 e = nil
224 EM.run do
225 Fiber.new {
226 ARGV[0] = "component"
227 ARGV[6] = MMS_PROXY
228 begin
229 send("raw_#{m}")
230 rescue
231 e = $!
232 ensure
233 EM.stop
234 end
235 }.resume
236 end
237 raise e if e
238 end
239 end
240 end
241end