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			result = Minitest::Mock.new
 74			result.expect(:then, result)
 75			result.expect(:then, EMPromise.resolve(:test_result))
 76			Registration::Activation::COMMAND_MANAGER.expect(
 77				:write,
 78				result,
 79				[Blather::Stanza::Iq::Command]
 80			)
 81			assert_equal :test_result, @activation.write.sync
 82		end
 83		em :test_write
 84	end
 85
 86	class PaymentTest < Minitest::Test
 87		Customer::BRAINTREE = Minitest::Mock.new
 88		Registration::Payment::Bitcoin::ELECTRUM = Minitest::Mock.new
 89
 90		def test_for_bitcoin
 91			Registration::Payment::Bitcoin::ELECTRUM.expect(:createnewaddress, "addr")
 92			iq = Blather::Stanza::Iq::Command.new
 93			iq.form.fields = [
 94				{ var: "activation_method", value: "bitcoin" },
 95				{ var: "plan_name", value: "test_usd" }
 96			]
 97			result = Registration::Payment.for(
 98				iq,
 99				Customer.new("test"),
100				"+15555550000"
101			)
102			assert_kind_of Registration::Payment::Bitcoin, result
103		end
104
105		def test_for_credit_card
106			braintree_customer = Minitest::Mock.new
107			Customer::BRAINTREE.expect(
108				:customer,
109				braintree_customer
110			)
111			braintree_customer.expect(
112				:find,
113				EMPromise.resolve(OpenStruct.new(payment_methods: [])),
114				["test"]
115			)
116			iq = Blather::Stanza::Iq::Command.new
117			iq.from = "test@example.com"
118			iq.form.fields = [
119				{ var: "activation_method", value: "credit_card" },
120				{ var: "plan_name", value: "test_usd" }
121			]
122			result = Registration::Payment.for(
123				iq,
124				Customer.new("test"),
125				"+15555550000"
126			).sync
127			assert_kind_of Registration::Payment::CreditCard, result
128		end
129		em :test_for_credit_card
130
131		def test_for_code
132			skip "Code not implemented yet"
133			iq = Blather::Stanza::Iq::Command.new
134			iq.form.fields = [
135				{ var: "activation_method", value: "code" },
136				{ var: "plan_name", value: "test_usd" }
137			]
138			result = Registration::Payment.for(iq, "test", "+15555550000")
139			assert_kind_of Registration::Payment::Code, result
140		end
141
142		class BitcoinTest < Minitest::Test
143			Registration::Payment::Bitcoin::ELECTRUM = Minitest::Mock.new
144			Registration::Payment::Bitcoin::REDIS = Minitest::Mock.new
145			Registration::Payment::Bitcoin::BTC_SELL_PRICES = Minitest::Mock.new
146			Registration::Payment::Bitcoin::BLATHER = Minitest::Mock.new
147
148			def setup
149				Registration::Payment::Bitcoin::ELECTRUM.expect(
150					:createnewaddress,
151					EMPromise.resolve("testaddr")
152				)
153				iq = Blather::Stanza::Iq::Command.new
154				@bitcoin = Registration::Payment::Bitcoin.new(
155					iq,
156					Customer.new("test", plan_name: "test_usd"),
157					"+15555550000"
158				)
159			end
160
161			def test_write
162				reply_text = <<~NOTE
163					Activate your account by sending at least 1.000000 BTC to
164					testaddr
165
166					You will receive a notification when your payment is complete.
167				NOTE
168				Registration::Payment::Bitcoin::BLATHER.expect(
169					:<<,
170					nil,
171					[Matching.new do |reply|
172						assert_equal :completed, reply.status
173						assert_equal :info, reply.note_type
174						assert_equal reply_text, reply.note.content
175						true
176					end]
177				)
178				Registration::Payment::Bitcoin::BTC_SELL_PRICES.expect(
179					:usd,
180					EMPromise.resolve(BigDecimal.new(1))
181				)
182				@bitcoin.stub(:save, EMPromise.resolve(nil)) do
183					@bitcoin.write.sync
184				end
185				Registration::Payment::Bitcoin::BLATHER.verify
186			end
187			em :test_write
188		end
189
190		class CreditCardTest < Minitest::Test
191			def setup
192				@iq = Blather::Stanza::Iq::Command.new
193				@iq.from = "test@example.com"
194				@credit_card = Registration::Payment::CreditCard.new(
195					@iq,
196					Customer.new("test"),
197					"+15555550000"
198				)
199			end
200
201			def test_for
202				customer = Minitest::Mock.new(Customer.new("test"))
203				customer.expect(
204					:payment_methods,
205					EMPromise.resolve(OpenStruct.new(default_payment_method: :test))
206				)
207				assert_kind_of(
208					Registration::Payment::CreditCard::Activate,
209					Registration::Payment::CreditCard.for(
210						@iq,
211						customer,
212						"+15555550000"
213					).sync
214				)
215			end
216			em :test_for
217
218			def test_reply
219				assert_equal [:execute, :next], @credit_card.reply.allowed_actions
220				assert_equal(
221					"Add credit card, then return here and choose next: " \
222					"http://creditcard.example.com",
223					@credit_card.reply.note.content
224				)
225			end
226		end
227
228		class ActivateTest < Minitest::Test
229			Registration::Payment::CreditCard::Activate::Finish =
230				Minitest::Mock.new
231			Registration::Payment::CreditCard::Activate::Transaction =
232				Minitest::Mock.new
233			Registration::Payment::CreditCard::Activate::COMMAND_MANAGER =
234				Minitest::Mock.new
235
236			def test_write
237				transaction = PromiseMock.new
238				transaction.expect(
239					:insert,
240					EMPromise.resolve(nil)
241				)
242				customer = Minitest::Mock.new(
243					Customer.new("test", plan_name: "test_usd")
244				)
245				Registration::Payment::CreditCard::Activate::Transaction.expect(
246					:sale,
247					transaction,
248					[
249						customer,
250						CONFIG[:activation_amount],
251						:test_default_method
252					]
253				)
254				iq = Blather::Stanza::Iq::Command.new
255				customer.expect(:bill_plan, nil)
256				Registration::Payment::CreditCard::Activate::Finish.expect(
257					:new,
258					OpenStruct.new(write: nil),
259					[Blather::Stanza::Iq, customer, "+15555550000"]
260				)
261				Registration::Payment::CreditCard::Activate.new(
262					iq,
263					customer,
264					:test_default_method,
265					"+15555550000"
266				).write.sync
267				Registration::Payment::CreditCard::Activate::Transaction.verify
268				transaction.verify
269				customer.verify
270				Registration::Payment::CreditCard::Activate::Finish.verify
271			end
272			em :test_write
273
274			def test_write_declines
275				customer = Minitest::Mock.new(
276					Customer.new("test", plan_name: "test_usd")
277				)
278				Registration::Payment::CreditCard::Activate::Transaction.expect(
279					:sale,
280					EMPromise.reject("declined"),
281					[
282						customer,
283						CONFIG[:activation_amount],
284						:test_default_method
285					]
286				)
287				iq = Blather::Stanza::Iq::Command.new
288				iq.from = "test@example.com"
289				result = Minitest::Mock.new
290				result.expect(:then, nil)
291				Registration::Payment::CreditCard::Activate::COMMAND_MANAGER.expect(
292					:write,
293					result,
294					[Matching.new do |reply|
295						assert_equal :error, reply.note_type
296						assert_equal(
297							Registration::Payment::CreditCard::Activate::DECLINE_MESSAGE +
298							": http://creditcard.example.com",
299							reply.note.content
300						)
301					end]
302				)
303				Registration::Payment::CreditCard::Activate.new(
304					iq,
305					customer,
306					:test_default_method,
307					"+15555550000"
308				).write.sync
309				Registration::Payment::CreditCard::Activate::Transaction.verify
310			end
311			em :test_write_declines
312		end
313	end
314
315	class FinishTest < Minitest::Test
316		Registration::Finish::BLATHER = Minitest::Mock.new
317
318		def setup
319			@finish = Registration::Finish.new(
320				Blather::Stanza::Iq::Command.new,
321				Customer.new("test"),
322				"+15555550000"
323			)
324		end
325
326		def test_write
327			create_order = stub_request(
328				:post,
329				"https://dashboard.bandwidth.com/v1.0/accounts//orders"
330			).to_return(status: 201, body: <<~RESPONSE)
331				<OrderResponse>
332					<Order>
333						<id>test_order</id>
334					</Order>
335				</OrderResponse>
336			RESPONSE
337			stub_request(
338				:get,
339				"https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
340			).to_return(status: 201, body: <<~RESPONSE)
341				<OrderResponse>
342					<OrderStatus>COMPLETE</OrderStatus>
343				</OrderResponse>
344			RESPONSE
345			BACKEND_SGX.expect(
346				:register!,
347				EMPromise.resolve(OpenStruct.new(error?: false)),
348				["test", "+15555550000"]
349			)
350			Registration::Finish::BLATHER.expect(
351				:<<,
352				nil,
353				[Matching.new do |reply|
354					assert_equal :completed, reply.status
355					assert_equal :info, reply.note_type
356					assert_equal(
357						"Your JMP account has been activated as +15555550000",
358						reply.note.content
359					)
360				end]
361			)
362			@finish.write.sync
363			assert_requested create_order
364			BACKEND_SGX.verify
365			Registration::Finish::BLATHER.verify
366		end
367		em :test_write
368
369		def test_write_tn_fail
370			create_order = stub_request(
371				:post,
372				"https://dashboard.bandwidth.com/v1.0/accounts//orders"
373			).to_return(status: 201, body: <<~RESPONSE)
374				<OrderResponse>
375					<Order>
376						<id>test_order</id>
377					</Order>
378				</OrderResponse>
379			RESPONSE
380			stub_request(
381				:get,
382				"https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
383			).to_return(status: 201, body: <<~RESPONSE)
384				<OrderResponse>
385					<OrderStatus>FAILED</OrderStatus>
386				</OrderResponse>
387			RESPONSE
388			Registration::Finish::BLATHER.expect(
389				:<<,
390				nil,
391				[Matching.new do |reply|
392					assert_equal :completed, reply.status
393					assert_equal :error, reply.note_type
394					assert_equal(
395						"The JMP number +15555550000 is no longer available, " \
396						"please visit https://jmp.chat and choose another.",
397						reply.note.content
398					)
399				end]
400			)
401			@finish.write.sync
402			assert_requested create_order
403			Registration::Finish::BLATHER.verify
404		end
405		em :test_write_tn_fail
406	end
407end