test_registration.rb

  1# frozen_string_literal: true
  2
  3require "test_helper"
  4require "customer"
  5require "registration"
  6
  7BandwidthTnReservationRepo::REDIS = FakeRedis.new
  8
  9class RegistrationTest < Minitest::Test
 10	def test_for_registered
 11		sgx = OpenStruct.new(
 12			registered?: OpenStruct.new(phone: "+15555550000")
 13		)
 14		iq = Blather::Stanza::Iq::Command.new
 15		iq.from = "test@example.com"
 16		result = execute_command(iq) do
 17			Registration.for(
 18				customer(sgx: sgx),
 19				Minitest::Mock.new
 20			)
 21		end
 22		assert_kind_of Registration::Registered, result
 23	end
 24	em :test_for_registered
 25
 26	def test_for_activated
 27		reservation_req = stub_request(
 28			:post,
 29			"https://dashboard.bandwidth.com/v1.0/accounts//tnreservation"
 30		)
 31		web_manager = TelSelections.new(redis: FakeRedis.new)
 32		web_manager.set("test@example.net", "+15555550000")
 33		result = execute_command do
 34			sgx = OpenStruct.new(registered?: false)
 35			Registration.for(
 36				customer(
 37					plan_name: "test_usd",
 38					expires_at: Time.now + 999,
 39					sgx: sgx
 40				),
 41				web_manager
 42			)
 43		end
 44		assert_kind_of Registration::Finish, result
 45		assert_requested reservation_req
 46	end
 47	em :test_for_activated
 48
 49	def test_for_not_activated_approved
 50		sgx = OpenStruct.new(registered?: false)
 51		web_manager = TelSelections.new(redis: FakeRedis.new)
 52		web_manager.set("test\\40approved.example.com@component", "+15555550000")
 53		iq = Blather::Stanza::Iq::Command.new
 54		iq.from = "test@approved.example.com"
 55		result = execute_command(iq) do
 56			Registration::Activation.for(
 57				customer(
 58					sgx: sgx,
 59					jid: Blather::JID.new("test\\40approved.example.com@component")
 60				),
 61				web_manager
 62			)
 63		end
 64		assert_kind_of Registration::Activation::Allow, result
 65	end
 66	em :test_for_not_activated_approved
 67
 68	def test_for_not_activated_with_customer_id
 69		sgx = OpenStruct.new(registered?: false)
 70		web_manager = TelSelections.new(redis: FakeRedis.new)
 71		web_manager.set("test@example.net", "+15555550000")
 72		iq = Blather::Stanza::Iq::Command.new
 73		iq.from = "test@example.com"
 74		result = execute_command(iq) do
 75			Registration::Activation.for(
 76				customer(sgx: sgx),
 77				web_manager
 78			)
 79		end
 80		assert_kind_of Registration::Activation, result
 81	end
 82	em :test_for_not_activated_with_customer_id
 83
 84	class ActivationTest < Minitest::Test
 85		Command::COMMAND_MANAGER = Minitest::Mock.new
 86		def setup
 87			@activation = Registration::Activation.new("test", "+15555550000")
 88		end
 89
 90		def test_write
 91			stub_request(
 92				:get,
 93				"https://dashboard.bandwidth.com/v1.0/tns/+15555550000"
 94			).to_return(status: 201, body: <<~RESPONSE)
 95				<TelephoneNumberResponse>
 96					<TelephoneNumber>5555550000</TelephoneNumber>
 97				</TelephoneNumberResponse>
 98			RESPONSE
 99			stub_request(
100				:get,
101				"https://dashboard.bandwidth.com/v1.0/tns/5555550000/ratecenter"
102			).to_return(status: 201, body: <<~RESPONSE)
103				<TelephoneNumberResponse>
104					<TelephoneNumberDetails>
105						<State>KE</State>
106						<RateCenter>FA</RateCenter>
107					</TelephoneNumberDetails>
108				</TelephoneNumberResponse>
109			RESPONSE
110			Command::COMMAND_MANAGER.expect(
111				:write,
112				EMPromise.reject(:test_result),
113				[Matching.new do |iq|
114					assert_equal :form, iq.form.type
115					assert_equal(
116						"You've selected +15555550000 (FA, KE) as your JMP number.",
117						iq.form.instructions.lines.first.chomp
118					)
119				end]
120			)
121			assert_equal(
122				:test_result,
123				execute_command { @activation.write.catch { |e| e } }
124			)
125			assert_mock Command::COMMAND_MANAGER
126		end
127		em :test_write
128	end
129
130	class AllowTest < Minitest::Test
131		Command::COMMAND_MANAGER = Minitest::Mock.new
132		Registration::Activation::Allow::DB = Minitest::Mock.new
133
134		def test_write_credit_to_nil
135			cust = Minitest::Mock.new(customer("test"))
136			allow = Registration::Activation::Allow.new(cust, "+15555550000", nil)
137
138			stub_request(
139				:get,
140				"https://dashboard.bandwidth.com/v1.0/tns/+15555550000"
141			).to_return(status: 201, body: <<~RESPONSE)
142				<TelephoneNumberResponse>
143					<TelephoneNumber>5555550000</TelephoneNumber>
144				</TelephoneNumberResponse>
145			RESPONSE
146			stub_request(
147				:get,
148				"https://dashboard.bandwidth.com/v1.0/tns/5555550000/ratecenter"
149			).to_return(status: 201, body: <<~RESPONSE)
150				<TelephoneNumberResponse>
151					<TelephoneNumberDetails>
152						<State>KE</State>
153						<RateCenter>FA</RateCenter>
154					</TelephoneNumberDetails>
155				</TelephoneNumberResponse>
156			RESPONSE
157			Command::COMMAND_MANAGER.expect(
158				:write,
159				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
160					iq.form.fields = [{ var: "plan_name", value: "test_usd" }]
161				}),
162				[Matching.new do |iq|
163					assert_equal :form, iq.form.type
164					assert_equal(
165						"You've selected +15555550000 (FA, KE) as your JMP number.",
166						iq.form.instructions.lines.first.chomp
167					)
168					assert_equal 1, iq.form.fields.length
169				end]
170			)
171			Registration::Activation::Allow::DB.expect(
172				:transaction,
173				EMPromise.reject(:test_result)
174			) do |&blk|
175				blk.call
176				true
177			end
178			cust.expect(:with_plan, cust, ["test_usd"])
179			cust.expect(:activate_plan_starting_now, nil)
180			assert_equal(
181				:test_result,
182				execute_command { allow.write.catch { |e| e } }
183			)
184			assert_mock Command::COMMAND_MANAGER
185		end
186		em :test_write_credit_to_nil
187
188		def test_write_credit_to_refercust
189			cust = Minitest::Mock.new(customer("test"))
190			allow = Registration::Activation::Allow.new(
191				cust, "+15555550000", "refercust"
192			)
193
194			stub_request(
195				:get,
196				"https://dashboard.bandwidth.com/v1.0/tns/+15555550000"
197			).to_return(status: 201, body: <<~RESPONSE)
198				<TelephoneNumberResponse>
199					<TelephoneNumber>5555550000</TelephoneNumber>
200				</TelephoneNumberResponse>
201			RESPONSE
202			stub_request(
203				:get,
204				"https://dashboard.bandwidth.com/v1.0/tns/5555550000/ratecenter"
205			).to_return(status: 201, body: <<~RESPONSE)
206				<TelephoneNumberResponse>
207					<TelephoneNumberDetails>
208						<State>KE</State>
209						<RateCenter>FA</RateCenter>
210					</TelephoneNumberDetails>
211				</TelephoneNumberResponse>
212			RESPONSE
213			Command::COMMAND_MANAGER.expect(
214				:write,
215				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
216					iq.form.fields = [{ var: "plan_name", value: "test_usd" }]
217				}),
218				[Matching.new do |iq|
219					assert_equal :form, iq.form.type
220					assert_equal(
221						"You've selected +15555550000 (FA, KE) as your JMP number.",
222						iq.form.instructions.lines.first.chomp
223					)
224					assert_equal 1, iq.form.fields.length
225				end]
226			)
227			Registration::Activation::Allow::DB.expect(
228				:transaction,
229				EMPromise.reject(:test_result)
230			) do |&blk|
231				blk.call
232				true
233			end
234			Registration::Activation::Allow::DB.expect(
235				:exec,
236				nil,
237				[String, ["refercust", "test"]]
238			)
239			cust.expect(:with_plan, cust, ["test_usd"])
240			cust.expect(:activate_plan_starting_now, nil)
241			assert_equal(
242				:test_result,
243				execute_command { allow.write.catch { |e| e } }
244			)
245			assert_mock Command::COMMAND_MANAGER
246		end
247		em :test_write_credit_to_refercust
248	end
249
250	class PaymentTest < Minitest::Test
251		CustomerFinancials::BRAINTREE = Minitest::Mock.new
252
253		def test_for_bitcoin
254			cust = Minitest::Mock.new(customer)
255			cust.expect(:with_plan, cust, ["test_usd"])
256			cust.expect(:save_plan!, nil)
257			iq = Blather::Stanza::Iq::Command.new
258			iq.form.fields = [
259				{ var: "activation_method", value: "bitcoin" },
260				{ var: "plan_name", value: "test_usd" }
261			]
262			result = Registration::Payment.for(iq, cust, "+15555550000")
263			assert_kind_of Registration::Payment::Bitcoin, result
264			assert_mock cust
265		end
266
267		def test_for_credit_card
268			cust = Minitest::Mock.new(customer)
269			cust.expect(:with_plan, cust, ["test_usd"])
270			cust.expect(:save_plan!, nil)
271			braintree_customer = Minitest::Mock.new
272			CustomerFinancials::BRAINTREE.expect(
273				:customer,
274				braintree_customer
275			)
276			CustomerFinancials::REDIS.expect(:smembers, [], ["block_credit_cards"])
277			braintree_customer.expect(
278				:find,
279				EMPromise.resolve(OpenStruct.new(payment_methods: [])),
280				["test"]
281			)
282			iq = Blather::Stanza::Iq::Command.new
283			iq.from = "test@example.com"
284			iq.form.fields = [
285				{ var: "activation_method", value: "credit_card" },
286				{ var: "plan_name", value: "test_usd" }
287			]
288			result = execute_command do
289				Command.execution.customer_repo.expect(:find, cust, ["test"])
290				Registration::Payment.for(
291					iq,
292					cust,
293					""
294				).sync
295			end
296			assert_kind_of Registration::Payment::CreditCard, result
297			assert_mock cust
298		end
299		em :test_for_credit_card
300
301		def test_for_code
302			cust = Minitest::Mock.new(customer)
303			cust.expect(:with_plan, cust, ["test_usd"])
304			cust.expect(:save_plan!, nil)
305			iq = Blather::Stanza::Iq::Command.new
306			iq.form.fields = [
307				{ var: "activation_method", value: "code" },
308				{ var: "plan_name", value: "test_usd" }
309			]
310			result = Registration::Payment.for(
311				iq,
312				cust,
313				"+15555550000"
314			)
315			assert_kind_of Registration::Payment::InviteCode, result
316			assert_mock cust
317		end
318
319		class BitcoinTest < Minitest::Test
320			Registration::Payment::Bitcoin::BTC_SELL_PRICES = Minitest::Mock.new
321			CustomerFinancials::REDIS = Minitest::Mock.new
322
323			def setup
324				@customer = Minitest::Mock.new(
325					customer(plan_name: "test_usd")
326				)
327				@customer.expect(
328					:add_btc_address,
329					EMPromise.resolve("testaddr")
330				)
331				@bitcoin = Registration::Payment::Bitcoin.new(
332					@customer,
333					"+15555550000"
334				)
335			end
336
337			def test_write
338				CustomerFinancials::REDIS.expect(
339					:smembers,
340					EMPromise.resolve([]),
341					["jmp_customer_btc_addresses-test"]
342				)
343				blather = Minitest::Mock.new
344				Command::COMMAND_MANAGER.expect(
345					:write,
346					EMPromise.reject(SessionManager::Timeout.new),
347					[Matching.new do |reply|
348						assert_equal :canceled, reply.status
349						assert_equal "1.000000", reply.form.field("amount").value
350						assert_equal "testaddr", reply.form.field("btc_addresses").value
351						true
352					end]
353				)
354				Registration::Payment::Bitcoin::BTC_SELL_PRICES.expect(
355					:usd,
356					EMPromise.resolve(BigDecimal(1))
357				)
358				@bitcoin.stub(:save, EMPromise.resolve(nil)) do
359					execute_command(blather: blather) do
360						@bitcoin.write
361					end
362				end
363				assert_mock blather
364			end
365			em :test_write
366		end
367
368		class CreditCardTest < Minitest::Test
369			def setup
370				@credit_card = Registration::Payment::CreditCard.new(
371					customer,
372					"+15555550000"
373				)
374			end
375
376			def test_for
377				cust = Minitest::Mock.new(customer)
378				cust.expect(
379					:payment_methods,
380					EMPromise.resolve(OpenStruct.new(default_payment_method: :test))
381				)
382				execute_command do
383					Command.execution.customer_repo.expect(:find, cust, ["test"])
384					assert_kind_of(
385						Registration::Payment::CreditCard::Activate,
386						Registration::Payment::CreditCard.for(
387							cust,
388							"+15555550000"
389						).sync
390					)
391				end
392			end
393			em :test_for
394
395			def test_for_has_balance
396				cust = Minitest::Mock.new(customer)
397				cust.expect(:balance, 100)
398				cust.expect(:payment_methods, EMPromise.resolve(nil))
399				execute_command do
400					Command.execution.customer_repo.expect(:find, cust, ["test"])
401					assert_kind_of(
402						Registration::BillPlan,
403						Registration::Payment::CreditCard.for(
404							cust,
405							"+15555550000"
406						).sync
407					)
408				end
409			end
410			em :test_for_has_balance
411
412			def test_write
413				result = execute_command do
414					Command::COMMAND_MANAGER.expect(
415						:write,
416						EMPromise.reject(:test_result),
417						[Matching.new do |reply|
418							assert_equal [:execute, :next, :prev], reply.allowed_actions
419							assert_equal(
420								"Add credit card, save, then next here to continue: " \
421								"http://creditcard.example.com?&amount=1",
422								reply.note.content
423							)
424						end]
425					)
426
427					@credit_card.write.catch { |e| e }
428				end
429
430				assert_equal :test_result, result
431			end
432			em :test_write
433		end
434
435		class MailTest < Minitest::Test
436			def setup
437				@mail = Registration::Payment::Mail.new(
438					customer(plan_name: "test_cad"),
439					"+15555550000"
440				)
441			end
442
443			def test_write
444				result = execute_command do
445					Command::COMMAND_MANAGER.expect(
446						:write,
447						EMPromise.reject(:test_result),
448						[Matching.new do |reply|
449							assert_equal [:execute, :prev], reply.allowed_actions
450							refute reply.form.instructions.empty?
451							assert_equal(
452								"A Mailing Address",
453								reply.form.field("adr").value
454							)
455							assert_equal(
456								"interac@example.com",
457								reply.form.field("interac_email").value
458							)
459						end]
460					)
461
462					@mail.write.catch { |e| e }
463				end
464
465				assert_equal :test_result, result
466			end
467			em :test_write
468		end
469
470		class ActivateTest < Minitest::Test
471			Registration::Payment::CreditCard::Activate::Finish =
472				Minitest::Mock.new
473			Registration::Payment::CreditCard::Activate::CreditCardSale =
474				Minitest::Mock.new
475			Command::COMMAND_MANAGER = Minitest::Mock.new
476
477			def test_write
478				customer = Minitest::Mock.new(
479					customer(plan_name: "test_usd")
480				)
481				Registration::Payment::CreditCard::Activate::CreditCardSale.expect(
482					:create,
483					EMPromise.resolve(nil)
484				) do |acustomer, amount:, payment_method:|
485					assert_operator customer, :===, acustomer
486					assert_equal CONFIG[:activation_amount], amount
487					assert_equal :test_default_method, payment_method
488				end
489				customer.expect(
490					:bill_plan,
491					nil,
492					note: "Bill +15555550000 for first month"
493				)
494				Registration::Payment::CreditCard::Activate::Finish.expect(
495					:new,
496					OpenStruct.new(write: nil),
497					[customer, "+15555550000"]
498				)
499				execute_command do
500					Registration::Payment::CreditCard::Activate.new(
501						customer,
502						:test_default_method,
503						"+15555550000"
504					).write
505				end
506				Registration::Payment::CreditCard::Activate::CreditCardSale.verify
507				customer.verify
508				Registration::Payment::CreditCard::Activate::Finish.verify
509			end
510			em :test_write
511
512			def test_write_declines
513				customer = Minitest::Mock.new(
514					customer(plan_name: "test_usd")
515				)
516				iq = Blather::Stanza::Iq::Command.new
517				iq.from = "test@example.com"
518				msg = Registration::Payment::CreditCard::Activate::DECLINE_MESSAGE
519				Command::COMMAND_MANAGER.expect(
520					:write,
521					EMPromise.reject(:test_result),
522					[Matching.new do |reply|
523						assert_equal :error, reply.note_type
524						assert_equal(
525							"#{msg}: http://creditcard.example.com?&amount=1",
526							reply.note.content
527						)
528					end]
529				)
530				result = execute_command do
531					Registration::Payment::CreditCard::Activate::CreditCardSale.expect(
532						:create,
533						EMPromise.reject("declined")
534					) do |acustomer, amount:, payment_method:|
535						assert_operator customer, :===, acustomer
536						assert_equal CONFIG[:activation_amount], amount
537						assert_equal :test_default_method, payment_method
538					end
539
540					Registration::Payment::CreditCard::Activate.new(
541						customer,
542						:test_default_method,
543						"+15555550000"
544					).write.catch { |e| e }
545				end
546				assert_equal :test_result, result
547				Registration::Payment::CreditCard::Activate::CreditCardSale.verify
548			end
549			em :test_write_declines
550		end
551
552		class InviteCodeTest < Minitest::Test
553			Registration::Payment::InviteCode::DB =
554				Minitest::Mock.new
555			Registration::Payment::InviteCode::REDIS =
556				Minitest::Mock.new
557			Command::COMMAND_MANAGER = Minitest::Mock.new
558			Registration::Payment::InviteCode::Finish =
559				Minitest::Mock.new
560			def test_write
561				customer = customer(plan_name: "test_usd")
562				Registration::Payment::InviteCode::DB.expect(:transaction, true, [])
563				Registration::Payment::InviteCode::Finish.expect(
564					:new,
565					OpenStruct.new(write: nil),
566					[
567						customer,
568						"+15555550000"
569					]
570				)
571				execute_command do
572					Registration::Payment::InviteCode::REDIS.expect(
573						:get,
574						EMPromise.resolve(nil),
575						["jmp_invite_tries-test"]
576					)
577					Command::COMMAND_MANAGER.expect(
578						:write,
579						EMPromise.resolve(
580							Blather::Stanza::Iq::Command.new.tap { |iq|
581								iq.form.fields = [{ var: "code", value: "abc" }]
582							}
583						),
584						[Matching.new do |reply|
585							assert_equal :form, reply.form.type
586							assert_nil reply.form.instructions
587						end]
588					)
589
590					Registration::Payment::InviteCode.new(
591						customer,
592						"+15555550000"
593					).write
594				end
595				assert_mock Command::COMMAND_MANAGER
596				assert_mock Registration::Payment::InviteCode::DB
597				assert_mock Registration::Payment::InviteCode::REDIS
598				assert_mock Registration::Payment::InviteCode::Finish
599			end
600			em :test_write
601
602			def test_write_bad_code
603				result = execute_command do
604					customer = customer(plan_name: "test_usd")
605					Registration::Payment::InviteCode::REDIS.expect(
606						:get,
607						EMPromise.resolve(0),
608						["jmp_invite_tries-test"]
609					)
610					Registration::Payment::InviteCode::DB.expect(:transaction, []) do
611						raise InvitesRepo::Invalid, "wut"
612					end
613					Registration::Payment::InviteCode::REDIS.expect(
614						:incr,
615						EMPromise.resolve(nil),
616						["jmp_invite_tries-test"]
617					)
618					Registration::Payment::InviteCode::REDIS.expect(
619						:expire,
620						EMPromise.resolve(nil),
621						["jmp_invite_tries-test", 60 * 60]
622					)
623					Command::COMMAND_MANAGER.expect(
624						:write,
625						EMPromise.resolve(
626							Blather::Stanza::Iq::Command.new.tap { |iq|
627								iq.form.fields = [{ var: "code", value: "abc" }]
628							}
629						),
630						[Matching.new do |reply|
631							assert_equal :form, reply.form.type
632							assert_nil reply.form.instructions
633						end]
634					)
635					Command::COMMAND_MANAGER.expect(
636						:write,
637						EMPromise.reject(:test_result),
638						[Matching.new do |reply|
639							assert_equal :form, reply.form.type
640							assert_equal "wut", reply.form.instructions
641						end]
642					)
643
644					Registration::Payment::InviteCode.new(
645						customer,
646						"+15555550000"
647					).write.catch { |e| e }
648				end
649				assert_equal :test_result, result
650				assert_mock Command::COMMAND_MANAGER
651				assert_mock Registration::Payment::InviteCode::DB
652				assert_mock Registration::Payment::InviteCode::REDIS
653			end
654			em :test_write_bad_code
655
656			def test_write_bad_code_over_limit
657				result = execute_command do
658					customer = customer(plan_name: "test_usd")
659					Registration::Payment::InviteCode::REDIS.expect(
660						:get,
661						EMPromise.resolve(11),
662						["jmp_invite_tries-test"]
663					)
664					Command::COMMAND_MANAGER.expect(
665						:write,
666						EMPromise.resolve(
667							Blather::Stanza::Iq::Command.new.tap { |iq|
668								iq.form.fields = [{ var: "code", value: "abc" }]
669							}
670						),
671						[Matching.new do |reply|
672							assert_equal :form, reply.form.type
673							assert_nil reply.form.instructions
674						end]
675					)
676					Registration::Payment::InviteCode::REDIS.expect(
677						:incr,
678						EMPromise.resolve(nil),
679						["jmp_invite_tries-test"]
680					)
681					Registration::Payment::InviteCode::REDIS.expect(
682						:expire,
683						EMPromise.resolve(nil),
684						["jmp_invite_tries-test", 60 * 60]
685					)
686					Command::COMMAND_MANAGER.expect(
687						:write,
688						EMPromise.reject(:test_result),
689						[Matching.new do |reply|
690							assert_equal :form, reply.form.type
691							assert_equal "Too many wrong attempts", reply.form.instructions
692						end]
693					)
694					Registration::Payment::InviteCode.new(
695						customer,
696						"+15555550000"
697					).write.catch { |e| e }
698				end
699				assert_equal :test_result, result
700				assert_mock Command::COMMAND_MANAGER
701				assert_mock Registration::Payment::InviteCode::REDIS
702			end
703			em :test_write_bad_code_over_limit
704		end
705	end
706
707	class FinishTest < Minitest::Test
708		Customer::BLATHER = Minitest::Mock.new
709		Command::COMMAND_MANAGER = Minitest::Mock.new
710		Registration::Finish::TEL_SELECTIONS = FakeTelSelections.new
711		Registration::Finish::REDIS = Minitest::Mock.new
712		Bwmsgsv2Repo::REDIS = Minitest::Mock.new
713
714		def setup
715			@sgx = Minitest::Mock.new(TrivialBackendSgxRepo.new.get("test"))
716			iq = Blather::Stanza::Iq::Command.new
717			iq.from = "test\\40example.com@cheogram.com"
718			@finish = Registration::Finish.new(
719				customer(sgx: @sgx),
720				"+15555550000"
721			)
722		end
723
724		def test_write
725			create_order = stub_request(
726				:post,
727				"https://dashboard.bandwidth.com/v1.0/accounts//orders"
728			).to_return(status: 201, body: <<~RESPONSE)
729				<OrderResponse>
730					<Order>
731						<id>test_order</id>
732					</Order>
733				</OrderResponse>
734			RESPONSE
735			stub_request(
736				:get,
737				"https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
738			).to_return(status: 201, body: <<~RESPONSE)
739				<OrderResponse>
740					<OrderStatus>COMPLETE</OrderStatus>
741					<CompletedNumbers>
742						<TelephoneNumber>
743							<FullNumber>5555550000</FullNumber>
744						</TelephoneNumber>
745					</CompletedNumbers>
746				</OrderResponse>
747			RESPONSE
748			stub_request(
749				:post,
750				"https://dashboard.bandwidth.com/v1.0/accounts//sites//sippeers//movetns"
751			)
752			Registration::Finish::REDIS.expect(
753				:del,
754				nil,
755				["pending_tel_for-test@example.net"]
756			)
757			Bwmsgsv2Repo::REDIS.expect(
758				:set,
759				nil,
760				[
761					"catapult_fwd-+15555550000",
762					"xmpp:test@example.net"
763				]
764			)
765			Bwmsgsv2Repo::REDIS.expect(
766				:set,
767				nil,
768				["catapult_fwd_timeout-customer_test@component", 25]
769			)
770			Customer::BLATHER.expect(
771				:<<,
772				nil,
773				[Matching.new do |m|
774					assert_equal :chat, m.type
775					assert m.body =~ /^Welcome to JMP/
776				end]
777			)
778			blather = Minitest::Mock.new
779			blather.expect(
780				:<<,
781				nil,
782				[Matching.new do |reply|
783					assert_equal :completed, reply.status
784					assert_equal :info, reply.note_type
785					assert_equal(
786						"Your JMP account has been activated as +15555550000",
787						reply.note.content
788					)
789				end]
790			)
791			execute_command(blather: blather) do
792				@sgx.expect(
793					:register!,
794					EMPromise.resolve(@sgx.with(
795						registered?: Blather::Stanza::Iq::IBR.new.tap do |ibr|
796							ibr.phone = "+15555550000"
797						end
798					)),
799					["+15555550000"]
800				)
801
802				@finish.write
803			end
804			assert_requested create_order
805			assert_mock @sgx
806			assert_mock Registration::Finish::REDIS
807			assert_mock Bwmsgsv2Repo::REDIS
808			assert_mock Customer::BLATHER
809			assert_mock blather
810		end
811		em :test_write
812
813		def test_write_tn_fail
814			create_order = stub_request(
815				:post,
816				"https://dashboard.bandwidth.com/v1.0/accounts//orders"
817			).to_return(status: 201, body: <<~RESPONSE)
818				<OrderResponse>
819					<Order>
820						<id>test_order</id>
821					</Order>
822				</OrderResponse>
823			RESPONSE
824			stub_request(
825				:get,
826				"https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
827			).to_return(status: 201, body: <<~RESPONSE)
828				<OrderResponse>
829					<OrderStatus>FAILED</OrderStatus>
830				</OrderResponse>
831			RESPONSE
832
833			result = execute_command do
834				Command::COMMAND_MANAGER.expect(
835					:write,
836					EMPromise.reject(:test_result),
837					[Matching.new do |iq|
838						assert_equal :form, iq.form.type
839						assert_equal(
840							"The JMP number +15555550000 is no longer available.",
841							iq.form.instructions
842						)
843					end]
844				)
845
846				@finish.write.catch { |e| e }
847			end
848
849			assert_equal :test_result, result
850			assert_mock Command::COMMAND_MANAGER
851			assert_instance_of(
852				TelSelections::ChooseTel,
853				Registration::Finish::TEL_SELECTIONS["test@example.com"]
854			)
855			assert_requested create_order
856		end
857		em :test_write_tn_fail
858	end
859end