test_component.rb

  1# frozen_string_literal: true
  2
  3require "test_helper"
  4require_relative "../sgx-bwmsgsv2"
  5
  6def panic(e)
  7	$panic = e
  8end
  9
 10class ComponentTest < Minitest::Test
 11	def setup
 12		SGXbwmsgsv2.instance_variable_set(:@written, [])
 13
 14		def SGXbwmsgsv2.write_to_stream(s)
 15			@written ||= []
 16			@written << s
 17		end
 18
 19		REDIS.reset!
 20		REDIS.set("catapult_cred-test@example.com", [
 21			'account', 'user', 'password', '+15550000000'
 22		])
 23	end
 24
 25	def written
 26		SGXbwmsgsv2.instance_variable_get(:@written)
 27	end
 28
 29	def xmpp_error_name(error)
 30		error.find_first(
 31			"child::*[name()!='text']",
 32			Blather::StanzaError::STANZA_ERR_NS
 33		).element_name
 34	end
 35
 36	def xmpp_error_text(error)
 37		error.find_first("ns:text", ns: Blather::StanzaError::STANZA_ERR_NS)&.text
 38	end
 39
 40	def process_stanza(s)
 41		SGXbwmsgsv2.send(:client).receive_data(s)
 42		raise $panic if $panic
 43	end
 44
 45	def test_message_unregistered
 46		m = Blather::Stanza::Message.new("+15551234567@component", "a"*4096)
 47		m.from = "unknown@example.com"
 48		process_stanza(m)
 49
 50		assert_equal 1, written.length
 51
 52		stanza = Blather::XMPPNode.parse(written.first.to_xml)
 53		assert stanza.error?
 54		error = stanza.find_first("error")
 55		assert_equal "auth", error["type"]
 56		assert_equal "registration-required", xmpp_error_name(error)
 57	end
 58	em :test_message_unregistered
 59
 60	def test_message_too_long
 61		req = stub_request(
 62			:post,
 63			"https://messaging.bandwidth.com/api/v2/users/account/messages"
 64		).with(body: {
 65			from: "+15550000000",
 66			to: "+15551234567",
 67			text: "a"*4096,
 68			applicationId: nil,
 69			tag: " "
 70		}).to_return(status: 400, body: JSON.dump(
 71			description: "Bad text.",
 72			fieldErrors: [{ description: "4096 not allowed" }]
 73		))
 74
 75		m = Blather::Stanza::Message.new("+15551234567@component", "a"*4096)
 76		m.from = "test@example.com"
 77		process_stanza(m)
 78
 79		assert_requested req
 80		assert_equal 1, written.length
 81
 82		stanza = Blather::XMPPNode.parse(written.first.to_xml)
 83		assert stanza.error?
 84		error = stanza.find_first("error")
 85		assert_equal "cancel", error["type"]
 86		assert_equal "internal-server-error", xmpp_error_name(error)
 87		assert_equal "Bad text. 4096 not allowed", xmpp_error_text(error)
 88	end
 89	em :test_message_too_long
 90
 91	def test_message_to_component_not_group
 92		m = Blather::Stanza::Message.new("component", "a"*4096)
 93		m.from = "test@example.com"
 94		process_stanza(m)
 95
 96		assert_equal 1, written.length
 97
 98		stanza = Blather::XMPPNode.parse(written.first.to_xml)
 99		assert stanza.error?
