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.

173 lines
5.9 KiB

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