You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_range.py 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. import random
  2. from django.contrib.messages.constants import SUCCESS, WARNING
  3. from django.test import TestCase
  4. from django.urls import reverse
  5. from webtest.forms import Upload
  6. from oscar.apps.dashboard.ranges import forms
  7. from oscar.apps.offer.models import Range, RangeProductFileUpload
  8. from oscar.test.factories import create_product
  9. from oscar.test.testcases import WebTestCase
  10. class RangeProductFormTests(TestCase):
  11. def setUp(self):
  12. self.range = Range.objects.create(name='dummy')
  13. def tearDown(self):
  14. Range.objects.all().delete()
  15. def submit_form(self, data):
  16. return forms.RangeProductForm(self.range, data)
  17. def test_either_query_or_file_must_be_submitted(self):
  18. form = self.submit_form({'query': ''})
  19. self.assertFalse(form.is_valid())
  20. def test_non_match_becomes_error(self):
  21. form = self.submit_form({'query': '123123'})
  22. self.assertFalse(form.is_valid())
  23. def test_matching_query_is_valid(self):
  24. create_product(partner_sku='123123')
  25. form = self.submit_form({'query': '123123'})
  26. self.assertTrue(form.is_valid())
  27. def test_passing_form_return_product_list(self):
  28. product = create_product(partner_sku='123123')
  29. form = self.submit_form({'query': '123123'})
  30. form.is_valid()
  31. self.assertEqual(1, len(form.get_products()))
  32. self.assertEqual(product.id, form.get_products()[0].id)
  33. def test_missing_skus_are_available(self):
  34. create_product(partner_sku='123123')
  35. form = self.submit_form({'query': '123123, 123xxx'})
  36. form.is_valid()
  37. self.assertEqual(1, len(form.get_missing_skus()))
  38. self.assertTrue('123xxx' in form.get_missing_skus())
  39. def test_only_dupes_is_invalid(self):
  40. product = create_product(partner_sku='123123')
  41. self.range.add_product(product)
  42. form = self.submit_form({'query': '123123'})
  43. self.assertFalse(form.is_valid())
  44. def test_dupe_skus_are_available(self):
  45. product = create_product(partner_sku='123123')
  46. create_product(partner_sku='123124')
  47. self.range.add_product(product)
  48. form = self.submit_form({'query': '123123, 123124'})
  49. self.assertTrue(form.is_valid())
  50. self.assertTrue('123123' in form.get_duplicate_skus())
  51. class RangeProductViewTest(WebTestCase):
  52. is_staff = True
  53. def setUp(self):
  54. super().setUp()
  55. self.range = Range.objects.create(name='dummy')
  56. self.url = reverse('dashboard:range-products', args=(self.range.id,))
  57. self.product1 = create_product(
  58. title='Product 1', partner_sku='123123', partner_name='Partner 1'
  59. )
  60. self.product2 = create_product(
  61. title='Product 2', partner_sku='123123', partner_name='Partner 2'
  62. )
  63. self.product3 = create_product(partner_sku='456')
  64. self.product4 = create_product(partner_sku='789')
  65. self.parent = create_product(upc="1234", structure="parent")
  66. self.child1 = create_product(upc="1234.345", structure="child", parent=self.parent)
  67. self.child2 = create_product(upc="1234-345", structure="child", parent=self.parent)
  68. def test_upload_file_with_skus(self):
  69. range_products_page = self.get(self.url)
  70. form = range_products_page.forms[0]
  71. form['file_upload'] = Upload('new_skus.txt', b'456')
  72. form.submit().follow()
  73. all_products = self.range.all_products()
  74. self.assertEqual(len(all_products), 1)
  75. self.assertTrue(self.product3 in all_products)
  76. range_product_file_upload = RangeProductFileUpload.objects.get()
  77. self.assertEqual(range_product_file_upload.range, self.range)
  78. self.assertEqual(range_product_file_upload.num_new_skus, 1)
  79. self.assertEqual(range_product_file_upload.status,
  80. RangeProductFileUpload.PROCESSED)
  81. self.assertEqual(range_product_file_upload.size, 3)
  82. def test_upload_excluded_file_with_skus(self):
  83. excluded_products = self.range.excluded_products.all()
  84. self.assertEqual(len(excluded_products), 0)
  85. self.assertFalse(self.product3 in excluded_products)
  86. # Upload the product
  87. range_products_page = self.get(self.url)
  88. form = range_products_page.forms[1]
  89. form['file_upload'] = Upload('new_skus.txt', b'456')
  90. form.submit().follow()
  91. excluded_products = self.range.excluded_products.all()
  92. self.assertEqual(len(excluded_products), 1)
  93. self.assertTrue(self.product3 in excluded_products)
  94. range_product_file_upload = RangeProductFileUpload.objects.get()
  95. self.assertEqual(range_product_file_upload.range, self.range)
  96. self.assertEqual(range_product_file_upload.num_new_skus, 1)
  97. self.assertEqual(range_product_file_upload.status,
  98. RangeProductFileUpload.PROCESSED)
  99. self.assertEqual(range_product_file_upload.size, 3)
  100. def test_upload_multiple_excluded_file_with_skus(self):
  101. excluded_products = self.range.excluded_products.all()
  102. self.assertEqual(len(excluded_products), 0)
  103. self.assertFalse(self.product3 in excluded_products)
  104. self.assertFalse(self.product4 in excluded_products)
  105. # Upload the products
  106. range_products_page = self.get(self.url)
  107. form = range_products_page.forms[1]
  108. form['file_upload'] = Upload('new_skus.txt', b'456,789')
  109. form.submit().follow()
  110. excluded_products = self.range.excluded_products.all()
  111. self.assertEqual(len(excluded_products), 2)
  112. self.assertTrue(self.product3 in excluded_products)
  113. self.assertTrue(self.product4 in excluded_products)
  114. range_product_file_upload = RangeProductFileUpload.objects.get()
  115. self.assertEqual(range_product_file_upload.range, self.range)
  116. self.assertEqual(range_product_file_upload.num_new_skus, 2)
  117. self.assertEqual(range_product_file_upload.status,
  118. RangeProductFileUpload.PROCESSED)
  119. self.assertEqual(range_product_file_upload.size, 7)
  120. def test_exclude_skus_textarea_form_field(self):
  121. excluded_products = self.range.excluded_products.all()
  122. self.assertEqual(len(excluded_products), 0)
  123. self.assertFalse(self.product3 in excluded_products)
  124. range_products_page = self.get(self.url)
  125. form = range_products_page.forms[1]
  126. form['query'] = '456'
  127. form.submit().follow()
  128. excluded_products = self.range.excluded_products.all()
  129. self.assertEqual(len(excluded_products), 1)
  130. self.assertTrue(self.product3 in excluded_products)
  131. def test_exclude_multiple_skus_textarea_form_field(self):
  132. excluded_products = self.range.excluded_products.all()
  133. self.assertEqual(len(excluded_products), 0)
  134. self.assertFalse(self.product3 in excluded_products)
  135. self.assertFalse(self.product4 in excluded_products)
  136. range_products_page = self.get(self.url)
  137. form = range_products_page.forms[1]
  138. form['query'] = '456,789'
  139. form.submit().follow()
  140. excluded_products = self.range.excluded_products.all()
  141. self.assertEqual(len(excluded_products), 2)
  142. self.assertTrue(self.product3 in excluded_products)
  143. self.assertTrue(self.product4 in excluded_products)
  144. def test_dupe_skus_warning(self):
  145. self.range.add_product(self.product3)
  146. range_products_page = self.get(self.url)
  147. form = range_products_page.forms[0]
  148. form['query'] = '456'
  149. response = form.submit()
  150. self.assertEqual(list(response.context['messages']), [])
  151. self.assertEqual(
  152. response.context['form'].errors['query'],
  153. ['The products with SKUs or UPCs matching 456 have already been added to this range']
  154. )
  155. form = response.forms[0]
  156. form['query'] = '456, 789'
  157. response = form.submit().follow()
  158. messages = list(response.context['messages'])
  159. self.assertEqual(len(messages), 2)
  160. self.assertEqual(messages[0].level, SUCCESS)
  161. self.assertEqual(messages[0].message, '1 product has been added to this range')
  162. self.assertEqual(messages[1].level, WARNING)
  163. self.assertEqual(
  164. messages[1].message,
  165. 'The products with SKUs or UPCs matching 456 have already been added to this range'
  166. )
  167. def test_dupe_excluded_skus_warning(self):
  168. self.range.add_product(self.product3)
  169. self.range.add_product(self.product4)
  170. self.range.excluded_products.add(self.product3)
  171. range_products_page = self.get(self.url)
  172. form = range_products_page.forms[2]
  173. form['query'] = '456'
  174. response = form.submit()
  175. self.assertEqual(list(response.context['messages']), [])
  176. self.assertEqual(
  177. response.context['form_excluded'].errors['query'],
  178. ['The products with SKUs or UPCs matching 456 have already been excluded from this range']
  179. )
  180. form = response.forms[2]
  181. form['query'] = '456, 789'
  182. response = form.submit().follow()
  183. messages = list(response.context['messages'])
  184. self.assertEqual(len(messages), 2)
  185. self.assertEqual(messages[0].level, SUCCESS)
  186. self.assertEqual(messages[0].message, '1 product has been excluded from this range')
  187. self.assertEqual(messages[1].level, WARNING)
  188. self.assertEqual(
  189. messages[1].message,
  190. 'The products with SKUs or UPCs matching 456 have already been excluded from this range'
  191. )
  192. def test_missing_skus_warning(self):
  193. range_products_page = self.get(self.url)
  194. form = range_products_page.forms[0]
  195. form['query'] = '321'
  196. response = form.submit()
  197. self.assertEqual(list(response.context['messages']), [])
  198. self.assertEqual(
  199. response.context['form'].errors['query'],
  200. ['No products exist with a SKU or UPC matching 321']
  201. )
  202. form = range_products_page.forms[0]
  203. form['query'] = '456, 321'
  204. response = form.submit().follow()
  205. messages = list(response.context['messages'])
  206. self.assertEqual(len(messages), 2)
  207. self.assertEqual(messages[0].level, SUCCESS)
  208. self.assertEqual(messages[0].message, '1 product has been added to this range')
  209. self.assertEqual(messages[1].level, WARNING)
  210. self.assertEqual(
  211. messages[1].message, 'No product(s) were found with SKU or UPC matching 321'
  212. )
  213. def test_same_skus_within_different_products_warning_query(self):
  214. range_products_page = self.get(self.url)
  215. form = range_products_page.forms[0]
  216. form['query'] = '123123'
  217. response = form.submit().follow()
  218. messages = list(response.context['messages'])
  219. self.assertEqual(len(messages), 2)
  220. self.assertEqual(messages[1].level, WARNING)
  221. self.assertEqual(
  222. messages[1].message, 'There are more than one product with SKU 123123'
  223. )
  224. def test_same_skus_within_different_products_warning_file_upload(self):
  225. range_products_page = self.get(self.url)
  226. form = range_products_page.forms[0]
  227. form['file_upload'] = Upload('skus.txt', b'123123')
  228. response = form.submit().follow()
  229. messages = list(response.context['messages'])
  230. self.assertEqual(len(messages), 2)
  231. self.assertEqual(messages[1].level, WARNING)
  232. self.assertEqual(
  233. messages[1].message, 'There are more than one product with SKU 123123'
  234. )
  235. def test_adding_child_does_not_add_parent(self):
  236. range_products_page = self.get(self.url)
  237. form = range_products_page.forms[0]
  238. form['query'] = '1234.345'
  239. form.submit().follow()
  240. all_products = self.range.all_products()
  241. self.assertEqual(len(all_products), 1)
  242. self.assertFalse(self.range.contains_product(self.parent))
  243. self.assertTrue(self.range.contains_product(self.child1))
  244. self.assertFalse(self.range.contains_product(self.child2))
  245. form = range_products_page.forms[0]
  246. form['query'] = '1234-345'
  247. form.submit().follow()
  248. all_products = self.range.all_products()
  249. self.assertEqual(len(all_products), 1)
  250. self.assertTrue(self.range.contains_product(self.child1))
  251. self.assertTrue(self.range.contains_product(self.child2))
  252. self.assertFalse(self.range.contains_product(self.parent))
  253. def test_adding_multiple_children_does_not_add_parent(self):
  254. range_products_page = self.get(self.url)
  255. form = range_products_page.forms[0]
  256. form['query'] = '1234.345 1234-345'
  257. form.submit().follow()
  258. all_products = self.range.all_products()
  259. self.assertEqual(len(all_products), 2)
  260. self.assertTrue(self.range.contains_product(self.child1))
  261. self.assertTrue(self.range.contains_product(self.child2))
  262. self.assertFalse(self.range.contains_product(self.parent))
  263. def test_adding_multiple_comma_separated_children_does_not_add_parent(self):
  264. range_products_page = self.get(self.url)
  265. form = range_products_page.forms[0]
  266. form['query'] = '1234.345, 1234-345'
  267. form.submit().follow()
  268. all_products = self.range.all_products()
  269. self.assertEqual(len(all_products), 2)
  270. self.assertTrue(self.range.contains_product(self.child1))
  271. self.assertTrue(self.range.contains_product(self.child2))
  272. self.assertFalse(self.range.contains_product(self.parent))
  273. def test_remove_selected_product(self):
  274. self.range.add_product(self.product3)
  275. range_products_page = self.get(self.url)
  276. form = range_products_page.forms[1]
  277. form['selected_product'] = '456'
  278. response = form.submit().follow()
  279. messages = list(response.context['messages'])
  280. self.assertEqual(len(messages), 1)
  281. self.assertEqual(messages[0].level, SUCCESS)
  282. self.assertEqual(messages[0].message, 'Removed 1 product from range')
  283. self.assertFalse(self.range.contains_product(self.product3))
  284. self.assertTrue(self.product3 in self.range.excluded_products.all())
  285. def test_remove_excluded_product(self):
  286. self.range.add_product(self.product3)
  287. self.range.excluded_products.add(self.product3)
  288. self.assertFalse(self.range.contains_product(self.product3))
  289. # Remove the product from exclusion form
  290. range_products_page = self.get(self.url)
  291. form = range_products_page.forms[2]
  292. form['selected_product'] = '456'
  293. response = form.submit().follow()
  294. messages = list(response.context['messages'])
  295. self.assertEqual(len(messages), 1)
  296. self.assertEqual(messages[0].level, SUCCESS)
  297. self.assertEqual(messages[0].message, 'Removed 1 product from excluded list')
  298. self.assertTrue(self.range.contains_product(self.product3))
  299. def test_remove_multiple_excluded_products(self):
  300. self.test_upload_multiple_excluded_file_with_skus()
  301. self.assertIn(self.product3, self.range.excluded_products.all())
  302. self.assertIn(self.product4, self.range.excluded_products.all())
  303. range_products_page = self.get(self.url)
  304. form = range_products_page.forms[2]
  305. form['selected_product'] = [self.product3.pk, self.product4.pk]
  306. response = form.submit().follow()
  307. messages = list(response.context['messages'])
  308. self.assertEqual(len(messages), 1)
  309. self.assertEqual(messages[0].level, SUCCESS)
  310. self.assertEqual(messages[0].message, 'Removed 2 products from excluded list')
  311. self.assertNotIn(self.product3, self.range.excluded_products.all())
  312. self.assertNotIn(self.product4, self.range.excluded_products.all())
  313. class RangeReorderViewTest(WebTestCase):
  314. is_staff = True
  315. csrf_checks = False
  316. def setUp(self):
  317. super().setUp()
  318. self.range = Range.objects.create(name='dummy')
  319. self.url = reverse('dashboard:range-reorder', args=(self.range.id,))
  320. self.product1 = create_product()
  321. self.product2 = create_product()
  322. self.product3 = create_product()
  323. self.range.included_products.set([
  324. self.product1, self.product2, self.product3])
  325. def test_range_product_reordering(self):
  326. product_order = list(self.range.rangeproduct_set.values_list(
  327. 'product_id', flat=True))
  328. random.shuffle(product_order)
  329. data = {'product': product_order}
  330. self.post(self.url, params=data)
  331. new_product_order = list(self.range.rangeproduct_set.values_list(
  332. 'product_id', flat=True).order_by('display_order'))
  333. self.assertEqual(new_product_order, product_order)