data: mark json config cell as invalid if not found in settings (#71168) #5
|
@ -26,6 +26,9 @@ class DataConfig(AppConfig):
|
|||
from combo.data.models import CellBase
|
||||
|
||||
cell_classes = [c for c in self.get_models() if c in get_cell_classes()]
|
||||
for cell in CellBase.get_cells(cell_filter=lambda x: x in cell_classes, page__snapshot__isnull=True):
|
||||
|
||||
for cell in CellBase.get_cells(
|
||||
cell_filter=lambda x: x in cell_classes, page__snapshot__isnull=True, get_all_objects=True
|
||||
):
|
||||
if hasattr(cell, 'check_validity'):
|
||||
cell.check_validity()
|
||||
|
|
|
@ -1040,6 +1040,7 @@ class CellBase(models.Model, metaclass=CellMeta):
|
|||
select_related=None,
|
||||
load_contenttypes=False,
|
||||
cells_exclude=None,
|
||||
get_all_objects=False,
|
||||
**kwargs,
|
||||
):
|
||||
"""Returns the list of cells of various classes matching **kwargs"""
|
||||
|
@ -1074,7 +1075,10 @@ class CellBase(models.Model, metaclass=CellMeta):
|
|||
continue
|
||||
if cell_filter and not cell_filter(klass):
|
||||
continue
|
||||
cells_queryset = klass.objects.filter(**kwargs)
|
||||
manager = klass.objects
|
||||
if get_all_objects and hasattr(klass, 'all_objects'):
|
||||
manager = klass.all_objects
|
||||
cells_queryset = manager.filter(**kwargs)
|
||||
if cells_exclude:
|
||||
cells_queryset = cells_queryset.exclude(cells_exclude)
|
||||
if extra_filter:
|
||||
|
@ -2360,10 +2364,15 @@ class ConfigJsonCellManager(models.Manager):
|
|||
@register_cell_class
|
||||
class ConfigJsonCell(JsonCellBase):
|
||||
objects = ConfigJsonCellManager()
|
||||
|
||||
all_objects = models.Manager()
|
||||
|
||||
key = models.CharField(max_length=50)
|
||||
parameters = JSONField(blank=True, default=dict)
|
||||
|
||||
invalid_reason_codes = {
|
||||
'settings_not_found': _('Cell not found in settings'),
|
||||
}
|
||||
|
||||
def __str__(self):
|
||||
return force_str(_('%s (JSON Cell)') % self.get_label())
|
||||
|
||||
|
@ -2383,6 +2392,8 @@ class ConfigJsonCell(JsonCellBase):
|
|||
return l
|
||||
|
||||
def get_label(self):
|
||||
if self.key not in settings.JSON_CELL_TYPES:
|
||||
return _('Unknown ConfigJsonCell %s') % self.key
|
||||
return settings.JSON_CELL_TYPES[self.key]['name']
|
||||
|
||||
def set_variant(self, variant):
|
||||
|
@ -2465,6 +2476,18 @@ class ConfigJsonCell(JsonCellBase):
|
|||
self.template_string = self.parameters['template_string']
|
||||
return super().render(context)
|
||||
|
||||
def check_validity(self):
|
||||
if self.key not in settings.JSON_CELL_TYPES:
|
||||
self.mark_as_invalid('settings_not_found')
|
||||
return
|
||||
validity_info = self.get_validity_info()
|
||||
if validity_info is None:
|
||||
return
|
||||
if validity_info.invalid_reason_code != 'settings_not_found':
|
||||
# don't overwrite other invalid reasons
|
||||
return
|
||||
self.mark_as_valid()
|
||||
|
||||
|
||||
@receiver(pre_save, sender=Page)
|
||||
def create_redirects(sender, instance, raw, **kwargs):
|
||||
|
|
|
@ -185,7 +185,10 @@ site_import = SiteImportView.as_view()
|
|||
|
||||
def invalid_cell_report(request):
|
||||
invalid_cells = CellBase.get_cells(
|
||||
page__snapshot__isnull=True, validity_info__invalid_since__isnull=False, load_contenttypes=True
|
||||
page__snapshot__isnull=True,
|
||||
validity_info__invalid_since__isnull=False,
|
||||
load_contenttypes=True,
|
||||
get_all_objects=True,
|
||||
)
|
||||
# manual prefetch of cell pages (for ordering and placeholders)
|
||||
all_pages_by_pk = {p.pk: p for p in Page.objects.filter(snapshot__isnull=True)}
|
||||
|
|
|
@ -1258,6 +1258,44 @@ def test_config_json_cell_validity(settings, context):
|
|||
assert ValidityInfo.objects.exists() is False
|
||||
|
||||
|
||||
def test_config_json_cell_check_validity(settings):
|
||||
settings.JSON_CELL_TYPES = {
|
||||
'test-config-json-cell': {
|
||||
'name': 'Foobar',
|
||||
},
|
||||
}
|
||||
page = Page.objects.create(title='example page', slug='example-page')
|
||||
cell = ConfigJsonCell.objects.create(
|
||||
page=page,
|
||||
placeholder='content',
|
||||
order=1,
|
||||
key='test-config-json-cell',
|
||||
)
|
||||
cell.check_validity()
|
||||
assert ValidityInfo.objects.exists() is False
|
||||
|
||||
settings.JSON_CELL_TYPES = {}
|
||||
cell.check_validity()
|
||||
validity_info = ValidityInfo.objects.latest('pk')
|
||||
assert validity_info.invalid_reason_code == 'settings_not_found'
|
||||
assert validity_info.invalid_since is not None
|
||||
|
||||
settings.JSON_CELL_TYPES = {
|
||||
'test-config-json-cell': {
|
||||
'name': 'Foobar',
|
||||
},
|
||||
}
|
||||
validity_info.invalid_reason_code = 'foobar'
|
||||
validity_info.save()
|
||||
cell.check_validity()
|
||||
assert ValidityInfo.objects.exists() is True
|
||||
|
||||
validity_info.invalid_reason_code = 'settings_not_found'
|
||||
validity_info.save()
|
||||
cell.check_validity()
|
||||
assert ValidityInfo.objects.exists() is False
|
||||
|
||||
|
||||
def test_json_force_async():
|
||||
cell = JsonCell()
|
||||
cell.url = 'http://example.net/test-force-async'
|
||||
|
@ -1623,7 +1661,7 @@ def test_hourly():
|
|||
for klass in cell_classes:
|
||||
klass.objects.create(page=page, placeholder='content', order=0)
|
||||
for klass in cell_classes:
|
||||
if klass in [LinkCell, LinkListCell]:
|
||||
if klass in [LinkCell, LinkListCell, ConfigJsonCell]:
|
||||
with mock.patch('combo.data.models.%s.check_validity' % klass.__name__) as check_validity:
|
||||
appconfig.hourly()
|
||||
assert check_validity.call_args_list == [mock.call()]
|
||||
|
|
|
@ -1272,6 +1272,17 @@ def test_invalid_cell_report(app, admin_user):
|
|||
resp = app.get('/manage/cells/invalid-report/')
|
||||
assert resp.context['object_list'] == [cell]
|
||||
|
||||
# unknown config cell
|
||||
cell2 = ConfigJsonCell.objects.create(
|
||||
page=page,
|
||||
placeholder='content',
|
||||
order=1,
|
||||
key='test-config-json-cell',
|
||||
)
|
||||
cell2.mark_as_invalid('settings_not_found')
|
||||
resp = app.get('/manage/cells/invalid-report/')
|
||||
assert resp.context['object_list'] == [cell, cell2]
|
||||
|
||||
|
||||
def test_duplicate_page(app, admin_user):
|
||||
page = Page.objects.create(
|
||||
|
|
Loading…
Reference in New Issue
Ce manager fait un
queryset.filter(key__in=settings.JSON_CELL_TYPES.keys())
=> nécessité d'avoir un autre manager qui ne filtre pas sur les settings, pour le job cron, et pour la page de rapport des anomalies.