test_registration.rb

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