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