civics-cdf-validator 1.66.dev11__tar.gz → 1.66.dev12__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {civics_cdf_validator-1.66.dev11/civics_cdf_validator.egg-info → civics_cdf_validator-1.66.dev12}/PKG-INFO +1 -1
- {civics_cdf_validator-1.66.dev11 → civics_cdf_validator-1.66.dev12/civics_cdf_validator.egg-info}/PKG-INFO +1 -1
- {civics_cdf_validator-1.66.dev11 → civics_cdf_validator-1.66.dev12}/rules.py +78 -0
- {civics_cdf_validator-1.66.dev11 → civics_cdf_validator-1.66.dev12}/version.py +1 -1
- {civics_cdf_validator-1.66.dev11 → civics_cdf_validator-1.66.dev12}/CONTRIBUTING.md +0 -0
- {civics_cdf_validator-1.66.dev11 → civics_cdf_validator-1.66.dev12}/LICENSE-2.0.txt +0 -0
- {civics_cdf_validator-1.66.dev11 → civics_cdf_validator-1.66.dev12}/MANIFEST.in +0 -0
- {civics_cdf_validator-1.66.dev11 → civics_cdf_validator-1.66.dev12}/README.md +0 -0
- {civics_cdf_validator-1.66.dev11 → civics_cdf_validator-1.66.dev12}/__init__.py +0 -0
- {civics_cdf_validator-1.66.dev11 → civics_cdf_validator-1.66.dev12}/base.py +0 -0
- {civics_cdf_validator-1.66.dev11 → civics_cdf_validator-1.66.dev12}/civics_cdf_validator.egg-info/SOURCES.txt +0 -0
- {civics_cdf_validator-1.66.dev11 → civics_cdf_validator-1.66.dev12}/civics_cdf_validator.egg-info/dependency_links.txt +0 -0
- {civics_cdf_validator-1.66.dev11 → civics_cdf_validator-1.66.dev12}/civics_cdf_validator.egg-info/entry_points.txt +0 -0
- {civics_cdf_validator-1.66.dev11 → civics_cdf_validator-1.66.dev12}/civics_cdf_validator.egg-info/requires.txt +0 -0
- {civics_cdf_validator-1.66.dev11 → civics_cdf_validator-1.66.dev12}/civics_cdf_validator.egg-info/top_level.txt +0 -0
- {civics_cdf_validator-1.66.dev11 → civics_cdf_validator-1.66.dev12}/gpunit_rules.py +0 -0
- {civics_cdf_validator-1.66.dev11 → civics_cdf_validator-1.66.dev12}/loggers.py +0 -0
- {civics_cdf_validator-1.66.dev11 → civics_cdf_validator-1.66.dev12}/office_utils.py +0 -0
- {civics_cdf_validator-1.66.dev11 → civics_cdf_validator-1.66.dev12}/setup.cfg +0 -0
- {civics_cdf_validator-1.66.dev11 → civics_cdf_validator-1.66.dev12}/setup.py +0 -0
- {civics_cdf_validator-1.66.dev11 → civics_cdf_validator-1.66.dev12}/stats.py +0 -0
- {civics_cdf_validator-1.66.dev11 → civics_cdf_validator-1.66.dev12}/validator.py +0 -0
|
@@ -4406,6 +4406,83 @@ class ResultsReportingStagesMustHaveUniqueType(base.BaseRule):
|
|
|
4406
4406
|
raise loggers.ElectionError(errors)
|
|
4407
4407
|
|
|
4408
4408
|
|
|
4409
|
+
class ValidateResultReportingStages(base.BaseRule):
|
|
4410
|
+
"""Validates ResultsReportingStage elements in a stage collection."""
|
|
4411
|
+
|
|
4412
|
+
def setup(self):
|
|
4413
|
+
self.composing_contest_ids = self._get_composing_contest_ids()
|
|
4414
|
+
|
|
4415
|
+
def _get_composing_contest_ids(self):
|
|
4416
|
+
composing_contest_ids = set()
|
|
4417
|
+
for contest in self.get_elements_by_class(self.election_tree, "Contest"):
|
|
4418
|
+
composing_contest_ids_element = contest.find("ComposingContestIds")
|
|
4419
|
+
if element_has_text(composing_contest_ids_element):
|
|
4420
|
+
composing_contest_ids.update(composing_contest_ids_element.text.split())
|
|
4421
|
+
return composing_contest_ids
|
|
4422
|
+
|
|
4423
|
+
def elements(self):
|
|
4424
|
+
return ["ResultsReportingStageCollection"]
|
|
4425
|
+
|
|
4426
|
+
def check(self, element):
|
|
4427
|
+
inherit_from_composed = _is_xml_true(
|
|
4428
|
+
element.find("InheritFromComposedContest")
|
|
4429
|
+
)
|
|
4430
|
+
stages = element.findall("ResultsReportingStage")
|
|
4431
|
+
|
|
4432
|
+
if inherit_from_composed:
|
|
4433
|
+
error_log = []
|
|
4434
|
+
if stages:
|
|
4435
|
+
error_log.append(
|
|
4436
|
+
loggers.LogEntry(
|
|
4437
|
+
"ResultsReportingStageCollection must not contain any"
|
|
4438
|
+
" ResultsReportingStage elements when"
|
|
4439
|
+
" InheritFromComposedContest is true.",
|
|
4440
|
+
[element],
|
|
4441
|
+
)
|
|
4442
|
+
)
|
|
4443
|
+
contest = element.getparent()
|
|
4444
|
+
contest_id = contest.get("objectId") if contest is not None else None
|
|
4445
|
+
if contest_id not in self.composing_contest_ids:
|
|
4446
|
+
error_log.append(
|
|
4447
|
+
loggers.LogEntry(
|
|
4448
|
+
f"Contest {contest_id} sets InheritFromComposedContest to"
|
|
4449
|
+
" true but is not listed in the ComposingContestIds of any"
|
|
4450
|
+
" other Contest.",
|
|
4451
|
+
[contest],
|
|
4452
|
+
)
|
|
4453
|
+
)
|
|
4454
|
+
if error_log:
|
|
4455
|
+
raise loggers.ElectionError(error_log)
|
|
4456
|
+
return
|
|
4457
|
+
|
|
4458
|
+
if not stages:
|
|
4459
|
+
raise loggers.ElectionError.from_message(
|
|
4460
|
+
"ResultsReportingStageCollection must contain at least one"
|
|
4461
|
+
" ResultsReportingStage element when InheritFromComposedContest is"
|
|
4462
|
+
" not true.",
|
|
4463
|
+
[element],
|
|
4464
|
+
)
|
|
4465
|
+
|
|
4466
|
+
stage_types = set()
|
|
4467
|
+
for stage in stages:
|
|
4468
|
+
stage_type_element = stage.find("StageType")
|
|
4469
|
+
if element_has_text(stage_type_element):
|
|
4470
|
+
stage_types.add(stage_type_element.text.strip())
|
|
4471
|
+
|
|
4472
|
+
if (
|
|
4473
|
+
len(stages) < 2
|
|
4474
|
+
or "no-results" not in stage_types
|
|
4475
|
+
or stage_types.isdisjoint({"preliminary", "official"})
|
|
4476
|
+
):
|
|
4477
|
+
raise loggers.ElectionWarning.from_message(
|
|
4478
|
+
"ResultsReportingStageCollection should contain at least two"
|
|
4479
|
+
" ResultsReportingStage elements, including one of StageType"
|
|
4480
|
+
" 'no-results' and at least one of StageType 'preliminary' or"
|
|
4481
|
+
" 'official', when InheritFromComposedContest is not true.",
|
|
4482
|
+
[element],
|
|
4483
|
+
)
|
|
4484
|
+
|
|
4485
|
+
|
|
4409
4486
|
class CandidateContestTypesAreCompatible(base.BaseRule):
|
|
4410
4487
|
"""CandidateContest Type values cannot have both a general and primary type."""
|
|
4411
4488
|
|
|
@@ -5652,6 +5729,7 @@ ELECTION_RULES = COMMON_RULES + (
|
|
|
5652
5729
|
ValidateIncludeInAggregationBallotSelections,
|
|
5653
5730
|
ValidateInfoUriAnnotation,
|
|
5654
5731
|
ValidatePollsCloseDatetimes,
|
|
5732
|
+
ValidateResultReportingStages,
|
|
5655
5733
|
ValidateResultsEmbargoEnd,
|
|
5656
5734
|
ValidateResultsExpected,
|
|
5657
5735
|
ValidateSpecialBallotSelectionCountedInTotal,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|