def reward_address_for_task_internal(public_address, task_id, send_push, user_id, memo): '''transfer the correct amount of kins for the task to the given address this function runs in the background and sends a push message to the client to indicate that the money was indeed transferred. ''' # get reward amount from db amount = get_reward_for_task(task_id) if not amount: print('could not figure reward amount for task_id: %s' % task_id) raise InternalError('cant find reward for taskid %s' % task_id) try: # send the moneys print('calling send_kin: %s, %s' % (public_address, amount)) tx_hash = send_kin(public_address, amount, memo) except Exception as e: print('caught exception sending %s kins to %s - exception: %s:' % (amount, public_address, e)) raise InternalError('failed sending %s kins to %s' % (amount, public_address)) finally: #TODO dont do this if we fail with the tx if send_push: send_push_tx_completed(user_id, tx_hash, amount, task_id) create_tx(tx_hash, user_id, public_address, False, amount, { 'task_id': task_id, 'memo': memo }) # TODO Add memeo?
def compensate_user_api(): """internal endpoint used to manually compensate users for missing txs""" if not config.DEBUG: limit_to_localhost() payload = request.get_json(silent=True) user_id = payload.get('user_id', None) kin_amount = int(payload.get('kin_amount', None)) task_id = payload.get('task_id', None) memo = utils.generate_memo(is_manual=True) if None in (user_id, kin_amount, task_id): raise InvalidUsage('invalid param') public_address = get_address_by_userid(user_id) if not public_address: log.error('cant compensate user %s - no public address' % user_id) return jsonify(status='error', reason='no_public_address') user_tx_task_ids = [ tx.tx_info.get('task_id', '-1') for tx in list_user_transactions(user_id) ] if task_id in user_tx_task_ids: print( 'refusing to compensate user %s for task %s - already received funds!' % (user_id, task_id)) return jsonify(status='error', reason='already_compensated') print('calling send_kin: %s, %s' % (public_address, kin_amount)) try: tx_hash = send_kin(public_address, kin_amount, memo) create_tx(tx_hash, user_id, public_address, False, kin_amount, { 'task_id': task_id, 'memo': memo }) except Exception as e: print('error attempting to compensate user %s for task %s' % (user_id, task_id)) print(e) return jsonify(status='error', reason='internal_error') else: print('compensated user %s with %s kins for task_id %s' % (user_id, kin_amount, task_id)) # also send push to the user task_title = get_task_details(task_id)['title'] send_compensated_push(user_id, kin_amount, task_title) increment_metric('manual-compensation') return jsonify(status='ok', tx_hash=tx_hash)
def reward_address_for_task(public_address, task_id): '''transfer the correct amount of kins for the task to the given address''' # get reward amount amount = get_reward_for_task(task_id) if not amount: print('could not figure reward amount for task_id: %s' % task_id) raise InternalError('cant find reward for taskid %s' % task_id) try: print('calling send_kin: %s, %s' % (public_address, amount)) tx_hash = stellar.send_kin(public_address, amount, 'kin-app')#-taskid:%s' % task_id) print('tx_has: %s' % tx_hash) print('after calling send_kin') except Exception as e: print('caught exception sending %s kins to %s - exception: %s:' % (amount, public_address, e)) raise InternalError('failed sending %s kins to %s' % (amount, public_address)) return tx_hash, amount
def send_kin_to_user(): '''temp endpoint for testing sending kin TODO remove''' payload = request.get_json(silent=True) try: public_address = payload.get('public_address', None) amount = payload.get('amount', None) if None in (public_address, amount): raise InvalidUsage('bad-request') except Exception as e: print('exception: %s' % e) raise InvalidUsage('bad-request') #establish trust from stellar_base.asset import Asset my_asset = Asset( 'KIN', 'GCKG5WGBIJP74UDNRIRDFGENNIH5Y3KBI5IHREFAJKV4MQXLELT7EX6V') tx_hash = app.kin_sdk.trust_asset(my_asset, limit=2) print('trust tx hash: %s' % tx_hash) tx_hash = send_kin(public_address, amount, 'test') print('transfer tx hash: %s' % tx_hash) return jsonify(status='ok')
def test_book_and_redeem(self): """test creating orders""" cat = { 'id': '0', 'title': 'cat-title', 'supported_os': 'all', 'ui_data': { 'color': "#something", 'image_url': 'https://s3.amazonaws.com/kinapp-static/brand_img/gift_card.png', 'header_image_url': 'https://s3.amazonaws.com/kinapp-static/brand_img/gift_card.png' } } resp = self.app.post('/category/add', data=json.dumps({'category': cat}), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) task = { 'title': 'do you know horses?', 'desc': 'horses_4_dummies', 'type': 'questionnaire', 'position': 0, 'cat_id': '0', 'task_id': '0', 'price': 100, 'min_to_complete': 2, 'skip_image_test': False, # test link-checking code 'tags': ['music', 'crypto', 'movies', 'kardashians', 'horses'], 'provider': { 'name': 'om-nom-nom-food', 'image_url': 'https://s3.amazonaws.com/kinapp-static/brand_img/gift_card.png' }, 'post_task_actions': [{ 'type': 'external-url', 'text': 'please vote mofos', 'text_ok': 'yes! register!', 'text_cancel': 'no thanks mofos', 'url': 'https://s3.amazonaws.com/kinapp-static/brand_img/gift_card.png', 'icon_url': 'https://s3.amazonaws.com/kinapp-static/brand_img/gift_card.png', 'campaign_name': 'buy-moar-underwear' }], 'items': [{ 'id': '435', 'text': 'what animal is this?', 'image_url': 'https://s3.amazonaws.com/kinapp-static/brand_img/gift_card.png', 'type': 'textimage', 'results': [ { 'id': '235', 'text': 'a horse!', 'image_url': 'https://s3.amazonaws.com/kinapp-static/brand_img/gift_card.png' }, { 'id': '2465436', 'text': 'a cat!', 'image_url': 'https://s3.amazonaws.com/kinapp-static/brand_img/gift_card.png' }, ], }] } # task_id isn't given, should be '0' resp = self.app.post( '/task/add', # task_id should be 0 data=json.dumps({'task': task}), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) offerid = '0' offer = { 'id': offerid, 'type': 'gift-card', 'type_image_url': "https://s3.amazonaws.com/kinapp-static/brand_img/gift_card.png", 'domain': 'music', 'title': 'offer_title', 'desc': 'offer_desc', 'image_url': 'image_url', 'skip_image_test': True, 'price': 5, 'address': 'GCYUCLHLMARYYT5EXJIK2KZJCMRGIKKUCCJKJOAPUBALTBWVXAT4F4OZ', 'provider': { 'name': 'om-nom-nom-food', 'image_url': 'http://inter.webs/horsie.jpg' }, } print('listing all orders: %s' % models.list_all_order_data()) # add an offer resp = self.app.post('/offer/add', data=json.dumps({'offer': offer}), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) # enable the offer resp = self.app.post('/offer/set_active', data=json.dumps({ 'id': offerid, 'is_active': True }), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) # create a good instance for the offer (1) resp = self.app.post('/good/add', data=json.dumps({ 'offer_id': offerid, 'good_type': 'code', 'value': 'abcd1' }), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) # create a good instance for the offer (2) resp = self.app.post('/good/add', data=json.dumps({ 'offer_id': offerid, 'good_type': 'code', 'value': 'abcd2' }), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) # create a good instance for the offer (3) resp = self.app.post('/good/add', data=json.dumps({ 'offer_id': offerid, 'good_type': 'code', 'value': 'abcd3' }), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) # create a good instance for the offer (4) resp = self.app.post('/good/add', data=json.dumps({ 'offer_id': offerid, 'good_type': 'code', 'value': 'abcd4' }), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) # 4 goods at this point resp = self.app.get('/good/inventory') self.assertEqual(resp.status_code, 200) self.assertEqual( json.loads(resp.data)['inventory'], {offer['id']: { 'total': 4, 'unallocated': 4 }}) # register a couple of users userid1 = uuid4() resp = self.app.post('/user/register', data=json.dumps({ 'user_id': str(userid1), 'os': 'android', 'device_model': 'samsung8', 'device_id': '234234', 'time_zone': '05:00', 'token': 'fake_token', 'app_ver': '1.0' }), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) userid2 = uuid4() resp = self.app.post('/user/register', data=json.dumps({ 'user_id': str(userid2), 'os': 'android', 'device_model': 'samsung8', 'device_id': '234234', 'time_zone': '05:00', 'token': 'fake_token', 'app_ver': '1.0' }), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) # add transactions to the user db.engine.execute( """update public.push_auth_token set auth_token='%s' where user_id='%s';""" % (str(userid2), str(userid2))) db.engine.execute( """update public.push_auth_token set auth_token='%s' where user_id='%s';""" % (str(userid1), str(userid1))) resp = self.app.post('/user/auth/ack', data=json.dumps({'token': str(userid2)}), headers={USER_ID_HEADER: str(userid2)}, content_type='application/json') self.assertEqual(resp.status_code, 200) resp = self.app.post('/user/auth/ack', data=json.dumps({'token': str(userid1)}), headers={USER_ID_HEADER: str(userid1)}, content_type='application/json') self.assertEqual(resp.status_code, 200) # user updates his phone number to the server after client-side verification phone_num1 = '+9720000000000' resp = self.app.post('/user/firebase/update-id-token', data=json.dumps({ 'token': 'fake-token', 'phone_number': phone_num1 }), headers={USER_ID_HEADER: str(userid1)}, content_type='application/json') self.assertEqual(resp.status_code, 200) # user updates his phone number to the server after client-side verification phone_num2 = '+972111111111' resp = self.app.post('/user/firebase/update-id-token', data=json.dumps({ 'token': 'fake-token', 'phone_number': phone_num2 }), headers={USER_ID_HEADER: str(userid2)}, content_type='application/json') self.assertEqual(resp.status_code, 200) # get user2 tx history - should have 0 items resp = self.app.get('/user/transactions', headers={USER_ID_HEADER: str(userid2)}) self.assertEqual(resp.status_code, 200) print('txs: %s' % json.loads(resp.data)) self.assertEqual(json.loads(resp.data)['txs'], []) # add transactions to the user create_tx("AAA", userid1, "someaddress", False, 100, { 'task_id': '0', 'memo': 'kit-12312312312' }) create_tx("BBB", userid2, "someaddress", False, 100, { 'task_id': '0', 'memo': 'kit-12312312312' }) # get user2 redeem history - should be empty resp = self.app.get('/user/redeemed', headers={USER_ID_HEADER: str(userid2)}) self.assertEqual(resp.status_code, 200) print('redeemed: %s' % json.loads(resp.data)) self.assertEqual(json.loads(resp.data)['redeemed'], []) # create the first order resp = self.app.post('/offer/book', data=json.dumps({'id': offerid}), headers={USER_ID_HEADER: str(userid1)}, content_type='application/json') self.assertEqual(resp.status_code, 200) data = json.loads(resp.data) self.assertEqual(data['status'], 'ok') self.assertNotEqual(data['order_id'], None) orderid1 = data['order_id'] print('order_id: %s' % orderid1) # pay for the order but give a differet address - should fail print('setting memo of %s' % orderid1) tx_hash_wrong_address = stellar.send_kin( 'GCKG5WGBIJP74UDNRIRDFGENNIH5Y3KBI5IHREFAJKV4MQXLELT7EX6V', offer['price'], orderid1) print('tx_hash: %s' % tx_hash_wrong_address) # try to redeem the goods with the tx_hash - should fail print('trying to redeem with the wrong address...') resp = self.app.post('/offer/redeem', data=json.dumps( {'tx_hash': tx_hash_wrong_address}), headers={USER_ID_HEADER: str(userid1)}, content_type='application/json') self.assertNotEqual(resp.status_code, 200) data = json.loads(resp.data) print(data) # re-create the first order resp = self.app.post('/offer/book', data=json.dumps({'id': offerid}), headers={USER_ID_HEADER: str(userid1)}, content_type='application/json') self.assertEqual(resp.status_code, 200) data = json.loads(resp.data) self.assertEqual(data['status'], 'ok') self.assertNotEqual(data['order_id'], None) orderid1 = data['order_id'] print('order_id: %s' % orderid1) # pay for the order - but pay less than expected print('setting memo of %s' % orderid1) tx_hash_pay_less = stellar.send_kin(offer['address'], offer['price'] - 1, orderid1) print('tx_hash: %s' % tx_hash_pay_less) # try to redeem the goods - shuld fail print('trying to redeem with underpayed tx...') resp = self.app.post('/offer/redeem', data=json.dumps({'tx_hash': tx_hash_pay_less}), headers={USER_ID_HEADER: str(userid1)}, content_type='application/json') self.assertNotEqual(resp.status_code, 200) data = json.loads(resp.data) print(data) # re-create the order (use userid2 now) resp = self.app.post('/offer/book', data=json.dumps({'id': offerid}), headers={USER_ID_HEADER: str(userid2)}, content_type='application/json') self.assertEqual(resp.status_code, 200) data = json.loads(resp.data) self.assertEqual(data['status'], 'ok') self.assertNotEqual(data['order_id'], None) orderid1 = data['order_id'] print('order_id: %s' % orderid1) # pay for the order - but use an invalid orderid print('setting memo of %s' % orderid1) tx_hash_other_orderid = stellar.send_kin(offer['address'], offer['price'], "other_order_id") print('tx_hash: %s' % tx_hash_other_orderid) # try to redeem the goods - should fail print('trying to redeem with unknown order_id...') resp = self.app.post('/offer/redeem', data=json.dumps( {'tx_hash': tx_hash_other_orderid}), headers={USER_ID_HEADER: str(userid2)}, content_type='application/json') self.assertNotEqual(resp.status_code, 200) data = json.loads(resp.data) print(data) # re-create the order resp = self.app.post('/offer/book', data=json.dumps({'id': offerid}), headers={USER_ID_HEADER: str(userid2)}, content_type='application/json') self.assertEqual(resp.status_code, 200) data = json.loads(resp.data) self.assertEqual(data['status'], 'ok') self.assertNotEqual(data['order_id'], None) orderid1 = data['order_id'] print('order_id: %s' % orderid1) # pay for the order print('setting memo of %s' % orderid1) tx_hash = stellar.send_kin(offer['address'], offer['price'], orderid1) print('tx_hash: %s' % tx_hash) # try to redeem the goods - should work resp = self.app.post('/offer/redeem', data=json.dumps({'tx_hash': tx_hash}), headers={USER_ID_HEADER: str(userid2)}, content_type='application/json') self.assertEqual(resp.status_code, 200) data = json.loads(resp.data) print(data) # try to book again - should fail - out of goods resp = self.app.post('/offer/book', data=json.dumps({'id': offerid}), headers={USER_ID_HEADER: str(userid1)}, content_type='application/json') self.assertEqual(resp.status_code, 400) resp = self.app.post('/good/add', data=json.dumps({ 'offer_id': offerid, 'good_type': 'code', 'value': 'abcda1' }), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) # try to book again - should fail - max offer reached resp = self.app.post('/offer/book', data=json.dumps({'id': offerid}), headers={USER_ID_HEADER: str(userid2)}, content_type='application/json') self.assertEqual(resp.status_code, 400) # get user2 redeem history - should have one item resp = self.app.get('/user/redeemed', headers={USER_ID_HEADER: str(userid2)}) self.assertEqual(resp.status_code, 200) print('redeemed: %s' % json.loads(resp.data)) self.assertEqual(len(json.loads(resp.data)['redeemed']), 1) # get user2 tx history - should have 2 items resp = self.app.get('/user/transactions', headers={USER_ID_HEADER: str(userid2)}) self.assertEqual(resp.status_code, 200) print('txs: %s' % json.loads(resp.data)) self.assertEqual(len(json.loads(resp.data)['txs']), 2) # no unallocated goods at this point resp = self.app.get('/good/inventory') self.assertEqual(resp.status_code, 200) self.assertEqual( json.loads(resp.data)['inventory'], {offer['id']: { 'total': 5, 'unallocated': 1 }}) print('listing all orders: %s' % models.list_all_order_data()) resp = self.app.post('/user/nuke-data', data=json.dumps({'phone_number': phone_num1}), headers={USER_ID_HEADER: str(userid1)}, content_type='application/json') self.assertEqual(resp.status_code, 200) resp = self.app.post('/user/nuke-data', data=json.dumps({ 'phone_number': phone_num2, 'nuke_all': True }), headers={USER_ID_HEADER: str(userid2)}, content_type='application/json') self.assertEqual(resp.status_code, 200)
def test_book_and_redeem(self): """test creating orders""" offerid = '0' offer = { 'id': offerid, 'type': 'gift-card', 'type_image_url': "https://s3.amazonaws.com/kinapp-static/brand_img/gift_card.png", 'domain': 'music', 'title': 'offer_title', 'desc': 'offer_desc', 'image_url': 'image_url', 'price': 2, 'address': 'GCORIYYEQP3ANHFT6XHMBY7VB3RH53WB5KZZHGCEXYRWCEJQZUXPGWQM', 'provider': { 'name': 'om-nom-nom-food', 'image_url': 'http://inter.webs/horsie.jpg' }, } # add an offer resp = self.app.post('/offer/add', data=json.dumps({'offer': offer}), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) # enable the offer resp = self.app.post('/offer/set_active', data=json.dumps({ 'id': offerid, 'is_active': True }), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) # create a good instance for the offer (1) resp = self.app.post('/good/add', data=json.dumps({ 'offer_id': offerid, 'good_type': 'code', 'value': 'abcd' }), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) # create a good instance for the offer (2) resp = self.app.post('/good/add', data=json.dumps({ 'offer_id': offerid, 'good_type': 'code', 'value': 'abcd' }), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) # create a good instance for the offer (3) resp = self.app.post('/good/add', data=json.dumps({ 'offer_id': offerid, 'good_type': 'code', 'value': 'abcd' }), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) # create a good instance for the offer (4) resp = self.app.post('/good/add', data=json.dumps({ 'offer_id': offerid, 'good_type': 'code', 'value': 'abcd' }), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) # 4 goods at this point resp = self.app.get('/good/inventory') self.assertEqual(resp.status_code, 200) self.assertEqual( json.loads(resp.data)['inventory'], {offer['id']: { 'total': 4, 'unallocated': 4 }}) # register a couple of users userid1 = uuid4() resp = self.app.post('/user/register', data=json.dumps({ 'user_id': str(userid1), 'os': 'android', 'device_model': 'samsung8', 'device_id': '234234', 'time_zone': '05:00', 'token': 'fake_token', 'app_ver': '1.0' }), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) userid2 = uuid4() resp = self.app.post('/user/register', data=json.dumps({ 'user_id': str(userid2), 'os': 'android', 'device_model': 'samsung8', 'device_id': '234234', 'time_zone': '05:00', 'token': 'fake_token', 'app_ver': '1.0' }), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) # create the first order resp = self.app.post('/offer/book', data=json.dumps({'id': offerid}), headers={USER_ID_HEADER: str(userid1)}, content_type='application/json') self.assertEqual(resp.status_code, 200) data = json.loads(resp.data) self.assertEqual(data['status'], 'ok') self.assertNotEqual(data['order_id'], None) orderid1 = data['order_id'] print('order_id: %s' % orderid1) # pay for the order but give a differet address - should fail print('setting memo of %s' % orderid1) tx_hash_wrong_address = stellar.send_kin( 'GCKG5WGBIJP74UDNRIRDFGENNIH5Y3KBI5IHREFAJKV4MQXLELT7EX6V', offer['price'], orderid1) print('tx_hash: %s' % tx_hash_wrong_address) # try to redeem the goods with the tx_hash - should fail print('trying to redeem with the wrong address...') resp = self.app.post('/offer/redeem', data=json.dumps( {'tx_hash': tx_hash_wrong_address}), headers={USER_ID_HEADER: str(userid1)}, content_type='application/json') self.assertNotEqual(resp.status_code, 200) data = json.loads(resp.data) print(data) # re-create the first order resp = self.app.post('/offer/book', data=json.dumps({'id': offerid}), headers={USER_ID_HEADER: str(userid1)}, content_type='application/json') self.assertEqual(resp.status_code, 200) data = json.loads(resp.data) self.assertEqual(data['status'], 'ok') self.assertNotEqual(data['order_id'], None) orderid1 = data['order_id'] print('order_id: %s' % orderid1) # pay for the order - but pay less than expected print('setting memo of %s' % orderid1) tx_hash_pay_less = stellar.send_kin(offer['address'], offer['price'] - 1, orderid1) print('tx_hash: %s' % tx_hash_pay_less) # try to redeem the goods - shuld fail print('trying to redeem with underpayed tx...') resp = self.app.post('/offer/redeem', data=json.dumps({'tx_hash': tx_hash_pay_less}), headers={USER_ID_HEADER: str(userid1)}, content_type='application/json') self.assertNotEqual(resp.status_code, 200) data = json.loads(resp.data) print(data) # re-create the order (use userid2 now) resp = self.app.post('/offer/book', data=json.dumps({'id': offerid}), headers={USER_ID_HEADER: str(userid2)}, content_type='application/json') self.assertEqual(resp.status_code, 200) data = json.loads(resp.data) self.assertEqual(data['status'], 'ok') self.assertNotEqual(data['order_id'], None) orderid1 = data['order_id'] print('order_id: %s' % orderid1) # pay for the order - but use an invalid orderid print('setting memo of %s' % orderid1) tx_hash_other_orderid = stellar.send_kin(offer['address'], offer['price'], "other_order_id") print('tx_hash: %s' % tx_hash_other_orderid) # try to redeem the goods - should fail print('trying to redeem with unknown order_id...') resp = self.app.post('/offer/redeem', data=json.dumps( {'tx_hash': tx_hash_other_orderid}), headers={USER_ID_HEADER: str(userid2)}, content_type='application/json') self.assertNotEqual(resp.status_code, 200) data = json.loads(resp.data) print(data) # re-create the order resp = self.app.post('/offer/book', data=json.dumps({'id': offerid}), headers={USER_ID_HEADER: str(userid2)}, content_type='application/json') self.assertEqual(resp.status_code, 200) data = json.loads(resp.data) self.assertEqual(data['status'], 'ok') self.assertNotEqual(data['order_id'], None) orderid1 = data['order_id'] print('order_id: %s' % orderid1) # pay for the order print('setting memo of %s' % orderid1) tx_hash = stellar.send_kin(offer['address'], offer['price'], orderid1) print('tx_hash: %s' % tx_hash) #try to redeem the goods - should work resp = self.app.post('/offer/redeem', data=json.dumps({'tx_hash': tx_hash}), headers={USER_ID_HEADER: str(userid2)}, content_type='application/json') self.assertEqual(resp.status_code, 200) data = json.loads(resp.data) print(data) # no goods at this point resp = self.app.get('/good/inventory') self.assertEqual(resp.status_code, 200) self.assertEqual( json.loads(resp.data)['inventory'], {offer['id']: { 'total': 4, 'unallocated': 0 }})
def test_book_and_redeem_multiple(self): """test creating orders""" offerid = '0' offer = { 'id': offerid, 'type': 'gift-card', 'type_image_url': "https://s3.amazonaws.com/kinapp-static/brand_img/gift_card.png", 'domain': 'music', 'title': 'offer_title', 'desc': 'offer_desc', 'image_url': 'image_url', 'price': 2, 'skip_image_test': True, 'address': 'GCYUCLHLMARYYT5EXJIK2KZJCMRGIKKUCCJKJOAPUBALTBWVXAT4F4OZ', 'provider': { 'name': 'om-nom-nom-food', 'image_url': 'http://inter.webs/horsie.jpg' }, } # add an offer resp = self.app.post('/offer/add', data=json.dumps({'offer': offer}), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) # enable the offer resp = self.app.post('/offer/set_active', data=json.dumps({ 'id': offerid, 'is_active': True }), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) # create a good instance for the offer (1) resp = self.app.post('/good/add', data=json.dumps({ 'offer_id': offerid, 'good_type': 'code', 'value': 'abcd1' }), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) # create a good instance for the offer (2) resp = self.app.post('/good/add', data=json.dumps({ 'offer_id': offerid, 'good_type': 'code', 'value': 'abcd2' }), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) # 2 goods at this point resp = self.app.get('/good/inventory') self.assertEqual(resp.status_code, 200) self.assertEqual( json.loads(resp.data)['inventory'], {offer['id']: { 'total': 2, 'unallocated': 2 }}) # register a user userid1 = uuid4() resp = self.app.post('/user/register', data=json.dumps({ 'user_id': str(userid1), 'os': 'android', 'device_model': 'samsung8', 'device_id': '234234', 'time_zone': '05:00', 'token': 'fake_token', 'app_ver': '1.0' }), headers={}, content_type='application/json') self.assertEqual(resp.status_code, 200) db.engine.execute( """update public.push_auth_token set auth_token='%s' where user_id='%s';""" % (str(userid1), str(userid1))) resp = self.app.post('/user/auth/ack', data=json.dumps({'token': str(userid1)}), headers={USER_ID_HEADER: str(userid1)}, content_type='application/json') self.assertEqual(resp.status_code, 200) # get user1 redeem history - should be empty resp = self.app.get('/user/redeemed', headers={USER_ID_HEADER: str(userid1)}) self.assertEqual(resp.status_code, 200) print('redeemed: %s' % json.loads(resp.data)) self.assertEqual(json.loads(resp.data)['redeemed'], []) # get user1 tx history - should have 0 items resp = self.app.get('/user/transactions', headers={USER_ID_HEADER: str(userid1)}) self.assertEqual(resp.status_code, 200) print('txs: %s' % json.loads(resp.data)) self.assertEqual(json.loads(resp.data)['txs'], []) # create the order resp = self.app.post('/offer/book', data=json.dumps({'id': offerid}), headers={USER_ID_HEADER: str(userid1)}, content_type='application/json') self.assertEqual(resp.status_code, 200) data = json.loads(resp.data) self.assertEqual(data['status'], 'ok') self.assertNotEqual(data['order_id'], None) orderid1 = data['order_id'] print('order_id: %s' % orderid1) # pay for the order print('setting memo of %s' % orderid1) tx_hash = stellar.send_kin(offer['address'], offer['price'], orderid1) print('tx_hash: %s' % tx_hash) # try to redeem the goods - should work resp = self.app.post('/offer/redeem', data=json.dumps({'tx_hash': tx_hash}), headers={USER_ID_HEADER: str(userid1)}, content_type='application/json') self.assertEqual(resp.status_code, 200) data = json.loads(resp.data) print(data) # get user1 redeem history - should have one item resp = self.app.get('/user/redeemed', headers={USER_ID_HEADER: str(userid1)}) self.assertEqual(resp.status_code, 200) print('redeemed: %s' % json.loads(resp.data)) self.assertNotEqual(json.loads(resp.data)['redeemed'], []) # get user1 tx history - should have 2 items resp = self.app.get('/user/transactions', headers={USER_ID_HEADER: str(userid1)}) self.assertEqual(resp.status_code, 200) print('txs: %s' % json.loads(resp.data)) self.assertNotEqual(json.loads(resp.data)['txs'], []) # create the order resp = self.app.post('/offer/book', data=json.dumps({'id': offerid}), headers={USER_ID_HEADER: str(userid1)}, content_type='application/json') self.assertEqual(resp.status_code, 200) data = json.loads(resp.data) self.assertEqual(data['status'], 'ok') self.assertNotEqual(data['order_id'], None) orderid1 = data['order_id'] print('order_id: %s' % orderid1) # pay for the order print('setting memo of %s' % orderid1) tx_hash = stellar.send_kin(offer['address'], offer['price'], orderid1) print('tx_hash: %s' % tx_hash) # try to redeem the goods - should work resp = self.app.post('/offer/redeem', data=json.dumps({'tx_hash': tx_hash}), headers={USER_ID_HEADER: str(userid1)}, content_type='application/json') self.assertEqual(resp.status_code, 200) data = json.loads(resp.data) print(data) # get user1 redeem history - should have 2 items resp = self.app.get('/user/redeemed', headers={USER_ID_HEADER: str(userid1)}) self.assertEqual(resp.status_code, 200) print('redeemed: %s' % json.loads(resp.data)) self.assertNotEqual(json.loads(resp.data)['redeemed'], []) print('asserting redeemed goods order') self.assertEqual( json.loads(resp.data)['redeemed'][0]['date'] > json.loads( resp.data)['redeemed'][1]['date'], True) # get user1 tx history - should have 4 items resp = self.app.get('/user/transactions', headers={USER_ID_HEADER: str(userid1)}) self.assertEqual(resp.status_code, 200) print('txs: %s' % json.loads(resp.data)) self.assertNotEqual(json.loads(resp.data)['txs'], []) print('assert tx order') self.assertEqual( json.loads(resp.data)['txs'][0]['date'] > json.loads( resp.data)['txs'][1]['date'], True) # no unallocated goods at this point resp = self.app.get('/good/inventory') self.assertEqual(resp.status_code, 200) self.assertEqual( json.loads(resp.data)['inventory'], {offer['id']: { 'total': 2, 'unallocated': 0 }})