Commit 91eb21e6 authored by Sylvain Thénault's avatar Sylvain Thénault
Browse files

Add rules for "simplified profile must have one and only one access/appraisal rule"

Introduce a new 'simplified' fake format, indicating wether a profile may be
simplified or not. Profiles where are/may not be simplified are not expected to
be exportable to SEDA 1 / SEDA 0.2.
parent a77fc051bb8a
......@@ -22,7 +22,7 @@ from cubicweb.view import EntityAdapter
from cubicweb.selectors import is_instance
ALL_FORMATS = frozenset(('SEDA 2.0', 'SEDA 1.0', 'SEDA 0.2'))
ALL_FORMATS = frozenset(('SEDA 2.0', 'SEDA 1.0', 'SEDA 0.2', 'simplified'))
Rule = namedtuple('Rule', ['impacted_formats', 'message', 'tab_id', 'watch'])
RULES = {
......@@ -36,6 +36,46 @@ RULES = {
'seda_archive_unit',
'seda_alt_archive_unit_archive_unit_ref_id',
'seda_seq_alt_archive_unit_archive_unit_ref_id_management',
'seda_access_rule',
])),
'rule_without_rule': Rule(
set(['SEDA 1.0', 'SEDA 0.2', 'simplified']),
_("Some management rule has no inner rule, one is required."),
'seda_management_tab',
set([
'seda_seq_access_rule_rule',
'seda_seq_appraisal_rule_rule',
])),
'rule_with_too_much_rules': Rule(
set(['SEDA 1.0', 'SEDA 0.2', 'simplified']),
_("Some management rule has more than one inner rules, a single one is required."),
'seda_management_tab',
set([
'seda_seq_access_rule_rule',
'seda_seq_appraisal_rule_rule',
])),
'rule_unsupported_card': Rule(
set(['SEDA 1.0', 'SEDA 0.2', 'simplified']),
_("Inner rule has cardinality other than 1."),
'seda_management_tab',
set([
('SEDASeqAccessRuleRule', 'user_cardinality'),
('SEDASeqAppraisalRuleRule', 'user_cardinality'),
])),
'rule_need_start_date': Rule(
set(['SEDA 1.0', 'SEDA 0.2', 'simplified']),
_("Inner rule has no start date."),
'seda_management_tab',
set([
'seda_start_date',
])),
'rule_start_unsupported_card': Rule(
set(['SEDA 1.0', 'SEDA 0.2', 'simplified']),
_("Start date has cardinality other than 1."),
'seda_management_tab',
set([
('SEDAStartDate', 'user_cardinality'),
])),
}
......@@ -87,3 +127,27 @@ class ISEDACompatAnalyzer(EntityAdapter):
seq = archive_unit.first_level_choice.content_sequence
if not seq.reverse_seda_access_rule:
yield 'seda1_need_access_rule', archive_unit
# Access/appraisal rule must have one and only one sequence, which have one and only one
# start date (and both of them must have 1 cardinality)
for rule in self._cw.execute(
'Any X WHERE X is IN (SEDAAccessRule, SEDAAppraisalRule), '
'X container C, C eid %(c)s', {'c': profile.eid}).entities():
if not rule.rules:
yield 'rule_without_rule', _parent(rule)
elif len(rule.rules) > 1:
yield 'rule_with_too_much_rules', _parent(rule)
else:
rule_seq = rule.rules[0]
if rule_seq.user_cardinality != '1':
yield 'rule_unsupported_card', _parent(rule)
if not rule_seq.start_date:
yield 'rule_need_start_date', _parent(rule)
elif rule_seq.start_date.user_cardinality != '1':
yield 'rule_start_unsupported_card', _parent(rule)
def _parent(entity):
"""Return the first encountered parent which is an ArchiveUnit"""
while entity.cw_etype not in ('SEDAArchiveTransfer', 'SEDAArchiveUnit'):
entity = entity.cw_adapt_to('IContained').parent
return entity
......@@ -280,7 +280,10 @@ class CheckNewProfile(hook.Hook):
CheckProfileSEDACompatiblityOp.get_instance(self._cw).add_entity(self.entity)
WATCH_RTYPES_SET = set().union(*(rule.watch for rule in diag.RULES.values()))
WATCH_RTYPES_SET = set().union(*((rtype for rtype in rule.watch
# filter out (entity type, attribute)
if not isinstance(rtype, tuple))
for rule in diag.RULES.values()))
class AddOrRemoveChildrenHook(hook.Hook):
......
......@@ -119,6 +119,12 @@ msgstr ""
msgid "Impacted formats"
msgstr ""
msgid "Inner rule has cardinality other than 1."
msgstr ""
msgid "Inner rule has no start date."
msgstr ""
msgid "Message"
msgstr ""
......@@ -1839,6 +1845,13 @@ msgstr ""
msgid "Sequence"
msgstr ""
msgid ""
"Some management rule has more than one inner rules, a single one is required."
msgstr ""
msgid "Some management rule has no inner rule, one is required."
msgstr ""
msgid ""
"Special relation from a concept scheme to a relation type, that may be used "
"to restrict possible concept of a particular relation without depending on "
......@@ -1851,6 +1864,9 @@ msgid ""
"`scheme_relation_type`)."
msgstr ""
msgid "Start date has cardinality other than 1."
msgstr ""
#, python-brace-format
msgid "Supported formats: {0}."
msgstr ""
......
......@@ -125,6 +125,12 @@ msgstr "documentation HTML"
msgid "Impacted formats"
msgstr "Formats impactés"
msgid "Inner rule has cardinality other than 1."
msgstr "Une règle à une cardinalité différente de 1."
msgid "Inner rule has no start date."
msgstr "Une règle n'a pas de date de départ."
msgid "Message"
msgstr "Message"
......@@ -1845,6 +1851,13 @@ msgstr ""
msgid "Sequence"
msgstr "Séquence"
msgid ""
"Some management rule has more than one inner rules, a single one is required."
msgstr "Un élément de gestion a plusieurs règles associées, une seule est requise."
msgid "Some management rule has no inner rule, one is required."
msgstr "Un élément de gestion n'a pas de règle associée, une seule est requise."
msgid ""
"Special relation from a concept scheme to a relation type, that may be used "
"to restrict possible concept of a particular relation without depending on "
......@@ -1857,6 +1870,9 @@ msgid ""
"`scheme_relation_type`)."
msgstr ""
msgid "Start date has cardinality other than 1."
msgstr "Une date de départ à une cardinality différente de 1."
#, python-brace-format
msgid "Supported formats: {0}."
msgstr "Formats supportés : {0}."
......
......@@ -26,15 +26,49 @@ class CompatAnalyzerTC(CubicWebTC):
with self.admin_access.repo_cnx() as cnx:
transfer = cnx.create_entity('SEDAArchiveTransfer', title=u'diagnosis testing')
doctor = transfer.cw_adapt_to('ISEDACompatAnalyzer')
cnx.commit()
self.assertDiagnostic(doctor, ('SEDA 2.0', 'SEDA 1.0', 'SEDA 0.2'))
self.assertDiagnostic(doctor, ['SEDA 2.0', 'SEDA 1.0', 'SEDA 0.2', 'simplified'])
unit, unit_alt, unit_alt_seq = create_archive_unit(transfer)
transfer.cw_clear_all_caches()
cnx.commit()
self.assertDiagnostic(doctor, ('SEDA 2.0', 'SEDA 0.2'), 'seda1_need_access_rule')
self.assertDiagnostic(doctor, ['SEDA 2.0', 'SEDA 0.2', 'simplified'],
'seda1_need_access_rule')
access_rule = cnx.create_entity('SEDAAccessRule', seda_access_rule=unit_alt_seq)
unit_alt_seq.cw_clear_all_caches()
cnx.commit()
self.assertDiagnostic(doctor, ['SEDA 2.0'], 'rule_without_rule')
access_rule_seq = cnx.create_entity('SEDASeqAccessRuleRule',
user_cardinality=u'1..n',
reverse_seda_seq_access_rule_rule=access_rule)
access_rule.cw_clear_all_caches()
cnx.commit()
self.assertDiagnostic(doctor, ['SEDA 2.0'],
'rule_unsupported_card', 'rule_need_start_date')
access_rule_seq.cw_set(user_cardinality=u'1')
start_date = cnx.create_entity('SEDAStartDate',
user_cardinality=u'0..1',
seda_start_date=access_rule_seq)
access_rule_seq.cw_clear_all_caches()
cnx.commit()
self.assertDiagnostic(doctor, ['SEDA 2.0'],
'rule_start_unsupported_card')
start_date.cw_set(user_cardinality=u'1')
start_date.cw_clear_all_caches()
access_rule_seq = cnx.create_entity('SEDASeqAccessRuleRule',
user_cardinality=u'1..n',
reverse_seda_seq_access_rule_rule=access_rule)
access_rule.cw_clear_all_caches()
cnx.commit()
self.assertDiagnostic(doctor, ['SEDA 2.0'],
'rule_with_too_much_rules')
def assertDiagnostic(self, doctor, expected_formats, *expected_rule_ids):
doctor.entity.cw_clear_all_caches()
rule_ids = set(rule_id for rule_id, entity in doctor.failing_rules())
self.assertEqual(rule_ids, set(expected_rule_ids))
self.assertEqual(doctor.diagnose(), set(expected_formats))
......
......@@ -697,7 +697,8 @@ class OldSEDAExportMixin(object):
create('SEDAAccessRule', # XXX mandatory for seda 1.0
user_cardinality=u'1',
seda_access_rule=unit_alt_seq,
seda_seq_access_rule_rule=create('SEDASeqAccessRuleRule'))
seda_seq_access_rule_rule=create(
'SEDASeqAccessRuleRule', reverse_seda_start_date=create('SEDAStartDate')))
content = create('SEDAContent',
user_cardinality=u'1',
......@@ -721,7 +722,8 @@ class OldSEDAExportMixin(object):
appraisal_rule_rule = create('SEDASeqAppraisalRuleRule',
seda_rule=concepts['P10Y'],
user_annotation=u"C'est dans 10ans je m'en irai")
user_annotation=u"C'est dans 10ans je m'en irai",
reverse_seda_start_date=create('SEDAStartDate'))
create('SEDAAppraisalRule',
seda_appraisal_rule=unit_alt_seq,
seda_final_action=concepts['detruire'],
......@@ -738,13 +740,16 @@ class OldSEDAExportMixin(object):
cnx.create_entity('SEDATitle', seda_title=content)
create('SEDAAppraisalRule',
seda_appraisal_rule=subunit_alt_seq)
seda_appraisal_rule=subunit_alt_seq,
seda_seq_appraisal_rule_rule=create(
'SEDASeqAppraisalRuleRule', reverse_seda_start_date=create('SEDAStartDate')))
create('SEDAAccessRule',
user_cardinality=u'1',
user_annotation=u'restrict',
seda_access_rule=subunit_alt_seq,
seda_seq_access_rule_rule=create('SEDASeqAccessRuleRule',
reverse_seda_start_date=create('SEDAStartDate'),
seda_rule=concepts['AR038']))
# Add minimal document to first level archive
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment