Coverage for src/mesh/views/forms/editorial_forms.py: 42%

51 statements  

« prev     ^ index     » next       coverage.py v7.7.0, created at 2025-04-28 07:45 +0000

1from typing import Any 

2 

3from django import forms 

4from django.core.exceptions import ValidationError 

5from django.utils.translation import gettext_lazy as _ 

6 

7from mesh.models.editorial_models import EditorialDecision, EditorialDecisionFile 

8from mesh.views.components.ckeditor_config import DEFAULT_CKEDITOR_CONFIG 

9 

10from .base_forms import FileModelForm, MeshFormMixin 

11from .fields import CKEditorFormField, FileField 

12 

13 

14class StartReviewProcessForm(forms.Form): 

15 process = forms.BooleanField(required=True, widget=forms.HiddenInput) 

16 

17 def clean_process(self) -> bool: 

18 value: bool = self.cleaned_data["process"] 

19 if value is False: 

20 raise ValidationError("Error in the form, `process` boolean must be True") 

21 return value 

22 

23 

24class EditorialDecisionCreateForm(MeshFormMixin, FileModelForm): 

25 custom_display = "inline" 

26 

27 comment = CKEditorFormField(DEFAULT_CKEDITOR_CONFIG, required=False) 

28 additional_files = FileField( 

29 required=False, 

30 label=_("File(s)"), 

31 allow_multiple_selected=True, 

32 model_class=EditorialDecisionFile, 

33 ) 

34 

35 class Meta: 

36 model = EditorialDecision 

37 fields = ["value", "comment", "additional_files"] 

38 

39 def clean(self) -> dict[str, Any]: 

40 cleaned_data = super().clean() 

41 if self.errors: 

42 return cleaned_data 

43 

44 comment = cleaned_data["comment"].strip() 

45 if comment[0:3] == "<p>": 

46 comment = comment[3:] 

47 if comment[-4:] == "</p>": 

48 comment = comment[:-4] 

49 cleaned_data["comment"] = comment 

50 

51 if not cleaned_data["comment"] and not cleaned_data["additional_files"]: 

52 instance: EditorialDecision | None = getattr(self, "instance") 

53 if not ( 

54 instance and instance._state.adding is False and instance.additional_files.exists() # type:ignore 

55 ): 

56 raise ValidationError( 

57 _( 

58 "You must either fill out the description or upload a file to explain your editorial decision." 

59 ) 

60 ) 

61 

62 return cleaned_data 

63 

64 

65class EditorialDecisionUpdateForm(EditorialDecisionCreateForm): 

66 by = forms.CharField(label=_("Created by"), max_length=1024, disabled=True, required=False) 

67 date = forms.DateField(label=_("Creation date"), disabled=True, required=False) 

68 value_display = forms.CharField(label=_("Decision"), disabled=True, required=False) 

69 

70 class Meta: 

71 model = EditorialDecision 

72 fields = ["by", "date", "value_display", "comment", "additional_files"] 

73 

74 def __init__(self, *args, **kwargs) -> None: 

75 super().__init__(*args, **kwargs) 

76 

77 instance: EditorialDecision | None = getattr(self, "instance") 

78 if instance: 

79 self.fields["by"].initial = instance.created_by 

80 self.fields["date"].initial = instance.date_created 

81 self.fields["value_display"].initial = instance.get_value_display() # type:ignore