test_registration.rb

   1# frozen_string_literal: true
   2
   3require "test_helper"
   4require "customer"
   5require "registration"
   6
   7BandwidthTnReservationRepo::REDIS = FakeRedis.new
   8
   9class RegistrationTest < Minitest::Test
  10	def test_for_registered
  11		sgx = OpenStruct.new(
  12			registered?: OpenStruct.new(phone: "+15555550000")
  13		)
  14		iq = Blather::Stanza::Iq::Command.new
  15		iq.from = "test@example.com"
  16		result = execute_command(iq) do
  17			Registration.for(
  18				customer(sgx: sgx),
  19				nil,
  20				Minitest::Mock.new
  21			)
  22		end
  23		assert_kind_of Registration::Registered, result
  24	end
  25	em :test_for_registered
  26
  27	def test_for_activated
  28		reservation_req = stub_request(
  29			:post,
  30			"https://dashboard.bandwidth.com/v1.0/accounts//tnreservation"
  31		)
  32		web_manager = TelSelections.new(redis: FakeRedis.new)
  33		web_manager.set("test@example.net", "+15555550000")
  34		result = execute_command do
  35			sgx = OpenStruct.new(registered?: false)
  36			Registration.for(
  37				customer(
  38					plan_name: "test_usd",
  39					expires_at: Time.now + 999,
  40					sgx: sgx
  41				),
  42				nil,
  43				web_manager
  44			)
  45		end
  46		assert_kind_of Registration::Finish, result
  47		assert_requested reservation_req
  48	end
  49	em :test_for_activated
  50
  51	def test_for_not_activated_approved
  52		sgx = OpenStruct.new(registered?: false)
  53		web_manager = TelSelections.new(redis: FakeRedis.new)
  54		web_manager.set("test\\40approved.example.com@component", "+15555550000")
  55		iq = Blather::Stanza::Iq::Command.new
  56		iq.from = "test@approved.example.com"
  57		result = execute_command(iq) do
  58			Registration::Activation.for(
  59				customer(
  60					sgx: sgx,
  61					jid: Blather::JID.new("test\\40approved.example.com@component")
  62				),
  63				nil,
  64				web_manager
  65			)
  66		end
  67		assert_kind_of Registration::Activation::Allow, result
  68	end
  69	em :test_for_not_activated_approved
  70
  71	def test_for_not_activated_googleplay
  72		sgx = OpenStruct.new(registered?: false)
  73		web_manager = TelSelections.new(redis: FakeRedis.new)
  74		web_manager.set("test@example.net", "+15555550000")
  75		iq = Blather::Stanza::Iq::Command.new
  76		iq.from = "test@approved.example.com"
  77		result = execute_command(iq) do
  78			Registration::Activation.for(
  79				customer(sgx: sgx),
  80				"GARBLEDYGOOK==",
  81				web_manager
  82			)
  83		end
  84		assert_kind_of Registration::Activation::GooglePlay, result
  85	end
  86	em :test_for_not_activated_googleplay
  87
  88	def test_for_not_activated_with_customer_id
  89		sgx = OpenStruct.new(registered?: false)
  90		web_manager = TelSelections.new(redis: FakeRedis.new)
  91		web_manager.set("test@example.net", "+15555550000")
  92		iq = Blather::Stanza::Iq::Command.new
  93		iq.from = "test@example.com"
  94		result = execute_command(iq) do
  95			Registration::Activation.for(
  96				customer(sgx: sgx),
  97				nil,
  98				web_manager
  99			)
 100		end
 101		assert_kind_of Registration::Activation, result
 102	end
 103	em :test_for_not_activated_with_customer_id
 104
 105	class ActivationTest < Minitest::Test
 106		Registration::Activation::DB = Minitest::Mock.new
 107		Registration::Activation::REDIS = FakeRedis.new
 108		Registration::Activation::Payment = Minitest::Mock.new
 109		Registration::Activation::Finish = Minitest::Mock.new
 110		Command::COMMAND_MANAGER = Minitest::Mock.new
 111
 112		def setup
 113			@customer = Minitest::Mock.new(customer)
 114			@activation = Registration::Activation.new(@customer, "+15555550000")
 115		end
 116
 117		def test_write
 118			Command::COMMAND_MANAGER.expect(
 119				:write,
 120				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 121					iq.form.fields = [{ var: "plan_name", value: "test_usd" }]
 122				}),
 123				[Matching.new do |iq|
 124					assert_equal :form, iq.form.type
 125					assert_equal(
 126						"You've selected +15555550000 as your JMP number.",
 127						iq.form.instructions.lines.first.chomp
 128					)
 129				end]
 130			)
 131			@customer.expect(:with_plan, @customer, ["test_usd"])
 132			@customer.expect(:save_plan!, EMPromise.resolve(nil), [])
 133			Registration::Activation::Payment.expect(
 134				:for,
 135				EMPromise.reject(:test_result),
 136				[Blather::Stanza::Iq, @customer, "+15555550000"]
 137			)
 138			assert_equal(
 139				:test_result,
 140				execute_command { @activation.write.catch { |e| e } }
 141			)
 142			assert_mock Command::COMMAND_MANAGER
 143			assert_mock @customer
 144			assert_mock Registration::Activation::Payment
 145		end
 146		em :test_write
 147
 148		def test_write_with_code
 149			Command::COMMAND_MANAGER.expect(
 150				:write,
 151				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 152					iq.form.fields = [
 153						{ var: "plan_name", value: "test_usd" },
 154						{ var: "code", value: "123" }
 155					]
 156				}),
 157				[Matching.new do |iq|
 158					assert_equal :form, iq.form.type
 159					assert_equal(
 160						"You've selected +15555550000 as your JMP number.",
 161						iq.form.instructions.lines.first.chomp
 162					)
 163				end]
 164			)
 165			@customer.expect(:with_plan, @customer, ["test_usd"])
 166			@customer.expect(:save_plan!, EMPromise.resolve(nil), [])
 167			@customer.expect(:activate_plan_starting_now, EMPromise.resolve(nil), [])
 168			Registration::Activation::DB.expect(:transaction, []) { |&blk| blk.call }
 169			Registration::Activation::DB.expect(
 170				:exec,
 171				OpenStruct.new(cmd_tuples: 1),
 172				[String, ["test", "123"]]
 173			)
 174			Registration::Activation::Finish.expect(
 175				:new,
 176				OpenStruct.new(write: EMPromise.reject(:test_result)),
 177				[@customer, "+15555550000"]
 178			)
 179			assert_equal(
 180				:test_result,
 181				execute_command { @activation.write.catch { |e| e } }
 182			)
 183			assert_mock Command::COMMAND_MANAGER
 184			assert_mock @customer
 185			assert_mock Registration::Activation::Payment
 186			assert_mock Registration::Activation::DB
 187		end
 188		em :test_write_with_code
 189
 190		def test_write_with_group_code
 191			Command::COMMAND_MANAGER.expect(
 192				:write,
 193				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 194					iq.form.fields = [
 195						{ var: "plan_name", value: "test_usd" },
 196						{ var: "code", value: "123" }
 197					]
 198				}),
 199				[Matching.new do |iq|
 200					assert_equal :form, iq.form.type
 201					assert_equal(
 202						"You've selected +15555550000 as your JMP number.",
 203						iq.form.instructions.lines.first.chomp
 204					)
 205				end]
 206			)
 207			@customer.expect(:with_plan, @customer, ["test_usd"])
 208			@customer.expect(:save_plan!, EMPromise.resolve(nil), [])
 209			Registration::Activation::DB.expect(:transaction, []) { |&blk| blk.call }
 210			Registration::Activation::DB.expect(
 211				:exec,
 212				OpenStruct.new(cmd_tuples: 0),
 213				[String, ["test", "123"]]
 214			)
 215			Registration::Activation::Payment.expect(
 216				:for,
 217				EMPromise.reject(:test_result),
 218				[Blather::Stanza::Iq, @customer, "+15555550000"]
 219			)
 220			assert_equal(
 221				:test_result,
 222				execute_command { @activation.write.catch { |e| e } }
 223			)
 224			assert_equal(
 225				"123",
 226				Registration::Activation::REDIS.get(
 227					"jmp_customer_pending_invite-test"
 228				).sync
 229			)
 230			assert_mock Command::COMMAND_MANAGER
 231			assert_mock @customer
 232			assert_mock Registration::Activation::Payment
 233			assert_mock Registration::Activation::DB
 234		end
 235		em :test_write_with_group_code
 236	end
 237
 238	class AllowTest < Minitest::Test
 239		Command::COMMAND_MANAGER = Minitest::Mock.new
 240		Registration::Activation::Allow::DB = Minitest::Mock.new
 241
 242		def test_write_credit_to_nil
 243			cust = Minitest::Mock.new(customer("test"))
 244			allow = Registration::Activation::Allow.new(cust, "+15555550000", nil)
 245
 246			Command::COMMAND_MANAGER.expect(
 247				:write,
 248				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 249					iq.form.fields = [{ var: "plan_name", value: "test_usd" }]
 250				}),
 251				[Matching.new do |iq|
 252					assert_equal :form, iq.form.type
 253					assert_equal(
 254						"You've selected +15555550000 as your JMP number.",
 255						iq.form.instructions.lines.first.chomp
 256					)
 257					assert_equal 1, iq.form.fields.length
 258				end]
 259			)
 260			Registration::Activation::Allow::DB.expect(
 261				:transaction,
 262				EMPromise.reject(:test_result)
 263			) do |&blk|
 264				blk.call
 265				true
 266			end
 267			cust.expect(:with_plan, cust, ["test_usd"])
 268			cust.expect(:activate_plan_starting_now, nil)
 269			assert_equal(
 270				:test_result,
 271				execute_command { allow.write.catch { |e| e } }
 272			)
 273			assert_mock Command::COMMAND_MANAGER
 274		end
 275		em :test_write_credit_to_nil
 276
 277		def test_write_credit_to_refercust
 278			cust = Minitest::Mock.new(customer("test"))
 279			allow = Registration::Activation::Allow.new(
 280				cust, "+15555550000", "refercust"
 281			)
 282
 283			Command::COMMAND_MANAGER.expect(
 284				:write,
 285				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
 286					iq.form.fields = [{ var: "plan_name", value: "test_usd" }]
 287				}),
 288				[Matching.new do |iq|
 289					assert_equal :form, iq.form.type
 290					assert_equal(
 291						"You've selected +15555550000 as your JMP number.",
 292						iq.form.instructions.lines.first.chomp
 293					)
 294					assert_equal 1, iq.form.fields.length
 295				end]
 296			)
 297			Registration::Activation::Allow::DB.expect(
 298				:transaction,
 299				EMPromise.reject(:test_result)
 300			) do |&blk|
 301				blk.call
 302				true
 303			end
 304			Registration::Activation::Allow::DB.expect(
 305				:exec,
 306				nil,
 307				[String, ["refercust", "test"]]
 308			)
 309			cust.expect(:with_plan, cust, ["test_usd"])
 310			cust.expect(:activate_plan_starting_now, nil)
 311			assert_equal(
 312				:test_result,
 313				execute_command { allow.write.catch { |e| e } }
 314			)
 315			assert_mock Command::COMMAND_MANAGER
 316		end
 317		em :test_write_credit_to_refercust
 318	end
 319
 320	class PaymentTest < Minitest::Test
 321		CustomerFinancials::BRAINTREE = Minitest::Mock.new
 322
 323		def test_for_bitcoin
 324			iq = Blather::Stanza::Iq::Command.new
 325			iq.form.fields = [
 326				{ var: "activation_method", value: "bitcoin" },
 327				{ var: "plan_name", value: "test_usd" }
 328			]
 329			result = Registration::Payment.for(iq, customer, "+15555550000")
 330			assert_kind_of Registration::Payment::Bitcoin, result
 331		end
 332
 333		def test_for_credit_card
 334			braintree_customer = Minitest::Mock.new
 335			CustomerFinancials::BRAINTREE.expect(
 336				:customer,
 337				braintree_customer
 338			)
 339			CustomerFinancials::REDIS.expect(:smembers, [], ["block_credit_cards"])
 340			braintree_customer.expect(
 341				:find,
 342				EMPromise.resolve(OpenStruct.new(payment_methods: [])),
 343				["test"]
 344			)
 345			iq = Blather::Stanza::Iq::Command.new
 346			iq.from = "test@example.com"
 347			iq.form.fields = [
 348				{ var: "activation_method", value: "credit_card" },
 349				{ var: "plan_name", value: "test_usd" }
 350			]
 351			cust = customer
 352			result = execute_command do
 353				Command.execution.customer_repo.expect(:find, cust, ["test"])
 354				Registration::Payment.for(
 355					iq,
 356					cust,
 357					""
 358				).sync
 359			end
 360			assert_kind_of Registration::Payment::CreditCard, result
 361		end
 362		em :test_for_credit_card
 363
 364		def test_for_code
 365			iq = Blather::Stanza::Iq::Command.new
 366			iq.form.fields = [
 367				{ var: "activation_method", value: "code" },
 368				{ var: "plan_name", value: "test_usd" }
 369			]
 370			result = Registration::Payment.for(
 371				iq,
 372				customer,
 373				"+15555550000"
 374			)
 375			assert_kind_of Registration::Payment::InviteCode, result
 376		end
 377
 378		class BitcoinTest < Minitest::Test
 379			Registration::Payment::Bitcoin::BTC_SELL_PRICES = Minitest::Mock.new
 380			CustomerFinancials::REDIS = Minitest::Mock.new
 381
 382			def setup
 383				@customer = Minitest::Mock.new(
 384					customer(plan_name: "test_usd")
 385				)
 386				@customer.expect(
 387					:add_btc_address,
 388					EMPromise.resolve("testaddr")
 389				)
 390				@bitcoin = Registration::Payment::Bitcoin.new(
 391					@customer,
 392					"+15555550000"
 393				)
 394			end
 395
 396			def test_write
 397				CustomerFinancials::REDIS.expect(
 398					:smembers,
 399					EMPromise.resolve([]),
 400					["jmp_customer_btc_addresses-test"]
 401				)
 402				blather = Minitest::Mock.new
 403				Command::COMMAND_MANAGER.expect(
 404					:write,
 405					EMPromise.reject(SessionManager::Timeout.new),
 406					[Matching.new do |reply|
 407						assert_equal :canceled, reply.status
 408						assert_equal "1.000000", reply.form.field("amount").value
 409						assert_equal "testaddr", reply.form.field("btc_addresses").value
 410						true
 411					end]
 412				)
 413				Registration::Payment::Bitcoin::BTC_SELL_PRICES.expect(
 414					:usd,
 415					EMPromise.resolve(BigDecimal(1))
 416				)
 417				@bitcoin.stub(:save, EMPromise.resolve(nil)) do
 418					execute_command(blather: blather) do
 419						@bitcoin.write
 420					end
 421				end
 422				assert_mock blather
 423			end
 424			em :test_write
 425		end
 426
 427		class CreditCardTest < Minitest::Test
 428			def setup
 429				@credit_card = Registration::Payment::CreditCard.new(
 430					customer,
 431					"+15555550000"
 432				)
 433			end
 434
 435			def test_for
 436				cust = Minitest::Mock.new(customer)
 437				cust.expect(
 438					:payment_methods,
 439					EMPromise.resolve(OpenStruct.new(default_payment_method: :test))
 440				)
 441				execute_command do
 442					Command.execution.customer_repo.expect(:find, cust, ["test"])
 443					assert_kind_of(
 444						Registration::Payment::CreditCard::Activate,
 445						Registration::Payment::CreditCard.for(
 446							cust,
 447							"+15555550000"
 448						).sync
 449					)
 450				end
 451			end
 452			em :test_for
 453
 454			def test_for_has_balance
 455				cust = Minitest::Mock.new(customer)
 456				cust.expect(:balance, 100)
 457				cust.expect(:payment_methods, EMPromise.resolve(nil))
 458				execute_command do
 459					Command.execution.customer_repo.expect(:find, cust, ["test"])
 460					assert_kind_of(
 461						Registration::BillPlan,
 462						Registration::Payment::CreditCard.for(
 463							cust,
 464							"+15555550000"
 465						).sync
 466					)
 467				end
 468			end
 469			em :test_for_has_balance
 470
 471			def test_write
 472				result = execute_command do
 473					Command::COMMAND_MANAGER.expect(
 474						:write,
 475						EMPromise.reject(:test_result),
 476						[Matching.new do |reply|
 477							assert_equal [:execute, :next, :prev], reply.allowed_actions
 478							assert_equal(
 479								"Add credit card, save, then next here to continue: " \
 480								"http://creditcard.example.com?&amount=1",
 481								reply.note.content
 482							)
 483						end]
 484					)
 485
 486					@credit_card.write.catch { |e| e }
 487				end
 488
 489				assert_equal :test_result, result
 490			end
 491			em :test_write
 492		end
 493
 494		class MailTest < Minitest::Test
 495			def setup
 496				@mail = Registration::Payment::Mail.new(
 497					customer(plan_name: "test_cad"),
 498					"+15555550000"
 499				)
 500			end
 501
 502			def test_write
 503				result = execute_command do
 504					Command::COMMAND_MANAGER.expect(
 505						:write,
 506						EMPromise.reject(:test_result),
 507						[Matching.new do |reply|
 508							assert_equal [:execute, :prev], reply.allowed_actions
 509							refute reply.form.instructions.empty?
 510							assert_equal(
 511								"A Mailing Address",
 512								reply.form.field("adr").value
 513							)
 514							assert_equal(
 515								"interac@example.com",
 516								reply.form.field("interac_email").value
 517							)
 518						end]
 519					)
 520
 521					@mail.write.catch { |e| e }
 522				end
 523
 524				assert_equal :test_result, result
 525			end
 526			em :test_write
 527		end
 528
 529		class ActivateTest < Minitest::Test
 530			Registration::Payment::CreditCard::Activate::Finish =
 531				Minitest::Mock.new
 532			Registration::Payment::CreditCard::Activate::CreditCardSale =
 533				Minitest::Mock.new
 534			Command::COMMAND_MANAGER = Minitest::Mock.new
 535
 536			def test_write
 537				customer = Minitest::Mock.new(
 538					customer(plan_name: "test_usd")
 539				)
 540				Registration::Payment::CreditCard::Activate::CreditCardSale.expect(
 541					:create,
 542					EMPromise.resolve(nil)
 543				) do |acustomer, amount:, payment_method:|
 544					assert_operator customer, :===, acustomer
 545					assert_equal CONFIG[:activation_amount], amount
 546					assert_equal :test_default_method, payment_method
 547				end
 548				customer.expect(
 549					:bill_plan,
 550					nil,
 551					note: "Bill +15555550000 for first month"
 552				)
 553				Registration::Payment::CreditCard::Activate::Finish.expect(
 554					:new,
 555					OpenStruct.new(write: nil),
 556					[customer, "+15555550000"]
 557				)
 558				execute_command do
 559					Registration::Payment::CreditCard::Activate.new(
 560						customer,
 561						:test_default_method,
 562						"+15555550000"
 563					).write
 564				end
 565				Registration::Payment::CreditCard::Activate::CreditCardSale.verify
 566				customer.verify
 567				Registration::Payment::CreditCard::Activate::Finish.verify
 568			end
 569			em :test_write
 570
 571			def test_write_declines
 572				customer = Minitest::Mock.new(
 573					customer(plan_name: "test_usd")
 574				)
 575				iq = Blather::Stanza::Iq::Command.new
 576				iq.from = "test@example.com"
 577				msg = Registration::Payment::CreditCard::Activate::DECLINE_MESSAGE
 578				Command::COMMAND_MANAGER.expect(
 579					:write,
 580					EMPromise.reject(:test_result),
 581					[Matching.new do |reply|
 582						assert_equal :error, reply.note_type
 583						assert_equal(
 584							"#{msg}: http://creditcard.example.com?&amount=1",
 585							reply.note.content
 586						)
 587					end]
 588				)
 589				result = execute_command do
 590					Registration::Payment::CreditCard::Activate::CreditCardSale.expect(
 591						:create,
 592						EMPromise.reject("declined")
 593					) do |acustomer, amount:, payment_method:|
 594						assert_operator customer, :===, acustomer
 595						assert_equal CONFIG[:activation_amount], amount
 596						assert_equal :test_default_method, payment_method
 597					end
 598
 599					Registration::Payment::CreditCard::Activate.new(
 600						customer,
 601						:test_default_method,
 602						"+15555550000"
 603					).write.catch { |e| e }
 604				end
 605				assert_equal :test_result, result
 606				Registration::Payment::CreditCard::Activate::CreditCardSale.verify
 607			end
 608			em :test_write_declines
 609		end
 610
 611		class InviteCodeTest < Minitest::Test
 612			Registration::Payment::InviteCode::DB =
 613				Minitest::Mock.new
 614			Registration::Payment::InviteCode::REDIS =
 615				Minitest::Mock.new
 616			Command::COMMAND_MANAGER = Minitest::Mock.new
 617			Registration::Payment::InviteCode::Finish =
 618				Minitest::Mock.new
 619			def test_write
 620				customer = customer(plan_name: "test_usd")
 621				Registration::Payment::InviteCode::DB.expect(:transaction, true, [])
 622				Registration::Payment::InviteCode::Finish.expect(
 623					:new,
 624					OpenStruct.new(write: nil),
 625					[
 626						customer,
 627						"+15555550000"
 628					]
 629				)
 630				execute_command do
 631					Registration::Payment::InviteCode::REDIS.expect(
 632						:get,
 633						EMPromise.resolve(nil),
 634						["jmp_invite_tries-test"]
 635					)
 636					Command::COMMAND_MANAGER.expect(
 637						:write,
 638						EMPromise.resolve(
 639							Blather::Stanza::Iq::Command.new.tap { |iq|
 640								iq.form.fields = [{ var: "code", value: "abc" }]
 641							}
 642						),
 643						[Matching.new do |reply|
 644							assert_equal :form, reply.form.type
 645							assert_nil reply.form.instructions
 646						end]
 647					)
 648
 649					Registration::Payment::InviteCode.new(
 650						customer,
 651						"+15555550000"
 652					).write
 653				end
 654				assert_mock Command::COMMAND_MANAGER
 655				assert_mock Registration::Payment::InviteCode::DB
 656				assert_mock Registration::Payment::InviteCode::REDIS
 657				assert_mock Registration::Payment::InviteCode::Finish
 658			end
 659			em :test_write
 660
 661			def test_write_bad_code
 662				result = execute_command do
 663					customer = customer(plan_name: "test_usd")
 664					Registration::Payment::InviteCode::REDIS.expect(
 665						:get,
 666						EMPromise.resolve(0),
 667						["jmp_invite_tries-test"]
 668					)
 669					Registration::Payment::InviteCode::DB.expect(
 670						:transaction,
 671						[]
 672					) { |&blk| blk.call }
 673					Registration::Payment::InviteCode::DB.expect(
 674						:exec,
 675						OpenStruct.new(cmd_tuples: 0),
 676						[String, ["test", "abc"]]
 677					)
 678					Registration::Payment::InviteCode::REDIS.expect(
 679						:incr,
 680						EMPromise.resolve(nil),
 681						["jmp_invite_tries-test"]
 682					)
 683					Registration::Payment::InviteCode::REDIS.expect(
 684						:expire,
 685						EMPromise.resolve(nil),
 686						["jmp_invite_tries-test", 60 * 60]
 687					)
 688					Command::COMMAND_MANAGER.expect(
 689						:write,
 690						EMPromise.resolve(
 691							Blather::Stanza::Iq::Command.new.tap { |iq|
 692								iq.form.fields = [{ var: "code", value: "abc" }]
 693							}
 694						),
 695						[Matching.new do |reply|
 696							assert_equal :form, reply.form.type
 697							assert_nil reply.form.instructions
 698						end]
 699					)
 700					Command::COMMAND_MANAGER.expect(
 701						:write,
 702						EMPromise.reject(:test_result),
 703						[Matching.new do |reply|
 704							assert_equal :form, reply.form.type
 705							assert_equal(
 706								"Not a valid invite code: abc",
 707								reply.form.instructions
 708							)
 709						end]
 710					)
 711
 712					Registration::Payment::InviteCode.new(
 713						customer,
 714						"+15555550000"
 715					).write.catch { |e| e }
 716				end
 717				assert_equal :test_result, result
 718				assert_mock Command::COMMAND_MANAGER
 719				assert_mock Registration::Payment::InviteCode::DB
 720				assert_mock Registration::Payment::InviteCode::REDIS
 721			end
 722			em :test_write_bad_code
 723
 724			def test_write_bad_code_over_limit
 725				result = execute_command do
 726					customer = customer(plan_name: "test_usd")
 727					Registration::Payment::InviteCode::REDIS.expect(
 728						:get,
 729						EMPromise.resolve(11),
 730						["jmp_invite_tries-test"]
 731					)
 732					Command::COMMAND_MANAGER.expect(
 733						:write,
 734						EMPromise.resolve(
 735							Blather::Stanza::Iq::Command.new.tap { |iq|
 736								iq.form.fields = [{ var: "code", value: "abc" }]
 737							}
 738						),
 739						[Matching.new do |reply|
 740							assert_equal :form, reply.form.type
 741							assert_nil reply.form.instructions
 742						end]
 743					)
 744					Command::COMMAND_MANAGER.expect(
 745						:write,
 746						EMPromise.reject(:test_result),
 747						[Matching.new do |reply|
 748							assert_equal :form, reply.form.type
 749							assert_equal "Too many wrong attempts", reply.form.instructions
 750						end]
 751					)
 752					Registration::Payment::InviteCode.new(
 753						customer,
 754						"+15555550000"
 755					).write.catch { |e| e }
 756				end
 757				assert_equal :test_result, result
 758				assert_mock Command::COMMAND_MANAGER
 759				assert_mock Registration::Payment::InviteCode::REDIS
 760			end
 761			em :test_write_bad_code_over_limit
 762		end
 763	end
 764
 765	class FinishTest < Minitest::Test
 766		Customer::BLATHER = Minitest::Mock.new
 767		Command::COMMAND_MANAGER = Minitest::Mock.new
 768		Registration::Finish::TEL_SELECTIONS = FakeTelSelections.new
 769		Registration::Finish::REDIS = Minitest::Mock.new
 770		Registration::Finish::DB = Minitest::Mock.new
 771		Bwmsgsv2Repo::REDIS = Minitest::Mock.new
 772		Registration::FinishOnboarding::DB = FakeDB.new
 773
 774		def setup
 775			@sgx = Minitest::Mock.new(TrivialBackendSgxRepo.new.get("test"))
 776			iq = Blather::Stanza::Iq::Command.new
 777			iq.from = "test\\40example.com@cheogram.com"
 778			@finish = Registration::Finish.new(
 779				customer(sgx: @sgx),
 780				"+15555550000"
 781			)
 782		end
 783
 784		def test_write
 785			create_order = stub_request(
 786				:post,
 787				"https://dashboard.bandwidth.com/v1.0/accounts//orders"
 788			).to_return(status: 201, body: <<~RESPONSE)
 789				<OrderResponse>
 790					<Order>
 791						<id>test_order</id>
 792					</Order>
 793				</OrderResponse>
 794			RESPONSE
 795			stub_request(
 796				:get,
 797				"https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
 798			).to_return(status: 201, body: <<~RESPONSE)
 799				<OrderResponse>
 800					<OrderStatus>COMPLETE</OrderStatus>
 801					<CompletedNumbers>
 802						<TelephoneNumber>
 803							<FullNumber>5555550000</FullNumber>
 804						</TelephoneNumber>
 805					</CompletedNumbers>
 806				</OrderResponse>
 807			RESPONSE
 808			stub_request(
 809				:post,
 810				"https://dashboard.bandwidth.com/v1.0/accounts//sites//sippeers//movetns"
 811			)
 812			Registration::Finish::REDIS.expect(
 813				:del,
 814				nil,
 815				["pending_tel_for-test@example.net"]
 816			)
 817			Registration::Finish::REDIS.expect(
 818				:get,
 819				nil,
 820				["jmp_customer_pending_invite-test"]
 821			)
 822			Registration::Finish::REDIS.expect(
 823				:del,
 824				nil,
 825				["jmp_customer_pending_invite-test"]
 826			)
 827			Registration::Finish::REDIS.expect(
 828				:hget,
 829				nil,
 830				["jmp_group_codes", nil]
 831			)
 832			Bwmsgsv2Repo::REDIS.expect(
 833				:set,
 834				nil,
 835				[
 836					"catapult_fwd-+15555550000",
 837					"xmpp:test@example.net"
 838				]
 839			)
 840			Bwmsgsv2Repo::REDIS.expect(
 841				:set,
 842				nil,
 843				["catapult_fwd_timeout-customer_test@component", 25]
 844			)
 845			Customer::BLATHER.expect(
 846				:<<,
 847				nil,
 848				[Matching.new do |m|
 849					assert_equal :chat, m.type
 850					assert m.body =~ /^Welcome to JMP/
 851				end]
 852			)
 853			blather = Minitest::Mock.new
 854			blather.expect(
 855				:<<,
 856				nil,
 857				[Matching.new do |reply|
 858					assert_equal :completed, reply.status
 859					assert_equal :info, reply.note_type
 860					assert_equal(
 861						"Your JMP account has been activated as +15555550000",
 862						reply.note.content
 863					)
 864				end]
 865			)
 866			execute_command(blather: blather) do
 867				@sgx.expect(
 868					:register!,
 869					EMPromise.resolve(@sgx.with(
 870						registered?: Blather::Stanza::Iq::IBR.new.tap do |ibr|
 871							ibr.phone = "+15555550000"
 872						end
 873					)),
 874					["+15555550000"]
 875				)
 876
 877				@finish.write
 878			end
 879			assert_requested create_order
 880			assert_mock @sgx
 881			assert_mock Registration::Finish::REDIS
 882			assert_mock Bwmsgsv2Repo::REDIS
 883			assert_mock Customer::BLATHER
 884			assert_mock blather
 885		end
 886		em :test_write
 887
 888		def test_write_onboarding
 889			create_order = stub_request(
 890				:post,
 891				"https://dashboard.bandwidth.com/v1.0/accounts//orders"
 892			).to_return(status: 201, body: <<~RESPONSE)
 893				<OrderResponse>
 894					<Order>
 895						<id>test_order</id>
 896					</Order>
 897				</OrderResponse>
 898			RESPONSE
 899			stub_request(
 900				:get,
 901				"https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
 902			).to_return(status: 201, body: <<~RESPONSE)
 903				<OrderResponse>
 904					<OrderStatus>COMPLETE</OrderStatus>
 905					<CompletedNumbers>
 906						<TelephoneNumber>
 907							<FullNumber>5555550000</FullNumber>
 908						</TelephoneNumber>
 909					</CompletedNumbers>
 910				</OrderResponse>
 911			RESPONSE
 912			stub_request(
 913				:post,
 914				"https://dashboard.bandwidth.com/v1.0/accounts//sites//sippeers//movetns"
 915			)
 916			Registration::Finish::REDIS.expect(
 917				:del,
 918				nil,
 919				["pending_tel_for-test\\40onboarding.example.com@proxy"]
 920			)
 921			Registration::Finish::REDIS.expect(
 922				:get,
 923				nil,
 924				["jmp_customer_pending_invite-test"]
 925			)
 926			Registration::Finish::REDIS.expect(
 927				:del,
 928				nil,
 929				["jmp_customer_pending_invite-test"]
 930			)
 931			Registration::Finish::REDIS.expect(
 932				:hget,
 933				nil,
 934				["jmp_group_codes", nil]
 935			)
 936			Bwmsgsv2Repo::REDIS.expect(
 937				:set,
 938				nil,
 939				[
 940					"catapult_fwd-+15555550000",
 941					"xmpp:test\\40onboarding.example.com@proxy"
 942				]
 943			)
 944			Bwmsgsv2Repo::REDIS.expect(
 945				:set,
 946				nil,
 947				["catapult_fwd_timeout-customer_test@component", 25]
 948			)
 949			result = execute_command do
 950				@sgx.expect(
 951					:register!,
 952					EMPromise.resolve(@sgx.with(
 953						registered?: Blather::Stanza::Iq::IBR.new.tap do |ibr|
 954							ibr.phone = "+15555550000"
 955						end
 956					)),
 957					["+15555550000"]
 958				)
 959
 960				Command::COMMAND_MANAGER.expect(
 961					:write,
 962					EMPromise.reject(:test_result),
 963					[Matching.new do |iq|
 964						assert_equal :form, iq.form.type
 965						assert iq.form.field("subdomain")
 966					end]
 967				)
 968
 969				Registration::Finish.new(
 970					customer(
 971						sgx: @sgx,
 972						jid: Blather::JID.new("test\\40onboarding.example.com@proxy")
 973					),
 974					"+15555550000"
 975				).write.catch { |e| e }
 976			end
 977			assert_equal :test_result, result
 978			assert_requested create_order
 979			assert_mock @sgx
 980			assert_mock Registration::Finish::REDIS
 981			assert_mock Bwmsgsv2Repo::REDIS
 982			assert_mock Command::COMMAND_MANAGER
 983		end
 984		em :test_write_onboarding
 985
 986		def test_write_tn_fail
 987			create_order = stub_request(
 988				:post,
 989				"https://dashboard.bandwidth.com/v1.0/accounts//orders"
 990			).to_return(status: 201, body: <<~RESPONSE)
 991				<OrderResponse>
 992					<Order>
 993						<id>test_order</id>
 994					</Order>
 995				</OrderResponse>
 996			RESPONSE
 997			stub_request(
 998				:get,
 999				"https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
1000			).to_return(status: 201, body: <<~RESPONSE)
1001				<OrderResponse>
1002					<OrderStatus>FAILED</OrderStatus>
1003				</OrderResponse>
1004			RESPONSE
1005
1006			result = execute_command do
1007				Command::COMMAND_MANAGER.expect(
1008					:write,
1009					EMPromise.reject(:test_result),
1010					[Matching.new do |iq|
1011						assert_equal :form, iq.form.type
1012						assert_equal(
1013							"The JMP number +15555550000 is no longer available.",
1014							iq.form.instructions
1015						)
1016					end]
1017				)
1018
1019				@finish.write.catch { |e| e }
1020			end
1021
1022			assert_equal :test_result, result
1023			assert_mock Command::COMMAND_MANAGER
1024			assert_instance_of(
1025				TelSelections::ChooseTel,
1026				Registration::Finish::TEL_SELECTIONS["test@example.com"]
1027			)
1028			assert_requested create_order
1029		end
1030		em :test_write_tn_fail
1031	end
1032
1033	class SnikketTest < Minitest::Test
1034		Command::COMMAND_MANAGER = Minitest::Mock.new
1035		Registration::FinishOnboarding::Snikket::IQ_MANAGER = Minitest::Mock.new
1036
1037		def setup
1038			@sgx = Minitest::Mock.new(TrivialBackendSgxRepo.new.get("test"))
1039			@snikket = Registration::FinishOnboarding::Snikket.new(
1040				customer,
1041				"+15555550000",
1042				db: FakeDB.new
1043			)
1044		end
1045
1046		def test_write
1047			xmpp_uri = "xmpp:test.snikket.chat?register;preauth=NEWTOKEN"
1048
1049			subdomain_form = Blather::Stanza::Iq::Command.new
1050			subdomain_form.form.fields = [
1051				{ var: "subdomain", value: "test" }
1052			]
1053
1054			launched = Snikket::Launched.new
1055			launched << Niceogiri::XML::Node.new(
1056				:launched, launched.document, "xmpp:snikket.org/hosting/v1"
1057			).tap { |inner|
1058				inner << Niceogiri::XML::Node.new(
1059					:'instance-id', launched.document, "xmpp:snikket.org/hosting/v1"
1060				).tap { |id|
1061					id.content = "si-1234"
1062				}
1063				inner << Niceogiri::XML::Node.new(
1064					:bootstrap, launched.document, "xmpp:snikket.org/hosting/v1"
1065				).tap { |bootstrap|
1066					bootstrap << Niceogiri::XML::Node.new(
1067						:token, launched.document, "xmpp:snikket.org/hosting/v1"
1068					).tap { |token|
1069						token.content = "TOKEN"
1070					}
1071				}
1072			}
1073
1074			blather = Minitest::Mock.new
1075			blather.expect(
1076				:<<,
1077				nil,
1078				[Matching.new do |reply|
1079					assert_equal :completed, reply.status
1080					assert_equal(
1081						xmpp_uri,
1082						OOB.find_or_create(reply.command).url
1083					)
1084				end]
1085			)
1086
1087			execute_command(blather: blather) do
1088				Command::COMMAND_MANAGER.expect(
1089					:write,
1090					EMPromise.resolve(subdomain_form),
1091					[Matching.new do |iq|
1092						assert_equal :form, iq.form.type
1093						assert iq.form.field("subdomain")
1094					end]
1095				)
1096
1097				Registration::FinishOnboarding::Snikket::IQ_MANAGER.expect(
1098					:write,
1099					EMPromise.resolve(launched),
1100					[Matching.new do |iq|
1101						assert_equal :set, iq.type
1102						assert_equal CONFIG[:snikket_hosting_api], iq.to.to_s
1103						assert_equal(
1104							"test.snikket.chat",
1105							iq.xpath(
1106								"./ns:launch/ns:domain",
1107								ns: "xmpp:snikket.org/hosting/v1"
1108							).text
1109						)
1110					end]
1111				)
1112
1113				# Webmock doesn't support redirects properly, but they work live
1114				stub_request(
1115					:head, "https://test.snikket.chat/invites_bootstrap?token=TOKEN"
1116				).to_return(
1117					status: 200,
1118					headers: {
1119						"link" => "<#{xmpp_uri}>; rel=\"alternate\""
1120					}
1121				)
1122
1123				@snikket.write
1124			end
1125
1126			assert_mock Command::COMMAND_MANAGER
1127			assert_mock Registration::FinishOnboarding::Snikket::IQ_MANAGER
1128			assert_mock blather
1129		end
1130		em :test_write
1131
1132		def test_write_not_yet
1133			subdomain_form = Blather::Stanza::Iq::Command.new
1134			subdomain_form.form.fields = [
1135				{ var: "subdomain", value: "test" }
1136			]
1137
1138			launched = Snikket::Launched.new
1139			launched << Niceogiri::XML::Node.new(
1140				:launched, launched.document, "xmpp:snikket.org/hosting/v1"
1141			).tap { |inner|
1142				inner << Niceogiri::XML::Node.new(
1143					:'instance-id', launched.document, "xmpp:snikket.org/hosting/v1"
1144				).tap { |id|
1145					id.content = "si-1234"
1146				}
1147				inner << Niceogiri::XML::Node.new(
1148					:bootstrap, launched.document, "xmpp:snikket.org/hosting/v1"
1149				).tap { |bootstrap|
1150					bootstrap << Niceogiri::XML::Node.new(
1151						:token, launched.document, "xmpp:snikket.org/hosting/v1"
1152					).tap { |token|
1153						token.content = "TOKEN"
1154					}
1155				}
1156			}
1157
1158			result = execute_command do
1159				Command::COMMAND_MANAGER.expect(
1160					:write,
1161					EMPromise.resolve(subdomain_form),
1162					[Matching.new do |iq|
1163						assert_equal :form, iq.form.type
1164						assert iq.form.field("subdomain")
1165					end]
1166				)
1167
1168				Registration::FinishOnboarding::Snikket::IQ_MANAGER.expect(
1169					:write,
1170					EMPromise.resolve(launched),
1171					[Matching.new do |iq|
1172						assert_equal :set, iq.type
1173						assert_equal CONFIG[:snikket_hosting_api], iq.to.to_s
1174						assert_equal(
1175							"test.snikket.chat",
1176							iq.xpath(
1177								"./ns:launch/ns:domain",
1178								ns: "xmpp:snikket.org/hosting/v1"
1179							).text
1180						)
1181					end]
1182				)
1183
1184				stub_request(
1185					:head, "https://test.snikket.chat/invites_bootstrap?token=TOKEN"
1186				).to_timeout
1187
1188				Command::COMMAND_MANAGER.expect(
1189					:write,
1190					EMPromise.reject(:test_result),
1191					[Matching.new do |iq|
1192						assert_equal :result, iq.form.type
1193						assert iq.form.instructions =~ / test\.snikket\.chat /
1194						assert_equal "jid-single", iq.form.field("support").type
1195					end]
1196				)
1197
1198				@snikket.write.catch { |e| e }
1199			end
1200
1201			assert_equal :test_result, result
1202			assert_mock Command::COMMAND_MANAGER
1203			assert_mock Registration::FinishOnboarding::Snikket::IQ_MANAGER
1204		end
1205		em :test_write_not_yet
1206
1207		def test_write_already_taken
1208			subdomain_form = Blather::Stanza::Iq::Command.new
1209			subdomain_form.form.fields = [
1210				{ var: "subdomain", value: "test" }
1211			]
1212
1213			launched = Snikket::Launched.new.as_error(
1214				"internal-server-error",
1215				:wait,
1216				"This is an error"
1217			)
1218
1219			result = execute_command do
1220				Command::COMMAND_MANAGER.expect(
1221					:write,
1222					EMPromise.resolve(subdomain_form),
1223					[Matching.new do |iq|
1224						assert_equal :form, iq.form.type
1225						assert iq.form.field("subdomain")
1226					end]
1227				)
1228
1229				Registration::FinishOnboarding::Snikket::IQ_MANAGER.expect(
1230					:write,
1231					EMPromise.reject(launched),
1232					[Matching.new do |iq|
1233						assert_equal :set, iq.type
1234						assert_equal CONFIG[:snikket_hosting_api], iq.to.to_s
1235						assert_equal(
1236							"test.snikket.chat",
1237							iq.xpath(
1238								"./ns:launch/ns:domain",
1239								ns: "xmpp:snikket.org/hosting/v1"
1240							).text
1241						)
1242					end]
1243				)
1244
1245				stub_request(
1246					:head, "https://test.snikket.chat/invites_bootstrap?token=TOKEN"
1247				).to_timeout
1248
1249				Command::COMMAND_MANAGER.expect(
1250					:write,
1251					EMPromise.reject(:test_result),
1252					[Matching.new do |iq|
1253						assert iq.executing?
1254						assert_equal(
1255							"This is an error",
1256							iq.form.field("subdomain").desc
1257						)
1258					end]
1259				)
1260
1261				@snikket.write.catch { |e| e }
1262			end
1263
1264			assert_equal :test_result, result
1265			assert_mock Command::COMMAND_MANAGER
1266			assert_mock Registration::FinishOnboarding::Snikket::IQ_MANAGER
1267		end
1268		em :test_write_already_taken
1269	end
1270end