@hestia-earth/data-validation 0.37.7

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 (410) hide show
  1. package/.coveragerc +14 -0
  2. package/.dockerignore +19 -0
  3. package/.eslintignore +17 -0
  4. package/.eslintrc.js +11 -0
  5. package/.flake8 +5 -0
  6. package/.gitlab/issue_templates/new validation.md +82 -0
  7. package/.gitlab-ci.yml +216 -0
  8. package/.readthedocs.yml +24 -0
  9. package/CODEOWNERS +11 -0
  10. package/Dockerfile +13 -0
  11. package/LICENSE +21 -0
  12. package/MANIFEST.in +2 -0
  13. package/bin/hestia-validate-data +80 -0
  14. package/build_mocking.py +14 -0
  15. package/commitlint.config.js +1 -0
  16. package/docs/Makefile +20 -0
  17. package/docs/_static/styles.css +4 -0
  18. package/docs/_templates/custom-class-template.rst +34 -0
  19. package/docs/_templates/custom-module-template.rst +66 -0
  20. package/docs/_templates/layout.html +4 -0
  21. package/docs/conf.py +74 -0
  22. package/docs/index.rst +42 -0
  23. package/docs/make.bat +35 -0
  24. package/docs/requirements.txt +13 -0
  25. package/envs/.develop.env +1 -0
  26. package/envs/.master.env +1 -0
  27. package/guide-assets/.gitkeep +0 -0
  28. package/hestia_earth/validation/README.md +5 -0
  29. package/hestia_earth/validation/__init__.py +32 -0
  30. package/hestia_earth/validation/distribution.py +22 -0
  31. package/hestia_earth/validation/gee.py +162 -0
  32. package/hestia_earth/validation/log.py +44 -0
  33. package/hestia_earth/validation/models.py +141 -0
  34. package/hestia_earth/validation/preload_requests.py +61 -0
  35. package/hestia_earth/validation/terms.py +88 -0
  36. package/hestia_earth/validation/utils.py +444 -0
  37. package/hestia_earth/validation/validators/__init__.py +141 -0
  38. package/hestia_earth/validation/validators/aggregated_cycle.py +32 -0
  39. package/hestia_earth/validation/validators/aggregated_shared.py +37 -0
  40. package/hestia_earth/validation/validators/animal.py +88 -0
  41. package/hestia_earth/validation/validators/completeness.py +252 -0
  42. package/hestia_earth/validation/validators/cycle.py +1123 -0
  43. package/hestia_earth/validation/validators/distribution.py +86 -0
  44. package/hestia_earth/validation/validators/emission.py +109 -0
  45. package/hestia_earth/validation/validators/impact_assessment.py +138 -0
  46. package/hestia_earth/validation/validators/indicator.py +154 -0
  47. package/hestia_earth/validation/validators/infrastructure.py +25 -0
  48. package/hestia_earth/validation/validators/input.py +268 -0
  49. package/hestia_earth/validation/validators/management.py +131 -0
  50. package/hestia_earth/validation/validators/measurement.py +368 -0
  51. package/hestia_earth/validation/validators/organisation.py +43 -0
  52. package/hestia_earth/validation/validators/practice.py +590 -0
  53. package/hestia_earth/validation/validators/product.py +263 -0
  54. package/hestia_earth/validation/validators/property.py +266 -0
  55. package/hestia_earth/validation/validators/shared.py +940 -0
  56. package/hestia_earth/validation/validators/site.py +312 -0
  57. package/hestia_earth/validation/validators/source.py +20 -0
  58. package/hestia_earth/validation/validators/transformation.py +250 -0
  59. package/hestia_earth/validation/version.py +1 -0
  60. package/layer/build.sh +34 -0
  61. package/layer/deploy.sh +18 -0
  62. package/package.json +59 -0
  63. package/release.sh +11 -0
  64. package/requirements-ci.txt +6 -0
  65. package/requirements-test.txt +4 -0
  66. package/requirements.txt +2 -0
  67. package/run-docker-test.sh +7 -0
  68. package/run-docker.sh +9 -0
  69. package/run.py +99 -0
  70. package/scripts/build_docs.py +283 -0
  71. package/scripts/build_validation_list.py +160 -0
  72. package/scripts/guide-create-branch.sh +15 -0
  73. package/scripts/update-package-version.js +28 -0
  74. package/search-results.json +384 -0
  75. package/setup.cfg +2 -0
  76. package/setup.py +35 -0
  77. package/src/index.ts +1 -0
  78. package/src/validations.ts +22 -0
  79. package/src/version.ts +1 -0
  80. package/tests/Dockerfile +13 -0
  81. package/tests/__init__.py +3 -0
  82. package/tests/fixtures/aggregated/cycle/inputs-impactAssessment/invalid-no-impactAssessment.json +64 -0
  83. package/tests/fixtures/aggregated/cycle/inputs-impactAssessment/invalid-world.json +69 -0
  84. package/tests/fixtures/aggregated/cycle/inputs-impactAssessment/valid.json +69 -0
  85. package/tests/fixtures/animal/duplicated-input-cycle/invalid.json +98 -0
  86. package/tests/fixtures/animal/duplicated-input-cycle/valid.json +91 -0
  87. package/tests/fixtures/animal/pregnancyRateTotal/invalid.json +49 -0
  88. package/tests/fixtures/animal/pregnancyRateTotal/valid.json +60 -0
  89. package/tests/fixtures/animal/required/invalid.json +59 -0
  90. package/tests/fixtures/animal/required/valid.json +72 -0
  91. package/tests/fixtures/completeness/all-values/warning.json +22 -0
  92. package/tests/fixtures/completeness/animalPopulation/invalid.json +58 -0
  93. package/tests/fixtures/completeness/animalPopulation/valid-animals.json +71 -0
  94. package/tests/fixtures/completeness/animalPopulation/valid-incomplete.json +58 -0
  95. package/tests/fixtures/completeness/animalPopulation/valid-no-liveAnimals.json +37 -0
  96. package/tests/fixtures/completeness/blank-nodes/agri-food processor-invalid.json +52 -0
  97. package/tests/fixtures/completeness/blank-nodes/invalid.json +124 -0
  98. package/tests/fixtures/completeness/blank-nodes/valid.json +128 -0
  99. package/tests/fixtures/completeness/cropland/site.json +16 -0
  100. package/tests/fixtures/completeness/cropland/valid.json +22 -0
  101. package/tests/fixtures/completeness/cropland/warning.json +22 -0
  102. package/tests/fixtures/completeness/freshForage/error-animals.json +63 -0
  103. package/tests/fixtures/completeness/freshForage/error-products.json +65 -0
  104. package/tests/fixtures/completeness/freshForage/valid-animal-inputs.json +63 -0
  105. package/tests/fixtures/completeness/freshForage/valid-animals.json +63 -0
  106. package/tests/fixtures/completeness/freshForage/valid-not-grazing-liveAnimal.json +55 -0
  107. package/tests/fixtures/completeness/freshForage/valid-not-liveAnimal.json +47 -0
  108. package/tests/fixtures/completeness/freshForage/valid-products.json +68 -0
  109. package/tests/fixtures/completeness/ingredient/invalid-agri-food-processor.json +37 -0
  110. package/tests/fixtures/completeness/ingredient/invalid.json +49 -0
  111. package/tests/fixtures/completeness/ingredient/valid-agri-food-processor-complete.json +49 -0
  112. package/tests/fixtures/completeness/ingredient/valid-agri-food-processor-incomplete.json +37 -0
  113. package/tests/fixtures/completeness/ingredient/valid.json +49 -0
  114. package/tests/fixtures/completeness/material/error.json +49 -0
  115. package/tests/fixtures/completeness/material/valid-fuel-material.json +60 -0
  116. package/tests/fixtures/completeness/material/valid-incomplete.json +36 -0
  117. package/tests/fixtures/completeness/material/valid-no-fuel.json +36 -0
  118. package/tests/fixtures/completeness/valid.json +22 -0
  119. package/tests/fixtures/cycle/aboveGroundCropResidue/invalid.json +76 -0
  120. package/tests/fixtures/cycle/aboveGroundCropResidue/valid.json +76 -0
  121. package/tests/fixtures/cycle/aggregated-valid.json +102 -0
  122. package/tests/fixtures/cycle/coverCrop/invalid.json +64 -0
  123. package/tests/fixtures/cycle/coverCrop/valid-not-coverCrop.json +54 -0
  124. package/tests/fixtures/cycle/coverCrop/valid.json +64 -0
  125. package/tests/fixtures/cycle/cropResidue/complete/invalid.json +56 -0
  126. package/tests/fixtures/cycle/cropResidue/complete/valid.json +82 -0
  127. package/tests/fixtures/cycle/cropResidue/incomplete/invalid.json +42 -0
  128. package/tests/fixtures/cycle/cropResidue/incomplete/valid.json +56 -0
  129. package/tests/fixtures/cycle/dates/invalid-emissions.json +70 -0
  130. package/tests/fixtures/cycle/liveAnimal-animalProduct-mapping/invalid.json +63 -0
  131. package/tests/fixtures/cycle/liveAnimal-animalProduct-mapping/valid.json +63 -0
  132. package/tests/fixtures/cycle/maximumCycleDuration/invalid-dates-year-only.json +48 -0
  133. package/tests/fixtures/cycle/maximumCycleDuration/invalid-dates.json +48 -0
  134. package/tests/fixtures/cycle/maximumCycleDuration/invalid.json +48 -0
  135. package/tests/fixtures/cycle/maximumCycleDuration/valid-dates-year-only.json +48 -0
  136. package/tests/fixtures/cycle/maximumCycleDuration/valid-dates.json +48 -0
  137. package/tests/fixtures/cycle/maximumCycleDuration/valid.json +48 -0
  138. package/tests/fixtures/cycle/otherSites/cycleDuration/invalid.json +52 -0
  139. package/tests/fixtures/cycle/otherSites/cycleDuration/valid-no-siteDuration.json +40 -0
  140. package/tests/fixtures/cycle/otherSites/cycleDuration/valid.json +52 -0
  141. package/tests/fixtures/cycle/practices/stockingDensityPermanentPastureAverage/invalid.json +56 -0
  142. package/tests/fixtures/cycle/practices/stockingDensityPermanentPastureAverage/valid.json +65 -0
  143. package/tests/fixtures/cycle/primary-product-as-input/invalid.json +59 -0
  144. package/tests/fixtures/cycle/primary-product-as-input/valid.json +48 -0
  145. package/tests/fixtures/cycle/product-linked-ia/cycle.json +66 -0
  146. package/tests/fixtures/cycle/product-linked-ia/invalid-multiple.json +58 -0
  147. package/tests/fixtures/cycle/product-linked-ia/valid.json +57 -0
  148. package/tests/fixtures/cycle/products/animals/invalid.json +69 -0
  149. package/tests/fixtures/cycle/products/animals/valid.json +58 -0
  150. package/tests/fixtures/cycle/riceGrainInHuskFlooded-minimumCycleDuration/invalid.json +53 -0
  151. package/tests/fixtures/cycle/riceGrainInHuskFlooded-minimumCycleDuration/valid.json +53 -0
  152. package/tests/fixtures/cycle/siteDuration/crop/invalid.json +53 -0
  153. package/tests/fixtures/cycle/siteDuration/crop/valid-different-duration.json +53 -0
  154. package/tests/fixtures/cycle/siteDuration/crop/valid-same-duration.json +53 -0
  155. package/tests/fixtures/cycle/siteDuration/invalid.json +41 -0
  156. package/tests/fixtures/cycle/siteDuration/valid-no-siteDuration.json +40 -0
  157. package/tests/fixtures/cycle/siteDuration/valid-otherSites.json +48 -0
  158. package/tests/fixtures/cycle/siteDuration/valid.json +45 -0
  159. package/tests/fixtures/cycle/substrate/required/invalid.json +50 -0
  160. package/tests/fixtures/cycle/substrate/required/valid.json +60 -0
  161. package/tests/fixtures/cycle/valid.json +343 -0
  162. package/tests/fixtures/emission/linked-terms/inputs/invalid.json +78 -0
  163. package/tests/fixtures/emission/linked-terms/inputs/valid.json +106 -0
  164. package/tests/fixtures/emission/linked-terms/transformation/error.json +104 -0
  165. package/tests/fixtures/emission/linked-terms/transformation/valid.json +107 -0
  166. package/tests/fixtures/emission/linked-terms/transformation/warning.json +76 -0
  167. package/tests/fixtures/emission/methodTier-background/invalid.json +60 -0
  168. package/tests/fixtures/emission/methodTier-background/valid.json +60 -0
  169. package/tests/fixtures/emission/not-relevant/invalid.json +71 -0
  170. package/tests/fixtures/emission/not-relevant/valid.json +95 -0
  171. package/tests/fixtures/emission/not-relevant-methodTier/invalid.json +70 -0
  172. package/tests/fixtures/emission/not-relevant-methodTier/valid.json +95 -0
  173. package/tests/fixtures/impactAssessment/aggregated-valid.json +43 -0
  174. package/tests/fixtures/impactAssessment/cycle-contains-product/invalid.json +34 -0
  175. package/tests/fixtures/impactAssessment/cycle-contains-product/valid.json +34 -0
  176. package/tests/fixtures/impactAssessment/cycle-endDate/invalid.json +26 -0
  177. package/tests/fixtures/impactAssessment/cycle-endDate/valid.json +26 -0
  178. package/tests/fixtures/impactAssessment/valid.json +93 -0
  179. package/tests/fixtures/indicator/characterisedIndicator-methodModel/invalid.json +52 -0
  180. package/tests/fixtures/indicator/characterisedIndicator-methodModel/valid.json +52 -0
  181. package/tests/fixtures/indicator/ionisingCompounds/invalid.json +23 -0
  182. package/tests/fixtures/indicator/ionisingCompounds/valid.json +23 -0
  183. package/tests/fixtures/indicator/landTransformation/invalid-grouped.json +257 -0
  184. package/tests/fixtures/indicator/landTransformation/invalid.json +100 -0
  185. package/tests/fixtures/indicator/landTransformation/valid-grouped-full.json +507 -0
  186. package/tests/fixtures/indicator/landTransformation/valid-grouped.json +507 -0
  187. package/tests/fixtures/indicator/landTransformation/valid.json +100 -0
  188. package/tests/fixtures/infrastructure/lifespan/invalid.json +26 -0
  189. package/tests/fixtures/infrastructure/lifespan/valid.json +45 -0
  190. package/tests/fixtures/input/animalFeed-fate/invalid.json +103 -0
  191. package/tests/fixtures/input/animalFeed-fate/valid.json +90 -0
  192. package/tests/fixtures/input/country/invalid.json +64 -0
  193. package/tests/fixtures/input/country/valid.json +64 -0
  194. package/tests/fixtures/input/distribution/animalHousing.json +103 -0
  195. package/tests/fixtures/input/distribution/complete/invalid.json +177 -0
  196. package/tests/fixtures/input/distribution/complete/valid.json +163 -0
  197. package/tests/fixtures/input/distribution/incomplete/valid.json +139 -0
  198. package/tests/fixtures/input/impactAssessment/invalid.json +99 -0
  199. package/tests/fixtures/input/impactAssessment/valid.json +89 -0
  200. package/tests/fixtures/input/input-as-product/invalid.json +57 -0
  201. package/tests/fixtures/input/input-as-product/valid.json +59 -0
  202. package/tests/fixtures/input/mustIncludeId/invalid.json +13 -0
  203. package/tests/fixtures/input/mustIncludeId/valid-multiple-ids.json +31 -0
  204. package/tests/fixtures/input/mustIncludeId/valid.json +22 -0
  205. package/tests/fixtures/input/saplings/invalid.json +58 -0
  206. package/tests/fixtures/input/saplings/valid-no-saplings.json +58 -0
  207. package/tests/fixtures/input/saplings/valid-not-plantation.json +58 -0
  208. package/tests/fixtures/input/saplings/valid.json +58 -0
  209. package/tests/fixtures/integration/distribution/product-yield-invalid.json +54 -0
  210. package/tests/fixtures/management/cycle-overlap/cycles.json +39 -0
  211. package/tests/fixtures/management/cycle-overlap/invalid.json +26 -0
  212. package/tests/fixtures/management/cycle-overlap/valid.json +26 -0
  213. package/tests/fixtures/management/exists/invalid.json +13 -0
  214. package/tests/fixtures/management/exists/valid.json +25 -0
  215. package/tests/fixtures/management/fallow-dates/invalid.json +24 -0
  216. package/tests/fixtures/management/fallow-dates/valid.json +24 -0
  217. package/tests/fixtures/management/termType/invalid-cropland.json +35 -0
  218. package/tests/fixtures/management/termType/invalid-permanent-pasture.json +25 -0
  219. package/tests/fixtures/management/termType/valid-cropland.json +55 -0
  220. package/tests/fixtures/management/termType/valid-no-management.json +13 -0
  221. package/tests/fixtures/management/termType/valid-permanent-pasture.json +35 -0
  222. package/tests/fixtures/measurement/depths/invalid.json +44 -0
  223. package/tests/fixtures/measurement/depths/valid.json +50 -0
  224. package/tests/fixtures/measurement/models/valid.json +33 -0
  225. package/tests/fixtures/measurement/models/warning-no-value.json +30 -0
  226. package/tests/fixtures/measurement/models/warning.json +33 -0
  227. package/tests/fixtures/measurement/pond-measurements/invalid.json +11 -0
  228. package/tests/fixtures/measurement/pond-measurements/valid.json +23 -0
  229. package/tests/fixtures/measurement/required-depths/error.json +71 -0
  230. package/tests/fixtures/measurement/required-depths/valid.json +126 -0
  231. package/tests/fixtures/measurement/required-depths/warning.json +29 -0
  232. package/tests/fixtures/measurement/soilTexture/missing-texture-value.json +227 -0
  233. package/tests/fixtures/measurement/soilTexture/percent-invalid.json +110 -0
  234. package/tests/fixtures/measurement/soilTexture/percent-missing-value.json +43 -0
  235. package/tests/fixtures/measurement/soilTexture/percent-valid.json +110 -0
  236. package/tests/fixtures/measurement/startDate-endDate-required/invalid.json +32 -0
  237. package/tests/fixtures/measurement/startDate-endDate-required/valid.json +46 -0
  238. package/tests/fixtures/measurement/unique/invalid.json +28 -0
  239. package/tests/fixtures/measurement/unique/valid.json +16 -0
  240. package/tests/fixtures/measurement/value-length/invalid.json +46 -0
  241. package/tests/fixtures/measurement/value-length/valid.json +44 -0
  242. package/tests/fixtures/measurement/water-salinity/invalid.json +33 -0
  243. package/tests/fixtures/measurement/water-salinity/valid-brakish.json +40 -0
  244. package/tests/fixtures/measurement/water-salinity/valid.json +33 -0
  245. package/tests/fixtures/organisation/valid.json +26 -0
  246. package/tests/fixtures/practice/croppingDuration/riceGrainInHuskFlooded/invalid.json +63 -0
  247. package/tests/fixtures/practice/croppingDuration/riceGrainInHuskFlooded/valid.json +63 -0
  248. package/tests/fixtures/practice/defaultValue/invalid.json +12 -0
  249. package/tests/fixtures/practice/defaultValue/valid.json +15 -0
  250. package/tests/fixtures/practice/excretaManagement/invalid.json +50 -0
  251. package/tests/fixtures/practice/excretaManagement/valid.json +60 -0
  252. package/tests/fixtures/practice/irrigated-complete/invalid.json +47 -0
  253. package/tests/fixtures/practice/irrigated-complete/valid-incomplete.json +47 -0
  254. package/tests/fixtures/practice/irrigated-complete/valid.json +60 -0
  255. package/tests/fixtures/practice/landCover-products/invalid.json +58 -0
  256. package/tests/fixtures/practice/landCover-products/valid-coverCrop.json +69 -0
  257. package/tests/fixtures/practice/landCover-products/valid.json +58 -0
  258. package/tests/fixtures/practice/liveAnimal-system/invalid.json +58 -0
  259. package/tests/fixtures/practice/liveAnimal-system/valid.json +69 -0
  260. package/tests/fixtures/practice/longFallowDuration/invalid.json +20 -0
  261. package/tests/fixtures/practice/longFallowDuration/valid.json +20 -0
  262. package/tests/fixtures/practice/noTillage/invalid.json +23 -0
  263. package/tests/fixtures/practice/noTillage/valid-value-not-100.json +23 -0
  264. package/tests/fixtures/practice/noTillage/valid.json +21 -0
  265. package/tests/fixtures/practice/pastureGrass/key-termType/invalid.json +16 -0
  266. package/tests/fixtures/practice/pastureGrass/key-termType/valid.json +16 -0
  267. package/tests/fixtures/practice/pastureGrass/key-value/invalid-numbers.json +67 -0
  268. package/tests/fixtures/practice/pastureGrass/key-value/invalid.json +67 -0
  269. package/tests/fixtures/practice/pastureGrass/key-value/valid.json +67 -0
  270. package/tests/fixtures/practice/pastureGrass/permanent-pasture/invalid.json +37 -0
  271. package/tests/fixtures/practice/pastureGrass/permanent-pasture/valid.json +47 -0
  272. package/tests/fixtures/practice/primaryPercent/invalid.json +49 -0
  273. package/tests/fixtures/practice/primaryPercent/valid.json +49 -0
  274. package/tests/fixtures/practice/processingOperation/invalid-no-primary.json +48 -0
  275. package/tests/fixtures/practice/processingOperation/invalid.json +49 -0
  276. package/tests/fixtures/practice/processingOperation/valid-cropland.json +37 -0
  277. package/tests/fixtures/practice/processingOperation/valid.json +49 -0
  278. package/tests/fixtures/practice/productivePhasePermanentCrops/invalid.json +48 -0
  279. package/tests/fixtures/practice/productivePhasePermanentCrops/valid-0-value.json +58 -0
  280. package/tests/fixtures/practice/productivePhasePermanentCrops/valid-no-value.json +47 -0
  281. package/tests/fixtures/practice/productivePhasePermanentCrops/valid.json +48 -0
  282. package/tests/fixtures/practice/site-management/invalid.json +75 -0
  283. package/tests/fixtures/practice/site-management/valid.json +75 -0
  284. package/tests/fixtures/practice/tillage-siteType/valid.json +51 -0
  285. package/tests/fixtures/practice/tillage-siteType/warning.json +42 -0
  286. package/tests/fixtures/practice/tillage-values/invalid-fullTillage.json +61 -0
  287. package/tests/fixtures/practice/tillage-values/invalid-noTillage.json +61 -0
  288. package/tests/fixtures/practice/tillage-values/valid.json +61 -0
  289. package/tests/fixtures/practice/waterRegime/rice/invalid.json +59 -0
  290. package/tests/fixtures/practice/waterRegime/rice/valid-0-value.json +59 -0
  291. package/tests/fixtures/practice/waterRegime/rice/valid.json +58 -0
  292. package/tests/fixtures/product/economicValueShare/invalid.json +31 -0
  293. package/tests/fixtures/product/economicValueShare/valid.json +22 -0
  294. package/tests/fixtures/product/excreta/invalid.json +62 -0
  295. package/tests/fixtures/product/excreta/valid.json +62 -0
  296. package/tests/fixtures/product/excreta/warning.json +53 -0
  297. package/tests/fixtures/product/excreta/with-system/invalid.json +79 -0
  298. package/tests/fixtures/product/excreta/with-system/valid.json +88 -0
  299. package/tests/fixtures/product/excreta/with-system/warning.json +70 -0
  300. package/tests/fixtures/product/fu_ha/invalid.json +49 -0
  301. package/tests/fixtures/product/fu_ha/valid.json +49 -0
  302. package/tests/fixtures/product/primary/invalid.json +22 -0
  303. package/tests/fixtures/product/primary/valid.json +22 -0
  304. package/tests/fixtures/product/value/valid.json +26 -0
  305. package/tests/fixtures/product/value/value-0/error.json +40 -0
  306. package/tests/fixtures/product/value/value-empty/warning.json +23 -0
  307. package/tests/fixtures/product/yield/invalid.json +54 -0
  308. package/tests/fixtures/product/yield/no-value.json +75 -0
  309. package/tests/fixtures/product/yield/valid.json +54 -0
  310. package/tests/fixtures/property/default-value/valid-allowed-exception.json +61 -0
  311. package/tests/fixtures/property/default-value/valid.json +61 -0
  312. package/tests/fixtures/property/default-value/warning.json +61 -0
  313. package/tests/fixtures/property/termType/invalid.json +60 -0
  314. package/tests/fixtures/property/termType/valid.json +60 -0
  315. package/tests/fixtures/property/value-min-max/invalid.json +77 -0
  316. package/tests/fixtures/property/value-min-max/valid-skip-maximum.json +57 -0
  317. package/tests/fixtures/property/value-min-max/valid.json +78 -0
  318. package/tests/fixtures/property/valueType/invalid.json +79 -0
  319. package/tests/fixtures/property/valueType/valid.json +79 -0
  320. package/tests/fixtures/property/volatileSolidsContent/invalid.json +99 -0
  321. package/tests/fixtures/property/volatileSolidsContent/valid.json +99 -0
  322. package/tests/fixtures/shared/coordinates/invalid.json +18 -0
  323. package/tests/fixtures/shared/coordinates/valid.json +18 -0
  324. package/tests/fixtures/shared/data-duplicates/valid.json +113 -0
  325. package/tests/fixtures/shared/data-duplicates/warning.json +172 -0
  326. package/tests/fixtures/shared/duplicated-term-units/invalid-animalProduct.json +61 -0
  327. package/tests/fixtures/shared/duplicated-term-units/invalid-organicFertiliser.json +61 -0
  328. package/tests/fixtures/shared/duplicated-term-units/valid.json +49 -0
  329. package/tests/fixtures/shared/list-country-region/invalid.json +54 -0
  330. package/tests/fixtures/shared/list-country-region/valid.json +54 -0
  331. package/tests/fixtures/shared/list-percent-value/invalid.json +49 -0
  332. package/tests/fixtures/shared/list-percent-value/valid.json +52 -0
  333. package/tests/fixtures/shared/list-valueType/invalid.json +49 -0
  334. package/tests/fixtures/shared/list-valueType/valid.json +49 -0
  335. package/tests/fixtures/shared/list-values-sum-100/management/with-properties/valid.json +91 -0
  336. package/tests/fixtures/shared/list-values-sum-100/measurements/missing-soil.json +46 -0
  337. package/tests/fixtures/shared/list-values-sum-100/measurements/no-depth-high-value.json +63 -0
  338. package/tests/fixtures/shared/list-values-sum-100/measurements/no-depth-valid.json +40 -0
  339. package/tests/fixtures/shared/list-values-sum-100/measurements/with-depth-high-value.json +71 -0
  340. package/tests/fixtures/shared/list-values-sum-100/practices/total-100.json +61 -0
  341. package/tests/fixtures/shared/list-values-sum-100/practices/total-110.json +61 -0
  342. package/tests/fixtures/shared/list-values-sum-100/practices/total-90.json +61 -0
  343. package/tests/fixtures/shared/min-max/value-above.json +31 -0
  344. package/tests/fixtures/shared/min-max/value-below.json +31 -0
  345. package/tests/fixtures/shared/min-max/value-valid.json +45 -0
  346. package/tests/fixtures/shared/model/emissions/invalid.json +102 -0
  347. package/tests/fixtures/shared/model/emissions/valid-variable-tolerance.json +180 -0
  348. package/tests/fixtures/shared/model/emissions/valid.json +102 -0
  349. package/tests/fixtures/shared/model/impacts/invalid.json +75 -0
  350. package/tests/fixtures/shared/model/impacts/valid.json +75 -0
  351. package/tests/fixtures/shared/model/inputs/valid-no-value.json +84 -0
  352. package/tests/fixtures/shared/model/inputs/valid.json +87 -0
  353. package/tests/fixtures/shared/model/inputs/warning.json +87 -0
  354. package/tests/fixtures/shared/model/products/valid-no-value.json +88 -0
  355. package/tests/fixtures/shared/model/products/valid.json +91 -0
  356. package/tests/fixtures/shared/model/products/warning.json +91 -0
  357. package/tests/fixtures/shared/otherModel/invalid.json +69 -0
  358. package/tests/fixtures/shared/otherModel/valid.json +70 -0
  359. package/tests/fixtures/shared/properties-duplicate-values/invalid.json +61 -0
  360. package/tests/fixtures/shared/properties-duplicate-values/valid.json +57 -0
  361. package/tests/fixtures/shared/properties-same-length/invalid.json +62 -0
  362. package/tests/fixtures/shared/properties-same-length/valid.json +52 -0
  363. package/tests/fixtures/shared/unit-percent/invalid.json +34 -0
  364. package/tests/fixtures/shared/unit-percent/valid.json +60 -0
  365. package/tests/fixtures/shared/unit-percent/warning.json +52 -0
  366. package/tests/fixtures/site/cycles-linked-ia/invalid.json +129 -0
  367. package/tests/fixtures/site/cycles-linked-ia/valid.json +129 -0
  368. package/tests/fixtures/site/valid.json +138 -0
  369. package/tests/fixtures/source/valid.json +19 -0
  370. package/tests/fixtures/transformation/excretaManagement/invalid.json +47 -0
  371. package/tests/fixtures/transformation/excretaManagement/valid.json +59 -0
  372. package/tests/fixtures/transformation/inputs-products/invalid.json +43 -0
  373. package/tests/fixtures/transformation/inputs-products/valid.json +43 -0
  374. package/tests/fixtures/transformation/linked-emission/invalid.json +101 -0
  375. package/tests/fixtures/transformation/linked-emission/valid.json +107 -0
  376. package/tests/fixtures/transformation/previousTransformationId/invalid-no-previous.json +127 -0
  377. package/tests/fixtures/transformation/previousTransformationId/invalid-previous-input.json +100 -0
  378. package/tests/fixtures/transformation/previousTransformationId/invalid-product-input.json +106 -0
  379. package/tests/fixtures/transformation/previousTransformationId/invalid-wrong-order.json +136 -0
  380. package/tests/fixtures/transformation/previousTransformationId/valid.json +171 -0
  381. package/tests/integration/__init__.py +0 -0
  382. package/tests/integration/test_product.py +17 -0
  383. package/tests/test_gee.py +10 -0
  384. package/tests/test_utils.py +36 -0
  385. package/tests/test_validation.py +11 -0
  386. package/tests/utils.py +28 -0
  387. package/tests/validators/__init__.py +0 -0
  388. package/tests/validators/test_aggregated_cycle.py +44 -0
  389. package/tests/validators/test_aggregated_shared.py +63 -0
  390. package/tests/validators/test_animal.py +72 -0
  391. package/tests/validators/test_completeness.py +337 -0
  392. package/tests/validators/test_cycle.py +600 -0
  393. package/tests/validators/test_emission.py +170 -0
  394. package/tests/validators/test_impact_assessment.py +80 -0
  395. package/tests/validators/test_indicator.py +120 -0
  396. package/tests/validators/test_infrastructure.py +26 -0
  397. package/tests/validators/test_input.py +434 -0
  398. package/tests/validators/test_management.py +177 -0
  399. package/tests/validators/test_measurement.py +317 -0
  400. package/tests/validators/test_organisation.py +32 -0
  401. package/tests/validators/test_practice.py +490 -0
  402. package/tests/validators/test_product.py +291 -0
  403. package/tests/validators/test_property.py +143 -0
  404. package/tests/validators/test_shared.py +1139 -0
  405. package/tests/validators/test_site.py +151 -0
  406. package/tests/validators/test_source.py +15 -0
  407. package/tests/validators/test_transformation.py +151 -0
  408. package/tests/validators/test_validators.py +74 -0
  409. package/tsconfig.dist.json +9 -0
  410. package/tsconfig.json +25 -0
