def test_creating_style(self): beer = BeerFactory(api_vendor_style='my style') self.assertIsNone(beer.style) url = reverse('TapListProviderStyleMapping-list'.lower()) user = UserFactory(is_staff=True) self.client.credentials(HTTP_AUTHORIZATION=f'Token {user.auth_token}') style = BeerStyleFactory() body = { 'provider_style_name': beer.api_vendor_style, 'style_id': style.id, } response = self.client.post(url, body) self.assertEqual( response.status_code, status.HTTP_201_CREATED, response.data, ) self.assertEqual( response.data['provider_style_name'], beer.api_vendor_style, response.data, ) self.assertEqual(response.data['style']['id'], style.id, response.data) beer.refresh_from_db() self.assertEqual(beer.style_id, style.id)
def test_beers(self): tap = TapFactory(venue=self.venue, beer=BeerFactory()) BeerFactory() url = f"{self.url}beers/" response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) self.assertEqual(len(response.data["results"]), 1, response.data) self.assertEqual(response.data["results"][0]["id"], tap.beer_id)
def test_beers(self): tap = TapFactory(venue=self.venue, beer=BeerFactory()) BeerFactory() url = f'{self.url}beers/' response = self.client.get(url) eq_(response.status_code, status.HTTP_200_OK, response.data) eq_(len(response.data['results']), 1, response.data) eq_(response.data['results'][0]['id'], tap.beer_id)
def test_single_beer_removed_from_draft(self, mock_retry, mock_api): beer = BeerFactory() with self.settings_context_manager(): tweet_about_beers([beer.id]) # pylint: disable=no-value-for-parameter mock_retry.assert_not_called() mock_api.assert_called_once_with( consumer_key=self.consumer_key, consumer_secret=self.consumer_secret, access_token_key=self.api_key, access_token_secret=self.api_secret, ) mock_api.return_value.PostUpdate.assert_not_called() mock_api.return_value.PostUpdates.assert_not_called() beer.refresh_from_db() self.assertTrue(beer.tweeted_about)
def test_filtering(self): beer = BeerFactory() venue = VenueFactory() TapFactory(venue=venue, beer=beer) url = f'{self.url}?taps__beer__name__istartswith={beer.name.lower()[:5]}' response = self.client.get(url) self.assertEqual(len(response.data['results']), 1) self.assertEqual(response.data['results'][0]['id'], venue.id, response.data) url = f'{self.url}?taps__beer__name={beer.name.lower()}aaaaa' response = self.client.get(url) self.assertEqual(len(response.data['results']), 0, response.data)
def test_single_beer_no_creds(self, mock_retry, mock_api): beer = BeerFactory() TapFactory(venue=self.venue, beer=beer) with self.settings( TWITTER_CONSUMER_KEY="", TWITTER_CONSUMER_SECRET="", TWITTER_ACCESS_TOKEN_KEY="", TWITTER_ACCESS_TOKEN_SECRET="", ): tweet_about_beers([beer.id]) # pylint: disable=no-value-for-parameter mock_retry.assert_not_called() mock_api.assert_not_called()
def test_single_beer_no_creds(self, mock_retry, mock_api): beer = BeerFactory() TapFactory(venue=self.venue, beer=beer) with self.settings( TWITTER_CONSUMER_KEY='', TWITTER_CONSUMER_SECRET='', TWITTER_ACCESS_TOKEN_KEY='', TWITTER_ACCESS_TOKEN_SECRET='', ): tweet_about_beers([beer.id]) mock_retry.assert_not_called() mock_api.assert_not_called()
def test_styles(self): style = BeerStyleFactory() tap = TapFactory(venue=self.venue, beer=BeerFactory(style=style)) BeerStyleFactory() url = f'{self.url}styles/' response = self.client.get(url) eq_(response.status_code, status.HTTP_200_OK, response.data) eq_(len(response.data['results']), 1, response.data) eq_(response.data['results'][0]['id'], style.id) beers = response.data['results'][0]['beers'] eq_(len(beers), 1, beers) eq_(beers[0]['id'], tap.beer_id, beers[0])
def test_single_beer_already_tweeted(self, mock_retry, mock_api): beer = BeerFactory(tweeted_about=True) TapFactory(venue=self.venue, beer=beer) with self.settings_context_manager(): tweet_about_beers([beer.id]) mock_retry.assert_not_called() mock_api.assert_called_once_with( consumer_key=self.consumer_key, consumer_secret=self.consumer_secret, access_token_key=self.api_key, access_token_secret=self.api_secret, ) mock_api.return_value.PostUpdate.assert_not_called() mock_api.return_value.PostUpdates.assert_not_called()
def test_unmapped_list(self): beer = BeerFactory(api_vendor_style='my style') url = f"{reverse('TapListProviderStyleMapping-list'.lower())}unmapped/" user = UserFactory(is_staff=True) self.client.credentials(HTTP_AUTHORIZATION=f'Token {user.auth_token}') response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) self.assertEqual(len(response.data), 1, response.data) self.assertEqual( response.data[0]['provider_style_name'], beer.api_vendor_style, response.data, )
def test_beers(self): mfg = ManufacturerFactory() beers = Beer.objects.bulk_create( BeerFactory.build(manufacturer=mfg) for dummy in range(10)) taps = Tap.objects.bulk_create( Tap( beer=beer, tap_number=index + 1, venue=self.venue, ) for index, beer in enumerate(beers)) response = self.client.get(f"{self.url}beers/") self.assertEqual(len(taps), len(beers)) self.assertEqual(Beer.objects.count(), len(beers)) self.assertEqual(response.status_code, 200, response.data) self.assertEqual(len(response.data["results"]), len(beers))
def test_invalid_gas(self): self.client.force_login(self.normal_user) VenueTapManager.objects.create(venue=self.venue, user=self.normal_user) form_data = { "beer": BeerFactory(manufacturer=ManufacturerFactory()).id, "estimated_percent_remaining": 90, "gas_type": "xenon", } with self.assertNumQueries(12): response = self.client.post(self.edit_url, data=form_data) self.assertEqual(response.status_code, 400) self.assertTemplateUsed(response, "taps/tap_form.html") self.assertIn( "Select a valid choice. xenon is not one of the available choices.", response.content.decode("utf-8"), )
def test_invalid_percent_remaining(self): self.client.force_login(self.normal_user) VenueTapManager.objects.create(venue=self.venue, user=self.normal_user) self.assertFalse(Beer.objects.exists()) form_data = { "beer": BeerFactory(manufacturer=ManufacturerFactory()).id, "estimated_percent_remaining": 101, "gas_type": "co2", } with self.assertNumQueries(12): response = self.client.post(self.edit_url, data=form_data) self.assertEqual(response.status_code, 400) self.assertTemplateUsed(response, "taps/tap_form.html") self.assertIn( "A keg cannot be more than 100% full.", response.content.decode("utf-8"), )
def setUpTestData(cls): super().setUpTestData() cls.venue = VenueFactory() cls.normal_user = UserFactory() cls.styles = Style.objects.bulk_create(StyleFactory.build_batch(50)) cls.manufacturer = ManufacturerFactory() cls.beers = Beer.objects.bulk_create( BeerFactory.build(style=style, manufacturer=cls.manufacturer) for style in cls.styles) cls.taps = Tap.objects.bulk_create( TapFactory.build( beer=beer, venue=cls.venue, tap_number=index, ) for index, beer in enumerate(cls.beers)) VenueTapManager.objects.create( user=cls.normal_user, venue=cls.venue, )
def test_superuser_valid_form_new_tap(self): self.client.force_login(UserFactory(is_superuser=True)) form_data = { "beer": BeerFactory(manufacturer=ManufacturerFactory()).id, "estimated_percent_remaining": 90, "gas_type": "co2", } with self.assertNumQueries(10): response = self.client.post(self.create_url, data=form_data) self.assertEqual(response.status_code, 302) self.assertEqual( response["Location"], reverse("venue_table", args=[self.venue.id]), ) tap = Tap.objects.exclude(id=self.existing_tap.id).get() self.assertEqual(tap.beer_id, form_data["beer"]) self.assertEqual(tap.estimated_percent_remaining, 90) self.assertEqual(tap.gas_type, "co2") self.assertEqual(Tap.objects.count(), 2)
def test_valid_form_existing_tap(self): self.client.force_login(self.normal_user) VenueTapManager.objects.create(venue=self.venue, user=self.normal_user) form_data = { "beer": BeerFactory(manufacturer=ManufacturerFactory()).id, "estimated_percent_remaining": 90, "gas_type": "co2", } with self.assertNumQueries(12): response = self.client.post(self.edit_url, data=form_data) self.assertEqual(response.status_code, 302) self.assertEqual( response["Location"], reverse("venue_table", args=[self.venue.id]), ) self.existing_tap.refresh_from_db() self.assertEqual(self.existing_tap.beer_id, form_data["beer"]) self.assertEqual(self.existing_tap.estimated_percent_remaining, 90) self.assertEqual(self.existing_tap.gas_type, "co2") self.assertEqual(Tap.objects.count(), 1)
def test_single_beer(self, mock_retry, mock_api): beer = BeerFactory() TapFactory(venue=self.venue, beer=beer) with self.settings_context_manager(): tweet_about_beers([beer.id]) # pylint: disable=no-value-for-parameter mock_retry.assert_not_called() mock_api.assert_called_once_with( consumer_key=self.consumer_key, consumer_secret=self.consumer_secret, access_token_key=self.api_key, access_token_secret=self.api_secret, ) mock_api.return_value.PostUpdate.assert_called_once_with( SINGLE_BEER_TEMPLATE.format( beer.name, "@" + beer.manufacturer.twitter_handle, beer.style.name, self.venue.name, )) mock_api.return_value.PostUpdates.assert_not_called()
def setUp(self): manufacturer = ManufacturerFactory() venue = VenueFactory() style = StyleFactory() self.beers = Beer.objects.bulk_create( BeerFactory.build( manufacturer=manufacturer, style=style, ) for _ in range(20)) self.prices = BeerPrice.objects.bulk_create( BeerPrice( # pint serving_size_id=1, price=index * 2.1, beer=beer, venue=venue, ) for index, beer in enumerate(self.beers)) self.taps = Tap.objects.bulk_create( # only for half of them TapFactory.build(beer=beer, venue=venue) for beer in self.beers[:10])
def setUp(self): self.beer = BeerFactory( untappd_url="https://untappd.com/b/omnipollo-hypnopompa/432069") self.untappd_url = "https://api.untappd.com/v4/beer/info/432069" # just enough to avoid exceptions self.json_data = json.dumps({ "response": { "beer": {} }, "meta": { "code": 200 }, }) self.limit_headers = { "Date": "Fri, 15 Nov 2019 02:24:36 GMT", "Content-Type": "application/json; charset=UTF-8", "Transfer-Encoding": "chunked", "Connection": "keep-alive", "Server": "nginx", "X-Ratelimit-Expired": "Fri, 15 Nov 2019 03:00:00 +0000", "X-Ratelimit-Limit": "100", "X-Ratelimit-Remaining": "0", "X-Auth-Type": "key", "X-API-Version": "4", "Access-Control-Allow-Methods": "GET, POST, OPTIONS, PUT", "Access-Control-Allow-Headers": "Origin,Content-Type,Accept," "X-Untappd-App,X-Untappd-App-Version", }
def test_multi_beer_more_to_come(self, mock_retry, mock_api): mfg = ManufacturerFactory() beers = Beer.objects.bulk_create( BeerFactory.build(manufacturer=mfg, style=None) for dummy in range(20)) Tap.objects.bulk_create( TapFactory.build(venue=self.venue, beer=beer) for beer in beers) with self.settings_context_manager(): tweet_about_beers([i.id for i in beers]) # pylint: disable=no-value-for-parameter beers = beers[:10] mock_retry.assert_not_called() mock_api.assert_called_once_with( consumer_key=self.consumer_key, consumer_secret=self.consumer_secret, access_token_key=self.api_key, access_token_secret=self.api_secret, ) mock_api.return_value.PostUpdates.assert_called_once() mock_api.return_value.PostUpdate.assert_not_called() call_args = mock_api.return_value.PostUpdates.call_args self.assertEqual(call_args[1], {"continuation": "…", "threaded": True}) self.assertEqual(len(call_args[0]), 1) tweet = call_args[0][0] self.assertIn( MULTI_BEER_OUTER.format(len(beers), "(10 still to come!)").strip(), tweet, ) lines = tweet.splitlines() self.assertEqual(len(lines), 1 + len(beers)) for beer, line in zip(beers, lines[1:]): self.assertIn( MULTI_BEER_INNER.format( beer.name, "@" + beer.manufacturer.twitter_handle, "unknown", self.venue.name, ), line, )
def test_valid_form_remove_beer(self): self.client.force_login(self.normal_user) VenueTapManager.objects.create(venue=self.venue, user=self.normal_user) self.existing_tap.beer = BeerFactory( manufacturer=ManufacturerFactory()) self.existing_tap.save() form_data = { "beer": "", "estimated_percent_remaining": 0.9, "gas_type": "co2", } with self.assertNumQueries(10): response = self.client.post(self.edit_url, data=form_data) self.assertEqual(response.status_code, 302) self.assertEqual( response["Location"], reverse("venue_table", args=[self.venue.id]), ) tap = Tap.objects.get() self.assertIsNone(tap.beer) self.assertIsNone(tap.estimated_percent_remaining) self.assertEqual(tap.gas_type, "")
def test_multi_beer(self, mock_retry, mock_api): mfg = ManufacturerFactory() beers = Beer.objects.bulk_create( BeerFactory.build(manufacturer=mfg, style=None) for dummy in range(10) ) Tap.objects.bulk_create( TapFactory.build(venue=self.venue, beer=beer) for beer in beers ) with self.settings_context_manager(): tweet_about_beers([i.id for i in beers]) mock_retry.assert_not_called() mock_api.assert_called_once_with( consumer_key=self.consumer_key, consumer_secret=self.consumer_secret, access_token_key=self.api_key, access_token_secret=self.api_secret, ) mock_api.return_value.PostUpdates.assert_called_once() mock_api.return_value.PostUpdate.assert_not_called() call_args = mock_api.return_value.PostUpdates.call_args self.assertEqual(call_args[1], {'continuation': '…', 'threaded': True}) self.assertEqual(len(call_args[0]), 1) tweet = call_args[0][0] self.assertIn( MULTI_BEER_OUTER.format(len(beers), '').strip(), tweet, ) lines = tweet.splitlines() self.assertEqual(len(lines), 1 + len(beers)) for beer, line in zip(beers, lines[1:]): self.assertIn(MULTI_BEER_INNER.format( beer.name, '@' + beer.manufacturer.twitter_handle, 'unknown', self.venue.name, ), line)
def test_high_ibu(self): with self.assertRaises(IntegrityError): BeerFactory(ibu=1001)
def test_negative_abv(self): with self.assertRaises(IntegrityError): BeerFactory(abv=-1)
def setUpTestData(cls): cls.normal_user = UserFactory() cls.staff_user = UserFactory(is_staff=True) cls.beer = BeerFactory() cls.url = reverse('beer-detail', kwargs={'pk': cls.beer.id})
def test_high_abv(self): with self.assertRaises(InvalidOperation): BeerFactory(abv=100.1)
def test_srm_high(self): with self.assertRaises(IntegrityError): BeerFactory(color_srm=501)
def test_srm_negative(self): with self.assertRaises(IntegrityError): BeerFactory(color_srm=-1)
def test_import_stemandstein_data(self): """Test parsing the JSON data""" for pk, html_data in self.html_data.items(): if pk == "root": url = "https://thestemandstein.com/" else: url = f"https://thestemandstein.com/Home/BeerDetails/{pk}" responses.add(responses.GET, url, body=html_data, status=200) self.assertFalse(Tap.objects.exists()) self.assertEqual(Venue.objects.count(), 1) self.assertFalse(Beer.objects.exists()) self.assertFalse(Manufacturer.objects.exists()) deleted_tap = Tap.objects.create( venue=self.venue, tap_number=3000, ) mfg = ManufacturerFactory(name="Founders") beer = BeerFactory(name="Dirty Bastard", manufacturer=mfg) other = Style.objects.create(name="other") # Create a fake shorter style name that the search for fruit ale should # ignore StyleAlternateName.objects.create(name="t Ale", style=other) style = Style.objects.create(name="Fruit Beer") StyleAlternateName.objects.create(name="Fruit Ale", style=style) for dummy in range(2): # running twice to make sure we're not double-creating args = [] opts = {} call_command("parsestemandstein", *args, **opts) self.assertEqual(Beer.objects.count(), 17) # Bell's and Founders have two each self.assertEqual(Manufacturer.objects.count(), 15) self.assertEqual(Tap.objects.count(), 17) taps = (Tap.objects.filter( venue=self.venue, tap_number__in=[1, 3, 9, 17], ).select_related( "beer__style", "beer__manufacturer", ).order_by("tap_number")) tap = taps[0] self.assertTrue( tap.beer.name.endswith("Space Blood Orange Cider"), tap.beer.name, ) self.assertEqual(tap.beer.manufacturer.location, "Sebastopol, CA") self.assertEqual(tap.beer.abv, Decimal("6.9")) self.assertEqual(tap.beer.stem_and_stein_pk, 967) prices = list(tap.beer.prices.all()) self.assertEqual(len(prices), 1) price = prices[0] self.assertEqual(price.price, 5) self.assertEqual(price.serving_size.volume_oz, 16) tap = taps[3] # this one ends with an asterisk. Make sure it's stripped. self.assertTrue( tap.beer.name.endswith("Karmeliet"), tap.beer.name, ) self.assertEqual(tap.beer.manufacturer.location, "Belgium") prices = list(tap.beer.prices.all()) self.assertEqual(len(prices), 1) price = prices[0] self.assertEqual(price.price, 8) self.assertEqual(price.serving_size.volume_oz, 10) self.assertFalse(Tap.objects.filter(id=deleted_tap.id).exists()) # make sure style stripping works tap = taps[2] self.assertEqual(tap.beer.style.name, "Scotch Ale") self.assertEqual(tap.beer.name, "Dirty Bastard") self.assertEqual(tap.beer.id, beer.id) self.assertEqual(tap.beer.manufacturer_id, mfg.id) tap = taps[1] # style is set to Fruit Ale but the beer name is preserved self.assertEqual(tap.beer.style_id, style.id) self.assertTrue(tap.beer.name.endswith("Fruit Ale"))
def test_negative_ibu(self): with self.assertRaises(IntegrityError): BeerFactory(ibu=-1)