def setUp(self): self.c = CsobClient( merchant_id="MERCHANT", base_url="https://gw.cz", private_key_file=KEY_PATH, csob_pub_key_file=KEY_PATH, )
def test_client_init_can_take_key_path(self): client = CsobClient(merchant_id='MERCHANT', base_url=BASE_URL, private_key=KEY_PATH, csob_pub_key=KEY_PATH) assert client.key == self.key assert client.pubkey == self.key
def test_client_init_can_take_key_string(self): client = CsobClient(merchant_id='MERCHANT', base_url=BASE_URL, private_key=self.key, csob_pub_key=self.key) assert client.key == self.key assert client.pubkey == self.key
def client(self): """Get CSOB Gateway Client.""" if self._client is None: self._client = CsobClient( SETTINGS.csob_card['merchant_id'], SETTINGS.csob_card['api_url'], str(SETTINGS.csob_card['merchant_private_key']), str(SETTINGS.csob_card['api_public_key']) ) return self._client
class CsobClientTests(TestCase): dttm = "20190502161426" dttime = datetime.datetime(2019, 5, 2, 16, 14, 26) def setUp(self): self.c = CsobClient( merchant_id="MERCHANT", base_url="https://gw.cz", private_key_file=KEY_PATH, csob_pub_key_file=KEY_PATH, ) @responses.activate def test_echo_post(self): resp_payload = utils.mk_payload( KEY_PATH, pairs=( ("dttm", utils.dttm()), ("resultCode", conf.RETURN_CODE_OK), ("resultMessage", "OK"), ), ) responses.add( responses.POST, "/echo/", body=json.dumps(resp_payload), status=200, content_type="application/json", ) out = self.c.echo().payload self.assertEqual(out["dttm"], self.dttm) self.assertEqual(out["dttime"], self.dttime) self.assertEqual(out["resultCode"], conf.RETURN_CODE_OK) @responses.activate def test_echo_get(self): payload = utils.mk_payload( KEY_PATH, pairs=( ("merchantId", self.c.merchant_id), ("dttm", utils.dttm()), ), ) resp_payload = utils.mk_payload( KEY_PATH, pairs=( ("dttm", utils.dttm()), ("resultCode", conf.RETURN_CODE_OK), ("resultMessage", "OK"), ), ) url = utils.mk_url("/", "echo/", payload) responses.add( responses.GET, url, body=json.dumps(resp_payload), status=200, content_type="application/json", ) out = self.c.echo(method="GET").payload self.assertEqual(out["dttm"], self.dttm) self.assertEqual(out["dttime"], self.dttime) self.assertEqual(out["resultCode"], conf.RETURN_CODE_OK) def test_sign_message(self): msg = "Příliš žluťoučký kůň úpěl ďábelské ódy." payload = utils.mk_payload( KEY_PATH, pairs=( ("merchantId", self.c.merchant_id), ("dttm", utils.dttm()), ("description", msg), ), ) assert payload["description"] == msg sig = payload.pop("signature") assert utils.verify(payload, sig, KEY_PATH) @responses.activate def test_payment_init_success(self): resp_url = "/payment/init" resp_payload = utils.mk_payload( KEY_PATH, pairs=( ("payId", PAY_ID), ("dttm", utils.dttm()), ("resultCode", conf.RETURN_CODE_OK), ("resultMessage", "OK"), ("paymentStatus", 1), ), ) responses.add(responses.POST, resp_url, body=json.dumps(resp_payload), status=200) out = self.c.payment_init( order_no=666, total_amount="66600", return_url="http://example.com", description="Nějaký popis", ).payload assert out["paymentStatus"] == conf.PAYMENT_STATUS_INIT assert out["resultCode"] == conf.RETURN_CODE_OK assert len(responses.calls) == 1 @responses.activate def test_payment_init_bad_cart(self): cart = [ OrderedDict([ ("name", "Order in sho XYZ"), ("quantity", 5), ("amount", 12345), ]), OrderedDict([ ("name", "Postage"), ("quantity", 1), ("amount", 0), ]), ] resp_payload = utils.mk_payload( KEY_PATH, pairs=( ("payId", PAY_ID), ("dttm", utils.dttm()), ("resultCode", conf.RETURN_CODE_PARAM_INVALID), ( "resultMessage", "Invalid 'cart' amounts, does not sum to totalAmount", ), ("paymentStatus", conf.PAYMENT_STATUS_REJECTED), ), ) resp_url = "/payment/init" responses.add(responses.POST, resp_url, body=json.dumps(resp_payload), status=200) out = self.c.payment_init( order_no=666, total_amount="2200000", return_url="http://", description="X", cart=cart, ).payload assert out["paymentStatus"] == conf.PAYMENT_STATUS_REJECTED assert out["resultCode"] == conf.RETURN_CODE_PARAM_INVALID @responses.activate def test_payment_status_extension(self): payload = utils.mk_payload( KEY_PATH, pairs=( ("merchantId", self.c.merchant_id), ("payId", PAY_ID), ("dttm", utils.dttm()), ), ) resp_payload = utils.mk_payload( KEY_PATH, pairs=( ("payId", PAY_ID), ("dttm", utils.dttm()), ("resultCode", conf.RETURN_CODE_PARAM_INVALID), ("resultMessage", "OK"), ("paymentStatus", conf.PAYMENT_STATUS_WAITING), ("authCode", "F7A23E"), ), ) ext_payload = utils.mk_payload( KEY_PATH, pairs=( ("extension", "maskClnRP"), ("dttm", utils.dttm()), ("maskedCln", "****1234"), ("expiration", "12/20"), ("longMaskedCln", "PPPPPP****XXXX"), ), ) resp_payload["extensions"] = [ext_payload] resp_url = utils.mk_url("/", "payment/status/", payload) responses.add(responses.GET, resp_url, body=json.dumps(resp_payload), status=200) out = self.c.payment_status(PAY_ID) assert hasattr(out, "extensions") assert len(out.extensions) == 1 assert out.extensions[0]["longMaskedCln"] == ext_payload[ "longMaskedCln"] @responses.activate def test_http_status_raised(self): responses.add(responses.POST, "/echo/", status=500) with pytest.raises(HTTPError) as excinfo: self.c.echo(method="POST") assert "500 Server Error" in str(excinfo.value) def test_gateway_return_retype(self): resp_payload = utils.mk_payload( KEY_PATH, pairs=( ("resultCode", str(conf.RETURN_CODE_PARAM_INVALID)), ("paymentStatus", str(conf.PAYMENT_STATUS_WAITING)), ("authCode", "F7A23E"), ), ) r = self.c.gateway_return(dict(resp_payload)) assert type(r["paymentStatus"]) == int assert type(r["resultCode"]) == int def test_gateway_return_merchant_data(self): resp_payload = utils.mk_payload( KEY_PATH, pairs=( ("resultCode", str(conf.RETURN_CODE_PARAM_INVALID)), ("paymentStatus", str(conf.PAYMENT_STATUS_WAITING)), ("merchantData", "Rm9v"), ), ) r = self.c.gateway_return(dict(resp_payload)) self.assertEqual( r, OrderedDict([("resultCode", 110), ("paymentStatus", 7), ("merchantData", b"Foo")]), ) @staticmethod def test_get_card_provider(): fn = utils.get_card_provider assert fn("423451****111")[0] == conf.CARD_PROVIDER_VISA @responses.activate def test_payment_init_with_merchant_data(self): resp_url = "/payment/init" resp_payload = utils.mk_payload( KEY_PATH, pairs=( ("payId", PAY_ID), ("dttm", utils.dttm()), ("resultCode", conf.RETURN_CODE_OK), ("resultMessage", "OK"), ("paymentStatus", 1), ), ) responses.add(responses.POST, resp_url, body=json.dumps(resp_payload), status=200) out = self.c.payment_init( order_no=666, total_amount="66600", return_url="http://example.com", description="Fooo", merchant_data=b"Foo", ).payload assert out["paymentStatus"] == conf.PAYMENT_STATUS_INIT assert out["resultCode"] == conf.RETURN_CODE_OK assert len(responses.calls) == 1 @responses.activate def test_payment_init_with_too_long_merchant_data(self): resp_url = "/payment/init" resp_payload = utils.mk_payload( KEY_PATH, pairs=( ("payId", PAY_ID), ("dttm", utils.dttm()), ("resultCode", conf.RETURN_CODE_OK), ("resultMessage", "OK"), ("paymentStatus", 1), ), ) responses.add(responses.POST, resp_url, body=json.dumps(resp_payload), status=200) with self.assertRaisesRegex( ValueError, "Merchant data length encoded to BASE64 is over 255 chars"): self.c.payment_init( order_no=666, total_amount="66600", return_url="http://example.com", description="Fooo", merchant_data=b"Foo" * 80, ).payload @responses.activate def test_payment_init_language_with_locale_cs(self): resp_url = "/payment/init" resp_payload = utils.mk_payload( KEY_PATH, pairs=( ("payId", PAY_ID), ("dttm", utils.dttm()), ("resultCode", conf.RETURN_CODE_OK), ("resultMessage", "OK"), ("paymentStatus", 1), ), ) responses.add(responses.POST, resp_url, body=json.dumps(resp_payload), status=200) out = self.c.payment_init( order_no=666, total_amount="66600", return_url="http://example.com", description="Fooo", language="cs_CZ.utf8", ).payload assert out["paymentStatus"] == conf.PAYMENT_STATUS_INIT assert out["resultCode"] == conf.RETURN_CODE_OK assert len(responses.calls) == 1 @responses.activate def test_button(self): resp_url = "/payment/button/" resp_payload = utils.mk_payload( KEY_PATH, pairs=( ("payId", PAY_ID), ("dttm", utils.dttm()), ("resultCode", conf.RETURN_CODE_OK), ("resultMessage", "OK"), ), ) responses.add(responses.POST, resp_url, body=json.dumps(resp_payload), status=200) out = self.c.button(PAY_ID, "csob").payload self.assertEqual( out, OrderedDict([ ("payId", "34ae55eb69e2cBF"), ("dttm", self.dttm), ("resultCode", 0), ("resultMessage", "OK"), ("dttime", self.dttime), ]), ) def test_dttm_decode(self): self.assertEqual(utils.dttm_decode("20190502161426"), self.dttime) @responses.activate def test_description_strip(self): resp_url = "/payment/init" resp_payload = utils.mk_payload( KEY_PATH, pairs=( ("payId", PAY_ID), ("dttm", utils.dttm()), ("resultCode", conf.RETURN_CODE_OK), ("resultMessage", "OK"), ("paymentStatus", 1), ), ) responses.add(responses.POST, resp_url, body=json.dumps(resp_payload), status=200) with patch("pycsob.utils.mk_payload", return_value=resp_payload) as mock_mk_payload: self.c.payment_init(42, "100", "http://example.com", "Konference Internet a Technologie 19") self.assertEqual( mock_mk_payload.mock_calls, [ call( KEY_PATH, pairs=( ("merchantId", "MERCHANT"), ("orderNo", "42"), ("dttm", "20190502161426"), ("payOperation", "payment"), ("payMethod", "card"), ("totalAmount", "100"), ("currency", "CZK"), ("closePayment", True), ("returnUrl", "http://example.com"), ("returnMethod", "POST"), ( "cart", [ OrderedDict([ ("name", "Konference Internet"), ("quantity", 1), ("amount", "100"), ]) ], ), ("description", "Konference Internet a Technologie 19"), ("merchantData", None), ("customerId", None), ("language", "CZ"), ("ttlSec", 600), ("logoVersion", None), ("colorSchemeVersion", None), ), ) ], )
def setUp(self): self.c = CsobClient(merchant_id='MERCHANT', base_url='https://gw.cz', private_key_file=KEY_PATH, csob_pub_key_file=KEY_PATH)
class CsobClientTests(TestCase): def setUp(self): self.c = CsobClient(merchant_id='MERCHANT', base_url='https://gw.cz', private_key_file=KEY_PATH, csob_pub_key_file=KEY_PATH) @responses.activate def test_echo_post(self): resp_payload = utils.mk_payload(KEY_PATH, pairs=( ('dttm', utils.dttm()), ('resultCode', conf.RETURN_CODE_OK), ('resultMessage', 'OK'), )) responses.add(responses.POST, '/echo/', body=json.dumps(resp_payload), status=200, content_type='application/json') out = self.c.echo().payload assert out['dttm'] == resp_payload['dttm'] assert out['resultCode'] == conf.RETURN_CODE_OK sig = resp_payload.pop('signature') assert utils.verify(out, sig, KEY_PATH) @responses.activate def test_echo_get(self): payload = utils.mk_payload(KEY_PATH, pairs=( ('merchantId', self.c.merchant_id), ('dttm', utils.dttm()), )) resp_payload = utils.mk_payload(KEY_PATH, pairs=( ('dttm', utils.dttm()), ('resultCode', conf.RETURN_CODE_OK), ('resultMessage', 'OK'), )) url = utils.mk_url('/', 'echo/', payload) responses.add(responses.GET, url, body=json.dumps(resp_payload), status=200, content_type='application/json') out = self.c.echo(method='GET').payload assert out['dttm'] == resp_payload['dttm'] assert out['resultCode'] == conf.RETURN_CODE_OK def test_sign_message(self): msg = 'Příliš žluťoučký kůň úpěl ďábelské ódy.' payload = utils.mk_payload(KEY_PATH, pairs=( ('merchantId', self.c.merchant_id), ('dttm', utils.dttm()), ('description', msg) )) assert payload['description'] == msg sig = payload.pop('signature') assert utils.verify(payload, sig, KEY_PATH) @responses.activate def test_payment_init_success(self): resp_url = '/payment/init' resp_payload = utils.mk_payload(KEY_PATH, pairs=( ('payId', PAY_ID), ('dttm', utils.dttm()), ('resultCode', conf.RETURN_CODE_OK), ('resultMessage', 'OK'), ('paymentStatus', 1) )) responses.add(responses.POST, resp_url, body=json.dumps(resp_payload), status=200) out = self.c.payment_init(order_no=666, total_amount='66600', return_url='http://example.com', description='Nějaký popis').payload assert out['paymentStatus'] == conf.PAYMENT_STATUS_INIT assert out['resultCode'] == conf.RETURN_CODE_OK assert len(responses.calls) == 1 @responses.activate def test_payment_init_bad_cart(self): cart = [ OrderedDict([ ('name', 'Order in sho XYZ'), ('quantity', 5), ('amount', 12345), ]), OrderedDict([ ('name', 'Postage'), ('quantity', 1), ('amount', 0), ]) ] resp_payload = utils.mk_payload(KEY_PATH, pairs=( ('payId', PAY_ID), ('dttm', utils.dttm()), ('resultCode', conf.RETURN_CODE_PARAM_INVALID), ('resultMessage', "Invalid 'cart' amounts, does not sum to totalAmount"), ('paymentStatus', conf.PAYMENT_STATUS_REJECTED) )) resp_url = '/payment/init' responses.add(responses.POST, resp_url, body=json.dumps(resp_payload), status=200) out = self.c.payment_init(order_no=666, total_amount='2200000', return_url='http://', description='X', cart=cart).payload assert out['paymentStatus'] == conf.PAYMENT_STATUS_REJECTED assert out['resultCode'] == conf.RETURN_CODE_PARAM_INVALID @responses.activate def test_payment_status_extension(self): payload = utils.mk_payload(KEY_PATH, pairs=( ('merchantId', self.c.merchant_id), ('payId', PAY_ID), ('dttm', utils.dttm()), )) resp_payload = utils.mk_payload(KEY_PATH, pairs=( ('payId', PAY_ID), ('dttm', utils.dttm()), ('resultCode', conf.RETURN_CODE_PARAM_INVALID), ('resultMessage', "OK"), ('paymentStatus', conf.PAYMENT_STATUS_WAITING), ('authCode', 'F7A23E') )) ext_payload = utils.mk_payload(KEY_PATH, pairs=( ('extension', 'maskClnRP'), ('dttm', utils.dttm()), ('maskedCln', '****1234'), ('expiration', '12/20'), ('longMaskedCln', 'PPPPPP****XXXX') )) resp_payload['extensions'] = [ext_payload] resp_url = utils.mk_url('/', 'payment/status/', payload) responses.add(responses.GET, resp_url, body=json.dumps(resp_payload), status=200) out = self.c.payment_status(PAY_ID) assert hasattr(out, 'extensions') assert len(out.extensions) == 1 assert out.extensions[0]['longMaskedCln'] == ext_payload['longMaskedCln'] @responses.activate def test_http_status_raised(self): responses.add(responses.POST, '/echo/', status=500) with pytest.raises(HTTPError) as excinfo: self.c.echo(method='POST') assert '500 Server Error' in str(excinfo.value) def test_gateway_return_retype(self): resp_payload = utils.mk_payload(KEY_PATH, pairs=( ('resultCode', str(conf.RETURN_CODE_PARAM_INVALID)), ('paymentStatus', str(conf.PAYMENT_STATUS_WAITING)), ('authCode', 'F7A23E') )) r = self.c.gateway_return(dict(resp_payload)) assert type(r['paymentStatus']) == int assert type(r['resultCode']) == int def test_get_card_provider(self): fn = utils.get_card_provider assert fn('423451****111')[0] == conf.CARD_PROVIDER_VISA
def setUp(self): self.key = open(KEY_PATH).read() self.c = CsobClient(merchant_id='MERCHANT', base_url=BASE_URL, private_key=KEY_PATH, csob_pub_key=KEY_PATH)