Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

test_offer_views.py 34KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983
  1. # pylint: disable=redefined-outer-name, unused-argument
  2. import json
  3. import pytest
  4. from django.contrib.messages import get_messages
  5. from django.test import TestCase
  6. from django.urls import reverse
  7. from freezegun import freeze_time
  8. from oscar.apps.dashboard.offers import views as offer_views
  9. from oscar.apps.dashboard.ranges import views as range_views
  10. from oscar.apps.offer.custom import create_benefit, create_condition
  11. from oscar.core.loading import get_model
  12. from oscar.test.factories.catalogue import ProductFactory
  13. from oscar.test.factories.offer import ConditionalOfferFactory, RangeFactory
  14. from oscar.test.factories.voucher import VoucherFactory
  15. from tests._site.model_tests_app.models import 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 _ 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(name="Test offer %d" % i)
  30. @pytest.fixture
  31. def range_with_products():
  32. productrange = RangeFactory()
  33. for _ in range(0, 30):
  34. product = ProductFactory()
  35. productrange.add_product(product)
  36. return productrange
  37. @pytest.mark.django_db
  38. class TestDashboardOffers:
  39. def test_range_list_view(self, rf, many_ranges):
  40. request = rf.get("/")
  41. view = range_views.RangeListView.as_view()
  42. response = view(request)
  43. # if these are missing the pagination is broken
  44. assert response.context_data["paginator"]
  45. assert response.context_data["page_obj"]
  46. assert response.status_code == 200
  47. def test_offer_list_view(self, rf, many_offers):
  48. request = rf.get("/")
  49. view = offer_views.OfferListView.as_view()
  50. response = view(request)
  51. # if these are missing the pagination is broken
  52. assert response.context_data["paginator"]
  53. assert response.context_data["page_obj"]
  54. assert response.status_code == 200
  55. def test_offer_delete_view_for_voucher_offer_without_vouchers(self):
  56. offer = ConditionalOfferFactory(offer_type=ConditionalOffer.VOUCHER)
  57. view = offer_views.OfferDeleteView.as_view()
  58. request = RequestFactory().get("/")
  59. response = view(request, pk=offer.pk)
  60. assert response.status_code == 200
  61. request = RequestFactory().post("/")
  62. response = view(request, pk=offer.pk)
  63. assert response.status_code == 302
  64. assert response.url == reverse("dashboard:offer-list")
  65. assert [(m.level_tag, str(m.message)) for m in get_messages(request)][0] == (
  66. "success",
  67. "Offer deleted!",
  68. )
  69. assert not ConditionalOffer.objects.exists()
  70. def test_offer_delete_view_for_voucher_offer_with_vouchers(self):
  71. offer = ConditionalOfferFactory(offer_type=ConditionalOffer.VOUCHER)
  72. VoucherFactory().offers.add(offer)
  73. view = offer_views.OfferDeleteView.as_view()
  74. request = RequestFactory().get("/")
  75. response = view(request, pk=offer.pk)
  76. assert response.status_code == 302
  77. assert response.url == reverse(
  78. "dashboard:offer-detail", kwargs={"pk": offer.pk}
  79. )
  80. assert [(m.level_tag, str(m.message)) for m in get_messages(request)][0] == (
  81. "warning",
  82. "This offer can only be deleted if it has no vouchers attached to it",
  83. )
  84. request = RequestFactory().post("/")
  85. response = view(request, pk=offer.pk)
  86. assert response.status_code == 302
  87. assert response.url == reverse(
  88. "dashboard:offer-detail", kwargs={"pk": offer.pk}
  89. )
  90. assert [(m.level_tag, str(m.message)) for m in get_messages(request)][0] == (
  91. "warning",
  92. "This offer can only be deleted if it has no vouchers attached to it",
  93. )
  94. assert ConditionalOffer.objects.exists()
  95. def test_range_product_list_view(self, rf, range_with_products):
  96. view = range_views.RangeProductListView.as_view()
  97. pk = range_with_products.pk
  98. request = rf.get("/")
  99. response = view(request, pk=pk)
  100. # if these are missing the pagination is broken
  101. assert response.context_data["paginator"]
  102. assert response.context_data["page_obj"]
  103. assert response.status_code == 200
  104. class TestCreateOfferWizardStepView(TestCase):
  105. def setUp(self):
  106. range_ = RangeFactory()
  107. self.metadata_form_kwargs_session_data = {
  108. "data": {
  109. "name": "Test offer",
  110. "slug": "",
  111. "description": "Test description",
  112. "offer_type": ConditionalOffer.SITE,
  113. "exclusive": True,
  114. "status": ConditionalOffer.OPEN,
  115. "condition": None,
  116. "benefit": None,
  117. "priority": 0,
  118. "start_datetime": None,
  119. "end_datetime": None,
  120. "max_global_applications": None,
  121. "max_user_applications": None,
  122. "max_basket_applications": None,
  123. "max_discount": None,
  124. "total_discount": "0.00",
  125. "num_applications": 0,
  126. "num_orders": 0,
  127. "redirect_url": "",
  128. "date_created": None,
  129. },
  130. }
  131. self.metadata_obj_session_data = [
  132. {
  133. "model": "offer.conditionaloffer",
  134. "pk": None,
  135. "fields": {
  136. "name": "Test offer",
  137. "description": "Test description",
  138. "offer_type": ConditionalOffer.SITE,
  139. },
  140. }
  141. ]
  142. self.benefit_form_kwargs_session_data = {
  143. "data": {
  144. "range": range_.pk,
  145. "type": Benefit.PERCENTAGE,
  146. "value": "10",
  147. "max_affected_items": None,
  148. "custom_benefit": "",
  149. },
  150. }
  151. self.benefit_obj_session_data = [
  152. {
  153. "model": "offer.benefit",
  154. "pk": None,
  155. "fields": {
  156. "range": range_.pk,
  157. "type": Benefit.PERCENTAGE,
  158. "value": "10",
  159. "max_affected_items": None,
  160. "proxy_class": None,
  161. },
  162. }
  163. ]
  164. self.condition_form_kwargs_session_data = {
  165. "data": {
  166. "range": range_.pk,
  167. "type": Condition.COUNT,
  168. "value": "10",
  169. "custom_condition": "",
  170. },
  171. }
  172. self.condition_obj_session_data = [
  173. {
  174. "model": "offer.condition",
  175. "pk": None,
  176. "fields": {
  177. "range": range_.pk,
  178. "type": Condition.COUNT,
  179. "value": "10",
  180. "proxy_class": None,
  181. },
  182. }
  183. ]
  184. def test_offer_meta_data_view(self):
  185. request = RequestFactory().post(
  186. "/",
  187. data={
  188. "name": "Test offer",
  189. "description": "Test description",
  190. "offer_type": ConditionalOffer.SITE,
  191. },
  192. )
  193. response = offer_views.OfferMetaDataView.as_view()(request)
  194. self.assertEqual(response.status_code, 302)
  195. self.assertEqual(response.url, reverse("dashboard:offer-benefit"))
  196. self.assertJSONEqual(
  197. request.session["offer_wizard"]["metadata"],
  198. {
  199. "data": {
  200. "name": "Test offer",
  201. "description": "Test description",
  202. "offer_type": ConditionalOffer.SITE,
  203. },
  204. },
  205. )
  206. self.assertJSONEqual(
  207. request.session["offer_wizard"]["metadata_obj"],
  208. [
  209. {
  210. "model": "offer.conditionaloffer",
  211. "pk": None,
  212. "fields": {
  213. "name": "Test offer",
  214. "slug": "",
  215. "description": "Test description",
  216. "offer_type": ConditionalOffer.SITE,
  217. "exclusive": True,
  218. "status": ConditionalOffer.OPEN,
  219. "condition": None,
  220. "benefit": None,
  221. "priority": 0,
  222. "start_datetime": None,
  223. "end_datetime": None,
  224. "max_global_applications": None,
  225. "max_user_applications": None,
  226. "max_basket_applications": None,
  227. "max_discount": None,
  228. "total_discount": "0.00",
  229. "num_applications": 0,
  230. "num_orders": 0,
  231. "redirect_url": "",
  232. "date_created": None,
  233. },
  234. }
  235. ],
  236. )
  237. def test_offer_benefit_view_with_built_in_benefit_type(self):
  238. range_ = RangeFactory()
  239. request = RequestFactory().post(
  240. "/",
  241. data={
  242. "range": range_.pk,
  243. "type": Benefit.PERCENTAGE,
  244. "value": 10,
  245. },
  246. )
  247. request.session["offer_wizard"] = {
  248. "metadata": json.dumps(self.metadata_form_kwargs_session_data),
  249. "metadata_obj": json.dumps(self.metadata_obj_session_data),
  250. }
  251. response = offer_views.OfferBenefitView.as_view()(request)
  252. self.assertEqual(response.status_code, 302)
  253. self.assertEqual(response.url, reverse("dashboard:offer-condition"))
  254. self.assertJSONEqual(
  255. request.session["offer_wizard"]["metadata"],
  256. self.metadata_form_kwargs_session_data,
  257. )
  258. self.assertJSONEqual(
  259. request.session["offer_wizard"]["metadata_obj"],
  260. self.metadata_obj_session_data,
  261. )
  262. self.assertJSONEqual(
  263. request.session["offer_wizard"]["benefit"],
  264. {
  265. "data": {
  266. "range": range_.pk,
  267. "type": Benefit.PERCENTAGE,
  268. "value": "10",
  269. "max_affected_items": None,
  270. "custom_benefit": "",
  271. },
  272. },
  273. )
  274. self.assertJSONEqual(
  275. request.session["offer_wizard"]["benefit_obj"],
  276. [
  277. {
  278. "model": "offer.benefit",
  279. "pk": None,
  280. "fields": {
  281. "range": range_.pk,
  282. "type": Benefit.PERCENTAGE,
  283. "value": "10",
  284. "max_affected_items": None,
  285. "proxy_class": None,
  286. },
  287. }
  288. ],
  289. )
  290. def test_offer_benefit_view_with_custom_benefit_type(self):
  291. benefit = create_benefit(CustomBenefitModel)
  292. request = RequestFactory().post(
  293. "/",
  294. data={
  295. "custom_benefit": benefit.pk,
  296. },
  297. )
  298. request.session["offer_wizard"] = {
  299. "metadata": json.dumps(self.metadata_form_kwargs_session_data),
  300. "metadata_obj": json.dumps(self.metadata_obj_session_data),
  301. }
  302. response = offer_views.OfferBenefitView.as_view()(request)
  303. self.assertEqual(response.status_code, 302)
  304. self.assertEqual(response.url, reverse("dashboard:offer-condition"))
  305. self.assertJSONEqual(
  306. request.session["offer_wizard"]["metadata"],
  307. self.metadata_form_kwargs_session_data,
  308. )
  309. self.assertJSONEqual(
  310. request.session["offer_wizard"]["metadata_obj"],
  311. self.metadata_obj_session_data,
  312. )
  313. self.assertJSONEqual(
  314. request.session["offer_wizard"]["benefit"],
  315. {
  316. "data": {
  317. "range": None,
  318. "type": "",
  319. "value": None,
  320. "max_affected_items": None,
  321. "custom_benefit": str(benefit.pk),
  322. },
  323. },
  324. )
  325. self.assertJSONEqual(
  326. request.session["offer_wizard"]["benefit_obj"],
  327. [
  328. {
  329. "model": "offer.benefit",
  330. "pk": benefit.pk,
  331. "fields": {
  332. "range": None,
  333. "type": "",
  334. "value": None,
  335. "max_affected_items": None,
  336. "proxy_class": benefit.proxy_class,
  337. },
  338. }
  339. ],
  340. )
  341. def test_offer_condition_view_with_built_in_condition_type(self):
  342. range_ = RangeFactory()
  343. request = RequestFactory().post(
  344. "/",
  345. data={
  346. "range": range_.pk,
  347. "type": Condition.COUNT,
  348. "value": 10,
  349. },
  350. )
  351. request.session["offer_wizard"] = {
  352. "metadata": json.dumps(self.metadata_form_kwargs_session_data),
  353. "metadata_obj": json.dumps(self.metadata_obj_session_data),
  354. "benefit": json.dumps(self.benefit_form_kwargs_session_data),
  355. "benefit_obj": json.dumps(self.benefit_obj_session_data),
  356. }
  357. response = offer_views.OfferConditionView.as_view()(request)
  358. self.assertEqual(response.status_code, 302)
  359. self.assertEqual(response.url, reverse("dashboard:offer-restrictions"))
  360. self.assertJSONEqual(
  361. request.session["offer_wizard"]["metadata"],
  362. self.metadata_form_kwargs_session_data,
  363. )
  364. self.assertJSONEqual(
  365. request.session["offer_wizard"]["metadata_obj"],
  366. self.metadata_obj_session_data,
  367. )
  368. self.assertJSONEqual(
  369. request.session["offer_wizard"]["benefit"],
  370. self.benefit_form_kwargs_session_data,
  371. )
  372. self.assertJSONEqual(
  373. request.session["offer_wizard"]["benefit_obj"],
  374. self.benefit_obj_session_data,
  375. )
  376. self.assertJSONEqual(
  377. request.session["offer_wizard"]["condition"],
  378. {
  379. "data": {
  380. "range": range_.pk,
  381. "type": Condition.COUNT,
  382. "value": "10",
  383. "custom_condition": "",
  384. },
  385. },
  386. )
  387. self.assertJSONEqual(
  388. request.session["offer_wizard"]["condition_obj"],
  389. [
  390. {
  391. "model": "offer.condition",
  392. "pk": None,
  393. "fields": {
  394. "range": range_.pk,
  395. "type": Condition.COUNT,
  396. "value": "10",
  397. "proxy_class": None,
  398. },
  399. }
  400. ],
  401. )
  402. def test_offer_condition_view_with_custom_condition_type(self):
  403. condition = create_condition(CustomConditionModel)
  404. request = RequestFactory().post(
  405. "/",
  406. data={
  407. "custom_condition": condition.pk,
  408. },
  409. )
  410. request.session["offer_wizard"] = {
  411. "metadata": json.dumps(self.metadata_form_kwargs_session_data),
  412. "metadata_obj": json.dumps(self.metadata_obj_session_data),
  413. "benefit": json.dumps(self.benefit_form_kwargs_session_data),
  414. "benefit_obj": json.dumps(self.benefit_obj_session_data),
  415. }
  416. response = offer_views.OfferConditionView.as_view()(request)
  417. self.assertEqual(response.status_code, 302)
  418. self.assertEqual(response.url, reverse("dashboard:offer-restrictions"))
  419. self.assertJSONEqual(
  420. request.session["offer_wizard"]["metadata"],
  421. self.metadata_form_kwargs_session_data,
  422. )
  423. self.assertJSONEqual(
  424. request.session["offer_wizard"]["metadata_obj"],
  425. self.metadata_obj_session_data,
  426. )
  427. self.assertJSONEqual(
  428. request.session["offer_wizard"]["benefit"],
  429. self.benefit_form_kwargs_session_data,
  430. )
  431. self.assertJSONEqual(
  432. request.session["offer_wizard"]["benefit_obj"],
  433. self.benefit_obj_session_data,
  434. )
  435. self.assertJSONEqual(
  436. request.session["offer_wizard"]["condition"],
  437. {
  438. "data": {
  439. "range": None,
  440. "type": "",
  441. "value": None,
  442. "custom_condition": str(condition.pk),
  443. },
  444. },
  445. )
  446. self.assertJSONEqual(
  447. request.session["offer_wizard"]["condition_obj"],
  448. [
  449. {
  450. "model": "offer.condition",
  451. "pk": condition.pk,
  452. "fields": {
  453. "range": None,
  454. "type": "",
  455. "value": None,
  456. "proxy_class": condition.proxy_class,
  457. },
  458. }
  459. ],
  460. )
  461. def test_offer_restrictions_view(self):
  462. request = RequestFactory().post(
  463. "/",
  464. data={
  465. "priority": 0,
  466. },
  467. )
  468. request.session["offer_wizard"] = {
  469. "metadata": json.dumps(self.metadata_form_kwargs_session_data),
  470. "metadata_obj": json.dumps(self.metadata_obj_session_data),
  471. "benefit": json.dumps(self.benefit_form_kwargs_session_data),
  472. "benefit_obj": json.dumps(self.benefit_obj_session_data),
  473. "condition": json.dumps(self.condition_form_kwargs_session_data),
  474. "condition_obj": json.dumps(self.condition_obj_session_data),
  475. }
  476. response = offer_views.OfferRestrictionsView.as_view()(request)
  477. offer = ConditionalOffer.objects.get()
  478. self.assertEqual(response.status_code, 302)
  479. self.assertEqual(
  480. response.url, reverse("dashboard:offer-detail", kwargs={"pk": offer.pk})
  481. )
  482. self.assertEqual(
  483. [(m.level_tag, str(m.message)) for m in get_messages(request)][0],
  484. ("success", "Offer '%s' created!" % offer.name),
  485. )
  486. self.assertEqual(request.session["offer_wizard"], {})
  487. @freeze_time("2021-04-23 14:00:00")
  488. class TestUpdateOfferWizardStepView(TestCase):
  489. def setUp(self):
  490. self.offer = ConditionalOfferFactory()
  491. self.metadata_form_kwargs_key = "metadata%s" % self.offer.pk
  492. self.metadata_obj_key = "metadata%s_obj" % self.offer.pk
  493. self.benefit_form_kwargs_key = "benefit%s" % self.offer.pk
  494. self.benefit_obj_key = "benefit%s_obj" % self.offer.pk
  495. self.condition_form_kwargs_key = "condition%s" % self.offer.pk
  496. self.condition_obj_key = "condition%s_obj" % self.offer.pk
  497. range_ = RangeFactory()
  498. self.metadata_form_kwargs_session_data = {
  499. "data": {
  500. "name": "Test offer",
  501. "slug": self.offer.slug,
  502. "description": "Test description",
  503. "offer_type": ConditionalOffer.VOUCHER,
  504. "exclusive": True,
  505. "status": ConditionalOffer.OPEN,
  506. "condition": self.offer.condition.pk,
  507. "benefit": self.offer.benefit.pk,
  508. "priority": 0,
  509. "start_datetime": None,
  510. "end_datetime": None,
  511. "max_global_applications": None,
  512. "max_user_applications": None,
  513. "max_basket_applications": None,
  514. "max_discount": None,
  515. "total_discount": "0.00",
  516. "num_applications": 0,
  517. "num_orders": 0,
  518. "redirect_url": "",
  519. "date_created": "2021-04-23T14:00:00Z",
  520. },
  521. }
  522. self.metadata_obj_session_data = [
  523. {
  524. "model": "offer.conditionaloffer",
  525. "pk": None,
  526. "fields": {
  527. "name": "Test offer",
  528. "description": "Test description",
  529. "offer_type": ConditionalOffer.VOUCHER,
  530. },
  531. }
  532. ]
  533. self.benefit_form_kwargs_session_data = {
  534. "data": {
  535. "range": range_.pk,
  536. "type": Benefit.FIXED,
  537. "value": "2000",
  538. "max_affected_items": 2,
  539. "custom_benefit": "",
  540. },
  541. }
  542. self.benefit_obj_session_data = [
  543. {
  544. "model": "offer.benefit",
  545. "pk": None,
  546. "fields": {
  547. "range": range_.pk,
  548. "type": Benefit.FIXED,
  549. "value": "2000",
  550. "max_affected_items": 2,
  551. "proxy_class": "",
  552. },
  553. }
  554. ]
  555. self.condition_form_kwargs_session_data = {
  556. "data": {
  557. "range": range_.pk,
  558. "type": Condition.VALUE,
  559. "value": "2000",
  560. "custom_condition": "",
  561. },
  562. }
  563. self.condition_obj_session_data = [
  564. {
  565. "model": "offer.condition",
  566. "pk": None,
  567. "fields": {
  568. "range": range_.pk,
  569. "type": Condition.VALUE,
  570. "value": "2000",
  571. "proxy_class": "",
  572. },
  573. }
  574. ]
  575. def test_offer_meta_data_view(self):
  576. request = RequestFactory().post(
  577. "/",
  578. data={
  579. "name": "Test offer",
  580. "description": "Test description",
  581. "offer_type": ConditionalOffer.VOUCHER,
  582. },
  583. )
  584. response = offer_views.OfferMetaDataView.as_view(update=True)(
  585. request, pk=self.offer.pk
  586. )
  587. self.assertEqual(response.status_code, 302)
  588. self.assertEqual(
  589. response.url,
  590. reverse("dashboard:offer-benefit", kwargs={"pk": self.offer.pk}),
  591. )
  592. self.assertJSONEqual(
  593. request.session["offer_wizard"][self.metadata_form_kwargs_key],
  594. {
  595. "data": {
  596. "name": "Test offer",
  597. "description": "Test description",
  598. "offer_type": ConditionalOffer.VOUCHER,
  599. },
  600. },
  601. )
  602. self.assertJSONEqual(
  603. request.session["offer_wizard"][self.metadata_obj_key],
  604. [
  605. {
  606. "model": "offer.conditionaloffer",
  607. "pk": self.offer.pk,
  608. "fields": {
  609. "name": "Test offer",
  610. "slug": self.offer.slug,
  611. "description": "Test description",
  612. "offer_type": ConditionalOffer.VOUCHER,
  613. "exclusive": True,
  614. "status": ConditionalOffer.OPEN,
  615. "condition": self.offer.condition.pk,
  616. "benefit": self.offer.benefit.pk,
  617. "priority": 0,
  618. "start_datetime": None,
  619. "end_datetime": None,
  620. "max_global_applications": None,
  621. "max_user_applications": None,
  622. "max_basket_applications": None,
  623. "max_discount": None,
  624. "total_discount": "0.00",
  625. "num_applications": 0,
  626. "num_orders": 0,
  627. "redirect_url": "",
  628. "date_created": "2021-04-23T14:00:00Z",
  629. },
  630. }
  631. ],
  632. )
  633. def test_offer_benefit_view_with_built_in_benefit_type(self):
  634. range_ = RangeFactory()
  635. request = RequestFactory().post(
  636. "/",
  637. data={
  638. "range": range_.pk,
  639. "type": Benefit.FIXED,
  640. "value": 2000,
  641. },
  642. )
  643. request.session["offer_wizard"] = {
  644. self.metadata_form_kwargs_key: json.dumps(
  645. self.metadata_form_kwargs_session_data
  646. ),
  647. self.metadata_obj_key: json.dumps(self.metadata_obj_session_data),
  648. }
  649. response = offer_views.OfferBenefitView.as_view(update=True)(
  650. request, pk=self.offer.pk
  651. )
  652. self.assertEqual(response.status_code, 302)
  653. self.assertEqual(
  654. response.url,
  655. reverse("dashboard:offer-condition", kwargs={"pk": self.offer.pk}),
  656. )
  657. self.assertJSONEqual(
  658. request.session["offer_wizard"][self.metadata_form_kwargs_key],
  659. self.metadata_form_kwargs_session_data,
  660. )
  661. self.assertJSONEqual(
  662. request.session["offer_wizard"][self.metadata_obj_key],
  663. self.metadata_obj_session_data,
  664. )
  665. self.assertJSONEqual(
  666. request.session["offer_wizard"][self.benefit_form_kwargs_key],
  667. {
  668. "data": {
  669. "range": range_.pk,
  670. "type": Benefit.FIXED,
  671. "value": "2000",
  672. "max_affected_items": None,
  673. "custom_benefit": "",
  674. },
  675. },
  676. )
  677. self.assertJSONEqual(
  678. request.session["offer_wizard"][self.benefit_obj_key],
  679. [
  680. {
  681. "model": "offer.benefit",
  682. "pk": self.offer.benefit.pk,
  683. "fields": {
  684. "range": range_.pk,
  685. "type": Benefit.FIXED,
  686. "value": "2000",
  687. "max_affected_items": None,
  688. "proxy_class": "",
  689. },
  690. }
  691. ],
  692. )
  693. def test_offer_benefit_view_with_custom_benefit_type(self):
  694. benefit = create_benefit(CustomBenefitModel)
  695. request = RequestFactory().post(
  696. "/",
  697. data={
  698. "custom_benefit": benefit.pk,
  699. },
  700. )
  701. request.session["offer_wizard"] = {
  702. self.metadata_form_kwargs_key: json.dumps(
  703. self.metadata_form_kwargs_session_data
  704. ),
  705. self.metadata_obj_key: json.dumps(self.metadata_obj_session_data),
  706. }
  707. response = offer_views.OfferBenefitView.as_view(update=True)(
  708. request, pk=self.offer.pk
  709. )
  710. self.assertEqual(response.status_code, 302)
  711. self.assertEqual(
  712. response.url,
  713. reverse("dashboard:offer-condition", kwargs={"pk": self.offer.pk}),
  714. )
  715. self.assertJSONEqual(
  716. request.session["offer_wizard"][self.metadata_form_kwargs_key],
  717. self.metadata_form_kwargs_session_data,
  718. )
  719. self.assertJSONEqual(
  720. request.session["offer_wizard"][self.metadata_obj_key],
  721. self.metadata_obj_session_data,
  722. )
  723. self.assertJSONEqual(
  724. request.session["offer_wizard"][self.benefit_form_kwargs_key],
  725. {
  726. "data": {
  727. "range": None,
  728. "type": "",
  729. "value": None,
  730. "max_affected_items": None,
  731. "custom_benefit": str(benefit.pk),
  732. },
  733. },
  734. )
  735. self.assertJSONEqual(
  736. request.session["offer_wizard"][self.benefit_obj_key],
  737. [
  738. {
  739. "model": "offer.benefit",
  740. "pk": benefit.pk,
  741. "fields": {
  742. "range": None,
  743. "type": "",
  744. "value": None,
  745. "max_affected_items": None,
  746. "proxy_class": benefit.proxy_class,
  747. },
  748. }
  749. ],
  750. )
  751. def test_offer_condition_view_with_built_in_condition_type(self):
  752. range_ = RangeFactory()
  753. request = RequestFactory().post(
  754. "/",
  755. data={
  756. "range": range_.pk,
  757. "type": Condition.VALUE,
  758. "value": 2000,
  759. },
  760. )
  761. request.session["offer_wizard"] = {
  762. self.metadata_form_kwargs_key: json.dumps(
  763. self.metadata_form_kwargs_session_data
  764. ),
  765. self.metadata_obj_key: json.dumps(self.metadata_obj_session_data),
  766. self.benefit_form_kwargs_key: json.dumps(
  767. self.benefit_form_kwargs_session_data
  768. ),
  769. self.benefit_obj_key: json.dumps(self.benefit_obj_session_data),
  770. }
  771. response = offer_views.OfferConditionView.as_view(update=True)(
  772. request, pk=self.offer.pk
  773. )
  774. self.assertEqual(response.status_code, 302)
  775. self.assertEqual(
  776. response.url,
  777. reverse("dashboard:offer-restrictions", kwargs={"pk": self.offer.pk}),
  778. )
  779. self.assertJSONEqual(
  780. request.session["offer_wizard"][self.metadata_form_kwargs_key],
  781. self.metadata_form_kwargs_session_data,
  782. )
  783. self.assertJSONEqual(
  784. request.session["offer_wizard"][self.metadata_obj_key],
  785. self.metadata_obj_session_data,
  786. )
  787. self.assertJSONEqual(
  788. request.session["offer_wizard"][self.benefit_form_kwargs_key],
  789. self.benefit_form_kwargs_session_data,
  790. )
  791. self.assertJSONEqual(
  792. request.session["offer_wizard"][self.benefit_obj_key],
  793. self.benefit_obj_session_data,
  794. )
  795. self.assertJSONEqual(
  796. request.session["offer_wizard"][self.condition_form_kwargs_key],
  797. {
  798. "data": {
  799. "range": range_.pk,
  800. "type": Condition.VALUE,
  801. "value": "2000",
  802. "custom_condition": "",
  803. },
  804. },
  805. )
  806. self.assertJSONEqual(
  807. request.session["offer_wizard"][self.condition_obj_key],
  808. [
  809. {
  810. "model": "offer.condition",
  811. "pk": self.offer.condition.pk,
  812. "fields": {
  813. "range": range_.pk,
  814. "type": Condition.VALUE,
  815. "value": "2000",
  816. "proxy_class": "",
  817. },
  818. }
  819. ],
  820. )
  821. def test_offer_condition_view_with_custom_condition_type(self):
  822. condition = create_condition(CustomConditionModel)
  823. request = RequestFactory().post(
  824. "/",
  825. data={
  826. "custom_condition": condition.pk,
  827. },
  828. )
  829. request.session["offer_wizard"] = {
  830. self.metadata_form_kwargs_key: json.dumps(
  831. self.metadata_form_kwargs_session_data
  832. ),
  833. self.metadata_obj_key: json.dumps(self.metadata_obj_session_data),
  834. self.benefit_form_kwargs_key: json.dumps(
  835. self.benefit_form_kwargs_session_data
  836. ),
  837. self.benefit_obj_key: json.dumps(self.benefit_obj_session_data),
  838. }
  839. response = offer_views.OfferConditionView.as_view(update=True)(
  840. request, pk=self.offer.pk
  841. )
  842. self.assertEqual(response.status_code, 302)
  843. self.assertEqual(
  844. response.url,
  845. reverse("dashboard:offer-restrictions", kwargs={"pk": self.offer.pk}),
  846. )
  847. self.assertJSONEqual(
  848. request.session["offer_wizard"][self.metadata_form_kwargs_key],
  849. self.metadata_form_kwargs_session_data,
  850. )
  851. self.assertJSONEqual(
  852. request.session["offer_wizard"][self.metadata_obj_key],
  853. self.metadata_obj_session_data,
  854. )
  855. self.assertJSONEqual(
  856. request.session["offer_wizard"][self.benefit_form_kwargs_key],
  857. self.benefit_form_kwargs_session_data,
  858. )
  859. self.assertJSONEqual(
  860. request.session["offer_wizard"][self.benefit_obj_key],
  861. self.benefit_obj_session_data,
  862. )
  863. self.assertJSONEqual(
  864. request.session["offer_wizard"][self.condition_form_kwargs_key],
  865. {
  866. "data": {
  867. "range": None,
  868. "type": "",
  869. "value": None,
  870. "custom_condition": str(condition.pk),
  871. },
  872. },
  873. )
  874. self.assertJSONEqual(
  875. request.session["offer_wizard"][self.condition_obj_key],
  876. [
  877. {
  878. "model": "offer.condition",
  879. "pk": condition.pk,
  880. "fields": {
  881. "range": None,
  882. "type": "",
  883. "value": None,
  884. "proxy_class": condition.proxy_class,
  885. },
  886. }
  887. ],
  888. )
  889. def test_offer_restrictions_view(self):
  890. request = RequestFactory().post(
  891. "/",
  892. data={
  893. "priority": 0,
  894. },
  895. )
  896. request.session["offer_wizard"] = {
  897. self.metadata_form_kwargs_key: json.dumps(
  898. self.metadata_form_kwargs_session_data
  899. ),
  900. self.metadata_obj_key: json.dumps(self.metadata_obj_session_data),
  901. self.benefit_form_kwargs_key: json.dumps(
  902. self.benefit_form_kwargs_session_data
  903. ),
  904. self.benefit_obj_key: json.dumps(self.benefit_obj_session_data),
  905. self.condition_form_kwargs_key: json.dumps(
  906. self.condition_form_kwargs_session_data
  907. ),
  908. self.condition_obj_key: json.dumps(self.condition_obj_session_data),
  909. }
  910. response = offer_views.OfferRestrictionsView.as_view(update=True)(
  911. request, pk=self.offer.pk
  912. )
  913. self.offer.refresh_from_db()
  914. self.assertEqual(response.status_code, 302)
  915. self.assertEqual(
  916. response.url,
  917. reverse("dashboard:offer-detail", kwargs={"pk": self.offer.pk}),
  918. )
  919. self.assertEqual(
  920. [(m.level_tag, str(m.message)) for m in get_messages(request)][0],
  921. ("success", "Offer '%s' updated" % self.offer.name),
  922. )
  923. self.assertEqual(request.session["offer_wizard"], {})