def test_postback(self, slumber, fake_req): self.set_secret_mock(slumber, 'f') payload = self.payload(typ=TYP_POSTBACK, extra_req={'simulate': { 'result': 'postback' }}) url = payload['request']['postbackURL'] def req_ok(req): dd = jwt.decode(req['notice'], verify=False) eq_(dd['request'], payload['request']) eq_(dd['typ'], payload['typ']) jwt.decode(req['notice'], 'f', verify=True) return True (fake_req.expects('post').with_args( url, arg.passes_test(req_ok), timeout=arg.any()).returns_fake().has_attr( text=self.trans_uuid).expects('raise_for_status')) self.notify(payload) notice = Notice.objects.get() assert notice.transaction_uuid, notice eq_(notice.success, True) eq_(notice.url, url) eq_(notice.simulated, SIMULATED_POSTBACK)
def test_paykey_amount(self, get_paykey): def check(*args, **kw): return args[0]['amount'] == Decimal('0.99') (get_paykey.expects_call() .with_args(arg.passes_test(check)) .returns(('some-pay-key', ''))) self.client.post_ajax(self.purchase_url)
def test_notify_refund_chargeback(self, fake_req): url = self.url(self.chargeback) payload = self.payload(typ="mozilla/payments/pay/chargeback/v1") def req_ok(req): dd = jwt.decode(req, verify=False) eq_(dd["request"], payload["request"]) eq_(dd["typ"], payload["typ"]) eq_(dd["response"]["transactionID"], self.trans_uuid) eq_(dd["response"]["reason"], "refund") jwt.decode(req, self.iss.get_private_key(), verify=True) return True ( fake_req.expects("post") .with_args(url, arg.passes_test(req_ok), timeout=5) .returns_fake() .has_attr(text=self.trans_uuid) .expects("raise_for_status") ) self.do_chargeback("refund") notice = Notice.objects.get() eq_(notice.transaction_uuid, self.trans_uuid) eq_(notice.success, True) eq_(notice.url, url)
def test_signed_app_response(self, fake_req, slumber): app_payment = self.payload() self.set_secret_mock(slumber, 'f') slumber.generic.product.get_object_or_404.return_value = { 'secret': 'f'} # Ensure that the JWT sent to the app for payment notification # includes the same payment data that the app originally sent. def is_valid(payload): data = jwt.decode(payload['notice'], 'f', # secret key verify=True) eq_(data['iss'], settings.NOTIFY_ISSUER) eq_(data['typ'], TYP_POSTBACK) eq_(data['request']['pricePoint'], 1) eq_(data['request']['name'], app_payment['request']['name']) eq_(data['request']['description'], app_payment['request']['description']) eq_(data['request']['productdata'], app_payment['request']['productdata']) eq_(data['request']['postbackURL'], 'http://foo.url/post') eq_(data['request']['chargebackURL'], 'http://foo.url/charge') eq_(data['response']['transactionID'], 'some:uuid') assert data['iat'] <= gmtime() + 60, ( 'Expected iat to be about now') assert data['exp'] > gmtime() + 3500, ( 'Expected exp to be about an hour from now') return True (fake_req.expects('post').with_args(arg.any(), arg.passes_test(is_valid), timeout=arg.any()) .returns_fake() .has_attr(text='some:uuid') .provides('raise_for_status')) self.notify()
def test_pay_start_error(self, fetch_prod_im, cef): self.inapp_config.addon.support_url = 'http://friendlyapp.org/support' self.inapp_config.addon.support_email = '*****@*****.**' self.inapp_config.addon.save() def inspect_msg(msg): assert 'RequestVerificationError' in msg, ( 'CEF log should have exception message') return True cef.expects_call().with_args(arg.any(), 'unknown', 'inapp_pay_error', arg.passes_test(inspect_msg), severity=arg.any()) rp = self.start(req=self.request(app_secret='invalid')) eq_(rp.status_code, 200) doc = pq(rp.content) eq_(doc('h3').text(), 'Payment Error') self.assertContains(rp, 'mailto:[email protected]') self.assertContains(rp, 'friendlyapp.org/support') log = InappPayLog.objects.get() eq_(log.action, InappPayLog._actions['EXCEPTION']) eq_(log.app_public_key, self.inapp_config.public_key) eq_(log.exception, InappPayLog._exceptions['RequestVerificationError']) assert log.session_key, 'Unexpected session_key: %r' % log.session_key assert not fetch_prod_im.delay.called, ( 'product image not fetched on error')
def test_create_not_latin_chars(self): def inspect_request(r): # NOTE: due to URL fetching, you can only raise # AssertionError here self.assertEqual( r.get_full_url(), 'http://__dummylive365service__/cgi-bin/add_song.cgi') qs = dict(cgi.parse_qsl(r.data)) self.assertEqual(qs['member_name'], "dummy_member") self.assertEqual(qs['password'], "dummy_password") self.assertEqual(qs['seconds'], '30') # c should be replaced because latin-1 can't encode that and Live365 likes latin-1 self.assertEqual(qs['title'], 'Ivan Krsti song') self.assertEqual(qs['album'], 'Ivan Krsti album') self.assertEqual(qs['artist'], 'Ivan Krsti') return True fake_urlopen = (fudge.Fake('urlopen', expect_call=True).with_args( arg.passes_test(inspect_request))) fake_response = (fake_urlopen.returns_fake().has_attr( code='200').provides('read').returns("<service response>")) with fudge.patched_context(playlists.tasks.urllib2, "urlopen", fake_urlopen): resp = self.client.post(reverse('playlists.send_track_to_live365'), {'id': self.track.key()}) fudge.verify()
def test_sync(self, fetch, tq): (fetch.expects_call().returns_fake() .has_attr(status_code=200, content=XML)) def user_data(data): user = json.loads(data['user']) eq_(user['name_first'], 'Ivan') eq_(user['name_last'], u'Krsti\u0107') eq_(user['member_id'], 1) eq_(user['nick'], u'DJ Krsti\u0107') eq_(user['email'], '*****@*****.**') return True (tq.expects('add') .with_args( url=reverse('auth.tasks.sync_user'), params=arg.passes_test(user_data), )) res = self.client.post(self.url, HTTP_X_APPENGINE_CRON='true') eq_(res.status_code, 200) eq_(UserSync.all()[0].last_sync.timetuple()[0:3], date(2012, 12, 2).timetuple()[0:3])
def test_signed_app_response(self, fake_req): app_payment = self.payload() # Ensure that the JWT sent to the app for payment notification # includes the same payment data that the app originally sent. def is_valid(payload): data = jwt.decode(payload, self.iss.get_private_key(), verify=True) eq_(data["iss"], settings.NOTIFY_ISSUER) eq_(data["aud"], self.iss.issuer_key) eq_(data["typ"], "mozilla/payments/pay/postback/v1") eq_(data["request"]["pricePoint"], 1) eq_(data["request"]["name"], app_payment["request"]["name"]) eq_(data["request"]["description"], app_payment["request"]["description"]) eq_(data["request"]["productdata"], app_payment["request"]["productdata"]) eq_(data["response"]["transactionID"], "some:uuid") assert data["iat"] <= calendar.timegm(time.gmtime()) + 60, "Expected iat to be about now" assert data["exp"] > calendar.timegm(time.gmtime()) + 3500, "Expected exp to be about an hour from now" return True ( fake_req.expects("post") .with_args(arg.any(), arg.passes_test(is_valid), timeout=arg.any()) .returns_fake() .has_attr(text="<not a valid response>") .provides("raise_for_status") ) self.notify()
def test_signed_app_response(self, urlopen): app_payment = self.payload() # Ensure that the JWT sent to the app for payment notification # includes the same payment data that the app originally sent. def is_valid(payload): data = jwt.decode(payload, self.inapp_config.private_key, verify=True) eq_(data["iss"], settings.INAPP_MARKET_ID) eq_(data["aud"], self.inapp_config.public_key) eq_(data["typ"], "mozilla/payments/pay/postback/v1") eq_(data["request"]["price"], app_payment["request"]["price"]) eq_(data["request"]["currency"], app_payment["request"]["currency"]) eq_(data["request"]["name"], app_payment["request"]["name"]) eq_(data["request"]["description"], app_payment["request"]["description"]) eq_(data["request"]["productdata"], app_payment["request"]["productdata"]) eq_(data["response"]["transactionID"], self.contrib.pk) assert data["iat"] <= calendar.timegm(time.gmtime()) + 60, "Expected iat to be about now" assert data["exp"] > calendar.timegm(time.gmtime()) + 3500, "Expected exp to be about an hour from now" return True ( urlopen.expects_call() .with_args(arg.any(), arg.passes_test(is_valid), timeout=arg.any()) .returns_fake() .expects("read") .returns("<not a valid response>") .expects("close") ) self.notify()
def test_passes(self): def isint(v): return isinstance(v, int) counter = Fake("counter").expects("increment").with_args( arg.passes_test(isint)) counter.increment(25)
def test_delete_known_track(self): resp = self.client.get(reverse('playlists_landing_page')) context = resp.context[0] tracks = [t for t in context['playlist_events']] self.assertEquals(tracks[0].artist_name, "Steely Dan") def inspect_request(r): self.assertEqual(r.get_full_url(), 'http://testapi/playlist/delete/%s' % self.track.key()) self.assertEqual(r.http_method, 'DELETE') return True fake_urlopen = (fudge.Fake('urlopen', expect_call=True) .with_args(arg.passes_test(inspect_request))) fake_response = (fake_urlopen .returns_fake() .has_attr(code='200') .provides('read') .returns("<service response>")) with fudge.patched_context(playlists.tasks.urllib2, "urlopen", fake_urlopen): resp = self.client.get(reverse('playlists_delete_event', args=[self.track.key()])) self.assertRedirects(resp, reverse('playlists_landing_page')) # simulate the redirect: resp = self.client.get(reverse('playlists_landing_page')) context = resp.context[0] tracks = [t for t in context['playlist_events']] self.assertEquals(tracks, [])
def test_prepare_pay(self, api_post): def good_data(da): da = json.loads(da) # TODO(Kumar) fix this when we have default currencies (bug 777747) eq_(da['currency'], 'USD') eq_(da['amount'], str(self.price.price)) eq_(da['app_name'], unicode(self.addon.name)) eq_(da['app_description'], unicode(self.addon.description)) eq_(da['postback_url'], absolutify(reverse('bluevia.postback'))) eq_(da['chargeback_url'], absolutify(reverse('bluevia.chargeback'))) pd = urlparse.parse_qs(da['product_data']) assert 'contrib_uuid' in pd, 'Unexpected: %s' % pd eq_(pd['addon_id'][0], str(self.addon.pk)) return True # Sample of BlueVia JWT but not complete. bluevia_jwt = {'typ': 'tu.com/payments/inapp/v1'} (api_post.expects_call() .with_args(arg.any(), data=arg.passes_test(good_data), timeout=arg.any(), headers=arg.any()) .returns(Mock(text=json.dumps(bluevia_jwt), status_code=200))) data = self.post(self.prepare_pay) cn = Contribution.objects.get(uuid=data['contrib_uuid']) eq_(cn.type, amo.CONTRIB_PENDING) eq_(cn.user, self.user) eq_(cn.price_tier, self.price) eq_(data['bluevia_jwt'], bluevia_jwt)
def test_create_not_latin_chars(self): def inspect_request(r): # NOTE: due to URL fetching, you can only raise # AssertionError here self.assertEqual(r.get_full_url(), 'http://__dummylive365service__/cgi-bin/add_song.cgi') qs = dict(cgi.parse_qsl(r.data)) self.assertEqual(qs['member_name'], "dummy_member") self.assertEqual(qs['password'], "dummy_password") self.assertEqual(qs['seconds'], '30') # c should be replaced because latin-1 can't encode that and Live365 likes latin-1 self.assertEqual(qs['title'], 'Ivan Krsti song') self.assertEqual(qs['album'], 'Ivan Krsti album') self.assertEqual(qs['artist'], 'Ivan Krsti') return True fake_urlopen = (fudge.Fake('urlopen', expect_call=True) .with_args(arg.passes_test(inspect_request))) fake_response = (fake_urlopen .returns_fake() .has_attr(code='200') .provides('read') .returns("<service response>")) with fudge.patched_context(playlists.tasks.urllib2, "urlopen", fake_urlopen): resp = self.client.post(reverse('playlists.send_track_to_live365'), { 'id': self.track.key() }) fudge.verify()
def test_updates_package_release_modified(self, db_session, tmpdir): from belt.refresh import refresh_packages modified = Delorean(datetime.datetime(1999, 10, 5), timezone='UTC') package = create_releases_for_package(tmpdir.join('lemon-3.0.tar.gz'), '1.4', '1.2.3', modified=modified.datetime) db_session.add(package) db_session.flush() original_modification_times = [rel.modified for rel in package.releases] with fudge.patch('belt.refresh.package_releases') as package_releases: (package_releases.expects_call() .with_args('lemon', '/na/lemon', arg.passes_test(version_order)) .returns([])) package = list(refresh_packages(db_session, datetime.datetime.utcnow(), '/na'))[0] new_modification_times = [rel.modified for rel in package.releases] results = [original < new for original, new in zip(original_modification_times, new_modification_times)] assert all(results)
def test_reset(self, cef): cfg = self.config(public_key='old-key', private_key='old-secret') def inspect_msg(msg): assert 'old-key' in msg, 'CEF should log old key' return True cef.expects_call().with_args(arg.any(), cfg.addon, 'inapp_reset', arg.passes_test(inspect_msg), severity=6) res = self.client.post(self.get_url(cfg.pk)) self.assertRedirects(res, self.webapp.get_dev_url('in_app_config')) old_cfg = InappConfig.objects.get(pk=cfg.pk) eq_(old_cfg.status, amo.INAPP_STATUS_REVOKED) inapp = InappConfig.objects.get(addon=self.webapp, status=amo.INAPP_STATUS_ACTIVE) eq_(inapp.chargeback_url, cfg.chargeback_url) eq_(inapp.postback_url, cfg.postback_url) assert inapp.public_key != cfg.public_key, ( 'Unexpected: %s' % inapp.public_key) pk = inapp.get_private_key() assert pk != cfg.get_private_key, ('Unexpected: %s' % pk)
def test_notify_refund_chargeback(self, urlopen): url = self.url(self.chargeback) payload = self.payload(typ='mozilla/payments/pay/chargeback/v1') def req_ok(req): dd = jwt.decode(req, verify=False) eq_(dd['request'], payload['request']) eq_(dd['typ'], payload['typ']) eq_(dd['response']['transactionID'], self.contrib.pk) eq_(dd['response']['reason'], 'refund') jwt.decode(req, self.inapp_config.get_private_key(), verify=True) return True (urlopen.expects_call().with_args(url, arg.passes_test(req_ok), timeout=5) .returns_fake() .expects('read') .returns(str(self.contrib.pk)) .expects('close')) self.do_chargeback('refund') notice = InappPayNotice.objects.get() eq_(notice.notice, amo.INAPP_NOTICE_CHARGEBACK) eq_(notice.success, True) eq_(notice.url, url) eq_(notice.payment.pk, self.payment.pk)
def test_passes_fail(self): def is_str(v): return isinstance(v, str) counter = Fake("counter").expects("set_name").with_args( arg.passes_test(is_str)) counter.set_name(25)
def test_signed_app_response(self, fake_req): app_payment = self.payload() # Ensure that the JWT sent to the app for payment notification # includes the same payment data that the app originally sent. def is_valid(payload): data = jwt.decode(payload, self.inapp_config.get_private_key(), verify=True) eq_(data['iss'], settings.INAPP_MARKET_ID) eq_(data['aud'], self.inapp_config.public_key) eq_(data['typ'], 'mozilla/payments/pay/postback/v1') eq_(data['request']['price'], app_payment['request']['price']) eq_(data['request']['currency'], app_payment['request']['currency']) eq_(data['request']['name'], app_payment['request']['name']) eq_(data['request']['description'], app_payment['request']['description']) eq_(data['request']['productdata'], app_payment['request']['productdata']) eq_(data['response']['transactionID'], self.contrib.pk) assert data['iat'] <= calendar.timegm(time.gmtime()) + 60, ( 'Expected iat to be about now') assert data['exp'] > calendar.timegm(time.gmtime()) + 3500, ( 'Expected exp to be about an hour from now') return True (fake_req.expects('post').with_args(arg.any(), arg.passes_test(is_valid), timeout=arg.any()) .has_attr(text='<not a valid response>')) self.notify()
def test_chargeback(self, slumber, fake_req): self.set_secret_mock(slumber, 'f') req = {'simulate': {'result': 'chargeback'}} payload = self.payload(typ=TYP_CHARGEBACK, extra_req=req) url = payload['request']['chargebackURL'] def req_ok(req): dd = jwt.decode(req['notice'], verify=False) eq_(dd['request'], payload['request']) eq_(dd['typ'], payload['typ']) jwt.decode(req['notice'], 'f', verify=True) return True (fake_req.expects('post').with_args(url, arg.passes_test(req_ok), timeout=arg.any()) .returns_fake() .has_attr(text=self.trans_uuid) .expects('raise_for_status')) self.notify(payload) notice = Notice.objects.get() assert notice.transaction_uuid, notice eq_(notice.success, True) eq_(notice.url, url) eq_(notice.simulated, SIMULATED_CHARGEBACK)
def test_get_geo_poetry_rate_limit(MockGeoTweets, MockMarkovGenerator): """ The get_geo_poetry method returns 429 Too Many Requests if the tweet count is below MIN_TWEETS_TO_READ. Functions tested: - L{geo_poetry_server.get_geo_poetry} """ # Temporarily set correct minimum number of tweets to read prev_min_tweets = geo_poetry_server.MIN_TWEETS_TO_READ geo_poetry_server.MIN_TWEETS_TO_READ = 3 fake_tweets_list = iter(['Tweet 1', 'Tweet 2']) fake_poetry_line = 'A Line Of CG Poetry.' def check_location_obj(obj): if not isinstance(obj, Location): return False if not obj.latitude == 0.0: return False if not obj.longitude == 0.0: return False if not obj.radius == 10: return False if not obj.imperial_units == True: return False return True def check_is_boolean(obj): return isinstance(obj, bool) (MockGeoTweets.expects_call().with_args( TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET).returns_fake().expects('Tweets').with_args( arg.passes_test(check_location_obj), arg.passes_test(check_is_boolean)).returns(fake_tweets_list)) response = client.post("/geo-poetry", data=json.dumps({ 'latitude': 0.0, 'longitude': 0.0, 'radius': 10, 'imperial_units': True }), content_type='application/json') assert response.status_code == 429 # Set MIN_TWEETS_TO_READ back to normal geo_poetry_server.MIN_TWEETS_TO_READ = prev_min_tweets
def test_paykey_invalid_currency(self, get_paykey): waffle.models.Switch.objects.create(name="currencies", active=True) def check(*args, **kw): return args[0]["currency"] == "USD" and args[0]["amount"] == Decimal("0.99") (get_paykey.expects_call().with_args(arg.passes_test(check)).returns(("some-pay-key", ""))) self.client.post_ajax(self.purchase_url, data={"tier": 0})
def test_paykey_invalid_currency(self, get_paykey): def check(*args, **kw): return (args[0]['currency'] == 'USD' and args[0]['amount'] == Decimal('0.99')) (get_paykey.expects_call() .with_args(arg.passes_test(check)) .returns(('some-pay-key', ''))) self.client.post_ajax(self.purchase_url, data={'tier': 0})
def test_paykey_default_currency(self, get_paykey): PreApprovalUser.objects.create(user=self.user, currency="BRL", paypal_key="foo") def check(*args, **kw): return args[0]["currency"] == "BRL" and args[0]["amount"] == Decimal("0.99") (get_paykey.expects_call().with_args(arg.passes_test(check)).returns(("some-pay-key", ""))) self.client.post_ajax(self.purchase_url, data={"tier": 0})
def test_paykey_pre_approval_empty(self, _call, check_purchase): check_purchase.return_value = 'COMPLETED' PreApprovalUser.objects.create(user=self.user, paypal_key='') r = lambda s: 'receiverList.receiver(0).email' in s (_call.expects_call() .with_matching_args(arg.any(), arg.passes_test(r)) .returns({'payKey': 'some-pay-key', 'paymentExecStatus': 'COMPLETED'})) self.client.post_ajax(self.purchase_url)
def test_MultipleBackend_is_passed_configured_objects(self): def is_TestableBackend(obj): return isinstance(obj, TestableBackend) def is_SomeOtherTestableBackend(obj): return isinstance(obj, SomeOtherTestableBackend) fake = fudge.Fake(backends.MultipleBackends) fake.expects('__init__').with_args(arg.passes_test(is_TestableBackend), arg.passes_test(is_SomeOtherTestableBackend)) my_backends = [self.backend_name('TestableBackend'), self.backend_name('SomeOtherTestableBackend')] settings = fudge.Fake() settings.has_attr(ARMSTRONG_EXTERNAL_VIDEO_BACKEND=my_backends) with fudge.patched_context(backends, 'MultipleBackends', fake): backends.get_backend(settings=settings)
def test_paykey_invalid_currency(self, get_paykey): waffle.models.Switch.objects.create(name='currencies', active=True) def check(*args, **kw): return (args[0]['currency'] == 'USD' and args[0]['amount'] == Decimal('0.99')) (get_paykey.expects_call() .with_args(arg.passes_test(check)) .returns(('some-pay-key', ''))) self.client.post_ajax(self.purchase_url, data={'tier': 0})
def test_get_geo_poetry_rate_limit(MockGeoTweets, MockMarkovGenerator): """ The get_geo_poetry method returns 429 Too Many Requests if the tweet count is below MIN_TWEETS_TO_READ. Functions tested: - L{geo_poetry_server.get_geo_poetry} """ # Temporarily set correct minimum number of tweets to read prev_min_tweets = geo_poetry_server.MIN_TWEETS_TO_READ geo_poetry_server.MIN_TWEETS_TO_READ = 3 fake_tweets_list = iter(['Tweet 1', 'Tweet 2']) fake_poetry_line = 'A Line Of CG Poetry.' def check_location_obj(obj): if not isinstance(obj, Location): return False if not obj.latitude == 0.0: return False if not obj.longitude == 0.0: return False if not obj.radius == 10: return False if not obj.imperial_units == True: return False return True def check_is_boolean(obj): return isinstance(obj, bool) (MockGeoTweets.expects_call() .with_args(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET) .returns_fake() .expects('Tweets').with_args(arg.passes_test(check_location_obj), arg.passes_test(check_is_boolean)) .returns(fake_tweets_list)) response = client.post("/geo-poetry", data=json.dumps({ 'latitude' : 0.0, 'longitude' : 0.0, 'radius' : 10, 'imperial_units' : True}), content_type='application/json') assert response.status_code == 429 # Set MIN_TWEETS_TO_READ back to normal geo_poetry_server.MIN_TWEETS_TO_READ = prev_min_tweets
def test_paykey_default_currency(self, get_paykey): PreApprovalUser.objects.create(user=self.user, currency='BRL', paypal_key='foo') def check(*args, **kw): return (args[0]['currency'] == 'BRL' and args[0]['amount'] == Decimal('0.99')) (get_paykey.expects_call() .with_args(arg.passes_test(check)) .returns(('some-pay-key', ''))) self.client.post_ajax(self.purchase_url, data={'tier': 0})
def test_MultipleBackend_is_passed_configured_objects(self): def is_TestableBackend(obj): return isinstance(obj, TestableBackend) def is_SomeOtherTestableBackend(obj): return isinstance(obj, SomeOtherTestableBackend) fake = fudge.Fake(backends.MultipleBackends) fake.expects('__init__').with_args( arg.passes_test(is_TestableBackend), arg.passes_test(is_SomeOtherTestableBackend)) my_backends = [ self.backend_name('TestableBackend'), self.backend_name('SomeOtherTestableBackend') ] settings = fudge.Fake() settings.has_attr(ARMSTRONG_EXTERNAL_VIDEO_BACKEND=my_backends) with fudge.patched_context(backends, 'MultipleBackends', fake): backends.get_backend(settings=settings)
def test_notify_reversal_chargeback(self, fake_req, slumber): self.set_secret_mock(slumber, 'f') def req_ok(req): dd = jwt.decode(req['notice'], verify=False) eq_(dd['response']['reason'], 'reversal') return True (fake_req.expects('post').with_args( 'http://foo.url/charge', arg.passes_test(req_ok), timeout=5).returns_fake().has_attr( text=self.trans_uuid).expects('raise_for_status')) self.do_chargeback('reversal')
def test_notify_reversal_chargeback(self, fake_req, slumber): self.set_secret_mock(slumber, 'f') def req_ok(req): dd = jwt.decode(req['notice'], verify=False) eq_(dd['response']['reason'], 'reversal') return True (fake_req.expects('post').with_args('http://foo.url/charge', arg.passes_test(req_ok), timeout=5) .returns_fake() .has_attr(text=self.trans_uuid) .expects('raise_for_status')) self.do_chargeback('reversal')
def test_notify_reversal_chargeback(self, fake_req): url = self.url(self.chargeback) def req_ok(req): dd = jwt.decode(req, verify=False) eq_(dd['response']['reason'], 'reversal') return True (fake_req.expects('post').with_args( url, arg.passes_test(req_ok), timeout=5).returns_fake().has_attr( text=str(self.contrib.pk)).expects('raise_for_status')) self.do_chargeback('reversal') notice = InappPayNotice.objects.get() eq_(notice.notice, amo.INAPP_NOTICE_CHARGEBACK) eq_(notice.last_error, '') eq_(notice.success, True)
def expected_payload(self, expected=None): def test_is_a(instance): def test(value): self.assertIsA(value, instance) return True return test payload = {} for key, value in expected.items(): if value: type_data = type(value).__mro__ if len(type_data) is 3 and type_data[-2] is type: payload[key] = arg.passes_test(test_is_a(value)) else: payload[key] = value else: payload[key] = arg.any() return payload
def test_notify_pay(self, fake_req, slumber): self.set_secret_mock(slumber, 'f') payload = self.payload(typ=TYP_POSTBACK) url = payload['request']['postbackURL'] def req_ok(req): dd = jwt.decode(req['notice'], verify=False) eq_(dd['request'], payload['request']) eq_(dd['typ'], payload['typ']) jwt.decode(req['notice'], 'f', verify=True) return True (fake_req.expects('post').with_args(url, arg.passes_test(req_ok), timeout=5) .returns_fake() .has_attr(text=self.trans_uuid) .expects('raise_for_status')) self.notify()
def test_notify_reversal_chargeback(self, urlopen): url = self.url(self.chargeback) def req_ok(req): dd = jwt.decode(req, verify=False) eq_(dd['response']['reason'], 'reversal') return True (urlopen.expects_call().with_args(url, arg.passes_test(req_ok), timeout=5) .returns_fake() .expects('read') .returns(str(self.contrib.pk)) .expects('close')) self.do_chargeback('reversal') notice = InappPayNotice.objects.get() eq_(notice.notice, amo.INAPP_NOTICE_CHARGEBACK) eq_(notice.success, True)
def test_notify_pay(self, fake_req, slumber): self.set_secret_mock(slumber, 'f') payload = self.payload(typ=TYP_POSTBACK) url = payload['request']['postbackURL'] def req_ok(req): dd = jwt.decode(req['notice'], verify=False) eq_(dd['request'], payload['request']) eq_(dd['typ'], payload['typ']) eq_(dd['response']['price']['amount'], 1) eq_(dd['response']['price']['currency'], u'USD') jwt.decode(req['notice'], 'f', verify=True) return True (fake_req.expects('post').with_args( url, arg.passes_test(req_ok), timeout=5).returns_fake().has_attr( text=self.trans_uuid).expects('raise_for_status')) self.notify()
def test_notify_refund_chargeback(self, fake_req, slumber): self.set_secret_mock(slumber, 'f') payload = self.payload(typ=TYP_CHARGEBACK) url = payload['request']['chargebackURL'] def req_ok(req): dd = jwt.decode(req['notice'], verify=False) eq_(dd['request'], payload['request']) eq_(dd['typ'], payload['typ']) eq_(dd['response']['transactionID'], self.trans_uuid) eq_(dd['response']['reason'], 'refund') jwt.decode(req['notice'], 'f', verify=True) return True (fake_req.expects('post').with_args( url, arg.passes_test(req_ok), timeout=5).returns_fake().has_attr( text=self.trans_uuid).expects('raise_for_status')) self.do_chargeback('refund')
def test_chargeback_reason(self, slumber, fake_req): self.set_secret_mock(slumber, 'f') reason = 'something' req = {'simulate': {'result': 'chargeback', 'reason': reason}} payload = self.payload(typ=TYP_CHARGEBACK, extra_req=req) url = payload['request']['chargebackURL'] def req_ok(req): dd = jwt.decode(req['notice'], verify=False) eq_(dd['request'], payload['request']) eq_(dd['response']['reason'], reason) return True (fake_req.expects('post').with_args( url, arg.passes_test(req_ok), timeout=arg.any()).returns_fake().has_attr( text=self.trans_uuid).expects('raise_for_status')) self.notify(payload)
def test_notify_reversal_chargeback(self, fake_req): url = self.url(self.chargeback) def req_ok(req): dd = jwt.decode(req, verify=False) eq_(dd['response']['reason'], 'reversal') return True (fake_req.expects('post').with_args(url, arg.passes_test(req_ok), timeout=5) .returns_fake() .has_attr(text=str(self.contrib.pk)) .expects('raise_for_status')) self.do_chargeback('reversal') notice = InappPayNotice.objects.get() eq_(notice.notice, amo.INAPP_NOTICE_CHARGEBACK) eq_(notice.last_error, '') eq_(notice.success, True)
def test_postback(self, slumber, fake_req): self.set_secret_mock(slumber, 'f') payload = self.payload(typ=TYP_POSTBACK, extra_req={'simulate': {'result': 'postback'}}) url = payload['request']['postbackURL'] def req_ok(req): dd = jwt.decode(req['notice'], verify=False) eq_(dd['request'], payload['request']) eq_(dd['typ'], payload['typ']) jwt.decode(req['notice'], 'f', verify=True, audience=self.payment_issuer) return True (fake_req.expects('post').with_args(url, arg.passes_test(req_ok), timeout=arg.any()) .returns_fake() .has_attr(text=self.trans_uuid) .expects('raise_for_status')) self.notify(payload)
def test_notify_pay(self, fake_req): url = self.url(self.postback) payload = self.payload(typ='mozilla/payments/pay/postback/v1') def req_ok(req): dd = jwt.decode(req, verify=False) eq_(dd['request'], payload['request']) eq_(dd['typ'], payload['typ']) jwt.decode(req, self.inapp_config.get_private_key(), verify=True) return True (fake_req.expects('post').with_args( url, arg.passes_test(req_ok), timeout=5).returns_fake().has_attr( text=str(self.contrib.pk)).expects('raise_for_status')) self.notify() notice = InappPayNotice.objects.get() eq_(notice.notice, amo.INAPP_NOTICE_PAY) eq_(notice.success, True) eq_(notice.url, url) eq_(notice.payment.pk, self.payment.pk)
def test_notify_refund_chargeback(self, fake_req, slumber): self.set_secret_mock(slumber, 'f') payload = self.payload(typ=TYP_CHARGEBACK) url = payload['request']['chargebackURL'] def req_ok(req): dd = jwt.decode(req['notice'], verify=False) eq_(dd['request'], payload['request']) eq_(dd['typ'], payload['typ']) eq_(dd['response']['transactionID'], self.trans_uuid) eq_(dd['response']['reason'], 'refund') jwt.decode(req['notice'], 'f', verify=True) return True (fake_req.expects('post').with_args(url, arg.passes_test(req_ok), timeout=5) .returns_fake() .has_attr(text=self.trans_uuid) .expects('raise_for_status')) self.do_chargeback('refund')
def test_notify_reversal_chargeback(self, fake_req): url = self.url(self.chargeback) def req_ok(req): dd = jwt.decode(req, verify=False) eq_(dd["response"]["reason"], "reversal") return True ( fake_req.expects("post") .with_args(url, arg.passes_test(req_ok), timeout=5) .returns_fake() .has_attr(text=self.trans_uuid) .expects("raise_for_status") ) self.do_chargeback("reversal") notice = Notice.objects.get() eq_(notice.transaction_uuid, self.trans_uuid) eq_(notice.last_error, "") eq_(notice.success, True)
def test_notify_pay(self, fake_req, slumber): self.set_secret_mock(slumber, 'f') payload = self.payload(typ=TYP_POSTBACK) url = payload['request']['postbackURL'] def req_ok(req): dd = jwt.decode(req['notice'], verify=False) eq_(dd['request'], payload['request']) eq_(dd['typ'], payload['typ']) jwt.decode(req['notice'], 'f', verify=True) return True (fake_req.expects('post').with_args( url, arg.passes_test(req_ok), timeout=5).returns_fake().has_attr( text=self.trans_uuid).expects('raise_for_status')) self.notify() notice = Notice.objects.get() eq_(notice.transaction_uuid, self.trans_uuid) eq_(notice.success, True) eq_(notice.url, url)
def test_sync(self, fetch, tq): (fetch.expects_call().returns_fake().has_attr(status_code=200, content=XML)) def user_data(data): user = json.loads(data['user']) eq_(user['name_first'], 'Ivan') eq_(user['name_last'], u'Krsti\u0107') eq_(user['member_id'], 1) eq_(user['nick'], u'DJ Krsti\u0107') eq_(user['email'], '*****@*****.**') return True (tq.expects('add').with_args( url=reverse('auth.tasks.sync_user'), params=arg.passes_test(user_data), )) res = self.client.post(self.url, HTTP_X_APPENGINE_CRON='true') eq_(res.status_code, 200) eq_(UserSync.all()[0].last_sync.timetuple()[0:3], date(2012, 12, 2).timetuple()[0:3])
def test_signed_app_response(self, fake_req, slumber): app_payment = self.payload() self.set_secret_mock(slumber, 'f') slumber.generic.product.get_object_or_404.return_value = { 'secret': 'f' } # Ensure that the JWT sent to the app for payment notification # includes the same payment data that the app originally sent. def is_valid(payload): data = jwt.decode( payload['notice'], 'f', # secret key verify=True, audience=self.payment_issuer) eq_(data['iss'], settings.NOTIFY_ISSUER) eq_(data['typ'], TYP_POSTBACK) eq_(data['request']['pricePoint'], 1) eq_(data['request']['name'], app_payment['request']['name']) eq_(data['request']['description'], app_payment['request']['description']) eq_(data['request']['productdata'], app_payment['request']['productdata']) eq_(data['request']['postbackURL'], 'http://foo.url/post') eq_(data['request']['chargebackURL'], 'http://foo.url/charge') eq_(data['response']['transactionID'], 'some:uuid') assert data['iat'] <= gmtime() + 60, ( 'Expected iat to be about now') assert data['exp'] > gmtime() + 3500, ( 'Expected exp to be about an hour from now') return True (fake_req.expects('post').with_args( arg.any(), arg.passes_test(is_valid), timeout=arg.any()).returns_fake().has_attr( text='some:uuid').provides('raise_for_status')) self.notify(payload=app_payment)
from tapes.reporting.statsd import StatsdReporter from tests.local.base import StatsTest def is_within(delta): class _(object): def of(self, expected_value): def _check(value): return abs(value - expected_value) < delta return arg.passes_test(_check) return _() is_float = arg.passes_test(lambda x: isinstance(x, float)) class StatsdReportingTestCase(StatsTest): @fudge.patch('statsd.StatsClient', 'tapes.local.meter.time') def test_statsd_reporter_periodically_sends_meter_stats_to_statsd( self, StatsClient, time): (StatsClient.expects_call().with_args( 'localhost', 8125, None).returns_fake().expects('gauge').with_args( 'some.path.total', 5).expects('timing').with_args( 'some.path.m1_rate', is_within(0.5).of(1.0)).expects('timing').with_args( 'some.path.m5_rate', is_within(0.5).of(1.0)).expects('timing').with_args( 'some.path.m15_rate', is_within(0.5).of(1.0)))
def test_get_geo_poetry_unknown_genre(MockGeoTweets, MockMarkovGenerator, MockGetSentiment, MockClientCredentials, MockSpotify): """ The get_geo_poetry method returns 400 Bad Request when Spotify returns no tracks. Functions tested: - L{geo_poetry_server.get_geo_poetry} """ # Temporarily set low enough minimum number of tweets to read prev_min_tweets = geo_poetry_server.MIN_TWEETS_TO_READ geo_poetry_server.MIN_TWEETS_TO_READ = 0 fake_tweets_list = iter(['Tweet 1', 'Tweet 2']) fake_poetry_line = 'A Line Of CG Poetry.' fake_spotify_uri = 'spotify:track:example' fake_genre = 'MyGenre' def check_location_obj(obj): if not isinstance(obj, Location): return False if not obj.latitude == 0.0: return False if not obj.longitude == 0.0: return False if not obj.radius == 10: return False if not obj.imperial_units == True: return False return True def check_is_boolean(obj): return isinstance(obj, bool) (MockGeoTweets.expects_call().with_args( TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET).returns_fake().expects('Tweets').with_args( arg.passes_test(check_location_obj), arg.passes_test(check_is_boolean)).returns(fake_tweets_list)) (MockMarkovGenerator.expects_call().with_args( ['Tweet 1', 'Tweet 2'], MARKOV_DEPTH, ':memory:').returns_fake().expects('next').times_called( POEM_LINES_TO_GENERATE).returns(fake_poetry_line)) (MockGetSentiment.expects_call().with_args('Tweet 1').returns({ 'compound': SENTIMENT_MIN_MAGNITUDE + 0.01 }).next_call().with_args('Tweet 2').returns( {'compound': -(SENTIMENT_MIN_MAGNITUDE + 0.01)})) (MockClientCredentials.expects_call().with_args( client_id=SPOTIFY_CLIENT_ID, client_secret=SPOTIFY_CLIENT_SECRET).returns('Constant')) (MockSpotify.expects_call().with_args( client_credentials_manager='Constant').returns_fake().expects( 'recommendations').with_args(seed_genres=[fake_genre], limit=1, target_instrumentalness=1.0, target_energy=SPOTIFY_DEFAULT_ENERGY, target_valence=((0.0) + 1.0) / 2.0).returns({'tracks': []})) response = client.post("/geo-poetry", data=json.dumps({ 'latitude': 0.0, 'longitude': 0.0, 'radius': 10, 'imperial_units': True, 'genre': fake_genre }), content_type='application/json') assert response.status_code == 400 # Set MIN_TWEETS_TO_READ back to normal geo_poetry_server.MIN_TWEETS_TO_READ = prev_min_tweets
def test_get_geo_poetry_min_sentiment_magnitude(MockGeoTweets, MockMarkovGenerator, MockGetSentiment, MockClientCredentials, MockSpotify): """ The get_geo_poetry method excludes sentiments with absolute value less than SENTIMENT_MIN_MAGNITUDE from the average sentiment. Functions tested: - L{geo_poetry_server.get_geo_poetry} """ # Temporarily set low enough minimum number of tweets to read prev_min_tweets = geo_poetry_server.MIN_TWEETS_TO_READ geo_poetry_server.MIN_TWEETS_TO_READ = 0 fake_tweets_list = iter(['Tweet 1', 'Tweet 2']) fake_poetry_line = 'A Line Of CG Poetry.' fake_spotify_uri = 'spotify:track:example' def check_location_obj(obj): if not isinstance(obj, Location): return False if not obj.latitude == 0.0: return False if not obj.longitude == 0.0: return False if not obj.radius == 10: return False if not obj.imperial_units == True: return False return True def check_is_boolean(obj): return isinstance(obj, bool) (MockGeoTweets.expects_call().with_args( TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET).returns_fake().expects('Tweets').with_args( arg.passes_test(check_location_obj), arg.passes_test(check_is_boolean)).returns(fake_tweets_list)) (MockMarkovGenerator.expects_call().with_args( ['Tweet 1', 'Tweet 2'], MARKOV_DEPTH, ':memory:').returns_fake().expects('next').times_called( POEM_LINES_TO_GENERATE).returns(fake_poetry_line)) (MockGetSentiment.expects_call().with_args('Tweet 1').returns({ 'compound': SENTIMENT_MIN_MAGNITUDE + 0.01 }).next_call().with_args('Tweet 2').returns( {'compound': SENTIMENT_MIN_MAGNITUDE - 0.01})) (MockClientCredentials.expects_call().with_args( client_id=SPOTIFY_CLIENT_ID, client_secret=SPOTIFY_CLIENT_SECRET).returns('Constant')) (MockSpotify.expects_call().with_args( client_credentials_manager='Constant').returns_fake().expects( 'recommendations').with_args( seed_genres=[SPOTIFY_DEFAULT_GENRE], limit=1, target_instrumentalness=1.0, target_energy=SPOTIFY_DEFAULT_ENERGY, target_valence=((SENTIMENT_MIN_MAGNITUDE + 0.01) + 1.0) / 2.0).returns({'tracks': [{ 'uri': fake_spotify_uri }]})) response = client.post("/geo-poetry", data=json.dumps({ 'latitude': 0.0, 'longitude': 0.0, 'radius': 10, 'imperial_units': True }), content_type='application/json') response_json = json.loads(response.get_data()) assert response.status_code == 200 assert response_json[RESPONSE_KEY_POETRY] == '\n'.join( [fake_poetry_line for _ in range(POEM_LINES_TO_GENERATE)]) assert response_json[RESPONSE_KEY_TWEETS_READ_COUNT] == 2 assert response_json[ RESPONSE_KEY_AVG_SENTIMENT] == SENTIMENT_MIN_MAGNITUDE + 0.01 assert response_json[RESPONSE_KEY_TRACK] == fake_spotify_uri assert response_json[RESPONSE_KEY_GENRE] == SPOTIFY_DEFAULT_GENRE # Set MIN_TWEETS_TO_READ back to normal geo_poetry_server.MIN_TWEETS_TO_READ = prev_min_tweets
def of(self, expected_value): def _check(value): return abs(value - expected_value) < delta return arg.passes_test(_check)