# frozen_string_literal: true

require "test_helper"
require_relative "../../sgx-bwmsgsv2"
require "rantly/minitest_extensions"
require_relative "generators/webhook"
require_relative "generators/message"

def panic(e)
	$panic = e
end

MMS_PROXY = "https://proxy.test.example.com/"

class WebhookPropertyTest < Minitest::Test
	def setup
		reset_stanzas!
		reset_redis!
	end

	def test_single_recipient_message_delivered_sends_one_receipt
		property_of {
			Webhook
				.new(REDIS)
				.type { "message-delivered" }
				.message { |registered, jid, dir, top_level_to|
					Message
						.new(REDIS)
						.to { [top_level_to] }
						.generate(registered, jid, dir)
				}
				.generate
		}.check { |metadata, example|
			result = invoke_webhook(example)
			assert_equal 200, result[0]
			assert_equal 1, written.length, "Should only send the delivery receipt"
			receipt = written.shift
			assert_equal(
				receipt.to,
				metadata["jid"],
				"Should send receipt to customer's jid"
			)
			assert_equal(
				receipt.from.to_s,
				"#{example["to"]}@#{ARGV[0]}",
				"Should send receipt from sender's Cheogram jid"
			)
		}
	end
	em :test_single_recipient_message_delivered_sends_one_receipt

	def test_multi_recipient_outbound_sends_no_receipts
		property_of {
			Webhook
				.new(REDIS)
				.type { choose(*Webhook::OUTBOUND_TYPES) }
				.message { |registered, jid, dir, top_level_to|
					Message
						.new(REDIS)
						.to {
							array(integer(2)) { nanpa_phone } +
								[top_level_to] +
								array(range(1, 3)) { nanpa_phone }
						}
						.generate(registered, jid, dir)
				}
				.generate
		}.check { |metadata, example|
			result = invoke_webhook(example)
			assert_equal 200, result[0]
			assert_equal 0, written.length, "Should not group chat receipts"
		}
	end
	em :test_multi_recipient_outbound_sends_no_receipts

	def test_single_recipient_message_failed_sends_one_error
		property_of {
			Webhook
				.new(REDIS)
				.type { "message-failed" }
				.message { |registered, jid, dir, top_level_to|
					Message
						.new(REDIS)
						.to { [top_level_to] }
						.generate(registered, jid, dir)
				}
				.generate
		}.check { |metadata, example|
			result = invoke_webhook(example)
			assert_equal 200, result[0]
			assert_equal(
				written.length,
				1,
				"Message failed should only send one notification"
			)
			assert_kind_of(
				::Blather::StanzaError,
				written.shift,
				"Should not notify message-failed"
			)
		}
	end
	em :test_single_recipient_message_failed_sends_one_error

	def test_outbound_unregistered_returns_403
		property_of {
			Webhook
				.new(REDIS)
				.registered {
					false
				}
				.type {
					choose(*Webhook::OUTBOUND_TYPES)
				}
				.generate
		}.check { |metadata, example|
			result = invoke_webhook(example)
			assert_equal [403, {}, "Customer not found\n"], result
			assert_empty written
			entries = REDIS.stream_entries("messages").sync
			assert_empty entries
		}
	end
	em :test_outbound_unregistered_returns_403

	def test_unknown_outbound_returns_200
		property_of {
			Webhook
				.new(REDIS)
				.type { "unknown" }
				.direction { "out" }
				.generate
		}.check { |metadata, example|
			result = invoke_webhook(example)
			assert_equal [200, {}, "OK"], result
			assert_empty written
			entries = REDIS.stream_entries("messages").sync
			assert_empty entries
		}
	end
	em :test_unknown_outbound_returns_200
end
