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				nil,
  20				Minitest::Mock.new
  21			)
  22		end
  23		assert_kind_of Registration::Registered, result
  24	end
  25	em :test_for_registered
  26
  27	def test_for_activated
  28		reservation_req = stub_request(
  29			:post,
  30			"https://dashboard.bandwidth.com/v1.0/accounts//tnreservation"
  31		)
  32		web_manager = TelSelections.new(
  33			redis: FakeRedis.new, db: FakeDB.new, memcache: FakeMemcache.new
  34		)
  35		web_manager.set("test@example.net", "+15555550000")
  36		result = execute_command do
  37			sgx = OpenStruct.new(registered?: false)
  38			Registration.for(
  39				customer(
  40					plan_name: "test_usd",
  41					expires_at: Time.now + 999,
  42					sgx: sgx
  43				),
  44				nil,
  45				web_manager
  46			)
  47		end
  48		assert_kind_of Registration::Finish, result
  49		assert_requested reservation_req
  50	end
  51	em :test_for_activated
  52
  53	def test_for_not_activated_approved
  54		sgx = OpenStruct.new(registered?: false)
  55		web_manager = TelSelections.new(
  56			redis: FakeRedis.new, db: FakeDB.new, memcache: FakeMemcache.new
  57		)
  58		web_manager.set("test\\40approved.example.com@component", "+15555550000")
  59		iq = Blather::Stanza::Iq::Command.new
  60		iq.from = "test@approved.example.com"
  61		result = execute_command(iq) do
  62			Registration::Activation.for(
  63				customer(
  64					sgx: sgx,
  65					jid: Blather::JID.new("test\\40approved.example.com@component")
  66				),
  67				nil,
  68				web_manager
  69			)
  70		end
  71		assert_kind_of Registration::Activation::Allow, result
  72	end
  73	em :test_for_not_activated_approved
  74
  75	def test_for_not_activated_googleplay
  76		sgx = OpenStruct.new(registered?: false)
  77		web_manager = TelSelections.new(
  78			redis: FakeRedis.new, db: FakeDB.new, memcache: FakeMemcache.new
  79		)
  80		web_manager.set("test@example.net", "+15555550000")
  81		iq = Blather::Stanza::Iq::Command.new
  82		iq.from = "test@approved.example.com"
  83		result = execute_command(iq) do
  84			Registration::Activation.for(
  85				customer(sgx: sgx),
  86				"GARBLEDYGOOK==",
  87				web_manager
  88			)
  89		end
  90		assert_kind_of Registration::Activation::GooglePlay, result
  91	end
  92	em :test_for_not_activated_googleplay
  93
  94	def test_for_not_activated_with_customer_id
  95		sgx = OpenStruct.new(registered?: false)
  96		web_manager = TelSelections.new(
  97			redis: FakeRedis.new, db: FakeDB.new, memcache: FakeMemcache.new
  98		)
  99		web_manager.set("test@example.net", "+15555550000")
 100		iq = Blather::Stanza::Iq::Command.new
 101		iq.from = "test@example.com"
 102		result = execute_command(iq) do
 103			Registration::Activation.for(
 104				customer(sgx: sgx),
 105				nil,
 106				web_manager
 107			)
 108		end
 109		assert_kind_of Registration::Activation, result
 110	end
 111	em :test_for_not_activated_with_customer_id
 112
 113	class ActivationTest < Minitest::Test
 114		Registration::Activation::DB = Minitest::Mock.new
 115		Registration::Activation::REDIS = FakeRedis.new
 116		Registration::Activation::Payment = Minitest::Mock.new
 117		Registration::Activation::Finish = Minitest::Mock.new
 118		Command::COMMAND_MANAGER = Minitest::Mock.new
 119
 120		def setup
 121			@customer = Minitest::Mock.new(customer)
 122			@activation = Registration::Activation.new(@customer, "+15555550000")
 123		end
 124
 125		def test_write
 126			Command::COMMAND_MANAGER.expect(
 127				:write,
 128				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 129					iq.form.fields = [{ var: "plan_name", value: "test_usd" }]
 130				}),
 131				[Matching.new do |iq|
 132					assert_equal :form, iq.form.type
 133					assert_equal(
 134						"You've selected +15555550000 as your JMP number.",
 135						iq.form.instructions.lines.first.chomp
 136					)
 137				end]
 138			)
 139			@customer.expect(:with_plan, @customer, ["test_usd"])
 140			@customer.expect(:save_plan!, EMPromise.resolve(nil), [])
 141			Registration::Activation::Payment.expect(
 142				:for,
 143				EMPromise.reject(:test_result),
 144				[Blather::Stanza::Iq, @customer, "+15555550000"]
 145			)
 146			assert_equal(
 147				:test_result,
 148				execute_command { @activation.write.catch { |e| e } }
 149			)
 150			assert_mock Command::COMMAND_MANAGER
 151			assert_mock @customer
 152			assert_mock Registration::Activation::Payment
 153		end
 154		em :test_write
 155
 156		def test_write_with_code
 157			Command::COMMAND_MANAGER.expect(
 158				:write,
 159				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 160					iq.form.fields = [
 161						{ var: "plan_name", value: "test_usd" },
 162						{ var: "code", value: "123" }
 163					]
 164				}),
 165				[Matching.new do |iq|
 166					assert_equal :form, iq.form.type
 167					assert_equal(
 168						"You've selected +15555550000 as your JMP number.",
 169						iq.form.instructions.lines.first.chomp
 170					)
 171				end]
 172			)
 173			@customer.expect(:with_plan, @customer, ["test_usd"])
 174			@customer.expect(:save_plan!, EMPromise.resolve(nil), [])
 175			@customer.expect(:activate_plan_starting_now, EMPromise.resolve(nil), [])
 176			Registration::Activation::DB.expect(:transaction, []) { |&blk| blk.call }
 177			Registration::Activation::DB.expect(
 178				:exec,
 179				OpenStruct.new(cmd_tuples: 1),
 180				[String, ["test", "123"]]
 181			)
 182			Registration::Activation::Finish.expect(
 183				:new,
 184				OpenStruct.new(write: EMPromise.reject(:test_result)),
 185				[@customer, "+15555550000"]
 186			)
 187			assert_equal(
 188				:test_result,
 189				execute_command { @activation.write.catch { |e| e } }
 190			)
 191			assert_mock Command::COMMAND_MANAGER
 192			assert_mock @customer
 193			assert_mock Registration::Activation::Payment
 194			assert_mock Registration::Activation::DB
 195		end
 196		em :test_write_with_code
 197
 198		def test_write_with_group_code
 199			Command::COMMAND_MANAGER.expect(
 200				:write,
 201				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 202					iq.form.fields = [
 203						{ var: "plan_name", value: "test_usd" },
 204						{ var: "code", value: "123" }
 205					]
 206				}),
 207				[Matching.new do |iq|
 208					assert_equal :form, iq.form.type
 209					assert_equal(
 210						"You've selected +15555550000 as your JMP number.",
 211						iq.form.instructions.lines.first.chomp
 212					)
 213				end]
 214			)
 215			@customer.expect(:with_plan, @customer, ["test_usd"])
 216			@customer.expect(:save_plan!, EMPromise.resolve(nil), [])
 217			Registration::Activation::DB.expect(:transaction, []) { |&blk| blk.call }
 218			Registration::Activation::DB.expect(
 219				:exec,
 220				OpenStruct.new(cmd_tuples: 0),
 221				[String, ["test", "123"]]
 222			)
 223			Registration::Activation::Payment.expect(
 224				:for,
 225				EMPromise.reject(:test_result),
 226				[Blather::Stanza::Iq, @customer, "+15555550000"]
 227			)
 228			assert_equal(
 229				:test_result,
 230				execute_command { @activation.write.catch { |e| e } }
 231			)
 232			assert_equal(
 233				"123",
 234				Registration::Activation::REDIS.get(
 235					"jmp_customer_pending_invite-test"
 236				).sync
 237			)
 238			assert_mock Command::COMMAND_MANAGER
 239			assert_mock @customer
 240			assert_mock Registration::Activation::Payment
 241			assert_mock Registration::Activation::DB
 242		end
 243		em :test_write_with_group_code
 244	end
 245
 246	class AllowTest < Minitest::Test
 247		Command::COMMAND_MANAGER = Minitest::Mock.new
 248		Registration::Activation::Allow::DB = Minitest::Mock.new
 249
 250		def test_write_credit_to_nil
 251			cust = Minitest::Mock.new(customer("test"))
 252			allow = Registration::Activation::Allow.new(cust, "+15555550000", nil)
 253
 254			Command::COMMAND_MANAGER.expect(
 255				:write,
 256				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 257					iq.form.fields = [{ var: "plan_name", value: "test_usd" }]
 258				}),
 259				[Matching.new do |iq|
 260					assert_equal :form, iq.form.type
 261					assert_equal(
 262						"You've selected +15555550000 as your JMP number.",
 263						iq.form.instructions.lines.first.chomp
 264					)
 265					assert_equal 1, iq.form.fields.length
 266				end]
 267			)
 268			Registration::Activation::Allow::DB.expect(
 269				:transaction,
 270				EMPromise.reject(:test_result)
 271			) do |&blk|
 272				blk.call
 273				true
 274			end
 275			cust.expect(:with_plan, cust, ["test_usd"])
 276			cust.expect(:activate_plan_starting_now, nil)
 277			assert_equal(
 278				:test_result,
 279				execute_command { allow.write.catch { |e| e } }
 280			)
 281			assert_mock Command::COMMAND_MANAGER
 282		end
 283		em :test_write_credit_to_nil
 284
 285		def test_write_credit_to_refercust
 286			cust = Minitest::Mock.new(customer("test"))
 287			allow = Registration::Activation::Allow.new(
 288				cust, "+15555550000", "refercust"
 289			)
 290
 291			Command::COMMAND_MANAGER.expect(
 292				:write,
 293				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 294					iq.form.fields = [{ var: "plan_name", value: "test_usd" }]
 295				}),
 296				[Matching.new do |iq|
 297					assert_equal :form, iq.form.type
 298					assert_equal(
 299						"You've selected +15555550000 as your JMP number.",
 300						iq.form.instructions.lines.first.chomp
 301					)
 302					assert_equal 1, iq.form.fields.length
 303				end]
 304			)
 305			Registration::Activation::Allow::DB.expect(
 306				:transaction,
 307				EMPromise.reject(:test_result)
 308			) do |&blk|
 309				blk.call
 310				true
 311			end
 312			Registration::Activation::Allow::DB.expect(
 313				:exec,
 314				nil,
 315				[String, ["refercust", "test"]]
 316			)
 317			cust.expect(:with_plan, cust, ["test_usd"])
 318			cust.expect(:activate_plan_starting_now, nil)
 319			assert_equal(
 320				:test_result,
 321				execute_command { allow.write.catch { |e| e } }
 322			)
 323			assert_mock Command::COMMAND_MANAGER
 324		end
 325		em :test_write_credit_to_refercust
 326	end
 327
 328	class GooglePlayTest < Minitest::Test
 329		CustomerPlan::DB = Minitest::Mock.new
 330		Registration::Activation::GooglePlay::Finish = Minitest::Mock.new
 331
 332		def setup
 333			@customer = customer
 334			@google_play = Registration::Activation::GooglePlay.new(
 335				@customer,
 336				"abcd",
 337				"+15555550000"
 338			)
 339		end
 340
 341		def test_write
 342			Command::COMMAND_MANAGER.expect(
 343				:write,
 344				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 345					iq.form.fields = [{ var: "plan_name", value: "test_usd" }]
 346				}),
 347				[Matching.new do |iq|
 348					assert_equal :form, iq.form.type
 349					assert_equal(
 350						"You've selected +15555550000 as your JMP number.",
 351						iq.form.instructions.lines.first.chomp
 352					)
 353				end]
 354			)
 355			CustomerPlan::DB.expect(
 356				:exec,
 357				OpenStruct.new(cmd_tuples: 1),
 358				[String, ["test", "test_usd", nil]]
 359			)
 360			CustomerPlan::DB.expect(
 361				:exec,
 362				OpenStruct.new(cmd_tuples: 0),
 363				[String, ["test"]]
 364			)
 365			Registration::Activation::GooglePlay::Finish.expect(
 366				:new,
 367				OpenStruct.new(write: EMPromise.reject(:test_result)),
 368				[Customer, "+15555550000"]
 369			)
 370			result = execute_command { @google_play.write.catch { |e| e } }
 371			assert_equal :test_result, result
 372			assert_mock Command::COMMAND_MANAGER
 373			assert_mock CustomerPlan::DB
 374			assert_mock Registration::Activation::GooglePlay::Finish
 375		end
 376		em :test_write
 377	end
 378
 379	class PaymentTest < Minitest::Test
 380		CustomerFinancials::BRAINTREE = Minitest::Mock.new
 381
 382		def test_for_bitcoin
 383			iq = Blather::Stanza::Iq::Command.new
 384			iq.form.fields = [
 385				{ var: "activation_method", value: "bitcoin" },
 386				{ var: "plan_name", value: "test_usd" }
 387			]
 388			result = Registration::Payment.for(iq, customer, "+15555550000")
 389			assert_kind_of Registration::Payment::Bitcoin, result
 390		end
 391
 392		def test_for_credit_card
 393			braintree_customer = Minitest::Mock.new
 394			CustomerFinancials::BRAINTREE.expect(
 395				:customer,
 396				braintree_customer
 397			)
 398			CustomerFinancials::REDIS.expect(:smembers, [], ["block_credit_cards"])
 399			braintree_customer.expect(
 400				:find,
 401				EMPromise.resolve(OpenStruct.new(payment_methods: [])),
 402				["test"]
 403			)
 404			iq = Blather::Stanza::Iq::Command.new
 405			iq.from = "test@example.com"
 406			iq.form.fields = [
 407				{ var: "activation_method", value: "credit_card" },
 408				{ var: "plan_name", value: "test_usd" }
 409			]
 410			cust = customer
 411			result = execute_command do
 412				Command.execution.customer_repo.expect(:find, cust, ["test"])
 413				Registration::Payment.for(
 414					iq,
 415					cust,
 416					""
 417				).sync
 418			end
 419			assert_kind_of Registration::Payment::CreditCard, result
 420		end
 421		em :test_for_credit_card
 422
 423		def test_for_code
 424			iq = Blather::Stanza::Iq::Command.new
 425			iq.form.fields = [
 426				{ var: "activation_method", value: "code" },
 427				{ var: "plan_name", value: "test_usd" }
 428			]
 429			result = Registration::Payment.for(
 430				iq,
 431				customer,
 432				"+15555550000"
 433			)
 434			assert_kind_of Registration::Payment::InviteCode, result
 435		end
 436
 437		class BitcoinTest < Minitest::Test
 438			Registration::Payment::Bitcoin::BTC_SELL_PRICES = Minitest::Mock.new
 439			CustomerFinancials::REDIS = Minitest::Mock.new
 440
 441			def setup
 442				@customer = Minitest::Mock.new(
 443					customer(plan_name: "test_usd")
 444				)
 445				@customer.expect(
 446					:add_btc_address,
 447					EMPromise.resolve("testaddr")
 448				)
 449				@bitcoin = Registration::Payment::Bitcoin.new(
 450					@customer,
 451					"+15555550000"
 452				)
 453			end
 454
 455			def test_write
 456				CustomerFinancials::REDIS.expect(
 457					:smembers,
 458					EMPromise.resolve([]),
 459					["jmp_customer_btc_addresses-test"]
 460				)
 461				blather = Minitest::Mock.new
 462				Command::COMMAND_MANAGER.expect(
 463					:write,
 464					EMPromise.reject(SessionManager::Timeout.new),
 465					[Matching.new do |reply|
 466						assert_equal :canceled, reply.status
 467						assert_equal "1.000000", reply.form.field("amount").value
 468						assert_equal "testaddr", reply.form.field("btc_addresses").value
 469						true
 470					end]
 471				)
 472				Registration::Payment::Bitcoin::BTC_SELL_PRICES.expect(
 473					:usd,
 474					EMPromise.resolve(BigDecimal(1))
 475				)
 476				@bitcoin.stub(:save, EMPromise.resolve(nil)) do
 477					execute_command(blather: blather) do
 478						@bitcoin.write
 479					end
 480				end
 481				assert_mock blather
 482			end
 483			em :test_write
 484		end
 485
 486		class CreditCardTest < Minitest::Test
 487			def setup
 488				@credit_card = Registration::Payment::CreditCard.new(
 489					customer,
 490					"+15555550000"
 491				)
 492			end
 493
 494			def test_for
 495				cust = Minitest::Mock.new(customer)
 496				cust.expect(
 497					:payment_methods,
 498					EMPromise.resolve(OpenStruct.new(default_payment_method: :test))
 499				)
 500				execute_command do
 501					Command.execution.customer_repo.expect(:find, cust, ["test"])
 502					assert_kind_of(
 503						Registration::Payment::CreditCard::Activate,
 504						Registration::Payment::CreditCard.for(
 505							cust,
 506							"+15555550000"
 507						).sync
 508					)
 509				end
 510			end
 511			em :test_for
 512
 513			def test_for_has_balance
 514				cust = Minitest::Mock.new(customer)
 515				cust.expect(:balance, 100)
 516				cust.expect(:payment_methods, EMPromise.resolve(nil))
 517				execute_command do
 518					Command.execution.customer_repo.expect(:find, cust, ["test"])
 519					assert_kind_of(
 520						Registration::BillPlan,
 521						Registration::Payment::CreditCard.for(
 522							cust,
 523							"+15555550000"
 524						).sync
 525					)
 526				end
 527			end
 528			em :test_for_has_balance
 529
 530			def test_write
 531				result = execute_command do
 532					Command::COMMAND_MANAGER.expect(
 533						:write,
 534						EMPromise.reject(:test_result),
 535						[Matching.new do |reply|
 536							assert_equal [:execute, :next, :prev], reply.allowed_actions
 537							assert_equal(
 538								"Add credit card, save, then next here to continue: " \
 539								"http://creditcard.example.com?&amount=1",
 540								reply.note.content
 541							)
 542						end]
 543					)
 544
 545					@credit_card.write.catch { |e| e }
 546				end
 547
 548				assert_equal :test_result, result
 549			end
 550			em :test_write
 551		end
 552
 553		class MailTest < Minitest::Test
 554			def setup
 555				@mail = Registration::Payment::Mail.new(
 556					customer(plan_name: "test_cad"),
 557					"+15555550000"
 558				)
 559			end
 560
 561			def test_write
 562				result = execute_command do
 563					Command::COMMAND_MANAGER.expect(
 564						:write,
 565						EMPromise.reject(:test_result),
 566						[Matching.new do |reply|
 567							assert_equal [:execute, :prev], reply.allowed_actions
 568							refute reply.form.instructions.empty?
 569							assert_equal(
 570								"A Mailing Address",
 571								reply.form.field("adr").value
 572							)
 573							assert_equal(
 574								"interac@example.com",
 575								reply.form.field("interac_email").value
 576							)
 577						end]
 578					)
 579
 580					@mail.write.catch { |e| e }
 581				end
 582
 583				assert_equal :test_result, result
 584			end
 585			em :test_write
 586		end
 587
 588		class ActivateTest < Minitest::Test
 589			Registration::Payment::CreditCard::Activate::Finish =
 590				Minitest::Mock.new
 591			Registration::Payment::CreditCard::Activate::CreditCardSale =
 592				Minitest::Mock.new
 593			Command::COMMAND_MANAGER = Minitest::Mock.new
 594
 595			def test_write
 596				customer = Minitest::Mock.new(
 597					customer(plan_name: "test_usd")
 598				)
 599				Registration::Payment::CreditCard::Activate::CreditCardSale.expect(
 600					:create,
 601					EMPromise.resolve(nil)
 602				) do |acustomer, amount:, payment_method:|
 603					assert_operator customer, :===, acustomer
 604					assert_equal CONFIG[:activation_amount], amount
 605					assert_equal :test_default_method, payment_method
 606				end
 607				customer.expect(
 608					:bill_plan,
 609					nil,
 610					note: "Bill +15555550000 for first month"
 611				)
 612				Registration::Payment::CreditCard::Activate::Finish.expect(
 613					:new,
 614					OpenStruct.new(write: nil),
 615					[customer, "+15555550000"]
 616				)
 617				execute_command do
 618					Registration::Payment::CreditCard::Activate.new(
 619						customer,
 620						:test_default_method,
 621						"+15555550000"
 622					).write
 623				end
 624				Registration::Payment::CreditCard::Activate::CreditCardSale.verify
 625				customer.verify
 626				Registration::Payment::CreditCard::Activate::Finish.verify
 627			end
 628			em :test_write
 629
 630			def test_write_declines
 631				customer = Minitest::Mock.new(
 632					customer(plan_name: "test_usd")
 633				)
 634				iq = Blather::Stanza::Iq::Command.new
 635				iq.from = "test@example.com"
 636				msg = Registration::Payment::CreditCard::Activate::DECLINE_MESSAGE
 637				Command::COMMAND_MANAGER.expect(
 638					:write,
 639					EMPromise.reject(:test_result),
 640					[Matching.new do |reply|
 641						assert_equal :error, reply.note_type
 642						assert_equal(
 643							"#{msg}: http://creditcard.example.com?&amount=1",
 644							reply.note.content
 645						)
 646					end]
 647				)
 648				result = execute_command do
 649					Registration::Payment::CreditCard::Activate::CreditCardSale.expect(
 650						:create,
 651						EMPromise.reject("declined")
 652					) do |acustomer, amount:, payment_method:|
 653						assert_operator customer, :===, acustomer
 654						assert_equal CONFIG[:activation_amount], amount
 655						assert_equal :test_default_method, payment_method
 656					end
 657
 658					Registration::Payment::CreditCard::Activate.new(
 659						customer,
 660						:test_default_method,
 661						"+15555550000"
 662					).write.catch { |e| e }
 663				end
 664				assert_equal :test_result, result
 665				Registration::Payment::CreditCard::Activate::CreditCardSale.verify
 666			end
 667			em :test_write_declines
 668		end
 669
 670		class InviteCodeTest < Minitest::Test
 671			Registration::Payment::InviteCode::DB =
 672				Minitest::Mock.new
 673			Registration::Payment::InviteCode::REDIS =
 674				Minitest::Mock.new
 675			Command::COMMAND_MANAGER = Minitest::Mock.new
 676			Registration::Payment::InviteCode::Finish =
 677				Minitest::Mock.new
 678			def test_write
 679				customer = customer(plan_name: "test_usd")
 680				Registration::Payment::InviteCode::DB.expect(:transaction, true, [])
 681				Registration::Payment::InviteCode::Finish.expect(
 682					:new,
 683					OpenStruct.new(write: nil),
 684					[
 685						customer,
 686						"+15555550000"
 687					]
 688				)
 689				execute_command do
 690					Registration::Payment::InviteCode::REDIS.expect(
 691						:get,
 692						EMPromise.resolve(nil),
 693						["jmp_invite_tries-test"]
 694					)
 695					Command::COMMAND_MANAGER.expect(
 696						:write,
 697						EMPromise.resolve(
 698							Blather::Stanza::Iq::Command.new.tap { |iq|
 699								iq.form.fields = [{ var: "code", value: "abc" }]
 700							}
 701						),
 702						[Matching.new do |reply|
 703							assert_equal :form, reply.form.type
 704							assert_nil reply.form.instructions
 705						end]
 706					)
 707
 708					Registration::Payment::InviteCode.new(
 709						customer,
 710						"+15555550000"
 711					).write
 712				end
 713				assert_mock Command::COMMAND_MANAGER
 714				assert_mock Registration::Payment::InviteCode::DB
 715				assert_mock Registration::Payment::InviteCode::REDIS
 716				assert_mock Registration::Payment::InviteCode::Finish
 717			end
 718			em :test_write
 719
 720			def test_write_bad_code
 721				result = execute_command do
 722					customer = customer(plan_name: "test_usd")
 723					Registration::Payment::InviteCode::REDIS.expect(
 724						:get,
 725						EMPromise.resolve(0),
 726						["jmp_invite_tries-test"]
 727					)
 728					Registration::Payment::InviteCode::DB.expect(
 729						:transaction,
 730						[]
 731					) { |&blk| blk.call }
 732					Registration::Payment::InviteCode::DB.expect(
 733						:exec,
 734						OpenStruct.new(cmd_tuples: 0),
 735						[String, ["test", "abc"]]
 736					)
 737					Registration::Payment::InviteCode::REDIS.expect(
 738						:incr,
 739						EMPromise.resolve(nil),
 740						["jmp_invite_tries-test"]
 741					)
 742					Registration::Payment::InviteCode::REDIS.expect(
 743						:expire,
 744						EMPromise.resolve(nil),
 745						["jmp_invite_tries-test", 60 * 60]
 746					)
 747					Registration::Payment::InviteCode::REDIS.expect(
 748						:hexists,
 749						EMPromise.resolve(0),
 750						["jmp_group_codes", "abc"]
 751					)
 752					Command::COMMAND_MANAGER.expect(
 753						:write,
 754						EMPromise.resolve(
 755							Blather::Stanza::Iq::Command.new.tap { |iq|
 756								iq.form.fields = [{ var: "code", value: "abc" }]
 757							}
 758						),
 759						[Matching.new do |reply|
 760							assert_equal :form, reply.form.type
 761							assert_nil reply.form.instructions
 762						end]
 763					)
 764					Command::COMMAND_MANAGER.expect(
 765						:write,
 766						EMPromise.reject(:test_result),
 767						[Matching.new do |reply|
 768							assert_equal :form, reply.form.type
 769							assert_equal(
 770								"Not a valid invite code: abc",
 771								reply.form.instructions
 772							)
 773						end]
 774					)
 775
 776					Registration::Payment::InviteCode.new(
 777						customer,
 778						"+15555550000"
 779					).write.catch { |e| e }
 780				end
 781				assert_equal :test_result, result
 782				assert_mock Command::COMMAND_MANAGER
 783				assert_mock Registration::Payment::InviteCode::DB
 784				assert_mock Registration::Payment::InviteCode::REDIS
 785			end
 786			em :test_write_bad_code
 787
 788			def test_write_group_code
 789				result = execute_command do
 790					customer = customer(plan_name: "test_usd")
 791					Registration::Payment::InviteCode::REDIS.expect(
 792						:get,
 793						EMPromise.resolve(0),
 794						["jmp_invite_tries-test"]
 795					)
 796					Registration::Payment::InviteCode::DB.expect(
 797						:transaction,
 798						[]
 799					) { |&blk| blk.call }
 800					Registration::Payment::InviteCode::DB.expect(
 801						:exec,
 802						OpenStruct.new(cmd_tuples: 0),
 803						[String, ["test", "abc"]]
 804					)
 805					Registration::Payment::InviteCode::REDIS.expect(
 806						:incr,
 807						EMPromise.resolve(nil),
 808						["jmp_invite_tries-test"]
 809					)
 810					Registration::Payment::InviteCode::REDIS.expect(
 811						:expire,
 812						EMPromise.resolve(nil),
 813						["jmp_invite_tries-test", 60 * 60]
 814					)
 815					Registration::Payment::InviteCode::REDIS.expect(
 816						:hexists,
 817						EMPromise.resolve(1),
 818						["jmp_group_codes", "abc"]
 819					)
 820					Command::COMMAND_MANAGER.expect(
 821						:write,
 822						EMPromise.resolve(
 823							Blather::Stanza::Iq::Command.new.tap { |iq|
 824								iq.form.fields = [{ var: "code", value: "abc" }]
 825							}
 826						),
 827						[Matching.new do |reply|
 828							assert_equal :form, reply.form.type
 829							assert_nil reply.form.instructions
 830						end]
 831					)
 832					Command::COMMAND_MANAGER.expect(
 833						:write,
 834						EMPromise.reject(:test_result),
 835						[Matching.new do |reply|
 836							assert_equal :form, reply.form.type
 837							assert_equal(
 838								"abc is a post-payment referral",
 839								reply.form.instructions
 840							)
 841						end]
 842					)
 843
 844					Registration::Payment::InviteCode.new(
 845						customer,
 846						"+15555550000"
 847					).write.catch { |e| e }
 848				end
 849				assert_equal :test_result, result
 850				assert_mock Command::COMMAND_MANAGER
 851				assert_mock Registration::Payment::InviteCode::DB
 852				assert_mock Registration::Payment::InviteCode::REDIS
 853			end
 854			em :test_write_group_code
 855
 856			def test_write_bad_code_over_limit
 857				result = execute_command do
 858					customer = customer(plan_name: "test_usd")
 859					Registration::Payment::InviteCode::REDIS.expect(
 860						:get,
 861						EMPromise.resolve(11),
 862						["jmp_invite_tries-test"]
 863					)
 864					Command::COMMAND_MANAGER.expect(
 865						:write,
 866						EMPromise.resolve(
 867							Blather::Stanza::Iq::Command.new.tap { |iq|
 868								iq.form.fields = [{ var: "code", value: "abc" }]
 869							}
 870						),
 871						[Matching.new do |reply|
 872							assert_equal :form, reply.form.type
 873							assert_nil reply.form.instructions
 874						end]
 875					)
 876					Command::COMMAND_MANAGER.expect(
 877						:write,
 878						EMPromise.reject(:test_result),
 879						[Matching.new do |reply|
 880							assert_equal :form, reply.form.type
 881							assert_equal "Too many wrong attempts", reply.form.instructions
 882						end]
 883					)
 884					Registration::Payment::InviteCode.new(
 885						customer,
 886						"+15555550000"
 887					).write.catch { |e| e }
 888				end
 889				assert_equal :test_result, result
 890				assert_mock Command::COMMAND_MANAGER
 891				assert_mock Registration::Payment::InviteCode::REDIS
 892			end
 893			em :test_write_bad_code_over_limit
 894		end
 895	end
 896
 897	class FinishTest < Minitest::Test
 898		Customer::BLATHER = Minitest::Mock.new
 899		Command::COMMAND_MANAGER = Minitest::Mock.new
 900		Registration::Finish::TEL_SELECTIONS = FakeTelSelections.new
 901		Registration::Finish::REDIS = Minitest::Mock.new
 902		Registration::Finish::DB = Minitest::Mock.new
 903		Bwmsgsv2Repo::REDIS = Minitest::Mock.new
 904		Registration::FinishOnboarding::DB = FakeDB.new
 905		Transaction::DB = Minitest::Mock.new
 906
 907		def setup
 908			@sgx = Minitest::Mock.new(TrivialBackendSgxRepo.new.get("test"))
 909			iq = Blather::Stanza::Iq::Command.new
 910			iq.from = "test\\40example.com@cheogram.com"
 911			@finish = Registration::Finish.new(
 912				customer(sgx: @sgx, plan_name: "test_usd"),
 913				"+15555550000"
 914			)
 915		end
 916
 917		def test_write
 918			create_order = stub_request(
 919				:post,
 920				"https://dashboard.bandwidth.com/v1.0/accounts//orders"
 921			).to_return(status: 201, body: <<~RESPONSE)
 922				<OrderResponse>
 923					<Order>
 924						<id>test_order</id>
 925					</Order>
 926				</OrderResponse>
 927			RESPONSE
 928			stub_request(
 929				:get,
 930				"https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
 931			).to_return(status: 201, body: <<~RESPONSE)
 932				<OrderResponse>
 933					<OrderStatus>COMPLETE</OrderStatus>
 934					<CompletedNumbers>
 935						<TelephoneNumber>
 936							<FullNumber>5555550000</FullNumber>
 937						</TelephoneNumber>
 938					</CompletedNumbers>
 939				</OrderResponse>
 940			RESPONSE
 941			stub_request(
 942				:post,
 943				"https://dashboard.bandwidth.com/v1.0/accounts//sites//sippeers//movetns"
 944			)
 945			Registration::Finish::REDIS.expect(
 946				:del,
 947				nil,
 948				["pending_tel_for-test@example.net"]
 949			)
 950			Registration::Finish::REDIS.expect(
 951				:get,
 952				nil,
 953				["jmp_customer_pending_invite-test"]
 954			)
 955			Registration::Finish::REDIS.expect(
 956				:del,
 957				nil,
 958				["jmp_customer_pending_invite-test"]
 959			)
 960			Registration::Finish::REDIS.expect(
 961				:hget,
 962				nil,
 963				["jmp_group_codes", nil]
 964			)
 965			Bwmsgsv2Repo::REDIS.expect(
 966				:set,
 967				nil,
 968				[
 969					"catapult_fwd-+15555550000",
 970					"xmpp:test@example.net"
 971				]
 972			)
 973			Bwmsgsv2Repo::REDIS.expect(
 974				:set,
 975				nil,
 976				["catapult_fwd_timeout-customer_test@component", 25]
 977			)
 978			Customer::BLATHER.expect(
 979				:<<,
 980				nil,
 981				[Matching.new do |m|
 982					assert_equal :chat, m.type
 983					assert m.body =~ /^Welcome to JMP/
 984				end]
 985			)
 986			blather = Minitest::Mock.new
 987			blather.expect(
 988				:<<,
 989				nil,
 990				[Matching.new do |reply|
 991					assert_equal :completed, reply.status
 992					assert_equal :info, reply.note_type
 993					assert_equal(
 994						"Your JMP account has been activated as +15555550000",
 995						reply.note.content
 996					)
 997				end]
 998			)
 999			execute_command(blather: blather) do
