コード例 #1
0
    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)
コード例 #2
0
    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()
コード例 #3
0
    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))
コード例 #4
0
 def setup_method(self, method):
     self.decorator = FileFieldAutoDelete()
コード例 #5
0
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'
        )
コード例 #6
0
 def setUpClass(cls):
     cls.f = FileFieldAutoDelete.to_decorator()('file_field')