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 = Registration::Payment.for(
289				iq,
290				cust,
291				"+15555550000"
292			).sync
293			assert_kind_of Registration::Payment::CreditCard, result
294			assert_mock cust
295		end
296		em :test_for_credit_card
297
298		def test_for_code
299			cust = Minitest::Mock.new(customer)
300			cust.expect(:with_plan, cust, ["test_usd"])
301			cust.expect(:save_plan!, nil)
302			iq = Blather::Stanza::Iq::Command.new
303			iq.form.fields = [
304				{ var: "activation_method", value: "code" },
305				{ var: "plan_name", value: "test_usd" }
306			]
307			result = Registration::Payment.for(
308				iq,
309				cust,
310				"+15555550000"
311			)
312			assert_kind_of Registration::Payment::InviteCode, result
313			assert_mock cust
314		end
315
316		class BitcoinTest < Minitest::Test
317			Registration::Payment::Bitcoin::BTC_SELL_PRICES = Minitest::Mock.new
318			CustomerFinancials::REDIS = Minitest::Mock.new
319
320			def setup
321				@customer = Minitest::Mock.new(
322					customer(plan_name: "test_usd")
323				)
324				@customer.expect(
325					:add_btc_address,
326					EMPromise.resolve("testaddr")
327				)
328				@bitcoin = Registration::Payment::Bitcoin.new(
329					@customer,
330					"+15555550000"
331				)
332			end
333
334			def test_write
335				CustomerFinancials::REDIS.expect(
336					:smembers,
337					EMPromise.resolve([]),
338					["jmp_customer_btc_addresses-test"]
339				)
340				reply_text = <<~NOTE
341					Activate your account by sending at least 1.000000 BTC to
342					testaddr
343
344					You will receive a notification when your payment is complete.
345				NOTE
346				blather = Minitest::Mock.new
347				Command::COMMAND_MANAGER.expect(
348					:write,
349					EMPromise.reject(SessionManager::Timeout.new),
350					[Matching.new do |reply|
351						assert_equal :canceled, reply.status
352						assert_equal :info, reply.note_type
353						assert_equal reply_text, reply.note.content
354						true
355					end]
356				)
357				Registration::Payment::Bitcoin::BTC_SELL_PRICES.expect(
358					:usd,
359					EMPromise.resolve(BigDecimal(1))
360				)
361				@bitcoin.stub(:save, EMPromise.resolve(nil)) do
362					execute_command(blather: blather) do
363						@bitcoin.write
364					end
365				end
366				assert_mock blather
367			end
368			em :test_write
369		end
370
371		class CreditCardTest < Minitest::Test
372			def setup
373				@credit_card = Registration::Payment::CreditCard.new(
374					customer,
375					"+15555550000"
376				)
377			end
378
379			def test_for
380				customer = Minitest::Mock.new(customer)
381				customer.expect(
382					:payment_methods,
383					EMPromise.resolve(OpenStruct.new(default_payment_method: :test))
384				)
385				assert_kind_of(
386					Registration::Payment::CreditCard::Activate,
387					Registration::Payment::CreditCard.for(
388						customer,
389						"+15555550000"
390					).sync
391				)
392			end
393			em :test_for
394
395			def test_write
396				result = execute_command do
397					Command::COMMAND_MANAGER.expect(
398						:write,
399						EMPromise.reject(:test_result),
400						[Matching.new do |reply|
401							assert_equal [:execute, :next, :prev], reply.allowed_actions
402							assert_equal(
403								"Add credit card, save, then next here to continue: " \
404								"http://creditcard.example.com",
405								reply.note.content
406							)
407						end]
408					)
409
410					@credit_card.write.catch { |e| e }
411				end
412
413				assert_equal :test_result, result
414			end
415			em :test_write
416		end
417
418		class MailTest < Minitest::Test
419			def setup
420				@mail = Registration::Payment::Mail.new(
421					customer(plan_name: "test_cad"),
422					"+15555550000"
423				)
424			end
425
426			def test_write
427				result = execute_command do
428					Command::COMMAND_MANAGER.expect(
429						:write,
430						EMPromise.reject(:test_result),
431						[Matching.new do |reply|
432							assert_equal [:execute, :prev], reply.allowed_actions
433							refute reply.form.instructions.empty?
434							assert_equal(
435								"A Mailing Address",
436								reply.form.field("adr").value
437							)
438							assert_equal(
439								"interac@example.com",
440								reply.form.field("interac_email").value
441							)
442						end]
443					)
444
445					@mail.write.catch { |e| e }
446				end
447
448				assert_equal :test_result, result
449			end
450			em :test_write
451		end
452
453		class ActivateTest < Minitest::Test
454			Registration::Payment::CreditCard::Activate::Finish =
455				Minitest::Mock.new
456			Registration::Payment::CreditCard::Activate::CreditCardSale =
457				Minitest::Mock.new
458			Command::COMMAND_MANAGER = Minitest::Mock.new
459
460			def test_write
461				customer = Minitest::Mock.new(
462					customer(plan_name: "test_usd")
463				)
464				Registration::Payment::CreditCard::Activate::CreditCardSale.expect(
465					:create,
466					EMPromise.resolve(nil)
467				) do |acustomer, amount:, payment_method:|
468					assert_operator customer, :===, acustomer
469					assert_equal CONFIG[:activation_amount], amount
470					assert_equal :test_default_method, payment_method
471				end
472				customer.expect(
473					:bill_plan,
474					nil,
475					note: "Bill +15555550000 for first month"
476				)
477				Registration::Payment::CreditCard::Activate::Finish.expect(
478					:new,
479					OpenStruct.new(write: nil),
480					[customer, "+15555550000"]
481				)
482				execute_command do
483					Registration::Payment::CreditCard::Activate.new(
484						customer,
485						:test_default_method,
486						"+15555550000"
487					).write
488				end
489				Registration::Payment::CreditCard::Activate::CreditCardSale.verify
490				customer.verify
491				Registration::Payment::CreditCard::Activate::Finish.verify
492			end
493			em :test_write
494
495			def test_write_declines
496				customer = Minitest::Mock.new(
497					customer(plan_name: "test_usd")
498				)
499				iq = Blather::Stanza::Iq::Command.new
500				iq.from = "test@example.com"
501				msg = Registration::Payment::CreditCard::Activate::DECLINE_MESSAGE
502				Command::COMMAND_MANAGER.expect(
503					:write,
504					EMPromise.reject(:test_result),
505					[Matching.new do |reply|
506						assert_equal :error, reply.note_type
507						assert_equal(
508							"#{msg}: http://creditcard.example.com",
509							reply.note.content
510						)
511					end]
512				)
513				result = execute_command do
514					Registration::Payment::CreditCard::Activate::CreditCardSale.expect(
515						:create,
516						EMPromise.reject("declined")
517					) do |acustomer, amount:, payment_method:|
518						assert_operator customer, :===, acustomer
519						assert_equal CONFIG[:activation_amount], amount
520						assert_equal :test_default_method, payment_method
521					end
522
523					Registration::Payment::CreditCard::Activate.new(
524						customer,
525						:test_default_method,
526						"+15555550000"
527					).write.catch { |e| e }
528				end
529				assert_equal :test_result, result
530				Registration::Payment::CreditCard::Activate::CreditCardSale.verify
531			end
532			em :test_write_declines
533		end
534
535		class InviteCodeTest < Minitest::Test
536			Registration::Payment::InviteCode::DB =
537				Minitest::Mock.new
538			Registration::Payment::InviteCode::REDIS =
539				Minitest::Mock.new
540			Command::COMMAND_MANAGER = Minitest::Mock.new
541			Registration::Payment::InviteCode::Finish =
542				Minitest::Mock.new
543			def test_write
544				customer = customer(plan_name: "test_usd")
545				Registration::Payment::InviteCode::DB.expect(:transaction, true, [])
546				Registration::Payment::InviteCode::Finish.expect(
547					:new,
548					OpenStruct.new(write: nil),
549					[
550						customer,
551						"+15555550000"
552					]
553				)
554				execute_command do
555					Registration::Payment::InviteCode::REDIS.expect(
556						:get,
557						EMPromise.resolve(nil),
558						["jmp_invite_tries-test"]
559					)
560					Command::COMMAND_MANAGER.expect(
561						:write,
562						EMPromise.resolve(
563							Blather::Stanza::Iq::Command.new.tap { |iq|
564								iq.form.fields = [{ var: "code", value: "abc" }]
565							}
566						),
567						[Matching.new do |reply|
568							assert_equal :form, reply.form.type
569							assert_nil reply.form.instructions
570						end]
571					)
572
573					Registration::Payment::InviteCode.new(
574						customer,
575						"+15555550000"
576					).write
577				end
578				assert_mock Command::COMMAND_MANAGER
579				assert_mock Registration::Payment::InviteCode::DB
580				assert_mock Registration::Payment::InviteCode::REDIS
581				assert_mock Registration::Payment::InviteCode::Finish
582			end
583			em :test_write
584
585			def test_write_bad_code
586				result = execute_command do
587					customer = customer(plan_name: "test_usd")
588					Registration::Payment::InviteCode::REDIS.expect(
589						:get,
590						EMPromise.resolve(0),
591						["jmp_invite_tries-test"]
592					)
593					Registration::Payment::InviteCode::DB.expect(:transaction, []) do
594						raise InvitesRepo::Invalid, "wut"
595					end
596					Registration::Payment::InviteCode::REDIS.expect(
597						:incr,
598						EMPromise.resolve(nil),
599						["jmp_invite_tries-test"]
600					)
601					Registration::Payment::InviteCode::REDIS.expect(
602						:expire,
603						EMPromise.resolve(nil),
604						["jmp_invite_tries-test", 60 * 60]
605					)
606					Command::COMMAND_MANAGER.expect(
607						:write,
608						EMPromise.resolve(
609							Blather::Stanza::Iq::Command.new.tap { |iq|
610								iq.form.fields = [{ var: "code", value: "abc" }]
611							}
612						),
613						[Matching.new do |reply|
614							assert_equal :form, reply.form.type
615							assert_nil reply.form.instructions
616						end]
617					)
618					Command::COMMAND_MANAGER.expect(
619						:write,
620						EMPromise.reject(:test_result),
621						[Matching.new do |reply|
622							assert_equal :form, reply.form.type
623							assert_equal "wut", reply.form.instructions
624						end]
625					)
626
627					Registration::Payment::InviteCode.new(
628						customer,
629						"+15555550000"
630					).write.catch { |e| e }
631				end
632				assert_equal :test_result, result
633				assert_mock Command::COMMAND_MANAGER
634				assert_mock Registration::Payment::InviteCode::DB
635				assert_mock Registration::Payment::InviteCode::REDIS
636			end
637			em :test_write_bad_code
638
639			def test_write_bad_code_over_limit
640				result = execute_command do
641					customer = customer(plan_name: "test_usd")
642					Registration::Payment::InviteCode::REDIS.expect(
643						:get,
644						EMPromise.resolve(11),
645						["jmp_invite_tries-test"]
646					)
647					Command::COMMAND_MANAGER.expect(
648						:write,
649						EMPromise.resolve(
650							Blather::Stanza::Iq::Command.new.tap { |iq|
651								iq.form.fields = [{ var: "code", value: "abc" }]
652							}
653						),
654						[Matching.new do |reply|
655							assert_equal :form, reply.form.type
656							assert_nil reply.form.instructions
657						end]
658					)
659					Registration::Payment::InviteCode::REDIS.expect(
660						:incr,
661						EMPromise.resolve(nil),
662						["jmp_invite_tries-test"]
663					)
664					Registration::Payment::InviteCode::REDIS.expect(
665						:expire,
666						EMPromise.resolve(nil),
667						["jmp_invite_tries-test", 60 * 60]
668					)
669					Command::COMMAND_MANAGER.expect(
670						:write,
671						EMPromise.reject(:test_result),
672						[Matching.new do |reply|
673							assert_equal :form, reply.form.type
674							assert_equal "Too many wrong attempts", reply.form.instructions
675						end]
676					)
677					Registration::Payment::InviteCode.new(
678						customer,
679						"+15555550000"
680					).write.catch { |e| e }
681				end
682				assert_equal :test_result, result
683				assert_mock Command::COMMAND_MANAGER
684				assert_mock Registration::Payment::InviteCode::REDIS
685			end
686			em :test_write_bad_code_over_limit
687		end
688	end
689
690	class FinishTest < Minitest::Test
691		Command::COMMAND_MANAGER = Minitest::Mock.new
692		Registration::Finish::TEL_SELECTIONS = FakeTelSelections.new
693		Registration::Finish::REDIS = Minitest::Mock.new
694		Bwmsgsv2Repo::REDIS = Minitest::Mock.new
695
696		def setup
697			@sgx = Minitest::Mock.new(TrivialBackendSgxRepo.new.get("test"))
698			iq = Blather::Stanza::Iq::Command.new
699			iq.from = "test\\40example.com@cheogram.com"
700			@finish = Registration::Finish.new(
701				customer(sgx: @sgx),
702				"+15555550000"
703			)
704		end
705
706		def test_write
707			create_order = stub_request(
708				:post,
709				"https://dashboard.bandwidth.com/v1.0/accounts//orders"
710			).to_return(status: 201, body: <<~RESPONSE)
711				<OrderResponse>
712					<Order>
713						<id>test_order</id>
714					</Order>
715				</OrderResponse>
716			RESPONSE
717			stub_request(
718				:get,
719				"https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
720			).to_return(status: 201, body: <<~RESPONSE)
721				<OrderResponse>
722					<OrderStatus>COMPLETE</OrderStatus>
723					<CompletedNumbers>
724						<TelephoneNumber>
725							<FullNumber>5555550000</FullNumber>
726						</TelephoneNumber>
727					</CompletedNumbers>
728				</OrderResponse>
729			RESPONSE
730			stub_request(
731				:post,
732				"https://dashboard.bandwidth.com/v1.0/accounts//sites//sippeers//movetns"
733			)
734			Registration::Finish::REDIS.expect(
735				:del,
736				nil,
737				["pending_tel_for-test@example.net"]
738			)
739			Bwmsgsv2Repo::REDIS.expect(
740				:set,
741				nil,
742				[
743					"catapult_fwd-+15555550000",
744					"xmpp:test@example.net"
745				]
746			)
747			Bwmsgsv2Repo::REDIS.expect(
748				:set,
749				nil,
750				["catapult_fwd_timeout-customer_test@component", 25]
751			)
752			blather = Minitest::Mock.new
753			blather.expect(
754				:<<,
755				nil,
756				[Matching.new do |reply|
757					assert_equal :completed, reply.status
758					assert_equal :info, reply.note_type
759					assert_equal(
760						"Your JMP account has been activated as +15555550000",
761						reply.note.content
762					)
763				end]
764			)
765			execute_command(blather: blather) do
766				@sgx.expect(
767					:register!,
768					EMPromise.resolve(@sgx.with(
769						registered?: Blather::Stanza::Iq::IBR.new.tap do |ibr|
770							ibr.phone = "+15555550000"
771						end
772					)),
773					["+15555550000"]
774				)
775
776				@finish.write
777			end
778			assert_requested create_order
779			assert_mock @sgx
780			assert_mock Registration::Finish::REDIS
781			assert_mock Bwmsgsv2Repo::REDIS
782			assert_mock blather
783		end
784		em :test_write
785
786		def test_write_tn_fail
787			create_order = stub_request(
788				:post,
789				"https://dashboard.bandwidth.com/v1.0/accounts//orders"
790			).to_return(status: 201, body: <<~RESPONSE)
791				<OrderResponse>
792					<Order>
793						<id>test_order</id>
794					</Order>
795				</OrderResponse>
796			RESPONSE
797			stub_request(
798				:get,
799				"https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
800			).to_return(status: 201, body: <<~RESPONSE)
801				<OrderResponse>
802					<OrderStatus>FAILED</OrderStatus>
803				</OrderResponse>
804			RESPONSE
805
806			result = execute_command do
807				Command::COMMAND_MANAGER.expect(
808					:write,
809					EMPromise.reject(:test_result),
810					[Matching.new do |iq|
811						assert_equal :form, iq.form.type
812						assert_equal(
813							"The JMP number +15555550000 is no longer available.",
814							iq.form.instructions
815						)
816					end]
817				)
818
819				@finish.write.catch { |e| e }
820			end
821
822			assert_equal :test_result, result
823			assert_mock Command::COMMAND_MANAGER
824			assert_instance_of(
825				TelSelections::ChooseTel,
826				Registration::Finish::TEL_SELECTIONS["test@example.com"]
827			)
828			assert_requested create_order
829		end
830		em :test_write_tn_fail
831	end
832end