1000				@sgx.expect(
1001					:register!,
1002					EMPromise.resolve(@sgx.with(
1003						registered?: Blather::Stanza::Iq::IBR.new.tap do |ibr|
1004							ibr.phone = "+15555550000"
1005						end
1006					)),
1007					["+15555550000"]
1008				)
1009
1010				@finish.write
1011			end
1012			assert_requested create_order
1013			assert_mock @sgx
1014			assert_mock Registration::Finish::REDIS
1015			assert_mock Bwmsgsv2Repo::REDIS
1016			assert_mock Customer::BLATHER
1017			assert_mock blather
1018		end
1019		em :test_write
1020
1021		def test_write_with_pending_code
1022			create_order = stub_request(
1023				:post,
1024				"https://dashboard.bandwidth.com/v1.0/accounts//orders"
1025			).to_return(status: 201, body: <<~RESPONSE)
1026				<OrderResponse>
1027					<Order>
1028						<id>test_order</id>
1029					</Order>
1030				</OrderResponse>
1031			RESPONSE
1032			stub_request(
1033				:get,
1034				"https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
1035			).to_return(status: 201, body: <<~RESPONSE)
1036				<OrderResponse>
1037					<OrderStatus>COMPLETE</OrderStatus>
1038					<CompletedNumbers>
1039						<TelephoneNumber>
1040							<FullNumber>5555550000</FullNumber>
1041						</TelephoneNumber>
1042					</CompletedNumbers>
1043				</OrderResponse>
1044			RESPONSE
1045			stub_request(
1046				:post,
1047				"https://dashboard.bandwidth.com/v1.0/accounts//sites//sippeers//movetns"
1048			)
1049			Registration::Finish::REDIS.expect(
1050				:del,
1051				nil,
1052				["pending_tel_for-test@example.net"]
1053			)
1054			Registration::Finish::REDIS.expect(
1055				:get,
1056				EMPromise.resolve("123"),
1057				["jmp_customer_pending_invite-test"]
1058			)
1059			Registration::Finish::REDIS.expect(
1060				:del,
1061				nil,
1062				["jmp_customer_pending_invite-test"]
1063			)
1064			Registration::Finish::REDIS.expect(
1065				:hget,
1066				EMPromise.resolve("test-inviter"),
1067				["jmp_group_codes", "123"]
1068			)
1069			Registration::Finish::DB.expect(
1070				:exec,
1071				EMPromise.resolve(nil),
1072				[String, ["test-inviter", "test"]]
1073			)
1074			Transaction::DB.expect(:transaction, nil) do |&blk|
1075				blk.call
1076				true
1077			end
1078			Transaction::DB.expect(
1079				:exec,
1080				nil,
1081				[String, Matching.new { |params|
1082					assert_equal "test", params[0]
1083					assert params[1].start_with?("referral_")
1084					assert_equal 1, params[4]
1085					assert_equal "Referral Bonus", params[5]
1086				}]
1087			)
1088			Bwmsgsv2Repo::REDIS.expect(
1089				:set,
1090				nil,
1091				[
1092					"catapult_fwd-+15555550000",
1093					"xmpp:test@example.net"
1094				]
1095			)
1096			Bwmsgsv2Repo::REDIS.expect(
1097				:set,
1098				nil,
1099				["catapult_fwd_timeout-customer_test@component", 25]
1100			)
1101			Customer::BLATHER.expect(
1102				:<<,
1103				nil,
1104				[Matching.new do |m|
1105					assert_equal :chat, m.type
1106					assert m.body =~ /^Welcome to JMP/
1107				end]
1108			)
1109			blather = Minitest::Mock.new
1110			blather.expect(
1111				:<<,
1112				nil,
1113				[Matching.new do |reply|
1114					assert_equal :completed, reply.status
1115					assert_equal :info, reply.note_type
1116					assert_equal(
1117						"Your JMP account has been activated as +15555550000",
1118						reply.note.content
1119					)
1120				end]
1121			)
1122			execute_command(blather: blather) do
1123				@sgx.expect(
1124					:register!,
1125					EMPromise.resolve(@sgx.with(
1126						registered?: Blather::Stanza::Iq::IBR.new.tap do |ibr|
1127							ibr.phone = "+15555550000"
1128						end
1129					)),
1130					["+15555550000"]
1131				)
1132
1133				@finish.write
1134			end
1135			assert_requested create_order
1136			assert_mock @sgx
1137			assert_mock Registration::Finish::REDIS
1138			assert_mock Bwmsgsv2Repo::REDIS
1139			assert_mock Customer::BLATHER
1140			assert_mock blather
1141			assert_mock Transaction::DB
1142		end
1143		em :test_write_with_pending_code
1144
1145		def test_write_onboarding
1146			create_order = stub_request(
1147				:post,
1148				"https://dashboard.bandwidth.com/v1.0/accounts//orders"
1149			).to_return(status: 201, body: <<~RESPONSE)
1150				<OrderResponse>
1151					<Order>
1152						<id>test_order</id>
1153					</Order>
1154				</OrderResponse>
1155			RESPONSE
1156			stub_request(
1157				:get,
1158				"https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
1159			).to_return(status: 201, body: <<~RESPONSE)
1160				<OrderResponse>
1161					<OrderStatus>COMPLETE</OrderStatus>
1162					<CompletedNumbers>
1163						<TelephoneNumber>
1164							<FullNumber>5555550000</FullNumber>
1165						</TelephoneNumber>
1166					</CompletedNumbers>
1167				</OrderResponse>
1168			RESPONSE
1169			stub_request(
1170				:post,
1171				"https://dashboard.bandwidth.com/v1.0/accounts//sites//sippeers//movetns"
1172			)
1173			Registration::Finish::REDIS.expect(
1174				:del,
1175				nil,
1176				["pending_tel_for-test\\40onboarding.example.com@proxy"]
1177			)
1178			Registration::Finish::REDIS.expect(
1179				:get,
1180				nil,
1181				["jmp_customer_pending_invite-test"]
1182			)
1183			Registration::Finish::REDIS.expect(
1184				:del,
1185				nil,
1186				["jmp_customer_pending_invite-test"]
1187			)
1188			Registration::Finish::REDIS.expect(
1189				:hget,
1190				nil,
1191				["jmp_group_codes", nil]
1192			)
1193			Bwmsgsv2Repo::REDIS.expect(
1194				:set,
1195				nil,
1196				[
1197					"catapult_fwd-+15555550000",
1198					"xmpp:test\\40onboarding.example.com@proxy"
1199				]
1200			)
1201			Bwmsgsv2Repo::REDIS.expect(
1202				:set,
1203				nil,
1204				["catapult_fwd_timeout-customer_test@component", 25]
1205			)
1206			result = execute_command do
1207				@sgx.expect(
1208					:register!,
1209					EMPromise.resolve(@sgx.with(
1210						registered?: Blather::Stanza::Iq::IBR.new.tap do |ibr|
1211							ibr.phone = "+15555550000"
1212						end
1213					)),
1214					["+15555550000"]
1215				)
1216
1217				Command::COMMAND_MANAGER.expect(
1218					:write,
1219					EMPromise.reject(:test_result),
1220					[Matching.new do |iq|
1221						assert_equal :form, iq.form.type
1222						assert iq.form.field("subdomain")
1223					end]
1224				)
1225
1226				Registration::Finish.new(
1227					customer(
1228						sgx: @sgx,
1229						jid: Blather::JID.new("test\\40onboarding.example.com@proxy")
1230					),
1231					"+15555550000"
1232				).write.catch { |e| e }
1233			end
1234			assert_equal :test_result, result
1235			assert_requested create_order
1236			assert_mock @sgx
1237			assert_mock Registration::Finish::REDIS
1238			assert_mock Bwmsgsv2Repo::REDIS
1239			assert_mock Command::COMMAND_MANAGER
1240		end
1241		em :test_write_onboarding
1242
1243		def test_write_tn_fail
1244			create_order = stub_request(
1245				:post,
1246				"https://dashboard.bandwidth.com/v1.0/accounts//orders"
1247			).to_return(status: 201, body: <<~RESPONSE)
1248				<OrderResponse>
1249					<Order>
1250						<id>test_order</id>
1251					</Order>
1252				</OrderResponse>
1253			RESPONSE
1254			stub_request(
1255				:get,
1256				"https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
1257			).to_return(status: 201, body: <<~RESPONSE)
1258				<OrderResponse>
1259					<OrderStatus>FAILED</OrderStatus>
1260				</OrderResponse>
1261			RESPONSE
1262
1263			result = execute_command do
1264				Command::COMMAND_MANAGER.expect(
1265					:write,
1266					EMPromise.reject(:test_result),
1267					[Matching.new do |iq|
1268						assert_equal :form, iq.form.type
1269						assert_equal(
1270							"The JMP number +15555550000 is no longer available.",
1271							iq.form.instructions
1272						)
1273					end]
1274				)
1275
1276				@finish.write.catch { |e| e }
1277			end
1278
1279			assert_equal :test_result, result
1280			assert_mock Command::COMMAND_MANAGER
1281			assert_instance_of(
1282				TelSelections::ChooseTel,
1283				Registration::Finish::TEL_SELECTIONS["test@example.com"]
1284			)
1285			assert_requested create_order
1286		end
1287		em :test_write_tn_fail
1288	end
1289
1290	class SnikketTest < Minitest::Test
1291		Command::COMMAND_MANAGER = Minitest::Mock.new
1292		Registration::FinishOnboarding::Snikket::IQ_MANAGER = Minitest::Mock.new
1293
1294		def setup
1295			@sgx = Minitest::Mock.new(TrivialBackendSgxRepo.new.get("test"))
1296			@snikket = Registration::FinishOnboarding::Snikket.new(
1297				customer,
1298				"+15555550000",
1299				db: FakeDB.new
1300			)
1301		end
1302
1303		def test_write
1304			xmpp_uri = "xmpp:test.snikket.chat?register;preauth=NEWTOKEN"
1305
1306			subdomain_form = Blather::Stanza::Iq::Command.new
1307			subdomain_form.form.fields = [
1308				{ var: "subdomain", value: "test" }
1309			]
1310
1311			launched = Snikket::Launched.new
1312			launched << Niceogiri::XML::Node.new(
1313				:launched, launched.document, "xmpp:snikket.org/hosting/v1"
1314			).tap { |inner|
1315				inner << Niceogiri::XML::Node.new(
1316					:'instance-id', launched.document, "xmpp:snikket.org/hosting/v1"
1317				).tap { |id|
1318					id.content = "si-1234"
1319				}
1320				inner << Niceogiri::XML::Node.new(
1321					:bootstrap, launched.document, "xmpp:snikket.org/hosting/v1"
1322				).tap { |bootstrap|
1323					bootstrap << Niceogiri::XML::Node.new(
1324						:token, launched.document, "xmpp:snikket.org/hosting/v1"
1325					).tap { |token|
1326						token.content = "TOKEN"
1327					}
1328				}
1329			}
1330
1331			blather = Minitest::Mock.new
1332			blather.expect(
1333				:<<,
1334				nil,
1335				[Matching.new do |reply|
1336					assert_equal :completed, reply.status
1337					assert_equal(
1338						xmpp_uri,
1339						OOB.find_or_create(reply.command).url
1340					)
1341				end]
1342			)
1343
1344			execute_command(blather: blather) do
1345				Command::COMMAND_MANAGER.expect(
1346					:write,
1347					EMPromise.resolve(subdomain_form),
1348					[Matching.new do |iq|
1349						assert_equal :form, iq.form.type
1350						assert iq.form.field("subdomain")
1351					end]
1352				)
1353
1354				Registration::FinishOnboarding::Snikket::IQ_MANAGER.expect(
1355					:write,
1356					EMPromise.resolve(launched),
1357					[Matching.new do |iq|
1358						assert_equal :set, iq.type
1359						assert_equal CONFIG[:snikket_hosting_api], iq.to.to_s
1360						assert_equal(
1361							"test.snikket.chat",
1362							iq.xpath(
1363								"./ns:launch/ns:domain",
1364								ns: "xmpp:snikket.org/hosting/v1"
1365							).text
1366						)
1367					end]
1368				)
1369
1370				# Webmock doesn't support redirects properly, but they work live
1371				stub_request(
1372					:head, "https://test.snikket.chat/invites_bootstrap?token=TOKEN"
1373				).to_return(
1374					status: 200,
1375					headers: {
1376						"link" => "<#{xmpp_uri}>; rel=\"alternate\""
1377					}
1378				)
1379
1380				@snikket.write
1381			end
1382
1383			assert_mock Command::COMMAND_MANAGER
1384			assert_mock Registration::FinishOnboarding::Snikket::IQ_MANAGER
1385			assert_mock blather
1386		end
1387		em :test_write
1388
1389		def test_write_not_yet
1390			subdomain_form = Blather::Stanza::Iq::Command.new
1391			subdomain_form.form.fields = [
1392				{ var: "subdomain", value: "test" }
1393			]
1394
1395			launched = Snikket::Launched.new
1396			launched << Niceogiri::XML::Node.new(
1397				:launched, launched.document, "xmpp:snikket.org/hosting/v1"
1398			).tap { |inner|
1399				inner << Niceogiri::XML::Node.new(
1400					:'instance-id', launched.document, "xmpp:snikket.org/hosting/v1"
1401				).tap { |id|
1402					id.content = "si-1234"
1403				}
1404				inner << Niceogiri::XML::Node.new(
1405					:bootstrap, launched.document, "xmpp:snikket.org/hosting/v1"
1406				).tap { |bootstrap|
1407					bootstrap << Niceogiri::XML::Node.new(
1408						:token, launched.document, "xmpp:snikket.org/hosting/v1"
1409					).tap { |token|
1410						token.content = "TOKEN"
1411					}
1412				}
1413			}
1414
1415			result = execute_command do
1416				Command::COMMAND_MANAGER.expect(
1417					:write,
1418					EMPromise.resolve(subdomain_form),
1419					[Matching.new do |iq|
1420						assert_equal :form, iq.form.type
1421						assert iq.form.field("subdomain")
1422					end]
1423				)
1424
1425				Registration::FinishOnboarding::Snikket::IQ_MANAGER.expect(
1426					:write,
1427					EMPromise.resolve(launched),
1428					[Matching.new do |iq|
1429						assert_equal :set, iq.type
1430						assert_equal CONFIG[:snikket_hosting_api], iq.to.to_s
1431						assert_equal(
1432							"test.snikket.chat",
1433							iq.xpath(
1434								"./ns:launch/ns:domain",
1435								ns: "xmpp:snikket.org/hosting/v1"
1436							).text
1437						)
1438					end]
1439				)
1440
1441				stub_request(
1442					:head, "https://test.snikket.chat/invites_bootstrap?token=TOKEN"
1443				).to_timeout
1444
1445				Command::COMMAND_MANAGER.expect(
1446					:write,
1447					EMPromise.reject(:test_result),
1448					[Matching.new do |iq|
1449						assert_equal :result, iq.form.type
1450						assert iq.form.instructions =~ / test\.snikket\.chat /
1451						assert_equal "jid-single", iq.form.field("support").type
1452					end]
1453				)
1454
1455				@snikket.write.catch { |e| e }
1456			end
1457
1458			assert_equal :test_result, result
1459			assert_mock Command::COMMAND_MANAGER
1460			assert_mock Registration::FinishOnboarding::Snikket::IQ_MANAGER
1461		end
1462		em :test_write_not_yet
1463
1464		def test_write_already_taken
1465			subdomain_form = Blather::Stanza::Iq::Command.new
1466			subdomain_form.form.fields = [
1467				{ var: "subdomain", value: "test" }
1468			]
1469
1470			launched = Snikket::Launched.new.as_error(
1471				"internal-server-error",
1472				:wait,
1473				"This is an error"
1474			)
1475
1476			result = execute_command do
1477				Command::COMMAND_MANAGER.expect(
1478					:write,
1479					EMPromise.resolve(subdomain_form),
1480					[Matching.new do |iq|
1481						assert_equal :form, iq.form.type
1482						assert iq.form.field("subdomain")
1483					end]
1484				)
1485
1486				Registration::FinishOnboarding::Snikket::IQ_MANAGER.expect(
1487					:write,
1488					EMPromise.reject(launched),
1489					[Matching.new do |iq|
1490						assert_equal :set, iq.type
1491						assert_equal CONFIG[:snikket_hosting_api], iq.to.to_s
1492						assert_equal(
1493							"test.snikket.chat",
1494							iq.xpath(
1495								"./ns:launch/ns:domain",
1496								ns: "xmpp:snikket.org/hosting/v1"
1497							).text
1498						)
1499					end]
1500				)
1501
1502				stub_request(
1503					:head, "https://test.snikket.chat/invites_bootstrap?token=TOKEN"
1504				).to_timeout
1505
1506				Command::COMMAND_MANAGER.expect(
1507					:write,
1508					EMPromise.reject(:test_result),
1509					[Matching.new do |iq|
1510						assert iq.executing?
1511						assert_equal(
1512							"This is an error",
1513							iq.form.field("subdomain").desc
1514						)
1515					end]
1516				)
1517
1518				@snikket.write.catch { |e| e }
1519			end
1520
1521			assert_equal :test_result, result
1522			assert_mock Command::COMMAND_MANAGER
1523			assert_mock Registration::FinishOnboarding::Snikket::IQ_MANAGER
1524		end
1525		em :test_write_already_taken
1526	end
1527
1528	class SnikketCustomDomainTest < Minitest::Test
1529		def setup
1530			@snikket = Registration::FinishOnboarding::CustomDomain.new(
1531				customer,
1532				"+15555550000",
1533				db: FakeDB.new
1534			)
1535		end
1536
1537		def test_write_needs_dns
1538			domain_form = Blather::Stanza::Iq::Command.new
1539			domain_form.form.fields = [
1540				{ var: "domain", value: "snikket.example.com" }
1541			]
1542
1543			launched = Snikket::Launched.new
1544			launched << Niceogiri::XML::Node.new(
1545				:launched, launched.document, "xmpp:snikket.org/hosting/v1"
1546			).tap { |inner|
1547				inner << Niceogiri::XML::Node.new(
1548					:'instance-id', launched.document, "xmpp:snikket.org/hosting/v1"
1549				).tap { |id|
1550					id.content = "si-1234"
1551				}
1552				inner << Niceogiri::XML::Node.new(
1553					:status, launched.document, "xmpp:snikket.org/hosting/v1"
1554				).tap { |id|
1555					id.content = "needs_dns"
1556				}
1557				inner << Niceogiri::XML::Node.new(
1558					:records, launched.document, "xmpp:snikket.org/hosting/v1"
1559				).tap { |records|
1560					records << Niceogiri::XML::Node.new(
1561						:record, launched.document, "xmpp:snikket.org/hosting/v1"
1562					).tap { |record|
1563						record << Niceogiri::XML::Node.new(
1564							:name, launched.document, "xmpp:snikket.org/hosting/v1"
1565						).tap { |name| name.content = "snikket.example.com" }
1566						record << Niceogiri::XML::Node.new(
1567							:type, launched.document, "xmpp:snikket.org/hosting/v1"
1568						).tap { |type| type.content = "AAAA" }
1569						record << Niceogiri::XML::Node.new(
1570							:status, launched.document, "xmpp:snikket.org/hosting/v1"
1571						).tap { |type| type.content = "incorrect" }
1572						record << Niceogiri::XML::Node.new(
1573							:expected, launched.document, "xmpp:snikket.org/hosting/v1"
1574						).tap { |expected|
1575							expected << Niceogiri::XML::Node.new(
1576								:value, launched.document, "xmpp:snikket.org/hosting/v1"
1577							).tap { |value| value.content = "1::2" }
1578						}
1579						record << Niceogiri::XML::Node.new(
1580							:found, launched.document, "xmpp:snikket.org/hosting/v1"
1581						).tap { |found|
1582							found << Niceogiri::XML::Node.new(
1583								:value, launched.document, "xmpp:snikket.org/hosting/v1"
1584							).tap { |value| value.content = "0::0" }
1585						}
1586					}
1587				}
1588			}
1589
1590			result = execute_command do
1591				Command::COMMAND_MANAGER.expect(
1592					:write,
1593					EMPromise.resolve(domain_form),
1594					[Matching.new do |iq|
1595						assert_equal :form, iq.form.type
1596						assert iq.form.field("domain")
1597					end]
1598				)
1599
1600				Registration::FinishOnboarding::Snikket::IQ_MANAGER.expect(
1601					:write,
1602					EMPromise.resolve(launched),
1603					[Matching.new do |iq|
1604						assert_equal :set, iq.type
1605						assert_equal CONFIG[:snikket_hosting_api], iq.to.to_s
1606						assert_equal(
1607							"snikket.example.com",
1608							iq.xpath(
1609								"./ns:launch/ns:domain",
1610								ns: "xmpp:snikket.org/hosting/v1"
1611							).text
1612						)
1613					end]
1614				)
1615
1616				Command::COMMAND_MANAGER.expect(
1617					:write,
1618					EMPromise.reject(:test_result),
1619					[Matching.new do |iq|
1620						assert_equal :form, iq.form.type
1621						assert_equal(
1622							["snikket.example.com"],
1623							iq.form.xpath(
1624								"./ns:item/ns:field[@var='name']/ns:value",
1625								ns: "jabber:x:data"
1626							).map(&:content)
1627						)
1628						assert_equal(
1629							["1::2"],
1630							iq.form.xpath(
1631								"./ns:item/ns:field[@var='expected']/ns:value",
1632								ns: "jabber:x:data"
1633							).map(&:content)
1634						)
1635					end]
1636				)
1637
1638				@snikket.write.catch { |e| e }
1639			end
1640
1641			assert_equal :test_result, result
1642			assert_mock Command::COMMAND_MANAGER
1643			assert_mock Registration::FinishOnboarding::Snikket::IQ_MANAGER
1644		end
1645		em :test_write_needs_dns
1646	end
1647end