test_registration.rb

  1# frozen_string_literal: true
  2
  3require "test_helper"
  4require "registration"
  5
  6class RegistrationTest < Minitest::Test
  7	def test_for_registered
  8		BACKEND_SGX.expect(
  9			:registered?,
 10			EMPromise.resolve(OpenStruct.new(phone: "+15555550000")),
 11			["test"]
 12		)
 13		iq = Blather::Stanza::Iq::Command.new
 14		iq.from = "test@example.com"
 15		result = Registration.for(iq, Customer.new("test"), Minitest::Mock.new).sync
 16		assert_kind_of Registration::Registered, result
 17	end
 18	em :test_for_registered
 19
 20	def test_for_activated
 21		BACKEND_SGX.expect(
 22			:registered?,
 23			EMPromise.resolve(nil),
 24			["test"]
 25		)
 26		web_manager = WebRegisterManager.new
 27		web_manager["test@example.com"] = "+15555550000"
 28		iq = Blather::Stanza::Iq::Command.new
 29		iq.from = "test@example.com"
 30		result = Registration.for(
 31			iq,
 32			Customer.new("test", plan_name: "test_usd", expires_at: Time.now + 999),
 33			web_manager
 34		).sync
 35		assert_kind_of Registration::Finish, result
 36	end
 37	em :test_for_activated
 38
 39	def test_for_not_activated_with_customer_id
 40		BACKEND_SGX.expect(
 41			:registered?,
 42			EMPromise.resolve(nil),
 43			["test"]
 44		)
 45		web_manager = WebRegisterManager.new
 46		web_manager["test@example.com"] = "+15555550000"
 47		iq = Blather::Stanza::Iq::Command.new
 48		iq.from = "test@example.com"
 49		result = Registration.for(
 50			iq,
 51			Customer.new("test"),
 52			web_manager
 53		).sync
 54		assert_kind_of Registration::Activation, result
 55	end
 56	em :test_for_not_activated_with_customer_id
 57
 58	def test_for_not_activated_without_customer_id
 59		skip "customer_id creation not implemented yet"
 60		iq = Blather::Stanza::Iq::Command.new
 61		Registration.for(iq, nil, Minitest::Mock.new).sync
 62	end
 63	em :test_for_not_activated_without_customer_id
 64
 65	class ActivationTest < Minitest::Test
 66		Registration::Activation::COMMAND_MANAGER = Minitest::Mock.new
 67		def setup
 68			iq = Blather::Stanza::Iq::Command.new
 69			@activation = Registration::Activation.new(iq, "test", "+15555550000")
 70		end
 71
 72		def test_write
 73			stub_request(
 74				:get,
 75				"https://dashboard.bandwidth.com/v1.0/tns/+15555550000"
 76			).to_return(status: 201, body: <<~RESPONSE)
 77				<TelephoneNumberResponse>
 78					<TelephoneNumber>5555550000</TelephoneNumber>
 79				</TelephoneNumberResponse>
 80			RESPONSE
 81			stub_request(
 82				:get,
 83				"https://dashboard.bandwidth.com/v1.0/tns/5555550000/ratecenter"
 84			).to_return(status: 201, body: <<~RESPONSE)
 85				<TelephoneNumberResponse>
 86					<TelephoneNumberDetails>
 87						<State>KE</State>
 88						<RateCenter>FA</RateCenter>
 89					</TelephoneNumberDetails>
 90				</TelephoneNumberResponse>
 91			RESPONSE
 92			result = Minitest::Mock.new
 93			result.expect(:then, result)
 94			result.expect(:then, EMPromise.resolve(:test_result))
 95			Registration::Activation::COMMAND_MANAGER.expect(
 96				:write,
 97				result,
 98				[Matching.new do |iq|
 99					assert_equal :form, iq.form.type
100					assert_equal(
101						"Going to activate +15555550000 (FA, KE)",
102						iq.form.instructions
103					)
104				end]
105			)
106			assert_equal :test_result, @activation.write.sync
107		end
108		em :test_write
109	end
110
111	class PaymentTest < Minitest::Test
112		Customer::BRAINTREE = Minitest::Mock.new
113		Registration::Payment::Bitcoin::ELECTRUM = Minitest::Mock.new
114
115		def test_for_bitcoin
116			Registration::Payment::Bitcoin::ELECTRUM.expect(:createnewaddress, "addr")
117			iq = Blather::Stanza::Iq::Command.new
118			iq.form.fields = [
119				{ var: "activation_method", value: "bitcoin" },
120				{ var: "plan_name", value: "test_usd" }
121			]
122			result = Registration::Payment.for(
123				iq,
124				Customer.new("test"),
125				"+15555550000"
126			)
127			assert_kind_of Registration::Payment::Bitcoin, result
128		end
129
130		def test_for_credit_card
131			braintree_customer = Minitest::Mock.new
132			Customer::BRAINTREE.expect(
133				:customer,
134				braintree_customer
135			)
136			braintree_customer.expect(
137				:find,
138				EMPromise.resolve(OpenStruct.new(payment_methods: [])),
139				["test"]
140			)
141			iq = Blather::Stanza::Iq::Command.new
142			iq.from = "test@example.com"
143			iq.form.fields = [
144				{ var: "activation_method", value: "credit_card" },
145				{ var: "plan_name", value: "test_usd" }
146			]
147			result = Registration::Payment.for(
148				iq,
149				Customer.new("test"),
150				"+15555550000"
151			).sync
152			assert_kind_of Registration::Payment::CreditCard, result
153		end
154		em :test_for_credit_card
155
156		def test_for_code
157			skip "Code not implemented yet"
158			iq = Blather::Stanza::Iq::Command.new
159			iq.form.fields = [
160				{ var: "activation_method", value: "code" },
161				{ var: "plan_name", value: "test_usd" }
162			]
163			result = Registration::Payment.for(iq, "test", "+15555550000")
164			assert_kind_of Registration::Payment::Code, result
165		end
166
167		class BitcoinTest < Minitest::Test
168			Registration::Payment::Bitcoin::ELECTRUM = Minitest::Mock.new
169			Registration::Payment::Bitcoin::REDIS = Minitest::Mock.new
170			Registration::Payment::Bitcoin::BTC_SELL_PRICES = Minitest::Mock.new
171			Registration::Payment::Bitcoin::BLATHER = Minitest::Mock.new
172
173			def setup
174				Registration::Payment::Bitcoin::ELECTRUM.expect(
175					:createnewaddress,
176					EMPromise.resolve("testaddr")
177				)
178				iq = Blather::Stanza::Iq::Command.new
179				@bitcoin = Registration::Payment::Bitcoin.new(
180					iq,
181					Customer.new("test", plan_name: "test_usd"),
182					"+15555550000"
183				)
184			end
185
186			def test_write
187				reply_text = <<~NOTE
188					Activate your account by sending at least 1.000000 BTC to
189					testaddr
190
191					You will receive a notification when your payment is complete.
192				NOTE
193				Registration::Payment::Bitcoin::BLATHER.expect(
194					:<<,
195					nil,
196					[Matching.new do |reply|
197						assert_equal :completed, reply.status
198						assert_equal :info, reply.note_type
199						assert_equal reply_text, reply.note.content
200						true
201					end]
202				)
203				Registration::Payment::Bitcoin::BTC_SELL_PRICES.expect(
204					:usd,
205					EMPromise.resolve(BigDecimal.new(1))
206				)
207				@bitcoin.stub(:save, EMPromise.resolve(nil)) do
208					@bitcoin.write.sync
209				end
210				Registration::Payment::Bitcoin::BLATHER.verify
211			end
212			em :test_write
213		end
214
215		class CreditCardTest < Minitest::Test
216			def setup
217				@iq = Blather::Stanza::Iq::Command.new
218				@iq.from = "test@example.com"
219				@credit_card = Registration::Payment::CreditCard.new(
220					@iq,
221					Customer.new("test"),
222					"+15555550000"
223				)
224			end
225
226			def test_for
227				customer = Minitest::Mock.new(Customer.new("test"))
228				customer.expect(
229					:payment_methods,
230					EMPromise.resolve(OpenStruct.new(default_payment_method: :test))
231				)
232				assert_kind_of(
233					Registration::Payment::CreditCard::Activate,
234					Registration::Payment::CreditCard.for(
235						@iq,
236						customer,
237						"+15555550000"
238					).sync
239				)
240			end
241			em :test_for
242
243			def test_reply
244				assert_equal [:execute, :next], @credit_card.reply.allowed_actions
245				assert_equal(
246					"Add credit card, then return here and choose next: " \
247					"http://creditcard.example.com",
248					@credit_card.reply.note.content
249				)
250			end
251		end
252
253		class ActivateTest < Minitest::Test
254			Registration::Payment::CreditCard::Activate::Finish =
255				Minitest::Mock.new
256			Registration::Payment::CreditCard::Activate::Transaction =
257				Minitest::Mock.new
258			Registration::Payment::CreditCard::Activate::COMMAND_MANAGER =
259				Minitest::Mock.new
260
261			def test_write
262				transaction = PromiseMock.new
263				transaction.expect(
264					:insert,
265					EMPromise.resolve(nil)
266				)
267				customer = Minitest::Mock.new(
268					Customer.new("test", plan_name: "test_usd")
269				)
270				Registration::Payment::CreditCard::Activate::Transaction.expect(
271					:sale,
272					transaction,
273					[
274						customer,
275						CONFIG[:activation_amount],
276						:test_default_method
277					]
278				)
279				iq = Blather::Stanza::Iq::Command.new
280				customer.expect(:bill_plan, nil)
281				Registration::Payment::CreditCard::Activate::Finish.expect(
282					:new,
283					OpenStruct.new(write: nil),
284					[Blather::Stanza::Iq, customer, "+15555550000"]
285				)
286				Registration::Payment::CreditCard::Activate.new(
287					iq,
288					customer,
289					:test_default_method,
290					"+15555550000"
291				).write.sync
292				Registration::Payment::CreditCard::Activate::Transaction.verify
293				transaction.verify
294				customer.verify
295				Registration::Payment::CreditCard::Activate::Finish.verify
296			end
297			em :test_write
298
299			def test_write_declines
300				customer = Minitest::Mock.new(
301					Customer.new("test", plan_name: "test_usd")
302				)
303				Registration::Payment::CreditCard::Activate::Transaction.expect(
304					:sale,
305					EMPromise.reject("declined"),
306					[
307						customer,
308						CONFIG[:activation_amount],
309						:test_default_method
310					]
311				)
312				iq = Blather::Stanza::Iq::Command.new
313				iq.from = "test@example.com"
314				result = Minitest::Mock.new
315				result.expect(:then, nil)
316				Registration::Payment::CreditCard::Activate::COMMAND_MANAGER.expect(
317					:write,
318					result,
319					[Matching.new do |reply|
320						assert_equal :error, reply.note_type
321						assert_equal(
322							Registration::Payment::CreditCard::Activate::DECLINE_MESSAGE +
323							": http://creditcard.example.com",
324							reply.note.content
325						)
326					end]
327				)
328				Registration::Payment::CreditCard::Activate.new(
329					iq,
330					customer,
331					:test_default_method,
332					"+15555550000"
333				).write.sync
334				Registration::Payment::CreditCard::Activate::Transaction.verify
335			end
336			em :test_write_declines
337		end
338	end
339
340	class FinishTest < Minitest::Test
341		Registration::Finish::BLATHER = Minitest::Mock.new
342
343		def setup
344			@finish = Registration::Finish.new(
345				Blather::Stanza::Iq::Command.new,
346				Customer.new("test"),
347				"+15555550000"
348			)
349		end
350
351		def test_write
352			create_order = stub_request(
353				:post,
354				"https://dashboard.bandwidth.com/v1.0/accounts//orders"
355			).to_return(status: 201, body: <<~RESPONSE)
356				<OrderResponse>
357					<Order>
358						<id>test_order</id>
359					</Order>
360				</OrderResponse>
361			RESPONSE
362			stub_request(
363				:get,
364				"https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
365			).to_return(status: 201, body: <<~RESPONSE)
366				<OrderResponse>
367					<OrderStatus>COMPLETE</OrderStatus>
368					<CompletedNumbers>
369						<TelephoneNumber>
370							<FullNumber>5555550000</FullNumber>
371						</TelephoneNumber>
372					</CompletedNumbers>
373				</OrderResponse>
374			RESPONSE
375			stub_request(
376				:post,
377				"https://api.catapult.inetwork.com/v1/users/catapult_user/phoneNumbers"
378			).with(
379				body: open(__dir__ + "/data/catapult_import_body.json").read.chomp,
380				headers: {
381					"Authorization" => "Basic Y2F0YXB1bHRfdG9rZW46Y2F0YXB1bHRfc2VjcmV0",
382					"Content-Type" => "application/json"
383				}
384			).to_return(status: 200)
385			BACKEND_SGX.expect(
386				:register!,
387				EMPromise.resolve(OpenStruct.new(error?: false)),
388				["test", "+15555550000"]
389			)
390			Registration::Finish::BLATHER.expect(
391				:<<,
392				nil,
393				[Matching.new do |reply|
394					assert_equal :completed, reply.status
395					assert_equal :info, reply.note_type
396					assert_equal(
397						"Your JMP account has been activated as +15555550000",
398						reply.note.content
399					)
400				end]
401			)
402			@finish.write.sync
403			assert_requested create_order
404			BACKEND_SGX.verify
405			Registration::Finish::BLATHER.verify
406		end
407		em :test_write
408
409		def test_write_tn_fail
410			create_order = stub_request(
411				:post,
412				"https://dashboard.bandwidth.com/v1.0/accounts//orders"
413			).to_return(status: 201, body: <<~RESPONSE)
414				<OrderResponse>
415					<Order>
416						<id>test_order</id>
417					</Order>
418				</OrderResponse>
419			RESPONSE
420			stub_request(
421				:get,
422				"https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
423			).to_return(status: 201, body: <<~RESPONSE)
424				<OrderResponse>
425					<OrderStatus>FAILED</OrderStatus>
426				</OrderResponse>
427			RESPONSE
428			Registration::Finish::BLATHER.expect(
429				:<<,
430				nil,
431				[Matching.new do |reply|
432					assert_equal :completed, reply.status
433					assert_equal :error, reply.note_type
434					assert_equal(
435						"The JMP number +15555550000 is no longer available, " \
436						"please visit https://jmp.chat and choose another.",
437						reply.note.content
438					)
439				end]
440			)
441			@finish.write.sync
442			assert_requested create_order
443			Registration::Finish::BLATHER.verify
444		end
445		em :test_write_tn_fail
446	end
447end