@@ -582,187 +582,6 @@ class ComponentTest < Minitest::Test
end
em :test_passthrough_message_emits_to_stream
- def invoke_webhook(payload, extra_env: {})
- with_stubs([
- [
- SGXbwmsgsv2,
- :write,
- ->(data) { SGXbwmsgsv2.write_to_stream(data) }
- ]
- ]) do
- handler = WebhookHandler.new
- env = {
- "REQUEST_URI" => "/",
- "REQUEST_METHOD" => "POST",
- "params" => {"_json" => [payload]}
- }.merge(extra_env)
- handler.instance_variable_set(:@env, env)
- def handler.params
- @env["params"]
- end
-
- EMPromise.resolve(nil).then {
- handler.response(env)
- }.sync
- end
- end
-
- def test_inbound_sms_emits_to_stream
- payload = {
- "type" => "message-received",
- "to" => "+15550000000",
- "message" => {
- "id" => "bw-in-123",
- "direction" => "in",
- "owner" => "+15550000000",
- "from" => "+15551234567",
- "to" => ["+15550000000"],
- "time" => "2025-01-13T10:00:00Z",
- "text" => "Hello from outside"
- }
- }
-
- invoke_webhook(payload)
-
- entries = REDIS.stream_entries("messages").sync
- assert_equal 1, entries.length
-
- event = entries.first[:fields]
- assert_equal "in", event["event"]
- assert_equal "+15551234567", event["from"]
- assert_equal JSON.dump(["+15550000000"]), event["to"]
- assert_equal "bw-in-123", event["bandwidth_id"]
- assert_equal "+15550000000", event["owner"]
- assert_equal "Hello from outside", event["body"]
- assert_equal JSON.dump([]), event["media_urls"]
- end
- em :test_inbound_sms_emits_to_stream
-
- def test_inbound_mms_emits_to_stream_and_filters_smil
- payload = {
- "type" => "message-received",
- "to" => "+15550000000",
- "message" => {
- "id" => "bw-mms-456",
- "direction" => "in",
- "owner" => "+15550000000",
- "from" => "+15551234567",
- "to" => ["+15550000000"],
- "time" => "2025-01-13T10:05:00Z",
- "text" => "Check this out",
- "media" => [
- "https://example.com/image.jpg",
- "https://example.com/file.smil",
- "https://example.com/data.txt",
- "https://example.com/meta.xml"
- ]
- }
- }
-
- invoke_webhook(payload)
-
- entries = REDIS.stream_entries("messages").sync
- assert_equal 1, entries.length
-
- event = entries.first[:fields]
- assert_equal "in", event["event"]
- assert_equal JSON.dump(["https://example.com/image.jpg"]), event["media_urls"]
- end
- em :test_inbound_mms_emits_to_stream_and_filters_smil
-
- def test_message_delivered_emits_to_stream
- payload = {
- "type" => "message-delivered",
- "to" => "+15550000000",
- "message" => {
- "id" => "bw-out-789",
- "direction" => "out",
- "owner" => "+15550000000",
- "from" => "+15550000000",
- "to" => ["+15551234567"],
- "time" => "2025-01-13T10:10:00Z",
- "tag" => "stanza-id-abc extra-data"
- }
- }
-
- invoke_webhook(payload)
-
- entries = REDIS.stream_entries("messages").sync
- assert_equal 1, entries.length
-
- event = entries.first[:fields]
- assert_equal "delivered", event["event"]
- assert_equal "stanza-id-abc", event["stanza_id"]
- assert_equal "bw-out-789", event["bandwidth_id"]
- assert_equal "2025-01-13T10:10:00Z", event["timestamp"]
- end
- em :test_message_delivered_emits_to_stream
-
- def test_message_failed_emits_to_stream
- payload = {
- "type" => "message-failed",
- "to" => "+15551234567",
- "message" => {
- "id" => "bw-out-999",
- "direction" => "out",
- "owner" => "+15550000000",
- "from" => "+15550000000",
- "to" => ["+15551234567"],
- "time" => "2025-01-13T10:15:00Z",
- "tag" => "failed-stanza-xyz extra",
- "errorCode" => 4720,
- "description" => "Carrier rejected message"
- }
- }
-
- invoke_webhook(payload)
-
- entries = REDIS.stream_entries("messages").sync
- assert_equal 1, entries.length
-
- event = entries.first[:fields]
- assert_equal "failed", event["event"]
- assert_equal "failed-stanza-xyz", event["stanza_id"]
- assert_equal "bw-out-999", event["bandwidth_id"]
- assert_equal "4720", event["error_code"]
- assert_equal "Carrier rejected message", event["error_description"]
- assert_equal "2025-01-13T10:15:00Z", event["timestamp"]
- end
- em :test_message_failed_emits_to_stream
-
- def test_resend_emits_resend_event_instead_of_in
- payload = {
- "type" => "message-received",
- "message" => {
- "id" => "bw-in-resend-001",
- "direction" => "in",
- "owner" => "+15550000000",
- "from" => "+15551234567",
- "to" => ["+15550000000"],
- "time" => "2025-01-13T10:00:00Z",
- "text" => "Resent message"
- }
- }
-
- invoke_webhook(
- payload,
- extra_env: { "HTTP_X_JMP_RESEND_OF" => "1736762400000-0" }
- )
-
- entries = REDIS.stream_entries("messages").sync
- assert_equal 1, entries.length
-
- event = entries.first[:fields]
- assert_equal "resend", event["event"]
- assert_equal "bwmsgsv2", event["source"]
- assert_equal "+15550000000", event["owner"]
- assert_equal "1736762400000-0", event["original_stream_id"]
- assert_equal "bw-in-resend-001", event["original_bandwidth_id"]
- refute event.key?("from"), "Resend events should not duplicate message fields"
- refute event.key?("body"), "Resend events should not duplicate message fields"
- end
- em :test_resend_emits_resend_event_instead_of_in
-
def test_sentry_captures_handler_exception
captured_exceptions = []
repo = SGXbwmsgsv2.instance_variable_get(:@registration_repo)
@@ -0,0 +1,208 @@
+# frozen_string_literal: true
+
+require "test_helper"
+require_relative "../sgx-bwmsgsv2"
+
+def panic(e)
+ $panic = e
+end
+
+class WebhookHandlerTest < Minitest::Test
+ def setup
+ ARGV[0] = 'component'
+ SGXbwmsgsv2.instance_variable_set(:@written, [])
+
+ def SGXbwmsgsv2.write_to_stream(s)
+ @written ||= []
+ @written << s
+ end
+
+ REDIS.reset!
+ REDIS.set("catapult_jid-", "HERE")
+ REDIS.set("catapult_jid-+15550000000", "test@example.com")
+ REDIS.set("catapult_cred-test@example.com", [
+ 'account', 'user', 'password', '+15550000000'
+ ])
+ end
+
+ def invoke_webhook(payload, extra_env: {})
+ with_stubs([
+ [
+ SGXbwmsgsv2,
+ :write,
+ ->(data) { SGXbwmsgsv2.write_to_stream(data) }
+ ]
+ ]) do
+ handler = WebhookHandler.new
+ env = {
+ "REQUEST_URI" => "/",
+ "REQUEST_METHOD" => "POST",
+ "params" => {"_json" => [payload]}
+ }.merge(extra_env)
+ handler.instance_variable_set(:@env, env)
+ def handler.params
+ @env["params"]
+ end
+
+ EMPromise.resolve(nil).then {
+ handler.response(env)
+ }.sync
+ end
+ end
+
+ def test_inbound_sms_emits_to_stream
+ payload = {
+ "type" => "message-received",
+ "to" => "+15550000000",
+ "message" => {
+ "id" => "bw-in-123",
+ "direction" => "in",
+ "owner" => "+15550000000",
+ "from" => "+15551234567",
+ "to" => ["+15550000000"],
+ "time" => "2025-01-13T10:00:00Z",
+ "text" => "Hello from outside"
+ }
+ }
+
+ invoke_webhook(payload)
+
+ entries = REDIS.stream_entries("messages").sync
+ assert_equal 1, entries.length
+
+ event = entries.first[:fields]
+ assert_equal "in", event["event"]
+ assert_equal "+15551234567", event["from"]
+ assert_equal JSON.dump(["+15550000000"]), event["to"]
+ assert_equal "bw-in-123", event["bandwidth_id"]
+ assert_equal "+15550000000", event["owner"]
+ assert_equal "Hello from outside", event["body"]
+ assert_equal JSON.dump([]), event["media_urls"]
+ end
+ em :test_inbound_sms_emits_to_stream
+
+ def test_inbound_mms_emits_to_stream_and_filters_smil
+ payload = {
+ "type" => "message-received",
+ "to" => "+15550000000",
+ "message" => {
+ "id" => "bw-mms-456",
+ "direction" => "in",
+ "owner" => "+15550000000",
+ "from" => "+15551234567",
+ "to" => ["+15550000000"],
+ "time" => "2025-01-13T10:05:00Z",
+ "text" => "Check this out",
+ "media" => [
+ "https://example.com/image.jpg",
+ "https://example.com/file.smil",
+ "https://example.com/data.txt",
+ "https://example.com/meta.xml"
+ ]
+ }
+ }
+
+ invoke_webhook(payload)
+
+ entries = REDIS.stream_entries("messages").sync
+ assert_equal 1, entries.length
+
+ event = entries.first[:fields]
+ assert_equal "in", event["event"]
+ assert_equal JSON.dump(["https://example.com/image.jpg"]), event["media_urls"]
+ end
+ em :test_inbound_mms_emits_to_stream_and_filters_smil
+
+ def test_message_delivered_emits_to_stream
+ payload = {
+ "type" => "message-delivered",
+ "to" => "+15550000000",
+ "message" => {
+ "id" => "bw-out-789",
+ "direction" => "out",
+ "owner" => "+15550000000",
+ "from" => "+15550000000",
+ "to" => ["+15551234567"],
+ "time" => "2025-01-13T10:10:00Z",
+ "tag" => "stanza-id-abc extra-data"
+ }
+ }
+
+ invoke_webhook(payload)
+
+ entries = REDIS.stream_entries("messages").sync
+ assert_equal 1, entries.length
+
+ event = entries.first[:fields]
+ assert_equal "delivered", event["event"]
+ assert_equal "stanza-id-abc", event["stanza_id"]
+ assert_equal "bw-out-789", event["bandwidth_id"]
+ assert_equal "2025-01-13T10:10:00Z", event["timestamp"]
+ end
+ em :test_message_delivered_emits_to_stream
+
+ def test_message_failed_emits_to_stream
+ payload = {
+ "type" => "message-failed",
+ "to" => "+15551234567",
+ "message" => {
+ "id" => "bw-out-999",
+ "direction" => "out",
+ "owner" => "+15550000000",
+ "from" => "+15550000000",
+ "to" => ["+15551234567"],
+ "time" => "2025-01-13T10:15:00Z",
+ "tag" => "failed-stanza-xyz extra",
+ "errorCode" => 4720,
+ "description" => "Carrier rejected message"
+ }
+ }
+
+ invoke_webhook(payload)
+
+ entries = REDIS.stream_entries("messages").sync
+ assert_equal 1, entries.length
+
+ event = entries.first[:fields]
+ assert_equal "failed", event["event"]
+ assert_equal "failed-stanza-xyz", event["stanza_id"]
+ assert_equal "bw-out-999", event["bandwidth_id"]
+ assert_equal "4720", event["error_code"]
+ assert_equal "Carrier rejected message", event["error_description"]
+ assert_equal "2025-01-13T10:15:00Z", event["timestamp"]
+ end
+ em :test_message_failed_emits_to_stream
+
+ def test_resend_emits_resend_event_instead_of_in
+ payload = {
+ "type" => "message-received",
+ "message" => {
+ "id" => "bw-in-resend-001",
+ "direction" => "in",
+ "owner" => "+15550000000",
+ "from" => "+15551234567",
+ "to" => ["+15550000000"],
+ "time" => "2025-01-13T10:00:00Z",
+ "text" => "Resent message"
+ }
+ }
+
+ invoke_webhook(
+ payload,
+ extra_env: { "HTTP_X_JMP_RESEND_OF" => "1736762400000-0" }
+ )
+
+ entries = REDIS.stream_entries("messages").sync
+ assert_equal 1, entries.length
+
+ event = entries.first[:fields]
+ assert_equal "resend", event["event"]
+ assert_equal "bwmsgsv2", event["source"]
+ assert_equal "+15550000000", event["owner"]
+ assert_equal "1736762400000-0", event["original_stream_id"]
+ assert_equal "bw-in-resend-001", event["original_bandwidth_id"]
+ refute event.key?("from"), "Resend events should not duplicate message fields"
+ refute event.key?("body"), "Resend events should not duplicate message fields"
+ end
+ em :test_resend_emits_resend_event_instead_of_in
+end