@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.
Files changed (411) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.js +17 -0
  3. package/dist/validations.d.ts +10 -0
  4. package/dist/validations.js +10 -0
  5. package/package.json +4 -3
  6. package/search-results.json +22 -22
  7. package/src/version.ts +1 -1
  8. package/validation.json +629 -0
  9. package/.coveragerc +0 -14
  10. package/.dockerignore +0 -19
  11. package/.eslintignore +0 -17
  12. package/.eslintrc.js +0 -11
  13. package/.flake8 +0 -5
  14. package/.gitlab/issue_templates/new validation.md +0 -82
  15. package/.gitlab-ci.yml +0 -216
  16. package/.readthedocs.yml +0 -24
  17. package/CODEOWNERS +0 -11
  18. package/Dockerfile +0 -13
  19. package/MANIFEST.in +0 -2
  20. package/bin/hestia-validate-data +0 -80
  21. package/build_mocking.py +0 -14
  22. package/commitlint.config.js +0 -1
  23. package/docs/Makefile +0 -20
  24. package/docs/_static/styles.css +0 -4
  25. package/docs/_templates/custom-class-template.rst +0 -34
  26. package/docs/_templates/custom-module-template.rst +0 -66
  27. package/docs/_templates/layout.html +0 -4
  28. package/docs/conf.py +0 -74
  29. package/docs/index.rst +0 -42
  30. package/docs/make.bat +0 -35
  31. package/docs/requirements.txt +0 -13
  32. package/envs/.develop.env +0 -1
  33. package/envs/.master.env +0 -1
  34. package/guide-assets/.gitkeep +0 -0
  35. package/hestia_earth/validation/README.md +0 -5
  36. package/hestia_earth/validation/__init__.py +0 -32
  37. package/hestia_earth/validation/distribution.py +0 -22
  38. package/hestia_earth/validation/gee.py +0 -162
  39. package/hestia_earth/validation/log.py +0 -44
  40. package/hestia_earth/validation/models.py +0 -141
  41. package/hestia_earth/validation/preload_requests.py +0 -61
  42. package/hestia_earth/validation/terms.py +0 -88
  43. package/hestia_earth/validation/utils.py +0 -444
  44. package/hestia_earth/validation/validators/__init__.py +0 -141
  45. package/hestia_earth/validation/validators/aggregated_cycle.py +0 -32
  46. package/hestia_earth/validation/validators/aggregated_shared.py +0 -37
  47. package/hestia_earth/validation/validators/animal.py +0 -88
  48. package/hestia_earth/validation/validators/completeness.py +0 -252
  49. package/hestia_earth/validation/validators/cycle.py +0 -1123
  50. package/hestia_earth/validation/validators/distribution.py +0 -86
  51. package/hestia_earth/validation/validators/emission.py +0 -109
  52. package/hestia_earth/validation/validators/impact_assessment.py +0 -138
  53. package/hestia_earth/validation/validators/indicator.py +0 -154
  54. package/hestia_earth/validation/validators/infrastructure.py +0 -25
  55. package/hestia_earth/validation/validators/input.py +0 -268
  56. package/hestia_earth/validation/validators/management.py +0 -131
  57. package/hestia_earth/validation/validators/measurement.py +0 -368
  58. package/hestia_earth/validation/validators/organisation.py +0 -43
  59. package/hestia_earth/validation/validators/practice.py +0 -590
  60. package/hestia_earth/validation/validators/product.py +0 -263
  61. package/hestia_earth/validation/validators/property.py +0 -266
  62. package/hestia_earth/validation/validators/shared.py +0 -940
  63. package/hestia_earth/validation/validators/site.py +0 -312
  64. package/hestia_earth/validation/validators/source.py +0 -20
  65. package/hestia_earth/validation/validators/transformation.py +0 -250
  66. package/hestia_earth/validation/version.py +0 -1
  67. package/layer/build.sh +0 -34
  68. package/layer/deploy.sh +0 -18
  69. package/release.sh +0 -11
  70. package/requirements-ci.txt +0 -6
  71. package/requirements-test.txt +0 -4
  72. package/requirements.txt +0 -2
  73. package/run-docker-test.sh +0 -7
  74. package/run-docker.sh +0 -9
  75. package/run.py +0 -99
  76. package/scripts/build_docs.py +0 -283
  77. package/scripts/build_validation_list.py +0 -160
  78. package/scripts/guide-create-branch.sh +0 -15
  79. package/scripts/update-package-version.js +0 -28
  80. package/setup.py +0 -35
  81. package/tests/Dockerfile +0 -13
  82. package/tests/__init__.py +0 -3
  83. package/tests/fixtures/aggregated/cycle/inputs-impactAssessment/invalid-no-impactAssessment.json +0 -64
  84. package/tests/fixtures/aggregated/cycle/inputs-impactAssessment/invalid-world.json +0 -69
  85. package/tests/fixtures/aggregated/cycle/inputs-impactAssessment/valid.json +0 -69
  86. package/tests/fixtures/animal/duplicated-input-cycle/invalid.json +0 -98
  87. package/tests/fixtures/animal/duplicated-input-cycle/valid.json +0 -91
  88. package/tests/fixtures/animal/pregnancyRateTotal/invalid.json +0 -49
  89. package/tests/fixtures/animal/pregnancyRateTotal/valid.json +0 -60
  90. package/tests/fixtures/animal/required/invalid.json +0 -59
  91. package/tests/fixtures/animal/required/valid.json +0 -72
  92. package/tests/fixtures/completeness/all-values/warning.json +0 -22
  93. package/tests/fixtures/completeness/animalPopulation/invalid.json +0 -58
  94. package/tests/fixtures/completeness/animalPopulation/valid-animals.json +0 -71
  95. package/tests/fixtures/completeness/animalPopulation/valid-incomplete.json +0 -58
  96. package/tests/fixtures/completeness/animalPopulation/valid-no-liveAnimals.json +0 -37
  97. package/tests/fixtures/completeness/blank-nodes/agri-food processor-invalid.json +0 -52
  98. package/tests/fixtures/completeness/blank-nodes/invalid.json +0 -124
  99. package/tests/fixtures/completeness/blank-nodes/valid.json +0 -128
  100. package/tests/fixtures/completeness/cropland/site.json +0 -16
  101. package/tests/fixtures/completeness/cropland/valid.json +0 -22
  102. package/tests/fixtures/completeness/cropland/warning.json +0 -22
  103. package/tests/fixtures/completeness/freshForage/error-animals.json +0 -63
  104. package/tests/fixtures/completeness/freshForage/error-products.json +0 -65
  105. package/tests/fixtures/completeness/freshForage/valid-animal-inputs.json +0 -63
  106. package/tests/fixtures/completeness/freshForage/valid-animals.json +0 -63
  107. package/tests/fixtures/completeness/freshForage/valid-not-grazing-liveAnimal.json +0 -55
  108. package/tests/fixtures/completeness/freshForage/valid-not-liveAnimal.json +0 -47
  109. package/tests/fixtures/completeness/freshForage/valid-products.json +0 -68
  110. package/tests/fixtures/completeness/ingredient/invalid-agri-food-processor.json +0 -37
  111. package/tests/fixtures/completeness/ingredient/invalid.json +0 -49
  112. package/tests/fixtures/completeness/ingredient/valid-agri-food-processor-complete.json +0 -49
  113. package/tests/fixtures/completeness/ingredient/valid-agri-food-processor-incomplete.json +0 -37
  114. package/tests/fixtures/completeness/ingredient/valid.json +0 -49
  115. package/tests/fixtures/completeness/material/error.json +0 -49
  116. package/tests/fixtures/completeness/material/valid-fuel-material.json +0 -60
  117. package/tests/fixtures/completeness/material/valid-incomplete.json +0 -36
  118. package/tests/fixtures/completeness/material/valid-no-fuel.json +0 -36
  119. package/tests/fixtures/completeness/valid.json +0 -22
  120. package/tests/fixtures/cycle/aboveGroundCropResidue/invalid.json +0 -76
  121. package/tests/fixtures/cycle/aboveGroundCropResidue/valid.json +0 -76
  122. package/tests/fixtures/cycle/aggregated-valid.json +0 -102
  123. package/tests/fixtures/cycle/coverCrop/invalid.json +0 -64
  124. package/tests/fixtures/cycle/coverCrop/valid-not-coverCrop.json +0 -54
  125. package/tests/fixtures/cycle/coverCrop/valid.json +0 -64
  126. package/tests/fixtures/cycle/cropResidue/complete/invalid.json +0 -56
  127. package/tests/fixtures/cycle/cropResidue/complete/valid.json +0 -82
  128. package/tests/fixtures/cycle/cropResidue/incomplete/invalid.json +0 -42
  129. package/tests/fixtures/cycle/cropResidue/incomplete/valid.json +0 -56
  130. package/tests/fixtures/cycle/dates/invalid-emissions.json +0 -70
  131. package/tests/fixtures/cycle/liveAnimal-animalProduct-mapping/invalid.json +0 -63
  132. package/tests/fixtures/cycle/liveAnimal-animalProduct-mapping/valid.json +0 -63
  133. package/tests/fixtures/cycle/maximumCycleDuration/invalid-dates-year-only.json +0 -48
  134. package/tests/fixtures/cycle/maximumCycleDuration/invalid-dates.json +0 -48
  135. package/tests/fixtures/cycle/maximumCycleDuration/invalid.json +0 -48
  136. package/tests/fixtures/cycle/maximumCycleDuration/valid-dates-year-only.json +0 -48
  137. package/tests/fixtures/cycle/maximumCycleDuration/valid-dates.json +0 -48
  138. package/tests/fixtures/cycle/maximumCycleDuration/valid.json +0 -48
  139. package/tests/fixtures/cycle/otherSites/cycleDuration/invalid.json +0 -52
  140. package/tests/fixtures/cycle/otherSites/cycleDuration/valid-no-siteDuration.json +0 -40
  141. package/tests/fixtures/cycle/otherSites/cycleDuration/valid.json +0 -52
  142. package/tests/fixtures/cycle/practices/stockingDensityPermanentPastureAverage/invalid.json +0 -56
  143. package/tests/fixtures/cycle/practices/stockingDensityPermanentPastureAverage/valid.json +0 -65
  144. package/tests/fixtures/cycle/primary-product-as-input/invalid.json +0 -59
  145. package/tests/fixtures/cycle/primary-product-as-input/valid.json +0 -48
  146. package/tests/fixtures/cycle/product-linked-ia/cycle.json +0 -66
  147. package/tests/fixtures/cycle/product-linked-ia/invalid-multiple.json +0 -58
  148. package/tests/fixtures/cycle/product-linked-ia/valid.json +0 -57
  149. package/tests/fixtures/cycle/products/animals/invalid.json +0 -69
  150. package/tests/fixtures/cycle/products/animals/valid.json +0 -58
  151. package/tests/fixtures/cycle/riceGrainInHuskFlooded-minimumCycleDuration/invalid.json +0 -53
  152. package/tests/fixtures/cycle/riceGrainInHuskFlooded-minimumCycleDuration/valid.json +0 -53
  153. package/tests/fixtures/cycle/siteDuration/crop/invalid.json +0 -53
  154. package/tests/fixtures/cycle/siteDuration/crop/valid-different-duration.json +0 -53
  155. package/tests/fixtures/cycle/siteDuration/crop/valid-same-duration.json +0 -53
  156. package/tests/fixtures/cycle/siteDuration/invalid.json +0 -41
  157. package/tests/fixtures/cycle/siteDuration/valid-no-siteDuration.json +0 -40
  158. package/tests/fixtures/cycle/siteDuration/valid-otherSites.json +0 -48
  159. package/tests/fixtures/cycle/siteDuration/valid.json +0 -45
  160. package/tests/fixtures/cycle/substrate/required/invalid.json +0 -50
  161. package/tests/fixtures/cycle/substrate/required/valid.json +0 -60
  162. package/tests/fixtures/cycle/valid.json +0 -343
  163. package/tests/fixtures/emission/linked-terms/inputs/invalid.json +0 -78
  164. package/tests/fixtures/emission/linked-terms/inputs/valid.json +0 -106
  165. package/tests/fixtures/emission/linked-terms/transformation/error.json +0 -104
  166. package/tests/fixtures/emission/linked-terms/transformation/valid.json +0 -107
  167. package/tests/fixtures/emission/linked-terms/transformation/warning.json +0 -76
  168. package/tests/fixtures/emission/methodTier-background/invalid.json +0 -60
  169. package/tests/fixtures/emission/methodTier-background/valid.json +0 -60
  170. package/tests/fixtures/emission/not-relevant/invalid.json +0 -71
  171. package/tests/fixtures/emission/not-relevant/valid.json +0 -95
  172. package/tests/fixtures/emission/not-relevant-methodTier/invalid.json +0 -70
  173. package/tests/fixtures/emission/not-relevant-methodTier/valid.json +0 -95
  174. package/tests/fixtures/impactAssessment/aggregated-valid.json +0 -43
  175. package/tests/fixtures/impactAssessment/cycle-contains-product/invalid.json +0 -34
  176. package/tests/fixtures/impactAssessment/cycle-contains-product/valid.json +0 -34
  177. package/tests/fixtures/impactAssessment/cycle-endDate/invalid.json +0 -26
  178. package/tests/fixtures/impactAssessment/cycle-endDate/valid.json +0 -26
  179. package/tests/fixtures/impactAssessment/valid.json +0 -93
  180. package/tests/fixtures/indicator/characterisedIndicator-methodModel/invalid.json +0 -52
  181. package/tests/fixtures/indicator/characterisedIndicator-methodModel/valid.json +0 -52
  182. package/tests/fixtures/indicator/ionisingCompounds/invalid.json +0 -23
  183. package/tests/fixtures/indicator/ionisingCompounds/valid.json +0 -23
  184. package/tests/fixtures/indicator/landTransformation/invalid-grouped.json +0 -257
  185. package/tests/fixtures/indicator/landTransformation/invalid.json +0 -100
  186. package/tests/fixtures/indicator/landTransformation/valid-grouped-full.json +0 -507
  187. package/tests/fixtures/indicator/landTransformation/valid-grouped.json +0 -507
  188. package/tests/fixtures/indicator/landTransformation/valid.json +0 -100
  189. package/tests/fixtures/infrastructure/lifespan/invalid.json +0 -26
  190. package/tests/fixtures/infrastructure/lifespan/valid.json +0 -45
  191. package/tests/fixtures/input/animalFeed-fate/invalid.json +0 -103
  192. package/tests/fixtures/input/animalFeed-fate/valid.json +0 -90
  193. package/tests/fixtures/input/country/invalid.json +0 -64
  194. package/tests/fixtures/input/country/valid.json +0 -64
  195. package/tests/fixtures/input/distribution/animalHousing.json +0 -103
  196. package/tests/fixtures/input/distribution/complete/invalid.json +0 -177
  197. package/tests/fixtures/input/distribution/complete/valid.json +0 -163
  198. package/tests/fixtures/input/distribution/incomplete/valid.json +0 -139
  199. package/tests/fixtures/input/impactAssessment/invalid.json +0 -99
  200. package/tests/fixtures/input/impactAssessment/valid.json +0 -89
  201. package/tests/fixtures/input/input-as-product/invalid.json +0 -57
  202. package/tests/fixtures/input/input-as-product/valid.json +0 -59
  203. package/tests/fixtures/input/mustIncludeId/invalid.json +0 -13
  204. package/tests/fixtures/input/mustIncludeId/valid-multiple-ids.json +0 -31
  205. package/tests/fixtures/input/mustIncludeId/valid.json +0 -22
  206. package/tests/fixtures/input/saplings/invalid.json +0 -58
  207. package/tests/fixtures/input/saplings/valid-no-saplings.json +0 -58
  208. package/tests/fixtures/input/saplings/valid-not-plantation.json +0 -58
  209. package/tests/fixtures/input/saplings/valid.json +0 -58
  210. package/tests/fixtures/integration/distribution/product-yield-invalid.json +0 -54
  211. package/tests/fixtures/management/cycle-overlap/cycles.json +0 -39
  212. package/tests/fixtures/management/cycle-overlap/invalid.json +0 -26
  213. package/tests/fixtures/management/cycle-overlap/valid.json +0 -26
  214. package/tests/fixtures/management/exists/invalid.json +0 -13
  215. package/tests/fixtures/management/exists/valid.json +0 -25
  216. package/tests/fixtures/management/fallow-dates/invalid.json +0 -24
  217. package/tests/fixtures/management/fallow-dates/valid.json +0 -24
  218. package/tests/fixtures/management/termType/invalid-cropland.json +0 -35
  219. package/tests/fixtures/management/termType/invalid-permanent-pasture.json +0 -25
  220. package/tests/fixtures/management/termType/valid-cropland.json +0 -55
  221. package/tests/fixtures/management/termType/valid-no-management.json +0 -13
  222. package/tests/fixtures/management/termType/valid-permanent-pasture.json +0 -35
  223. package/tests/fixtures/measurement/depths/invalid.json +0 -44
  224. package/tests/fixtures/measurement/depths/valid.json +0 -50
  225. package/tests/fixtures/measurement/models/valid.json +0 -33
  226. package/tests/fixtures/measurement/models/warning-no-value.json +0 -30
  227. package/tests/fixtures/measurement/models/warning.json +0 -33
  228. package/tests/fixtures/measurement/pond-measurements/invalid.json +0 -11
  229. package/tests/fixtures/measurement/pond-measurements/valid.json +0 -23
  230. package/tests/fixtures/measurement/required-depths/error.json +0 -71
  231. package/tests/fixtures/measurement/required-depths/valid.json +0 -126
  232. package/tests/fixtures/measurement/required-depths/warning.json +0 -29
  233. package/tests/fixtures/measurement/soilTexture/missing-texture-value.json +0 -227
  234. package/tests/fixtures/measurement/soilTexture/percent-invalid.json +0 -110
  235. package/tests/fixtures/measurement/soilTexture/percent-missing-value.json +0 -43
  236. package/tests/fixtures/measurement/soilTexture/percent-valid.json +0 -110
  237. package/tests/fixtures/measurement/startDate-endDate-required/invalid.json +0 -32
  238. package/tests/fixtures/measurement/startDate-endDate-required/valid.json +0 -46
  239. package/tests/fixtures/measurement/unique/invalid.json +0 -28
  240. package/tests/fixtures/measurement/unique/valid.json +0 -16
  241. package/tests/fixtures/measurement/value-length/invalid.json +0 -46
  242. package/tests/fixtures/measurement/value-length/valid.json +0 -44
  243. package/tests/fixtures/measurement/water-salinity/invalid.json +0 -33
  244. package/tests/fixtures/measurement/water-salinity/valid-brakish.json +0 -40
  245. package/tests/fixtures/measurement/water-salinity/valid.json +0 -33
  246. package/tests/fixtures/organisation/valid.json +0 -26
  247. package/tests/fixtures/practice/croppingDuration/riceGrainInHuskFlooded/invalid.json +0 -63
  248. package/tests/fixtures/practice/croppingDuration/riceGrainInHuskFlooded/valid.json +0 -63
  249. package/tests/fixtures/practice/defaultValue/invalid.json +0 -12
  250. package/tests/fixtures/practice/defaultValue/valid.json +0 -15
  251. package/tests/fixtures/practice/excretaManagement/invalid.json +0 -50
  252. package/tests/fixtures/practice/excretaManagement/valid.json +0 -60
  253. package/tests/fixtures/practice/irrigated-complete/invalid.json +0 -47
  254. package/tests/fixtures/practice/irrigated-complete/valid-incomplete.json +0 -47
  255. package/tests/fixtures/practice/irrigated-complete/valid.json +0 -60
  256. package/tests/fixtures/practice/landCover-products/invalid.json +0 -58
  257. package/tests/fixtures/practice/landCover-products/valid-coverCrop.json +0 -69
  258. package/tests/fixtures/practice/landCover-products/valid.json +0 -58
  259. package/tests/fixtures/practice/liveAnimal-system/invalid.json +0 -58
  260. package/tests/fixtures/practice/liveAnimal-system/valid.json +0 -69
  261. package/tests/fixtures/practice/longFallowDuration/invalid.json +0 -20
  262. package/tests/fixtures/practice/longFallowDuration/valid.json +0 -20
  263. package/tests/fixtures/practice/noTillage/invalid.json +0 -23
  264. package/tests/fixtures/practice/noTillage/valid-value-not-100.json +0 -23
  265. package/tests/fixtures/practice/noTillage/valid.json +0 -21
  266. package/tests/fixtures/practice/pastureGrass/key-termType/invalid.json +0 -16
  267. package/tests/fixtures/practice/pastureGrass/key-termType/valid.json +0 -16
  268. package/tests/fixtures/practice/pastureGrass/key-value/invalid-numbers.json +0 -67
  269. package/tests/fixtures/practice/pastureGrass/key-value/invalid.json +0 -67
  270. package/tests/fixtures/practice/pastureGrass/key-value/valid.json +0 -67
  271. package/tests/fixtures/practice/pastureGrass/permanent-pasture/invalid.json +0 -37
  272. package/tests/fixtures/practice/pastureGrass/permanent-pasture/valid.json +0 -47
  273. package/tests/fixtures/practice/primaryPercent/invalid.json +0 -49
  274. package/tests/fixtures/practice/primaryPercent/valid.json +0 -49
  275. package/tests/fixtures/practice/processingOperation/invalid-no-primary.json +0 -48
  276. package/tests/fixtures/practice/processingOperation/invalid.json +0 -49
  277. package/tests/fixtures/practice/processingOperation/valid-cropland.json +0 -37
  278. package/tests/fixtures/practice/processingOperation/valid.json +0 -49
  279. package/tests/fixtures/practice/productivePhasePermanentCrops/invalid.json +0 -48
  280. package/tests/fixtures/practice/productivePhasePermanentCrops/valid-0-value.json +0 -58
  281. package/tests/fixtures/practice/productivePhasePermanentCrops/valid-no-value.json +0 -47
  282. package/tests/fixtures/practice/productivePhasePermanentCrops/valid.json +0 -48
  283. package/tests/fixtures/practice/site-management/invalid.json +0 -75
  284. package/tests/fixtures/practice/site-management/valid.json +0 -75
  285. package/tests/fixtures/practice/tillage-siteType/valid.json +0 -51
  286. package/tests/fixtures/practice/tillage-siteType/warning.json +0 -42
  287. package/tests/fixtures/practice/tillage-values/invalid-fullTillage.json +0 -61
  288. package/tests/fixtures/practice/tillage-values/invalid-noTillage.json +0 -61
  289. package/tests/fixtures/practice/tillage-values/valid.json +0 -61
  290. package/tests/fixtures/practice/waterRegime/rice/invalid.json +0 -59
  291. package/tests/fixtures/practice/waterRegime/rice/valid-0-value.json +0 -59
  292. package/tests/fixtures/practice/waterRegime/rice/valid.json +0 -58
  293. package/tests/fixtures/product/economicValueShare/invalid.json +0 -31
  294. package/tests/fixtures/product/economicValueShare/valid.json +0 -22
  295. package/tests/fixtures/product/excreta/invalid.json +0 -62
  296. package/tests/fixtures/product/excreta/valid.json +0 -62
  297. package/tests/fixtures/product/excreta/warning.json +0 -53
  298. package/tests/fixtures/product/excreta/with-system/invalid.json +0 -79
  299. package/tests/fixtures/product/excreta/with-system/valid.json +0 -88
  300. package/tests/fixtures/product/excreta/with-system/warning.json +0 -70
  301. package/tests/fixtures/product/fu_ha/invalid.json +0 -49
  302. package/tests/fixtures/product/fu_ha/valid.json +0 -49
  303. package/tests/fixtures/product/primary/invalid.json +0 -22
  304. package/tests/fixtures/product/primary/valid.json +0 -22
  305. package/tests/fixtures/product/value/valid.json +0 -26
  306. package/tests/fixtures/product/value/value-0/error.json +0 -40
  307. package/tests/fixtures/product/value/value-empty/warning.json +0 -23
  308. package/tests/fixtures/product/yield/invalid.json +0 -54
  309. package/tests/fixtures/product/yield/no-value.json +0 -75
  310. package/tests/fixtures/product/yield/valid.json +0 -54
  311. package/tests/fixtures/property/default-value/valid-allowed-exception.json +0 -61
  312. package/tests/fixtures/property/default-value/valid.json +0 -61
  313. package/tests/fixtures/property/default-value/warning.json +0 -61
  314. package/tests/fixtures/property/termType/invalid.json +0 -60
  315. package/tests/fixtures/property/termType/valid.json +0 -60
  316. package/tests/fixtures/property/value-min-max/invalid.json +0 -77
  317. package/tests/fixtures/property/value-min-max/valid-skip-maximum.json +0 -57
  318. package/tests/fixtures/property/value-min-max/valid.json +0 -78
  319. package/tests/fixtures/property/valueType/invalid.json +0 -79
  320. package/tests/fixtures/property/valueType/valid.json +0 -79
  321. package/tests/fixtures/property/volatileSolidsContent/invalid.json +0 -99
  322. package/tests/fixtures/property/volatileSolidsContent/valid.json +0 -99
  323. package/tests/fixtures/shared/coordinates/invalid.json +0 -18
  324. package/tests/fixtures/shared/coordinates/valid.json +0 -18
  325. package/tests/fixtures/shared/data-duplicates/valid.json +0 -113
  326. package/tests/fixtures/shared/data-duplicates/warning.json +0 -172
  327. package/tests/fixtures/shared/duplicated-term-units/invalid-animalProduct.json +0 -61
  328. package/tests/fixtures/shared/duplicated-term-units/invalid-organicFertiliser.json +0 -61
  329. package/tests/fixtures/shared/duplicated-term-units/valid.json +0 -49
  330. package/tests/fixtures/shared/list-country-region/invalid.json +0 -54
  331. package/tests/fixtures/shared/list-country-region/valid.json +0 -54
  332. package/tests/fixtures/shared/list-percent-value/invalid.json +0 -49
  333. package/tests/fixtures/shared/list-percent-value/valid.json +0 -52
  334. package/tests/fixtures/shared/list-valueType/invalid.json +0 -49
  335. package/tests/fixtures/shared/list-valueType/valid.json +0 -49
  336. package/tests/fixtures/shared/list-values-sum-100/management/with-properties/valid.json +0 -91
  337. package/tests/fixtures/shared/list-values-sum-100/measurements/missing-soil.json +0 -46
  338. package/tests/fixtures/shared/list-values-sum-100/measurements/no-depth-high-value.json +0 -63
  339. package/tests/fixtures/shared/list-values-sum-100/measurements/no-depth-valid.json +0 -40
  340. package/tests/fixtures/shared/list-values-sum-100/measurements/with-depth-high-value.json +0 -71
  341. package/tests/fixtures/shared/list-values-sum-100/practices/total-100.json +0 -61
  342. package/tests/fixtures/shared/list-values-sum-100/practices/total-110.json +0 -61
  343. package/tests/fixtures/shared/list-values-sum-100/practices/total-90.json +0 -61
  344. package/tests/fixtures/shared/min-max/value-above.json +0 -31
  345. package/tests/fixtures/shared/min-max/value-below.json +0 -31
  346. package/tests/fixtures/shared/min-max/value-valid.json +0 -45
  347. package/tests/fixtures/shared/model/emissions/invalid.json +0 -102
  348. package/tests/fixtures/shared/model/emissions/valid-variable-tolerance.json +0 -180
  349. package/tests/fixtures/shared/model/emissions/valid.json +0 -102
  350. package/tests/fixtures/shared/model/impacts/invalid.json +0 -75
  351. package/tests/fixtures/shared/model/impacts/valid.json +0 -75
  352. package/tests/fixtures/shared/model/inputs/valid-no-value.json +0 -84
  353. package/tests/fixtures/shared/model/inputs/valid.json +0 -87
  354. package/tests/fixtures/shared/model/inputs/warning.json +0 -87
  355. package/tests/fixtures/shared/model/products/valid-no-value.json +0 -88
  356. package/tests/fixtures/shared/model/products/valid.json +0 -91
  357. package/tests/fixtures/shared/model/products/warning.json +0 -91
  358. package/tests/fixtures/shared/otherModel/invalid.json +0 -69
  359. package/tests/fixtures/shared/otherModel/valid.json +0 -70
  360. package/tests/fixtures/shared/properties-duplicate-values/invalid.json +0 -61
  361. package/tests/fixtures/shared/properties-duplicate-values/valid.json +0 -57
  362. package/tests/fixtures/shared/properties-same-length/invalid.json +0 -62
  363. package/tests/fixtures/shared/properties-same-length/valid.json +0 -52
  364. package/tests/fixtures/shared/unit-percent/invalid.json +0 -34
  365. package/tests/fixtures/shared/unit-percent/valid.json +0 -60
  366. package/tests/fixtures/shared/unit-percent/warning.json +0 -52
  367. package/tests/fixtures/site/cycles-linked-ia/invalid.json +0 -129
  368. package/tests/fixtures/site/cycles-linked-ia/valid.json +0 -129
  369. package/tests/fixtures/site/valid.json +0 -138
  370. package/tests/fixtures/source/valid.json +0 -19
  371. package/tests/fixtures/transformation/excretaManagement/invalid.json +0 -47
  372. package/tests/fixtures/transformation/excretaManagement/valid.json +0 -59
  373. package/tests/fixtures/transformation/inputs-products/invalid.json +0 -43
  374. package/tests/fixtures/transformation/inputs-products/valid.json +0 -43
  375. package/tests/fixtures/transformation/linked-emission/invalid.json +0 -101
  376. package/tests/fixtures/transformation/linked-emission/valid.json +0 -107
  377. package/tests/fixtures/transformation/previousTransformationId/invalid-no-previous.json +0 -127
  378. package/tests/fixtures/transformation/previousTransformationId/invalid-previous-input.json +0 -100
  379. package/tests/fixtures/transformation/previousTransformationId/invalid-product-input.json +0 -106
  380. package/tests/fixtures/transformation/previousTransformationId/invalid-wrong-order.json +0 -136
  381. package/tests/fixtures/transformation/previousTransformationId/valid.json +0 -171
  382. package/tests/integration/__init__.py +0 -0
  383. package/tests/integration/test_product.py +0 -17
  384. package/tests/test_gee.py +0 -10
  385. package/tests/test_utils.py +0 -36
  386. package/tests/test_validation.py +0 -11
  387. package/tests/utils.py +0 -28
  388. package/tests/validators/__init__.py +0 -0
  389. package/tests/validators/test_aggregated_cycle.py +0 -44
  390. package/tests/validators/test_aggregated_shared.py +0 -63
  391. package/tests/validators/test_animal.py +0 -72
  392. package/tests/validators/test_completeness.py +0 -337
  393. package/tests/validators/test_cycle.py +0 -600
  394. package/tests/validators/test_emission.py +0 -170
  395. package/tests/validators/test_impact_assessment.py +0 -80
  396. package/tests/validators/test_indicator.py +0 -120
  397. package/tests/validators/test_infrastructure.py +0 -26
  398. package/tests/validators/test_input.py +0 -434
  399. package/tests/validators/test_management.py +0 -177
  400. package/tests/validators/test_measurement.py +0 -317
  401. package/tests/validators/test_organisation.py +0 -32
  402. package/tests/validators/test_practice.py +0 -490
  403. package/tests/validators/test_product.py +0 -291
  404. package/tests/validators/test_property.py +0 -143
  405. package/tests/validators/test_shared.py +0 -1139
  406. package/tests/validators/test_site.py +0 -151
  407. package/tests/validators/test_source.py +0 -15
  408. package/tests/validators/test_transformation.py +0 -151
  409. package/tests/validators/test_validators.py +0 -74
  410. package/tsconfig.dist.json +0 -9
  411. 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