def test_cannot_confirm_for_models_with_validator_on_model_field_if_validator_fails( self, ): # ItemSale.currency has a validator on it shop = ShopFactory() item = ItemFactory() InventoryFactory(shop=shop, item=item, quantity=10) transaction = TransactionFactory(shop=shop) data = { "transaction": transaction.id, "item": item.id, "quantity": 1, "currency": "FAKE", "total": 10.00, "_confirm_add": True, "_save": True, } response = self.client.post(reverse("admin:market_itemsale_add"), data) # Should show form with error and not confirmation page self.assertEqual(response.status_code, 200) expected_templates = [ "admin/market/itemsale/change_form.html", "admin/market/change_form.html", "admin/change_form.html", ] self.assertEqual(response.template_name, expected_templates) self.assertEqual(ItemSale.objects.count(), 0) self.assertIn("error", str(response.rendered_content)) self.assertIn("Invalid Currency", str(response.rendered_content)) # Should still ask for confirmation self.assertIn(CONFIRM_ADD, response.rendered_content)
def test_update_item(self): """ Update an item on an shopcart """ # create a known item shopcart = self._create_shopcarts(1)[0] item = ItemFactory() resp = self.app.post("/shopcarts/{}/items".format(shopcart.id), json=item.serialize(), content_type="application/json") self.assertEqual(resp.status_code, status.HTTP_201_CREATED) data = resp.get_json() logging.debug(data) item_id = data["id"] data["item_name"] = "XXXX" # send the update back resp = self.app.put("/shopcarts/{}/items/{}".format( shopcart.id, item_id), json=data, content_type="application/json") self.assertEqual(resp.status_code, status.HTTP_200_OK) # retrieve it back resp = self.app.get("/shopcarts/{}/items/{}".format( shopcart.id, item_id), content_type="application/json") self.assertEqual(resp.status_code, status.HTTP_200_OK) data = resp.get_json() logging.debug(data) self.assertEqual(data["id"], item_id) self.assertEqual(data["shopcart_id"], shopcart.id) self.assertEqual(data["item_name"], "XXXX")
def test_post_add_with_confirm_add(self): item = ItemFactory() shop = ShopFactory() data = { "shop": shop.id, "item": item.id, "quantity": 5, "_confirm_add": True, "_continue": True, } response = self.client.post(reverse("admin:market_inventory_add"), data) # Ensure not redirected (confirmation page does not redirect) self.assertEqual(response.status_code, 200) expected_templates = [ "admin/market/inventory/change_confirmation.html", "admin/market/change_confirmation.html", "admin/change_confirmation.html", ] self.assertEqual(response.template_name, expected_templates) form_data = {"shop": str(shop.id), "item": str(item.id), "quantity": str(5)} self._assertSimpleFieldFormHtml( rendered_content=response.rendered_content, fields=form_data ) self._assertSubmitHtml( rendered_content=response.rendered_content, save_action="_continue" ) # Should not have been added yet self.assertEqual(Inventory.objects.count(), 0)
def test_cannot_confirm_for_models_with_clean_overridden_if_clean_fails( self): shop = ShopFactory() item = ItemFactory() InventoryFactory(shop=shop, item=item, quantity=1) transaction = TransactionFactory(shop=shop) # Asking to buy more than the shop has in stock data = { "transaction": transaction.id, "item": item.id, "quantity": 9, "currency": "USD", "total": 10.00, "_confirm_add": True, "_save": True, } response = self.client.post(reverse("admin:market_itemsale_add"), data) # Should not have been added yet self.assertEqual(ItemSale.objects.count(), 0) # Ensure it shows the form and not the confirmation page self.assertEqual(response.status_code, 200) expected_templates = [ "admin/market/itemsale/change_form.html", "admin/market/change_form.html", "admin/change_form.html", ] self.assertEqual(response.template_name, expected_templates) self.assertTrue("error" in str(response.content)) self.assertTrue("Shop does not have enough of the item stocked" in str( response.content)) # Should still be asking for confirmation self.assertIn(CONFIRM_ADD, response.rendered_content) # Fix the issue by buying only what shop has in stock data["quantity"] = 1 # _confirm_add would still be in the POST data response = self.client.post(reverse("admin:market_itemsale_add"), data) # Should show confirmation page # Ensure not redirected (confirmation page does not redirect) self.assertEqual(response.status_code, 200) expected_templates = [ "admin/market/itemsale/change_confirmation.html", "admin/market/change_confirmation.html", "admin/change_confirmation.html", ] self.assertEqual(response.template_name, expected_templates) self._assertSubmitHtml(rendered_content=response.rendered_content)
def test_checkout_shopcart(self): """ Checkout a Shopcart REAL """ shopcart = self._create_shopcarts(1)[0] item = ItemFactory() resp = self.app.post("/shopcarts/{}/items".format(shopcart.id), json=item.serialize(), content_type=CONTENT_TYPE_JSON) self.assertEqual(resp.status_code, status.HTTP_201_CREATED) resp2 = self.app.put("/shopcarts/{}".format(shopcart.id), json=item.serialize(), content_type=CONTENT_TYPE_JSON) self.assertEqual(resp2.status_code, status.HTTP_204_NO_CONTENT)
def test_no_add_permissions(self): user = User.objects.create_user(username="******", is_staff=True) self.client.force_login(user) item = ItemFactory() shop = ShopFactory() data = {"shop": shop.id, "item": item.id, "quantity": 5, "_confirm_add": True} response = self.client.post(reverse("admin:market_inventory_add"), data) # Ensure not redirected (confirmation page does not redirect) self.assertEqual(response.status_code, 403) self.assertTrue(isinstance(response, HttpResponseForbidden)) # Should not have been added self.assertEqual(Inventory.objects.count(), 0)
def test_add_item(self): """ Add an item to a shopcart """ shopcart = self._create_shopcarts(1)[0] item = ItemFactory() resp = self.app.post("/shopcarts/{}/items".format(shopcart.id), json=item.serialize(), content_type="application/json") self.assertEqual(resp.status_code, status.HTTP_201_CREATED) data = resp.get_json() logging.debug(data) self.assertEqual(data["shopcart_id"], shopcart.id) self.assertIsNotNone(data["id"]) self.assertEqual(data["item_name"], item.item_name) self.assertEqual(data["item_quantity"], item.item_quantity) self.assertEqual(data["item_price"], item.item_price)
def test_delete_shopcart(self): """ Delete a shopcart """ shopcart = self._create_shopcarts(1)[0] item = ItemFactory() resp = self.app.post("/shopcarts/{}/items".format(shopcart.id), json=item.serialize(), content_type="application/json") self.assertEqual(resp.status_code, status.HTTP_201_CREATED) data = resp.get_json() logging.debug(data) item_id = data["id"] # send delete request resp = self.app.delete("/shopcarts/{}".format(shopcart.id), content_type="application/json") self.assertEqual(resp.status_code, status.HTTP_204_NO_CONTENT)
def test_can_confirm_for_models_with_validator_on_model_field( self, _mock_clean): # ItemSale.currency has a validator on it item = ItemFactory() transaction = TransactionFactory() data = { "transaction": transaction.id, "item": item.id, "quantity": 1, "currency": "USD", "total": 10.00, "_confirm_add": True, "_save": True, } response = self.client.post(reverse("admin:market_itemsale_add"), data) # Should not have been added yet self.assertEqual(ItemSale.objects.count(), 0) # Ensure not redirected (confirmation page does not redirect) self.assertEqual(response.status_code, 200) expected_templates = [ "admin/market/itemsale/change_confirmation.html", "admin/market/change_confirmation.html", "admin/change_confirmation.html", ] self.assertEqual(response.template_name, expected_templates) self._assertSubmitHtml(rendered_content=response.rendered_content) # Confirmation page would not have the _confirm_add sent on submit del data["_confirm_add"] # Selecting to "Yes, I'm sure" on the confirmation page # Would post to the same endpoint response = self.client.post(reverse("admin:market_itemsale_add"), data) self.assertEqual(response.status_code, 302) self.assertEqual(response.url, "/admin/market/itemsale/") self.assertEqual(ItemSale.objects.count(), 1) # Ensure that the date and timestamp saved correctly item_sale = ItemSale.objects.first() self.assertEqual(item_sale.transaction, transaction) self.assertEqual(item_sale.item, item) self.assertEqual(item_sale.currency, "USD")
def test_confirmation_fields_set_with_confirm_add(self): self.assertEqual(InventoryAdmin.confirmation_fields, ["quantity"]) item = ItemFactory() shop = ShopFactory() # Don't set quantity - let it default data = {"shop": shop.id, "item": item.id, "_confirm_add": True} response = self.client.post(reverse("admin:market_inventory_add"), data) # No confirmation needed self.assertEqual(response.status_code, 302) # Should have been added self.assertEqual(Inventory.objects.count(), 1) new_inventory = Inventory.objects.all().first() self.assertEqual(new_inventory.shop, shop) self.assertEqual(new_inventory.item, item) self.assertEqual( new_inventory.quantity, Inventory._meta.get_field("quantity").default )
def test_get_item_list(self): """ Get an item from a shopcart """ # create a known item shopcart = self._create_shopcarts(1)[0] item = ItemFactory() resp = self.app.post("/shopcarts/{}/items".format(shopcart.id), json=item.serialize(), content_type="application/json") self.assertEqual(resp.status_code, status.HTTP_201_CREATED) data = resp.get_json() logging.debug(data) shopcart_id = data["id"] # retrieve it back resp = self.app.get("/shopcarts/{}/items".format(shopcart.id), content_type="application/json") self.assertEqual(resp.status_code, status.HTTP_200_OK) data = resp.get_json() logging.debug(data)
def test_handles_to_field_not_allowed(self): item = ItemFactory() shop = ShopFactory() data = { "shop": shop.id, "item": item.id, "quantity": 5, "_confirm_add": True, TO_FIELD_VAR: "shop", } response = self.client.post(reverse("admin:market_inventory_add"), data) # Ensure not redirected (confirmation page does not redirect) self.assertEqual(response.status_code, 400) self.assertTrue(isinstance(response, HttpResponseBadRequest)) self.assertEqual(response.reason_phrase, "Bad Request") self.assertEqual( response.context.get("exception_value"), "The field shop cannot be referenced.", ) # Should not have been added self.assertEqual(Inventory.objects.count(), 0)
def test_post_change_with_confirm_change(self): item = ItemFactory(name="item") data = { "name": "name", "price": 2.0, "currency": Item.VALID_CURRENCIES[0], "id": item.id, "_confirm_change": True, "csrfmiddlewaretoken": "fake token", "_save": True, } response = self.client.post(f"/admin/market/item/{item.id}/change/", data) # Ensure not redirected (confirmation page does not redirect) self.assertEqual(response.status_code, 200) expected_templates = [ "admin/market/item/change_confirmation.html", "admin/market/change_confirmation.html", "admin/change_confirmation.html", ] self.assertEqual(response.template_name, expected_templates) form_data = { "name": "name", "price": str(2.0), # "id": str(item.id), "currency": Item.VALID_CURRENCIES[0][0], } self._assertSimpleFieldFormHtml( rendered_content=response.rendered_content, fields=form_data ) self._assertSubmitHtml( rendered_content=response.rendered_content, multipart_form=True ) # Hasn't changed item yet item.refresh_from_db() self.assertEqual(item.name, "item")
def test_file_and_image_change(self): item = ItemFactory(name="Not name") # Select files image_path = "screenshot.png" f = SimpleUploadedFile( name="test_file.jpg", content=open(image_path, "rb").read(), content_type="image/jpeg", ) i = SimpleUploadedFile( name="test_image.jpg", content=open(image_path, "rb").read(), content_type="image/jpeg", ) item.file = f item.image = i item.save() # Load the Change Item Page ItemAdmin.confirm_change = True ItemAdmin.fields = ["name", "price", "file", "image", "currency"] response = self.client.get(f"/admin/market/item/{item.id}/change/") # Should be asked for confirmation self.assertTrue(response.context_data.get("confirm_change")) self.assertIn("_confirm_change", response.rendered_content) # Upload new image and remove file i2 = SimpleUploadedFile( name="test_image2.jpg", content=open(image_path, "rb").read(), content_type="image/jpeg", ) # Click "Save And Continue" data = { "id": item.id, "name": "name", "price": 2.0, "image": i2, "file": "", "file-clear": "on", "currency": Item.VALID_CURRENCIES[0][0], "_confirm_change": True, "_continue": True, } response = self.client.post(f"/admin/market/item/{item.id}/change/", data=data) # Should be shown confirmation page self._assertSubmitHtml( rendered_content=response.rendered_content, save_action="_continue", multipart_form=True, ) # Should have cached the unsaved item cached_item = cache.get(CACHE_KEYS["object"]) self.assertIsNotNone(cached_item) # Should not have saved the changes yet self.assertEqual(Item.objects.count(), 1) item.refresh_from_db() self.assertEqual(item.name, "Not name") self.assertIsNotNone(item.file) self.assertIsNotNone(item.image) # Click "Yes, I'm Sure" del data["_confirm_change"] data["image"] = "" data[CONFIRMATION_RECEIVED] = True response = self.client.post(f"/admin/market/item/{item.id}/change/", data=data) # Should not have redirected to changelist self.assertEqual(response.url, f"/admin/market/item/{item.id}/change/") # Should have saved item self.assertEqual(Item.objects.count(), 1) saved_item = Item.objects.all().first() self.assertEqual(saved_item.name, data["name"]) self.assertEqual(saved_item.price, data["price"]) self.assertEqual(saved_item.currency, data["currency"]) self.assertFalse(saved_item.file) self.assertIsNotNone(saved_item.image) self.assertRegex(saved_item.image.name, r"test_image2.*\.jpg$") # Should have cleared cache for key in CACHE_KEYS.values(): self.assertIsNone(cache.get(key))
def test_item_factory_typing(): instance = ItemFactory() check_dataclass_typing(instance)