# frozen_string_literal: true

require "minitest"

require "test_helper"

require "paypal_done"
require "migrate_billing"

Command::COMMAND_MANAGER = Minitest::Mock.new
CustomerPlan::DB = Minitest::Mock.new
MigrateBilling::BLATHER = Minitest::Mock.new

class TestMigrateBilling < Minitest::Test
	def setup
		@sgx = Minitest::Mock.new
	end

	def test_write_registered
		execute_command do |exe|
			Command::COMMAND_MANAGER.expect(
				:write,
				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
					iq.form.fields = [
						{ var: "activation_method", value: "credit_card" },
						{ var: "plan_name", value: "test_usd" }
					]
					iq.from = "test@example.com"
				}),
				[Matching.new { |iq|
					assert_equal :form, iq.form.type
					assert iq.form.instructions.include?("legacy PayPal")
				}]
			)

			CustomerPlan::DB.expect(
				:exec_defer,
				nil,
				[
					String,
					Matching.new do |(customer_id, plan_name, parent_customer_id)|
						assert_equal "test", customer_id
						assert_equal "test_usd", plan_name
						assert_nil parent_customer_id
					end
				]
			)

			Command::COMMAND_MANAGER.expect(
				:write,
				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
					iq.action = :next
				}),
				[Matching.new { |iq|
					assert_equal :executing, iq.status
					assert_equal(
						"http://creditcard.example.com?&amount=1",
						OOB.find_or_create(iq.command).url
					)
				}]
			)

			@sgx.expect(
				:registered?,
				OpenStruct.new(phone: "+15550000")
			)

			exe.customer_repo.expect(
				:find,
				EMPromise.resolve(
					customer(
						plan_name: "test_usd",
						sgx: @sgx
					).with(balance: 100)
				),
				["test"]
			)
			# Apparently the constant assignment from
			# `RegistrationTest::InviteCodeTest` pollutes this
			# test
			Registration::Payment::MaybeBill::BillPlan.expect(
				:new,
				PaypalDone.new
			) { |*| true }

			MigrateBilling::BLATHER.expect(
				:join,
				nil,
				[CONFIG[:notify_admin], "sgx-jmp"]
			)
			MigrateBilling::BLATHER.expect(
				:say,
				nil,
				[
					CONFIG[:notify_admin],
					"test migrated to USD",
					:groupchat
				]
			)

			cust = customer(plan_name: "test_usd_old_billing", sgx: @sgx)
			result = MigrateBilling.new(cust).write.catch { |e|
				e
			}.sync

			assert_equal(result.stanza.note.text, PaypalDone::MESSAGE)
			assert_mock Registration::Payment::MaybeBill::BillPlan
			assert_mock Command::COMMAND_MANAGER
			assert_mock @sgx
		end
	end
	em :test_write_registered
end
