wagtail / wagtail-factories

Factory boy classes for wagtail
http://wagtail-factories.readthedocs.io/en/latest/
MIT License
102 stars 40 forks source link

Add RedirectFactory #82

Open kbayliss opened 8 months ago

kbayliss commented 8 months ago

Wagtail provides a Redirect model so it would be useful to add a reusable RedirectFactory.

Example:

class RedirectFactory(factory.django.DjangoModelFactory):
    old_path = factory.Faker("slug")
    site = factory.SubFactory(wagtail_factories.SiteFactory)
    redirect_page = factory.SubFactory(wagtail_factories.PageFactory)
    redirect_link = factory.Faker("url")
    is_permanent = factory.Faker("boolean")

    class Meta:
        model = Redirect

    @classmethod
    def _create(cls, model_class, *args, **kwargs):
        """
        Override _create() to ensure that Redirect.clean() is run in order to
        normalise `old_path`.
        @see https://github.com/wagtail/wagtail/blob/main/wagtail/contrib/redirects/models.py#L191
        @see https://github.com/jamescooke/factory_djoy/blob/2744fa062f58f5eb13c68938faf844a0812a3ff6/factory_djoy/factories.py#L21
        """
        obj = model_class(*args, **kwargs)
        try:
            obj.clean()
        except ValidationError as ve:
            message = (
                f"Error building {model_class} with {cls.__name__}.\nBad values:\n"
            )
            for field in ve.error_dict.keys():
                if field == "__all__":
                    message += "  __all__: obj.clean() failed\n"
                else:
                    message += f'  {field}: "{getattr(obj, field)}"\n'
            raise RuntimeError(message) from ve
        obj.save()
        return obj

Needs tests adding :).