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