1# frozen_string_literal: true
  2
  3require "test_helper"
  4require "customer"
  5
  6Customer::BLATHER = Minitest::Mock.new
  7Customer::BRAINTREE = Minitest::Mock.new
  8Customer::REDIS = Minitest::Mock.new
  9Customer::DB = Minitest::Mock.new
 10Customer::IQ_MANAGER = Minitest::Mock.new
 11CustomerPlan::DB = Minitest::Mock.new
 12CustomerUsage::REDIS = Minitest::Mock.new
 13CustomerUsage::DB = Minitest::Mock.new
 14CustomerFinancials::REDIS = Minitest::Mock.new
 15CustomerFinancials::ELECTRUM = Minitest::Mock.new
 16CustomerFinancials::BRAINTREE = Minitest::Mock.new
 17
 18class CustomerTest < Minitest::Test
 19	def test_bill_plan_activate
 20		CustomerPlan::DB.expect(:transaction, nil) do |&block|
 21			block.call
 22			true
 23		end
 24		CustomerPlan::DB.expect(
 25			:exec,
 26			nil,
 27			[
 28				String,
 29				Matching.new do |params|
 30					params[0] == "test" &&
 31					params[1].is_a?(String) &&
 32					BigDecimal(-1) == params[2]
 33				end
 34			]
 35		)
 36		CustomerPlan::DB.expect(
 37			:exec,
 38			OpenStruct.new(cmd_tuples: 1),
 39			[String, ["test", "test_usd", nil]]
 40		)
 41		CustomerPlan::DB.expect(
 42			:exec,
 43			OpenStruct.new(cmd_tuples: 0),
 44			[String, ["test"]]
 45		)
 46		customer(plan_name: "test_usd").bill_plan.sync
 47		CustomerPlan::DB.verify
 48	end
 49	em :test_bill_plan_activate
 50
 51	def test_bill_plan_reactivate_child
 52		CustomerPlan::DB.expect(
 53			:query,
 54			[{ "plan_name" => "test_usd" }],
 55			[String, ["parent"]]
 56		)
 57		CustomerPlan::DB.expect(:transaction, nil) do |&block|
 58			block.call
 59			true
 60		end
 61		CustomerPlan::DB.expect(
 62			:exec,
 63			nil,
 64			[
 65				String,
 66				Matching.new do |params|
 67					params[0] == "test" &&
 68					params[1].is_a?(String) &&
 69					BigDecimal(-1) == params[2]
 70				end
 71			]
 72		)
 73		CustomerPlan::DB.expect(
 74			:exec,
 75			OpenStruct.new(cmd_tuples: 1),
 76			[String, ["test", "test_usd", "parent"]]
 77		)
 78		CustomerPlan::DB.expect(
 79			:exec,
 80			OpenStruct.new(cmd_tuples: 0),
 81			[String, ["test"]]
 82		)
 83		customer(plan_name: "test_usd", parent_customer_id: "parent").bill_plan.sync
 84		CustomerPlan::DB.verify
 85	end
 86	em :test_bill_plan_reactivate_child
 87
 88	def test_bill_plan_update
 89		CustomerPlan::DB.expect(:transaction, nil) do |&block|
 90			block.call
 91			true
 92		end
 93		CustomerPlan::DB.expect(
 94			:exec,
 95			nil,
 96			[
 97				String,
 98				Matching.new do |params|
 99					params[0] == "test" &&
100					params[1].is_a?(String) &&
101					BigDecimal(-1) == params[2]
102				end
103			]
104		)
105		CustomerPlan::DB.expect(
106			:exec,
107			OpenStruct.new(cmd_tuples: 0),
108			[String, ["test", "test_usd", nil]]
109		)
110		CustomerPlan::DB.expect(:exec, nil, [String, ["test"]])
111		customer(plan_name: "test_usd").bill_plan.sync
112		CustomerPlan::DB.verify
113	end
114	em :test_bill_plan_update
115
116	def test_stanza_to
117		Customer::BLATHER.expect(
118			:<<,
119			nil,
120			[Matching.new do |stanza|
121				assert_equal "+15555550000@component/a", stanza.from.to_s
122				assert_equal "test@example.net/b", stanza.to.to_s
123			end]
124		)
125		m = Blather::Stanza::Message.new
126		m.from = "+15555550000@sgx/a"
127		m.to = "customer_test@component/b"
128		customer.stanza_to(m)
129		assert_mock Customer::BLATHER
130	end
131	em :test_stanza_to
132
133	def test_stanza_from
134		Customer::BLATHER.expect(
135			:<<,
136			nil,
137			[Matching.new do |stanza|
138				assert_equal "customer_test@component/a", stanza.from.to_s
139				assert_equal "+15555550000@sgx/b", stanza.to.to_s
140			end]
141		)
142		m = Blather::Stanza::Message.new
143		m.from = "test@example.com/a"
144		m.to = "+15555550000@component/b"
145		customer.stanza_from(m)
146		Customer::BLATHER.verify
147	end
148
149	def test_fetch_pep
150		result = Blather::Stanza::PubSub::Items.new(:result)
151		result.items_node <<
152			Blather::Stanza::PubSubItem.new("current", Nokogiri.parse(<<~XML).root)
153				<vcard xmlns="urn:ietf:params:xml:ns:vcard-4.0">
154					<fn><text>A Human</text></fn>
155				</vcard4>
156			XML
157		Customer::IQ_MANAGER.expect(
158			:method,
159			->(*) { EMPromise.resolve(result) },
160			[:write]
161		)
162		assert_equal(
163			"A Human",
164			customer.fetch_pep("urn:xmpp:vcard4", "+15551234567").sync
165				.first.payload_node.find_first(
166					"./ns:fn/ns:text",
167					ns: "urn:ietf:params:xml:ns:vcard-4.0"
168				)&.content
169		)
170	end
171	em :test_fetch_pep
172
173	def test_customer_usage_report
174		report_for = (Date.today..(Date.today - 1))
175		report_for.first.downto(report_for.last).each.with_index do |day, idx|
176			CustomerUsage::REDIS.expect(
177				:zscore,
178				EMPromise.resolve(idx),
179				["jmp_customer_outbound_messages-test", day.strftime("%Y%m%d")]
180			)
181		end
182		CustomerUsage::DB.expect(
183			:query_defer,
184			EMPromise.resolve([{ "day" => report_for.first, "minutes" => 123 }]),
185			[String, ["test", report_for.first, report_for.last]]
186		)
187		assert_equal(
188			UsageReport.new(
189				report_for, {
190					Date.today => 0,
191					(Date.today - 1) => 1
192				},
193				Date.today => 123
194			),
195			customer.usage_report(report_for).sync
196		)
197	end
198	em :test_customer_usage_report
199
200	def test_sip_account_new
201		req = stub_request(
202			:get,
203			"https://dashboard.bandwidth.com/v1.0/accounts//sipcredentials/ctest"
204		).with(
205			headers: {
206				"Authorization" => "Basic Og=="
207			}
208		).to_return(
209			status: 404,
210			body:
211				"<r><ResponseStatus><ErrorCode>0</ErrorCode>" \
212				"<Description>desc</Description></ResponseStatus></r>"
213		)
214		sip = customer.sip_account
215		assert_kind_of SipAccount::New, sip
216		assert_equal "ctest", sip.username
217		assert_requested req
218	end
219	em :test_sip_account_new
220
221	def test_sip_account_existing
222		req1 = stub_request(
223			:get,
224			"https://dashboard.bandwidth.com/v1.0/accounts//sipcredentials/ctest"
225		).with(
226			headers: {
227				"Authorization" => "Basic Og=="
228			}
229		).to_return(status: 200, body: {
230			SipCredential: {
231				UserName: "ctest",
232				Realm: "sip.example.com"
233			}
234		}.to_xml)
235
236		sip = customer.sip_account
237		assert_kind_of SipAccount, sip
238		assert_equal "ctest", sip.username
239
240		assert_requested req1
241	end
242	em :test_sip_account_existing
243
244	def test_sip_account_error
245		stub_request(
246			:get,
247			"https://dashboard.bandwidth.com/v1.0/accounts//sipcredentials/ctest"
248		).to_return(
249			status: 404,
250			body:
251				"<r><ResponseStatus><ErrorCode>0</ErrorCode>" \
252				"<Description>desc</Description></ResponseStatus></r>"
253		)
254
255		assert_equal "ctest", customer.sip_account.username
256	end
257	em :test_sip_account_error
258
259	def test_btc_addresses
260		CustomerFinancials::REDIS.expect(
261			:smembers,
262			EMPromise.resolve(["testaddr"]),
263			["jmp_customer_btc_addresses-test"]
264		)
265		assert_equal ["testaddr"], customer.btc_addresses.sync
266		assert_mock Customer::REDIS
267	end
268	em :test_btc_addresses
269
270	def test_add_btc_address
271		CustomerFinancials::REDIS.expect(
272			:spopsadd,
273			EMPromise.resolve("testaddr"),
274			[["jmp_available_btc_addresses", "jmp_customer_btc_addresses-test"]]
275		)
276		CustomerFinancials::ELECTRUM.expect(
277			:notify,
278			EMPromise.resolve(nil),
279			["testaddr", "http://notify.example.com"]
280		)
281		assert_equal "testaddr", customer.add_btc_address.sync
282		assert_mock CustomerFinancials::REDIS
283		assert_mock CustomerFinancials::ELECTRUM
284	end
285	em :test_add_btc_address
286end