def setUp(self): self.ctx = self.app.test_request_context() self.ctx.push() db.create_all() # Initial Setup random_user_id = buid() self.user = User(userid=unicode(random_user_id), username=u'lukes{userid}'.format(userid=random_user_id), fullname=u"Luke Skywalker", email=u'luke{userid}@dagobah.org'.format(userid=random_user_id)) db.session.add(self.user) db.session.commit() self.profile = Profile(title=u"SpaceCon", userid=self.user.userid) db.session.add(self.profile) db.session.commit() self.project = Project(title=u"20000 AD", tagline=u"In a galaxy far far away...", profile=self.profile, user=self.user) self.project.make_name() db.session.add(self.project) db.session.commit() self.ticket_client = TicketClient(name=u"test client", client_eventid=u'123', clientid=u'123', client_secret=u'123', client_access_token=u'123', project=self.project) db.session.add(self.ticket_client) db.session.commit() bulk_upsert(self.project, event_ticket_types) db.session.commit() self.session = db.session
def gen_signed_code(self, identifier=None): """Generates a signed code in the format discount_code_base.randint.signature""" if not identifier: identifier = buid() signer = Signer(self.secret) key = "{base}.{identifier}".format(base=self.discount_code_base, identifier=identifier) return signer.sign(key)
def refresh(self): """ Create a new token while retaining the refresh token. """ if self.refresh_token is not None: self.token = buid() self.secret = newsecret()
def campaign_new(): form = CampaignForm() if request.method == 'GET' and g.board: form.boards.data = [g.board] if form.validate_on_submit(): campaign = Campaign(user=g.user) form.populate_obj(campaign) campaign.name = buid( ) # Use a random name since it's also used in user action submit forms db.session.add(campaign) db.session.commit() flash(u"Created a campaign", 'success') return render_redirect(url_for('campaign_view', campaign=campaign.name), code=303) return render_form( form=form, title=u"Create a campaign…", submit="Next", message= u"Campaigns appear around the job board and provide a call to action for users", formid="campaign_new", cancel_url=url_for('campaign_list'), ajax=False)
def render_form( form, title, message='', formid=None, submit=__("Submit"), cancel_url=None, ajax=False, with_chrome=True, action=None, autosave=False, draft_revision=None, ): multipart = False ref_id = 'form-' + (formid or buid()) if not action: action = request.url for field in form: if isinstance(field.widget, wtforms.widgets.FileInput): multipart = True if not with_chrome: template = THEME_FILES[current_app.config['theme']]['ajaxform.html.jinja2'] return render_template( template, form=form, title=title, message=message, formid=formid, ref_id=ref_id, action=action, submit=submit, cancel_url=cancel_url, ajax=ajax, multipart=multipart, with_chrome=with_chrome, autosave=autosave, draft_revision=draft_revision, ) if request_is_xhr() and ajax: template = THEME_FILES[current_app.config['theme']]['ajaxform.html.jinja2'] else: template = THEME_FILES[current_app.config['theme']]['autoform.html.jinja2'] return make_response( render_template( template, form=form, title=title, message=message, formid=formid, ref_id=ref_id, action=action, submit=submit, cancel_url=cancel_url, ajax=ajax, multipart=multipart, autosave=autosave, draft_revision=draft_revision, ), 200, )
def test_UserSession_get(self): """Test for verifying UserSession's get method""" oakley = self.fixtures.oakley oakley_buid = buid() oakley_session = models.UserSession(user=oakley, ipaddr='192.168.1.2', buid=oakley_buid, user_agent=u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36', accessed_at=utcnow()) result = oakley_session.get(buid=oakley_buid) self.assertIsInstance(result, models.UserSession) self.assertEqual(result.user_id, oakley.id)
def make_bulk(cls, discount_code_base, **kwargs): """Return a discount policy for bulk discount coupons.""" return cls( discount_type=DISCOUNT_TYPE.COUPON, discount_code_base=discount_code_base, secret=buid(), **kwargs, )
def test_UserSession_get(self): """Test for verifying UserSession's get method""" oakley = self.fixtures.oakley oakley_buid = buid() oakley_session = models.UserSession(user=oakley, ipaddr='192.168.1.2', buid=oakley_buid, user_agent=u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36', accessed_at=datetime.utcnow()) result = oakley_session.get(buid=oakley_buid) self.assertIsInstance(result, models.UserSession) self.assertEqual(result.user_id, oakley.id)
def test_UserSession_authenticate(self): """Test to verify authenticate method on UserSession""" chandler = models.User(username=u'chandler', fullname=u'Chandler Bing') chandler_buid = buid() chandler_session = models.UserSession(user=chandler, ipaddr='192.168.1.4', buid=chandler_buid, user_agent=u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36', accessed_at=utcnow()) db.session.add(chandler) db.session.add(chandler_session) db.session.commit() result = models.UserSession.authenticate(chandler_buid) self.assertIsInstance(result, models.UserSession) self.assertEqual(result, chandler_session)
def test_UserSession_authenticate(self): """Test to verify authenticate method on UserSession""" chandler = models.User(username=u'chandler', fullname=u'Chandler Bing') chandler_buid = buid() chandler_session = models.UserSession(user=chandler, ipaddr='192.168.1.4', buid=chandler_buid, user_agent=u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36', accessed_at=datetime.utcnow()) db.session.add(chandler) db.session.add(chandler_session) db.session.commit() result = models.UserSession.authenticate(chandler_buid) self.assertIsInstance(result, models.UserSession) self.assertEqual(result, chandler_session)
def migrate_profile(cls, old_profile, new_profile): names = {project.name for project in new_profile.projects} for project in old_profile.projects: if project.name in names: current_app.logger.warning( "Project %r had a conflicting name in profile migration, " "so renaming by adding adding random value to name", project, ) project.name += '-' + buid() project.profile = new_profile
def new(cls, client): """ Create a new client credential and return (cred, secret). The secret is not saved in plaintext, so this is the last time it will be available. :param client: The client for which a name/secret pair is being generated """ cred = cls(client=client, name=buid()) db.session.add(cred) secret = newsecret() cred.secret_hash = 'sha256$' + sha256(secret).hexdigest() return cred, secret
def make_fixtures(): # Make a test user user = User(userid=buid(), username=u"test", fullname=u"Test") db.session.add(user) # Make some inventory # Add inventory types tshirt = InventoryType(title=u"T-shirt") sticker = InventoryType(title=u"Sticker") mug = InventoryType(title=u"Mug") db.session.add_all([tshirt, sticker, mug]) # Add inventory variant attributes # T-shirts have two, mugs have one, stickers have none tshirt_size = InventoryVariantAttribute(inventory_type=tshirt, title=u"Size") tshirt_color = InventoryVariantAttribute(inventory_type=tshirt, title=u"Color") mug_color = InventoryVariantAttribute(inventory_type=mug, title=u"Color") db.session.add_all([tshirt_size, tshirt_color, mug_color]) # Add some inventory metarefresh_tshirt = InventoryItem(inventory_type=tshirt, title=u"Meta Refresh 2013") fifthel_tshirt1 = InventoryItem(inventory_type=tshirt, title=u"The Fifth Elephant 2013 stacked elephants") fifthel_tshirt2 = InventoryItem(inventory_type=tshirt, title=u"The Fifth Elephant 2013 panel of elephants") fifthel_stickerpack = InventoryItem(inventory_type=sticker, title=u"The Fifth Elephant 2013 pack of stickers") jsfoo_mug = InventoryItem(inventory_type=mug, title=u"JSFoo 2013") db.session.add_all([metarefresh_tshirt, fifthel_tshirt1, fifthel_tshirt2, fifthel_stickerpack, jsfoo_mug]) # Add variants for inventory size_chart = [u"S", u"M", u"L", u"XL", u"XXL", u"XXXL"] # Single colour, multiple sizes for size in size_chart: db.session.add( InventoryItemVariant(inventory_item=metarefresh_tshirt, price=400, stock=10, vattrs={tshirt_color: u"Black", tshirt_size: size})) # Two colours, multiple sizes for color in [u"Black", u"Blue"]: for size in size_chart: db.session.add( InventoryItemVariant(inventory_item=fifthel_tshirt1, price=400, stock=10, vattrs={tshirt_color: color, tshirt_size: size})) # Multiple colours, multiple sizes, variable prices for color, price in [(u"Black", 400), (u"Blue", 400), (u"Green", 400), (u"Red", 400), (u"White", 350)]: for size in size_chart: db.session.add( InventoryItemVariant(inventory_item=fifthel_tshirt2, price=price, stock=10, vattrs={tshirt_color: color, tshirt_size: size})) db.session.commit()
def gen_signed_code(self, identifier=None): """ Generate a signed code. Format: ``discount_code_base.randint.signature`` """ if not identifier: identifier = buid() signer = Signer(self.secret) key = "{base}.{identifier}".format(base=self.discount_code_base, identifier=identifier) return signer.sign(key).decode('utf-8')
def test_usersession_active_sessions(self): "Test for verifying UserSession's active_sessions" piglet = self.fixtures.piglet piglet_session = models.UserSession( user=piglet, ipaddr='192.168.1.3', buid=buid(), user_agent= u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36', accessed_at=datetime.utcnow()) self.assertIsInstance(piglet.active_sessions(), list) self.assertItemsEqual(piglet.active_sessions(), [piglet_session])
def campaign_new(): form = CampaignForm() if form.validate_on_submit(): campaign = Campaign(user=g.user) form.populate_obj(campaign) campaign.name = buid() # Use a random name since it's also used in user action submit forms db.session.add(campaign) db.session.commit() flash(u"Created a campaign", 'success') return render_redirect(url_for('campaign_view', campaign=campaign.name), code=303) return render_form(form=form, title=u"Create a campaign…", submit="Next", message=u"Campaigns appear around the job board and provide a call to action for users", formid="campaign_new", cancel_url=url_for('campaign_list'), ajax=False)
def new(cls, auth_client): """ Create a new client credential and return (cred, secret). The secret is not saved in plaintext, so this is the last time it will be available. :param auth_client: The client for which a name/secret pair is being generated """ cred = cls(auth_client=auth_client, name=buid()) db.session.add(cred) secret = newsecret() cred.secret_hash = ( 'blake2b$32$' + blake2b(secret.encode(), digest_size=32).hexdigest()) return cred, secret
def test_authtoken_user(self): """ Test for checking AuthToken's user property """ crusoe = self.fixtures.crusoe client = self.fixtures.client user_session = models.UserSession(buid=buid(), user=crusoe) auth_token_with_user_session = models.AuthToken(user=crusoe, user_session=user_session) self.assertIsInstance(auth_token_with_user_session.user_session.user, models.User) self.assertEqual(auth_token_with_user_session.user_session.user, crusoe) auth_token_without_user_session = models.AuthToken(client=client, user=crusoe) self.assertIsInstance(auth_token_without_user_session._user, models.User) self.assertEqual(auth_token_without_user_session._user, crusoe)
def test_partial_refund_in_order(self): original_quantity = 5 discounted_item = Item.query.filter_by(name='t-shirt').first() total_amount = discounted_item.current_price( ).amount * original_quantity data = { 'line_items': [{ 'item_id': unicode(discounted_item.id), 'quantity': original_quantity }], 'buyer': { 'fullname': 'Testing', 'phone': '9814141414', 'email': '*****@*****.**', } } ic = ItemCollection.query.first() # make a purchase order resp = self.client.post('/ic/{ic}/order'.format(ic=ic.id), data=json.dumps(data), content_type='application/json', headers=[('X-Requested-With', 'XMLHttpRequest'), ('Origin', app.config['BASE_URL'])]) self.assertEquals(resp.status_code, 201) resp_data = json.loads(resp.data)['result'] self.assertEquals( resp_data['final_amount'], (total_amount - 5 * total_amount / decimal.Decimal(100))) order = Order.query.get(resp_data['order_id']) # Create fake payment and transaction objects online_payment = OnlinePayment(pg_paymentid='pg_testpayment', order=order) online_payment.confirm() order_amounts = order.get_amounts(LINE_ITEM_STATUS.PURCHASE_ORDER) transaction = PaymentTransaction(order=order, online_payment=online_payment, amount=order_amounts.final_amount, currency=CURRENCY.INR) db.session.add(transaction) order.confirm_sale() db.session.commit() # Mock Razorpay's API razorpay.refund_payment = MagicMock(return_value=MockResponse( response_data={'id': buid()})) valid_refund_amount = 500 valid_refund_dict = { 'amount': valid_refund_amount, 'internal_note': 'internal reference', 'note_to_user': '******', 'refund_description': 'test refund' } process_partial_refund_for_order(order, valid_refund_dict) refund_transactions = order.transactions.filter_by( transaction_type=TRANSACTION_TYPE.REFUND).all() self.assertIsInstance(refund_transactions[0].refunded_at, datetime.datetime) self.assertEquals(refund_transactions[0].amount, decimal.Decimal(valid_refund_amount)) self.assertEquals(refund_transactions[0].internal_note, valid_refund_dict['internal_note']) self.assertEquals(refund_transactions[0].note_to_user, valid_refund_dict['note_to_user']) self.assertEquals(refund_transactions[0].refund_description, valid_refund_dict['refund_description']) invalid_refund_amount = 100000000 invalid_refund_dict = {'amount': invalid_refund_amount} resp = process_partial_refund_for_order(order, invalid_refund_dict) self.assertEquals(resp.status_code, 403) refund_transactions = order.transactions.filter_by( transaction_type=TRANSACTION_TYPE.REFUND).all() self.assertEquals(refund_transactions[0].amount, decimal.Decimal(valid_refund_amount)) resp = self.make_free_order() self.assertEquals(resp.status_code, 201) resp_data = json.loads(resp.data)['result'] order = Order.query.get(resp_data.get('order_id')) invalid_refund_amount = 100000000 invalid_refund_dict = {'amount': invalid_refund_amount} refund_resp = process_partial_refund_for_order(order, invalid_refund_dict) self.assertEquals(refund_resp.status_code, 403)
def __init__(self, *args, **kwargs): self.secret = kwargs.get('secret') if kwargs.get('secret') else buid() super(DiscountPolicy, self).__init__(*args, **kwargs)
def test_cancel_line_item_in_order(self): original_quantity = 2 order_item = Item.query.filter_by(name='t-shirt').first() total_amount = order_item.current_price().amount * original_quantity data = { 'line_items': [{ 'item_id': unicode(order_item.id), 'quantity': original_quantity }], 'buyer': { 'fullname': 'Testing', 'phone': '9814141414', 'email': '*****@*****.**', } } ic = ItemCollection.query.first() # make a purchase order resp = self.client.post('/ic/{ic}/order'.format(ic=ic.id), data=json.dumps(data), content_type='application/json', headers=[('X-Requested-With', 'XMLHttpRequest'), ('Origin', app.config['BASE_URL'])]) self.assertEquals(resp.status_code, 201) resp_json = json.loads(resp.data)['result'] self.assertEquals(resp_json['final_amount'], total_amount) order = Order.query.get(resp_json['order_id']) # Create fake payment and transaction objects online_payment = OnlinePayment(pg_paymentid='pg_testpayment', order=order) online_payment.confirm() order_amounts = order.get_amounts(LINE_ITEM_STATUS.PURCHASE_ORDER) transaction = PaymentTransaction(order=order, online_payment=online_payment, amount=order_amounts.final_amount, currency=CURRENCY.INR) db.session.add(transaction) order.confirm_sale() db.session.commit() refund_amount = total_amount - 1 refund_dict = { 'amount': refund_amount, 'internal_note': 'internal reference', 'note_to_user': '******' } razorpay.refund_payment = MagicMock(return_value=MockResponse( response_data={'id': buid()})) pre_refund_transactions_count = order.refund_transactions.count() process_partial_refund_for_order(order, refund_dict) self.assertEquals(pre_refund_transactions_count + 1, order.refund_transactions.count()) first_line_item = order.line_items[0] # Mock Razorpay's API razorpay.refund_payment = MagicMock(return_value=MockResponse( response_data={'id': buid()})) process_line_item_cancellation(first_line_item) self.assertEquals(first_line_item.status, LINE_ITEM_STATUS.CANCELLED) expected_refund_amount = total_amount - refund_amount refund_transaction1 = PaymentTransaction.query.filter_by( order=order, transaction_type=TRANSACTION_TYPE.REFUND).order_by( 'created_at desc').first() self.assertEquals(refund_transaction1.amount, expected_refund_amount)
def test_cancel_line_item_in_bulk_order(self): original_quantity = 5 discounted_item = Item.query.filter_by(name='t-shirt').first() total_amount = discounted_item.current_price( ).amount * original_quantity data = { 'line_items': [{ 'item_id': unicode(discounted_item.id), 'quantity': original_quantity }], 'buyer': { 'fullname': 'Testing', 'phone': '9814141414', 'email': '*****@*****.**', } } ic = ItemCollection.query.first() # make a purchase order resp = self.client.post('/ic/{ic}/order'.format(ic=ic.id), data=json.dumps(data), content_type='application/json', headers=[('X-Requested-With', 'XMLHttpRequest'), ('Origin', app.config['BASE_URL'])]) self.assertEquals(resp.status_code, 201) resp_json = json.loads(resp.data)['result'] self.assertEquals( resp_json['final_amount'], (total_amount - 5 * total_amount / decimal.Decimal(100))) order = Order.query.get(resp_json['order_id']) # Create fake payment and transaction objects online_payment = OnlinePayment(pg_paymentid='pg_testpayment', order=order) online_payment.confirm() order_amounts = order.get_amounts(LINE_ITEM_STATUS.PURCHASE_ORDER) transaction = PaymentTransaction(order=order, online_payment=online_payment, amount=order_amounts.final_amount, currency=CURRENCY.INR) db.session.add(transaction) order.confirm_sale() db.session.commit() first_line_item = order.line_items[0] to_be_void_line_items = order.line_items[1:] precancellation_order_amount = order.net_amount # Mock Razorpay's API razorpay.refund_payment = MagicMock(return_value=MockResponse( response_data={'id': buid()})) process_line_item_cancellation(first_line_item) self.assertEquals(first_line_item.status, LINE_ITEM_STATUS.CANCELLED) for void_line_item in to_be_void_line_items: self.assertEquals(void_line_item.status, LINE_ITEM_STATUS.VOID) expected_refund_amount = precancellation_order_amount - order.get_amounts( LINE_ITEM_STATUS.CONFIRMED).final_amount refund_transaction1 = PaymentTransaction.query.filter_by( order=order, transaction_type=TRANSACTION_TYPE.REFUND).first() self.assertEquals(refund_transaction1.amount, expected_refund_amount) second_line_item = order.get_confirmed_line_items[0] razorpay.refund_payment = MagicMock(return_value=MockResponse( response_data={'id': buid()})) process_line_item_cancellation(second_line_item) self.assertEquals(second_line_item.status, LINE_ITEM_STATUS.CANCELLED) refund_transaction2 = PaymentTransaction.query.filter_by( order=order, transaction_type=TRANSACTION_TYPE.REFUND).order_by( 'created_at desc').first() self.assertEquals(refund_transaction2.amount, second_line_item.final_amount) # test failed cancellation third_line_item = order.get_confirmed_line_items[0] failed_response = make_response('', 400) failed_response.content = 'failed' razorpay.refund_payment = MagicMock(return_value=failed_response) self.assertRaises( PaymentGatewayError, lambda: process_line_item_cancellation(third_line_item)) # refund the remaining amount paid, and attempt to cancel a line item # this should cancel the line item without resulting in a new refund transaction refund_amount = order.net_amount refund_dict = { 'amount': refund_amount, 'internal_note': 'internal reference', 'note_to_user': '******' } razorpay.refund_payment = MagicMock(return_value=MockResponse( response_data={'id': buid()})) process_partial_refund_for_order(order, refund_dict) third_line_item = order.get_confirmed_line_items[0] pre_cancellation_transactions_count = order.refund_transactions.count() cancelled_refund_amount = process_line_item_cancellation( third_line_item) self.assertEquals(cancelled_refund_amount, decimal.Decimal(0)) self.assertEquals(pre_cancellation_transactions_count, order.refund_transactions.count()) # test free line item cancellation free_order_resp = self.make_free_order() free_order_resp_data = json.loads(free_order_resp.data)['result'] free_order = Order.query.get(free_order_resp_data.get('order_id')) free_line_item = free_order.line_items[0] process_line_item_cancellation(free_line_item) self.assertEquals(free_line_item.status, LINE_ITEM_STATUS.CANCELLED) self.assertEquals(free_order.transactions.count(), 0)
def test_usersession_active_sessions(self): "Test for verifying UserSession's active_sessions" piglet = self.fixtures.piglet piglet_session = models.UserSession(user=piglet, ipaddr='192.168.1.3', buid=buid(), user_agent=u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36', accessed_at=datetime.utcnow()) self.assertIsInstance(piglet.active_sessions.all(), list) self.assertItemsEqual(piglet.active_sessions.all(), [piglet_session])
def __init__(self, password=None, **kwargs): self.userid = buid() self.password = password super(User, self).__init__(**kwargs)
def __init__(self, **kwargs): super(EmailCampaign, self).__init__(**kwargs) if 'name' not in kwargs: # Use random name unless one was provided self.name = buid()
def make_bulk(cls, discount_code_base, **kwargs): """ Returns a discount policy for the purpose of issuing signed discount coupons in bulk. """ return cls(discount_type=DISCOUNT_TYPE.COUPON, discount_code_base=discount_code_base, secret=buid(), **kwargs)
def __init__(self, **kwargs): super(AuthToken, self).__init__(**kwargs) self.token = buid() if self._user: self.refresh_token = buid() self.secret = newsecret()
def test_cancel_line_item_in_order(self): original_quantity = 2 order_item = Item.query.filter_by(name='t-shirt').first() total_amount = order_item.current_price().amount * original_quantity data = { 'line_items': [{'item_id': unicode(order_item.id), 'quantity': original_quantity}], 'buyer': { 'fullname': 'Testing', 'phone': '9814141414', 'email': '*****@*****.**', } } ic = ItemCollection.query.first() # make a purchase order resp = self.client.post('/ic/{ic}/order'.format(ic=ic.id), data=json.dumps(data), content_type='application/json', headers=[('X-Requested-With', 'XMLHttpRequest'), ('Origin', app.config['BASE_URL'])]) self.assertEquals(resp.status_code, 201) resp_json = json.loads(resp.data)['result'] self.assertEquals(resp_json['final_amount'], total_amount) order = Order.query.get(resp_json['order_id']) # Create fake payment and transaction objects online_payment = OnlinePayment(pg_paymentid='pg_testpayment', order=order) online_payment.confirm() order_amounts = order.get_amounts(LINE_ITEM_STATUS.PURCHASE_ORDER) transaction = PaymentTransaction(order=order, online_payment=online_payment, amount=order_amounts.final_amount, currency=CURRENCY.INR) db.session.add(transaction) order.confirm_sale() db.session.commit() refund_amount = total_amount - 1 razorpay.refund_payment = MagicMock(return_value=MockResponse(response_data={'id': buid()})) pre_refund_transactions_count = order.refund_transactions.count() formdata = { 'amount': refund_amount, 'internal_note': 'internal reference', 'refund_description': 'receipt description', 'note_to_user': '******' } refund_form = OrderRefundForm(data=formdata, parent=order, meta={'csrf': False}) partial_refund_args = { 'order': order, 'form': refund_form, 'request_method': 'POST' } with app.request_context(self.post_env): process_partial_refund_for_order(partial_refund_args) self.assertEquals(pre_refund_transactions_count + 1, order.refund_transactions.count()) first_line_item = order.line_items[0] # Mock Razorpay's API razorpay.refund_payment = MagicMock(return_value=MockResponse(response_data={'id': buid()})) process_line_item_cancellation(first_line_item) self.assertEquals(first_line_item.status, LINE_ITEM_STATUS.CANCELLED) expected_refund_amount = total_amount - refund_amount refund_transaction1 = PaymentTransaction.query.filter_by(order=order, transaction_type=TRANSACTION_TYPE.REFUND).order_by(PaymentTransaction.created_at.desc()).first() self.assertEquals(refund_transaction1.amount, expected_refund_amount)
def __init__(self, **kwargs): super(LoginCode, self).__init__(**kwargs) self.code = buid()
def render_form( form: Form, title: str, message: str = '', formid: Optional[str] = None, submit: str = __("Submit"), cancel_url: Optional[str] = None, ajax: bool = False, with_chrome: bool = True, action: Optional[str] = None, autosave: bool = False, draft_revision: bool = None, template: str = '', ) -> Union[str, Tuple[str, int], Response]: # TODO: Use ReturnView """Render a form.""" multipart = False ref_id = 'form-' + (formid or buid()) if not action: action = request.url for field in form: if isinstance(field.widget, wtforms.widgets.FileInput): multipart = True if not with_chrome: if not template: template = THEME_FILES[ current_app.config['theme']]['ajaxform.html.jinja2'] return render_template( template, form=form, title=title, message=message, formid=formid, ref_id=ref_id, action=action, submit=submit, cancel_url=cancel_url, ajax=ajax, multipart=multipart, with_chrome=with_chrome, autosave=autosave, draft_revision=draft_revision, ) if not template and request_is_xhr() and ajax: template = THEME_FILES[ current_app.config['theme']]['ajaxform.html.jinja2'] elif not template: template = THEME_FILES[ current_app.config['theme']]['autoform.html.jinja2'] return make_response( render_template( template, form=form, title=title, message=message, formid=formid, ref_id=ref_id, action=action, submit=submit, cancel_url=cancel_url, ajax=ajax, multipart=multipart, autosave=autosave, draft_revision=draft_revision, ), 200, )
def test_partial_refund_in_order(db_session, client, all_data, post_env): original_quantity = 5 discounted_item = Item.query.filter_by(name='t-shirt').first() total_amount = discounted_item.current_price().amount * original_quantity data = { 'line_items': [ {'item_id': str(discounted_item.id), 'quantity': original_quantity} ], 'buyer': { 'fullname': 'Testing', 'phone': '9814141414', 'email': '*****@*****.**', }, } ic = ItemCollection.query.first() # make a purchase order resp = client.post( '/ic/{ic}/order'.format(ic=ic.id), data=json.dumps(data), content_type='application/json', headers=[ ('X-Requested-With', 'XMLHttpRequest'), ('Origin', app.config['BASE_URL']), ], ) assert resp.status_code == 201 resp_data = json.loads(resp.data)['result'] assert resp_data['final_amount'] == ( total_amount - 5 * total_amount / decimal.Decimal(100) ) order = Order.query.get(resp_data['order_id']) # Create fake payment and transaction objects online_payment = OnlinePayment(pg_paymentid='pg_testpayment', order=order) online_payment.confirm() order_amounts = order.get_amounts(LINE_ITEM_STATUS.PURCHASE_ORDER) transaction = PaymentTransaction( order=order, online_payment=online_payment, amount=order_amounts.final_amount, currency=CURRENCY.INR, ) db_session.add(transaction) order.confirm_sale() db_session.commit() # Mock Razorpay's API razorpay.refund_payment = MagicMock( return_value=MockResponse(response_data={'id': buid()}) ) valid_refund_amount = 500 formdata = { 'amount': valid_refund_amount, 'internal_note': 'internal reference', 'note_to_user': '******', 'refund_description': 'test refund', } refund_form = OrderRefundForm(data=formdata, parent=order, meta={'csrf': False}) partial_refund_args = { 'order': order, 'form': refund_form, 'request_method': 'POST', } with app.request_context(post_env): process_partial_refund_for_order(partial_refund_args) refund_transactions = order.transactions.filter_by( transaction_type=TRANSACTION_TYPE.REFUND ).all() assert isinstance(refund_transactions[0].refunded_at, datetime.datetime) assert refund_transactions[0].amount == decimal.Decimal(valid_refund_amount) assert refund_transactions[0].internal_note == formdata['internal_note'] assert str(refund_transactions[0].note_to_user) == formdata['note_to_user'] assert refund_transactions[0].refund_description == formdata['refund_description'] invalid_refund_amount = 100000000 formdata = { 'amount': invalid_refund_amount, } refund_form = OrderRefundForm(data=formdata, parent=order, meta={'csrf': False}) partial_refund_args = { 'order': order, 'form': refund_form, 'request_method': 'POST', } with app.request_context(post_env): resp = process_partial_refund_for_order(partial_refund_args) assert resp.status_code == 403 refund_transactions = order.transactions.filter_by( transaction_type=TRANSACTION_TYPE.REFUND ).all() assert refund_transactions[0].amount == decimal.Decimal(valid_refund_amount) resp = make_free_order(client) assert resp.status_code == 201 resp_data = json.loads(resp.data)['result'] order = Order.query.get(resp_data.get('order_id')) invalid_refund_amount = 100000000 formdata = { 'amount': invalid_refund_amount, } refund_form = OrderRefundForm(data=formdata, parent=order, meta={'csrf': False}) partial_refund_args = { 'order': order, 'form': refund_form, 'request_method': 'POST', } with app.request_context(post_env): refund_resp = process_partial_refund_for_order(partial_refund_args) assert refund_resp.status_code == 403
def test_cancel_line_item_in_bulk_order(self): original_quantity = 5 discounted_item = Item.query.filter_by(name='t-shirt').first() total_amount = discounted_item.current_price().amount * original_quantity data = { 'line_items': [{'item_id': unicode(discounted_item.id), 'quantity': original_quantity}], 'buyer': { 'fullname': 'Testing', 'phone': '9814141414', 'email': '*****@*****.**', } } ic = ItemCollection.query.first() # make a purchase order resp = self.client.post('/ic/{ic}/order'.format(ic=ic.id), data=json.dumps(data), content_type='application/json', headers=[('X-Requested-With', 'XMLHttpRequest'), ('Origin', app.config['BASE_URL'])]) self.assertEquals(resp.status_code, 201) resp_json = json.loads(resp.data)['result'] self.assertEquals(resp_json['final_amount'], (total_amount - 5 * total_amount / decimal.Decimal(100))) order = Order.query.get(resp_json['order_id']) # Create fake payment and transaction objects online_payment = OnlinePayment(pg_paymentid='pg_testpayment', order=order) online_payment.confirm() order_amounts = order.get_amounts(LINE_ITEM_STATUS.PURCHASE_ORDER) transaction = PaymentTransaction(order=order, online_payment=online_payment, amount=order_amounts.final_amount, currency=CURRENCY.INR) db.session.add(transaction) order.confirm_sale() db.session.commit() first_line_item = order.line_items[0] to_be_void_line_items = order.line_items[1:] precancellation_order_amount = order.net_amount # Mock Razorpay's API razorpay.refund_payment = MagicMock(return_value=MockResponse(response_data={'id': buid()})) process_line_item_cancellation(first_line_item) self.assertEquals(first_line_item.status, LINE_ITEM_STATUS.CANCELLED) for void_line_item in to_be_void_line_items: self.assertEquals(void_line_item.status, LINE_ITEM_STATUS.VOID) expected_refund_amount = precancellation_order_amount - order.get_amounts(LINE_ITEM_STATUS.CONFIRMED).final_amount refund_transaction1 = PaymentTransaction.query.filter_by(order=order, transaction_type=TRANSACTION_TYPE.REFUND).first() self.assertEquals(refund_transaction1.amount, expected_refund_amount) second_line_item = order.confirmed_line_items[0] razorpay.refund_payment = MagicMock(return_value=MockResponse(response_data={'id': buid()})) process_line_item_cancellation(second_line_item) self.assertEquals(second_line_item.status, LINE_ITEM_STATUS.CANCELLED) refund_transaction2 = PaymentTransaction.query.filter_by(order=order, transaction_type=TRANSACTION_TYPE.REFUND).order_by(PaymentTransaction.created_at.desc()).first() self.assertEquals(refund_transaction2.amount, second_line_item.final_amount) # test failed cancellation third_line_item = order.confirmed_line_items[0] razorpay.refund_payment = MagicMock( return_value=MockResponse( response_data={ "error": { "code": "BAD_REQUEST_ERROR", "description": "The amount is invalid", "field": "amount" } }, status_code=400 )) self.assertRaises(PaymentGatewayError, lambda: process_line_item_cancellation(third_line_item)) # refund the remaining amount paid, and attempt to cancel a line item # this should cancel the line item without resulting in a new refund transaction refund_amount = order.net_amount refund_dict = {'id': buid(), 'amount': refund_amount, 'internal_note': 'internal reference', 'note_to_user': '******'} razorpay.refund_payment = MagicMock(return_value=MockResponse(response_data=refund_dict)) formdata = { 'amount': refund_amount, 'internal_note': 'internal reference', 'refund_description': 'receipt description', 'note_to_user': '******' } refund_form = OrderRefundForm(data=formdata, parent=order, meta={'csrf': False}) partial_refund_args = { 'order': order, 'form': refund_form, 'request_method': 'POST' } with app.request_context(self.post_env): process_partial_refund_for_order(partial_refund_args) third_line_item = order.confirmed_line_items[0] pre_cancellation_transactions_count = order.refund_transactions.count() cancelled_refund_amount = process_line_item_cancellation(third_line_item) self.assertEquals(cancelled_refund_amount, decimal.Decimal(0)) self.assertEquals(pre_cancellation_transactions_count, order.refund_transactions.count()) # test free line item cancellation free_order_resp = self.make_free_order() free_order_resp_data = json.loads(free_order_resp.data)['result'] free_order = Order.query.get(free_order_resp_data.get('order_id')) free_line_item = free_order.line_items[0] process_line_item_cancellation(free_line_item) self.assertEquals(free_line_item.status, LINE_ITEM_STATUS.CANCELLED) self.assertEquals(free_order.transactions.count(), 0)
def test_cancel_line_item_in_bulk_order(db_session, client, all_data, post_env): original_quantity = 5 discounted_item = Item.query.filter_by(name='t-shirt').first() total_amount = discounted_item.current_price().amount * original_quantity data = { 'line_items': [ {'item_id': str(discounted_item.id), 'quantity': original_quantity} ], 'buyer': { 'fullname': 'Testing', 'phone': '9814141414', 'email': '*****@*****.**', }, } ic = ItemCollection.query.first() # make a purchase order resp = client.post( '/ic/{ic}/order'.format(ic=ic.id), data=json.dumps(data), content_type='application/json', headers=[ ('X-Requested-With', 'XMLHttpRequest'), ('Origin', app.config['BASE_URL']), ], ) assert resp.status_code == 201 resp_json = json.loads(resp.data)['result'] assert resp_json['final_amount'] == ( total_amount - 5 * total_amount / decimal.Decimal(100) ) order = Order.query.get(resp_json['order_id']) # Create fake payment and transaction objects online_payment = OnlinePayment(pg_paymentid='pg_testpayment', order=order) online_payment.confirm() order_amounts = order.get_amounts(LINE_ITEM_STATUS.PURCHASE_ORDER) transaction = PaymentTransaction( order=order, online_payment=online_payment, amount=order_amounts.final_amount, currency=CURRENCY.INR, ) db_session.add(transaction) order.confirm_sale() db_session.commit() first_line_item = order.line_items[0] to_be_void_line_items = order.line_items[1:] precancellation_order_amount = order.net_amount # Mock Razorpay's API razorpay.refund_payment = MagicMock( return_value=MockResponse(response_data={'id': buid()}) ) process_line_item_cancellation(first_line_item) assert first_line_item.status == LINE_ITEM_STATUS.CANCELLED for void_line_item in to_be_void_line_items: assert void_line_item.status == LINE_ITEM_STATUS.VOID expected_refund_amount = ( precancellation_order_amount - order.get_amounts(LINE_ITEM_STATUS.CONFIRMED).final_amount ) refund_transaction1 = PaymentTransaction.query.filter_by( order=order, transaction_type=TRANSACTION_TYPE.REFUND ).first() assert refund_transaction1.amount == expected_refund_amount second_line_item = order.confirmed_line_items[0] razorpay.refund_payment = MagicMock( return_value=MockResponse(response_data={'id': buid()}) ) process_line_item_cancellation(second_line_item) assert second_line_item.status == LINE_ITEM_STATUS.CANCELLED refund_transaction2 = ( PaymentTransaction.query.filter_by( order=order, transaction_type=TRANSACTION_TYPE.REFUND ) .order_by(PaymentTransaction.created_at.desc()) .first() ) assert refund_transaction2.amount == second_line_item.final_amount # test failed cancellation third_line_item = order.confirmed_line_items[0] razorpay.refund_payment = MagicMock( return_value=MockResponse( response_data={ 'error': { 'code': 'BAD_REQUEST_ERROR', 'description': "The amount is invalid", 'field': 'amount', } }, status_code=400, ) ) with pytest.raises(PaymentGatewayError): process_line_item_cancellation(third_line_item) # refund the remaining amount paid, and attempt to cancel a line item # this should cancel the line item without resulting in a new refund transaction refund_amount = order.net_amount refund_dict = { 'id': buid(), 'amount': refund_amount, 'internal_note': 'internal reference', 'note_to_user': '******', } razorpay.refund_payment = MagicMock( return_value=MockResponse(response_data=refund_dict) ) formdata = { 'amount': refund_amount, 'internal_note': 'internal reference', 'refund_description': 'receipt description', 'note_to_user': '******', } refund_form = OrderRefundForm(data=formdata, parent=order, meta={'csrf': False}) partial_refund_args = { 'order': order, 'form': refund_form, 'request_method': 'POST', } with app.request_context(post_env): process_partial_refund_for_order(partial_refund_args) third_line_item = order.confirmed_line_items[0] pre_cancellation_transactions_count = order.refund_transactions.count() cancelled_refund_amount = process_line_item_cancellation(third_line_item) assert cancelled_refund_amount == decimal.Decimal(0) assert pre_cancellation_transactions_count == order.refund_transactions.count() # test free line item cancellation free_order_resp = make_free_order(client) free_order_resp_data = json.loads(free_order_resp.data)['result'] free_order = Order.query.get(free_order_resp_data.get('order_id')) free_line_item = free_order.line_items[0] process_line_item_cancellation(free_line_item) assert free_line_item.status == LINE_ITEM_STATUS.CANCELLED assert free_order.transactions.count() == 0
def test_partial_refund_in_order(self): original_quantity = 5 discounted_item = Item.query.filter_by(name='t-shirt').first() total_amount = discounted_item.current_price().amount * original_quantity data = { 'line_items': [{'item_id': unicode(discounted_item.id), 'quantity': original_quantity}], 'buyer': { 'fullname': 'Testing', 'phone': '9814141414', 'email': '*****@*****.**', } } ic = ItemCollection.query.first() # make a purchase order resp = self.client.post('/ic/{ic}/order'.format(ic=ic.id), data=json.dumps(data), content_type='application/json', headers=[('X-Requested-With', 'XMLHttpRequest'), ('Origin', app.config['BASE_URL'])]) self.assertEquals(resp.status_code, 201) resp_data = json.loads(resp.data)['result'] self.assertEquals(resp_data['final_amount'], (total_amount - 5 * total_amount / decimal.Decimal(100))) order = Order.query.get(resp_data['order_id']) # Create fake payment and transaction objects online_payment = OnlinePayment(pg_paymentid='pg_testpayment', order=order) online_payment.confirm() order_amounts = order.get_amounts(LINE_ITEM_STATUS.PURCHASE_ORDER) transaction = PaymentTransaction(order=order, online_payment=online_payment, amount=order_amounts.final_amount, currency=CURRENCY.INR) db.session.add(transaction) order.confirm_sale() db.session.commit() # Mock Razorpay's API razorpay.refund_payment = MagicMock(return_value=MockResponse(response_data={'id': buid()})) valid_refund_amount = 500 formdata = { 'amount': valid_refund_amount, 'internal_note': 'internal reference', 'note_to_user': '******', 'refund_description': 'test refund' } refund_form = OrderRefundForm(data=formdata, parent=order, meta={'csrf': False}) partial_refund_args = { 'order': order, 'form': refund_form, 'request_method': 'POST' } with app.request_context(self.post_env): process_partial_refund_for_order(partial_refund_args) refund_transactions = order.transactions.filter_by(transaction_type=TRANSACTION_TYPE.REFUND).all() self.assertIsInstance(refund_transactions[0].refunded_at, datetime.datetime) self.assertEquals(refund_transactions[0].amount, decimal.Decimal(valid_refund_amount)) self.assertEquals(refund_transactions[0].internal_note, formdata['internal_note']) self.assertEquals(refund_transactions[0].note_to_user, formdata['note_to_user']) self.assertEquals(refund_transactions[0].refund_description, formdata['refund_description']) invalid_refund_amount = 100000000 formdata = { 'amount': invalid_refund_amount, } refund_form = OrderRefundForm(data=formdata, parent=order, meta={'csrf': False}) partial_refund_args = { 'order': order, 'form': refund_form, 'request_method': 'POST' } with app.request_context(self.post_env): resp = process_partial_refund_for_order(partial_refund_args) self.assertEquals(resp.status_code, 403) refund_transactions = order.transactions.filter_by(transaction_type=TRANSACTION_TYPE.REFUND).all() self.assertEquals(refund_transactions[0].amount, decimal.Decimal(valid_refund_amount)) resp = self.make_free_order() self.assertEquals(resp.status_code, 201) resp_data = json.loads(resp.data)['result'] order = Order.query.get(resp_data.get('order_id')) invalid_refund_amount = 100000000 formdata = { 'amount': invalid_refund_amount, } refund_form = OrderRefundForm(data=formdata, parent=order, meta={'csrf': False}) partial_refund_args = { 'order': order, 'form': refund_form, 'request_method': 'POST' } with app.request_context(self.post_env): refund_resp = process_partial_refund_for_order(partial_refund_args) self.assertEquals(refund_resp.status_code, 403)
def test_cancel_line_item_in_order(db_session, client, all_data, post_env): original_quantity = 2 order_item = Item.query.filter_by(name='t-shirt').first() total_amount = order_item.current_price().amount * original_quantity data = { 'line_items': [{'item_id': str(order_item.id), 'quantity': original_quantity}], 'buyer': { 'fullname': 'Testing', 'phone': '9814141414', 'email': '*****@*****.**', }, } ic = ItemCollection.query.first() # make a purchase order resp = client.post( '/ic/{ic}/order'.format(ic=ic.id), data=json.dumps(data), content_type='application/json', headers=[ ('X-Requested-With', 'XMLHttpRequest'), ('Origin', app.config['BASE_URL']), ], ) assert resp.status_code == 201 resp_json = json.loads(resp.data)['result'] assert resp_json['final_amount'] == total_amount order = Order.query.get(resp_json['order_id']) # Create fake payment and transaction objects online_payment = OnlinePayment(pg_paymentid='pg_testpayment', order=order) online_payment.confirm() order_amounts = order.get_amounts(LINE_ITEM_STATUS.PURCHASE_ORDER) transaction = PaymentTransaction( order=order, online_payment=online_payment, amount=order_amounts.final_amount, currency=CURRENCY.INR, ) db_session.add(transaction) order.confirm_sale() db_session.commit() refund_amount = total_amount - 1 razorpay.refund_payment = MagicMock( return_value=MockResponse(response_data={'id': buid()}) ) pre_refund_transactions_count = order.refund_transactions.count() formdata = { 'amount': refund_amount, 'internal_note': 'internal reference', 'refund_description': 'receipt description', 'note_to_user': '******', } refund_form = OrderRefundForm(data=formdata, parent=order, meta={'csrf': False}) partial_refund_args = { 'order': order, 'form': refund_form, 'request_method': 'POST', } with app.request_context(post_env): process_partial_refund_for_order(partial_refund_args) assert pre_refund_transactions_count + 1 == order.refund_transactions.count() first_line_item = order.line_items[0] # Mock Razorpay's API razorpay.refund_payment = MagicMock( return_value=MockResponse(response_data={'id': buid()}) ) process_line_item_cancellation(first_line_item) assert first_line_item.status == LINE_ITEM_STATUS.CANCELLED expected_refund_amount = total_amount - refund_amount refund_transaction1 = ( PaymentTransaction.query.filter_by( order=order, transaction_type=TRANSACTION_TYPE.REFUND ) .order_by(PaymentTransaction.created_at.desc()) .first() ) assert refund_transaction1.amount == expected_refund_amount