tests.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. from __future__ import unicode_literals
  2. from operator import attrgetter
  3. from django.test import TestCase
  4. from .models import Person
  5. class RecursiveM2MTests(TestCase):
  6. def setUp(self):
  7. self.a, self.b, self.c, self.d = [
  8. Person.objects.create(name=name)
  9. for name in ["Anne", "Bill", "Chuck", "David"]
  10. ]
  11. # Anne is friends with Bill and Chuck
  12. self.a.friends.add(self.b, self.c)
  13. # David is friends with Anne and Chuck - add in reverse direction
  14. self.d.friends.add(self.a, self.c)
  15. def test_recursive_m2m_all(self):
  16. """ Test that m2m relations are reported correctly """
  17. # Who is friends with Anne?
  18. self.assertQuerysetEqual(
  19. self.a.friends.all(), [
  20. "Bill",
  21. "Chuck",
  22. "David"
  23. ],
  24. attrgetter("name"),
  25. ordered=False
  26. )
  27. # Who is friends with Bill?
  28. self.assertQuerysetEqual(
  29. self.b.friends.all(), [
  30. "Anne",
  31. ],
  32. attrgetter("name")
  33. )
  34. # Who is friends with Chuck?
  35. self.assertQuerysetEqual(
  36. self.c.friends.all(), [
  37. "Anne",
  38. "David"
  39. ],
  40. attrgetter("name"),
  41. ordered=False
  42. )
  43. # Who is friends with David?
  44. self.assertQuerysetEqual(
  45. self.d.friends.all(), [
  46. "Anne",
  47. "Chuck",
  48. ],
  49. attrgetter("name"),
  50. ordered=False
  51. )
  52. def test_recursive_m2m_reverse_add(self):
  53. """ Test reverse m2m relation is consistent """
  54. # Bill is already friends with Anne - add Anne again, but in the
  55. # reverse direction
  56. self.b.friends.add(self.a)
  57. # Who is friends with Anne?
  58. self.assertQuerysetEqual(
  59. self.a.friends.all(), [
  60. "Bill",
  61. "Chuck",
  62. "David",
  63. ],
  64. attrgetter("name"),
  65. ordered=False
  66. )
  67. # Who is friends with Bill?
  68. self.assertQuerysetEqual(
  69. self.b.friends.all(), [
  70. "Anne",
  71. ],
  72. attrgetter("name")
  73. )
  74. def test_recursive_m2m_remove(self):
  75. """ Test that we can remove items from an m2m relationship """
  76. # Remove Anne from Bill's friends
  77. self.b.friends.remove(self.a)
  78. # Who is friends with Anne?
  79. self.assertQuerysetEqual(
  80. self.a.friends.all(), [
  81. "Chuck",
  82. "David",
  83. ],
  84. attrgetter("name"),
  85. ordered=False
  86. )
  87. # Who is friends with Bill?
  88. self.assertQuerysetEqual(
  89. self.b.friends.all(), []
  90. )
  91. def test_recursive_m2m_clear(self):
  92. """ Tests the clear method works as expected on m2m fields """
  93. # Clear Anne's group of friends
  94. self.a.friends.clear()
  95. # Who is friends with Anne?
  96. self.assertQuerysetEqual(
  97. self.a.friends.all(), []
  98. )
  99. # Reverse relationships should also be gone
  100. # Who is friends with Chuck?
  101. self.assertQuerysetEqual(
  102. self.c.friends.all(), [
  103. "David",
  104. ],
  105. attrgetter("name")
  106. )
  107. # Who is friends with David?
  108. self.assertQuerysetEqual(
  109. self.d.friends.all(), [
  110. "Chuck",
  111. ],
  112. attrgetter("name")
  113. )
  114. def test_recursive_m2m_add_via_related_name(self):
  115. """ Tests that we can add m2m relations via the related_name attribute """
  116. # David is idolized by Anne and Chuck - add in reverse direction
  117. self.d.stalkers.add(self.a)
  118. # Who are Anne's idols?
  119. self.assertQuerysetEqual(
  120. self.a.idols.all(), [
  121. "David",
  122. ],
  123. attrgetter("name"),
  124. ordered=False
  125. )
  126. # Who is stalking Anne?
  127. self.assertQuerysetEqual(
  128. self.a.stalkers.all(), [],
  129. attrgetter("name")
  130. )
  131. def test_recursive_m2m_add_in_both_directions(self):
  132. """ Check that adding the same relation twice results in a single relation """
  133. # Ann idolizes David
  134. self.a.idols.add(self.d)
  135. # David is idolized by Anne
  136. self.d.stalkers.add(self.a)
  137. # Who are Anne's idols?
  138. self.assertQuerysetEqual(
  139. self.a.idols.all(), [
  140. "David",
  141. ],
  142. attrgetter("name"),
  143. ordered=False
  144. )
  145. # As the assertQuerysetEqual uses a set for comparison,
  146. # check we've only got David listed once
  147. self.assertEqual(self.a.idols.all().count(), 1)
  148. def test_recursive_m2m_related_to_self(self):
  149. """ Check the expected behavior when an instance is related to itself """
  150. # Ann idolizes herself
  151. self.a.idols.add(self.a)
  152. # Who are Anne's idols?
  153. self.assertQuerysetEqual(
  154. self.a.idols.all(), [
  155. "Anne",
  156. ],
  157. attrgetter("name"),
  158. ordered=False
  159. )
  160. # Who is stalking Anne?
  161. self.assertQuerysetEqual(
  162. self.a.stalkers.all(), [
  163. "Anne",
  164. ],
  165. attrgetter("name")
  166. )