1# frozen_string_literal: true
2
3require "test_helper"
4require "admin_command"
5
6BackendSgx::IQ_MANAGER = Minitest::Mock.new
7AdminAction::LaunchSnikket::IQ_MANAGER = Minitest::Mock.new
8Customer::BLATHER = Minitest::Mock.new
9AdminActionRepo::REDIS = Minitest::Mock.new
10TrivialBackendSgxRepo::REDIS = Minitest::Mock.new
11BandwidthTnRepo::DB = Minitest::Mock.new
12
13class AdminCommandTest < Minitest::Test
14 def admin_command(tel="+15556667777")
15 sgx = Minitest::Mock.new(OpenStruct.new(
16 registered?: OpenStruct.new(phone: tel)
17 ))
18 [
19 sgx,
20 AdminCommand.new(
21 customer(sgx: sgx),
22 CustomerRepo.new(db: FakeDB.new),
23 AdminActionRepo.new,
24 Snikket::Repo.new(db: FakeDB.new)
25 )
26 ]
27 end
28
29 def test_no_user
30 q_form = Blather::Stanza::Iq::Command.new
31 q_form.action = :complete
32 q_form.form.fields = [
33 { var: "q", value: "testuser" }
34 ]
35
36 customer_repo = Minitest::Mock.new
37
38 result = execute_command {
39 customer_repo.expect(
40 :find_by_format,
41 EMPromise.resolve(OpenStruct.new(
42 customer_id: "testuser",
43 billing_customer_id: "testuser",
44 balance: 0.to_d,
45 jid: Blather::JID.new("test@example.com"),
46 tndetails: {}
47 )),
48 ["testuser"]
49 )
50
51 customer_repo.expect(
52 :find_by_format,
53 EMPromise.resolve(nil),
54 [Blather::JID]
55 )
56
57 customer_repo.expect(
58 :find_by_format,
59 EMPromise.resolve(nil),
60 [ProxiedJID]
61 )
62
63 TrivialBackendSgxRepo::REDIS.expect(
64 :get,
65 EMPromise.resolve(nil),
66 ["jmp_customer_backend_sgx-testuser"]
67 )
68
69 TrustLevelRepo::REDIS.expect(
70 :get,
71 EMPromise.resolve("Customer"),
72 ["jmp_customer_trust_level-testuser"]
73 )
74
75 TrustLevelRepo::DB.expect(
76 :query_one,
77 EMPromise.resolve({ settled_amount: 0 }),
78 [String, "testuser"], default: {}
79 )
80
81 Subaccount::DB.expect(
82 :query_defer,
83 EMPromise.resolve([]),
84 [String, ["testuser"]]
85 )
86
87 Command::COMMAND_MANAGER.expect(
88 :write,
89 EMPromise.resolve(q_form),
90 [Matching.new do |iq|
91 assert_equal :form, iq.form.type
92 assert iq.form.field("q")
93 end]
94 )
95
96 AdminCommand.for(nil, customer_repo).start.catch { |e| e }
97 }
98
99 assert result.stanza.completed?
100 assert_mock customer_repo
101 assert_mock Command::COMMAND_MANAGER
102 assert_mock TrustLevelRepo::REDIS
103 assert_mock Subaccount::DB
104 assert_mock TrivialBackendSgxRepo::REDIS
105 end
106 em :test_no_user
107
108 def test_action_launch_snikket
109 sgx, admin = admin_command
110 domain_form = Blather::Stanza::Iq::Command.new
111 domain_form.form.fields = [
112 { var: "domain", value: "test.snikket.chat" }
113 ]
114
115 launched = Snikket::Launched.new
116 launched << Niceogiri::XML::Node.new(
117 :launched, launched.document, "xmpp:snikket.org/hosting/v1"
118 ).tap { |inner|
119 inner << Niceogiri::XML::Node.new(
120 :'instance-id', launched.document, "xmpp:snikket.org/hosting/v1"
121 ).tap { |id|
122 id.content = "si-1234"
123 }
124 inner << Niceogiri::XML::Node.new(
125 :bootstrap, launched.document, "xmpp:snikket.org/hosting/v1"
126 ).tap { |bootstrap|
127 bootstrap << Niceogiri::XML::Node.new(
128 :token, launched.document, "xmpp:snikket.org/hosting/v1"
129 ).tap { |token|
130 token.content = "TOKEN"
131 }
132 }
133 }
134
135 result = execute_command {
136 Command::COMMAND_MANAGER.expect(
137 :write,
138 EMPromise.resolve(domain_form),
139 [Matching.new do |iq|
140 assert_equal :form, iq.form.type
141 assert iq.form.field("domain")
142 end]
143 )
144 Command::COMMAND_MANAGER.expect(
145 :write,
146 EMPromise.reject(:test_result),
147 [Matching.new do |iq|
148 assert :result, iq.type
149 assert(
150 "https://test.snikket.chat/invites_bootstrap?token=TOKEN",
151 iq.form.field("bootstrap-uri").value
152 )
153 end]
154 )
155
156 AdminAction::LaunchSnikket::IQ_MANAGER.expect(
157 :write,
158 EMPromise.resolve(launched),
159 [Matching.new do |iq|
160 assert_equal :set, iq.type
161 assert_equal CONFIG[:snikket_hosting_api], iq.to.to_s
162 assert_equal(
163 "test.snikket.chat",
164 iq.xpath(
165 "./ns:launch/ns:domain",
166 ns: "xmpp:snikket.org/hosting/v1"
167 ).text
168 )
169 end]
170 )
171
172 admin.action_launch_snikket.catch { |e| e }
173 }
174
175 assert_equal :test_result, result
176 assert_mock sgx
177 assert_mock AdminAction::LaunchSnikket::IQ_MANAGER
178 assert_mock Customer::BLATHER
179 end
180 em :test_action_launch_snikket
181
182 def test_action_cancel_account
183 req = stub_request(:post, "https://api.churnbuster.io/v1/cancellations")
184 .with(
185 body: {
186 customer: {
187 source: "braintree",
188 source_id: "test",
189 email: "test@smtp.cheogram.com",
190 properties: {}
191 },
192 subscription: {
193 source: "braintree",
194 source_id: "test"
195 }
196 }.to_json
197 )
198 .to_return(status: 200, body: "", headers: {})
199
200 sgx, admin = admin_command
201
202 Customer::BLATHER.expect(
203 :<<,
204 EMPromise.resolve(nil),
205 [
206 Matching.new do |m|
207 assert_equal "Your JMP account has been cancelled.", m.body
208 assert_equal "test@example.net", m.to.to_s
209 assert_equal "notify_from@component", m.from.to_s
210 end
211 ]
212 )
213
214 Customer::BLATHER.expect(
215 :<<,
216 EMPromise.resolve(nil),
217 [
218 Matching.new do |iq|
219 assert iq.remove?
220 assert_equal "test@example.net", iq.to.to_s
221 assert_equal "component", iq.from.to_s
222 end
223 ]
224 )
225
226 sgx.expect(:deregister!, EMPromise.resolve(nil))
227
228 stub_request(
229 :post,
230 "https://dashboard.bandwidth.com/v1.0/accounts//disconnects"
231 ).with(
232 body: {
233 name: "test",
234 DisconnectTelephoneNumberOrderType: {
235 TelephoneNumberList: {
236 TelephoneNumber: "5556667777"
237 }
238 }
239 }.to_xml(indent: 0, root: "DisconnectTelephoneNumberOrder")
240 ).to_return(status: 200, body: "")
241
242 admin.action_cancel_account.sync
243
244 assert_mock sgx
245 assert_mock BackendSgx::IQ_MANAGER
246 assert_mock Customer::BLATHER
247 assert_requested req
248 end
249 em :test_action_cancel_account
250
251 def test_action_cancel_account_keep_number
252 rate_center_response = {
253 "TelephoneNumberDetails": {
254 City: "MANHATTAN",
255 State: "NY",
256 RateCenter: "NWYRCYZN01"
257 }
258 }.to_xml(indent: 0, root: "TelephoneNumberResponse")
259
260 bandwidth_req = stub_request(
261 :get,
262 "https://dashboard.bandwidth.com/v1.0/tns/5566667777/ratecenter"
263 )
264 .with(
265 headers: {
266 "Accept" => "application/xml",
267 "Accept-Encoding" => "gzip, compressed",
268 "Authorization" => "Basic dGVzdF9id191c2VyOnRlc3RfYndfcGFzc3dvcmQ=",
269 "User-Agent" => "Ruby-Bandwidth-Iris"
270 },
271 body: ""
272 )
273 .to_return(status: 200, body: rate_center_response, headers: {})
274
275 churnbuster_req = stub_request(
276 :post,
277 "https://api.churnbuster.io/v1/cancellations"
278 )
279 .with(
280 body: {
281 customer: {
282 source: "braintree",
283 source_id: "test",
284 email: "test@smtp.cheogram.com",
285 properties: {}
286 },
287 subscription: {
288 source: "braintree",
289 source_id: "test"
290 }
291 }.to_json
292 )
293 .to_return(status: 200, body: "", headers: {})
294
295 sgx, admin = admin_command("+15566667777")
296
297 sql_params = ["+15566667777", "NY", "NWYRCYZN01", "test_bw_account"]
298
299 BandwidthTnRepo::DB.expect(
300 :exec,
301 EMPromise.resolve(nil),
302 [String, sql_params]
303 )
304
305 Customer::BLATHER.expect(
306 :<<,
307 EMPromise.resolve(nil),
308 [
309 Matching.new do |m|
310 assert_equal "Your JMP account has been cancelled.", m.body
311 assert_equal "test@example.net", m.to.to_s
312 assert_equal "notify_from@component", m.from.to_s
313 end
314 ]
315 )
316
317 Customer::BLATHER.expect(
318 :<<,
319 EMPromise.resolve(nil),
320 [
321 Matching.new do |iq|
322 assert iq.remove?
323 assert_equal "test@example.net", iq.to.to_s
324 assert_equal "component", iq.from.to_s
325 end
326 ]
327 )
328
329 sgx.expect(:deregister!, EMPromise.resolve(nil))
330
331 admin.action_cancel_account.sync
332
333 assert_mock sgx
334 assert_mock BackendSgx::IQ_MANAGER
335 assert_mock Customer::BLATHER
336 assert_mock BandwidthTnRepo::DB
337
338 assert_requested churnbuster_req
339 assert_requested bandwidth_req
340 end
341 em :test_action_cancel_account_keep_number
342end