test_registration.rb

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