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.

181 lines
6.3 KiB

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