# frozen_string_literal: true

require "test_helper"
require_relative "../../sgx-bwmsgsv2"
require "rantly/minitest_extensions"
require_relative "rantly_extensions/data_extensions"

class InvisibleSeparatorPropertyTest < Minitest::Test
	def setup
		reset_stanzas!
		reset_redis!
		WebMock.reset!
	end

	BW_MESSAGES_URL =
		"https://messaging.bandwidth.com/api/v2/users/account/messages"

	def test_message_containing_invisible_separator_is_rejected
		property_of {
			chars = message_body(nil_pct: 0).chars
			insertions = range(1, 3)
			insertions.times { chars.insert(range(0, chars.length), "\u2063") }
			body = chars.join

			dest = nanpa_phone
			[body, dest]
		}.check { |body, dest|
			reset_stanzas!
			reset_redis!
			WebMock.reset!

			m = Blather::Stanza::Message.new("#{dest}@component", body)
			m.from = "test@example.com"
			process_stanza(m)

			assert_equal 1, written.length,
			             "Expected exactly one error stanza for body: #{body.inspect}"

			stanza = Blather::XMPPNode.parse(written.first.to_xml)
			assert stanza.error?,
			       "Expected error stanza for body: #{body.inspect}"

			error = stanza.find_first("error")
			assert_equal "wait", error["type"],
			             "Expected error type 'wait' for body: #{body.inspect}"
			assert_equal "recipient-unavailable", xmpp_error_name(error),
			             "Expected 'recipient-unavailable' for body: #{body.inspect}"
		}
	end
	em :test_message_containing_invisible_separator_is_rejected

	def test_message_without_invisible_separator_is_not_rejected_as_unavailable
		property_of {
			dest = nanpa_phone
			[message_body(nil_pct: 0, empty_pct: 0), dest]
		}.check { |body, dest|
			reset_stanzas!
			reset_redis!
			WebMock.reset!

			m = Blather::Stanza::Message.new("#{dest}@component", body)
			m.from = "test@example.com"

			# WebMock's JSON parser does ad-hoc conversion to YAML (!!!!)
			# then returns the parsed YAML object and pretends it's JSON.
			# The YAML parser chokes on (at least) backslashes. Avoid that
			# mess when you can.
			bw_req = stub_request(:post, BW_MESSAGES_URL).with { |req|
				parsed = ::JSON.parse(req.body)
				parsed["to"] == dest &&
					(parsed["text"] == m.body.to_s ||
					 (parsed["text"] == "" && parsed["media"]))
			}.to_return(
				status: 201,
				body: JSON.dump(id: "bw-msg-stub")
			)

			process_stanza(m)

			assert_empty written,
			             "Expected no error stanzas for body: #{body.inspect}"
			assert_requested bw_req
		}
	end
	em :test_message_without_invisible_separator_is_not_rejected_as_unavailable
end
