Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

test_product.py 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. import datetime
  2. import os
  3. import shutil
  4. from PIL import Image
  5. from django.conf import settings
  6. from django.urls import reverse
  7. from django.utils import timezone
  8. from oscar.test import factories
  9. from oscar.test.testcases import WebTestCase
  10. from oscar.core.compat import get_user_model
  11. from oscar.core.loading import get_model
  12. from oscar.apps.catalogue.models import Product, ProductAttribute
  13. from oscar.test.factories import (
  14. CategoryFactory, ProductFactory, ProductAttributeFactory,
  15. ProductClassFactory)
  16. from six import BytesIO
  17. from webtest import Upload
  18. User = get_user_model()
  19. ProductImage = get_model('catalogue', 'ProductImage')
  20. class ProductWebTest(WebTestCase):
  21. is_staff = True
  22. def setUp(self):
  23. self.user = User.objects.create_user(username='testuser',
  24. email='test@email.com',
  25. password='somefancypassword')
  26. self.user.is_staff = self.is_staff
  27. self.user.save()
  28. def get(self, url, **kwargs):
  29. kwargs['user'] = self.user
  30. return self.app.get(url, **kwargs)
  31. class TestGatewayPage(ProductWebTest):
  32. is_staff = True
  33. def test_redirects_to_list_page_when_no_query_param(self):
  34. url = reverse('dashboard:catalogue-product-create')
  35. response = self.get(url)
  36. self.assertRedirects(response,
  37. reverse('dashboard:catalogue-product-list'))
  38. def test_redirects_to_list_page_when_invalid_query_param(self):
  39. url = reverse('dashboard:catalogue-product-create')
  40. response = self.get(url + '?product_class=bad')
  41. self.assertRedirects(response,
  42. reverse('dashboard:catalogue-product-list'))
  43. def test_redirects_to_form_page_when_valid_query_param(self):
  44. pclass = ProductClassFactory(name='Books', slug='books')
  45. url = reverse('dashboard:catalogue-product-create')
  46. response = self.get(url + '?product_class=%s' % pclass.pk)
  47. expected_url = reverse('dashboard:catalogue-product-create',
  48. kwargs={'product_class_slug': pclass.slug})
  49. self.assertRedirects(response, expected_url)
  50. class TestCreateParentProduct(ProductWebTest):
  51. is_staff = True
  52. def setUp(self):
  53. self.pclass = ProductClassFactory(name='Books', slug='books')
  54. super().setUp()
  55. def submit(self, title=None, category=None, upc=None):
  56. url = reverse('dashboard:catalogue-product-create',
  57. kwargs={'product_class_slug': self.pclass.slug})
  58. product_form = self.get(url).form
  59. product_form['title'] = title
  60. product_form['upc'] = upc
  61. product_form['structure'] = 'parent'
  62. if category:
  63. product_form['productcategory_set-0-category'] = category.id
  64. return product_form.submit()
  65. def test_title_is_required(self):
  66. response = self.submit(title='')
  67. self.assertContains(response, "must have a title")
  68. self.assertEqual(Product.objects.count(), 0)
  69. def test_requires_a_category(self):
  70. response = self.submit(title="Nice T-Shirt")
  71. self.assertContains(response, "must have at least one category")
  72. self.assertEqual(Product.objects.count(), 0)
  73. def test_for_smoke(self):
  74. category = CategoryFactory()
  75. response = self.submit(title='testing', category=category)
  76. self.assertIsRedirect(response)
  77. self.assertEqual(Product.objects.count(), 1)
  78. def test_doesnt_allow_duplicate_upc(self):
  79. ProductFactory(parent=None, upc="12345")
  80. category = CategoryFactory()
  81. self.assertTrue(Product.objects.get(upc="12345"))
  82. response = self.submit(title="Nice T-Shirt", category=category,
  83. upc="12345")
  84. self.assertEqual(Product.objects.count(), 1)
  85. self.assertNotEqual(Product.objects.get(upc='12345').title,
  86. 'Nice T-Shirt')
  87. self.assertContains(response,
  88. "Product with this UPC already exists.")
  89. class TestCreateChildProduct(ProductWebTest):
  90. is_staff = True
  91. def setUp(self):
  92. self.pclass = ProductClassFactory(name='Books', slug='books')
  93. self.parent = ProductFactory(structure='parent', stockrecords=[])
  94. super().setUp()
  95. def test_categories_are_not_required(self):
  96. url = reverse('dashboard:catalogue-product-create-child',
  97. kwargs={'parent_pk': self.parent.pk})
  98. page = self.get(url)
  99. product_form = page.form
  100. product_form['title'] = expected_title = 'Nice T-Shirt'
  101. product_form.submit()
  102. try:
  103. product = Product.objects.get(title=expected_title)
  104. except Product.DoesNotExist:
  105. self.fail('creating a child product did not work')
  106. self.assertEqual(product.parent, self.parent)
  107. class TestProductUpdate(ProductWebTest):
  108. def test_product_update_form(self):
  109. self.product = factories.ProductFactory()
  110. url = reverse('dashboard:catalogue-product',
  111. kwargs={'pk': self.product.id})
  112. page = self.get(url)
  113. product_form = page.form
  114. product_form['title'] = expected_title = 'Nice T-Shirt'
  115. page = product_form.submit()
  116. product = Product.objects.get(id=self.product.id)
  117. self.assertEqual(page.context['product'], self.product)
  118. self.assertEqual(product.title, expected_title)
  119. class TestProductClass(ProductWebTest):
  120. def setUp(self):
  121. super().setUp()
  122. self.pclass = ProductClassFactory(name='T-Shirts', slug='tshirts')
  123. for attribute_type, __ in ProductAttribute.TYPE_CHOICES:
  124. values = {
  125. 'type': attribute_type, 'code': attribute_type,
  126. 'product_class': self.pclass, 'name': attribute_type,
  127. }
  128. if attribute_type == ProductAttribute.OPTION:
  129. option_group = factories.AttributeOptionGroupFactory()
  130. self.option = factories.AttributeOptionFactory(group=option_group)
  131. values['option_group'] = option_group
  132. elif attribute_type == ProductAttribute.MULTI_OPTION:
  133. option_group = factories.AttributeOptionGroupFactory()
  134. self.multi_option = factories.AttributeOptionFactory(group=option_group)
  135. values['option_group'] = option_group
  136. ProductAttributeFactory(**values)
  137. self.product = factories.ProductFactory(product_class=self.pclass)
  138. self.url = reverse('dashboard:catalogue-product',
  139. kwargs={'pk': self.product.id})
  140. def test_product_update_attribute_values(self):
  141. page = self.get(self.url)
  142. product_form = page.form
  143. # Send string field values due to an error
  144. # in the Webtest during multipart form encode.
  145. product_form['attr_text'] = 'test1'
  146. product_form['attr_integer'] = '1'
  147. product_form['attr_float'] = '1.2'
  148. product_form['attr_boolean'] = 'yes'
  149. product_form['attr_richtext'] = 'longread'
  150. product_form['attr_date'] = '2016-10-12'
  151. product_form.submit()
  152. # Reloading model instance to re-initiate ProductAttributeContainer
  153. # with new attributes.
  154. self.product = Product.objects.get(pk=self.product.id)
  155. self.assertEqual(self.product.attr.text, 'test1')
  156. self.assertEqual(self.product.attr.integer, 1)
  157. self.assertEqual(self.product.attr.float, 1.2)
  158. self.assertTrue(self.product.attr.boolean)
  159. self.assertEqual(self.product.attr.richtext, 'longread')
  160. self.assertEqual(self.product.attr.date, datetime.date(2016, 10, 12))
  161. page = self.get(self.url)
  162. product_form = page.form
  163. product_form['attr_text'] = 'test2'
  164. product_form['attr_integer'] = '2'
  165. product_form['attr_float'] = '5.2'
  166. product_form['attr_boolean'] = ''
  167. product_form['attr_richtext'] = 'article'
  168. product_form['attr_date'] = '2016-10-10'
  169. product_form.submit()
  170. self.product = Product.objects.get(pk=self.product.id)
  171. self.assertEqual(self.product.attr.text, 'test2')
  172. self.assertEqual(self.product.attr.integer, 2)
  173. self.assertEqual(self.product.attr.float, 5.2)
  174. self.assertFalse(self.product.attr.boolean)
  175. self.assertEqual(self.product.attr.richtext, 'article')
  176. self.assertEqual(self.product.attr.date, datetime.date(2016, 10, 10))
  177. class TestProductImages(ProductWebTest):
  178. def setUp(self):
  179. super().setUp()
  180. self.product = factories.ProductFactory()
  181. self.url = reverse('dashboard:catalogue-product',
  182. kwargs={'pk': self.product.id})
  183. self.image_folder = timezone.now().strftime(settings.OSCAR_IMAGE_FOLDER)
  184. def tearDown(self):
  185. root_image_folder = self.image_folder.split(os.sep)[0]
  186. shutil.rmtree(root_image_folder, ignore_errors=True)
  187. def generate_test_image(self, name):
  188. tempfile = BytesIO()
  189. image = Image.new("RGBA", size=(50, 50), color=(256, 0, 0))
  190. image.save(tempfile, "PNG")
  191. tempfile.seek(0)
  192. return tempfile.read()
  193. def test_product_images_upload(self):
  194. page = self.get(self.url)
  195. product_form = page.form
  196. product_form['images-0-original'] = Upload('image1.png', self.generate_test_image('image1.png'), 'image/png')
  197. product_form['images-1-original'] = Upload('image2.png', self.generate_test_image('image2.png'), 'image/png')
  198. product_form.submit(name='action', value='continue').follow()
  199. self.product = Product.objects.get(pk=self.product.id)
  200. self.assertEqual(self.product.images.count(), 2)
  201. page = self.get(self.url)
  202. product_form = page.form
  203. product_form['images-2-original'] = Upload('image3.png', self.generate_test_image('image3.png'), 'image/png')
  204. product_form.submit()
  205. self.product = Product.objects.get(pk=self.product.id)
  206. self.assertEqual(self.product.images.count(), 3)
  207. images = self.product.images.all()
  208. self.assertEqual(images[0].original.name, os.path.join(self.image_folder, 'image1.png'))
  209. self.assertEqual(images[0].display_order, 0)
  210. self.assertEqual(images[1].original.name, os.path.join(self.image_folder, 'image2.png'))
  211. self.assertEqual(images[1].display_order, 1)
  212. self.assertEqual(images[2].original.name, os.path.join(self.image_folder, 'image3.png'))
  213. self.assertEqual(images[2].display_order, 2)
  214. def test_product_images_reordering(self):
  215. self.images = factories.ProductImageFactory.create_batch(3, product=self.product)
  216. image_ids = list(self.product.images.values_list('id', flat=True))
  217. self.assertEqual(image_ids, [3, 2, 1])
  218. page = self.get(self.url)
  219. product_form = page.form
  220. product_form['images-0-display_order'] = '5'
  221. product_form['images-1-display_order'] = '3'
  222. product_form['images-2-display_order'] = '4'
  223. product_form.submit()
  224. self.product = Product.objects.get(pk=self.product.id)
  225. display_orders = list(self.product.images.values_list('display_order', flat=True))
  226. image_ids = list(self.product.images.values_list('id', flat=True))
  227. self.assertEqual(display_orders, [0, 1, 2])
  228. self.assertEqual(image_ids, [2, 1, 3])