add XEP-0334 store hint to media messages

Phillip Davis created

Change summary

sgx-bwmsgsv2.rb                                    |  4 +
test/property/rantly_extensions/data_extensions.rb | 15 +++++
test/property/test_webhook_handler.rb              | 36 ++++++++++++++++
3 files changed, 53 insertions(+), 2 deletions(-)

Detailed changes

sgx-bwmsgsv2.rb 🔗

@@ -321,6 +321,10 @@ module SGXbwmsgsv2
 
 		msg.add_child(x)
 
+		store = Nokogiri::XML::Node.new 'store', msg.document
+		store['xmlns'] = 'urn:xmpp:hints'
+		msg.add_child(store)
+
 		write(msg)
 	rescue Exception => e
 		panic(e)

test/property/rantly_extensions/data_extensions.rb 🔗

@@ -109,14 +109,25 @@ class Rantly
 				)
 			end
 
+			# @return [Array<String>]
+			DELIVERABLE_MEDIA_EXTENSIONS = %w[.jpg .png .gif .mp4 .pdf].freeze
+			# @return [Array<String>]
+			CARRIER_MEDIA_EXTENSIONS = %w[.smil .txt .xml].freeze
+
+			# @param extensions [Array<String>]
 			# @return [String]
-			def media_url
+			def media_url(extensions: DELIVERABLE_MEDIA_EXTENSIONS + CARRIER_MEDIA_EXTENSIONS)
 				user_id = sized(range(3, 10)) { string(:alnum) }
 				name = sized(range(3, 12)) { string(:alnum) }
-				ext = choose(".jpg", ".png", ".gif", ".mp4", ".pdf", ".smil", ".txt", ".xml")
+				ext = choose(*extensions)
 				"https://messaging.bandwidth.com/api/v2/users/#{user_id}/media/#{name}#{ext}"
 			end
 
+			# @return [String]
+			def deliverable_media_url
+				media_url(extensions: DELIVERABLE_MEDIA_EXTENSIONS)
+			end
+
 			# @param ascii_only [Boolean, nil] truthy=force ASCII, nil=random
 			# @param nil_pct [Integer] weight (out of 100) for nil result
 			# @param empty_pct [Integer] weight (out of 100) for empty string result

test/property/test_webhook_handler.rb 🔗

@@ -526,4 +526,40 @@ class WebhookPropertyTest < Minitest::Test
 		}
 	end
 	em :test_inbound_nil_text_with_media_multi_recipient_writes_empty_body
+
+	def test_inbound_media_stanzas_include_store_hint
+		property_of {
+			Webhook
+				.new(REDIS)
+				.type { "message-received" }
+				.message { |registered, jid, dir, top_level_to|
+					Message
+						.new(REDIS)
+						.to {
+							array(integer(2)) { nanpa_phone } +
+								[top_level_to] +
+								array(integer(2)) { nanpa_phone }
+						}
+						.media { array(range(1, 3)) { deliverable_media_url } }
+						.generate(registered, jid, dir)
+				}
+				.generate
+		}.check { |metadata, example|
+			result = invoke_webhook(example)
+			assert_equal 200, result[0]
+
+			oob_stanzas = written.select { |s|
+				s.is_a?(Blather::Stanza::Message) &&
+					s.find_first("x")&.[]("xmlns") == "jabber:x:oob"
+			}
+			refute_empty oob_stanzas, "Should write at least one OOB stanza"
+
+			oob_stanzas.each do |msg|
+				store = msg.find_first("store")
+				assert_equal "urn:xmpp:hints", store&.[]("xmlns"),
+					"Every OOB stanza must include <store xmlns='urn:xmpp:hints'/>"
+			end
+		}
+	end
+	em :test_inbound_media_stanzas_include_store_hint
 end