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		).to_return(
  32			status: 201,
  33			headers: {
  34				location: "https://dashboard.bandwidth.com/api/accounts//TnReservation/8da0f39c-043c-4806-9f0f-497b2d197bc5"
  35			}
  36		)
  37		stub_request(
  38			:get, "https://dashboard.bandwidth.com/v1.0/accounts//tnreservation/8da0f39c-043c-4806-9f0f-497b2d197bc5"
  39		).to_return(status: 200, body: <<~RESPONSE)
  40			<ReservationResponse>
  41				<Reservation>
  42					<ReservationId>f342904f-b03a-4499-bac0-e8f43a2664a1</ReservationId>
  43					<AccountId>12346099</AccountId>
  44					<ReservationExpires>1492</ReservationExpires>
  45					<ReservedTn>4354776010</ReservedTn>
  46				</Reservation>
  47			</ReservationResponse>
  48		RESPONSE
  49		web_manager = TelSelections.new(
  50			redis: FakeRedis.new, db: FakeDB.new, memcache: FakeMemcache.new
  51		)
  52		web_manager.set(
  53			"test@example.net",
  54			TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
  55		)
  56		result = execute_command do
  57			sgx = OpenStruct.new(registered?: false)
  58			Registration.for(
  59				customer(
  60					plan_name: "test_usd",
  61					expires_at: Time.now + 999,
  62					sgx: sgx
  63				),
  64				nil,
  65				web_manager
  66			)
  67		end
  68		assert_kind_of Registration::Finish, result
  69		assert_requested reservation_req
  70	end
  71	em :test_for_activated
  72
  73	def test_for_not_activated_approved
  74		sgx = OpenStruct.new(registered?: false)
  75		web_manager = TelSelections.new(
  76			redis: FakeRedis.new, db: FakeDB.new, memcache: FakeMemcache.new
  77		)
  78		web_manager.set(
  79			"test\\40approved.example.com@component",
  80			TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
  81		)
  82		iq = Blather::Stanza::Iq::Command.new
  83		iq.from = "test@approved.example.com"
  84		result = execute_command(iq) do
  85			Registration::Activation.for(
  86				customer(
  87					sgx: sgx,
  88					jid: Blather::JID.new("test\\40approved.example.com@component")
  89				),
  90				nil,
  91				web_manager
  92			)
  93		end
  94		assert_kind_of Registration::Activation::Allow, result
  95	end
  96	em :test_for_not_activated_approved
  97
  98	def test_for_not_activated_googleplay
  99		sgx = OpenStruct.new(registered?: false)
 100		web_manager = TelSelections.new(
 101			redis: FakeRedis.new, db: FakeDB.new, memcache: FakeMemcache.new
 102		)
 103		web_manager.set(
 104			"test@example.net",
 105			TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
 106		)
 107		iq = Blather::Stanza::Iq::Command.new
 108		iq.from = "test@approved.example.com"
 109		result = execute_command(iq) do
 110			Registration::Activation.for(
 111				customer(sgx: sgx),
 112				"GARBLEDYGOOK==",
 113				web_manager
 114			)
 115		end
 116		assert_kind_of Registration::Activation::GooglePlay, result
 117	end
 118	em :test_for_not_activated_googleplay
 119
 120	def test_for_not_activated_with_customer_id
 121		sgx = OpenStruct.new(registered?: false)
 122		web_manager = TelSelections.new(
 123			redis: FakeRedis.new, db: FakeDB.new, memcache: FakeMemcache.new
 124		)
 125		web_manager.set(
 126			"test@example.net",
 127			TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
 128		)
 129		iq = Blather::Stanza::Iq::Command.new
 130		iq.from = "test@example.com"
 131		result = execute_command(iq) do
 132			Registration::Activation.for(
 133				customer(sgx: sgx),
 134				nil,
 135				web_manager
 136			)
 137		end
 138		assert_kind_of Registration::Activation, result
 139	end
 140	em :test_for_not_activated_with_customer_id
 141
 142	class ActivationTest < Minitest::Test
 143		Registration::Activation::DB = Minitest::Mock.new
 144		Registration::Activation::REDIS = FakeRedis.new(
 145			"jmp_parent_codes" => {
 146				"PARENT_CODE" => "1",
 147				"PARENT_TOMB" => "2",
 148				"PARENT_MANY_SUBACCOUNTS" => "many_subaccounts"
 149			},
 150			"jmp_customer_trust_level-2" => "Tomb"
 151		)
 152		Registration::Activation::Payment = Minitest::Mock.new
 153		Registration::Activation::Finish = Minitest::Mock.new
 154		Command::COMMAND_MANAGER = Minitest::Mock.new
 155
 156		def setup
 157			@customer = Minitest::Mock.new(customer)
 158			@tel = TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
 159			@activation = Registration::Activation.new(@customer, @tel)
 160		end
 161
 162		def test_write
 163			Command::COMMAND_MANAGER.expect(
 164				:write,
 165				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 166					iq.form.fields = [{ var: "plan_name", value: "test_usd" }]
 167				}),
 168				[Matching.new do |iq|
 169					assert_equal :form, iq.form.type
 170					assert_equal(
 171						"You've selected (555) 555-0000 as your JMP number.",
 172						iq.form.instructions.lines.first.chomp
 173					)
 174				end]
 175			)
 176			@customer.expect(:with_plan, @customer) do |*args, **|
 177				assert_equal ["test_usd"], args
 178			end
 179			@customer.expect(:save_plan!, EMPromise.resolve(nil), [])
 180			Registration::Activation::Payment.expect(
 181				:for,
 182				EMPromise.reject(:test_result),
 183				[Blather::Stanza::Iq, @customer, @tel]
 184			)
 185			assert_equal(
 186				:test_result,
 187				execute_command { @activation.write.catch { |e| e } }
 188			)
 189			assert_mock Command::COMMAND_MANAGER
 190			assert_mock @customer
 191			assert_mock Registration::Activation::Payment
 192		end
 193		em :test_write
 194
 195		def test_write_with_onboarding_jid
 196			Command::COMMAND_MANAGER.expect(
 197				:write,
 198				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 199					iq.form.fields = [{ var: "plan_name", value: "test_usd" }]
 200				}),
 201				[Matching.new do |iq|
 202					assert_equal :form, iq.form.type
 203					assert_equal(
 204						"You've selected (555) 555-0000 as your JMP number.",
 205						iq.form.instructions.lines.first.chomp
 206					)
 207				end]
 208			)
 209			@customer.expect(
 210				:jid,
 211				Blather::JID.new("test\\40onboarding.example.com@proxy")
 212			)
 213			@customer.expect(:with_plan, @customer) do |*args, **|
 214				assert_equal ["test_usd"], args
 215			end
 216			@customer.expect(:save_plan!, EMPromise.resolve(nil), [])
 217			Registration::Activation::Payment.expect(
 218				:for,
 219				EMPromise.reject(:test_result),
 220				[Blather::Stanza::Iq, @customer, @tel]
 221			)
 222			assert_equal(
 223				:test_result,
 224				execute_command { @activation.write.catch { |e| e } }
 225			)
 226			assert_mock Command::COMMAND_MANAGER
 227			assert_mock @customer
 228			assert_mock Registration::Activation::Payment
 229		end
 230		em :test_write_with_onboarding_jid
 231
 232		def test_write_bad_plan
 233			Command::COMMAND_MANAGER.expect(
 234				:write,
 235				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 236					iq.form.fields = [{ var: "plan_name", value: "test_usd_no_register" }]
 237				}),
 238				[Matching.new do |iq|
 239					assert_equal :form, iq.form.type
 240					assert_equal(
 241						"You've selected (555) 555-0000 as your JMP number.",
 242						iq.form.instructions.lines.first.chomp
 243					)
 244				end]
 245			)
 246			assert_equal(
 247				"No registration plan by that name",
 248				execute_command { @activation.write.catch { |e| e } }.message
 249			)
 250			assert_mock Command::COMMAND_MANAGER
 251			assert_mock @customer
 252		end
 253		em :test_write_bad_plan
 254
 255		def test_write_with_code
 256			Command::COMMAND_MANAGER.expect(
 257				:write,
 258				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 259					iq.form.fields = [
 260						{ var: "plan_name", value: "test_usd" },
 261						{ var: "code", value: "123" }
 262					]
 263				}),
 264				[Matching.new do |iq|
 265					assert_equal :form, iq.form.type
 266					assert_equal(
 267						"You've selected (555) 555-0000 as your JMP number.",
 268						iq.form.instructions.lines.first.chomp
 269					)
 270				end]
 271			)
 272			@customer.expect(:with_plan, @customer) do |*args, **|
 273				assert_equal ["test_usd"], args
 274			end
 275			@customer.expect(:save_plan!, EMPromise.resolve(nil), [])
 276			@customer.expect(:activate_plan_starting_now, EMPromise.resolve(nil), [])
 277			Registration::Activation::DB.expect(:transaction, []) { |&blk| blk.call }
 278			Registration::Activation::DB.expect(
 279				:exec,
 280				OpenStruct.new(cmd_tuples: 1),
 281				[String, ["test", "123"]]
 282			)
 283			Registration::Activation::Finish.expect(
 284				:new,
 285				OpenStruct.new(write: EMPromise.reject(:test_result)),
 286				[@customer, @tel]
 287			)
 288			assert_equal(
 289				:test_result,
 290				execute_command { @activation.write.catch { |e| e } }
 291			)
 292			assert_mock Command::COMMAND_MANAGER
 293			assert_mock @customer
 294			assert_mock Registration::Activation::Payment
 295			assert_mock Registration::Activation::DB
 296		end
 297		em :test_write_with_code
 298
 299		def test_write_with_group_code
 300			Command::COMMAND_MANAGER.expect(
 301				:write,
 302				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 303					iq.form.fields = [
 304						{ var: "plan_name", value: "test_usd" },
 305						{ var: "code", value: "123" }
 306					]
 307				}),
 308				[Matching.new do |iq|
 309					assert_equal :form, iq.form.type
 310					assert_equal(
 311						"You've selected (555) 555-0000 as your JMP number.",
 312						iq.form.instructions.lines.first.chomp
 313					)
 314				end]
 315			)
 316			@customer.expect(:with_plan, @customer) do |*args, **|
 317				assert_equal ["test_usd"], args
 318			end
 319			@customer.expect(:save_plan!, EMPromise.resolve(nil), [])
 320			Registration::Activation::DB.expect(:transaction, []) { |&blk| blk.call }
 321			Registration::Activation::DB.expect(
 322				:exec,
 323				OpenStruct.new(cmd_tuples: 0),
 324				[String, ["test", "123"]]
 325			)
 326			Registration::Activation::Payment.expect(
 327				:for,
 328				EMPromise.reject(:test_result),
 329				[Blather::Stanza::Iq, @customer, @tel]
 330			)
 331			assert_equal(
 332				:test_result,
 333				execute_command { @activation.write.catch { |e| e } }
 334			)
 335			assert_equal(
 336				"123",
 337				Registration::Activation::REDIS.get(
 338					"jmp_customer_pending_invite-test"
 339				).sync
 340			)
 341			assert_mock Command::COMMAND_MANAGER
 342			assert_mock @customer
 343			assert_mock Registration::Activation::Payment
 344			assert_mock Registration::Activation::DB
 345		end
 346		em :test_write_with_group_code
 347
 348		def test_write_with_parent_code
 349			execute_command do
 350				Command::COMMAND_MANAGER.expect(
 351					:write,
 352					EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 353						iq.form.fields = [
 354							{ var: "plan_name", value: "test_usd" },
 355							{ var: "code", value: "PARENT_CODE" }
 356						]
 357					}),
 358					[Matching.new do |iq|
 359						assert_equal :form, iq.form.type
 360						assert_equal(
 361							"You've selected (555) 555-0000 as your JMP number.",
 362							iq.form.instructions.lines.first.chomp
 363						)
 364					end]
 365				)
 366				Registration::Activation::DB.expect(
 367					:query_one, {}, [String, "1"], default: {}
 368				)
 369				Registration::Activation::DB.expect(
 370					:query_one, { c: 0 }, [String, "1"], default: { c: 0 }
 371				)
 372				@customer.expect(:with_plan, @customer) do |*args, **|
 373					assert_equal ["test_usd"], args
 374				end
 375				@customer.expect(:with_plan, @customer) do |*, **kwargs|
 376					assert_equal({ parent_customer_id: "1" }, kwargs)
 377				end
 378				@customer.expect(:save_plan!, EMPromise.resolve(nil), [])
 379				@customer.expect(:balance, 100, [])
 380				Command.execution.customer_repo.expect(
 381					:find,
 382					EMPromise.resolve(@customer), ["test"]
 383				)
 384				Registration::Payment::MaybeBill::BillPlan.expect(
 385					:new,
 386					EMPromise.reject(:test_result)
 387				) do |*args, **|
 388					assert_equal @tel, args[1]
 389				end
 390				assert_equal(
 391					:test_result,
 392					@activation.write.catch { |e| e }.sync
 393				)
 394			end
 395			assert_mock Command::COMMAND_MANAGER
 396			assert_mock @customer
 397			assert_mock Registration::Activation::Payment
 398			assert_mock Registration::Activation::DB
 399			assert_mock Registration::Payment::MaybeBill::BillPlan
 400		end
 401		em :test_write_with_parent_code
 402
 403		def test_write_with_parent_code_onboarding_jid
 404			Command::COMMAND_MANAGER.expect(
 405				:write,
 406				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 407					iq.form.fields = [
 408						{ var: "plan_name", value: "test_usd" },
 409						{ var: "code", value: "PARENT_CODE" }
 410					]
 411				}),
 412				[Matching.new do |iq|
 413					assert_equal :form, iq.form.type
 414					assert_equal(
 415						"You've selected (555) 555-0000 as your JMP number.",
 416						iq.form.instructions.lines.first.chomp
 417					)
 418				end]
 419			)
 420			Registration::Activation::DB.expect(
 421				:query_one, {}, [String, "1"], default: {}
 422			)
 423			Registration::Activation::DB.expect(
 424				:query_one, { c: 0 }, [String, "1"], default: { c: 0 }
 425			)
 426			@customer.expect(:with_plan, @customer, ["test_usd"])
 427			@customer.expect(
 428				:jid,
 429				Blather::JID.new("test\\40onboarding.example.com@proxy")
 430			)
 431			iq = Blather::Stanza::Iq::Command.new
 432			iq.from = "test\\40onboarding.example.com@proxied"
 433			assert_equal(
 434				"Please create a new Jabber ID before creating a subaccount.",
 435				execute_command(iq) { @activation.write.catch(&:to_s) }
 436			)
 437			assert_mock Command::COMMAND_MANAGER
 438			assert_mock @customer
 439			assert_mock Registration::Activation::Payment
 440			assert_mock Registration::Activation::DB
 441		end
 442		em :test_write_with_parent_code_onboarding_jid
 443
 444		def test_write_with_parent_code_tombed_parent
 445			Command::COMMAND_MANAGER.expect(
 446				:write,
 447				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 448					iq.form.fields = [
 449						{ var: "plan_name", value: "test_usd" },
 450						{ var: "code", value: "PARENT_TOMB" }
 451					]
 452				}),
 453				[Matching.new do |iq|
 454					assert_equal :form, iq.form.type
 455					assert_equal(
 456						"You've selected (555) 555-0000 as your JMP number.",
 457						iq.form.instructions.lines.first.chomp
 458					)
 459				end]
 460			)
 461			Registration::Activation::DB.expect(
 462				:query_one, {}, [String, "2"], default: {}
 463			)
 464			Registration::Activation::DB.expect(
 465				:query_one, { c: 0 }, [String, "2"], default: { c: 0 }
 466			)
 467			assert_equal(
 468				"Please contact support to create a subaccount",
 469				execute_command { @activation.write.catch(&:to_s) }
 470			)
 471			assert_mock Command::COMMAND_MANAGER
 472			assert_mock @customer
 473			assert_mock Registration::Activation::Payment
 474			assert_mock Registration::Activation::DB
 475		end
 476		em :test_write_with_parent_code_tombed_parent
 477
 478		def test_write_with_parent_code_too_many
 479			Command::COMMAND_MANAGER.expect(
 480				:write,
 481				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 482					iq.form.fields = [
 483						{ var: "plan_name", value: "test_usd" },
 484						{ var: "code", value: "PARENT_MANY_SUBACCOUNTS" }
 485					]
 486				}),
 487				[Matching.new do |iq|
 488					assert_equal :form, iq.form.type
 489					assert_equal(
 490						"You've selected (555) 555-0000 as your JMP number.",
 491						iq.form.instructions.lines.first.chomp
 492					)
 493				end]
 494			)
 495			Registration::Activation::DB.expect(
 496				:query_one, {}, [String, "many_subaccounts"], default: {}
 497			)
 498			Registration::Activation::DB.expect(
 499				:query_one, { c: 2 }, [String, "many_subaccounts"], default: { c: 0 }
 500			)
 501			assert_equal(
 502				"Please contact support to create a subaccount",
 503				execute_command { @activation.write.catch(&:to_s) }
 504			)
 505			assert_mock Command::COMMAND_MANAGER
 506			assert_mock @customer
 507			assert_mock Registration::Activation::Payment
 508			assert_mock Registration::Activation::DB
 509		end
 510		em :test_write_with_parent_code_too_many
 511	end
 512
 513	class AllowTest < Minitest::Test
 514		Command::COMMAND_MANAGER = Minitest::Mock.new
 515		Registration::Activation::Allow::DB = Minitest::Mock.new
 516
 517		def test_write_credit_to_nil
 518			tel = TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
 519			cust = Minitest::Mock.new(customer("test"))
 520			allow = Registration::Activation::Allow.new(cust, tel, nil)
 521
 522			Command::COMMAND_MANAGER.expect(
 523				:write,
 524				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 525					iq.form.fields = [{ var: "plan_name", value: "test_usd" }]
 526				}),
 527				[Matching.new do |iq|
 528					assert_equal :form, iq.form.type
 529					assert_equal(
 530						"You've selected (555) 555-0000 as your JMP number.",
 531						iq.form.instructions.lines.first.chomp
 532					)
 533					assert_equal 1, iq.form.fields.length
 534				end]
 535			)
 536			Registration::Activation::Allow::DB.expect(
 537				:transaction,
 538				EMPromise.reject(:test_result)
 539			) do |&blk|
 540				blk.call
 541				true
 542			end
 543			cust.expect(:with_plan, cust, ["test_usd"])
 544			cust.expect(:activate_plan_starting_now, nil)
 545			assert_equal(
 546				:test_result,
 547				execute_command { allow.write.catch { |e| e } }
 548			)
 549			assert_mock Command::COMMAND_MANAGER
 550		end
 551		em :test_write_credit_to_nil
 552
 553		def test_write_credit_to_refercust
 554			cust = Minitest::Mock.new(customer("test"))
 555			tel = TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
 556			allow = Registration::Activation::Allow.new(
 557				cust, tel, "refercust"
 558			)
 559
 560			Command::COMMAND_MANAGER.expect(
 561				:write,
 562				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 563					iq.form.fields = [{ var: "plan_name", value: "test_usd" }]
 564				}),
 565				[Matching.new do |iq|
 566					assert_equal :form, iq.form.type
 567					assert_equal(
 568						"You've selected (555) 555-0000 as your JMP number.",
 569						iq.form.instructions.lines.first.chomp
 570					)
 571					assert_equal 1, iq.form.fields.length
 572				end]
 573			)
 574			Registration::Activation::Allow::DB.expect(
 575				:transaction,
 576				EMPromise.reject(:test_result)
 577			) do |&blk|
 578				blk.call
 579				true
 580			end
 581			Registration::Activation::Allow::DB.expect(
 582				:exec,
 583				nil,
 584				[String, ["refercust", "test"]]
 585			)
 586			cust.expect(:with_plan, cust, ["test_usd"])
 587			cust.expect(:activate_plan_starting_now, nil)
 588			assert_equal(
 589				:test_result,
 590				execute_command { allow.write.catch { |e| e } }
 591			)
 592			assert_mock Command::COMMAND_MANAGER
 593		end
 594		em :test_write_credit_to_refercust
 595	end
 596
 597	class GooglePlayTest < Minitest::Test
 598		CustomerPlan::DB = Minitest::Mock.new
 599		Registration::Activation::GooglePlay::Finish = Minitest::Mock.new
 600
 601		def setup
 602			@customer = customer
 603			@tel = TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
 604			@google_play = Registration::Activation::GooglePlay.new(
 605				@customer,
 606				"abcd",
 607				@tel
 608			)
 609		end
 610
 611		def test_write
 612			Command::COMMAND_MANAGER.expect(
 613				:write,
 614				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 615					iq.form.fields = [{ var: "plan_name", value: "test_usd" }]
 616				}),
 617				[Matching.new do |iq|
 618					assert_equal :form, iq.form.type
 619					assert_equal(
 620						"You've selected (555) 555-0000 as your JMP number.",
 621						iq.form.instructions.lines.first.chomp
 622					)
 623				end]
 624			)
 625			CustomerPlan::DB.expect(
 626				:exec,
 627				OpenStruct.new(cmd_tuples: 1),
 628				[String, ["test", "test_usd", nil]]
 629			)
 630			CustomerPlan::DB.expect(
 631				:exec,
 632				OpenStruct.new(cmd_tuples: 0),
 633				[String, ["test"]]
 634			)
 635			Transaction::DB.expect(:transaction, true, [])
 636			Registration::Activation::GooglePlay::Finish.expect(
 637				:new,
 638				OpenStruct.new(write: EMPromise.reject(:test_result)),
 639				[Customer, @tel]
 640			)
 641			result = execute_command { @google_play.write.catch { |e| e } }
 642			assert_equal :test_result, result
 643			assert_mock Command::COMMAND_MANAGER
 644			assert_mock CustomerPlan::DB
 645			assert_mock Transaction::DB
 646			assert_mock Registration::Activation::GooglePlay::Finish
 647		end
 648		em :test_write
 649	end
 650
 651	class PaymentTest < Minitest::Test
 652		CustomerFinancials::BRAINTREE = Minitest::Mock.new
 653
 654		def test_for_bitcoin
 655			tel = TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
 656			iq = Blather::Stanza::Iq::Command.new
 657			iq.form.fields = [
 658				{ var: "activation_method", value: "bitcoin" },
 659				{ var: "plan_name", value: "test_usd" }
 660			]
 661			result = Registration::Payment.for(iq, customer, tel)
 662			assert_kind_of Registration::Payment::Bitcoin, result
 663		end
 664
 665		def test_for_bch
 666			tel = TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
 667			iq = Blather::Stanza::Iq::Command.new
 668			iq.form.fields = [
 669				{ var: "activation_method", value: "bch" },
 670				{ var: "plan_name", value: "test_usd" }
 671			]
 672			result = Registration::Payment.for(iq, customer, tel)
 673			assert_kind_of Registration::Payment::BCH, result
 674		end
 675
 676		def test_for_credit_card
 677			tel = TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
 678			iq = Blather::Stanza::Iq::Command.new
 679			iq.from = "test@example.com"
 680			iq.form.fields = [
 681				{ var: "activation_method", value: "credit_card" },
 682				{ var: "plan_name", value: "test_usd" }
 683			]
 684			cust = customer
 685			result = execute_command do
 686				Command.execution.customer_repo.expect(:find, cust, ["test"])
 687				Registration::Payment.for(
 688					iq,
 689					cust,
 690					tel
 691				)
 692			end
 693			assert_kind_of Registration::Payment::CreditCard, result
 694		end
 695		em :test_for_credit_card
 696
 697		def test_for_code
 698			iq = Blather::Stanza::Iq::Command.new
 699			iq.form.fields = [
 700				{ var: "activation_method", value: "code" },
 701				{ var: "plan_name", value: "test_usd" }
 702			]
 703			cust = customer
 704			result = execute_command do
 705				Command.execution.customer_repo.expect(:find, cust, ["test"])
 706				Registration::Payment.for(
 707					iq,
 708					cust,
 709					TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
 710				)
 711			end
 712			assert_kind_of Registration::Payment::InviteCode, result
 713		end
 714		em :test_for_code
 715
 716		class BitcoinTest < Minitest::Test
 717			Registration::Payment::Bitcoin::BTC_SELL_PRICES = Minitest::Mock.new
 718			CustomerFinancials::REDIS = Minitest::Mock.new
 719
 720			def setup
 721				@customer = Minitest::Mock.new(
 722					customer(plan_name: "test_usd")
 723				)
 724				@customer.expect(
 725					:add_btc_address,
 726					EMPromise.resolve("testaddr")
 727				)
 728				@tel = TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
 729				@bitcoin = Registration::Payment::Bitcoin.new(
 730					@customer,
 731					@tel
 732				)
 733			end
 734
 735			def test_write
 736				CustomerFinancials::REDIS.expect(
 737					:smembers,
 738					EMPromise.resolve([]),
 739					["jmp_customer_btc_addresses-test"]
 740				)
 741				blather = Minitest::Mock.new
 742				Command::COMMAND_MANAGER.expect(
 743					:write,
 744					EMPromise.reject(SessionManager::Timeout.new),
 745					[Matching.new do |reply|
 746						assert_equal :canceled, reply.status
 747						assert_equal "1.000000", reply.form.field("amount").value
 748						assert_equal "testaddr", reply.form.field("btc_addresses").value
 749						true
 750					end]
 751				)
 752				Registration::Payment::Bitcoin::BTC_SELL_PRICES.expect(
 753					:usd,
 754					EMPromise.resolve(BigDecimal(1))
 755				)
 756				@bitcoin.stub(:save, EMPromise.resolve(nil)) do
 757					execute_command(blather: blather) do
 758						@bitcoin.write
 759					end
 760				end
 761				assert_mock blather
 762			end
 763			em :test_write
 764		end
 765
 766		class BCHTest < Minitest::Test
 767			Registration::Payment::BCH::BCH_SELL_PRICES = Minitest::Mock.new
 768			CustomerFinancials::REDIS = Minitest::Mock.new
 769
 770			def setup
 771				@customer = Minitest::Mock.new(
 772					customer(plan_name: "test_usd")
 773				)
 774				@customer.expect(
 775					:add_bch_address,
 776					EMPromise.resolve("testaddr")
 777				)
 778				@tel = TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
 779				@bch = Registration::Payment::BCH.new(
 780					@customer,
 781					@tel
 782				)
 783			end
 784
 785			def test_write
 786				CustomerFinancials::REDIS.expect(
 787					:smembers,
 788					EMPromise.resolve([]),
 789					["jmp_customer_bch_addresses-test"]
 790				)
 791				blather = Minitest::Mock.new
 792				Command::COMMAND_MANAGER.expect(
 793					:write,
 794					EMPromise.reject(SessionManager::Timeout.new),
 795					[Matching.new do |reply|
 796						assert_equal :canceled, reply.status
 797						assert_equal "1.000000", reply.form.field("amount").value
 798						assert_equal "testaddr", reply.form.field("bch_addresses").value
 799						true
 800					end]
 801				)
 802				Registration::Payment::BCH::BCH_SELL_PRICES.expect(
 803					:usd,
 804					EMPromise.resolve(BigDecimal(1))
 805				)
 806				@bch.stub(:save, EMPromise.resolve(nil)) do
 807					execute_command(blather: blather) do
 808						@bch.write
 809					end
 810				end
 811				assert_mock blather
 812			end
 813			em :test_write
 814		end
 815
 816		class CreditCardTest < Minitest::Test
 817			def setup
 818				@tel = TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
 819				@credit_card = Registration::Payment::CreditCard.new(
 820					customer,
 821					@tel
 822				)
 823			end
 824
 825			def test_new
 826				tel = TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
 827				cust = Minitest::Mock.new(customer)
 828				cust.expect(
 829					:payment_methods,
 830					EMPromise.resolve(OpenStruct.new(default_payment_method: :test))
 831				)
 832				execute_command do
 833					Command.execution.customer_repo.expect(:find, cust, ["test"])
 834					assert_kind_of(
 835						Registration::Payment::CreditCard,
 836						Registration::Payment::CreditCard.new(cust, tel)
 837					)
 838				end
 839			end
 840			em :test_new
 841
 842			def test_write
 843				result = execute_command do
 844					Command::COMMAND_MANAGER.expect(
 845						:write,
 846						EMPromise.reject(:test_result),
 847						[Matching.new do |reply|
 848							assert_equal [:execute, :next, :prev], reply.allowed_actions
 849							assert_equal(
 850								"Pay by credit card, save, then next here to continue: " \
 851								"http://creditcard.example.com?&amount=1",
 852								reply.note.content
 853							)
 854						end]
 855					)
 856
 857					@credit_card.write.catch { |e| e }
 858				end
 859
 860				assert_equal :test_result, result
 861			end
 862			em :test_write
 863		end
 864
 865		class MailTest < Minitest::Test
 866			def setup
 867				@tel = TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
 868				@mail = Registration::Payment::Mail.new(
 869					customer(plan_name: "test_cad"),
 870					@tel
 871				)
 872			end
 873
 874			def test_write
 875				result = execute_command do
 876					Command::COMMAND_MANAGER.expect(
 877						:write,
 878						EMPromise.reject(:test_result),
 879						[Matching.new do |reply|
 880							assert_equal [:execute, :prev], reply.allowed_actions
 881							refute reply.form.instructions.empty?
 882							assert_equal(
 883								"A Mailing Address",
 884								reply.form.field("adr").value
 885							)
 886							assert_equal(
 887								"interac@example.com",
 888								reply.form.field("interac_email").value
 889							)
 890						end]
 891					)
 892
 893					@mail.write.catch { |e| e }
 894				end
 895
 896				assert_equal :test_result, result
 897			end
 898			em :test_write
 899		end
 900
 901		class InviteCodeTest < Minitest::Test
 902			Registration::Payment::InviteCode::DB =
 903				Minitest::Mock.new
 904			Registration::Payment::InviteCode::REDIS =
 905				Minitest::Mock.new
 906			Command::COMMAND_MANAGER = Minitest::Mock.new
 907			Registration::Payment::InviteCode::Finish =
 908				Minitest::Mock.new
 909			Registration::Payment::MaybeBill::BillPlan =
 910				Minitest::Mock.new
 911
 912			def setup
 913				@tel = TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
 914			end
 915
 916			def test_write
 917				customer = customer(plan_name: "test_usd")
 918				Registration::Payment::InviteCode::DB.expect(:transaction, true, [])
 919				Registration::Payment::InviteCode::Finish.expect(
 920					:new,
 921					OpenStruct.new(write: nil),
 922					[
 923						customer,
 924						@tel
 925					]
 926				)
 927				execute_command do
 928					Registration::Payment::InviteCode::REDIS.expect(
 929						:get,
 930						EMPromise.resolve(nil),
 931						["jmp_invite_tries-test"]
 932					)
 933					Registration::Payment::InviteCode::REDIS.expect(
 934						:hget,
 935						EMPromise.resolve(nil),
 936						["jmp_parent_codes", "abc"]
 937					)
 938					Command::COMMAND_MANAGER.expect(
 939						:write,
 940						EMPromise.resolve(
 941							Blather::Stanza::Iq::Command.new.tap { |iq|
 942								iq.form.fields = [{ var: "code", value: "abc" }]
 943							}
 944						),
 945						[Matching.new do |reply|
 946							assert_equal :form, reply.form.type
 947							assert_nil reply.form.instructions
 948						end]
 949					)
 950
 951					Registration::Payment::InviteCode.new(
 952						customer,
 953						@tel
 954					).write
 955				end
 956				assert_mock Command::COMMAND_MANAGER
 957				assert_mock Registration::Payment::InviteCode::DB
 958				assert_mock Registration::Payment::InviteCode::REDIS
 959				assert_mock Registration::Payment::InviteCode::Finish
 960			end
 961			em :test_write
 962
 963			def test_write_parent_code
 964				customer = customer(plan_name: "test_usd")
 965				Registration::Payment::MaybeBill::BillPlan.expect(
 966					:new,
 967					OpenStruct.new(write: nil)
 968				) { |*| true }
 969				Registration::Payment::InviteCode::DB.expect(
 970					:query_one, {}, [String, "parent_customer"], default: {}
 971				)
 972				Registration::Payment::InviteCode::DB.expect(
 973					:query_one, { c: 0 }, [String, "parent_customer"], default: { c: 0 }
 974				)
 975				execute_command do
 976					Registration::Payment::InviteCode::REDIS.expect(
 977						:hget,
 978						EMPromise.resolve("parent_customer"),
 979						["jmp_parent_codes", "pabc"]
 980					)
 981					Registration::Payment::InviteCode::REDIS.expect(
 982						:get,
 983						EMPromise.resolve(nil),
 984						["jmp_customer_trust_level-parent_customer"]
 985					)
 986					CustomerPlan::DB.expect(
 987						:query,
 988						[{ "plan_name" => "test_usd" }],
 989						[String, ["parent_customer"]]
 990					)
 991					CustomerPlan::DB.expect(
 992						:exec_defer,
 993						EMPromise.resolve(nil),
 994						[String, ["test", "test_usd", "parent_customer"]]
 995					)
 996					Command.execution.customer_repo.expect(
 997						:find,
 998						customer.with_balance(10000),
 999						["test"]
1000					)
1001					Command::COMMAND_MANAGER.expect(
1002						:write,
1003						EMPromise.resolve(
1004							Blather::Stanza::Iq::Command.new.tap { |iq|
1005								iq.form.fields = [{ var: "code", value: "pabc" }]
1006							}
1007						),
1008						[Matching.new do |reply|
1009							assert_equal :form, reply.form.type
1010							assert_nil reply.form.instructions
1011						end]
1012					)
1013
1014					Registration::Payment::InviteCode.new(
1015						customer,
1016						@tel
1017					).write
1018				end
1019				assert_mock Command::COMMAND_MANAGER
1020				assert_mock Registration::Payment::InviteCode::DB
1021				assert_mock Registration::Payment::InviteCode::REDIS
1022				assert_mock Registration::Payment::MaybeBill::BillPlan
1023			end
1024			em :test_write_parent_code
1025
1026			def test_write_bad_code
1027				result = execute_command do
1028					customer = customer(plan_name: "test_usd")
1029					Registration::Payment::InviteCode::REDIS.expect(
1030						:set,
1031						EMPromise.resolve(nil),
1032						["jmp_customer_pending_invite-test", "abc"]
1033					)
1034					Registration::Payment::InviteCode::REDIS.expect(
1035						:get,
1036						EMPromise.resolve(0),
1037						["jmp_invite_tries-test"]
1038					)
1039					Registration::Payment::InviteCode::REDIS.expect(
1040						:hget,
1041						EMPromise.resolve(nil),
1042						["jmp_parent_codes", "abc"]
1043					)
1044					Registration::Payment::InviteCode::DB.expect(
1045						:transaction,
1046						[]
1047					) { |&blk| blk.call }
1048					Registration::Payment::InviteCode::DB.expect(
1049						:exec,
1050						OpenStruct.new(cmd_tuples: 0),
1051						[String, ["test", "abc"]]
1052					)
1053					Registration::Payment::InviteCode::REDIS.expect(
1054						:incr,
1055						EMPromise.resolve(nil),
1056						["jmp_invite_tries-test"]
1057					)
1058					Registration::Payment::InviteCode::REDIS.expect(
1059						:expire,
1060						EMPromise.resolve(nil),
1061						["jmp_invite_tries-test", 60 * 60]
1062					)
1063					Registration::Payment::InviteCode::REDIS.expect(
1064						:hexists,
1065						EMPromise.resolve(0),
1066						["jmp_group_codes", "abc"]
1067					)
1068					Command::COMMAND_MANAGER.expect(
1069						:write,
1070						EMPromise.resolve(
1071							Blather::Stanza::Iq::Command.new.tap { |iq|
1072								iq.form.fields = [{ var: "code", value: "abc" }]
1073							}
1074						),
1075						[Matching.new do |reply|
1076							assert_equal :form, reply.form.type
1077							assert_nil reply.form.instructions
1078						end]
1079					)
1080					Command::COMMAND_MANAGER.expect(
1081						:write,
1082						EMPromise.reject(:test_result),
1083						[Matching.new do |reply|
1084							assert_equal :form, reply.form.type
1085							assert_equal(
1086								"Not a valid invite code: abc",
1087								reply.form.instructions
1088							)
1089						end]
1090					)
1091
1092					Registration::Payment::InviteCode.new(
1093						customer,
1094						@tel
1095					).write.catch { |e| e }
1096				end
1097				assert_equal :test_result, result
1098				assert_mock Command::COMMAND_MANAGER
1099				assert_mock Registration::Payment::InviteCode::DB
1100				assert_mock Registration::Payment::InviteCode::REDIS
1101			end
1102			em :test_write_bad_code
1103
1104			def test_write_group_code
1105				result = execute_command do
1106					customer = customer(plan_name: "test_usd")
1107					Registration::Payment::InviteCode::REDIS.expect(
1108						:set,
1109						EMPromise.resolve(nil),
1110						["jmp_customer_pending_invite-test", "abc"]
1111					)
1112					Registration::Payment::InviteCode::REDIS.expect(
1113						:get,
1114						EMPromise.resolve(0),
1115						["jmp_invite_tries-test"]
1116					)
1117					Registration::Payment::InviteCode::REDIS.expect(
1118						:hget,
1119						EMPromise.resolve(nil),
1120						["jmp_parent_codes", "abc"]
1121					)
1122					Registration::Payment::InviteCode::DB.expect(
1123						:transaction,
1124						[]
1125					) { |&blk| blk.call }
1126					Registration::Payment::InviteCode::DB.expect(
1127						:exec,
1128						OpenStruct.new(cmd_tuples: 0),
1129						[String, ["test", "abc"]]
1130					)
1131					Registration::Payment::InviteCode::REDIS.expect(
1132						:incr,
1133						EMPromise.resolve(nil),
1134						["jmp_invite_tries-test"]
1135					)
1136					Registration::Payment::InviteCode::REDIS.expect(
1137						:expire,
1138						EMPromise.resolve(nil),
1139						["jmp_invite_tries-test", 60 * 60]
1140					)
1141					Registration::Payment::InviteCode::REDIS.expect(
1142						:hexists,
1143						EMPromise.resolve(1),
1144						["jmp_group_codes", "abc"]
1145					)
1146					Command::COMMAND_MANAGER.expect(
1147						:write,
1148						EMPromise.resolve(
1149							Blather::Stanza::Iq::Command.new.tap { |iq|
1150								iq.form.fields = [{ var: "code", value: "abc" }]
1151							}
1152						),
1153						[Matching.new do |reply|
1154							assert_equal :form, reply.form.type
1155							assert_nil reply.form.instructions
1156						end]
1157					)
1158					Command::COMMAND_MANAGER.expect(
1159						:write,
1160						EMPromise.reject(:test_result),
1161						[Matching.new do |reply|
1162							assert_equal :form, reply.form.type
1163							assert_equal(
1164								"abc is a post-payment referral",
1165								reply.form.instructions
1166							)
1167						end]
1168					)
1169
1170					Registration::Payment::InviteCode.new(
1171						customer,
1172						@tel
1173					).write.catch { |e| e }
1174				end
1175				assert_equal :test_result, result
1176				assert_mock Command::COMMAND_MANAGER
1177				assert_mock Registration::Payment::InviteCode::DB
1178				assert_mock Registration::Payment::InviteCode::REDIS
1179			end
1180			em :test_write_group_code
1181
1182			def test_write_bad_code_over_limit
1183				result = execute_command do
1184					customer = customer(plan_name: "test_usd")
1185					Registration::Payment::InviteCode::REDIS.expect(
1186						:get,
1187						EMPromise.resolve(11),
1188						["jmp_invite_tries-test"]
1189					)
1190					Registration::Payment::InviteCode::REDIS.expect(
1191						:hget,
1192						EMPromise.resolve(nil),
1193						["jmp_parent_codes", "abc"]
1194					)
1195					Command::COMMAND_MANAGER.expect(
1196						:write,
1197						EMPromise.resolve(
1198							Blather::Stanza::Iq::Command.new.tap { |iq|
1199								iq.form.fields = [{ var: "code", value: "abc" }]
1200							}
1201						),
1202						[Matching.new do |reply|
1203							assert_equal :form, reply.form.type
1204							assert_nil reply.form.instructions
1205						end]
1206					)
1207					Command::COMMAND_MANAGER.expect(
1208						:write,
1209						EMPromise.reject(:test_result),
1210						[Matching.new do |reply|
1211							assert_equal :form, reply.form.type
1212							assert_equal "Too many wrong attempts", reply.form.instructions
1213						end]
1214					)
1215					Registration::Payment::InviteCode.new(
1216						customer,
1217						@tel
1218					).write.catch { |e| e }
1219				end
1220				assert_equal :test_result, result
1221				assert_mock Command::COMMAND_MANAGER
1222				assert_mock Registration::Payment::InviteCode::REDIS
1223			end
1224			em :test_write_bad_code_over_limit
1225		end
1226	end
1227
1228	class FinishTest < Minitest::Test
1229		Customer::BLATHER = Minitest::Mock.new
1230		Command::COMMAND_MANAGER = Minitest::Mock.new
1231		Registration::Finish::TEL_SELECTIONS = FakeTelSelections.new
1232		Registration::Finish::REDIS = Minitest::Mock.new
1233		Registration::Finish::DB = Minitest::Mock.new
1234		Bwmsgsv2Repo::REDIS = Minitest::Mock.new
1235		Registration::FinishOnboarding::DB = FakeDB.new
1236		Transaction::DB = Minitest::Mock.new
1237
1238		def setup
1239			@sgx = Minitest::Mock.new(mksgx)
1240			iq = Blather::Stanza::Iq::Command.new
1241			iq.from = "test\\40example.com@cheogram.com"
1242			@finish = Registration::Finish.new(
1243				customer(sgx: @sgx, plan_name: "test_usd"),
1244				TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
1245			)
1246		end
1247
1248		def test_write
1249			create_order = stub_request(
1250				:post,
1251				"https://dashboard.bandwidth.com/v1.0/accounts//orders"
1252			).to_return(status: 201, body: <<~RESPONSE)
1253				<OrderResponse>
1254					<Order>
1255						<id>test_order</id>
1256					</Order>
1257				</OrderResponse>
1258			RESPONSE
1259			stub_request(
1260				:get,
1261				"https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
1262			).to_return(status: 201, body: <<~RESPONSE)
1263				<OrderResponse>
1264					<OrderStatus>COMPLETE</OrderStatus>
1265					<CompletedNumbers>
1266						<TelephoneNumber>
1267							<FullNumber>5555550000</FullNumber>
1268						</TelephoneNumber>
1269					</CompletedNumbers>
1270				</OrderResponse>
1271			RESPONSE
1272			stub_request(
1273				:post,
1274				"https://dashboard.bandwidth.com/v1.0/accounts//sites//sippeers//movetns"
1275			)
1276			Registration::Finish::REDIS.expect(
1277				:get,
1278				nil,
1279				["jmp_customer_pending_invite-test"]
1280			)
1281			Registration::Finish::REDIS.expect(
1282				:del,
1283				nil,
1284				["jmp_customer_pending_invite-test"]
1285			)
1286			Registration::Finish::REDIS.expect(
1287				:hget,
1288				nil,
1289				["jmp_group_codes", nil]
1290			)
1291			Bwmsgsv2Repo::REDIS.expect(
1292				:get,
1293				EMPromise.resolve(nil),
1294				["jmp_customer_backend_sgx-test"]
1295			)
1296			Bwmsgsv2Repo::REDIS.expect(
1297				:set,
1298				nil,
1299				[
1300					"catapult_fwd-+15555550000",
1301					"xmpp:test@example.net"
1302				]
1303			)
1304			Bwmsgsv2Repo::REDIS.expect(
1305				:set,
1306				nil,
1307				["catapult_fwd_timeout-customer_test@component", 25]
1308			)
1309			Customer::BLATHER.expect(
1310				:<<,
1311				nil,
1312				[Matching.new do |m|
1313					assert_equal :chat, m.type
1314					assert m.body =~ /^Welcome to JMP/
1315				end]
1316			)
1317			blather = Minitest::Mock.new
1318			blather.expect(
1319				:<<,
1320				nil,
1321				[Matching.new do |reply|
1322					assert_equal :completed, reply.status
1323					assert_equal :info, reply.note_type
1324					assert_equal(
1325						"Your JMP account has been activated as (555) 555-0000",
1326						reply.note.content
1327					)
1328				end]
1329			)
1330			execute_command(blather: blather) do
1331				@sgx.expect(
1332					:register!,
1333					EMPromise.resolve(@sgx.with(
1334						registered?: Blather::Stanza::Iq::IBR.new.tap do |ibr|
1335							ibr.phone = "+15555550000"
1336						end
1337					)),
1338					["+15555550000"]
1339				)
1340
1341				@finish.write
1342			end
1343			assert_requested create_order
1344			assert_mock @sgx
1345			assert_mock Registration::Finish::REDIS
1346			assert_mock Bwmsgsv2Repo::REDIS
1347			assert_mock Customer::BLATHER
1348			assert_mock blather
1349		end
1350		em :test_write
1351
1352		def test_write_with_pending_code
1353			create_order = stub_request(
1354				:post,
1355				"https://dashboard.bandwidth.com/v1.0/accounts//orders"
1356			).to_return(status: 201, body: <<~RESPONSE)
1357				<OrderResponse>
1358					<Order>
1359						<id>test_order</id>
1360					</Order>
1361				</OrderResponse>
1362			RESPONSE
1363			stub_request(
1364				:get,
1365				"https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
1366			).to_return(status: 201, body: <<~RESPONSE)
1367				<OrderResponse>
1368					<OrderStatus>COMPLETE</OrderStatus>
1369					<CompletedNumbers>
1370						<TelephoneNumber>
1371							<FullNumber>5555550000</FullNumber>
1372						</TelephoneNumber>
1373					</CompletedNumbers>
1374				</OrderResponse>
1375			RESPONSE
1376			stub_request(
1377				:post,
1378				"https://dashboard.bandwidth.com/v1.0/accounts//sites//sippeers//movetns"
1379			)
1380			Registration::Finish::REDIS.expect(
1381				:get,
1382				EMPromise.resolve("123"),
1383				["jmp_customer_pending_invite-test"]
1384			)
1385			Registration::Finish::REDIS.expect(
1386				:del,
1387				nil,
1388				["jmp_customer_pending_invite-test"]
1389			)
1390			Registration::Finish::REDIS.expect(
1391				:hget,
1392				EMPromise.resolve("test-inviter"),
1393				["jmp_group_codes", "123"]
1394			)
1395			Registration::Finish::DB.expect(
1396				:exec,
1397				EMPromise.resolve(nil),
1398				[String, ["test-inviter", "test"]]
1399			)
1400			Transaction::DB.expect(:transaction, nil) do |&blk|
1401				blk.call
1402				true
1403			end
1404			Transaction::DB.expect(
1405				:exec,
1406				nil,
1407				[String, Matching.new { |params|
1408					assert_equal "test", params[0]
1409					assert params[1].start_with?("referral_")
1410					assert_equal 1, params[4]
1411					assert_equal "Referral Bonus", params[5]
1412				}]
1413			)
1414			Bwmsgsv2Repo::REDIS.expect(
1415				:get,
1416				EMPromise.resolve(nil),
1417				["jmp_customer_backend_sgx-test"]
1418			)
1419			Bwmsgsv2Repo::REDIS.expect(
1420				:set,
1421				nil,
1422				[
1423					"catapult_fwd-+15555550000",
1424					"xmpp:test@example.net"
1425				]
1426			)
1427			Bwmsgsv2Repo::REDIS.expect(
1428				:set,
1429				nil,
1430				["catapult_fwd_timeout-customer_test@component", 25]
1431			)
1432			Customer::BLATHER.expect(
1433				:<<,
1434				nil,
1435				[Matching.new do |m|
1436					assert_equal :chat, m.type
1437					assert m.body =~ /^Welcome to JMP/
1438				end]
1439			)
1440			blather = Minitest::Mock.new
1441			blather.expect(
1442				:<<,
1443				nil,
1444				[Matching.new do |reply|
1445					assert_equal :completed, reply.status
1446					assert_equal :info, reply.note_type
1447					assert_equal(
1448						"Your JMP account has been activated as (555) 555-0000",
1449						reply.note.content
1450					)
1451				end]
1452			)
1453			execute_command(blather: blather) do
1454				@sgx.expect(
1455					:register!,
1456					EMPromise.resolve(@sgx.with(
1457						registered?: Blather::Stanza::Iq::IBR.new.tap do |ibr|
1458							ibr.phone = "+15555550000"
1459						end
1460					)),
1461					["+15555550000"]
1462				)
1463
1464				@finish.write
1465			end
1466			assert_requested create_order
1467			assert_mock @sgx
1468			assert_mock Registration::Finish::REDIS
1469			assert_mock Bwmsgsv2Repo::REDIS
1470			assert_mock Customer::BLATHER
1471			assert_mock blather
1472			assert_mock Transaction::DB
1473		end
1474		em :test_write_with_pending_code
1475
1476		def test_write_onboarding
1477			create_order = stub_request(
1478				:post,
1479				"https://dashboard.bandwidth.com/v1.0/accounts//orders"
1480			).to_return(status: 201, body: <<~RESPONSE)
1481				<OrderResponse>
1482					<Order>
1483						<id>test_order</id>
1484					</Order>
1485				</OrderResponse>
1486			RESPONSE
1487			stub_request(
1488				:get,
1489				"https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
1490			).to_return(status: 201, body: <<~RESPONSE)
1491				<OrderResponse>
1492					<OrderStatus>COMPLETE</OrderStatus>
1493					<CompletedNumbers>
1494						<TelephoneNumber>
1495							<FullNumber>5555550000</FullNumber>
1496						</TelephoneNumber>
1497					</CompletedNumbers>
1498				</OrderResponse>
1499			RESPONSE
1500			stub_request(
1501				:post,
1502				"https://dashboard.bandwidth.com/v1.0/accounts//sites//sippeers//movetns"
1503			)
1504			Registration::Finish::REDIS.expect(
1505				:get,
1506				nil,
1507				["jmp_customer_pending_invite-test"]
1508			)
1509			Registration::Finish::REDIS.expect(
1510				:del,
1511				nil,
1512				["jmp_customer_pending_invite-test"]
1513			)
1514			Registration::Finish::REDIS.expect(
1515				:hget,
1516				nil,
1517				["jmp_group_codes", nil]
1518			)
1519			Bwmsgsv2Repo::REDIS.expect(
1520				:get,
1521				EMPromise.resolve(nil),
1522				["jmp_customer_backend_sgx-test"]
1523			)
1524			Bwmsgsv2Repo::REDIS.expect(
1525				:set,
1526				nil,
1527				[
1528					"catapult_fwd-+15555550000",
1529					"xmpp:test\\40onboarding.example.com@proxy"
1530				]
1531			)
1532			Bwmsgsv2Repo::REDIS.expect(
1533				:set,
1534				nil,
1535				["catapult_fwd_timeout-customer_test@component", 25]
1536			)
1537			result = execute_command do
1538				@sgx.expect(
1539					:register!,
1540					EMPromise.resolve(@sgx.with(
1541						registered?: Blather::Stanza::Iq::IBR.new.tap do |ibr|
1542							ibr.phone = "+15555550000"
1543						end
1544					)),
1545					["+15555550000"]
1546				)
1547
1548				Command::COMMAND_MANAGER.expect(
1549					:write,
1550					EMPromise.reject(:test_result),
1551					[Matching.new do |iq|
1552						assert_equal :form, iq.form.type
1553						assert iq.form.field("subdomain")
1554					end]
1555				)
1556
1557				Registration::Finish.new(
1558					customer(
1559						sgx: @sgx,
1560						jid: Blather::JID.new("test\\40onboarding.example.com@proxy")
1561					),
1562					TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
1563				).write.catch { |e| e }
1564			end
1565			assert_equal :test_result, result
1566			assert_requested create_order
1567			assert_mock @sgx
1568			assert_mock Registration::Finish::REDIS
1569			assert_mock Bwmsgsv2Repo::REDIS
1570			assert_mock Command::COMMAND_MANAGER
1571		end
1572		em :test_write_onboarding
1573
1574		def test_write_local_inventory
1575			stub_request(
1576				:post,
1577				"https://dashboard.bandwidth.com/v1.0/accounts/moveto/moveTns"
1578			).with(
1579				body: {
1580					CustomerOrderId: "test",
1581					SourceAccountId: "bandwidth_account_id",
1582					SiteId: "test_site",
1583					SipPeerId: "test_peer",
1584					TelephoneNumbers: { TelephoneNumber: "5555550000" }
1585				}.to_xml(indent: 0, root: "MoveTnsOrder")
1586			).to_return(status: 200, body: "", headers: {})
1587
1588			Registration::Finish::REDIS.expect(
1589				:get,
1590				nil,
1591				["jmp_customer_pending_invite-test"]
1592			)
1593			Registration::Finish::REDIS.expect(
1594				:del,
1595				nil,
1596				["jmp_customer_pending_invite-test"]
1597			)
1598			Registration::Finish::REDIS.expect(
1599				:hget,
1600				nil,
1601				["jmp_group_codes", nil]
1602			)
1603			Registration::Finish::DB.expect(
1604				:exec_defer,
1605				EMPromise.resolve(OpenStruct.new(cmd_tuples: 1)),
1606				[String, ["+15555550000"]]
1607			)
1608			Bwmsgsv2Repo::REDIS.expect(
1609				:get,
1610				EMPromise.resolve(nil),
1611				["jmp_customer_backend_sgx-test"]
1612			)
1613			Bwmsgsv2Repo::REDIS.expect(
1614				:set,
1615				nil,
1616				[
1617					"catapult_fwd-+15555550000",
1618					"xmpp:test\\40onboarding.example.com@proxy"
1619				]
1620			)
1621			Bwmsgsv2Repo::REDIS.expect(
1622				:set,
1623				nil,
1624				["catapult_fwd_timeout-customer_test@component", 25]
1625			)
1626			result = execute_command do
1627				@sgx.expect(
1628					:register!,
1629					EMPromise.resolve(@sgx.with(
1630						registered?: Blather::Stanza::Iq::IBR.new.tap do |ibr|
1631							ibr.phone = "+15555550000"
1632						end
1633					)),
1634					["+15555550000"]
1635				)
1636
1637				Command::COMMAND_MANAGER.expect(
1638					:write,
1639					EMPromise.reject(:test_result),
1640					[Matching.new do |iq|
1641						assert_equal :form, iq.form.type
1642						assert iq.form.field("subdomain")
1643					end]
1644				)
1645
1646				Registration::Finish.new(
1647					customer(
1648						sgx: @sgx,
1649						jid: Blather::JID.new("test\\40onboarding.example.com@proxy")
1650					),
1651					TelSelections::ChooseTel::Tn::LocalInventory.new(
1652						TelSelections::ChooseTel::Tn.new("+15555550000"),
1653						"bandwidth_account_id"
1654					)
1655				).write.catch { |e| e }
1656			end
1657			assert_equal :test_result, result
1658			assert_mock @sgx
1659			assert_mock Registration::Finish::REDIS
1660			assert_mock Bwmsgsv2Repo::REDIS
1661			assert_mock Command::COMMAND_MANAGER
1662		end
1663		em :test_write_local_inventory
1664
1665		def test_write_local_inventory_must_pay
1666			low_cust = customer(
1667				sgx: @sgx,
1668				jid: Blather::JID.new("test\\40onboarding.example.com@proxy")
1669			).with_balance(5.0)
1670			high_cust = customer(
1671				sgx: @sgx,
1672				jid: Blather::JID.new("test\\40onboarding.example.com@proxy")
1673			).with_balance(100.0)
1674
1675			stub_request(
1676				:post,
1677				"https://dashboard.bandwidth.com/v1.0/accounts/moveto/moveTns"
1678			).with(
1679				body: {
1680					CustomerOrderId: "test",
1681					SourceAccountId: "bandwidth_account_id",
1682					SiteId: "test_site",
1683					SipPeerId: "test_peer",
1684					TelephoneNumbers: { TelephoneNumber: "5555550000" }
1685				}.to_xml(indent: 0, root: "MoveTnsOrder")
1686			).to_return(status: 200, body: "", headers: {})
1687
1688			Registration::Finish::REDIS.expect(
1689				:get,
1690				nil,
1691				["jmp_customer_pending_invite-test"]
1692			)
1693			Registration::Finish::REDIS.expect(
1694				:del,
1695				nil,
1696				["jmp_customer_pending_invite-test"]
1697			)
1698			Registration::Finish::REDIS.expect(
1699				:hget,
1700				nil,
1701				["jmp_group_codes", nil]
1702			)
1703			Registration::Finish::DB.expect(
1704				:exec_defer,
1705				EMPromise.resolve(OpenStruct.new(cmd_tuples: 1)),
1706				[String, ["+15555550000"]]
1707			)
1708			Bwmsgsv2Repo::REDIS.expect(
1709				:get,
1710				EMPromise.resolve(nil),
1711				["jmp_customer_backend_sgx-test"]
1712			)
1713			Bwmsgsv2Repo::REDIS.expect(
1714				:set,
1715				nil,
1716				[
1717					"catapult_fwd-+15555550000",
1718					"xmpp:test\\40onboarding.example.com@proxy"
1719				]
1720			)
1721			Bwmsgsv2Repo::REDIS.expect(
1722				:set,
1723				nil,
1724				["catapult_fwd_timeout-customer_test@component", 25]
1725			)
1726
1727			local_tel = Minitest::Mock.new(
1728				TelSelections::ChooseTel::Tn::LocalInventory.new(
1729					TelSelections::ChooseTel::Tn.new("+15555550000"),
1730					"bandwidth_account_id",
1731					price: 10.0
1732				)
1733			)
1734
1735			result = execute_command do
1736				local_tel.expect(:charge, EMPromise.reject(:test_result), [Customer])
1737				@sgx.expect(
1738					:register!,
1739					EMPromise.resolve(@sgx.with(
1740						registered?: Blather::Stanza::Iq::IBR.new.tap do |ibr|
1741							ibr.phone = "+15555550000"
1742						end
1743					)),
1744					["+15555550000"]
1745				)
1746
1747				Command::COMMAND_MANAGER.expect(
1748					:write,
1749					EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
1750						iq.from = "customer@example.org"
1751						iq.form.fields = [
1752							{ var: "activation_method", value: "credit_card" }
1753						]
1754					}),
1755					[Matching.new do |iq|
1756						assert_equal :form, iq.form.type
1757						assert_equal "Purchase Number", iq.form.title
1758					end]
1759				)
1760
1761				Command.execution.customer_repo.expect(
1762					:find,
1763					EMPromise.resolve(high_cust),
1764					["test"]
1765				)
1766
1767				Command::COMMAND_MANAGER.expect(
1768					:write,
1769					EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
1770						iq.from = "customer@example.org"
1771					}),
1772					[Matching.new do |iq|
1773						assert_equal(
1774							"Pay by credit card, save, then next here to continue: " \
1775							"http://creditcard.example.com?&amount=10",
1776							iq.note.text
1777						)
1778					end]
1779				)
1780
1781				Registration::Finish.new(
1782					low_cust,
1783					local_tel
1784				).write.catch { |e| e }
1785			end
1786
1787			assert_equal :test_result, result
1788			assert_mock @sgx
1789			assert_mock Registration::Finish::REDIS
1790			assert_mock Bwmsgsv2Repo::REDIS
1791			assert_mock Command::COMMAND_MANAGER
1792		end
1793		em :test_write_local_inventory_must_pay
1794
1795		def test_write_tn_fail
1796			create_order = stub_request(
1797				:post,
1798				"https://dashboard.bandwidth.com/v1.0/accounts//orders"
1799			).to_return(status: 201, body: <<~RESPONSE)
1800				<OrderResponse>
1801					<Order>
1802						<id>test_order</id>
1803					</Order>
1804				</OrderResponse>
1805			RESPONSE
1806			stub_request(
1807				:get,
1808				"https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
1809			).to_return(status: 201, body: <<~RESPONSE)
1810				<OrderResponse>
1811					<OrderStatus>FAILED</OrderStatus>
1812				</OrderResponse>
1813			RESPONSE
1814
1815			result = execute_command do
1816				Command::COMMAND_MANAGER.expect(
1817					:write,
1818					EMPromise.reject(:test_result),
1819					[Matching.new do |iq|
1820						assert_equal :form, iq.form.type
1821						assert_equal(
1822							"The JMP number (555) 555-0000 is no longer available.",
1823							iq.form.instructions
1824						)
1825					end]
1826				)
1827
1828				@finish.write.catch { |e| e }
1829			end
1830
1831			assert_equal :test_result, result
1832			assert_mock Command::COMMAND_MANAGER
1833			assert_instance_of(
1834				TelSelections::ChooseTel,
1835				Registration::Finish::TEL_SELECTIONS["test@example.com"]
1836			)
1837			assert_requested create_order
1838		end
1839		em :test_write_tn_fail
1840	end
1841
1842	class SnikketTest < Minitest::Test
1843		Command::COMMAND_MANAGER = Minitest::Mock.new
1844		Registration::FinishOnboarding::Snikket::IQ_MANAGER = Minitest::Mock.new
1845
1846		def setup
1847			@sgx = Minitest::Mock.new(mksgx)
1848			@snikket = Registration::FinishOnboarding::Snikket.new(
1849				customer(sgx: @sgx),
1850				"+15555550000",
1851				db: FakeDB.new
1852			)
1853		end
1854
1855		def test_write
1856			xmpp_uri = "xmpp:test.snikket.chat?register;preauth=NEWTOKEN"
1857
1858			subdomain_form = Blather::Stanza::Iq::Command.new
1859			subdomain_form.form.fields = [
1860				{ var: "subdomain", value: "test" }
1861			]
1862
1863			launched = Snikket::Launched.new
1864			launched << Niceogiri::XML::Node.new(
1865				:launched, launched.document, "xmpp:snikket.org/hosting/v1"
1866			).tap { |inner|
1867				inner << Niceogiri::XML::Node.new(
1868					:'instance-id', launched.document, "xmpp:snikket.org/hosting/v1"
1869				).tap { |id|
1870					id.content = "si-1234"
1871				}
1872				inner << Niceogiri::XML::Node.new(
1873					:bootstrap, launched.document, "xmpp:snikket.org/hosting/v1"
1874				).tap { |bootstrap|
1875					bootstrap << Niceogiri::XML::Node.new(
1876						:token, launched.document, "xmpp:snikket.org/hosting/v1"
1877					).tap { |token|
1878						token.content = "TOKEN"
1879					}
1880				}
1881			}
1882
1883			blather = Minitest::Mock.new
1884			blather.expect(
1885				:<<,
1886				nil,
1887				[Matching.new do |reply|
1888					assert_equal :completed, reply.status
1889					assert_equal(
1890						xmpp_uri,
1891						OOB.find_or_create(reply.command).url
1892					)
1893				end]
1894			)
1895
1896			execute_command(blather: blather) do
1897				Command::COMMAND_MANAGER.expect(
1898					:write,
1899					EMPromise.resolve(subdomain_form),
1900					[Matching.new do |iq|
1901						assert_equal :form, iq.form.type
1902						assert iq.form.field("subdomain")
1903					end]
1904				)
1905
1906				Registration::FinishOnboarding::Snikket::IQ_MANAGER.expect(
1907					:write,
1908					EMPromise.resolve(launched),
1909					[Matching.new do |iq|
1910						assert_equal :set, iq.type
1911						assert_equal CONFIG[:snikket_hosting_api], iq.to.to_s
1912						assert_equal(
1913							"test.snikket.chat",
1914							iq.xpath(
1915								"./ns:launch/ns:domain",
1916								ns: "xmpp:snikket.org/hosting/v1"
1917							).text
1918						)
1919					end]
1920				)
1921
1922				# Webmock doesn't support redirects properly, but they work live
1923				stub_request(
1924					:head, "https://test.snikket.chat/invites_bootstrap?token=TOKEN"
1925				).to_return(
1926					status: 200,
1927					headers: {
1928						"link" => "<#{xmpp_uri}>; rel=\"alternate\""
1929					}
1930				)
1931
1932				@snikket.write
1933			end
1934
1935			assert_mock Command::COMMAND_MANAGER
1936			assert_mock Registration::FinishOnboarding::Snikket::IQ_MANAGER
1937			assert_mock blather
1938		end
1939		em :test_write
1940
1941		def test_write_not_yet
1942			subdomain_form = Blather::Stanza::Iq::Command.new
1943			subdomain_form.form.fields = [
1944				{ var: "subdomain", value: "test" }
1945			]
1946
1947			launched = Snikket::Launched.new
1948			launched << Niceogiri::XML::Node.new(
1949				:launched, launched.document, "xmpp:snikket.org/hosting/v1"
1950			).tap { |inner|
1951				inner << Niceogiri::XML::Node.new(
1952					:'instance-id', launched.document, "xmpp:snikket.org/hosting/v1"
1953				).tap { |id|
1954					id.content = "si-1234"
1955				}
1956				inner << Niceogiri::XML::Node.new(
1957					:bootstrap, launched.document, "xmpp:snikket.org/hosting/v1"
1958				).tap { |bootstrap|
1959					bootstrap << Niceogiri::XML::Node.new(
1960						:token, launched.document, "xmpp:snikket.org/hosting/v1"
1961					).tap { |token|
1962						token.content = "TOKEN"
1963					}
1964				}
1965			}
1966
1967			result = execute_command do
1968				Command::COMMAND_MANAGER.expect(
1969					:write,
1970					EMPromise.resolve(subdomain_form),
1971					[Matching.new do |iq|
1972						assert_equal :form, iq.form.type
1973						assert iq.form.field("subdomain")
1974					end]
1975				)
1976
1977				Registration::FinishOnboarding::Snikket::IQ_MANAGER.expect(
1978					:write,
1979					EMPromise.resolve(launched),
1980					[Matching.new do |iq|
1981						assert_equal :set, iq.type
1982						assert_equal CONFIG[:snikket_hosting_api], iq.to.to_s
1983						assert_equal(
1984							"test.snikket.chat",
1985							iq.xpath(
1986								"./ns:launch/ns:domain",
1987								ns: "xmpp:snikket.org/hosting/v1"
1988							).text
1989						)
1990					end]
1991				)
1992
1993				stub_request(
1994					:head, "https://test.snikket.chat/invites_bootstrap?token=TOKEN"
1995				).to_timeout
1996
1997				Command::COMMAND_MANAGER.expect(
1998					:write,
1999					EMPromise.reject(:test_result),
2000					[Matching.new do |iq|
2001						assert_equal :result, iq.form.type
2002						assert iq.form.instructions =~ / test\.snikket\.chat /
2003						assert_equal "jid-single", iq.form.field("support").type
2004					end]
2005				)
2006
2007				@snikket.write.catch { |e| e }
2008			end
2009
2010			assert_equal :test_result, result
2011			assert_mock Command::COMMAND_MANAGER
2012			assert_mock Registration::FinishOnboarding::Snikket::IQ_MANAGER
2013		end
2014		em :test_write_not_yet
2015
2016		def test_write_already_taken
2017			subdomain_form = Blather::Stanza::Iq::Command.new
2018			subdomain_form.form.fields = [
2019				{ var: "subdomain", value: "test" }
2020			]
2021
2022			launched = Snikket::Launched.new.as_error(
2023				"internal-server-error",
2024				:wait,
2025				"This is an error"
2026			)
2027
2028			result = execute_command do
2029				Command::COMMAND_MANAGER.expect(
2030					:write,
2031					EMPromise.resolve(subdomain_form),
2032					[Matching.new do |iq|
2033						assert_equal :form, iq.form.type
2034						assert iq.form.field("subdomain")
2035					end]
2036				)
2037
2038				Registration::FinishOnboarding::Snikket::IQ_MANAGER.expect(
2039					:write,
2040					EMPromise.reject(launched),
2041					[Matching.new do |iq|
2042						assert_equal :set, iq.type
2043						assert_equal CONFIG[:snikket_hosting_api], iq.to.to_s
2044						assert_equal(
2045							"test.snikket.chat",
2046							iq.xpath(
2047								"./ns:launch/ns:domain",
2048								ns: "xmpp:snikket.org/hosting/v1"
2049							).text
2050						)
2051					end]
2052				)
2053
2054				stub_request(
2055					:head, "https://test.snikket.chat/invites_bootstrap?token=TOKEN"
2056				).to_timeout
2057
2058				Command::COMMAND_MANAGER.expect(
2059					:write,
2060					EMPromise.reject(:test_result),
2061					[Matching.new do |iq|
2062						assert iq.executing?
2063						assert_equal(
2064							"This is an error",
2065							iq.form.field("subdomain").desc
2066						)
2067					end]
2068				)
2069
2070				@snikket.write.catch { |e| e }
2071			end
2072
2073			assert_equal :test_result, result
2074			assert_mock Command::COMMAND_MANAGER
2075			assert_mock Registration::FinishOnboarding::Snikket::IQ_MANAGER
2076		end
2077		em :test_write_already_taken
2078	end
2079
2080	class SnikketCustomDomainTest < Minitest::Test
2081		def setup
2082			@snikket = Registration::FinishOnboarding::CustomDomain.new(
2083				customer,
2084				"+15555550000",
2085				db: FakeDB.new
2086			)
2087		end
2088
2089		def test_write_needs_dns
2090			domain_form = Blather::Stanza::Iq::Command.new
2091			domain_form.form.fields = [
2092				{ var: "domain", value: "snikket.example.com" }
2093			]
2094
2095			launched = Snikket::Launched.new
2096			launched << Niceogiri::XML::Node.new(
2097				:launched, launched.document, "xmpp:snikket.org/hosting/v1"
2098			).tap { |inner|
2099				inner << Niceogiri::XML::Node.new(
2100					:'instance-id', launched.document, "xmpp:snikket.org/hosting/v1"
2101				).tap { |id|
2102					id.content = "si-1234"
2103				}
2104				inner << Niceogiri::XML::Node.new(
2105					:status, launched.document, "xmpp:snikket.org/hosting/v1"
2106				).tap { |id|
2107					id.content = "needs_dns"
2108				}
2109				inner << Niceogiri::XML::Node.new(
2110					:records, launched.document, "xmpp:snikket.org/hosting/v1"
2111				).tap { |records|
2112					records << Niceogiri::XML::Node.new(
2113						:record, launched.document, "xmpp:snikket.org/hosting/v1"
2114					).tap { |record|
2115						record << Niceogiri::XML::Node.new(
2116							:name, launched.document, "xmpp:snikket.org/hosting/v1"
2117						).tap { |name| name.content = "snikket.example.com" }
2118						record << Niceogiri::XML::Node.new(
2119							:type, launched.document, "xmpp:snikket.org/hosting/v1"
2120						).tap { |type| type.content = "AAAA" }
2121						record << Niceogiri::XML::Node.new(
2122							:status, launched.document, "xmpp:snikket.org/hosting/v1"
2123						).tap { |type| type.content = "incorrect" }
2124						record << Niceogiri::XML::Node.new(
2125							:expected, launched.document, "xmpp:snikket.org/hosting/v1"
2126						).tap { |expected|
2127							expected << Niceogiri::XML::Node.new(
2128								:value, launched.document, "xmpp:snikket.org/hosting/v1"
2129							).tap { |value| value.content = "1::2" }
2130						}
2131						record << Niceogiri::XML::Node.new(
2132							:found, launched.document, "xmpp:snikket.org/hosting/v1"
2133						).tap { |found|
2134							found << Niceogiri::XML::Node.new(
2135								:value, launched.document, "xmpp:snikket.org/hosting/v1"
2136							).tap { |value| value.content = "0::0" }
2137						}
2138					}
2139				}
2140			}
2141
2142			result = execute_command do
2143				Command::COMMAND_MANAGER.expect(
2144					:write,
2145					EMPromise.resolve(domain_form),
2146					[Matching.new do |iq|
2147						assert_equal :form, iq.form.type
2148						assert iq.form.field("domain")
2149					end]
2150				)
2151
2152				Registration::FinishOnboarding::Snikket::IQ_MANAGER.expect(
2153					:write,
2154					EMPromise.resolve(launched),
2155					[Matching.new do |iq|
2156						assert_equal :set, iq.type
2157						assert_equal CONFIG[:snikket_hosting_api], iq.to.to_s
2158						assert_equal(
2159							"snikket.example.com",
2160							iq.xpath(
2161								"./ns:launch/ns:domain",
2162								ns: "xmpp:snikket.org/hosting/v1"
2163							).text
2164						)
2165					end]
2166				)
2167
2168				Command::COMMAND_MANAGER.expect(
2169					:write,
2170					EMPromise.reject(:test_result),
2171					[Matching.new do |iq|
2172						assert_equal :form, iq.form.type
2173						assert_equal(
2174							["snikket.example.com"],
2175							iq.form.xpath(
2176								"./ns:item/ns:field[@var='name']/ns:value",
2177								ns: "jabber:x:data"
2178							).map(&:content)
2179						)
2180						assert_equal(
2181							["1::2"],
2182							iq.form.xpath(
2183								"./ns:item/ns:field[@var='expected']/ns:value",
2184								ns: "jabber:x:data"
2185							).map(&:content)
2186						)
2187					end]
2188				)
2189
2190				@snikket.write.catch { |e| e }
2191			end
2192
2193			assert_equal :test_result, result
2194			assert_mock Command::COMMAND_MANAGER
2195			assert_mock Registration::FinishOnboarding::Snikket::IQ_MANAGER
2196		end
2197		em :test_write_needs_dns
2198	end
2199end