def test_get_signal_function(self): # check cache f = FileFieldAutoDelete('file_field') a = f.get_signal_function() b = f.get_signal_function() self.assertIs(a, b) # with file_field mock = MagicMock() a(None, mock) self.assertGreater(len(mock.mock_calls), 1) self.assertIn(call.file_field.delete(save=False), mock.mock_calls) # file_field not there as returned by __nonzero__() == 0 mock = MagicMock() try: mock.file_field.__nonzero__.return_value = 0 # Python 2 except AttributeError: mock.file_field.__bool__.return_value = False # Python 3 a(None, mock) self.assertEqual(len(mock.mock_calls), 1) self.assertNotIn(call.file_field.delete(save=False), mock.mock_calls)
def test_connect_signal_function(self): self.disconnect_signals() f = FileFieldAutoDelete('file_field') f(self.get_model()) self.assertEqual(len(models.signals.post_delete.receivers), 1) self.assertIs(models.signals.post_delete.receivers[0][1], f.get_signal_function()) self.restore_signals() self.disconnect_signals() mock = MagicMock() f = FileFieldAutoDelete('file_field', signal=mock) m = self.get_model() f(m) self.assertEqual(len(mock.mock_calls), 1) self.assertEqual(mock.mock_calls[0], call.connect( f.get_signal_function(), weak=False, dispatch_uid='post_delete_Model_delete_file_field', sender=m )) self.restore_signals()
def test_get_signal_name(self): names = ('foo', 'bar',) for n in names: f = FileFieldAutoDelete(n, signal_name_pattern=n) f.to_wrap = None self.assertEqual(f.get_signal_name(), n) f = FileFieldAutoDelete(n) class foo(object): def __getattribute__(self, item): if item == '__name__': return n else: return object.__getattribute__(self, item) f.to_wrap = foo() self.assertEqual(f.get_signal_name(), 'post_delete_{0}_delete_{0}'.format(n))
def setup_method(self, method): self.decorator = FileFieldAutoDelete()
class TestFileFieldAutoDelete(object): def setup_method(self, method): self.decorator = FileFieldAutoDelete() def get_model(self): class Model(models.Model): file_field = models.FileField(upload_to='foo') foo_field = models.CharField(max_length=32) class Meta(object): app_label = 'foo' return Model def get_empty_model(self): class ModelEmpty(models.Model): class Meta(object): app_label = 'foo' return ModelEmpty def test_init(self): decorator = FileFieldAutoDelete() assert decorator.field_names == '*' assert decorator.signal is models.signals.post_delete assert decorator.signal_name_pattern == 'post_delete_{model.__name__}_delete_{field}' @mock.patch.object(FileFieldAutoDelete, 'connect_signal_function') @mock.patch.object(FileFieldAutoDelete, 'validate_fields') @mock.patch.object(FileFieldAutoDelete, 'get_field_names') @mock.patch.object(FileFieldAutoDelete, 'get_fields') @mock.patch.object(FileFieldAutoDelete, 'validate_model') def test_get_wrapped_object(self, mock_validate_model, mock_get_fields, mock_get_field_names, mock_validate_fields, mock_connect_signal_function): self.decorator.to_wrap = mock.sentinel.model # sanity assert assert self.decorator.field_names == '*' assert self.decorator.get_wrapped_object() is mock.sentinel.model assert self.decorator.field_names == mock_get_field_names.return_value assert self.decorator.fields == mock_get_fields.return_value mock_validate_model.assert_called_once_with() mock_get_field_names.assert_called_once_with() mock_get_fields.assert_called_once_with() mock_validate_fields.assert_called_once_with() mock_connect_signal_function.assert_called_once_with() def test_validate_model_not_class(self): self.decorator.to_wrap = None with pytest.raises(TypeError): self.decorator.validate_model() def test_validate_model_not_model(self): self.decorator.to_wrap = int with pytest.raises(TypeError): self.decorator.validate_model() def test_validate_model(self): self.decorator.to_wrap = self.get_empty_model() assert self.decorator.validate_model() is None def test_get_field_names_single_field(self): self.decorator.field_names = 'foo' assert self.decorator.get_field_names() == ['foo'] def test_get_field_names_single_multiple_fields(self): self.decorator.field_names = ['foo', 'bar'] assert self.decorator.get_field_names() == ['foo', 'bar'] def test_get_field_names_single_wildcard(self): self.decorator.field_names = '*' self.decorator.to_wrap = self.get_model() assert self.decorator.get_field_names() == ['file_field'] @mock.patch.object(FileFieldAutoDelete, 'validate_field') def test_validate_fields(self, mock_validate_field): self.decorator.field_names = ['foo'] assert self.decorator.validate_fields() is None mock_validate_field.assert_called_once_with('foo') def test_validate_field_not_present(self): self.decorator.to_wrap = self.get_model() with pytest.raises(AttributeError): self.decorator.validate_field('foo') def test_validate_field_not_filefield(self): self.decorator.to_wrap = self.get_model() with pytest.raises(TypeError): self.decorator.validate_field('foo_field') def test_validate_field(self): self.decorator.to_wrap = self.get_model() assert self.decorator.validate_field('file_field') is None def test_get_signal_name_single(self): self.decorator.to_wrap = self.get_model() self.decorator.fields = [FieldSpec('foo', None)] name = self.decorator.get_signal_name() assert name == 'post_delete_Model_delete_foo' def test_get_signal_name_multiple(self): self.decorator.to_wrap = self.get_model() self.decorator.fields = [FieldSpec('foo', None), FieldSpec('bar', None)] name = self.decorator.get_signal_name() assert name == 'post_delete_Model_delete_foo_bar' def test_get_signal_function_no_file(self): model = self.get_model() self.decorator.to_wrap = model self.decorator.fields = [FieldSpec('file_field', None)] signal = self.decorator.get_signal_function() assert callable(signal) f = mock.MagicMock(spec=ContentFile) instance = model(file_field=f) assert signal(model, instance) is None assert not f.mock_calls def test_get_signal_function_with_file(self): model = self.get_model() self.decorator.to_wrap = model self.decorator.fields = [FieldSpec('file_field', None)] signal = self.decorator.get_signal_function() assert callable(signal) f = mock.MagicMock() instance = model(file_field=f) assert signal(model, instance) is None f.delete.assert_called_once_with(save=False) @mock.patch.object(FileFieldAutoDelete, 'get_signal_function') def test_connect_signal_function(self, mock_get_signal_function): self.decorator.signal = signal = mock.MagicMock() self.decorator.fields = [FieldSpec('foo', None)] self.decorator.to_wrap = model = self.get_model() assert self.decorator.connect_signal_function() is None signal.connect.assert_called_once_with( mock_get_signal_function.return_value, sender=model, weak=False, dispatch_uid='post_delete_Model_delete_foo' )
def setUpClass(cls): cls.f = FileFieldAutoDelete.to_decorator()('file_field')