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_offer_views.py 30KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. import json
  2. import pytest
  3. from django.contrib.messages import get_messages
  4. from django.test import TestCase
  5. from django.urls import reverse
  6. from freezegun import freeze_time
  7. from oscar.apps.dashboard.offers import views as offer_views
  8. from oscar.apps.dashboard.ranges import views as range_views
  9. from oscar.apps.offer.custom import create_benefit, create_condition
  10. from oscar.core.loading import get_model
  11. from oscar.test.factories.catalogue import ProductFactory
  12. from oscar.test.factories.offer import ConditionalOfferFactory, RangeFactory
  13. from oscar.test.factories.voucher import VoucherFactory
  14. from tests._site.model_tests_app.models import (
  15. CustomBenefitModel, CustomConditionModel)
  16. from tests.fixtures import RequestFactory
  17. Range = get_model('offer', 'Range')
  18. ConditionalOffer = get_model('offer', 'ConditionalOffer')
  19. Benefit = get_model('offer', 'Benefit')
  20. Condition = get_model('offer', 'Condition')
  21. @pytest.fixture
  22. def many_ranges():
  23. for i in range(0, 30):
  24. RangeFactory()
  25. return Range.objects.all()
  26. @pytest.fixture
  27. def many_offers():
  28. for i in range(0, 30):
  29. ConditionalOfferFactory(
  30. name='Test offer %d' % i
  31. )
  32. @pytest.fixture
  33. def range_with_products():
  34. productrange = RangeFactory()
  35. for i in range(0, 30):
  36. product = ProductFactory()
  37. productrange.add_product(product)
  38. return productrange
  39. @pytest.mark.django_db
  40. class TestDashboardOffers:
  41. def test_range_list_view(self, rf, many_ranges):
  42. request = rf.get('/')
  43. view = range_views.RangeListView.as_view()
  44. response = view(request)
  45. # if these are missing the pagination is broken
  46. assert response.context_data['paginator']
  47. assert response.context_data['page_obj']
  48. assert response.status_code == 200
  49. def test_offer_list_view(self, rf, many_offers):
  50. request = rf.get('/')
  51. view = offer_views.OfferListView.as_view()
  52. response = view(request)
  53. # if these are missing the pagination is broken
  54. assert response.context_data['paginator']
  55. assert response.context_data['page_obj']
  56. assert response.status_code == 200
  57. def test_offer_delete_view_for_voucher_offer_without_vouchers(self):
  58. offer = ConditionalOfferFactory(offer_type=ConditionalOffer.VOUCHER)
  59. view = offer_views.OfferDeleteView.as_view()
  60. request = RequestFactory().get('/')
  61. response = view(request, pk=offer.pk)
  62. assert response.status_code == 200
  63. request = RequestFactory().post('/')
  64. response = view(request, pk=offer.pk)
  65. assert response.status_code == 302
  66. assert response.url == reverse('dashboard:offer-list')
  67. assert [(m.level_tag, str(m.message)) for m in get_messages(request)][0] == ('success', "Offer deleted!")
  68. assert not ConditionalOffer.objects.exists()
  69. def test_offer_delete_view_for_voucher_offer_with_vouchers(self):
  70. offer = ConditionalOfferFactory(offer_type=ConditionalOffer.VOUCHER)
  71. VoucherFactory().offers.add(offer)
  72. view = offer_views.OfferDeleteView.as_view()
  73. request = RequestFactory().get('/')
  74. response = view(request, pk=offer.pk)
  75. assert response.status_code == 302
  76. assert response.url == reverse('dashboard:offer-detail', kwargs={'pk': offer.pk})
  77. assert [(m.level_tag, str(m.message)) for m in get_messages(request)][0] == (
  78. 'warning', "This offer can only be deleted if it has no vouchers attached to it")
  79. request = RequestFactory().post('/')
  80. response = view(request, pk=offer.pk)
  81. assert response.status_code == 302
  82. assert response.url == reverse('dashboard:offer-detail', kwargs={'pk': offer.pk})
  83. assert [(m.level_tag, str(m.message)) for m in get_messages(request)][0] == (
  84. 'warning', "This offer can only be deleted if it has no vouchers attached to it")
  85. assert ConditionalOffer.objects.exists()
  86. def test_range_product_list_view(self, rf, range_with_products):
  87. view = range_views.RangeProductListView.as_view()
  88. pk = range_with_products.pk
  89. request = rf.get('/')
  90. response = view(request, pk=pk)
  91. # if these are missing the pagination is broken
  92. assert response.context_data['paginator']
  93. assert response.context_data['page_obj']
  94. assert response.status_code == 200
  95. class TestCreateOfferWizardStepView(TestCase):
  96. def setUp(self):
  97. range_ = RangeFactory()
  98. self.metadata_form_kwargs_session_data = {
  99. 'data': {
  100. 'name': 'Test offer',
  101. 'slug': '',
  102. 'description': 'Test description',
  103. 'offer_type': ConditionalOffer.SITE,
  104. 'exclusive': True,
  105. 'status': ConditionalOffer.OPEN,
  106. 'condition': None,
  107. 'benefit': None,
  108. 'priority': 0,
  109. 'start_datetime': None,
  110. 'end_datetime': None,
  111. 'max_global_applications': None,
  112. 'max_user_applications': None,
  113. 'max_basket_applications': None,
  114. 'max_discount': None,
  115. 'total_discount': '0.00',
  116. 'num_applications': 0,
  117. 'num_orders': 0,
  118. 'redirect_url': '',
  119. 'date_created': None,
  120. },
  121. }
  122. self.metadata_obj_session_data = [{
  123. 'model': 'offer.conditionaloffer',
  124. 'pk': None,
  125. 'fields': {
  126. 'name': 'Test offer',
  127. 'description': 'Test description',
  128. 'offer_type': ConditionalOffer.SITE,
  129. },
  130. }]
  131. self.benefit_form_kwargs_session_data = {
  132. 'data': {
  133. 'range': range_.pk,
  134. 'type': Benefit.PERCENTAGE,
  135. 'value': '10',
  136. 'max_affected_items': None,
  137. 'custom_benefit': '',
  138. },
  139. }
  140. self.benefit_obj_session_data = [{
  141. 'model': 'offer.benefit',
  142. 'pk': None,
  143. 'fields': {
  144. 'range': range_.pk,
  145. 'type': Benefit.PERCENTAGE,
  146. 'value': '10',
  147. 'max_affected_items': None,
  148. 'proxy_class': None,
  149. },
  150. }]
  151. self.condition_form_kwargs_session_data = {
  152. 'data': {
  153. 'range': range_.pk,
  154. 'type': Condition.COUNT,
  155. 'value': '10',
  156. 'custom_condition': '',
  157. },
  158. }
  159. self.condition_obj_session_data = [{
  160. 'model': 'offer.condition',
  161. 'pk': None,
  162. 'fields': {
  163. 'range': range_.pk,
  164. 'type': Condition.COUNT,
  165. 'value': '10',
  166. 'proxy_class': None,
  167. },
  168. }]
  169. def test_offer_meta_data_view(self):
  170. request = RequestFactory().post('/', data={
  171. 'name': 'Test offer',
  172. 'description': 'Test description',
  173. 'offer_type': ConditionalOffer.SITE,
  174. })
  175. response = offer_views.OfferMetaDataView.as_view()(request)
  176. self.assertEqual(response.status_code, 302)
  177. self.assertEqual(response.url, reverse('dashboard:offer-benefit'))
  178. self.assertJSONEqual(request.session['offer_wizard']['metadata'], {
  179. 'data': {
  180. 'name': 'Test offer',
  181. 'description': 'Test description',
  182. 'offer_type': ConditionalOffer.SITE,
  183. },
  184. })
  185. self.assertJSONEqual(request.session['offer_wizard']['metadata_obj'], [{
  186. 'model': 'offer.conditionaloffer',
  187. 'pk': None,
  188. 'fields': {
  189. 'name': 'Test offer',
  190. 'slug': '',
  191. 'description': 'Test description',
  192. 'offer_type': ConditionalOffer.SITE,
  193. 'exclusive': True,
  194. 'status': ConditionalOffer.OPEN,
  195. 'condition': None,
  196. 'benefit': None,
  197. 'priority': 0,
  198. 'start_datetime': None,
  199. 'end_datetime': None,
  200. 'max_global_applications': None,
  201. 'max_user_applications': None,
  202. 'max_basket_applications': None,
  203. 'max_discount': None,
  204. 'total_discount': '0.00',
  205. 'num_applications': 0,
  206. 'num_orders': 0,
  207. 'redirect_url': '',
  208. 'date_created': None,
  209. },
  210. }])
  211. def test_offer_benefit_view_with_built_in_benefit_type(self):
  212. range_ = RangeFactory()
  213. request = RequestFactory().post('/', data={
  214. 'range': range_.pk,
  215. 'type': Benefit.PERCENTAGE,
  216. 'value': 10,
  217. })
  218. request.session['offer_wizard'] = {
  219. 'metadata': json.dumps(self.metadata_form_kwargs_session_data),
  220. 'metadata_obj': json.dumps(self.metadata_obj_session_data),
  221. }
  222. response = offer_views.OfferBenefitView.as_view()(request)
  223. self.assertEqual(response.status_code, 302)
  224. self.assertEqual(response.url, reverse('dashboard:offer-condition'))
  225. self.assertJSONEqual(request.session['offer_wizard']['metadata'], self.metadata_form_kwargs_session_data)
  226. self.assertJSONEqual(request.session['offer_wizard']['metadata_obj'], self.metadata_obj_session_data)
  227. self.assertJSONEqual(request.session['offer_wizard']['benefit'], {
  228. 'data': {
  229. 'range': range_.pk,
  230. 'type': Benefit.PERCENTAGE,
  231. 'value': '10',
  232. 'max_affected_items': None,
  233. 'custom_benefit': '',
  234. },
  235. })
  236. self.assertJSONEqual(request.session['offer_wizard']['benefit_obj'], [{
  237. 'model': 'offer.benefit',
  238. 'pk': None,
  239. 'fields': {
  240. 'range': range_.pk,
  241. 'type': Benefit.PERCENTAGE,
  242. 'value': '10',
  243. 'max_affected_items': None,
  244. 'proxy_class': None,
  245. },
  246. }])
  247. def test_offer_benefit_view_with_custom_benefit_type(self):
  248. benefit = create_benefit(CustomBenefitModel)
  249. request = RequestFactory().post('/', data={
  250. 'custom_benefit': benefit.pk,
  251. })
  252. request.session['offer_wizard'] = {
  253. 'metadata': json.dumps(self.metadata_form_kwargs_session_data),
  254. 'metadata_obj': json.dumps(self.metadata_obj_session_data),
  255. }
  256. response = offer_views.OfferBenefitView.as_view()(request)
  257. self.assertEqual(response.status_code, 302)
  258. self.assertEqual(response.url, reverse('dashboard:offer-condition'))
  259. self.assertJSONEqual(request.session['offer_wizard']['metadata'], self.metadata_form_kwargs_session_data)
  260. self.assertJSONEqual(request.session['offer_wizard']['metadata_obj'], self.metadata_obj_session_data)
  261. self.assertJSONEqual(request.session['offer_wizard']['benefit'], {
  262. 'data': {
  263. 'range': None,
  264. 'type': '',
  265. 'value': None,
  266. 'max_affected_items': None,
  267. 'custom_benefit': str(benefit.pk),
  268. },
  269. })
  270. self.assertJSONEqual(request.session['offer_wizard']['benefit_obj'], [{
  271. 'model': 'offer.benefit',
  272. 'pk': benefit.pk,
  273. 'fields': {
  274. 'range': None,
  275. 'type': '',
  276. 'value': None,
  277. 'max_affected_items': None,
  278. 'proxy_class': benefit.proxy_class,
  279. }
  280. }])
  281. def test_offer_condition_view_with_built_in_condition_type(self):
  282. range_ = RangeFactory()
  283. request = RequestFactory().post('/', data={
  284. 'range': range_.pk,
  285. 'type': Condition.COUNT,
  286. 'value': 10,
  287. })
  288. request.session['offer_wizard'] = {
  289. 'metadata': json.dumps(self.metadata_form_kwargs_session_data),
  290. 'metadata_obj': json.dumps(self.metadata_obj_session_data),
  291. 'benefit': json.dumps(self.benefit_form_kwargs_session_data),
  292. 'benefit_obj': json.dumps(self.benefit_obj_session_data),
  293. }
  294. response = offer_views.OfferConditionView.as_view()(request)
  295. self.assertEqual(response.status_code, 302)
  296. self.assertEqual(response.url, reverse('dashboard:offer-restrictions'))
  297. self.assertJSONEqual(request.session['offer_wizard']['metadata'], self.metadata_form_kwargs_session_data)
  298. self.assertJSONEqual(request.session['offer_wizard']['metadata_obj'], self.metadata_obj_session_data)
  299. self.assertJSONEqual(request.session['offer_wizard']['benefit'], self.benefit_form_kwargs_session_data)
  300. self.assertJSONEqual(request.session['offer_wizard']['benefit_obj'], self.benefit_obj_session_data)
  301. self.assertJSONEqual(request.session['offer_wizard']['condition'], {
  302. 'data': {
  303. 'range': range_.pk,
  304. 'type': Condition.COUNT,
  305. 'value': '10',
  306. 'custom_condition': '',
  307. },
  308. })
  309. self.assertJSONEqual(request.session['offer_wizard']['condition_obj'], [{
  310. 'model': 'offer.condition',
  311. 'pk': None,
  312. 'fields': {
  313. 'range': range_.pk,
  314. 'type': Condition.COUNT,
  315. 'value': '10',
  316. 'proxy_class': None,
  317. },
  318. }])
  319. def test_offer_condition_view_with_custom_condition_type(self):
  320. condition = create_condition(CustomConditionModel)
  321. request = RequestFactory().post('/', data={
  322. 'custom_condition': condition.pk,
  323. })
  324. request.session['offer_wizard'] = {
  325. 'metadata': json.dumps(self.metadata_form_kwargs_session_data),
  326. 'metadata_obj': json.dumps(self.metadata_obj_session_data),
  327. 'benefit': json.dumps(self.benefit_form_kwargs_session_data),
  328. 'benefit_obj': json.dumps(self.benefit_obj_session_data),
  329. }
  330. response = offer_views.OfferConditionView.as_view()(request)
  331. self.assertEqual(response.status_code, 302)
  332. self.assertEqual(response.url, reverse('dashboard:offer-restrictions'))
  333. self.assertJSONEqual(request.session['offer_wizard']['metadata'], self.metadata_form_kwargs_session_data)
  334. self.assertJSONEqual(request.session['offer_wizard']['metadata_obj'], self.metadata_obj_session_data)
  335. self.assertJSONEqual(request.session['offer_wizard']['benefit'], self.benefit_form_kwargs_session_data)
  336. self.assertJSONEqual(request.session['offer_wizard']['benefit_obj'], self.benefit_obj_session_data)
  337. self.assertJSONEqual(request.session['offer_wizard']['condition'], {
  338. 'data': {
  339. 'range': None,
  340. 'type': '',
  341. 'value': None,
  342. 'custom_condition': str(condition.pk),
  343. },
  344. })
  345. self.assertJSONEqual(request.session['offer_wizard']['condition_obj'], [{
  346. 'model': 'offer.condition',
  347. 'pk': condition.pk,
  348. 'fields': {
  349. 'range': None,
  350. 'type': '',
  351. 'value': None,
  352. 'proxy_class': condition.proxy_class,
  353. }
  354. }])
  355. def test_offer_restrictions_view(self):
  356. request = RequestFactory().post('/', data={
  357. 'priority': 0,
  358. })
  359. request.session['offer_wizard'] = {
  360. 'metadata': json.dumps(self.metadata_form_kwargs_session_data),
  361. 'metadata_obj': json.dumps(self.metadata_obj_session_data),
  362. 'benefit': json.dumps(self.benefit_form_kwargs_session_data),
  363. 'benefit_obj': json.dumps(self.benefit_obj_session_data),
  364. 'condition': json.dumps(self.condition_form_kwargs_session_data),
  365. 'condition_obj': json.dumps(self.condition_obj_session_data),
  366. }
  367. response = offer_views.OfferRestrictionsView.as_view()(request)
  368. offer = ConditionalOffer.objects.get()
  369. self.assertEqual(response.status_code, 302)
  370. self.assertEqual(response.url, reverse('dashboard:offer-detail', kwargs={'pk': offer.pk}))
  371. self.assertEqual([(m.level_tag, str(m.message)) for m in get_messages(request)][0],
  372. ('success', "Offer '%s' created!" % offer.name))
  373. self.assertEqual(request.session['offer_wizard'], {})
  374. @freeze_time('2021-04-23 14:00:00')
  375. class TestUpdateOfferWizardStepView(TestCase):
  376. def setUp(self):
  377. self.offer = ConditionalOfferFactory()
  378. self.metadata_form_kwargs_key = 'metadata%s' % self.offer.pk
  379. self.metadata_obj_key = 'metadata%s_obj' % self.offer.pk
  380. self.benefit_form_kwargs_key = 'benefit%s' % self.offer.pk
  381. self.benefit_obj_key = 'benefit%s_obj' % self.offer.pk
  382. self.condition_form_kwargs_key = 'condition%s' % self.offer.pk
  383. self.condition_obj_key = 'condition%s_obj' % self.offer.pk
  384. range_ = RangeFactory()
  385. self.metadata_form_kwargs_session_data = {
  386. 'data': {
  387. 'name': 'Test offer',
  388. 'slug': self.offer.slug,
  389. 'description': 'Test description',
  390. 'offer_type': ConditionalOffer.VOUCHER,
  391. 'exclusive': True,
  392. 'status': ConditionalOffer.OPEN,
  393. 'condition': self.offer.condition.pk,
  394. 'benefit': self.offer.benefit.pk,
  395. 'priority': 0,
  396. 'start_datetime': None,
  397. 'end_datetime': None,
  398. 'max_global_applications': None,
  399. 'max_user_applications': None,
  400. 'max_basket_applications': None,
  401. 'max_discount': None,
  402. 'total_discount': '0.00',
  403. 'num_applications': 0,
  404. 'num_orders': 0,
  405. 'redirect_url': '',
  406. 'date_created': '2021-04-23T14:00:00Z',
  407. },
  408. }
  409. self.metadata_obj_session_data = [{
  410. 'model': 'offer.conditionaloffer',
  411. 'pk': None,
  412. 'fields': {
  413. 'name': 'Test offer',
  414. 'description': 'Test description',
  415. 'offer_type': ConditionalOffer.VOUCHER,
  416. },
  417. }]
  418. self.benefit_form_kwargs_session_data = {
  419. 'data': {
  420. 'range': range_.pk,
  421. 'type': Benefit.FIXED,
  422. 'value': '2000',
  423. 'max_affected_items': 2,
  424. 'custom_benefit': '',
  425. },
  426. }
  427. self.benefit_obj_session_data = [{
  428. 'model': 'offer.benefit',
  429. 'pk': None,
  430. 'fields': {
  431. 'range': range_.pk,
  432. 'type': Benefit.FIXED,
  433. 'value': '2000',
  434. 'max_affected_items': 2,
  435. 'proxy_class': '',
  436. },
  437. }]
  438. self.condition_form_kwargs_session_data = {
  439. 'data': {
  440. 'range': range_.pk,
  441. 'type': Condition.VALUE,
  442. 'value': '2000',
  443. 'custom_condition': '',
  444. },
  445. }
  446. self.condition_obj_session_data = [{
  447. 'model': 'offer.condition',
  448. 'pk': None,
  449. 'fields': {
  450. 'range': range_.pk,
  451. 'type': Condition.VALUE,
  452. 'value': '2000',
  453. 'proxy_class': '',
  454. },
  455. }]
  456. def test_offer_meta_data_view(self):
  457. request = RequestFactory().post('/', data={
  458. 'name': 'Test offer',
  459. 'description': 'Test description',
  460. 'offer_type': ConditionalOffer.VOUCHER,
  461. })
  462. response = offer_views.OfferMetaDataView.as_view(update=True)(request, pk=self.offer.pk)
  463. self.assertEqual(response.status_code, 302)
  464. self.assertEqual(response.url, reverse('dashboard:offer-benefit', kwargs={'pk': self.offer.pk}))
  465. self.assertJSONEqual(request.session['offer_wizard'][self.metadata_form_kwargs_key], {
  466. 'data': {
  467. 'name': 'Test offer',
  468. 'description': 'Test description',
  469. 'offer_type': ConditionalOffer.VOUCHER,
  470. },
  471. })
  472. self.assertJSONEqual(request.session['offer_wizard'][self.metadata_obj_key], [{
  473. 'model': 'offer.conditionaloffer',
  474. 'pk': self.offer.pk,
  475. 'fields': {
  476. 'name': 'Test offer',
  477. 'slug': self.offer.slug,
  478. 'description': 'Test description',
  479. 'offer_type': ConditionalOffer.VOUCHER,
  480. 'exclusive': True,
  481. 'status': ConditionalOffer.OPEN,
  482. 'condition': self.offer.condition.pk,
  483. 'benefit': self.offer.benefit.pk,
  484. 'priority': 0,
  485. 'start_datetime': None,
  486. 'end_datetime': None,
  487. 'max_global_applications': None,
  488. 'max_user_applications': None,
  489. 'max_basket_applications': None,
  490. 'max_discount': None,
  491. 'total_discount': '0.00',
  492. 'num_applications': 0,
  493. 'num_orders': 0,
  494. 'redirect_url': '',
  495. 'date_created': '2021-04-23T14:00:00Z',
  496. },
  497. }])
  498. def test_offer_benefit_view_with_built_in_benefit_type(self):
  499. range_ = RangeFactory()
  500. request = RequestFactory().post('/', data={
  501. 'range': range_.pk,
  502. 'type': Benefit.FIXED,
  503. 'value': 2000,
  504. })
  505. request.session['offer_wizard'] = {
  506. self.metadata_form_kwargs_key: json.dumps(self.metadata_form_kwargs_session_data),
  507. self.metadata_obj_key: json.dumps(self.metadata_obj_session_data),
  508. }
  509. response = offer_views.OfferBenefitView.as_view(update=True)(request, pk=self.offer.pk)
  510. self.assertEqual(response.status_code, 302)
  511. self.assertEqual(response.url, reverse('dashboard:offer-condition', kwargs={'pk': self.offer.pk}))
  512. self.assertJSONEqual(request.session['offer_wizard'][self.metadata_form_kwargs_key],
  513. self.metadata_form_kwargs_session_data)
  514. self.assertJSONEqual(request.session['offer_wizard'][self.metadata_obj_key], self.metadata_obj_session_data)
  515. self.assertJSONEqual(request.session['offer_wizard'][self.benefit_form_kwargs_key], {
  516. 'data': {
  517. 'range': range_.pk,
  518. 'type': Benefit.FIXED,
  519. 'value': '2000',
  520. 'max_affected_items': None,
  521. 'custom_benefit': '',
  522. },
  523. })
  524. self.assertJSONEqual(request.session['offer_wizard'][self.benefit_obj_key], [{
  525. 'model': 'offer.benefit',
  526. 'pk': self.offer.benefit.pk,
  527. 'fields': {
  528. 'range': range_.pk,
  529. 'type': Benefit.FIXED,
  530. 'value': '2000',
  531. 'max_affected_items': None,
  532. 'proxy_class': '',
  533. },
  534. }])
  535. def test_offer_benefit_view_with_custom_benefit_type(self):
  536. benefit = create_benefit(CustomBenefitModel)
  537. request = RequestFactory().post('/', data={
  538. 'custom_benefit': benefit.pk,
  539. })
  540. request.session['offer_wizard'] = {
  541. self.metadata_form_kwargs_key: json.dumps(self.metadata_form_kwargs_session_data),
  542. self.metadata_obj_key: json.dumps(self.metadata_obj_session_data),
  543. }
  544. response = offer_views.OfferBenefitView.as_view(update=True)(request, pk=self.offer.pk)
  545. self.assertEqual(response.status_code, 302)
  546. self.assertEqual(response.url, reverse('dashboard:offer-condition', kwargs={'pk': self.offer.pk}))
  547. self.assertJSONEqual(request.session['offer_wizard'][self.metadata_form_kwargs_key],
  548. self.metadata_form_kwargs_session_data)
  549. self.assertJSONEqual(request.session['offer_wizard'][self.metadata_obj_key], self.metadata_obj_session_data)
  550. self.assertJSONEqual(request.session['offer_wizard'][self.benefit_form_kwargs_key], {
  551. 'data': {
  552. 'range': None,
  553. 'type': '',
  554. 'value': None,
  555. 'max_affected_items': None,
  556. 'custom_benefit': str(benefit.pk),
  557. },
  558. })
  559. self.assertJSONEqual(request.session['offer_wizard'][self.benefit_obj_key], [{
  560. 'model': 'offer.benefit',
  561. 'pk': benefit.pk,
  562. 'fields': {
  563. 'range': None,
  564. 'type': '',
  565. 'value': None,
  566. 'max_affected_items': None,
  567. 'proxy_class': benefit.proxy_class,
  568. }
  569. }])
  570. def test_offer_condition_view_with_built_in_condition_type(self):
  571. range_ = RangeFactory()
  572. request = RequestFactory().post('/', data={
  573. 'range': range_.pk,
  574. 'type': Condition.VALUE,
  575. 'value': 2000,
  576. })
  577. request.session['offer_wizard'] = {
  578. self.metadata_form_kwargs_key: json.dumps(self.metadata_form_kwargs_session_data),
  579. self.metadata_obj_key: json.dumps(self.metadata_obj_session_data),
  580. self.benefit_form_kwargs_key: json.dumps(self.benefit_form_kwargs_session_data),
  581. self.benefit_obj_key: json.dumps(self.benefit_obj_session_data),
  582. }
  583. response = offer_views.OfferConditionView.as_view(update=True)(request, pk=self.offer.pk)
  584. self.assertEqual(response.status_code, 302)
  585. self.assertEqual(response.url, reverse('dashboard:offer-restrictions', kwargs={'pk': self.offer.pk}))
  586. self.assertJSONEqual(request.session['offer_wizard'][self.metadata_form_kwargs_key],
  587. self.metadata_form_kwargs_session_data)
  588. self.assertJSONEqual(request.session['offer_wizard'][self.metadata_obj_key], self.metadata_obj_session_data)
  589. self.assertJSONEqual(request.session['offer_wizard'][self.benefit_form_kwargs_key],
  590. self.benefit_form_kwargs_session_data)
  591. self.assertJSONEqual(request.session['offer_wizard'][self.benefit_obj_key], self.benefit_obj_session_data)
  592. self.assertJSONEqual(request.session['offer_wizard'][self.condition_form_kwargs_key], {
  593. 'data': {
  594. 'range': range_.pk,
  595. 'type': Condition.VALUE,
  596. 'value': '2000',
  597. 'custom_condition': '',
  598. },
  599. })
  600. self.assertJSONEqual(request.session['offer_wizard'][self.condition_obj_key], [{
  601. 'model': 'offer.condition',
  602. 'pk': self.offer.condition.pk,
  603. 'fields': {
  604. 'range': range_.pk,
  605. 'type': Condition.VALUE,
  606. 'value': '2000',
  607. 'proxy_class': '',
  608. },
  609. }])
  610. def test_offer_condition_view_with_custom_condition_type(self):
  611. condition = create_condition(CustomConditionModel)
  612. request = RequestFactory().post('/', data={
  613. 'custom_condition': condition.pk,
  614. })
  615. request.session['offer_wizard'] = {
  616. self.metadata_form_kwargs_key: json.dumps(self.metadata_form_kwargs_session_data),
  617. self.metadata_obj_key: json.dumps(self.metadata_obj_session_data),
  618. self.benefit_form_kwargs_key: json.dumps(self.benefit_form_kwargs_session_data),
  619. self.benefit_obj_key: json.dumps(self.benefit_obj_session_data),
  620. }
  621. response = offer_views.OfferConditionView.as_view(update=True)(request, pk=self.offer.pk)
  622. self.assertEqual(response.status_code, 302)
  623. self.assertEqual(response.url, reverse('dashboard:offer-restrictions', kwargs={'pk': self.offer.pk}))
  624. self.assertJSONEqual(request.session['offer_wizard'][self.metadata_form_kwargs_key],
  625. self.metadata_form_kwargs_session_data)
  626. self.assertJSONEqual(request.session['offer_wizard'][self.metadata_obj_key], self.metadata_obj_session_data)
  627. self.assertJSONEqual(request.session['offer_wizard'][self.benefit_form_kwargs_key],
  628. self.benefit_form_kwargs_session_data)
  629. self.assertJSONEqual(request.session['offer_wizard'][self.benefit_obj_key], self.benefit_obj_session_data)
  630. self.assertJSONEqual(request.session['offer_wizard'][self.condition_form_kwargs_key], {
  631. 'data': {
  632. 'range': None,
  633. 'type': '',
  634. 'value': None,
  635. 'custom_condition': str(condition.pk),
  636. },
  637. })
  638. self.assertJSONEqual(request.session['offer_wizard'][self.condition_obj_key], [{
  639. 'model': 'offer.condition',
  640. 'pk': condition.pk,
  641. 'fields': {
  642. 'range': None,
  643. 'type': '',
  644. 'value': None,
  645. 'proxy_class': condition.proxy_class,
  646. }
  647. }])
  648. def test_offer_restrictions_view(self):
  649. request = RequestFactory().post('/', data={
  650. 'priority': 0,
  651. })
  652. request.session['offer_wizard'] = {
  653. self.metadata_form_kwargs_key: json.dumps(self.metadata_form_kwargs_session_data),
  654. self.metadata_obj_key: json.dumps(self.metadata_obj_session_data),
  655. self.benefit_form_kwargs_key: json.dumps(self.benefit_form_kwargs_session_data),
  656. self.benefit_obj_key: json.dumps(self.benefit_obj_session_data),
  657. self.condition_form_kwargs_key: json.dumps(self.condition_form_kwargs_session_data),
  658. self.condition_obj_key: json.dumps(self.condition_obj_session_data),
  659. }
  660. response = offer_views.OfferRestrictionsView.as_view(update=True)(request, pk=self.offer.pk)
  661. self.offer.refresh_from_db()
  662. self.assertEqual(response.status_code, 302)
  663. self.assertEqual(response.url, reverse('dashboard:offer-detail', kwargs={'pk': self.offer.pk}))
  664. self.assertEqual([(m.level_tag, str(m.message)) for m in get_messages(request)][0],
  665. ('success', "Offer '%s' updated" % self.offer.name))
  666. self.assertEqual(request.session['offer_wizard'], {})