@@ -0,0 +1,600 @@
1
+ from unittest.mock import patch
2
+ import pytest
3
+ import os
4
+ import json
5
+ from hestia_earth.schema import SiteSiteType, CycleFunctionalUnit
6
+
7
+ from tests.utils import fixtures_path, fake_get_terms
8
+ from hestia_earth.validation.utils import _group_nodes
9
+ from hestia_earth.validation.validators.cycle import (
10
+ validate_cycle,
11
+ validate_cycle_dates,
12
+ validate_cycleDuration,
13
+ validate_durations,
14
+ validate_economicValueShare,
15
+ validate_sum_aboveGroundCropResidue,
16
+ validate_crop_residue_complete,
17
+ validate_crop_residue_incomplete,
18
+ validate_crop_siteDuration,
19
+ validate_siteDuration,
20
+ validate_possibleCoverCrop,
21
+ validate_set_treatment,
22
+ validate_products_animals,
23
+ validate_linked_impact_assessment,
24
+ validate_functionalUnit_not_1_ha,
25
+ validate_stocking_density,
26
+ validate_animal_product_mapping,
27
+ validate_requires_substrate,
28
+ validate_maximum_cycleDuration,
29
+ validate_riceGrainInHuskFlooded_minimum_cycleDuration,
30
+ )
31
+
32
+ fixtures_folder = os.path.join(fixtures_path, "cycle")
33
+ class_path = "hestia_earth.validation.validators.cycle"
34
+
35
+
36
+ @patch(
37
+ "hestia_earth.validation.validators.completeness.get_terms",
38
+ return_value=fake_get_terms,
39
+ )
40
+ def test_validate_cycle_valid(*args):
41
+ with open(f"{fixtures_folder}/valid.json") as f:
42
+ node = json.load(f)
43
+ results = validate_cycle(node)
44
+ print(results)
45
+ assert all([r is True for r in results])
46
+
47
+
48
+ def test_validate_cycle_dates_valid():
49
+ cycle = {"startDate": "2020-01-01", "endDate": "2020-01-02"}
50
+ assert validate_cycle_dates(cycle) is True
51
+ cycle = {"startDate": "2020-01", "endDate": "2020-01"}
52
+ assert validate_cycle_dates(cycle) is True
53
+ cycle = {"startDate": "2020", "endDate": "2020"}
54
+ assert validate_cycle_dates(cycle) is True
55
+
56
+
57
+ def test_validate_cycle_dates_invalid():
58
+ cycle = {"startDate": "2020-01-02", "endDate": "2020-01-01"}
59
+ assert validate_cycle_dates(cycle) == {
60
+ "level": "error",
61
+ "dataPath": ".endDate",
62
+ "message": "must be greater than startDate",
63
+ }
64
+
65
+ # same day
66
+ cycle = {"startDate": "2020-01-01", "endDate": "2020-01-01"}
67
+ assert validate_cycle_dates(cycle) == {
68
+ "level": "error",
69
+ "dataPath": ".endDate",
70
+ "message": "must be greater than startDate",
71
+ }
72
+
73
+ # different formats
74
+ cycle = {"startDate": "2020", "endDate": "2021-01-01"}
75
+ assert validate_cycle_dates(cycle) == {
76
+ "level": "error",
77
+ "dataPath": ".startDate",
78
+ "message": "must be in the same format as endDate",
79
+ }
80
+
81
+
82
+ def test_validate_cycleDuration_valid():
83
+ cycle = {"startDate": "2020-01-02", "endDate": "2021-01-01", "cycleDuration": 365}
84
+ assert validate_cycleDuration(cycle) is True
85
+
86
+
87
+ def test_validate_cycleDuration_invalid():
88
+ cycle = {"startDate": "2020-01-02", "endDate": "2021-01-01", "cycleDuration": 200}
89
+ assert validate_cycleDuration(cycle) == {
90
+ "level": "error",
91
+ "dataPath": ".cycleDuration",
92
+ "message": "must equal to endDate - startDate in days",
93
+ "params": {"expected": 365.0},
94
+ }
95
+
96
+
97
+ @pytest.mark.parametrize(
98
+ "cycle,expected",
99
+ [
100
+ ({"functionalUnit": "1 ha"}, True),
101
+ (
102
+ {"functionalUnit": "relative"},
103
+ {
104
+ "level": "warning",
105
+ "dataPath": "",
106
+ "message": "should add the fields for a relative cycle",
107
+ "params": {"expected": ["siteDuration", "siteArea"]},
108
+ },
109
+ ),
110
+ (
111
+ {"functionalUnit": "relative", "otherSites": [{}, {}]},
112
+ {
113
+ "level": "warning",
114
+ "dataPath": "",
115
+ "message": "should add the fields for a relative cycle",
116
+ "params": {
117
+ "expected": [
118
+ "siteDuration",
119
+ "siteArea",
120
+ "otherSitesDuration",
121
+ "otherSitesArea",
122
+ ]
123
+ },
124
+ },
125
+ ),
126
+ (
127
+ {
128
+ "functionalUnit": "relative",
129
+ "otherSites": [{}, {}],
130
+ "otherSitesDuration": [10, 20],
131
+ },
132
+ {
133
+ "level": "warning",
134
+ "dataPath": "",
135
+ "message": "should add the fields for a relative cycle",
136
+ "params": {"expected": ["siteDuration", "siteArea", "otherSitesArea"]},
137
+ },
138
+ ),
139
+ ],
140
+ )
141
+ def test_validate_durations(cycle: dict, expected):
142
+ assert validate_durations(cycle) == expected
143
+
144
+
145
+ def test_validate_economicValueShare_valid():
146
+ products = [{"economicValueShare": 10}, {"economicValueShare": 80}]
147
+ assert validate_economicValueShare(products) is True
148
+
149
+
150
+ def test_validate_economicValueShare_invalid():
151
+ products = [
152
+ {"economicValueShare": 10},
153
+ {"economicValueShare": 90},
154
+ {"economicValueShare": 10},
155
+ ]
156
+ assert validate_economicValueShare(products) == {
157
+ "level": "error",
158
+ "dataPath": ".products",
159
+ "message": "economicValueShare should sum to 100 or less across all products",
160
+ "params": {"sum": 110},
161
+ }
162
+
163
+
164
+ def test_validate_sum_aboveGroundCropResidue_valid():
165
+ with open(f"{fixtures_folder}/aboveGroundCropResidue/valid.json") as f:
166
+ data = json.load(f)
167
+ assert validate_sum_aboveGroundCropResidue(data.get("products")) is True
168
+
169
+
170
+ def test_validate_sum_aboveGroundCropResidue_invalid():
171
+ with open(f"{fixtures_folder}/aboveGroundCropResidue/invalid.json") as f:
172
+ data = json.load(f)
173
+ assert validate_sum_aboveGroundCropResidue(data.get("products")) == {
174
+ "level": "error",
175
+ "dataPath": ".products[0].value",
176
+ "message": "must be more than or equal to other crop residues",
177
+ "params": {
178
+ "expected": [
179
+ "aboveGroundCropResidueBurnt",
180
+ "aboveGroundCropResidueLeftOnField",
181
+ ],
182
+ },
183
+ }
184
+
185
+
186
+ @patch(f"{class_path}.get_terms", side_effect=fake_get_terms)
187
+ def test_validate_crop_residue_complete_valid(*args):
188
+ with open(f"{fixtures_folder}/cropResidue/complete/valid.json") as f:
189
+ data = json.load(f)
190
+ assert validate_crop_residue_complete(data, data.get("site")) is True
191
+
192
+
193
+ @patch(f"{class_path}.get_terms", side_effect=fake_get_terms)
194
+ def test_validate_crop_residue_complete_invalid(*args):
195
+ with open(f"{fixtures_folder}/cropResidue/complete/invalid.json") as f:
196
+ data = json.load(f)
197
+ assert validate_crop_residue_complete(data, data.get("site")) == {
198
+ "level": "error",
199
+ "dataPath": "",
200
+ "message": "must specify the fate of cropResidue",
201
+ "params": {"siteType": ["cropland", "glass or high accessible cover"]},
202
+ }
203
+
204
+
205
+ @patch(f"{class_path}.get_terms", side_effect=fake_get_terms)
206
+ def test_validate_crop_residue_incomplete_valid(*args):
207
+ with open(f"{fixtures_folder}/cropResidue/incomplete/valid.json") as f:
208
+ data = json.load(f)
209
+ assert validate_crop_residue_incomplete(data, data.get("site")) is True
210
+
211
+
212
+ @patch(f"{class_path}.get_terms", side_effect=fake_get_terms)
213
+ def test_validate_crop_residue_incomplete_invalid(*args):
214
+ with open(f"{fixtures_folder}/cropResidue/incomplete/invalid.json") as f:
215
+ data = json.load(f)
216
+ assert validate_crop_residue_incomplete(data, data.get("site")) == {
217
+ "level": "warning",
218
+ "dataPath": "",
219
+ "message": "should specify the fate of cropResidue",
220
+ "params": {"siteType": ["cropland", "glass or high accessible cover"]},
221
+ }
222
+
223
+
224
+ def test_validate_crop_siteDuration_valid():
225
+ with open(f"{fixtures_folder}/siteDuration/crop/valid-same-duration.json") as f:
226
+ data = json.load(f)
227
+ assert validate_crop_siteDuration(data) is True
228
+
229
+ with open(
230
+ f"{fixtures_folder}/siteDuration/crop/valid-different-duration.json"
231
+ ) as f:
232
+ data = json.load(f)
233
+ assert validate_crop_siteDuration(data) is True
234
+
235
+
236
+ def test_validate_crop_siteDuration_invalid():
237
+ with open(f"{fixtures_folder}/siteDuration/crop/invalid.json") as f:
238
+ data = json.load(f)
239
+ assert validate_crop_siteDuration(data) == {
240
+ "level": "error",
241
+ "dataPath": ".siteDuration",
242
+ "message": "should not be equal to cycleDuration for crop",
243
+ "params": {"current": "one year prior", "expected": "harvest of previous crop"},
244
+ }
245
+
246
+
247
+ def test_validate_siteDuration_valid():
248
+ with open(f"{fixtures_folder}/siteDuration/valid.json") as f:
249
+ data = json.load(f)
250
+ assert validate_siteDuration(data) is True
251
+
252
+ with open(f"{fixtures_folder}/siteDuration/valid-no-siteDuration.json") as f:
253
+ data = json.load(f)
254
+ assert validate_siteDuration(data) is True
255
+
256
+ with open(f"{fixtures_folder}/siteDuration/valid-otherSites.json") as f:
257
+ data = json.load(f)
258
+ assert validate_siteDuration(data) is True
259
+
260
+
261
+ def test_validate_siteDuration_invalid():
262
+ with open(f"{fixtures_folder}/siteDuration/invalid.json") as f:
263
+ data = json.load(f)
264
+ assert validate_siteDuration(data) == {
265
+ "level": "error",
266
+ "dataPath": ".siteDuration",
267
+ "message": "must be less than or equal to cycleDuration",
268
+ }
269
+
270
+
271
+ def test_validate_possibleCoverCrop_valid():
272
+ # no products should be valid
273
+ assert validate_possibleCoverCrop({}) is True
274
+
275
+ with open(f"{fixtures_folder}/coverCrop/valid.json") as f:
276
+ data = json.load(f)
277
+ assert validate_possibleCoverCrop(data) is True
278
+
279
+ with open(f"{fixtures_folder}/coverCrop/valid-not-coverCrop.json") as f:
280
+ data = json.load(f)
281
+ assert validate_possibleCoverCrop(data) is True
282
+
283
+
284
+ def test_validate_possibleCoverCrop_error():
285
+ with open(f"{fixtures_folder}/coverCrop/invalid.json") as f:
286
+ data = json.load(f)
287
+ assert validate_possibleCoverCrop(data) == {
288
+ "level": "error",
289
+ "dataPath": "",
290
+ "message": "cover crop cycle contains non cover crop product",
291
+ }
292
+
293
+
294
+ def test_validate_set_treatment_valid():
295
+ cycle = {"treatment": "treatment"}
296
+
297
+ # no experimentDesign in Source
298
+ source = {}
299
+ validate_set_treatment(cycle, source) is True
300
+
301
+ # with experimentDesign and treatment
302
+ source = {"experimentDesign": "design"}
303
+ validate_set_treatment(cycle, source) is True
304
+
305
+
306
+ def test_validate_set_treatment_warning():
307
+ source = {"experimentDesign": "design"}
308
+ cycle = {}
309
+ assert validate_set_treatment(cycle, source) == {
310
+ "level": "warning",
311
+ "dataPath": ".treatment",
312
+ "message": "should specify a treatment when experimentDesign is specified",
313
+ }
314
+
315
+
316
+ def test_validate_products_animals_valid():
317
+ # no products should be valid
318
+ assert validate_products_animals({}) is True
319
+
320
+ with open(f"{fixtures_folder}/products/animals/valid.json") as f:
321
+ data = json.load(f)
322
+ assert validate_products_animals(data) is True
323
+
324
+
325
+ def test_validate_products_animals_invalid():
326
+ with open(f"{fixtures_folder}/products/animals/invalid.json") as f:
327
+ data = json.load(f)
328
+ assert validate_products_animals(data) == {
329
+ "level": "warning",
330
+ "dataPath": ".products",
331
+ "message": "should not specify both liveAnimal and animalProduct",
332
+ }
333
+
334
+
335
+ def test_validate_linked_impact_assessment_valid():
336
+ with open(f"{fixtures_folder}/product-linked-ia/cycle.json") as f:
337
+ cycle = json.load(f)
338
+ with open(f"{fixtures_folder}/product-linked-ia/valid.json") as f:
339
+ nodes = json.load(f).get("nodes")
340
+ assert validate_linked_impact_assessment(cycle, _group_nodes(nodes)) is True
341
+
342
+
343
+ def test_validate_linked_impact_assessment_invalid():
344
+ with open(f"{fixtures_folder}/product-linked-ia/cycle.json") as f:
345
+ cycle = json.load(f)
346
+
347
+ assert validate_linked_impact_assessment(cycle, {}) == [
348
+ {
349
+ "level": "error",
350
+ "dataPath": ".products[0].term",
351
+ "message": "no ImpactAssessment are associated with this Product",
352
+ "params": {
353
+ "product": {"@type": "Term", "@id": "maizeGrain", "termType": "crop"},
354
+ "node": {"type": "Cycle", "id": "fake-cycle"},
355
+ },
356
+ },
357
+ {
358
+ "level": "error",
359
+ "dataPath": ".products[1].term",
360
+ "message": "no ImpactAssessment are associated with this Product",
361
+ "params": {
362
+ "product": {"@type": "Term", "@id": "maizeGrain", "termType": "crop"},
363
+ "node": {"type": "Cycle", "id": "fake-cycle"},
364
+ },
365
+ },
366
+ ]
367
+
368
+ with open(f"{fixtures_folder}/product-linked-ia/invalid-multiple.json") as f:
369
+ nodes = json.load(f).get("nodes")
370
+ assert validate_linked_impact_assessment(cycle, _group_nodes(nodes)) == [
371
+ {
372
+ "level": "error",
373
+ "dataPath": ".products[0].term",
374
+ "message": "no ImpactAssessment are associated with this Product",
375
+ "params": {
376
+ "product": {"@type": "Term", "@id": "maizeGrain", "termType": "crop"},
377
+ "node": {"type": "Cycle", "id": "fake-cycle"},
378
+ },
379
+ },
380
+ {
381
+ "level": "error",
382
+ "dataPath": ".products[1].term",
383
+ "message": "multiple ImpactAssessment are associated with this Product",
384
+ "params": {
385
+ "product": {"@type": "Term", "@id": "maizeGrain", "termType": "crop"},
386
+ "node": {"type": "Cycle", "id": "fake-cycle"},
387
+ },
388
+ },
389
+ ]
390
+
391
+
392
+ def test_validate_functionalUnit_not_1_ha_valid():
393
+ cycle = {"functionalUnit": CycleFunctionalUnit.RELATIVE.value}
394
+ site = {"siteType": SiteSiteType.AGRI_FOOD_PROCESSOR.value}
395
+ assert validate_functionalUnit_not_1_ha(cycle, site) is True
396
+
397
+
398
+ def test_validate_functionalUnit_not_1_ha_invalid():
399
+ cycle = {"functionalUnit": CycleFunctionalUnit._1_HA.value}
400
+ site = {"siteType": SiteSiteType.AGRI_FOOD_PROCESSOR.value}
401
+ assert validate_functionalUnit_not_1_ha(cycle, site) == {
402
+ "level": "error",
403
+ "dataPath": ".functionalUnit",
404
+ "message": "must not be equal to 1 ha",
405
+ "params": {"siteType": site.get("siteType")},
406
+ }
407
+
408
+
409
+ def test_validate_stocking_density_valid():
410
+ # no products should be valid
411
+ assert validate_stocking_density({}, {}) is True
412
+
413
+ with open(
414
+ f"{fixtures_folder}/practices/stockingDensityPermanentPastureAverage/valid.json"
415
+ ) as f:
416
+ cycle = json.load(f)
417
+
418
+ # not permanent pasture is valid
419
+ site = {"siteType": SiteSiteType.CROPLAND.value}
420
+ assert validate_stocking_density(cycle, site) is True
421
+
422
+ # permanent pasture is valid
423
+ site = {"siteType": SiteSiteType.PERMANENT_PASTURE.value}
424
+ assert validate_stocking_density(cycle, site) is True
425
+
426
+
427
+ def test_validate_stocking_density_invalid():
428
+ with open(
429
+ f"{fixtures_folder}/practices/stockingDensityPermanentPastureAverage/invalid.json"
430
+ ) as f:
431
+ cycle = json.load(f)
432
+
433
+ # not permanent pasture is valid
434
+ site = {"siteType": SiteSiteType.CROPLAND.value}
435
+ assert validate_stocking_density(cycle, site) is True
436
+
437
+ site = {"siteType": SiteSiteType.PERMANENT_PASTURE.value}
438
+ assert validate_stocking_density(cycle, site) == {
439
+ "level": "warning",
440
+ "dataPath": ".practices",
441
+ "message": "should add the term stockingDensityPermanentPastureAverage",
442
+ "params": {"expected": "stockingDensityPermanentPastureAverage"},
443
+ }
444
+
445
+
446
+ def test_validate_animal_product_mapping_valid():
447
+ # no products should be valid
448
+ assert validate_animal_product_mapping({}) is True
449
+
450
+ with open(f"{fixtures_folder}/liveAnimal-animalProduct-mapping/valid.json") as f:
451
+ cycle = json.load(f)
452
+ assert validate_animal_product_mapping(cycle) is True
453
+
454
+
455
+ def test_validate_animal_product_mapping_invalid():
456
+ with open(f"{fixtures_folder}/liveAnimal-animalProduct-mapping/invalid.json") as f:
457
+ cycle = json.load(f)
458
+ assert validate_animal_product_mapping(cycle) == {
459
+ "level": "error",
460
+ "dataPath": ".products[0].term",
461
+ "message": "is not an allowed animalProduct",
462
+ "params": {
463
+ "expected": [
464
+ "fatDairyCattle",
465
+ "hidesDairyCattleFresh",
466
+ "meatDairyCattleColdCarcassWeight",
467
+ "meatDairyCattleColdDressedCarcassWeight",
468
+ "meatDairyCattleLiveweight",
469
+ "offalDairyCattle",
470
+ "offalDairyCattleEdible",
471
+ "offalDairyCattleInedible",
472
+ ]
473
+ },
474
+ }
475
+
476
+
477
+ def test_validate_requires_substrate_valid():
478
+ # no practices should be valid
479
+ assert validate_requires_substrate({}, {}) is True
480
+
481
+ # different siteType should be valid
482
+ assert (
483
+ validate_requires_substrate({}, {"siteType": SiteSiteType.CROPLAND.value})
484
+ is True
485
+ )
486
+
487
+ with open(f"{fixtures_folder}/substrate/required/valid.json") as f:
488
+ cycle = json.load(f)
489
+ assert validate_requires_substrate(cycle, cycle.get("site")) is True
490
+
491
+
492
+ def test_validate_requires_substrate_invalid():
493
+ with open(f"{fixtures_folder}/substrate/required/invalid.json") as f:
494
+ cycle = json.load(f)
495
+ assert validate_requires_substrate(cycle, cycle.get("site")) == {
496
+ "level": "error",
497
+ "dataPath": ".inputs",
498
+ "message": "must add substrate inputs",
499
+ "params": {
500
+ "term": {
501
+ "@type": "Term",
502
+ "termType": "system",
503
+ "@id": "protectedCroppingSystemSubstrateBased",
504
+ }
505
+ },
506
+ }
507
+
508
+
509
+ def test_validate_maximum_cycleDuration_valid():
510
+ # no cycleDuration should be valid
511
+ assert validate_maximum_cycleDuration({}) is True
512
+
513
+ with open(f"{fixtures_folder}/maximumCycleDuration/valid.json") as f:
514
+ cycle = json.load(f)
515
+ assert validate_maximum_cycleDuration(cycle) is True
516
+
517
+ with open(f"{fixtures_folder}/maximumCycleDuration/valid-dates.json") as f:
518
+ cycle = json.load(f)
519
+ assert validate_maximum_cycleDuration(cycle) is True
520
+
521
+ with open(
522
+ f"{fixtures_folder}/maximumCycleDuration/valid-dates-year-only.json"
523
+ ) as f:
524
+ cycle = json.load(f)
525
+ assert validate_maximum_cycleDuration(cycle) is True
526
+
527
+
528
+ def test_validate_maximum_cycleDuration_invalid():
529
+ with open(f"{fixtures_folder}/maximumCycleDuration/invalid.json") as f:
530
+ cycle = json.load(f)
531
+ assert validate_maximum_cycleDuration(cycle) == {
532
+ "level": "error",
533
+ "dataPath": ".cycleDuration",
534
+ "message": "must be below maximum cycleDuration",
535
+ "params": {
536
+ "comparison": "<=",
537
+ "limit": 731,
538
+ "exclusive": False,
539
+ "current": 1000,
540
+ },
541
+ }
542
+
543
+ with open(f"{fixtures_folder}/maximumCycleDuration/invalid-dates.json") as f:
544
+ cycle = json.load(f)
545
+ assert validate_maximum_cycleDuration(cycle) == {
546
+ "level": "error",
547
+ "dataPath": ".startDate",
548
+ "message": "must be below maximum cycleDuration",
549
+ "params": {
550
+ "comparison": "<=",
551
+ "limit": 731,
552
+ "exclusive": False,
553
+ "current": 3257,
554
+ },
555
+ }
556
+
557
+ with open(
558
+ f"{fixtures_folder}/maximumCycleDuration/invalid-dates-year-only.json"
559
+ ) as f:
560
+ cycle = json.load(f)
561
+ assert validate_maximum_cycleDuration(cycle) == {
562
+ "level": "error",
563
+ "dataPath": ".startDate",
564
+ "message": "must be below maximum cycleDuration",
565
+ "params": {
566
+ "comparison": "<=",
567
+ "limit": 731,
568
+ "exclusive": False,
569
+ "current": 1096,
570
+ },
571
+ }
572
+
573
+
574
+ def test_validate_riceGrainInHuskFlooded_minimum_cycleDuration_valid():
575
+ # no cycleDuration should be valid
576
+ assert validate_riceGrainInHuskFlooded_minimum_cycleDuration({}, {}) is True
577
+
578
+ with open(
579
+ f"{fixtures_folder}/riceGrainInHuskFlooded-minimumCycleDuration/valid.json"
580
+ ) as f:
581
+ cycle = json.load(f)
582
+ assert (
583
+ validate_riceGrainInHuskFlooded_minimum_cycleDuration(cycle, cycle.get("site"))
584
+ is True
585
+ )
586
+
587
+
588
+ def test_validate_riceGrainInHuskFlooded_minimum_cycleDuration_invalid():
589
+ with open(
590
+ f"{fixtures_folder}/riceGrainInHuskFlooded-minimumCycleDuration/invalid.json"
591
+ ) as f:
592
+ cycle = json.load(f)
593
+ assert validate_riceGrainInHuskFlooded_minimum_cycleDuration(
594
+ cycle, cycle.get("site")
595
+ ) == {
596
+ "level": "warning",
597
+ "dataPath": ".cycleDuration",
598
+ "message": "should be more than the cropping duration",
599
+ "params": {"expected": 111, "current": 100},
600
+ }