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.

171 lines
5.9 KiB

  1. # Copyright 2017 Jairo Llopis <jairo.llopis@tecnativa.com>
  2. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  3. from datetime import datetime, timedelta
  4. from mock import patch
  5. from odoo import fields
  6. from odoo.tests.common import SavepointCase
  7. PATH = "odoo.addons.partner_phonecall_schedule.models.res_partner.datetime"
  8. class CanICallCase(SavepointCase):
  9. @classmethod
  10. def setUpClass(cls):
  11. super(CanICallCase, cls).setUpClass()
  12. cls.Calendar = cls.env["resource.calendar"].with_context(tz="UTC")
  13. cls.Partner = cls.env["res.partner"].with_context(tz="UTC")
  14. cls.some_mornings = cls.Calendar.create({
  15. "name": "Some mornings",
  16. "attendance_ids": [
  17. (0, 0, {
  18. "name": "Friday morning",
  19. "dayofweek": "4",
  20. "hour_from": 8,
  21. "hour_to": 12,
  22. }),
  23. (0, 0, {
  24. "name": "Next monday morning",
  25. "dayofweek": "0",
  26. "hour_from": 8,
  27. "hour_to": 12,
  28. "date_from": "2017-09-18",
  29. "date_to": "2017-09-18",
  30. }),
  31. ],
  32. })
  33. cls.some_evenings = cls.Calendar.create({
  34. "name": "Some evenings",
  35. "attendance_ids": [
  36. (0, 0, {
  37. "name": "Friday evening",
  38. "dayofweek": "4",
  39. "hour_from": 15,
  40. "hour_to": 19,
  41. }),
  42. (0, 0, {
  43. "name": "Next monday evening",
  44. "dayofweek": "0",
  45. "hour_from": 15,
  46. "hour_to": 19,
  47. "date_from": "2017-09-18",
  48. "date_to": "2017-09-18",
  49. }),
  50. ],
  51. })
  52. cls.dude = cls.Partner.create({
  53. "name": "Dude",
  54. })
  55. cls.dude.phonecall_calendar_ids = cls.some_mornings
  56. def setUp(self):
  57. super(CanICallCase, self).setUp()
  58. # Now it is a friday morning
  59. self.datetime = datetime(2017, 9, 15, 10, 53, 30)
  60. def _allowed(self, now=None):
  61. dude, Partner = self.dude, self.Partner
  62. if now:
  63. dude = dude.with_context(now=now)
  64. Partner = Partner.with_context(now=now)
  65. self.assertTrue(dude.phonecall_available)
  66. self.assertTrue(Partner.search([
  67. ("id", "=", dude.id),
  68. ("phonecall_available", "=", True),
  69. ]))
  70. self.assertTrue(Partner.search([
  71. ("id", "=", dude.id),
  72. ("phonecall_available", "!=", False),
  73. ]))
  74. self.assertFalse(Partner.search([
  75. ("id", "=", dude.id),
  76. ("phonecall_available", "=", False),
  77. ]))
  78. self.assertFalse(Partner.search([
  79. ("id", "=", dude.id),
  80. ("phonecall_available", "!=", True),
  81. ]))
  82. def allowed(self):
  83. # Test mocking datetime.now()
  84. with patch(PATH) as mocked_dt:
  85. mocked_dt.now.return_value = self.datetime
  86. mocked_dt.date.return_value = self.datetime.date()
  87. self._allowed()
  88. # Test sending a datetime object in the context
  89. self._allowed(self.datetime)
  90. # Test sending a string in the context
  91. self._allowed(
  92. fields.Datetime.to_string(self.datetime))
  93. def _disallowed(self, now=None):
  94. dude, Partner = self.dude, self.Partner
  95. if now:
  96. dude = dude.with_context(now=now)
  97. Partner = Partner.with_context(now=now)
  98. self.assertFalse(dude.phonecall_available)
  99. self.assertFalse(Partner.search([
  100. ("id", "=", dude.id),
  101. ("phonecall_available", "=", True),
  102. ]))
  103. self.assertFalse(Partner.search([
  104. ("id", "=", dude.id),
  105. ("phonecall_available", "!=", False),
  106. ]))
  107. self.assertTrue(Partner.search([
  108. ("id", "=", dude.id),
  109. ("phonecall_available", "=", False),
  110. ]))
  111. self.assertTrue(Partner.search([
  112. ("id", "=", dude.id),
  113. ("phonecall_available", "!=", True),
  114. ]))
  115. def disallowed(self):
  116. # Test mocking datetime.now()
  117. with patch(PATH) as mocked_dt:
  118. mocked_dt.now.return_value = self.datetime
  119. mocked_dt.date.return_value = self.datetime.date()
  120. self._disallowed()
  121. # Test sending a datetime object in the context
  122. self._disallowed(self.datetime)
  123. # Test sending a string in the context
  124. self._disallowed(
  125. fields.Datetime.to_string(self.datetime))
  126. def test_friday_morning(self):
  127. """I can call dude this morning"""
  128. self.allowed()
  129. def test_friday_evening(self):
  130. """I cannot call dude this evening"""
  131. self.datetime += timedelta(hours=4)
  132. self.disallowed()
  133. def test_saturday_morning(self):
  134. """I cannot call dude tomorrow morning"""
  135. self.datetime += timedelta(days=1)
  136. self.disallowed()
  137. def test_saturday_evening(self):
  138. """I cannot call dude tomorrow evening"""
  139. self.datetime += timedelta(days=1, hours=4)
  140. self.disallowed()
  141. def test_next_monday_morning(self):
  142. """I can call dude next monday morning"""
  143. self.datetime += timedelta(days=3)
  144. self.allowed()
  145. def test_second_next_monday_morning(self):
  146. """I cannot call dude second next monday morning"""
  147. self.datetime += timedelta(days=10, hours=4)
  148. self.disallowed()
  149. def test_aggregated_attendances(self):
  150. """I get aggregated schedules correctly."""
  151. self.dude.phonecall_calendar_ids |= self.some_evenings
  152. all_attendances = (self.some_mornings | self.some_evenings).mapped(
  153. "attendance_ids")
  154. self.assertEqual(
  155. self.dude.phonecall_calendar_attendance_ids, all_attendances)