test_registration.rb

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