100		error = stanza.find_first("error")
101		assert_equal "cancel", error["type"]
102		assert_equal "item-not-found", xmpp_error_name(error)
103	end
104	em :test_message_to_component_not_group
105
106	def test_message_to_invalid_num
107		m = Blather::Stanza::Message.new("123@component", "a"*4096)
108		m.from = "test@example.com"
109		process_stanza(m)
110
111		assert_equal 1, written.length
112
113		stanza = Blather::XMPPNode.parse(written.first.to_xml)
114		assert stanza.error?
115		error = stanza.find_first("error")
116		assert_equal "cancel", error["type"]
117		assert_equal "item-not-found", xmpp_error_name(error)
118	end
119	em :test_message_to_invalid_num
120
121	def test_message_to_anonymous
122		m = Blather::Stanza::Message.new(
123			"1;phone-context=anonymous.phone-context.soprani.ca@component",
124			"a"*4096
125		)
126		m.from = "test@example.com"
127		process_stanza(m)
128
129		assert_equal 1, written.length
130
131		stanza = Blather::XMPPNode.parse(written.first.to_xml)
132		assert stanza.error?
133		error = stanza.find_first("error")
134		assert_equal "cancel", error["type"]
135		assert_equal "gone", xmpp_error_name(error)
136	end
137	em :test_message_to_anonymous
138
139	def test_blank_message
140		m = Blather::Stanza::Message.new("+15551234567@component", " ")
141		m.from = "test@example.com"
142		process_stanza(m)
143
144		assert_equal 1, written.length
145
146		stanza = Blather::XMPPNode.parse(written.first.to_xml)
147		assert stanza.error?
148		error = stanza.find_first("error")
149		assert_equal "modify", error["type"]
150		assert_equal "policy-violation", xmpp_error_name(error)
151	end
152	em :test_blank_message
153
154	def test_ibr_bad_tel
155		iq = Blather::Stanza::Iq::IBR.new(:set, "component")
156		iq.from = "newuser@example.com"
157		iq.phone = "5551234567"
158		process_stanza(iq)
159
160		assert_equal 1, written.length
161
162		stanza = Blather::XMPPNode.parse(written.first.to_xml)
163		assert stanza.error?
164		error = stanza.find_first("error")
165		assert_equal "cancel", error["type"]
166		assert_equal "item-not-found", xmpp_error_name(error)
167	end
168	em :test_ibr_bad_tel
169
170	def test_ibr_bad_creds
171		stub_request(
172			:get,
173			"https://messaging.bandwidth.com/api/v2/users/acct/media"
174		).with(basic_auth: ["user", "pw"]).to_return(status: 401)
175
176		iq = Blather::Stanza::Iq::IBR.new(:set, "component")
177		iq.from = "newuser@example.com"
178		iq.phone = "+15551234567"
179		iq.nick = "acct"
180		iq.username = "user"
181		iq.password = "pw"
182		process_stanza(iq)
183
184		assert_equal 1, written.length
185
186		stanza = Blather::XMPPNode.parse(written.first.to_xml)
187		assert stanza.error?
188		error = stanza.find_first("error")
189		assert_equal "auth", error["type"]
190		assert_equal "not-authorized", xmpp_error_name(error)
191	end
192	em :test_ibr_bad_creds
193
194	def test_ibr_number_not_found
195		stub_request(
196			:get,
197			"https://messaging.bandwidth.com/api/v2/users/acct/media"
198		).with(basic_auth: ["user", "pw"]).to_return(status: 404)
199
200		iq = Blather::Stanza::Iq::IBR.new(:set, "component")
201		iq.from = "newuser@example.com"
202		iq.phone = "+15551234567"
203		iq.nick = "acct"
204		iq.username = "user"
205		iq.password = "pw"
206		process_stanza(iq)
207
208		assert_equal 1, written.length
209
210		stanza = Blather::XMPPNode.parse(written.first.to_xml)
211		assert stanza.error?
212		error = stanza.find_first("error")
213		assert_equal "cancel", error["type"]
214		assert_equal "item-not-found", xmpp_error_name(error)
215	end
216	em :test_ibr_number_not_found
217
218	def test_ibr_other_error
219		stub_request(
220			:get,
221			"https://messaging.bandwidth.com/api/v2/users/acct/media"
222		).with(basic_auth: ["user", "pw"]).to_return(status: 400)
223
224		iq = Blather::Stanza::Iq::IBR.new(:set, "component")
225		iq.from = "newuser@example.com"
226		iq.phone = "+15551234567"
227		iq.nick = "acct"
228		iq.username = "user"
229		iq.password = "pw"
230		process_stanza(iq)
231
232		assert_equal 1, written.length
233
234		stanza = Blather::XMPPNode.parse(written.first.to_xml)
235		assert stanza.error?
236		error = stanza.find_first("error")
237		assert_equal "modify", error["type"]
238		assert_equal "not-acceptable", xmpp_error_name(error)
239	end
240	em :test_ibr_other_error
241
242	def test_ibr_conflict
243		stub_request(
244			:get,
245			"https://messaging.bandwidth.com/api/v2/users/acct/media"
246		).with(basic_auth: ["user", "pw"]).to_return(status: 200, body: "[]")
247
248		iq = Blather::Stanza::Iq::IBR.new(:set, "component")
249		iq.from = "test@example.com"
250		iq.phone = "+15550000000"
251		iq.nick = "acct"
252		iq.username = "user"
253		iq.password = "pw"
254		process_stanza(iq)
255
256		assert_equal 1, written.length
257
258		stanza = Blather::XMPPNode.parse(written.first.to_xml)
259		assert stanza.error?
260		error = stanza.find_first("error")
261		assert_equal "cancel", error["type"]
262		assert_equal "conflict", xmpp_error_name(error)
263		assert_equal(
264			"Another user exists for +15550000000",
265			xmpp_error_text(error)
266		)
267	end
268	em :test_ibr_conflict
269
270	def test_ibr_remove
271		iq = Blather::Stanza::Iq::IBR.new(:set, "component")
272		iq.from = "test@example.com"
273		iq.remove!
274		process_stanza(iq)
275
276		refute REDIS.get("catapult_cred-test@example.com").sync
277
278		assert_equal 1, written.length
279
280		stanza = Blather::XMPPNode.parse(written.first.to_xml)
281		assert stanza.result?
282	end
283	em :test_ibr_remove
284
285	def test_ibr_form
286		stub_request(
287			:get,
288			"https://messaging.bandwidth.com/api/v2/users/acct/media"
289		).with(basic_auth: ["user", "pw"]).to_return(status: 200, body: "[]")
290
291		iq = Blather::Stanza::Iq::IBR.new(:set, "component")
292		iq.from = "formuser@example.com"
293		form = Blather::Stanza::X.find_or_create(iq.query)
294		form.fields = [
295			{
296				var: "nick",
297				value: "acct"
298			},
299			{
300				var: "username",
301				value: "user"
302			},
303			{
304				var: "password",
305				value: "pw"
306			},
307			{
308				var: "phone",
309				value: "+15551234567"
310			}
311		]
312		process_stanza(iq)
313
314		assert_equal(
315			["acct", "user", "pw", "+15551234567"],
316			REDIS.get("catapult_cred-formuser@example.com").sync
317		)
318
319		assert_equal(
320			"formuser@example.com",
321			REDIS.get("catapult_jid-+15551234567").sync
322		)
323
324		assert_equal 1, written.length
325		stanza = Blather::XMPPNode.parse(written.first.to_xml)
326		assert stanza.result?
327	end
328	em :test_ibr_form
329
330	def test_ibr_get_form_registered
331		iq = Blather::Stanza::Iq::IBR.new(:get, "component")
332		iq.from = "test@example.com"
333		process_stanza(iq)
334
335		assert_equal 1, written.length
336		stanza = Blather::XMPPNode.parse(written.first.to_xml)
337		assert stanza.result?
338		assert stanza.registered?
339		assert_equal(
340			["nick", "username", "password", "phone"],
341			stanza.form.fields.map(&:var)
342		)
343		assert stanza.instructions
344		assert stanza.nick
345		assert stanza.username
346		assert stanza.password
347		assert stanza.phone
348		refute stanza.email
349	end
350	em :test_ibr_get_form_registered
351end