Refs #18586 -- Split up tests/m2m_signals
This commit is contained in:
parent
02a2943e4c
commit
82ec05fcc9
|
@ -28,6 +28,7 @@ class ManyToManySignalsTest(TestCase):
|
||||||
self.vw = Car.objects.create(name='VW')
|
self.vw = Car.objects.create(name='VW')
|
||||||
self.bmw = Car.objects.create(name='BMW')
|
self.bmw = Car.objects.create(name='BMW')
|
||||||
self.toyota = Car.objects.create(name='Toyota')
|
self.toyota = Car.objects.create(name='Toyota')
|
||||||
|
|
||||||
self.wheelset = Part.objects.create(name='Wheelset')
|
self.wheelset = Part.objects.create(name='Wheelset')
|
||||||
self.doors = Part.objects.create(name='Doors')
|
self.doors = Part.objects.create(name='Doors')
|
||||||
self.engine = Part.objects.create(name='Engine')
|
self.engine = Part.objects.create(name='Engine')
|
||||||
|
@ -54,25 +55,23 @@ class ManyToManySignalsTest(TestCase):
|
||||||
self.m2m_changed_signal_receiver, Person.friends.through
|
self.m2m_changed_signal_receiver, Person.friends.through
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_m2m_relations_add_remove_clear(self):
|
def _initialize_signal_car(self, add_default_parts_before_set_signal=False):
|
||||||
expected_messages = []
|
""" Install a listener on the two m2m relations. """
|
||||||
|
|
||||||
# Install a listener on one of the two m2m relations.
|
|
||||||
models.signals.m2m_changed.connect(
|
models.signals.m2m_changed.connect(
|
||||||
self.m2m_changed_signal_receiver, Car.optional_parts.through
|
self.m2m_changed_signal_receiver, Car.optional_parts.through
|
||||||
)
|
)
|
||||||
|
if add_default_parts_before_set_signal:
|
||||||
# Test the add, remove and clear methods on both sides of the
|
# adding a default part to our car - no signal listener installed
|
||||||
# many-to-many relation
|
self.vw.default_parts.add(self.sunroof)
|
||||||
|
|
||||||
# adding a default part to our car - no signal listener installed
|
|
||||||
self.vw.default_parts.add(self.sunroof)
|
|
||||||
|
|
||||||
# Now install a listener
|
|
||||||
models.signals.m2m_changed.connect(
|
models.signals.m2m_changed.connect(
|
||||||
self.m2m_changed_signal_receiver, Car.default_parts.through
|
self.m2m_changed_signal_receiver, Car.default_parts.through
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_m2m_relations_add_remove_clear(self):
|
||||||
|
expected_messages = []
|
||||||
|
|
||||||
|
self._initialize_signal_car(add_default_parts_before_set_signal=True)
|
||||||
|
|
||||||
self.vw.default_parts.add(self.wheelset, self.doors, self.engine)
|
self.vw.default_parts.add(self.wheelset, self.doors, self.engine)
|
||||||
expected_messages.append({
|
expected_messages.append({
|
||||||
'instance': self.vw,
|
'instance': self.vw,
|
||||||
|
@ -108,24 +107,31 @@ class ManyToManySignalsTest(TestCase):
|
||||||
})
|
})
|
||||||
self.assertEqual(self.m2m_changed_messages, expected_messages)
|
self.assertEqual(self.m2m_changed_messages, expected_messages)
|
||||||
|
|
||||||
|
def test_m2m_relations_signals_remove_relation(self):
|
||||||
|
self._initialize_signal_car()
|
||||||
# remove the engine from the self.vw and the airbag (which is not set
|
# remove the engine from the self.vw and the airbag (which is not set
|
||||||
# but is returned)
|
# but is returned)
|
||||||
self.vw.default_parts.remove(self.engine, self.airbag)
|
self.vw.default_parts.remove(self.engine, self.airbag)
|
||||||
expected_messages.append({
|
self.assertEqual(self.m2m_changed_messages, [
|
||||||
'instance': self.vw,
|
{
|
||||||
'action': 'pre_remove',
|
'instance': self.vw,
|
||||||
'reverse': False,
|
'action': 'pre_remove',
|
||||||
'model': Part,
|
'reverse': False,
|
||||||
'objects': [self.airbag, self.engine],
|
'model': Part,
|
||||||
})
|
'objects': [self.airbag, self.engine],
|
||||||
expected_messages.append({
|
}, {
|
||||||
'instance': self.vw,
|
'instance': self.vw,
|
||||||
'action': 'post_remove',
|
'action': 'post_remove',
|
||||||
'reverse': False,
|
'reverse': False,
|
||||||
'model': Part,
|
'model': Part,
|
||||||
'objects': [self.airbag, self.engine],
|
'objects': [self.airbag, self.engine],
|
||||||
})
|
}
|
||||||
self.assertEqual(self.m2m_changed_messages, expected_messages)
|
])
|
||||||
|
|
||||||
|
def test_m2m_relations_signals_give_the_self_vw_some_optional_parts(self):
|
||||||
|
expected_messages = []
|
||||||
|
|
||||||
|
self._initialize_signal_car()
|
||||||
|
|
||||||
# give the self.vw some optional parts (second relation to same model)
|
# give the self.vw some optional parts (second relation to same model)
|
||||||
self.vw.optional_parts.add(self.airbag, self.sunroof)
|
self.vw.optional_parts.add(self.airbag, self.sunroof)
|
||||||
|
@ -163,73 +169,86 @@ class ManyToManySignalsTest(TestCase):
|
||||||
})
|
})
|
||||||
self.assertEqual(self.m2m_changed_messages, expected_messages)
|
self.assertEqual(self.m2m_changed_messages, expected_messages)
|
||||||
|
|
||||||
|
def test_m2m_relations_signals_reverse_relation_with_custom_related_name(self):
|
||||||
|
self._initialize_signal_car()
|
||||||
# remove airbag from the self.vw (reverse relation with custom
|
# remove airbag from the self.vw (reverse relation with custom
|
||||||
# related_name)
|
# related_name)
|
||||||
self.airbag.cars_optional.remove(self.vw)
|
self.airbag.cars_optional.remove(self.vw)
|
||||||
expected_messages.append({
|
self.assertEqual(self.m2m_changed_messages, [
|
||||||
'instance': self.airbag,
|
{
|
||||||
'action': 'pre_remove',
|
'instance': self.airbag,
|
||||||
'reverse': True,
|
'action': 'pre_remove',
|
||||||
'model': Car,
|
'reverse': True,
|
||||||
'objects': [self.vw],
|
'model': Car,
|
||||||
})
|
'objects': [self.vw],
|
||||||
expected_messages.append({
|
}, {
|
||||||
'instance': self.airbag,
|
'instance': self.airbag,
|
||||||
'action': 'post_remove',
|
'action': 'post_remove',
|
||||||
'reverse': True,
|
'reverse': True,
|
||||||
'model': Car,
|
'model': Car,
|
||||||
'objects': [self.vw],
|
'objects': [self.vw],
|
||||||
})
|
}
|
||||||
self.assertEqual(self.m2m_changed_messages, expected_messages)
|
])
|
||||||
|
|
||||||
|
def test_m2m_relations_signals_clear_all_parts_of_the_self_vw(self):
|
||||||
|
self._initialize_signal_car()
|
||||||
# clear all parts of the self.vw
|
# clear all parts of the self.vw
|
||||||
self.vw.default_parts.clear()
|
self.vw.default_parts.clear()
|
||||||
expected_messages.append({
|
self.assertEqual(self.m2m_changed_messages, [
|
||||||
'instance': self.vw,
|
{
|
||||||
'action': 'pre_clear',
|
'instance': self.vw,
|
||||||
'reverse': False,
|
'action': 'pre_clear',
|
||||||
'model': Part,
|
'reverse': False,
|
||||||
})
|
'model': Part,
|
||||||
expected_messages.append({
|
}, {
|
||||||
'instance': self.vw,
|
'instance': self.vw,
|
||||||
'action': 'post_clear',
|
'action': 'post_clear',
|
||||||
'reverse': False,
|
'reverse': False,
|
||||||
'model': Part,
|
'model': Part,
|
||||||
})
|
}
|
||||||
self.assertEqual(self.m2m_changed_messages, expected_messages)
|
])
|
||||||
|
|
||||||
|
def test_m2m_relations_signals_all_the_doors_off_of_cars(self):
|
||||||
|
self._initialize_signal_car()
|
||||||
# take all the doors off of cars
|
# take all the doors off of cars
|
||||||
self.doors.car_set.clear()
|
self.doors.car_set.clear()
|
||||||
expected_messages.append({
|
self.assertEqual(self.m2m_changed_messages, [
|
||||||
'instance': self.doors,
|
{
|
||||||
'action': 'pre_clear',
|
'instance': self.doors,
|
||||||
'reverse': True,
|
'action': 'pre_clear',
|
||||||
'model': Car,
|
'reverse': True,
|
||||||
})
|
'model': Car,
|
||||||
expected_messages.append({
|
}, {
|
||||||
'instance': self.doors,
|
'instance': self.doors,
|
||||||
'action': 'post_clear',
|
'action': 'post_clear',
|
||||||
'reverse': True,
|
'reverse': True,
|
||||||
'model': Car,
|
'model': Car,
|
||||||
})
|
}
|
||||||
self.assertEqual(self.m2m_changed_messages, expected_messages)
|
])
|
||||||
|
|
||||||
|
def test_m2m_relations_signals_reverse_relation(self):
|
||||||
|
self._initialize_signal_car()
|
||||||
# take all the airbags off of cars (clear reverse relation with custom
|
# take all the airbags off of cars (clear reverse relation with custom
|
||||||
# related_name)
|
# related_name)
|
||||||
self.airbag.cars_optional.clear()
|
self.airbag.cars_optional.clear()
|
||||||
expected_messages.append({
|
self.assertEqual(self.m2m_changed_messages, [
|
||||||
'instance': self.airbag,
|
{
|
||||||
'action': 'pre_clear',
|
'instance': self.airbag,
|
||||||
'reverse': True,
|
'action': 'pre_clear',
|
||||||
'model': Car,
|
'reverse': True,
|
||||||
})
|
'model': Car,
|
||||||
expected_messages.append({
|
}, {
|
||||||
'instance': self.airbag,
|
'instance': self.airbag,
|
||||||
'action': 'post_clear',
|
'action': 'post_clear',
|
||||||
'reverse': True,
|
'reverse': True,
|
||||||
'model': Car,
|
'model': Car,
|
||||||
})
|
}
|
||||||
self.assertEqual(self.m2m_changed_messages, expected_messages)
|
])
|
||||||
|
|
||||||
|
def test_m2m_relations_signals_alternative_ways(self):
|
||||||
|
expected_messages = []
|
||||||
|
|
||||||
|
self._initialize_signal_car()
|
||||||
|
|
||||||
# alternative ways of setting relation:
|
# alternative ways of setting relation:
|
||||||
self.vw.default_parts.create(name='Windows')
|
self.vw.default_parts.create(name='Windows')
|
||||||
|
@ -282,6 +301,11 @@ class ManyToManySignalsTest(TestCase):
|
||||||
})
|
})
|
||||||
self.assertEqual(self.m2m_changed_messages, expected_messages)
|
self.assertEqual(self.m2m_changed_messages, expected_messages)
|
||||||
|
|
||||||
|
def test_m2m_relations_signals_clearing_removing(self):
|
||||||
|
expected_messages = []
|
||||||
|
|
||||||
|
self._initialize_signal_car(add_default_parts_before_set_signal=True)
|
||||||
|
|
||||||
# set by clearing.
|
# set by clearing.
|
||||||
self.vw.default_parts.set([self.wheelset, self.doors, self.engine], clear=True)
|
self.vw.default_parts.set([self.wheelset, self.doors, self.engine], clear=True)
|
||||||
expected_messages.append({
|
expected_messages.append({
|
||||||
|
@ -330,6 +354,11 @@ class ManyToManySignalsTest(TestCase):
|
||||||
})
|
})
|
||||||
self.assertEqual(self.m2m_changed_messages, expected_messages)
|
self.assertEqual(self.m2m_changed_messages, expected_messages)
|
||||||
|
|
||||||
|
def test_m2m_relations_signals_when_inheritance(self):
|
||||||
|
expected_messages = []
|
||||||
|
|
||||||
|
self._initialize_signal_car(add_default_parts_before_set_signal=True)
|
||||||
|
|
||||||
# Check that signals still work when model inheritance is involved
|
# Check that signals still work when model inheritance is involved
|
||||||
c4 = SportsCar.objects.create(name='Bugatti', price='1000000')
|
c4 = SportsCar.objects.create(name='Bugatti', price='1000000')
|
||||||
c4b = Car.objects.get(name='Bugatti')
|
c4b = Car.objects.get(name='Bugatti')
|
||||||
|
@ -367,9 +396,8 @@ class ManyToManySignalsTest(TestCase):
|
||||||
})
|
})
|
||||||
self.assertEqual(self.m2m_changed_messages, expected_messages)
|
self.assertEqual(self.m2m_changed_messages, expected_messages)
|
||||||
|
|
||||||
def test_m2m_relations_with_self(self):
|
def _initialize_signal_person(self):
|
||||||
expected_messages = []
|
# Install a listener on the two m2m relations.
|
||||||
|
|
||||||
models.signals.m2m_changed.connect(
|
models.signals.m2m_changed.connect(
|
||||||
self.m2m_changed_signal_receiver, Person.fans.through
|
self.m2m_changed_signal_receiver, Person.fans.through
|
||||||
)
|
)
|
||||||
|
@ -377,53 +405,59 @@ class ManyToManySignalsTest(TestCase):
|
||||||
self.m2m_changed_signal_receiver, Person.friends.through
|
self.m2m_changed_signal_receiver, Person.friends.through
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_m2m_relations_with_self_add_friends(self):
|
||||||
|
self._initialize_signal_person()
|
||||||
self.alice.friends = [self.bob, self.chuck]
|
self.alice.friends = [self.bob, self.chuck]
|
||||||
expected_messages.append({
|
self.assertEqual(self.m2m_changed_messages, [
|
||||||
'instance': self.alice,
|
{
|
||||||
'action': 'pre_add',
|
'instance': self.alice,
|
||||||
'reverse': False,
|
'action': 'pre_add',
|
||||||
'model': Person,
|
'reverse': False,
|
||||||
'objects': [self.bob, self.chuck],
|
'model': Person,
|
||||||
})
|
'objects': [self.bob, self.chuck],
|
||||||
expected_messages.append({
|
}, {
|
||||||
'instance': self.alice,
|
'instance': self.alice,
|
||||||
'action': 'post_add',
|
'action': 'post_add',
|
||||||
'reverse': False,
|
'reverse': False,
|
||||||
'model': Person,
|
'model': Person,
|
||||||
'objects': [self.bob, self.chuck],
|
'objects': [self.bob, self.chuck],
|
||||||
})
|
}
|
||||||
self.assertEqual(self.m2m_changed_messages, expected_messages)
|
])
|
||||||
|
|
||||||
|
def test_m2m_relations_with_self_add_fan(self):
|
||||||
|
self._initialize_signal_person()
|
||||||
self.alice.fans = [self.daisy]
|
self.alice.fans = [self.daisy]
|
||||||
expected_messages.append({
|
self.assertEqual(self.m2m_changed_messages, [
|
||||||
'instance': self.alice,
|
{
|
||||||
'action': 'pre_add',
|
'instance': self.alice,
|
||||||
'reverse': False,
|
'action': 'pre_add',
|
||||||
'model': Person,
|
'reverse': False,
|
||||||
'objects': [self.daisy],
|
'model': Person,
|
||||||
})
|
'objects': [self.daisy],
|
||||||
expected_messages.append({
|
}, {
|
||||||
'instance': self.alice,
|
'instance': self.alice,
|
||||||
'action': 'post_add',
|
'action': 'post_add',
|
||||||
'reverse': False,
|
'reverse': False,
|
||||||
'model': Person,
|
'model': Person,
|
||||||
'objects': [self.daisy],
|
'objects': [self.daisy],
|
||||||
})
|
}
|
||||||
self.assertEqual(self.m2m_changed_messages, expected_messages)
|
])
|
||||||
|
|
||||||
|
def test_m2m_relations_with_self_add_idols(self):
|
||||||
|
self._initialize_signal_person()
|
||||||
self.chuck.idols = [self.alice, self.bob]
|
self.chuck.idols = [self.alice, self.bob]
|
||||||
expected_messages.append({
|
self.assertEqual(self.m2m_changed_messages, [
|
||||||
'instance': self.chuck,
|
{
|
||||||
'action': 'pre_add',
|
'instance': self.chuck,
|
||||||
'reverse': True,
|
'action': 'pre_add',
|
||||||
'model': Person,
|
'reverse': True,
|
||||||
'objects': [self.alice, self.bob],
|
'model': Person,
|
||||||
})
|
'objects': [self.alice, self.bob],
|
||||||
expected_messages.append({
|
}, {
|
||||||
'instance': self.chuck,
|
'instance': self.chuck,
|
||||||
'action': 'post_add',
|
'action': 'post_add',
|
||||||
'reverse': True,
|
'reverse': True,
|
||||||
'model': Person,
|
'model': Person,
|
||||||
'objects': [self.alice, self.bob],
|
'objects': [self.alice, self.bob],
|
||||||
})
|
}
|
||||||
self.assertEqual(self.m2m_changed_messages, expected_messages)
|
])
|
||||||
|
|
Loading…
Reference in New Issue