1# frozen_string_literal: true
2
3require "jennifer"
4require_relative "../rantly_extensions/data_extensions"
5
6class MessageStanza
7 # @param redis [FakeRedis]
8 def initialize(redis)
9 @redis = redis
10 end
11
12 include Jennifer.rant(self) { |component|
13 recv_nums(transient: true) {
14 array(range(1, 5)) {
15 choose(
16 value { nanpa_phone },
17 value { non_nanp_phone },
18 value { shortcode }
19 )
20 }
21 }
22 to derived_from(:recv_nums), transient: true do |recv_nums|
23 recv_nums.map { |num| "#{num}@#{component}" }
24 end
25 phone(transient: true) { nanpa_phone }
26 from(transient: true) { bare_jid }
27 media(transient: true) {
28 array(range(0, 5)) {
29 [media_url, range(0, MAX_MEDIA_SIZE << 1)]
30 }
31 }
32 registered?(transient: true) { true }
33 body(transient: true) { choose(nil, "", value { message_body }) }
34 id(transient: true) { SecureRandom.uuid }
35 subject { _utf8_body(range(1, 10)) }
36 stanza derived_from(:body, :to, :from, :subject, :media, :id, :recv_nums) { |body, to_jids, from, subject, media, id, recv_nums|
37 stanza_body = body
38 if media.any? && boolean
39 url = media.first.first
40 stanza_body = stanza_body.to_s.empty? ? url : "#{stanza_body}\n#{url}"
41 end
42
43 if recv_nums.length == 1
44 m = Blather::Stanza::Message.new(to_jids.first, stanza_body)
45 else
46 m = Blather::Stanza::Message.new(component, stanza_body)
47 addrs = Nokogiri::XML::Node.new('addresses', m.document)
48 addrs['xmlns'] = 'http://jabber.org/protocol/address'
49 recv_nums.each do |num|
50 addr = Nokogiri::XML::Node.new('address', m.document)
51 addr['type'] = 'to'
52 addr['uri'] = "sms:#{num}"
53 addrs.add_child(addr)
54 end
55 m.add_child(addrs)
56 end
57
58 m.from = from
59 m.id = id
60 m.subject = subject if subject
61
62 media.each do |url, _size|
63 x = Nokogiri::XML::Node.new('x', m.document)
64 ns = x.add_namespace(nil, 'jabber:x:oob')
65 url_node = Nokogiri::XML::Node.new('url', m.document)
66 url_node.namespace = ns
67 url_node.content = url
68 x.add_child(url_node)
69 m.add_child(x)
70 end
71
72 m
73 }
74 redis_state derived_from(:from, :phone, :registered?), transient: true do |from, phone, registered|
75 @redis.reset!
76 @redis.set("catapult_jid-", "HERE")
77 next unless registered
78
79 @redis.set("catapult_jid-#{phone}", from)
80 @redis.rpush("catapult_cred-#{from}", 'account', 'token', 'secret', phone)
81 end
82 http_stubs derived_from(:media, :registered?), transient: true do |media, registered|
83 WebMock.reset!
84 next [] unless registered
85
86 media.map do |url, size|
87 ext = File.extname(URI.parse(url).path)
88 content_type = freq(
89 [95, proc { Rack::Mime.mime_type(ext) }],
90 [5, proc { Rack::Mime.mime_type(".#{string(:alpha)}") }]
91 )
92 WebMock::API.stub_request(:head, url).to_return(
93 status: 200,
94 headers: {
95 "Content-Length" => size.to_s,
96 "Content-Type" => content_type
97 }
98 )
99 end
100 end
101 bandwidth_stub derived_from(:registered?, :media), transient: true do |registered, _media|
102 next unless registered
103
104 WebMock::API.stub_request(:post, BW_MESSAGES_URL).to_return(
105 status: 202,
106 body: JSON.dump(id: "bw-msg-#{SecureRandom.hex(4)}")
107 )
108 end
109 assertions derived_from(:http_stubs, :bandwidth_stub) { |stubs, bw|
110 a = stubs.map { |stub| -> { assert_requested(stub) } }
111 a << -> { assert_requested(bw) } if bw
112 a
113 }
114 written_state(transient: true) {
115 SGXbwmsgsv2.instance_variable_set(:@written, [])
116 }
117 }
118end