test_registration.rb

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