1# frozen_string_literal: true
  2
  3require "test_helper"
  4require "customer_repo"
  5
  6class CustomerRepo
  7	attr_reader :sgx_repo
  8end
  9
 10CustomerPlan::DB = Minitest::Mock.new
 11
 12class CustomerRepoTest < Minitest::Test
 13	FAKE_REDIS = FakeRedis.new(
 14		# sgx-jmp customer
 15		"jmp_customer_jid-test" => "test@example.com",
 16		"jmp_customer_id-test@example.com" => "test",
 17		"catapult_jid-+13334445555" => "customer_test@component",
 18		"catapult_cred-customer_test@component" => [
 19			"test_bw_customer", "", "", "+13334445555"
 20		],
 21		# sgx-jmp customer, empty DB
 22		"jmp_customer_jid-empty" => "empty@example.com",
 23		"jmp_customer_id-empty@example.com" => "empty",
 24		"catapult_jid-+16667778888" => "customer_empty@component",
 25		"catapult_cred-customer_empty@component" => [
 26			"test_bw_customer", "", "", "+16667778888"
 27		],
 28		# v2 customer
 29		"jmp_customer_jid-test_v2" => "test_v2@example.com",
 30		"jmp_customer_id-test_v2@example.com" => "test_v2",
 31		"catapult_jid-+14445556666" => "test_v2@example.com",
 32		"catapult_cred-test_v2@example.com" => [
 33			"test_bw_customer", "", "", "+14445556666"
 34		]
 35	)
 36
 37	FAKE_DB = FakeDB.new(
 38		["test"] => [{
 39			"balance" => BigDecimal(1234),
 40			"plan_name" => "test_usd",
 41			"expires_at" => Time.now + 100
 42		}],
 43		["testp"] => [{
 44			"balance" => BigDecimal(1234),
 45			"plan_name" => "test_usd",
 46			"expires_at" => Time.now + 100,
 47			"parent_customer_id" => "1234"
 48		}],
 49		["test_v2"] => [{
 50			"balance" => BigDecimal(2345),
 51			"plan_name" => "test_usd",
 52			"expires_at" => Time.now + 100
 53		}]
 54	)
 55
 56	def mkrepo(
 57		redis: FAKE_REDIS,
 58		db: FAKE_DB,
 59		braintree: Minitest::Mock.new
 60	)
 61		sgx_repo = Minitest::Mock.new(TrivialBackendSgxRepo.new(redis: FAKE_REDIS))
 62		CustomerRepo.new(
 63			redis: redis,
 64			db: db,
 65			braintree: braintree,
 66			sgx_repo: sgx_repo
 67		)
 68	end
 69
 70	def setup
 71		@repo = mkrepo
 72	end
 73
 74	def test_find_by_jid
 75		customer = @repo.find_by_jid("test@example.com").sync
 76		assert_kind_of Customer, customer
 77		assert_equal 1234, customer.balance
 78		assert_equal "merchant_usd", customer.merchant_account
 79	end
 80	em :test_find_by_jid
 81
 82	def test_find_by_id
 83		customer = @repo.find("test").sync
 84		assert_kind_of Customer, customer
 85		assert_equal 1234, customer.balance
 86		assert_equal "merchant_usd", customer.merchant_account
 87	end
 88	em :test_find_by_id
 89
 90	def test_find_by_customer_jid
 91		customer = @repo.find_by_jid("customer_test@component").sync
 92		assert_kind_of Customer, customer
 93		assert_equal 1234, customer.balance
 94		assert_equal "merchant_usd", customer.merchant_account
 95	end
 96	em :test_find_by_customer_jid
 97
 98	def test_find_by_jid_not_found
 99		assert_raises do
