@hestia-earth/data-validation 0.37.7 → 0.37.8
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.
- package/dist/index.d.ts +1 -0
- package/dist/index.js +17 -0
- package/dist/validations.d.ts +10 -0
- package/dist/validations.js +10 -0
- package/package.json +4 -3
- package/search-results.json +22 -22
- package/src/version.ts +1 -1
- package/validation.json +629 -0
- package/.coveragerc +0 -14
- package/.dockerignore +0 -19
- package/.eslintignore +0 -17
- package/.eslintrc.js +0 -11
- package/.flake8 +0 -5
- package/.gitlab/issue_templates/new validation.md +0 -82
- package/.gitlab-ci.yml +0 -216
- package/.readthedocs.yml +0 -24
- package/CODEOWNERS +0 -11
- package/Dockerfile +0 -13
- package/MANIFEST.in +0 -2
- package/bin/hestia-validate-data +0 -80
- package/build_mocking.py +0 -14
- package/commitlint.config.js +0 -1
- package/docs/Makefile +0 -20
- package/docs/_static/styles.css +0 -4
- package/docs/_templates/custom-class-template.rst +0 -34
- package/docs/_templates/custom-module-template.rst +0 -66
- package/docs/_templates/layout.html +0 -4
- package/docs/conf.py +0 -74
- package/docs/index.rst +0 -42
- package/docs/make.bat +0 -35
- package/docs/requirements.txt +0 -13
- package/envs/.develop.env +0 -1
- package/envs/.master.env +0 -1
- package/guide-assets/.gitkeep +0 -0
- package/hestia_earth/validation/README.md +0 -5
- package/hestia_earth/validation/__init__.py +0 -32
- package/hestia_earth/validation/distribution.py +0 -22
- package/hestia_earth/validation/gee.py +0 -162
- package/hestia_earth/validation/log.py +0 -44
- package/hestia_earth/validation/models.py +0 -141
- package/hestia_earth/validation/preload_requests.py +0 -61
- package/hestia_earth/validation/terms.py +0 -88
- package/hestia_earth/validation/utils.py +0 -444
- package/hestia_earth/validation/validators/__init__.py +0 -141
- package/hestia_earth/validation/validators/aggregated_cycle.py +0 -32
- package/hestia_earth/validation/validators/aggregated_shared.py +0 -37
- package/hestia_earth/validation/validators/animal.py +0 -88
- package/hestia_earth/validation/validators/completeness.py +0 -252
- package/hestia_earth/validation/validators/cycle.py +0 -1123
- package/hestia_earth/validation/validators/distribution.py +0 -86
- package/hestia_earth/validation/validators/emission.py +0 -109
- package/hestia_earth/validation/validators/impact_assessment.py +0 -138
- package/hestia_earth/validation/validators/indicator.py +0 -154
- package/hestia_earth/validation/validators/infrastructure.py +0 -25
- package/hestia_earth/validation/validators/input.py +0 -268
- package/hestia_earth/validation/validators/management.py +0 -131
- package/hestia_earth/validation/validators/measurement.py +0 -368
- package/hestia_earth/validation/validators/organisation.py +0 -43
- package/hestia_earth/validation/validators/practice.py +0 -590
- package/hestia_earth/validation/validators/product.py +0 -263
- package/hestia_earth/validation/validators/property.py +0 -266
- package/hestia_earth/validation/validators/shared.py +0 -940
- package/hestia_earth/validation/validators/site.py +0 -312
- package/hestia_earth/validation/validators/source.py +0 -20
- package/hestia_earth/validation/validators/transformation.py +0 -250
- package/hestia_earth/validation/version.py +0 -1
- package/layer/build.sh +0 -34
- package/layer/deploy.sh +0 -18
- package/release.sh +0 -11
- package/requirements-ci.txt +0 -6
- package/requirements-test.txt +0 -4
- package/requirements.txt +0 -2
- package/run-docker-test.sh +0 -7
- package/run-docker.sh +0 -9
- package/run.py +0 -99
- package/scripts/build_docs.py +0 -283
- package/scripts/build_validation_list.py +0 -160
- package/scripts/guide-create-branch.sh +0 -15
- package/scripts/update-package-version.js +0 -28
- package/setup.py +0 -35
- package/tests/Dockerfile +0 -13
- package/tests/__init__.py +0 -3
- package/tests/fixtures/aggregated/cycle/inputs-impactAssessment/invalid-no-impactAssessment.json +0 -64
- package/tests/fixtures/aggregated/cycle/inputs-impactAssessment/invalid-world.json +0 -69
- package/tests/fixtures/aggregated/cycle/inputs-impactAssessment/valid.json +0 -69
- package/tests/fixtures/animal/duplicated-input-cycle/invalid.json +0 -98
- package/tests/fixtures/animal/duplicated-input-cycle/valid.json +0 -91
- package/tests/fixtures/animal/pregnancyRateTotal/invalid.json +0 -49
- package/tests/fixtures/animal/pregnancyRateTotal/valid.json +0 -60
- package/tests/fixtures/animal/required/invalid.json +0 -59
- package/tests/fixtures/animal/required/valid.json +0 -72
- package/tests/fixtures/completeness/all-values/warning.json +0 -22
- package/tests/fixtures/completeness/animalPopulation/invalid.json +0 -58
- package/tests/fixtures/completeness/animalPopulation/valid-animals.json +0 -71
- package/tests/fixtures/completeness/animalPopulation/valid-incomplete.json +0 -58
- package/tests/fixtures/completeness/animalPopulation/valid-no-liveAnimals.json +0 -37
- package/tests/fixtures/completeness/blank-nodes/agri-food processor-invalid.json +0 -52
- package/tests/fixtures/completeness/blank-nodes/invalid.json +0 -124
- package/tests/fixtures/completeness/blank-nodes/valid.json +0 -128
- package/tests/fixtures/completeness/cropland/site.json +0 -16
- package/tests/fixtures/completeness/cropland/valid.json +0 -22
- package/tests/fixtures/completeness/cropland/warning.json +0 -22
- package/tests/fixtures/completeness/freshForage/error-animals.json +0 -63
- package/tests/fixtures/completeness/freshForage/error-products.json +0 -65
- package/tests/fixtures/completeness/freshForage/valid-animal-inputs.json +0 -63
- package/tests/fixtures/completeness/freshForage/valid-animals.json +0 -63
- package/tests/fixtures/completeness/freshForage/valid-not-grazing-liveAnimal.json +0 -55
- package/tests/fixtures/completeness/freshForage/valid-not-liveAnimal.json +0 -47
- package/tests/fixtures/completeness/freshForage/valid-products.json +0 -68
- package/tests/fixtures/completeness/ingredient/invalid-agri-food-processor.json +0 -37
- package/tests/fixtures/completeness/ingredient/invalid.json +0 -49
- package/tests/fixtures/completeness/ingredient/valid-agri-food-processor-complete.json +0 -49
- package/tests/fixtures/completeness/ingredient/valid-agri-food-processor-incomplete.json +0 -37
- package/tests/fixtures/completeness/ingredient/valid.json +0 -49
- package/tests/fixtures/completeness/material/error.json +0 -49
- package/tests/fixtures/completeness/material/valid-fuel-material.json +0 -60
- package/tests/fixtures/completeness/material/valid-incomplete.json +0 -36
- package/tests/fixtures/completeness/material/valid-no-fuel.json +0 -36
- package/tests/fixtures/completeness/valid.json +0 -22
- package/tests/fixtures/cycle/aboveGroundCropResidue/invalid.json +0 -76
- package/tests/fixtures/cycle/aboveGroundCropResidue/valid.json +0 -76
- package/tests/fixtures/cycle/aggregated-valid.json +0 -102
- package/tests/fixtures/cycle/coverCrop/invalid.json +0 -64
- package/tests/fixtures/cycle/coverCrop/valid-not-coverCrop.json +0 -54
- package/tests/fixtures/cycle/coverCrop/valid.json +0 -64
- package/tests/fixtures/cycle/cropResidue/complete/invalid.json +0 -56
- package/tests/fixtures/cycle/cropResidue/complete/valid.json +0 -82
- package/tests/fixtures/cycle/cropResidue/incomplete/invalid.json +0 -42
- package/tests/fixtures/cycle/cropResidue/incomplete/valid.json +0 -56
- package/tests/fixtures/cycle/dates/invalid-emissions.json +0 -70
- package/tests/fixtures/cycle/liveAnimal-animalProduct-mapping/invalid.json +0 -63
- package/tests/fixtures/cycle/liveAnimal-animalProduct-mapping/valid.json +0 -63
- package/tests/fixtures/cycle/maximumCycleDuration/invalid-dates-year-only.json +0 -48
- package/tests/fixtures/cycle/maximumCycleDuration/invalid-dates.json +0 -48
- package/tests/fixtures/cycle/maximumCycleDuration/invalid.json +0 -48
- package/tests/fixtures/cycle/maximumCycleDuration/valid-dates-year-only.json +0 -48
- package/tests/fixtures/cycle/maximumCycleDuration/valid-dates.json +0 -48
- package/tests/fixtures/cycle/maximumCycleDuration/valid.json +0 -48
- package/tests/fixtures/cycle/otherSites/cycleDuration/invalid.json +0 -52
- package/tests/fixtures/cycle/otherSites/cycleDuration/valid-no-siteDuration.json +0 -40
- package/tests/fixtures/cycle/otherSites/cycleDuration/valid.json +0 -52
- package/tests/fixtures/cycle/practices/stockingDensityPermanentPastureAverage/invalid.json +0 -56
- package/tests/fixtures/cycle/practices/stockingDensityPermanentPastureAverage/valid.json +0 -65
- package/tests/fixtures/cycle/primary-product-as-input/invalid.json +0 -59
- package/tests/fixtures/cycle/primary-product-as-input/valid.json +0 -48
- package/tests/fixtures/cycle/product-linked-ia/cycle.json +0 -66
- package/tests/fixtures/cycle/product-linked-ia/invalid-multiple.json +0 -58
- package/tests/fixtures/cycle/product-linked-ia/valid.json +0 -57
- package/tests/fixtures/cycle/products/animals/invalid.json +0 -69
- package/tests/fixtures/cycle/products/animals/valid.json +0 -58
- package/tests/fixtures/cycle/riceGrainInHuskFlooded-minimumCycleDuration/invalid.json +0 -53
- package/tests/fixtures/cycle/riceGrainInHuskFlooded-minimumCycleDuration/valid.json +0 -53
- package/tests/fixtures/cycle/siteDuration/crop/invalid.json +0 -53
- package/tests/fixtures/cycle/siteDuration/crop/valid-different-duration.json +0 -53
- package/tests/fixtures/cycle/siteDuration/crop/valid-same-duration.json +0 -53
- package/tests/fixtures/cycle/siteDuration/invalid.json +0 -41
- package/tests/fixtures/cycle/siteDuration/valid-no-siteDuration.json +0 -40
- package/tests/fixtures/cycle/siteDuration/valid-otherSites.json +0 -48
- package/tests/fixtures/cycle/siteDuration/valid.json +0 -45
- package/tests/fixtures/cycle/substrate/required/invalid.json +0 -50
- package/tests/fixtures/cycle/substrate/required/valid.json +0 -60
- package/tests/fixtures/cycle/valid.json +0 -343
- package/tests/fixtures/emission/linked-terms/inputs/invalid.json +0 -78
- package/tests/fixtures/emission/linked-terms/inputs/valid.json +0 -106
- package/tests/fixtures/emission/linked-terms/transformation/error.json +0 -104
- package/tests/fixtures/emission/linked-terms/transformation/valid.json +0 -107
- package/tests/fixtures/emission/linked-terms/transformation/warning.json +0 -76
- package/tests/fixtures/emission/methodTier-background/invalid.json +0 -60
- package/tests/fixtures/emission/methodTier-background/valid.json +0 -60
- package/tests/fixtures/emission/not-relevant/invalid.json +0 -71
- package/tests/fixtures/emission/not-relevant/valid.json +0 -95
- package/tests/fixtures/emission/not-relevant-methodTier/invalid.json +0 -70
- package/tests/fixtures/emission/not-relevant-methodTier/valid.json +0 -95
- package/tests/fixtures/impactAssessment/aggregated-valid.json +0 -43
- package/tests/fixtures/impactAssessment/cycle-contains-product/invalid.json +0 -34
- package/tests/fixtures/impactAssessment/cycle-contains-product/valid.json +0 -34
- package/tests/fixtures/impactAssessment/cycle-endDate/invalid.json +0 -26
- package/tests/fixtures/impactAssessment/cycle-endDate/valid.json +0 -26
- package/tests/fixtures/impactAssessment/valid.json +0 -93
- package/tests/fixtures/indicator/characterisedIndicator-methodModel/invalid.json +0 -52
- package/tests/fixtures/indicator/characterisedIndicator-methodModel/valid.json +0 -52
- package/tests/fixtures/indicator/ionisingCompounds/invalid.json +0 -23
- package/tests/fixtures/indicator/ionisingCompounds/valid.json +0 -23
- package/tests/fixtures/indicator/landTransformation/invalid-grouped.json +0 -257
- package/tests/fixtures/indicator/landTransformation/invalid.json +0 -100
- package/tests/fixtures/indicator/landTransformation/valid-grouped-full.json +0 -507
- package/tests/fixtures/indicator/landTransformation/valid-grouped.json +0 -507
- package/tests/fixtures/indicator/landTransformation/valid.json +0 -100
- package/tests/fixtures/infrastructure/lifespan/invalid.json +0 -26
- package/tests/fixtures/infrastructure/lifespan/valid.json +0 -45
- package/tests/fixtures/input/animalFeed-fate/invalid.json +0 -103
- package/tests/fixtures/input/animalFeed-fate/valid.json +0 -90
- package/tests/fixtures/input/country/invalid.json +0 -64
- package/tests/fixtures/input/country/valid.json +0 -64
- package/tests/fixtures/input/distribution/animalHousing.json +0 -103
- package/tests/fixtures/input/distribution/complete/invalid.json +0 -177
- package/tests/fixtures/input/distribution/complete/valid.json +0 -163
- package/tests/fixtures/input/distribution/incomplete/valid.json +0 -139
- package/tests/fixtures/input/impactAssessment/invalid.json +0 -99
- package/tests/fixtures/input/impactAssessment/valid.json +0 -89
- package/tests/fixtures/input/input-as-product/invalid.json +0 -57
- package/tests/fixtures/input/input-as-product/valid.json +0 -59
- package/tests/fixtures/input/mustIncludeId/invalid.json +0 -13
- package/tests/fixtures/input/mustIncludeId/valid-multiple-ids.json +0 -31
- package/tests/fixtures/input/mustIncludeId/valid.json +0 -22
- package/tests/fixtures/input/saplings/invalid.json +0 -58
- package/tests/fixtures/input/saplings/valid-no-saplings.json +0 -58
- package/tests/fixtures/input/saplings/valid-not-plantation.json +0 -58
- package/tests/fixtures/input/saplings/valid.json +0 -58
- package/tests/fixtures/integration/distribution/product-yield-invalid.json +0 -54
- package/tests/fixtures/management/cycle-overlap/cycles.json +0 -39
- package/tests/fixtures/management/cycle-overlap/invalid.json +0 -26
- package/tests/fixtures/management/cycle-overlap/valid.json +0 -26
- package/tests/fixtures/management/exists/invalid.json +0 -13
- package/tests/fixtures/management/exists/valid.json +0 -25
- package/tests/fixtures/management/fallow-dates/invalid.json +0 -24
- package/tests/fixtures/management/fallow-dates/valid.json +0 -24
- package/tests/fixtures/management/termType/invalid-cropland.json +0 -35
- package/tests/fixtures/management/termType/invalid-permanent-pasture.json +0 -25
- package/tests/fixtures/management/termType/valid-cropland.json +0 -55
- package/tests/fixtures/management/termType/valid-no-management.json +0 -13
- package/tests/fixtures/management/termType/valid-permanent-pasture.json +0 -35
- package/tests/fixtures/measurement/depths/invalid.json +0 -44
- package/tests/fixtures/measurement/depths/valid.json +0 -50
- package/tests/fixtures/measurement/models/valid.json +0 -33
- package/tests/fixtures/measurement/models/warning-no-value.json +0 -30
- package/tests/fixtures/measurement/models/warning.json +0 -33
- package/tests/fixtures/measurement/pond-measurements/invalid.json +0 -11
- package/tests/fixtures/measurement/pond-measurements/valid.json +0 -23
- package/tests/fixtures/measurement/required-depths/error.json +0 -71
- package/tests/fixtures/measurement/required-depths/valid.json +0 -126
- package/tests/fixtures/measurement/required-depths/warning.json +0 -29
- package/tests/fixtures/measurement/soilTexture/missing-texture-value.json +0 -227
- package/tests/fixtures/measurement/soilTexture/percent-invalid.json +0 -110
- package/tests/fixtures/measurement/soilTexture/percent-missing-value.json +0 -43
- package/tests/fixtures/measurement/soilTexture/percent-valid.json +0 -110
- package/tests/fixtures/measurement/startDate-endDate-required/invalid.json +0 -32
- package/tests/fixtures/measurement/startDate-endDate-required/valid.json +0 -46
- package/tests/fixtures/measurement/unique/invalid.json +0 -28
- package/tests/fixtures/measurement/unique/valid.json +0 -16
- package/tests/fixtures/measurement/value-length/invalid.json +0 -46
- package/tests/fixtures/measurement/value-length/valid.json +0 -44
- package/tests/fixtures/measurement/water-salinity/invalid.json +0 -33
- package/tests/fixtures/measurement/water-salinity/valid-brakish.json +0 -40
- package/tests/fixtures/measurement/water-salinity/valid.json +0 -33
- package/tests/fixtures/organisation/valid.json +0 -26
- package/tests/fixtures/practice/croppingDuration/riceGrainInHuskFlooded/invalid.json +0 -63
- package/tests/fixtures/practice/croppingDuration/riceGrainInHuskFlooded/valid.json +0 -63
- package/tests/fixtures/practice/defaultValue/invalid.json +0 -12
- package/tests/fixtures/practice/defaultValue/valid.json +0 -15
- package/tests/fixtures/practice/excretaManagement/invalid.json +0 -50
- package/tests/fixtures/practice/excretaManagement/valid.json +0 -60
- package/tests/fixtures/practice/irrigated-complete/invalid.json +0 -47
- package/tests/fixtures/practice/irrigated-complete/valid-incomplete.json +0 -47
- package/tests/fixtures/practice/irrigated-complete/valid.json +0 -60
- package/tests/fixtures/practice/landCover-products/invalid.json +0 -58
- package/tests/fixtures/practice/landCover-products/valid-coverCrop.json +0 -69
- package/tests/fixtures/practice/landCover-products/valid.json +0 -58
- package/tests/fixtures/practice/liveAnimal-system/invalid.json +0 -58
- package/tests/fixtures/practice/liveAnimal-system/valid.json +0 -69
- package/tests/fixtures/practice/longFallowDuration/invalid.json +0 -20
- package/tests/fixtures/practice/longFallowDuration/valid.json +0 -20
- package/tests/fixtures/practice/noTillage/invalid.json +0 -23
- package/tests/fixtures/practice/noTillage/valid-value-not-100.json +0 -23
- package/tests/fixtures/practice/noTillage/valid.json +0 -21
- package/tests/fixtures/practice/pastureGrass/key-termType/invalid.json +0 -16
- package/tests/fixtures/practice/pastureGrass/key-termType/valid.json +0 -16
- package/tests/fixtures/practice/pastureGrass/key-value/invalid-numbers.json +0 -67
- package/tests/fixtures/practice/pastureGrass/key-value/invalid.json +0 -67
- package/tests/fixtures/practice/pastureGrass/key-value/valid.json +0 -67
- package/tests/fixtures/practice/pastureGrass/permanent-pasture/invalid.json +0 -37
- package/tests/fixtures/practice/pastureGrass/permanent-pasture/valid.json +0 -47
- package/tests/fixtures/practice/primaryPercent/invalid.json +0 -49
- package/tests/fixtures/practice/primaryPercent/valid.json +0 -49
- package/tests/fixtures/practice/processingOperation/invalid-no-primary.json +0 -48
- package/tests/fixtures/practice/processingOperation/invalid.json +0 -49
- package/tests/fixtures/practice/processingOperation/valid-cropland.json +0 -37
- package/tests/fixtures/practice/processingOperation/valid.json +0 -49
- package/tests/fixtures/practice/productivePhasePermanentCrops/invalid.json +0 -48
- package/tests/fixtures/practice/productivePhasePermanentCrops/valid-0-value.json +0 -58
- package/tests/fixtures/practice/productivePhasePermanentCrops/valid-no-value.json +0 -47
- package/tests/fixtures/practice/productivePhasePermanentCrops/valid.json +0 -48
- package/tests/fixtures/practice/site-management/invalid.json +0 -75
- package/tests/fixtures/practice/site-management/valid.json +0 -75
- package/tests/fixtures/practice/tillage-siteType/valid.json +0 -51
- package/tests/fixtures/practice/tillage-siteType/warning.json +0 -42
- package/tests/fixtures/practice/tillage-values/invalid-fullTillage.json +0 -61
- package/tests/fixtures/practice/tillage-values/invalid-noTillage.json +0 -61
- package/tests/fixtures/practice/tillage-values/valid.json +0 -61
- package/tests/fixtures/practice/waterRegime/rice/invalid.json +0 -59
- package/tests/fixtures/practice/waterRegime/rice/valid-0-value.json +0 -59
- package/tests/fixtures/practice/waterRegime/rice/valid.json +0 -58
- package/tests/fixtures/product/economicValueShare/invalid.json +0 -31
- package/tests/fixtures/product/economicValueShare/valid.json +0 -22
- package/tests/fixtures/product/excreta/invalid.json +0 -62
- package/tests/fixtures/product/excreta/valid.json +0 -62
- package/tests/fixtures/product/excreta/warning.json +0 -53
- package/tests/fixtures/product/excreta/with-system/invalid.json +0 -79
- package/tests/fixtures/product/excreta/with-system/valid.json +0 -88
- package/tests/fixtures/product/excreta/with-system/warning.json +0 -70
- package/tests/fixtures/product/fu_ha/invalid.json +0 -49
- package/tests/fixtures/product/fu_ha/valid.json +0 -49
- package/tests/fixtures/product/primary/invalid.json +0 -22
- package/tests/fixtures/product/primary/valid.json +0 -22
- package/tests/fixtures/product/value/valid.json +0 -26
- package/tests/fixtures/product/value/value-0/error.json +0 -40
- package/tests/fixtures/product/value/value-empty/warning.json +0 -23
- package/tests/fixtures/product/yield/invalid.json +0 -54
- package/tests/fixtures/product/yield/no-value.json +0 -75
- package/tests/fixtures/product/yield/valid.json +0 -54
- package/tests/fixtures/property/default-value/valid-allowed-exception.json +0 -61
- package/tests/fixtures/property/default-value/valid.json +0 -61
- package/tests/fixtures/property/default-value/warning.json +0 -61
- package/tests/fixtures/property/termType/invalid.json +0 -60
- package/tests/fixtures/property/termType/valid.json +0 -60
- package/tests/fixtures/property/value-min-max/invalid.json +0 -77
- package/tests/fixtures/property/value-min-max/valid-skip-maximum.json +0 -57
- package/tests/fixtures/property/value-min-max/valid.json +0 -78
- package/tests/fixtures/property/valueType/invalid.json +0 -79
- package/tests/fixtures/property/valueType/valid.json +0 -79
- package/tests/fixtures/property/volatileSolidsContent/invalid.json +0 -99
- package/tests/fixtures/property/volatileSolidsContent/valid.json +0 -99
- package/tests/fixtures/shared/coordinates/invalid.json +0 -18
- package/tests/fixtures/shared/coordinates/valid.json +0 -18
- package/tests/fixtures/shared/data-duplicates/valid.json +0 -113
- package/tests/fixtures/shared/data-duplicates/warning.json +0 -172
- package/tests/fixtures/shared/duplicated-term-units/invalid-animalProduct.json +0 -61
- package/tests/fixtures/shared/duplicated-term-units/invalid-organicFertiliser.json +0 -61
- package/tests/fixtures/shared/duplicated-term-units/valid.json +0 -49
- package/tests/fixtures/shared/list-country-region/invalid.json +0 -54
- package/tests/fixtures/shared/list-country-region/valid.json +0 -54
- package/tests/fixtures/shared/list-percent-value/invalid.json +0 -49
- package/tests/fixtures/shared/list-percent-value/valid.json +0 -52
- package/tests/fixtures/shared/list-valueType/invalid.json +0 -49
- package/tests/fixtures/shared/list-valueType/valid.json +0 -49
- package/tests/fixtures/shared/list-values-sum-100/management/with-properties/valid.json +0 -91
- package/tests/fixtures/shared/list-values-sum-100/measurements/missing-soil.json +0 -46
- package/tests/fixtures/shared/list-values-sum-100/measurements/no-depth-high-value.json +0 -63
- package/tests/fixtures/shared/list-values-sum-100/measurements/no-depth-valid.json +0 -40
- package/tests/fixtures/shared/list-values-sum-100/measurements/with-depth-high-value.json +0 -71
- package/tests/fixtures/shared/list-values-sum-100/practices/total-100.json +0 -61
- package/tests/fixtures/shared/list-values-sum-100/practices/total-110.json +0 -61
- package/tests/fixtures/shared/list-values-sum-100/practices/total-90.json +0 -61
- package/tests/fixtures/shared/min-max/value-above.json +0 -31
- package/tests/fixtures/shared/min-max/value-below.json +0 -31
- package/tests/fixtures/shared/min-max/value-valid.json +0 -45
- package/tests/fixtures/shared/model/emissions/invalid.json +0 -102
- package/tests/fixtures/shared/model/emissions/valid-variable-tolerance.json +0 -180
- package/tests/fixtures/shared/model/emissions/valid.json +0 -102
- package/tests/fixtures/shared/model/impacts/invalid.json +0 -75
- package/tests/fixtures/shared/model/impacts/valid.json +0 -75
- package/tests/fixtures/shared/model/inputs/valid-no-value.json +0 -84
- package/tests/fixtures/shared/model/inputs/valid.json +0 -87
- package/tests/fixtures/shared/model/inputs/warning.json +0 -87
- package/tests/fixtures/shared/model/products/valid-no-value.json +0 -88
- package/tests/fixtures/shared/model/products/valid.json +0 -91
- package/tests/fixtures/shared/model/products/warning.json +0 -91
- package/tests/fixtures/shared/otherModel/invalid.json +0 -69
- package/tests/fixtures/shared/otherModel/valid.json +0 -70
- package/tests/fixtures/shared/properties-duplicate-values/invalid.json +0 -61
- package/tests/fixtures/shared/properties-duplicate-values/valid.json +0 -57
- package/tests/fixtures/shared/properties-same-length/invalid.json +0 -62
- package/tests/fixtures/shared/properties-same-length/valid.json +0 -52
- package/tests/fixtures/shared/unit-percent/invalid.json +0 -34
- package/tests/fixtures/shared/unit-percent/valid.json +0 -60
- package/tests/fixtures/shared/unit-percent/warning.json +0 -52
- package/tests/fixtures/site/cycles-linked-ia/invalid.json +0 -129
- package/tests/fixtures/site/cycles-linked-ia/valid.json +0 -129
- package/tests/fixtures/site/valid.json +0 -138
- package/tests/fixtures/source/valid.json +0 -19
- package/tests/fixtures/transformation/excretaManagement/invalid.json +0 -47
- package/tests/fixtures/transformation/excretaManagement/valid.json +0 -59
- package/tests/fixtures/transformation/inputs-products/invalid.json +0 -43
- package/tests/fixtures/transformation/inputs-products/valid.json +0 -43
- package/tests/fixtures/transformation/linked-emission/invalid.json +0 -101
- package/tests/fixtures/transformation/linked-emission/valid.json +0 -107
- package/tests/fixtures/transformation/previousTransformationId/invalid-no-previous.json +0 -127
- package/tests/fixtures/transformation/previousTransformationId/invalid-previous-input.json +0 -100
- package/tests/fixtures/transformation/previousTransformationId/invalid-product-input.json +0 -106
- package/tests/fixtures/transformation/previousTransformationId/invalid-wrong-order.json +0 -136
- package/tests/fixtures/transformation/previousTransformationId/valid.json +0 -171
- package/tests/integration/__init__.py +0 -0
- package/tests/integration/test_product.py +0 -17
- package/tests/test_gee.py +0 -10
- package/tests/test_utils.py +0 -36
- package/tests/test_validation.py +0 -11
- package/tests/utils.py +0 -28
- package/tests/validators/__init__.py +0 -0
- package/tests/validators/test_aggregated_cycle.py +0 -44
- package/tests/validators/test_aggregated_shared.py +0 -63
- package/tests/validators/test_animal.py +0 -72
- package/tests/validators/test_completeness.py +0 -337
- package/tests/validators/test_cycle.py +0 -600
- package/tests/validators/test_emission.py +0 -170
- package/tests/validators/test_impact_assessment.py +0 -80
- package/tests/validators/test_indicator.py +0 -120
- package/tests/validators/test_infrastructure.py +0 -26
- package/tests/validators/test_input.py +0 -434
- package/tests/validators/test_management.py +0 -177
- package/tests/validators/test_measurement.py +0 -317
- package/tests/validators/test_organisation.py +0 -32
- package/tests/validators/test_practice.py +0 -490
- package/tests/validators/test_product.py +0 -291
- package/tests/validators/test_property.py +0 -143
- package/tests/validators/test_shared.py +0 -1139
- package/tests/validators/test_site.py +0 -151
- package/tests/validators/test_source.py +0 -15
- package/tests/validators/test_transformation.py +0 -151
- package/tests/validators/test_validators.py +0 -74
- package/tsconfig.dist.json +0 -9
- package/tsconfig.json +0 -25
|
@@ -1,1139 +0,0 @@
|
|
|
1
|
-
from unittest.mock import patch
|
|
2
|
-
import pytest
|
|
3
|
-
import json
|
|
4
|
-
from hestia_earth.schema import TermTermType
|
|
5
|
-
|
|
6
|
-
from tests.utils import fixtures_path
|
|
7
|
-
from hestia_earth.validation.utils import _group_nodes, _hash_nodes
|
|
8
|
-
from hestia_earth.validation.validators.shared import (
|
|
9
|
-
validate_dates,
|
|
10
|
-
validate_list_dates,
|
|
11
|
-
validate_list_min_below_max,
|
|
12
|
-
validate_list_min_max_lookup,
|
|
13
|
-
validate_country,
|
|
14
|
-
validate_region_in_country,
|
|
15
|
-
validate_is_region,
|
|
16
|
-
validate_list_country_region,
|
|
17
|
-
validate_area,
|
|
18
|
-
validate_coordinates,
|
|
19
|
-
need_validate_coordinates,
|
|
20
|
-
validate_list_term_percent,
|
|
21
|
-
validate_empty_fields,
|
|
22
|
-
validate_linked_source_privacy,
|
|
23
|
-
validate_list_dates_length,
|
|
24
|
-
validate_date_lt_today,
|
|
25
|
-
validate_list_date_lt_today,
|
|
26
|
-
value_difference,
|
|
27
|
-
is_value_different,
|
|
28
|
-
validate_list_model,
|
|
29
|
-
validate_list_model_config,
|
|
30
|
-
validate_properties_same_length,
|
|
31
|
-
validate_list_duplicate_values,
|
|
32
|
-
validate_nodes_duplicates,
|
|
33
|
-
validate_boundary_area,
|
|
34
|
-
validate_region_size,
|
|
35
|
-
need_validate_region_size,
|
|
36
|
-
validate_private_has_source,
|
|
37
|
-
validate_list_value_between_min_max,
|
|
38
|
-
validate_list_dates_after,
|
|
39
|
-
validate_duplicated_term_units,
|
|
40
|
-
validate_list_sum_100_percent,
|
|
41
|
-
validate_list_percent_requires_value,
|
|
42
|
-
validate_other_model,
|
|
43
|
-
validate_list_valueType,
|
|
44
|
-
validate_nested_existing_node,
|
|
45
|
-
)
|
|
46
|
-
from hestia_earth.validation.validators.cycle import (
|
|
47
|
-
PRODUCTS_MODEL_CONFIG,
|
|
48
|
-
INPUTS_MODEL_CONFIG,
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
class_path = "hestia_earth.validation.validators.shared"
|
|
52
|
-
fixtures_folder = f"{fixtures_path}/shared"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
def test_validate_dates():
|
|
56
|
-
assert validate_dates({"startDate": "2020-01-01"}) is True
|
|
57
|
-
|
|
58
|
-
assert validate_dates({"endDate": "2020-01-02"}) is True
|
|
59
|
-
|
|
60
|
-
assert validate_dates({"startDate": "2020-01-01", "endDate": "2020-01-02"}) is True
|
|
61
|
-
|
|
62
|
-
assert not validate_dates({"startDate": "2020-01-02", "endDate": "2020-01-01"})
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
def test_validate_list_dates_length_valid():
|
|
66
|
-
cycle = {"emissions": [{"value": [1], "dates": [1]}]}
|
|
67
|
-
assert validate_list_dates_length(cycle, "emissions") is True
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def test_validate_list_dates_length_invalid():
|
|
71
|
-
cycle = {"emissions": [{"value": [1], "dates": [1, 2]}]}
|
|
72
|
-
assert validate_list_dates_length(cycle, "emissions") == {
|
|
73
|
-
"level": "error",
|
|
74
|
-
"dataPath": ".emissions[0].dates",
|
|
75
|
-
"message": "must contain as many items as values",
|
|
76
|
-
"params": {"current": 2, "expected": 1},
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
def test_validate_list_dates_valid():
|
|
81
|
-
node = {"list": [{"startDate": "2020-01-01", "endDate": "2020-01-02"}]}
|
|
82
|
-
assert validate_list_dates(node, "list") is True
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
def test_validate_list_dates_invalid():
|
|
86
|
-
node = {"list": [{"startDate": "2020-01-02", "endDate": "2020-01-01"}]}
|
|
87
|
-
assert validate_list_dates(node, "list") == {
|
|
88
|
-
"level": "error",
|
|
89
|
-
"dataPath": ".list[0].endDate",
|
|
90
|
-
"message": "must be greater than startDate",
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
def validate_list_dates_after_valid():
|
|
95
|
-
node = {
|
|
96
|
-
"type": "Cycle",
|
|
97
|
-
"date": "2020-01-01",
|
|
98
|
-
"list": [
|
|
99
|
-
{
|
|
100
|
-
"start": "2020-01-02",
|
|
101
|
-
"end": "2020-01-03",
|
|
102
|
-
"dates": ["2020-01-02", "2020-01-03"],
|
|
103
|
-
}
|
|
104
|
-
],
|
|
105
|
-
}
|
|
106
|
-
assert (
|
|
107
|
-
validate_list_dates_after(node, "date", "list", ["start", "end", "dates"])
|
|
108
|
-
is True
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
def test_validate_list_dates_after_invalid():
|
|
113
|
-
node = {
|
|
114
|
-
"type": "Cycle",
|
|
115
|
-
"date": "2020-01-01",
|
|
116
|
-
"list": [
|
|
117
|
-
{
|
|
118
|
-
"start": "2020-01-02",
|
|
119
|
-
"end": "2019-01-01",
|
|
120
|
-
"dates": ["2020-01-02", "2019-01-01"],
|
|
121
|
-
}
|
|
122
|
-
],
|
|
123
|
-
}
|
|
124
|
-
assert validate_list_dates_after(
|
|
125
|
-
node, "date", "list", ["start", "end", "dates"]
|
|
126
|
-
) == [
|
|
127
|
-
{
|
|
128
|
-
"level": "warning",
|
|
129
|
-
"dataPath": ".list[0].end",
|
|
130
|
-
"message": "must be greater than Cycle date",
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
"level": "warning",
|
|
134
|
-
"dataPath": ".list[0].dates[1]",
|
|
135
|
-
"message": "must be greater than Cycle date",
|
|
136
|
-
},
|
|
137
|
-
]
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
def test_validate_list_min_below_max_valid():
|
|
141
|
-
node = {"list": [{"min": 10, "max": 100}]}
|
|
142
|
-
assert validate_list_min_below_max(node, "list") is True
|
|
143
|
-
node = {"list": [{"min": [50, 10], "max": [60, 20]}]}
|
|
144
|
-
assert validate_list_min_below_max(node, "list") is True
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
def test_validate_list_min_below_max_invalid():
|
|
148
|
-
node = {"list": [{"min": 100, "max": 10}]}
|
|
149
|
-
assert validate_list_min_below_max(node, "list") == {
|
|
150
|
-
"level": "error",
|
|
151
|
-
"dataPath": ".list[0].max",
|
|
152
|
-
"message": "must be greater than min",
|
|
153
|
-
}
|
|
154
|
-
node = {"list": [{"min": [1, 120], "max": [10, 20]}]}
|
|
155
|
-
assert validate_list_min_below_max(node, "list") == {
|
|
156
|
-
"level": "error",
|
|
157
|
-
"dataPath": ".list[0].max",
|
|
158
|
-
"message": "must be greater than min",
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
def test_validate_list_value_between_min_max_valid():
|
|
163
|
-
node = {"list": [{"min": 10, "value": 50, "max": 100}]}
|
|
164
|
-
assert validate_list_value_between_min_max(node, "list") is True
|
|
165
|
-
node = {"list": [{"min": [50, 10], "value": [55, 15], "max": [60, 20]}]}
|
|
166
|
-
assert validate_list_value_between_min_max(node, "list") is True
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
def test_validate_list_value_between_min_max_invalid():
|
|
170
|
-
node = {"list": [{"min": 0, "value": 20, "max": 10}]}
|
|
171
|
-
assert validate_list_value_between_min_max(node, "list") == {
|
|
172
|
-
"level": "error",
|
|
173
|
-
"dataPath": ".list[0].value",
|
|
174
|
-
"message": "must be between min and max",
|
|
175
|
-
"params": {
|
|
176
|
-
"max": 10,
|
|
177
|
-
"min": 0,
|
|
178
|
-
},
|
|
179
|
-
}
|
|
180
|
-
node = {"list": [{"min": [1, 10], "value": [5, 200], "max": [10, 20]}]}
|
|
181
|
-
assert validate_list_value_between_min_max(node, "list") == {
|
|
182
|
-
"level": "error",
|
|
183
|
-
"dataPath": ".list[0].value",
|
|
184
|
-
"message": "must be between min and max",
|
|
185
|
-
"params": {
|
|
186
|
-
"max": [10, 20],
|
|
187
|
-
"min": [1, 10],
|
|
188
|
-
},
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
def test_validate_list_min_max_lookup_valid():
|
|
193
|
-
# no measurements should be valid
|
|
194
|
-
assert validate_list_min_max_lookup({}, "measurements") is True
|
|
195
|
-
|
|
196
|
-
with open(f"{fixtures_folder}/min-max/value-valid.json") as f:
|
|
197
|
-
data = json.load(f)
|
|
198
|
-
assert validate_list_min_max_lookup(data, "measurements") is True
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
def test_validate_list_min_max_lookup_invalid():
|
|
202
|
-
with open(f"{fixtures_folder}/min-max/value-above.json") as f:
|
|
203
|
-
data = json.load(f)
|
|
204
|
-
assert validate_list_min_max_lookup(data, "measurements") == {
|
|
205
|
-
"level": "error",
|
|
206
|
-
"dataPath": ".measurements[0].value",
|
|
207
|
-
"message": "should be below 25000.0",
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
with open(f"{fixtures_folder}/min-max/value-below.json") as f:
|
|
211
|
-
data = json.load(f)
|
|
212
|
-
assert validate_list_min_max_lookup(data, "measurements") == {
|
|
213
|
-
"level": "error",
|
|
214
|
-
"dataPath": ".measurements[0].value",
|
|
215
|
-
"message": "should be above 0.0",
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
def test_validate_country_valid():
|
|
220
|
-
node = {"country": {"@id": "GADM-AUS", "name": "Australia"}}
|
|
221
|
-
assert validate_country(node) is True
|
|
222
|
-
node["country"]["@id"] = "region-world"
|
|
223
|
-
assert validate_country(node) is True
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
def test_validate_country_invalid():
|
|
227
|
-
node = {"country": {"@id": "random-term"}}
|
|
228
|
-
assert validate_country(node) == {
|
|
229
|
-
"level": "error",
|
|
230
|
-
"dataPath": ".country",
|
|
231
|
-
"message": "must be a country",
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
node = {"country": {"@id": "GADM-IDN.1_1"}}
|
|
235
|
-
assert validate_country(node) == {
|
|
236
|
-
"level": "error",
|
|
237
|
-
"dataPath": ".country",
|
|
238
|
-
"message": "must be a country",
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
def test_validate_region_in_country_valid():
|
|
243
|
-
node = {
|
|
244
|
-
"country": {"@id": "GADM-AUS", "name": "Australia"},
|
|
245
|
-
"region": {"@id": "GADM-AUS.1_1"},
|
|
246
|
-
}
|
|
247
|
-
assert validate_region_in_country(node) is True
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
def test_validate_region_in_country_invalid():
|
|
251
|
-
node = {
|
|
252
|
-
"country": {"@id": "GADM-AUS", "name": "Australia"},
|
|
253
|
-
"region": {"@id": "GADM-FRA.1_1"},
|
|
254
|
-
}
|
|
255
|
-
assert validate_region_in_country(node) == {
|
|
256
|
-
"level": "error",
|
|
257
|
-
"dataPath": ".region",
|
|
258
|
-
"message": "must be within the country",
|
|
259
|
-
"params": {"country": "Australia"},
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
def test_validate_is_region_valid():
|
|
264
|
-
node = {"region": {"@id": "GADM-FRA.1_1"}}
|
|
265
|
-
assert validate_is_region(node) is True
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
def test_validate_is_region_invalid():
|
|
269
|
-
node = {"region": {"@id": "GADM-FRA"}}
|
|
270
|
-
assert validate_is_region(node) == {
|
|
271
|
-
"level": "error",
|
|
272
|
-
"dataPath": ".region",
|
|
273
|
-
"message": "must not be a country",
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
def test_validate_list_country_region_valid():
|
|
278
|
-
with open(f"{fixtures_folder}/list-country-region/valid.json") as f:
|
|
279
|
-
node = json.load(f)
|
|
280
|
-
assert validate_list_country_region(node, "inputs") is True
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
def test_validate_list_country_region_invalid():
|
|
284
|
-
with open(f"{fixtures_folder}/list-country-region/invalid.json") as f:
|
|
285
|
-
node = json.load(f)
|
|
286
|
-
assert validate_list_country_region(node, "inputs") == [
|
|
287
|
-
{
|
|
288
|
-
"level": "error",
|
|
289
|
-
"dataPath": ".inputs[0].country",
|
|
290
|
-
"message": "must be a country",
|
|
291
|
-
},
|
|
292
|
-
{
|
|
293
|
-
"level": "error",
|
|
294
|
-
"dataPath": ".inputs[0].region",
|
|
295
|
-
"message": "must not be a country",
|
|
296
|
-
},
|
|
297
|
-
{
|
|
298
|
-
"level": "error",
|
|
299
|
-
"dataPath": ".inputs[0].region",
|
|
300
|
-
"message": "must be within the country",
|
|
301
|
-
"params": {"country": None},
|
|
302
|
-
},
|
|
303
|
-
]
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
def test_validate_area_valid():
|
|
307
|
-
node = {"area": 4, "boundaryArea": 4}
|
|
308
|
-
assert validate_area(node) is True
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
def test_validate_area_invalid():
|
|
312
|
-
node = {"area": 4, "boundaryArea": 5}
|
|
313
|
-
assert validate_area(node) == {
|
|
314
|
-
"level": "warning",
|
|
315
|
-
"dataPath": ".area",
|
|
316
|
-
"message": "should be equal to boundary",
|
|
317
|
-
"params": {"current": 4, "expected": 5, "delta": 20, "threshold": 0.05},
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
@patch(f"{class_path}.get_region_id", return_value="GADM-GBR")
|
|
322
|
-
def test_validate_coordinates_valid(*args):
|
|
323
|
-
with open(f"{fixtures_folder}/coordinates/valid.json") as f:
|
|
324
|
-
node = json.load(f)
|
|
325
|
-
assert validate_coordinates(node) is True
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
@patch(f"{class_path}.get_region_distance", return_value=5)
|
|
329
|
-
@patch(f"{class_path}.get_region_id", return_value="GADM-GBR")
|
|
330
|
-
def test_validate_coordinates_invalid(*args):
|
|
331
|
-
with open(f"{fixtures_folder}/coordinates/invalid.json") as f:
|
|
332
|
-
node = json.load(f)
|
|
333
|
-
assert validate_coordinates(node) == {
|
|
334
|
-
"level": "error",
|
|
335
|
-
"dataPath": ".country",
|
|
336
|
-
"message": "does not contain latitude and longitude",
|
|
337
|
-
"params": {"current": "GADM-FRA", "expected": "GADM-GBR", "distance": 5},
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
@patch(f"{class_path}.gee_is_enabled", return_value=True)
|
|
342
|
-
def test_need_validate_coordinates(*args):
|
|
343
|
-
node = {}
|
|
344
|
-
assert not need_validate_coordinates(node)
|
|
345
|
-
|
|
346
|
-
node["latitude"] = 0
|
|
347
|
-
node["longitude"] = 0
|
|
348
|
-
assert need_validate_coordinates(node) is True
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
def test_validate_list_term_percent_valid():
|
|
352
|
-
with open(f"{fixtures_folder}/unit-percent/valid.json") as f:
|
|
353
|
-
node = json.load(f)
|
|
354
|
-
assert validate_list_term_percent(node, "measurements") is True
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
def test_validate_list_term_percent_invalid():
|
|
358
|
-
with open(f"{fixtures_folder}/unit-percent/invalid.json") as f:
|
|
359
|
-
node = json.load(f)
|
|
360
|
-
assert validate_list_term_percent(node, "measurements") == {
|
|
361
|
-
"level": "error",
|
|
362
|
-
"dataPath": ".measurements[0].value",
|
|
363
|
-
"message": "should be between 0 and 100 (percentage)",
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
def test_validate_list_term_percent_warning():
|
|
368
|
-
with open(f"{fixtures_folder}/unit-percent/warning.json") as f:
|
|
369
|
-
node = json.load(f)
|
|
370
|
-
assert validate_list_term_percent(node, "measurements") == [
|
|
371
|
-
{
|
|
372
|
-
"level": "warning",
|
|
373
|
-
"dataPath": ".measurements[0].value",
|
|
374
|
-
"message": "may be between 0 and 100",
|
|
375
|
-
},
|
|
376
|
-
{
|
|
377
|
-
"level": "warning",
|
|
378
|
-
"dataPath": ".measurements[1].value",
|
|
379
|
-
"message": "may be between 0 and 100",
|
|
380
|
-
},
|
|
381
|
-
]
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
def test_validate_empty_fields_valid():
|
|
385
|
-
node = {"value": "correct string"}
|
|
386
|
-
assert validate_empty_fields(node) == []
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
def test_validate_empty_fields_warning():
|
|
390
|
-
node = {"value1": "N/A", "value2": "no data", "test": None}
|
|
391
|
-
assert validate_empty_fields(node) == [
|
|
392
|
-
{"level": "warning", "dataPath": ".value1", "message": "may not be empty"},
|
|
393
|
-
{"level": "warning", "dataPath": ".value2", "message": "may not be empty"},
|
|
394
|
-
]
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
def test_validate_private_has_source_valid():
|
|
398
|
-
# valid if public
|
|
399
|
-
node = {"dataPrivate": False}
|
|
400
|
-
assert validate_private_has_source(node, "source") is True
|
|
401
|
-
|
|
402
|
-
# valid if private and with Source
|
|
403
|
-
node = {"source": {"type": "Source", "id": "1"}, "dataPrivate": True}
|
|
404
|
-
assert validate_private_has_source(node, "source") is True
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
def test_validate_private_has_source_warning():
|
|
408
|
-
node = {"dataPrivate": True}
|
|
409
|
-
assert validate_private_has_source(node, "source") == {
|
|
410
|
-
"level": "warning",
|
|
411
|
-
"dataPath": ".dataPrivate",
|
|
412
|
-
"message": "should add a source",
|
|
413
|
-
"params": {"current": "source"},
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
def test_validate_linked_source_privacy_valid():
|
|
418
|
-
node = {"source": {"type": "Source", "id": "1"}, "dataPrivate": True}
|
|
419
|
-
# valid if no connected source
|
|
420
|
-
assert validate_linked_source_privacy(node, "source") is True
|
|
421
|
-
|
|
422
|
-
source = {"type": "Source", "id": "1", "dataPrivate": True}
|
|
423
|
-
assert (
|
|
424
|
-
validate_linked_source_privacy(node, "source", _group_nodes([source])) is True
|
|
425
|
-
)
|
|
426
|
-
|
|
427
|
-
node["dataPrivate"] = False
|
|
428
|
-
source["dataPrivate"] = False
|
|
429
|
-
assert (
|
|
430
|
-
validate_linked_source_privacy(node, "source", _group_nodes([source])) is True
|
|
431
|
-
)
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
def test_validate_linked_source_privacy_invalid():
|
|
435
|
-
node = {"source": {"type": "Source", "id": "1"}, "dataPrivate": False}
|
|
436
|
-
source = {"type": "Source", "id": "1", "dataPrivate": True}
|
|
437
|
-
assert validate_linked_source_privacy(node, "source", _group_nodes([source])) == {
|
|
438
|
-
"level": "error",
|
|
439
|
-
"dataPath": ".dataPrivate",
|
|
440
|
-
"message": "should have the same privacy as the related source",
|
|
441
|
-
"params": {"dataPrivate": False, "source": {"dataPrivate": True}},
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
node["dataPrivate"] = True
|
|
445
|
-
source["dataPrivate"] = False
|
|
446
|
-
assert validate_linked_source_privacy(node, "source", _group_nodes([source])) == {
|
|
447
|
-
"level": "error",
|
|
448
|
-
"dataPath": ".dataPrivate",
|
|
449
|
-
"message": "should have the same privacy as the related source",
|
|
450
|
-
"params": {"dataPrivate": True, "source": {"dataPrivate": False}},
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
@patch(f"{class_path}.find_linked_node")
|
|
455
|
-
def test_validate_linked_source_privacy_indexed(mockfind_linked_node):
|
|
456
|
-
node = {"source": {"@type": "Source", "@id": "1"}, "dataPrivate": True}
|
|
457
|
-
mockfind_linked_node.return_value = {"dataPrivate": True}
|
|
458
|
-
assert validate_linked_source_privacy(node, "source") is True
|
|
459
|
-
|
|
460
|
-
mockfind_linked_node.return_value = {"dataPrivate": False}
|
|
461
|
-
assert validate_linked_source_privacy(node, "source") == {
|
|
462
|
-
"level": "error",
|
|
463
|
-
"dataPath": ".dataPrivate",
|
|
464
|
-
"message": "should have the same privacy as the related source",
|
|
465
|
-
"params": {"dataPrivate": True, "source": {"dataPrivate": False}},
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
def test_validate_date_lt_today_valid():
|
|
470
|
-
key = "date"
|
|
471
|
-
assert validate_date_lt_today({key: "2000-01-01"}, key) is True
|
|
472
|
-
assert validate_date_lt_today({key: "2022"}, key) is True
|
|
473
|
-
assert validate_date_lt_today({"test": {key: "2022"}}, f"test.{key}") is True
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
def test_validate_date_lt_today_invalid():
|
|
477
|
-
key = "date"
|
|
478
|
-
node = {key: "2500-01-01"}
|
|
479
|
-
assert validate_date_lt_today(node, key) == {
|
|
480
|
-
"level": "error",
|
|
481
|
-
"dataPath": ".date",
|
|
482
|
-
"message": "must be before today",
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
def test_validate_list_date_lt_today_valid():
|
|
487
|
-
node = {"list": [{"date1": "2001-01-01"}, {"date2": "2002-01-01"}]}
|
|
488
|
-
keys = ["date1", "date2", "date3"]
|
|
489
|
-
assert validate_list_date_lt_today(node, "list", keys) is True
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
def test_validate_list_date_lt_today_invalid():
|
|
493
|
-
node = {"list": [{"date1": "2001-01-01"}, {"date2": "2500-01-01"}]}
|
|
494
|
-
keys = ["date1", "date2", "date3"]
|
|
495
|
-
assert validate_list_date_lt_today(node, "list", keys) == {
|
|
496
|
-
"level": "error",
|
|
497
|
-
"dataPath": ".list[1].date2",
|
|
498
|
-
"message": "must be before today",
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
def test_value_difference():
|
|
503
|
-
assert value_difference(125, 100) == 0.25
|
|
504
|
-
assert value_difference(75, 100) == 0.25
|
|
505
|
-
assert value_difference(0, 50) == 1
|
|
506
|
-
assert value_difference(50, 0) == 0
|
|
507
|
-
assert value_difference(67.0, 52.87673036) == 0.2671
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
def test_is_value_different():
|
|
511
|
-
# default detla is 5%
|
|
512
|
-
assert is_value_different(106, 100) is True
|
|
513
|
-
assert not is_value_different(105, 100)
|
|
514
|
-
|
|
515
|
-
assert is_value_different(111, 100, 0.1) is True
|
|
516
|
-
assert not is_value_different(110, 100, 0.1)
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
@patch("hestia_earth.models.utils.property.get_node_property", return_value=None)
|
|
520
|
-
def test_validate_list_model_valid(*args):
|
|
521
|
-
# validating Cycle.emissions
|
|
522
|
-
with open(f"{fixtures_folder}/model/emissions/valid.json") as f:
|
|
523
|
-
cycle = json.load(f)
|
|
524
|
-
assert validate_list_model(cycle, "emissions") is True
|
|
525
|
-
|
|
526
|
-
with open(f"{fixtures_folder}/model/emissions/valid-variable-tolerance.json") as f:
|
|
527
|
-
cycle = json.load(f)
|
|
528
|
-
assert validate_list_model(cycle, "emissions") is True
|
|
529
|
-
|
|
530
|
-
# validating ImpactAssessment.impacts
|
|
531
|
-
with open(f"{fixtures_folder}/model/impacts/valid.json") as f:
|
|
532
|
-
impact = json.load(f)
|
|
533
|
-
assert validate_list_model(impact, "impacts") is True
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
@patch("hestia_earth.models.utils.property.get_node_property", return_value=None)
|
|
537
|
-
def test_validate_list_model_invalid(*args):
|
|
538
|
-
# validating Cycle.emissions
|
|
539
|
-
with open(f"{fixtures_folder}/model/emissions/invalid.json") as f:
|
|
540
|
-
cycle = json.load(f)
|
|
541
|
-
assert validate_list_model(cycle, "emissions") == {
|
|
542
|
-
"level": "error",
|
|
543
|
-
"dataPath": ".emissions[0].value",
|
|
544
|
-
"message": "the value provided is not consistent with the model result",
|
|
545
|
-
"params": {
|
|
546
|
-
"model": {
|
|
547
|
-
"@type": "Term",
|
|
548
|
-
"@id": "ipcc2019",
|
|
549
|
-
"name": "IPCC (2019)",
|
|
550
|
-
"termType": "model",
|
|
551
|
-
},
|
|
552
|
-
"term": {
|
|
553
|
-
"@type": "Term",
|
|
554
|
-
"@id": "co2ToAirUreaHydrolysis",
|
|
555
|
-
"name": "CO2, to air, urea hydrolysis",
|
|
556
|
-
"units": "kg CO2",
|
|
557
|
-
"termType": "emission",
|
|
558
|
-
},
|
|
559
|
-
"current": 200,
|
|
560
|
-
"expected": 157,
|
|
561
|
-
"delta": 27.39,
|
|
562
|
-
"threshold": 0.05,
|
|
563
|
-
},
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
# validating ImpactAssessment.impacts
|
|
567
|
-
with open(f"{fixtures_folder}/model/impacts/invalid.json") as f:
|
|
568
|
-
impact = json.load(f)
|
|
569
|
-
assert validate_list_model(impact, "impacts") == {
|
|
570
|
-
"level": "error",
|
|
571
|
-
"dataPath": ".impacts[0].value",
|
|
572
|
-
"message": "the value provided is not consistent with the model result",
|
|
573
|
-
"params": {
|
|
574
|
-
"model": {
|
|
575
|
-
"@type": "Term",
|
|
576
|
-
"@id": "ipcc2013IncludingFeedbacks",
|
|
577
|
-
"name": "IPCC (2013) including feedbacks",
|
|
578
|
-
"termType": "model",
|
|
579
|
-
},
|
|
580
|
-
"term": {
|
|
581
|
-
"@type": "Term",
|
|
582
|
-
"@id": "gwp100",
|
|
583
|
-
"name": "GWP100",
|
|
584
|
-
"units": "kg CO2eq",
|
|
585
|
-
"termType": "characterisedIndicator",
|
|
586
|
-
},
|
|
587
|
-
"current": 5,
|
|
588
|
-
"expected": 0.0642,
|
|
589
|
-
"delta": 7688,
|
|
590
|
-
"threshold": 0.05,
|
|
591
|
-
},
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
def test_validate_list_model_config_valid():
|
|
596
|
-
# validating Cycle.products
|
|
597
|
-
with open(f"{fixtures_folder}/model/products/valid.json") as f:
|
|
598
|
-
data = json.load(f)
|
|
599
|
-
assert validate_list_model_config(data, "products", PRODUCTS_MODEL_CONFIG) is True
|
|
600
|
-
|
|
601
|
-
# missing value should skip validation
|
|
602
|
-
with open(f"{fixtures_folder}/model/products/valid-no-value.json") as f:
|
|
603
|
-
data = json.load(f)
|
|
604
|
-
assert validate_list_model_config(data, "products", PRODUCTS_MODEL_CONFIG) is True
|
|
605
|
-
|
|
606
|
-
# validating Cycle.inputs
|
|
607
|
-
with open(f"{fixtures_folder}/model/inputs/valid.json") as f:
|
|
608
|
-
data = json.load(f)
|
|
609
|
-
assert validate_list_model_config(data, "inputs", INPUTS_MODEL_CONFIG) is True
|
|
610
|
-
|
|
611
|
-
# missing value should skip validation
|
|
612
|
-
with open(f"{fixtures_folder}/model/inputs/valid-no-value.json") as f:
|
|
613
|
-
data = json.load(f)
|
|
614
|
-
assert validate_list_model_config(data, "inputs", INPUTS_MODEL_CONFIG) is True
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
def test_validate_list_model_config_invalid():
|
|
618
|
-
# validating Cycle.products
|
|
619
|
-
with open(f"{fixtures_folder}/model/products/warning.json") as f:
|
|
620
|
-
data = json.load(f)
|
|
621
|
-
assert validate_list_model_config(data, "products", PRODUCTS_MODEL_CONFIG) == {
|
|
622
|
-
"level": "warning",
|
|
623
|
-
"dataPath": ".products[1].value",
|
|
624
|
-
"message": "the value provided is not consistent with the model result",
|
|
625
|
-
"params": {
|
|
626
|
-
"model": {
|
|
627
|
-
"@type": "Term",
|
|
628
|
-
"@id": "ipcc2006",
|
|
629
|
-
"name": "IPCC (2006)",
|
|
630
|
-
"termType": "model",
|
|
631
|
-
},
|
|
632
|
-
"term": {
|
|
633
|
-
"@type": "Term",
|
|
634
|
-
"name": "Above Ground Crop Residue Total",
|
|
635
|
-
"@id": "aboveGroundCropResidueTotal",
|
|
636
|
-
},
|
|
637
|
-
"current": 150,
|
|
638
|
-
"expected": 3450,
|
|
639
|
-
"delta": 95.65,
|
|
640
|
-
"threshold": 0.5,
|
|
641
|
-
},
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
# validating Cycle.inputs
|
|
645
|
-
with open(f"{fixtures_folder}/model/inputs/warning.json") as f:
|
|
646
|
-
data = json.load(f)
|
|
647
|
-
assert validate_list_model_config(data, "inputs", INPUTS_MODEL_CONFIG) == {
|
|
648
|
-
"level": "warning",
|
|
649
|
-
"dataPath": ".inputs[0].value",
|
|
650
|
-
"message": "the value provided is not consistent with the model result",
|
|
651
|
-
"params": {
|
|
652
|
-
"model": {
|
|
653
|
-
"@type": "Term",
|
|
654
|
-
"@id": "pooreNemecek2018",
|
|
655
|
-
"name": "Poore & Nemecek (2018)",
|
|
656
|
-
"termType": "model",
|
|
657
|
-
},
|
|
658
|
-
"term": {
|
|
659
|
-
"@type": "Term",
|
|
660
|
-
"name": "Saplings, depreciated amount per Cycle",
|
|
661
|
-
"@id": "saplingsDepreciatedAmountPerCycle",
|
|
662
|
-
},
|
|
663
|
-
"current": 8.25,
|
|
664
|
-
"expected": 16.5,
|
|
665
|
-
"delta": 50,
|
|
666
|
-
"threshold": 0.25,
|
|
667
|
-
},
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
def test_validate_properties_same_length_valid():
|
|
672
|
-
with open(f"{fixtures_folder}/properties-same-length/valid.json") as f:
|
|
673
|
-
data = json.load(f)
|
|
674
|
-
assert (
|
|
675
|
-
validate_properties_same_length(data, "products", "endDate", ["startDate"])
|
|
676
|
-
is True
|
|
677
|
-
)
|
|
678
|
-
|
|
679
|
-
cycle = {"products": [{"endDate": "2019"}]}
|
|
680
|
-
assert (
|
|
681
|
-
validate_properties_same_length(cycle, "products", "endDate", ["startDate"])
|
|
682
|
-
is True
|
|
683
|
-
)
|
|
684
|
-
|
|
685
|
-
cycle = {"products": [{"startDate": "2019"}]}
|
|
686
|
-
assert (
|
|
687
|
-
validate_properties_same_length(cycle, "products", "endDate", ["startDate"])
|
|
688
|
-
is True
|
|
689
|
-
)
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
def test_validate_properties_same_length_invalid():
|
|
693
|
-
with open(f"{fixtures_folder}/properties-same-length/invalid.json") as f:
|
|
694
|
-
data = json.load(f)
|
|
695
|
-
assert validate_properties_same_length(
|
|
696
|
-
data, "products", "endDate", ["startDate"]
|
|
697
|
-
) == {
|
|
698
|
-
"level": "error",
|
|
699
|
-
"dataPath": ".products[1].startDate",
|
|
700
|
-
"message": "must have the same length as endDate",
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
def test_validate_list_duplicate_values_valid():
|
|
705
|
-
with open(f"{fixtures_folder}/properties-duplicate-values/valid.json") as f:
|
|
706
|
-
data = json.load(f)
|
|
707
|
-
assert (
|
|
708
|
-
validate_list_duplicate_values(
|
|
709
|
-
data, "practices", "term.termType", "excretaManagement"
|
|
710
|
-
)
|
|
711
|
-
is True
|
|
712
|
-
)
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
def test_validate_list_duplicate_values_invalid():
|
|
716
|
-
with open(f"{fixtures_folder}/properties-duplicate-values/invalid.json") as f:
|
|
717
|
-
data = json.load(f)
|
|
718
|
-
prop = "term.termType"
|
|
719
|
-
value = "excretaManagement"
|
|
720
|
-
assert validate_list_duplicate_values(data, "practices", prop, value) == {
|
|
721
|
-
"level": "error",
|
|
722
|
-
"dataPath": f".practices[1].{prop}",
|
|
723
|
-
"message": f"must have only one entry with the same {prop} = {value}",
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
def test_validate_nodes_duplicates_valid():
|
|
728
|
-
with open(f"{fixtures_folder}/data-duplicates/valid.json") as f:
|
|
729
|
-
nodes = json.load(f)
|
|
730
|
-
assert validate_nodes_duplicates(nodes[0], _hash_nodes(nodes)) == []
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
def test_validate_nodes_duplicates_invalid():
|
|
734
|
-
with open(f"{fixtures_folder}/data-duplicates/warning.json") as f:
|
|
735
|
-
nodes = json.load(f)
|
|
736
|
-
assert validate_nodes_duplicates(nodes[0], _hash_nodes(nodes)) == [
|
|
737
|
-
{
|
|
738
|
-
"level": "warning",
|
|
739
|
-
"dataPath": "",
|
|
740
|
-
"message": "might be a duplicate of the Site with id 2",
|
|
741
|
-
}
|
|
742
|
-
]
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
def test_validate_boundary_area_valid():
|
|
746
|
-
# no area => valid
|
|
747
|
-
assert validate_boundary_area({}) is True
|
|
748
|
-
|
|
749
|
-
area = 5000
|
|
750
|
-
assert validate_boundary_area({"boundaryArea": area}) is True
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
def test_validate_boundary_area_warning():
|
|
754
|
-
area = 520000
|
|
755
|
-
assert validate_boundary_area({"boundaryArea": area}) == {
|
|
756
|
-
"level": "warning",
|
|
757
|
-
"dataPath": ".boundaryArea",
|
|
758
|
-
"message": "should be lower than max size",
|
|
759
|
-
"params": {"current": 5200, "expected": 5000},
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
@patch(f"{class_path}.gee_is_enabled", return_value=True)
|
|
764
|
-
def test_need_validate_region_size(*args):
|
|
765
|
-
node = {}
|
|
766
|
-
assert not need_validate_region_size(node)
|
|
767
|
-
|
|
768
|
-
node["region"] = "GADM"
|
|
769
|
-
assert need_validate_region_size(node) is True
|
|
770
|
-
|
|
771
|
-
node["latitude"] = 10
|
|
772
|
-
node["longitude"] = 10
|
|
773
|
-
assert not need_validate_region_size(node)
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
@patch("hestia_earth.earth_engine.gadm.get_size_km2", return_value=2500)
|
|
777
|
-
@patch(f"{class_path}.download_hestia")
|
|
778
|
-
def test_validate_region_size_valid(mock_download, *args):
|
|
779
|
-
# no region => valid
|
|
780
|
-
assert validate_region_size({}) is True
|
|
781
|
-
|
|
782
|
-
# with region without download => valid
|
|
783
|
-
assert validate_region_size({"area": 2500}) is True
|
|
784
|
-
|
|
785
|
-
# with region and download => valid
|
|
786
|
-
data = {"region": {"@id": "GADM-FRA"}}
|
|
787
|
-
mock_download.return_value = {"area": 2500}
|
|
788
|
-
assert validate_region_size(data) is True
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
@patch("hestia_earth.earth_engine.gadm.get_size_km2", return_value=10000)
|
|
792
|
-
@patch(f"{class_path}.download_hestia", return_value={})
|
|
793
|
-
def test_validate_region_size_warning(*args):
|
|
794
|
-
assert validate_region_size({"country": {"@id": True}}) == {
|
|
795
|
-
"level": "warning",
|
|
796
|
-
"dataPath": ".country",
|
|
797
|
-
"message": "should be lower than max size",
|
|
798
|
-
"params": {"current": 10000, "expected": 5000},
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
def test_validate_duplicated_term_units_valid():
|
|
803
|
-
# no blank nodes should be valid
|
|
804
|
-
assert (
|
|
805
|
-
validate_duplicated_term_units({}, "inputs", [TermTermType.ORGANICFERTILISER])
|
|
806
|
-
is True
|
|
807
|
-
)
|
|
808
|
-
|
|
809
|
-
with open(f"{fixtures_folder}/duplicated-term-units/valid.json") as f:
|
|
810
|
-
data = json.load(f)
|
|
811
|
-
assert (
|
|
812
|
-
validate_duplicated_term_units(data, "inputs", [TermTermType.ORGANICFERTILISER])
|
|
813
|
-
is True
|
|
814
|
-
)
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
def test_validate_duplicated_term_units_invalid():
|
|
818
|
-
with open(
|
|
819
|
-
f"{fixtures_folder}/duplicated-term-units/invalid-organicFertiliser.json"
|
|
820
|
-
) as f:
|
|
821
|
-
data = json.load(f)
|
|
822
|
-
assert validate_duplicated_term_units(
|
|
823
|
-
data, "inputs", [TermTermType.ORGANICFERTILISER]
|
|
824
|
-
) == [
|
|
825
|
-
{
|
|
826
|
-
"level": "warning",
|
|
827
|
-
"dataPath": ".inputs[0].term",
|
|
828
|
-
"message": "should not use identical terms with different units",
|
|
829
|
-
"params": {
|
|
830
|
-
"term": {
|
|
831
|
-
"@type": "Term",
|
|
832
|
-
"@id": "bloodMealKgMass",
|
|
833
|
-
"termType": TermTermType.ORGANICFERTILISER.value,
|
|
834
|
-
"units": "kg",
|
|
835
|
-
},
|
|
836
|
-
"units": ["kg", "kg N"],
|
|
837
|
-
},
|
|
838
|
-
},
|
|
839
|
-
{
|
|
840
|
-
"level": "warning",
|
|
841
|
-
"dataPath": ".inputs[1].term",
|
|
842
|
-
"message": "should not use identical terms with different units",
|
|
843
|
-
"params": {
|
|
844
|
-
"term": {
|
|
845
|
-
"@type": "Term",
|
|
846
|
-
"@id": "bloodMealKgN",
|
|
847
|
-
"termType": TermTermType.ORGANICFERTILISER.value,
|
|
848
|
-
"units": "kg N",
|
|
849
|
-
},
|
|
850
|
-
"units": ["kg", "kg N"],
|
|
851
|
-
},
|
|
852
|
-
},
|
|
853
|
-
]
|
|
854
|
-
|
|
855
|
-
with open(
|
|
856
|
-
f"{fixtures_folder}/duplicated-term-units/invalid-animalProduct.json"
|
|
857
|
-
) as f:
|
|
858
|
-
data = json.load(f)
|
|
859
|
-
assert validate_duplicated_term_units(
|
|
860
|
-
data, "products", [TermTermType.ANIMALPRODUCT]
|
|
861
|
-
) == [
|
|
862
|
-
{
|
|
863
|
-
"level": "warning",
|
|
864
|
-
"dataPath": ".products[0].term",
|
|
865
|
-
"message": "should not use identical terms with different units",
|
|
866
|
-
"params": {
|
|
867
|
-
"term": {
|
|
868
|
-
"@type": "Term",
|
|
869
|
-
"@id": "meatChickenLiveweight",
|
|
870
|
-
"termType": TermTermType.ANIMALPRODUCT.value,
|
|
871
|
-
"units": "kg liveweight",
|
|
872
|
-
},
|
|
873
|
-
"units": ["kg liveweight", "kg cold carcass weight"],
|
|
874
|
-
},
|
|
875
|
-
},
|
|
876
|
-
{
|
|
877
|
-
"level": "warning",
|
|
878
|
-
"dataPath": ".products[1].term",
|
|
879
|
-
"message": "should not use identical terms with different units",
|
|
880
|
-
"params": {
|
|
881
|
-
"term": {
|
|
882
|
-
"@type": "Term",
|
|
883
|
-
"@id": "meatChickenColdCarcassWeight",
|
|
884
|
-
"termType": TermTermType.ANIMALPRODUCT.value,
|
|
885
|
-
"units": "kg cold carcass weight",
|
|
886
|
-
},
|
|
887
|
-
"units": ["kg liveweight", "kg cold carcass weight"],
|
|
888
|
-
},
|
|
889
|
-
},
|
|
890
|
-
]
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
def test_validate_list_sum_100_percent_valid():
|
|
894
|
-
# no practices should be valid
|
|
895
|
-
cycle = {"practices": []}
|
|
896
|
-
assert validate_list_sum_100_percent(cycle, "practices") is True
|
|
897
|
-
|
|
898
|
-
with open(f"{fixtures_folder}/list-values-sum-100/practices/total-90.json") as f:
|
|
899
|
-
cycle = json.load(f)
|
|
900
|
-
assert validate_list_sum_100_percent(cycle, "practices") is True
|
|
901
|
-
|
|
902
|
-
with open(f"{fixtures_folder}/list-values-sum-100/practices/total-100.json") as f:
|
|
903
|
-
cycle = json.load(f)
|
|
904
|
-
assert validate_list_sum_100_percent(cycle, "practices") is True
|
|
905
|
-
|
|
906
|
-
# missing element same depthUpper / depthLower
|
|
907
|
-
with open(
|
|
908
|
-
f"{fixtures_folder}/list-values-sum-100/measurements/missing-soil.json"
|
|
909
|
-
) as f:
|
|
910
|
-
site = json.load(f)
|
|
911
|
-
assert validate_list_sum_100_percent(site, "measurements") is True
|
|
912
|
-
|
|
913
|
-
# simple no depth
|
|
914
|
-
with open(
|
|
915
|
-
f"{fixtures_folder}/list-values-sum-100/measurements/no-depth-valid.json"
|
|
916
|
-
) as f:
|
|
917
|
-
site = json.load(f)
|
|
918
|
-
assert validate_list_sum_100_percent(site, "measurements") is True
|
|
919
|
-
|
|
920
|
-
with open(
|
|
921
|
-
f"{fixtures_folder}/list-values-sum-100/management/with-properties/valid.json"
|
|
922
|
-
) as f:
|
|
923
|
-
site = json.load(f)
|
|
924
|
-
assert validate_list_sum_100_percent(site, "management") is True
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
def test_validate_list_sum_100_percent_invalid():
|
|
928
|
-
with open(f"{fixtures_folder}/list-values-sum-100/practices/total-110.json") as f:
|
|
929
|
-
cycle = json.load(f)
|
|
930
|
-
assert validate_list_sum_100_percent(cycle, "practices") == [
|
|
931
|
-
{
|
|
932
|
-
"level": "error",
|
|
933
|
-
"dataPath": ".practices[0]",
|
|
934
|
-
"message": "value should sum to maximum 100 across all values",
|
|
935
|
-
"params": {
|
|
936
|
-
"sum": 110,
|
|
937
|
-
"max": 100.5,
|
|
938
|
-
"termIds": ["residueIncorporated", "residueLeftOnField"],
|
|
939
|
-
},
|
|
940
|
-
},
|
|
941
|
-
{
|
|
942
|
-
"level": "error",
|
|
943
|
-
"dataPath": ".practices[1]",
|
|
944
|
-
"message": "value should sum to maximum 100 across all values",
|
|
945
|
-
"params": {
|
|
946
|
-
"sum": 110,
|
|
947
|
-
"max": 100.5,
|
|
948
|
-
"termIds": ["residueIncorporated", "residueLeftOnField"],
|
|
949
|
-
},
|
|
950
|
-
},
|
|
951
|
-
]
|
|
952
|
-
|
|
953
|
-
# 90% on same depthUpper / depthLower
|
|
954
|
-
with open(
|
|
955
|
-
f"{fixtures_folder}/list-values-sum-100/measurements/with-depth-high-value.json"
|
|
956
|
-
) as f:
|
|
957
|
-
site = json.load(f)
|
|
958
|
-
assert validate_list_sum_100_percent(site, "measurements") == [
|
|
959
|
-
{
|
|
960
|
-
"level": "error",
|
|
961
|
-
"dataPath": ".measurements[1]",
|
|
962
|
-
"message": "value should sum to maximum 100 across all values",
|
|
963
|
-
"params": {
|
|
964
|
-
"sum": 110,
|
|
965
|
-
"max": 100.5,
|
|
966
|
-
"termIds": ["sandContent", "siltContent", "clayContent"],
|
|
967
|
-
},
|
|
968
|
-
},
|
|
969
|
-
{
|
|
970
|
-
"level": "error",
|
|
971
|
-
"dataPath": ".measurements[2]",
|
|
972
|
-
"message": "value should sum to maximum 100 across all values",
|
|
973
|
-
"params": {
|
|
974
|
-
"sum": 110,
|
|
975
|
-
"max": 100.5,
|
|
976
|
-
"termIds": ["sandContent", "siltContent", "clayContent"],
|
|
977
|
-
},
|
|
978
|
-
},
|
|
979
|
-
{
|
|
980
|
-
"level": "error",
|
|
981
|
-
"dataPath": ".measurements[3]",
|
|
982
|
-
"message": "value should sum to maximum 100 across all values",
|
|
983
|
-
"params": {
|
|
984
|
-
"sum": 110,
|
|
985
|
-
"max": 100.5,
|
|
986
|
-
"termIds": ["sandContent", "siltContent", "clayContent"],
|
|
987
|
-
},
|
|
988
|
-
},
|
|
989
|
-
]
|
|
990
|
-
|
|
991
|
-
# remove all depthUpper / depthLower
|
|
992
|
-
with open(
|
|
993
|
-
f"{fixtures_folder}/list-values-sum-100/measurements/no-depth-high-value.json"
|
|
994
|
-
) as f:
|
|
995
|
-
site = json.load(f)
|
|
996
|
-
assert validate_list_sum_100_percent(site, "measurements") == [
|
|
997
|
-
{
|
|
998
|
-
"level": "error",
|
|
999
|
-
"dataPath": ".measurements[0]",
|
|
1000
|
-
"message": "value should sum to maximum 100 across all values",
|
|
1001
|
-
"params": {
|
|
1002
|
-
"sum": 120,
|
|
1003
|
-
"max": 100.5,
|
|
1004
|
-
"termIds": ["sandContent", "siltContent", "clayContent"],
|
|
1005
|
-
},
|
|
1006
|
-
},
|
|
1007
|
-
{
|
|
1008
|
-
"level": "error",
|
|
1009
|
-
"dataPath": ".measurements[1]",
|
|
1010
|
-
"message": "value should sum to maximum 100 across all values",
|
|
1011
|
-
"params": {
|
|
1012
|
-
"sum": 120,
|
|
1013
|
-
"max": 100.5,
|
|
1014
|
-
"termIds": ["sandContent", "siltContent", "clayContent"],
|
|
1015
|
-
},
|
|
1016
|
-
},
|
|
1017
|
-
{
|
|
1018
|
-
"level": "error",
|
|
1019
|
-
"dataPath": ".measurements[2]",
|
|
1020
|
-
"message": "value should sum to maximum 100 across all values",
|
|
1021
|
-
"params": {
|
|
1022
|
-
"sum": 120,
|
|
1023
|
-
"max": 100.5,
|
|
1024
|
-
"termIds": ["sandContent", "siltContent", "clayContent"],
|
|
1025
|
-
},
|
|
1026
|
-
},
|
|
1027
|
-
]
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
_REQUIRES_VALUE_TERM_TYPES = [TermTermType.CROPRESIDUEMANAGEMENT]
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
def test_validate_list_percent_requires_value_valid():
|
|
1034
|
-
# no practices should be valid
|
|
1035
|
-
cycle = {"practices": []}
|
|
1036
|
-
assert (
|
|
1037
|
-
validate_list_percent_requires_value(
|
|
1038
|
-
cycle, "practices", _REQUIRES_VALUE_TERM_TYPES
|
|
1039
|
-
)
|
|
1040
|
-
is True
|
|
1041
|
-
)
|
|
1042
|
-
|
|
1043
|
-
with open(f"{fixtures_folder}/list-percent-value/valid.json") as f:
|
|
1044
|
-
cycle = json.load(f)
|
|
1045
|
-
assert (
|
|
1046
|
-
validate_list_percent_requires_value(
|
|
1047
|
-
cycle, "practices", _REQUIRES_VALUE_TERM_TYPES
|
|
1048
|
-
)
|
|
1049
|
-
is True
|
|
1050
|
-
)
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
def test_validate_list_percent_requires_value_invalid():
|
|
1054
|
-
with open(f"{fixtures_folder}/list-percent-value/invalid.json") as f:
|
|
1055
|
-
cycle = json.load(f)
|
|
1056
|
-
assert validate_list_percent_requires_value(
|
|
1057
|
-
cycle, "practices", _REQUIRES_VALUE_TERM_TYPES
|
|
1058
|
-
) == {
|
|
1059
|
-
"level": "error",
|
|
1060
|
-
"dataPath": ".practices[0]",
|
|
1061
|
-
"message": "should have required property 'value'",
|
|
1062
|
-
"params": {
|
|
1063
|
-
"term": {
|
|
1064
|
-
"@id": "residueIncorporated",
|
|
1065
|
-
"@type": "Term",
|
|
1066
|
-
"name": "Residue incorporated",
|
|
1067
|
-
"termType": "cropResidueManagement",
|
|
1068
|
-
"units": "%",
|
|
1069
|
-
},
|
|
1070
|
-
"missingProperty": "value",
|
|
1071
|
-
},
|
|
1072
|
-
}
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
def test_validate_other_model_valid():
|
|
1076
|
-
with open(f"{fixtures_folder}/otherModel/valid.json") as f:
|
|
1077
|
-
cycle = json.load(f)
|
|
1078
|
-
assert validate_other_model(cycle, "emissions") is True
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
def test_validate_other_model_invalid():
|
|
1082
|
-
with open(f"{fixtures_folder}/otherModel/invalid.json") as f:
|
|
1083
|
-
cycle = json.load(f)
|
|
1084
|
-
assert validate_other_model(cycle, "emissions") == {
|
|
1085
|
-
"level": "error",
|
|
1086
|
-
"dataPath": ".emissions[1].methodModel",
|
|
1087
|
-
"message": "is required when using other model",
|
|
1088
|
-
}
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
def test_validate_list_valueType_valid():
|
|
1092
|
-
# blank nodes emtpy should be valid
|
|
1093
|
-
node = {"values": []}
|
|
1094
|
-
assert validate_list_valueType(node, "values") is True
|
|
1095
|
-
|
|
1096
|
-
with open(f"{fixtures_folder}/list-valueType/valid.json") as f:
|
|
1097
|
-
cycle = json.load(f)
|
|
1098
|
-
assert validate_list_valueType(cycle, "practices") is True
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
def test_validate_list_valueType_invalid():
|
|
1102
|
-
with open(f"{fixtures_folder}/list-valueType/invalid.json") as f:
|
|
1103
|
-
cycle = json.load(f)
|
|
1104
|
-
assert validate_list_valueType(cycle, "practices") == {
|
|
1105
|
-
"level": "error",
|
|
1106
|
-
"dataPath": ".practices[0].value",
|
|
1107
|
-
"message": "the node value type is incorrect",
|
|
1108
|
-
"params": {"expected": "number"},
|
|
1109
|
-
}
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
@pytest.mark.parametrize(
|
|
1113
|
-
"node,expected",
|
|
1114
|
-
[
|
|
1115
|
-
({"id": "id", "nested": {"id": "id"}}, True),
|
|
1116
|
-
({"@id": "id", "nested": {"@id": "id"}}, True),
|
|
1117
|
-
({"@id": "id", "nested": {"id": "id"}}, True),
|
|
1118
|
-
(
|
|
1119
|
-
{"id": "id", "nested": {"@id": "id"}},
|
|
1120
|
-
{
|
|
1121
|
-
"level": "warning",
|
|
1122
|
-
"dataPath": ".nested.@id",
|
|
1123
|
-
"message": "should not link to an existing node",
|
|
1124
|
-
"params": {"node": {"@id": "id"}},
|
|
1125
|
-
},
|
|
1126
|
-
),
|
|
1127
|
-
(
|
|
1128
|
-
{"id": "id", "nested": [{"id": "id"}, {"@id": "id"}]},
|
|
1129
|
-
{
|
|
1130
|
-
"level": "warning",
|
|
1131
|
-
"dataPath": ".nested[1].@id",
|
|
1132
|
-
"message": "should not link to an existing node",
|
|
1133
|
-
"params": {"node": {"@id": "id"}},
|
|
1134
|
-
},
|
|
1135
|
-
),
|
|
1136
|
-
],
|
|
1137
|
-
)
|
|
1138
|
-
def test_validate_nested_existing_node(node: dict, expected):
|
|
1139
|
-
assert validate_nested_existing_node(node, "nested") == expected
|