100			@repo.find_by_jid("test2@example.com").sync
101		end
102	end
103	em :test_find_by_jid_not_found
104
105	def test_find_sgx_customer_by_phone
106		customer = @repo.find_by_tel("+13334445555").sync
107		assert_kind_of Customer, customer
108		assert_equal "test", customer.customer_id
109	end
110	em :test_find_sgx_customer_by_phone
111
112	def test_find_v2_customer_by_phone
113		assert_raises(CustomerRepo::NotFound) do
114			@repo.find_by_tel("+14445556666").sync
115		end
116	end
117	em :test_find_v2_customer_by_phone
118
119	def test_find_missing_phone
120		assert_raises do
121			@repo.find_by_tel("+15556667777").sync
122		end
123	end
124	em :test_find_missing_phone
125
126	def test_find_db_empty
127		customer = @repo.find("empty").sync
128		assert_equal BigDecimal(0), customer.balance
129	end
130	em :test_find_db_empty
131
132	def test_create
133		redis = Minitest::Mock.new
134		braintree = Minitest::Mock.new
135		repo = mkrepo(redis: redis, braintree: braintree)
136		braintree_customer = Minitest::Mock.new
137		braintree.expect(:customer, braintree_customer)
138		braintree_customer.expect(
139			:create,
140			EMPromise.resolve(
141				OpenStruct.new(success?: true, customer: OpenStruct.new(id: "test"))
142			)
143		)
144		redis.expect(
145			:msetnx,
146			EMPromise.resolve(1),
147			[
148				"jmp_customer_id-test@example.com", "test",
149				"jmp_customer_jid-test", "test@example.com"
150			]
151		)
152		redis.expect(
153			:get,
154			EMPromise.resolve(nil),
155			["jmp_customer_backend_sgx-test"]
156		)
157		assert_kind_of Customer, repo.create("test@example.com").sync
158		assert_mock braintree
159		assert_mock braintree_customer
160		assert_mock redis
161	end
162	em :test_create
163
164	def test_create_parented
165		redis = Minitest::Mock.new
166		braintree = Minitest::Mock.new
167		repo = mkrepo(redis: redis, braintree: braintree)
168		braintree_customer = Minitest::Mock.new
169		braintree.expect(:customer, braintree_customer)
170		braintree_customer.expect(
171			:create,
172			EMPromise.resolve(
173				OpenStruct.new(success?: true, customer: OpenStruct.new(id: "testp"))
174			)
175		)
176		redis.expect(
177			:msetnx,
178			EMPromise.resolve(1),
179			[
180				"jmp_customer_id-test@parented.example.com", "testp",
181				"jmp_customer_jid-testp", "test@parented.example.com"
182			]
183		)
184		redis.expect(
185			:get,
186			EMPromise.resolve(nil),
187			["jmp_customer_backend_sgx-testp"]
188		)
189		redis.expect(
190			:get,
191			EMPromise.resolve("test@parented.example.com"),
192			["jmp_customer_jid-testp"]
193		)
194		redis.expect(
195			:mget,
196			EMPromise.resolve([nil, nil]),
197			[
198				"jmp_customer_auto_top_up_amount-testp",
199				"jmp_customer_monthly_overage_limit-testp"
200			]
201		)
202		redis.expect(
203			:smembers,
204			EMPromise.resolve([]),
205			["jmp_customer_feature_flags-testp"]
206		)
207		CustomerPlan::DB.expect(
208			:query,
209			[{ "plan_name" => "test_usd" }],
210			[String, ["1234"]]
211		)
212		CustomerPlan::DB.expect(
213			:exec_defer,
214			EMPromise.resolve(nil),
215			[String, ["testp", "test_usd", "1234"]]
216		)
217		result = repo.create("test@parented.example.com").sync
218		assert_kind_of Customer::ChildCustomer, result
219		assert_equal "1234", result.billing_customer_id
220		assert_mock braintree
221		assert_mock braintree_customer
222		assert_mock redis
223		assert_mock CustomerPlan::DB
224	end
225	em :test_create_parented
226
227	def test_put_lidb_name
228		post = stub_request(
229			:post,
230			"https://dashboard.bandwidth.com/v1.0/accounts//lidbs"
231		).with(body: {
232			LidbTnGroups: {
233				LidbTnGroup: {
234					TelephoneNumbers: {
235						TelephoneNumber: "5556667777"
236					},
237					SubscriberInformation: "Hank",
238					UseType: "RESIDENTIAL",
239					Visibility: "PUBLIC"
240				}
241			}
242		}.to_xml(root: "LidbOrder", indent: 0)).to_return(
243			status: 201,
244			headers: { location: "/boop/123" }
245		)
246
247		stub_request(
248			:get,
249			"https://dashboard.bandwidth.com/v1.0/accounts//lidbs/123"
250		)
251
252		@repo.put_lidb_name(
253			Customer.new(
254				"test",
255				"test@exmple.com",
256				sgx: OpenStruct.new(registered?: OpenStruct.new(phone: "+15556667777"))
257			),
258			"Hank"
259		)
260
261		assert_requested post
262	end
263	em :test_put_lidb_name
264
265	def test_put_transcription_enabled
266		@repo.sgx_repo.expect(
267			:put_transcription_enabled,
268			EMPromise.resolve(nil),
269			["test", true]
270		)
271		@repo.put_transcription_enabled(
272			Customer.new("test", "test@exmple.com", sgx: nil),
273			true
274		)
275		assert_mock @repo.sgx_repo
276	end
277	em :test_put_transcription_enabled
278
279	def test_put_fwd
280		@repo.sgx_repo.expect(
281			:put_fwd,
282			EMPromise.resolve(nil),
283			["test", "+15556667777", :fwd]
284		)
285		@repo.put_fwd(
286			Customer.new(
287				"test",
288				"test@exmple.com",
289				sgx: OpenStruct.new(registered?: OpenStruct.new(phone: "+15556667777"))
290			),
291			:fwd
292		)
293		assert_mock @repo.sgx_repo
294	end
295	em :test_put_fwd
296end