invenio-app-ils 1.0.0a54__py2.py3-none-any.whl → 6.1.0__py2.py3-none-any.whl

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 (331) hide show
  1. invenio_app_ils/__init__.py +2 -2
  2. invenio_app_ils/acquisition/api.py +3 -1
  3. invenio_app_ils/acquisition/config.py +10 -21
  4. invenio_app_ils/acquisition/jsonresolvers/order_order_lines.py +1 -0
  5. invenio_app_ils/acquisition/mappings/os-v1/acq_orders/order-v1.0.0.json +364 -0
  6. invenio_app_ils/acquisition/mappings/os-v2/__init__.py +0 -0
  7. invenio_app_ils/acquisition/mappings/os-v2/acq_orders/order-v1.0.0.json +364 -0
  8. invenio_app_ils/acquisition/mappings/v7/acq_orders/order-v1.0.0.json +14 -0
  9. invenio_app_ils/acquisition/search.py +5 -15
  10. invenio_app_ils/assets/semantic-ui/less/theme.config +103 -0
  11. invenio_app_ils/assets/semantic-ui/templates/.gitkeep +0 -0
  12. invenio_app_ils/circulation/api.py +153 -67
  13. invenio_app_ils/circulation/config.py +29 -25
  14. invenio_app_ils/circulation/indexer.py +14 -19
  15. invenio_app_ils/circulation/loaders/__init__.py +2 -0
  16. invenio_app_ils/circulation/loaders/schemas/json/loan_checkout.py +2 -3
  17. invenio_app_ils/circulation/loaders/schemas/json/loan_request.py +82 -16
  18. invenio_app_ils/circulation/loaders/schemas/json/loan_self_checkout.py +19 -0
  19. invenio_app_ils/circulation/notifications/api.py +23 -19
  20. invenio_app_ils/circulation/notifications/messages.py +6 -6
  21. invenio_app_ils/circulation/notifications/tasks.py +1 -2
  22. invenio_app_ils/circulation/receivers.py +2 -5
  23. invenio_app_ils/circulation/search.py +23 -22
  24. invenio_app_ils/circulation/serializers/__init__.py +2 -2
  25. invenio_app_ils/circulation/serializers/csv.py +1 -3
  26. invenio_app_ils/circulation/serializers/custom_fields.py +5 -9
  27. invenio_app_ils/circulation/serializers/json.py +2 -6
  28. invenio_app_ils/circulation/serializers/response.py +12 -12
  29. invenio_app_ils/circulation/stats/views.py +5 -15
  30. invenio_app_ils/circulation/tasks.py +2 -6
  31. invenio_app_ils/circulation/templates/invenio_app_ils_circulation/notifications/self_checkout.html +19 -0
  32. invenio_app_ils/circulation/templates/invenio_app_ils_circulation/notifications/update_dates.html +19 -0
  33. invenio_app_ils/circulation/utils.py +23 -17
  34. invenio_app_ils/circulation/views.py +103 -39
  35. invenio_app_ils/cli.py +220 -260
  36. invenio_app_ils/closures/api.py +72 -7
  37. invenio_app_ils/closures/serializers/__init__.py +16 -0
  38. invenio_app_ils/closures/serializers/response.py +35 -0
  39. invenio_app_ils/closures/serializers/schema.py +28 -0
  40. invenio_app_ils/closures/tasks.py +4 -11
  41. invenio_app_ils/closures/views.py +66 -0
  42. invenio_app_ils/config.py +207 -150
  43. invenio_app_ils/document_requests/api.py +6 -21
  44. invenio_app_ils/document_requests/loaders/__init__.py +4 -12
  45. invenio_app_ils/document_requests/mappings/{v6 → os-v1}/__init__.py +2 -2
  46. invenio_app_ils/document_requests/mappings/os-v1/document_requests/document_request-v1.0.0.json +196 -0
  47. invenio_app_ils/document_requests/mappings/os-v2/__init__.py +8 -0
  48. invenio_app_ils/document_requests/mappings/os-v2/document_requests/document_request-v1.0.0.json +196 -0
  49. invenio_app_ils/document_requests/notifications/api.py +2 -7
  50. invenio_app_ils/document_requests/notifications/messages.py +3 -7
  51. invenio_app_ils/document_requests/search.py +2 -6
  52. invenio_app_ils/document_requests/views.py +4 -10
  53. invenio_app_ils/documents/api.py +19 -25
  54. invenio_app_ils/documents/indexer.py +13 -20
  55. invenio_app_ils/documents/jsonresolvers/document_circulation.py +11 -33
  56. invenio_app_ils/documents/jsonresolvers/document_eitem.py +1 -0
  57. invenio_app_ils/documents/jsonresolvers/document_item.py +8 -9
  58. invenio_app_ils/documents/jsonresolvers/document_stock.py +7 -7
  59. invenio_app_ils/documents/loaders/jsonschemas/document.py +3 -14
  60. invenio_app_ils/documents/mappings/{v6 → os-v1}/__init__.py +1 -1
  61. invenio_app_ils/documents/mappings/os-v1/documents/document-v1.0.0.json +932 -0
  62. invenio_app_ils/documents/mappings/os-v1/documents/document-v2.0.0.json +1066 -0
  63. invenio_app_ils/documents/mappings/os-v2/__init__.py +8 -0
  64. invenio_app_ils/documents/mappings/os-v2/documents/document-v1.0.0.json +932 -0
  65. invenio_app_ils/documents/mappings/os-v2/documents/document-v2.0.0.json +1066 -0
  66. invenio_app_ils/documents/mappings/v7/documents/document-v1.0.0.json +102 -11
  67. invenio_app_ils/documents/mappings/v7/documents/document-v2.0.0.json +1066 -0
  68. invenio_app_ils/documents/schemas/documents/document-v2.0.0.json +732 -0
  69. invenio_app_ils/eitems/api.py +41 -7
  70. invenio_app_ils/eitems/loaders/jsonschemas/eitems.py +6 -6
  71. invenio_app_ils/eitems/mappings/{v6 → os-v1}/__init__.py +1 -1
  72. invenio_app_ils/eitems/mappings/os-v1/eitems/eitem-v1.0.0.json +139 -0
  73. invenio_app_ils/eitems/mappings/os-v1/eitems/eitem-v2.0.0.json +142 -0
  74. invenio_app_ils/eitems/mappings/os-v1/eitems/eitem-v3.0.0.json +179 -0
  75. invenio_app_ils/{series/mappings/v6 → eitems/mappings/os-v2}/__init__.py +1 -1
  76. invenio_app_ils/eitems/mappings/os-v2/eitems/eitem-v1.0.0.json +139 -0
  77. invenio_app_ils/eitems/mappings/os-v2/eitems/eitem-v2.0.0.json +142 -0
  78. invenio_app_ils/eitems/mappings/os-v2/eitems/eitem-v3.0.0.json +179 -0
  79. invenio_app_ils/eitems/mappings/v7/eitems/eitem-v1.0.0.json +12 -2
  80. invenio_app_ils/eitems/mappings/v7/eitems/eitem-v2.0.0.json +142 -0
  81. invenio_app_ils/eitems/mappings/v7/eitems/eitem-v3.0.0.json +179 -0
  82. invenio_app_ils/eitems/schemas/eitems/eitem-v2.0.0.json +120 -0
  83. invenio_app_ils/eitems/schemas/eitems/eitem-v3.0.0.json +120 -0
  84. invenio_app_ils/eitems/search.py +3 -9
  85. invenio_app_ils/errors.py +119 -6
  86. invenio_app_ils/ext.py +15 -18
  87. invenio_app_ils/facets.py +13 -15
  88. invenio_app_ils/files/receivers.py +1 -1
  89. invenio_app_ils/files/views.py +1 -2
  90. invenio_app_ils/ill/api.py +1 -2
  91. invenio_app_ils/ill/config.py +10 -16
  92. invenio_app_ils/ill/jsonresolvers/borrowing_request_document.py +2 -3
  93. invenio_app_ils/ill/jsonresolvers/borrowing_request_patron.py +1 -3
  94. invenio_app_ils/ill/jsonresolvers/borrowing_request_provider.py +1 -3
  95. invenio_app_ils/ill/loaders/__init__.py +3 -9
  96. invenio_app_ils/ill/loaders/jsonschemas/patron_loan_actions.py +1 -8
  97. invenio_app_ils/ill/loaders/jsonschemas/patron_loan_extension_actions.py +3 -8
  98. invenio_app_ils/ill/mappings/{v6 → os-v1}/__init__.py +1 -1
  99. invenio_app_ils/ill/mappings/os-v1/ill_borrowing_requests/borrowing_request-v1.0.0.json +254 -0
  100. invenio_app_ils/{acquisition/mappings/v6 → ill/mappings/os-v2}/__init__.py +1 -1
  101. invenio_app_ils/ill/mappings/os-v2/ill_borrowing_requests/borrowing_request-v1.0.0.json +254 -0
  102. invenio_app_ils/ill/mappings/v7/ill_borrowing_requests/borrowing_request-v1.0.0.json +14 -0
  103. invenio_app_ils/ill/notifications/api.py +1 -4
  104. invenio_app_ils/ill/search.py +3 -9
  105. invenio_app_ils/ill/serializers/__init__.py +1 -3
  106. invenio_app_ils/ill/views.py +2 -4
  107. invenio_app_ils/internal_locations/api.py +1 -4
  108. invenio_app_ils/internal_locations/mappings/{v6 → os-v1}/__init__.py +1 -1
  109. invenio_app_ils/internal_locations/mappings/os-v1/internal_locations/internal_location-v1.0.0.json +108 -0
  110. invenio_app_ils/internal_locations/mappings/os-v2/__init__.py +8 -0
  111. invenio_app_ils/internal_locations/mappings/os-v2/internal_locations/internal_location-v1.0.0.json +108 -0
  112. invenio_app_ils/internal_locations/search.py +1 -3
  113. invenio_app_ils/items/api.py +18 -15
  114. invenio_app_ils/items/indexer.py +1 -3
  115. invenio_app_ils/items/jsonresolvers/item_document.py +1 -1
  116. invenio_app_ils/items/jsonresolvers/item_internal_location.py +2 -6
  117. invenio_app_ils/items/loaders/jsonschemas/items.py +2 -0
  118. {tests/api/circulation → invenio_app_ils/items/mappings/os-v1}/__init__.py +1 -1
  119. invenio_app_ils/items/mappings/os-v1/items/item-v1.0.0.json +285 -0
  120. invenio_app_ils/items/mappings/os-v1/items/item-v2.0.0.json +326 -0
  121. {tests/api/ill → invenio_app_ils/items/mappings/os-v2}/__init__.py +1 -1
  122. invenio_app_ils/items/mappings/os-v2/items/item-v1.0.0.json +285 -0
  123. invenio_app_ils/items/mappings/os-v2/items/item-v2.0.0.json +326 -0
  124. invenio_app_ils/items/mappings/v7/items/item-v1.0.0.json +11 -0
  125. invenio_app_ils/items/mappings/v7/items/item-v2.0.0.json +326 -0
  126. invenio_app_ils/items/schemas/items/item-v1.0.0.json +22 -0
  127. invenio_app_ils/items/schemas/items/item-v2.0.0.json +172 -0
  128. invenio_app_ils/items/search.py +18 -11
  129. invenio_app_ils/items/serializers/item.py +7 -6
  130. invenio_app_ils/literature/api.py +1 -3
  131. invenio_app_ils/literature/search.py +3 -5
  132. invenio_app_ils/literature/serializers/csv.py +1 -3
  133. invenio_app_ils/literature/serializers/json.py +1 -3
  134. invenio_app_ils/locations/api.py +2 -4
  135. invenio_app_ils/locations/indexer.py +3 -9
  136. invenio_app_ils/locations/loaders/__init__.py +1 -3
  137. invenio_app_ils/locations/loaders/jsonschemas/location.py +4 -11
  138. invenio_app_ils/locations/mappings/{v6 → os-v1}/__init__.py +1 -1
  139. invenio_app_ils/locations/mappings/os-v1/locations/location-v1.0.0.json +90 -0
  140. invenio_app_ils/locations/mappings/os-v2/__init__.py +8 -0
  141. invenio_app_ils/locations/mappings/os-v2/locations/location-v1.0.0.json +90 -0
  142. invenio_app_ils/notifications/messages.py +4 -3
  143. invenio_app_ils/notifications/tasks.py +1 -3
  144. invenio_app_ils/notifications/views.py +2 -2
  145. invenio_app_ils/patrons/anonymization.py +53 -32
  146. invenio_app_ils/patrons/api.py +3 -5
  147. invenio_app_ils/patrons/cli.py +1 -2
  148. invenio_app_ils/patrons/indexer.py +4 -13
  149. invenio_app_ils/patrons/mappings/os-v1/__init__.py +8 -0
  150. invenio_app_ils/patrons/mappings/os-v1/patrons/patron-v1.0.0.json +42 -0
  151. invenio_app_ils/patrons/mappings/os-v2/__init__.py +8 -0
  152. invenio_app_ils/patrons/mappings/os-v2/patrons/patron-v1.0.0.json +42 -0
  153. invenio_app_ils/patrons/views.py +4 -14
  154. invenio_app_ils/permissions.py +93 -35
  155. invenio_app_ils/providers/api.py +2 -6
  156. invenio_app_ils/providers/config.py +11 -19
  157. invenio_app_ils/providers/indexer.py +2 -6
  158. invenio_app_ils/providers/mappings/{v6 → os-v1}/__init__.py +1 -1
  159. invenio_app_ils/providers/mappings/os-v1/providers/provider-v1.0.0.json +57 -0
  160. invenio_app_ils/providers/mappings/os-v2/__init__.py +8 -0
  161. invenio_app_ils/providers/mappings/os-v2/providers/provider-v1.0.0.json +57 -0
  162. invenio_app_ils/providers/mappings/v7/__init__.py +1 -1
  163. invenio_app_ils/providers/proxies.py +1 -3
  164. invenio_app_ils/records/api.py +3 -9
  165. invenio_app_ils/records/loaders/schemas/changed_by.py +1 -3
  166. invenio_app_ils/records/loaders/schemas/identifiers.py +23 -0
  167. invenio_app_ils/records/metadata_extensions.py +1 -4
  168. invenio_app_ils/records/permissions.py +8 -2
  169. invenio_app_ils/records/serializers/__init__.py +1 -4
  170. invenio_app_ils/records/views.py +4 -7
  171. invenio_app_ils/records_relations/api.py +11 -34
  172. invenio_app_ils/records_relations/indexer.py +1 -3
  173. invenio_app_ils/records_relations/retriever.py +14 -9
  174. invenio_app_ils/records_relations/views.py +16 -50
  175. invenio_app_ils/relations/api.py +17 -16
  176. invenio_app_ils/search_permissions.py +24 -24
  177. invenio_app_ils/series/api.py +10 -12
  178. invenio_app_ils/series/loaders/jsonschemas/series.py +3 -2
  179. invenio_app_ils/{items/mappings/v6 → series/mappings/os-v1}/__init__.py +1 -1
  180. invenio_app_ils/series/mappings/os-v1/series/series-v1.0.0.json +324 -0
  181. invenio_app_ils/series/mappings/os-v1/series/series-v2.0.0.json +396 -0
  182. {tests/api/acquisition → invenio_app_ils/series/mappings/os-v2}/__init__.py +1 -1
  183. invenio_app_ils/series/mappings/os-v2/series/series-v1.0.0.json +324 -0
  184. invenio_app_ils/series/mappings/os-v2/series/series-v2.0.0.json +396 -0
  185. invenio_app_ils/series/mappings/v7/series/series-v1.0.0.json +35 -3
  186. invenio_app_ils/series/mappings/v7/series/series-v2.0.0.json +396 -0
  187. invenio_app_ils/series/schemas/series/series-v2.0.0.json +354 -0
  188. invenio_app_ils/stats/aggregations/aggr_file_download/os-v1/aggr-file-download-v1.json +60 -0
  189. invenio_app_ils/stats/aggregations/aggr_file_download/os-v2/__init__.py +9 -0
  190. invenio_app_ils/stats/aggregations/aggr_file_download/os-v2/aggr-file-download-v1.json +60 -0
  191. invenio_app_ils/stats/event_builders.py +73 -0
  192. invenio_app_ils/stats/file_download/os-v1/file-download-v1.json +72 -0
  193. invenio_app_ils/stats/file_download/os-v2/__init__.py +9 -0
  194. invenio_app_ils/stats/file_download/os-v2/file-download-v1.json +72 -0
  195. invenio_app_ils/stats/processors.py +30 -0
  196. invenio_app_ils/stats/templates/aggregations/__init__.py +8 -0
  197. invenio_app_ils/stats/templates/aggregations/ils_record_changes/__init__.py +8 -0
  198. invenio_app_ils/stats/templates/aggregations/ils_record_changes/os-v2/__init__.py +8 -0
  199. invenio_app_ils/stats/templates/aggregations/ils_record_changes/os-v2/aggr-ils-record-changes-v1.json +41 -0
  200. {tests → invenio_app_ils/stats/templates/events}/__init__.py +2 -2
  201. invenio_app_ils/stats/templates/events/ils_record_changes/__init__.py +8 -0
  202. invenio_app_ils/stats/templates/events/ils_record_changes/os-v2/__init__.py +8 -0
  203. invenio_app_ils/stats/templates/events/ils_record_changes/os-v2/ils-record-changes-v1.json +41 -0
  204. invenio_app_ils/templates/logged_out.html +12 -0
  205. invenio_app_ils/views.py +18 -4
  206. invenio_app_ils/vocabularies/api.py +1 -1
  207. invenio_app_ils/vocabularies/cli.py +6 -18
  208. invenio_app_ils/vocabularies/data/acq_order_line_payment_modes.json +5 -0
  209. invenio_app_ils/vocabularies/data/identifier_schemes.json +5 -0
  210. invenio_app_ils/vocabularies/indexer.py +1 -4
  211. invenio_app_ils/vocabularies/jsonresolvers/licenses.py +2 -11
  212. invenio_app_ils/vocabularies/mappings/os-v1/__init__.py +8 -0
  213. invenio_app_ils/vocabularies/mappings/os-v1/vocabularies/vocabulary-v1.0.0.json +23 -0
  214. invenio_app_ils/vocabularies/mappings/os-v2/__init__.py +8 -0
  215. invenio_app_ils/vocabularies/mappings/os-v2/vocabularies/vocabulary-v1.0.0.json +23 -0
  216. invenio_app_ils/vocabularies/sources/base.py +1 -3
  217. invenio_app_ils/webpack.py +27 -0
  218. invenio_app_ils-6.1.0.dist-info/METADATA +627 -0
  219. {invenio_app_ils-1.0.0a54.dist-info → invenio_app_ils-6.1.0.dist-info}/RECORD +227 -249
  220. {invenio_app_ils-1.0.0a54.dist-info → invenio_app_ils-6.1.0.dist-info}/WHEEL +1 -1
  221. {invenio_app_ils-1.0.0a54.dist-info → invenio_app_ils-6.1.0.dist-info}/entry_points.txt +9 -5
  222. {invenio_app_ils-1.0.0a54.dist-info → invenio_app_ils-6.1.0.dist-info}/top_level.txt +0 -1
  223. invenio_app_ils/acquisition/mappings/v6/acq_orders/order-v1.0.0.json +0 -352
  224. invenio_app_ils/document_requests/mappings/v6/document_requests/document_request-v1.0.0.json +0 -199
  225. invenio_app_ils/documents/mappings/v6/documents/document-v1.0.0.json +0 -843
  226. invenio_app_ils/eitems/mappings/v6/eitems/eitem-v1.0.0.json +0 -131
  227. invenio_app_ils/ill/mappings/v6/ill_borrowing_requests/borrowing_request-v1.0.0.json +0 -242
  228. invenio_app_ils/internal_locations/mappings/v6/internal_locations/internal_location-v1.0.0.json +0 -110
  229. invenio_app_ils/items/mappings/v6/items/item-v1.0.0.json +0 -276
  230. invenio_app_ils/locations/mappings/v6/locations/location-v1.0.0.json +0 -92
  231. invenio_app_ils/notifications/admin.py +0 -57
  232. invenio_app_ils/patrons/mappings/v6/__init__.py +0 -8
  233. invenio_app_ils/patrons/mappings/v6/patrons/patron-v1.0.0.json +0 -44
  234. invenio_app_ils/providers/mappings/v6/providers/provider-v1.0.0.json +0 -59
  235. invenio_app_ils/series/mappings/v6/series/series-v1.0.0.json +0 -298
  236. invenio_app_ils/stats/aggregations/aggr_file_download/v6/aggr-file-download-v1.json +0 -59
  237. invenio_app_ils/stats/file_download/v6/file-download-v1.json +0 -74
  238. invenio_app_ils/version.py +0 -14
  239. invenio_app_ils/vocabularies/mappings/v6/__init__.py +0 -8
  240. invenio_app_ils/vocabularies/mappings/v6/vocabularies/vocabulary-v1.0.0.json +0 -25
  241. invenio_app_ils-1.0.0a54.dist-info/METADATA +0 -95
  242. tests/api/__init__.py +0 -8
  243. tests/api/acquisition/test_acq_orders_crud.py +0 -102
  244. tests/api/acquisition/test_acq_orders_permissions.py +0 -104
  245. tests/api/acquisition/test_acq_providers_permissions.py +0 -83
  246. tests/api/circulation/test_expired_loans.py +0 -88
  247. tests/api/circulation/test_loan_checkout.py +0 -216
  248. tests/api/circulation/test_loan_default_durations.py +0 -57
  249. tests/api/circulation/test_loan_document_resolver.py +0 -18
  250. tests/api/circulation/test_loan_extend.py +0 -132
  251. tests/api/circulation/test_loan_item_permissions.py +0 -139
  252. tests/api/circulation/test_loan_item_resolver.py +0 -26
  253. tests/api/circulation/test_loan_list_permissions.py +0 -104
  254. tests/api/circulation/test_loan_patron_resolver.py +0 -38
  255. tests/api/circulation/test_loan_request.py +0 -234
  256. tests/api/circulation/test_loan_update.py +0 -150
  257. tests/api/circulation/test_notifications.py +0 -229
  258. tests/api/conftest.py +0 -236
  259. tests/api/document_requests/__init__.py +0 -8
  260. tests/api/document_requests/test_document_requests.py +0 -131
  261. tests/api/document_requests/test_document_requests_permissions.py +0 -177
  262. tests/api/document_requests/test_notifications_filter.py +0 -36
  263. tests/api/ill/test_ill_brw_crud.py +0 -84
  264. tests/api/ill/test_ill_brw_reqs_patron_loan_create_action.py +0 -207
  265. tests/api/ill/test_ill_brw_reqs_patron_loan_extension_actions.py +0 -298
  266. tests/api/ill/test_ill_brw_reqs_permissions.py +0 -169
  267. tests/api/ill/test_ill_providers_permissions.py +0 -82
  268. tests/api/ils/__init__.py +0 -8
  269. tests/api/ils/documents/__init__.py +0 -8
  270. tests/api/ils/documents/test_document_crud.py +0 -57
  271. tests/api/ils/documents/test_document_permissions.py +0 -106
  272. tests/api/ils/documents/test_document_resolvers.py +0 -35
  273. tests/api/ils/eitems/__init__.py +0 -8
  274. tests/api/ils/eitems/test_eitems_crud.py +0 -41
  275. tests/api/ils/eitems/test_eitems_permissions.py +0 -84
  276. tests/api/ils/eitems/test_files.py +0 -172
  277. tests/api/ils/items/__init__.py +0 -8
  278. tests/api/ils/items/test_apis.py +0 -43
  279. tests/api/ils/items/test_items_crud.py +0 -60
  280. tests/api/ils/items/test_items_permissions.py +0 -107
  281. tests/api/ils/items/test_items_update.py +0 -47
  282. tests/api/ils/records_relations/__init__.py +0 -8
  283. tests/api/ils/records_relations/helpers.py +0 -115
  284. tests/api/ils/records_relations/test_records_relations_parentchild.py +0 -560
  285. tests/api/ils/records_relations/test_records_relations_sequence.py +0 -302
  286. tests/api/ils/records_relations/test_records_relations_siblings.py +0 -678
  287. tests/api/ils/series/__init__.py +0 -8
  288. tests/api/ils/series/test_series_permissions.py +0 -95
  289. tests/api/ils/test_anonymization.py +0 -189
  290. tests/api/ils/test_apis.py +0 -76
  291. tests/api/ils/test_closures.py +0 -324
  292. tests/api/ils/test_errors.py +0 -126
  293. tests/api/ils/test_facets.py +0 -84
  294. tests/api/ils/test_internal_locations.py +0 -96
  295. tests/api/ils/test_loaders.py +0 -55
  296. tests/api/ils/test_metadata_extensions.py +0 -205
  297. tests/api/ils/test_notifications.py +0 -183
  298. tests/api/ils/test_notifications_mails.py +0 -39
  299. tests/api/ils/test_notifications_permissions.py +0 -55
  300. tests/api/ils/test_patrons.py +0 -106
  301. tests/api/ils/test_record_delete.py +0 -46
  302. tests/api/ils/test_record_permissions.py +0 -135
  303. tests/api/ils/test_resolvers.py +0 -207
  304. tests/api/ils/test_stats.py +0 -160
  305. tests/api/ils/test_tasks.py +0 -211
  306. tests/api/ils/test_vocabularies.py +0 -35
  307. tests/conftest.py +0 -123
  308. tests/data/acq_orders.json +0 -89
  309. tests/data/acq_providers.json +0 -12
  310. tests/data/document_requests.json +0 -77
  311. tests/data/documents.json +0 -237
  312. tests/data/eitems.json +0 -66
  313. tests/data/ill_borrowing_requests.json +0 -77
  314. tests/data/ill_providers.json +0 -12
  315. tests/data/internal_locations.json +0 -22
  316. tests/data/items.json +0 -271
  317. tests/data/loans.json +0 -133
  318. tests/data/loans_most_loaned.json +0 -128
  319. tests/data/locations.json +0 -20
  320. tests/data/series.json +0 -33
  321. tests/helpers.py +0 -104
  322. tests/templates/notifications/title_body.html +0 -8
  323. tests/templates/notifications/title_body_html.html +0 -13
  324. tests/templates/notifications/title_body_html_ctx.html +0 -13
  325. tests/templates/notifications/title_only.html +0 -3
  326. tests/test_version.py +0 -17
  327. /tests/templates/notifications/blank.html → /invenio_app_ils/acquisition/mappings/os-v1/__init__.py +0 -0
  328. /invenio_app_ils/stats/aggregations/aggr_file_download/{v6 → os-v1}/__init__.py +0 -0
  329. /invenio_app_ils/stats/file_download/{v6 → os-v1}/__init__.py +0 -0
  330. {invenio_app_ils-1.0.0a54.dist-info → invenio_app_ils-6.1.0.dist-info/licenses}/AUTHORS.rst +0 -0
  331. {invenio_app_ils-1.0.0a54.dist-info → invenio_app_ils-6.1.0.dist-info/licenses}/LICENSE +0 -0
@@ -1,126 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2018-2020 CERN.
4
- #
5
- # invenio-app-ils is free software; you can redistribute it and/or modify it
6
- # under the terms of the MIT License; see LICENSE file for more details.
7
-
8
- """Test errors."""
9
-
10
- import pytest
11
-
12
- from invenio_app_ils.errors import (
13
- ItemHasActiveLoanError,
14
- NotImplementedConfigurationError,
15
- PatronHasLoanOnItemError,
16
- PatronNotFoundError,
17
- RecordHasReferencesError,
18
- SearchQueryError,
19
- UnauthorizedSearchError,
20
- )
21
-
22
-
23
- def test_unauthorized_search_with_patron_pid(app):
24
- """Test UnauthorizedSearchError with patron_pid defined."""
25
- query = "test query"
26
- pid = "1"
27
- msg = "Search '{query}' not allowed by 'patron_pid:{patron_pid}'"
28
- with pytest.raises(UnauthorizedSearchError) as ex:
29
- raise UnauthorizedSearchError(query=query, patron_pid=pid)
30
- assert ex.value.code == 403
31
- assert ex.value.description == msg.format(query=query, patron_pid=pid)
32
-
33
-
34
- def test_unauthorized_search_without_patron_pid(app):
35
- """Test UnauthorizedSearchError without patron_pid defined."""
36
- query = "test query"
37
- msg = "Search '{query}' not allowed by 'patron_pid:None'"
38
- with pytest.raises(UnauthorizedSearchError) as ex:
39
- raise UnauthorizedSearchError(query=query)
40
- assert ex.value.code == 401
41
- assert ex.value.description == msg.format(query=query)
42
-
43
-
44
- def test_invalid_search_query(app):
45
- """Test SearchQueryError."""
46
- query = "invalid query"
47
- msg = "Invalid query syntax: '{query}'"
48
- with pytest.raises(SearchQueryError) as ex:
49
- raise SearchQueryError(query=query)
50
- assert ex.value.code == SearchQueryError.code
51
- assert ex.value.description == msg.format(query=query)
52
-
53
-
54
- def test_not_implemented(app):
55
- """Test NotImplementedConfigurationError."""
56
- config_variable = "CONFIG_VAR"
57
- msg = (
58
- "Function is not implemented. Implement this function in your module "
59
- "and pass it to the config variable '{}'".format(config_variable)
60
- )
61
- with pytest.raises(NotImplementedConfigurationError) as ex:
62
- raise NotImplementedConfigurationError(config_variable="CONFIG_VAR")
63
- assert ex.value.code == NotImplementedConfigurationError.code
64
- assert ex.value.description == msg
65
-
66
-
67
- def test_patron_not_found(app):
68
- """Test PatronNotFoundError."""
69
- patron_pid = "1"
70
- msg = "Patron with ID '{patron_pid}' was not found."
71
- with pytest.raises(PatronNotFoundError) as ex:
72
- raise PatronNotFoundError(patron_pid)
73
- assert ex.value.code == PatronNotFoundError.code
74
- assert ex.value.description == msg.format(patron_pid=patron_pid)
75
-
76
-
77
- def test_patron_has_loan_on_item(app):
78
- """Test PatronHasLoanOnItemError."""
79
- patron_pid = "1"
80
- item_pid = dict(type="pitmid", value="2")
81
- msg = "Patron '{0}' has already an active loan on item '{1}:{2}'"
82
- with pytest.raises(PatronHasLoanOnItemError) as ex:
83
- raise PatronHasLoanOnItemError(patron_pid, item_pid)
84
- assert ex.value.code == PatronHasLoanOnItemError.code
85
- assert ex.value.description == msg.format(
86
- patron_pid, item_pid["type"], item_pid["value"]
87
- )
88
-
89
-
90
- def test_record_has_references_error(app):
91
- """Test RecordHasReferencesError."""
92
- record_type = "Item"
93
- record_id = "item-1"
94
- ref_type = "RecordType"
95
- ref_ids = ["1", "2", "3"]
96
- msg = (
97
- "Cannot delete the {record_type} {record_id} record because it has "
98
- "references from {ref_type} records with ids: {ref_ids}."
99
- ).format(
100
- record_type=record_type,
101
- record_id=record_id,
102
- ref_type=ref_type,
103
- ref_ids=ref_ids,
104
- )
105
-
106
- with pytest.raises(RecordHasReferencesError) as ex:
107
- raise RecordHasReferencesError(
108
- record_type=record_type,
109
- record_id=record_id,
110
- ref_type=ref_type,
111
- ref_ids=ref_ids,
112
- )
113
- assert ex.value.code == RecordHasReferencesError.code
114
- assert ex.value.description == msg
115
-
116
-
117
- def test_item_has_active_loan_error(app):
118
- loan_pid = "1"
119
- msg = (
120
- "Could not update item because it has an active loan with "
121
- "pid: {loan_pid}."
122
- ).format(loan_pid=loan_pid)
123
- with pytest.raises(ItemHasActiveLoanError) as ex:
124
- raise ItemHasActiveLoanError(loan_pid=loan_pid)
125
- assert ex.value.code == ItemHasActiveLoanError.code
126
- assert ex.value.description == msg
@@ -1,84 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2018 CERN.
4
- #
5
- # invenio-app-ils is free software; you can redistribute it and/or modify it
6
- # under the terms of the MIT License; see LICENSE file for more details.
7
-
8
- """Facets tests."""
9
-
10
- from datetime import timedelta
11
-
12
- import arrow
13
- import pytest
14
- from elasticsearch_dsl.query import Bool, Q, Range, Terms
15
- from flask import current_app
16
-
17
- from invenio_app_ils.facets import (
18
- date_range_filter,
19
- default_value_when_missing_filter,
20
- keyed_range_filter,
21
- overdue_loans_filter,
22
- )
23
-
24
-
25
- def test_keyed_range_filter():
26
- """Test range filter."""
27
- range_query = {"None": {"lt": 1}, "1+": {"gte": 1}}
28
- rfilter = keyed_range_filter("field", range_query)
29
-
30
- assert rfilter(["None"]) == Range(field={"lt": 1})
31
- assert rfilter(["1+"]) == Range(field={"gte": 1})
32
- assert rfilter(["None", "1+"]) == Range(field={"gte": 1, "lt": 1})
33
-
34
-
35
- def test_current_ranged_loans_filter(app):
36
- """Test ranged current loans filter."""
37
- with app.app_context():
38
- rfilter = overdue_loans_filter("field")
39
-
40
- current_loans_query = Terms(
41
- state=current_app.config["CIRCULATION_STATES_LOAN_ACTIVE"]
42
- )
43
-
44
- overdue = rfilter(["Overdue"])
45
- field = {"lt": str(arrow.utcnow().date())}
46
- assert overdue == Range(field=field) & current_loans_query
47
-
48
- upcoming = rfilter(["Upcoming return"])
49
- field = {
50
- "gte": str(arrow.utcnow().date()),
51
- "lte": str((arrow.utcnow() + timedelta(days=7)).date()),
52
- }
53
- assert upcoming == Range(field=field) & current_loans_query
54
-
55
-
56
- def test_default_value_when_missing_filter(app):
57
- """Test custom exists filter."""
58
- with app.app_context():
59
- rfilter = default_value_when_missing_filter("field", "missing val")
60
-
61
- assert rfilter("test") == Terms(field="test")
62
- assert rfilter("missing val") == Bool(
63
- **{"must_not": {"exists": {"field": "field"}}}
64
- )
65
-
66
-
67
- def test_date_range_filter(app):
68
- """Test date range filter date validation and query."""
69
-
70
- tests = ["", "a string", "2020-02-02"]
71
-
72
- for input_date in tests:
73
- from_filter = date_range_filter("field", "gte")
74
- to_filter = date_range_filter("field", "lte")
75
-
76
- try:
77
- assert from_filter([input_date]) == Range(
78
- field={"gte": input_date}
79
- )
80
- assert to_filter([input_date]) == Range(field={"lte": input_date})
81
- except (ValueError, AssertionError):
82
- with pytest.raises(ValueError):
83
- from_filter([input_date])
84
- to_filter([input_date])
@@ -1,96 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2018-2021 CERN.
4
- #
5
- # invenio-app-ils is free software; you can redistribute it and/or modify it
6
- # under the terms of the MIT License; see LICENSE file for more details.
7
-
8
- """Test internal locations."""
9
-
10
- import json
11
-
12
- import pytest
13
- from flask import url_for
14
-
15
- from invenio_app_ils.errors import LocationNotFoundError
16
- from invenio_app_ils.internal_locations.api import InternalLocation
17
- from tests.helpers import user_login
18
-
19
- _HTTP_OK = [200, 201, 204]
20
- _INTERNAL_LOCATION_PID = "ilocid-1"
21
- _INTERNAL_LOCATION_NAME = "A location"
22
- _ITEM_ENDPOINT = "invenio_records_rest.ilocid_item"
23
- _LIST_ENDPOINT = "invenio_records_rest.ilocid_list"
24
-
25
-
26
- def test_internal_locations_validation(db, testdata):
27
- """Test validation when updating an Internal Location."""
28
- intloc_pid = testdata["internal_locations"][0]["pid"]
29
- intloc = InternalLocation.get_record_by_pid(intloc_pid)
30
-
31
- intloc["location_pid"] = "not_found_pid"
32
- with pytest.raises(LocationNotFoundError):
33
- intloc.commit()
34
-
35
-
36
- def test_internal_locations_permissions(client, testdata, json_headers, users):
37
- """Test internal locations endpoints permissions."""
38
- dummy_internal_location = dict(
39
- location_pid=testdata["locations"][0]["pid"],
40
- name=_INTERNAL_LOCATION_NAME,
41
- )
42
- tests = [
43
- ("admin", _HTTP_OK, dummy_internal_location),
44
- ("librarian", _HTTP_OK, dummy_internal_location),
45
- ("patron1", [403], dummy_internal_location),
46
- ("anonymous", [401], dummy_internal_location),
47
- ]
48
-
49
- def _test_list(expected_status):
50
- """Test get list."""
51
- url = url_for(_LIST_ENDPOINT)
52
- res = client.get(url, headers=json_headers)
53
- assert res.status_code in expected_status
54
-
55
- def _test_create(expected_status, data):
56
- """Test record creation."""
57
- url = url_for(_LIST_ENDPOINT)
58
- res = client.post(url, headers=json_headers, data=json.dumps(data))
59
- assert res.status_code in expected_status
60
-
61
- if res.status_code < 400:
62
- record = res.get_json()["metadata"]
63
- assert record["name"] == _INTERNAL_LOCATION_NAME
64
- return record["pid"]
65
-
66
- def _test_update(expected_status, data, pid):
67
- """Test record update."""
68
- pid_value = pid or _INTERNAL_LOCATION_PID
69
- url = url_for(_ITEM_ENDPOINT, pid_value=pid_value)
70
- res = client.put(url, headers=json_headers, data=json.dumps(data))
71
- assert res.status_code in expected_status
72
- if res.status_code < 400:
73
- record = res.get_json()["metadata"]
74
- assert record["name"] == _INTERNAL_LOCATION_NAME
75
-
76
- def _test_read(expected_status, pid):
77
- """Test record read."""
78
- pid_value = pid or _INTERNAL_LOCATION_PID
79
- url = url_for(_ITEM_ENDPOINT, pid_value=pid_value)
80
- res = client.get(url, headers=json_headers)
81
- assert res.status_code in expected_status
82
-
83
- def _test_delete(expected_status, pid):
84
- """Test record delete."""
85
- pid_value = pid or _INTERNAL_LOCATION_PID
86
- url = url_for(_ITEM_ENDPOINT, pid_value=pid_value)
87
- res = client.delete(url, headers=json_headers)
88
- assert res.status_code in expected_status
89
-
90
- for username, expected_status, data in tests:
91
- user_login(client, username, users)
92
- _test_list(expected_status)
93
- pid = _test_create(expected_status, data)
94
- _test_update(expected_status, data, pid)
95
- _test_read(expected_status, pid)
96
- _test_delete(expected_status, pid)
@@ -1,55 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2018 CERN.
4
- #
5
- # invenio-app-ils is free software; you can redistribute it and/or modify it
6
- # under the terms of the MIT License; see LICENSE file for more details.
7
-
8
- """Test accesibility of resource endpoints."""
9
-
10
- import json
11
-
12
- from flask import url_for
13
-
14
- from tests.helpers import user_login, validate_response
15
-
16
- NEW_INTERNAL_LOCATION = {
17
- "location_pid": "locid-1",
18
- "legacy_ids": ["Test legacy id"],
19
- "name": "My test internal location",
20
- "physical_location": "Left from the right building",
21
- "notes": "In house",
22
- }
23
-
24
-
25
- def test_post_internal_location(client, json_headers, testdata, users):
26
- """Test POST of internal_location."""
27
- user_login(client, "admin", users)
28
- url = url_for("invenio_records_rest.ilocid_list")
29
- res = validate_response(
30
- client, "post", url, json_headers, NEW_INTERNAL_LOCATION, 201
31
- )
32
- data = json.loads(res.data.decode("utf-8"))["metadata"]
33
- assert "name" in data["location"]
34
-
35
-
36
- def test_post_partial_internal_location(client, json_headers, testdata, users):
37
- """Test POST of internal_location without all required data."""
38
- user_login(client, "admin", users)
39
- del NEW_INTERNAL_LOCATION["location_pid"]
40
- url = url_for("invenio_records_rest.ilocid_list")
41
- validate_response(
42
- client, "post", url, json_headers, NEW_INTERNAL_LOCATION, 400
43
- )
44
-
45
-
46
- def test_post_item(client, json_headers, testdata, users, item_record):
47
- """Test POST of an item."""
48
- user_login(client, "admin", users)
49
- url = url_for("invenio_records_rest.pitmid_list")
50
- del item_record["pid"]
51
- res = validate_response(
52
- client, "post", url, json_headers, item_record, 201
53
- )
54
- data = json.loads(res.data.decode("utf-8"))["metadata"]
55
- assert "name" in data["internal_location"]
@@ -1,205 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2018-2020 CERN.
4
- #
5
- # invenio-app-ils is free software; you can redistribute it and/or modify it
6
- # under the terms of the MIT License; see LICENSE file for more details.
7
-
8
- """Test metadata extensions."""
9
-
10
- import pytest
11
- from invenio_indexer.api import RecordIndexer
12
- from invenio_records_rest.schemas.fields import DateString, SanitizedUnicode
13
- from marshmallow import ValidationError
14
- from marshmallow.fields import Bool, Integer, List
15
-
16
- from invenio_app_ils.records.metadata_extensions import MetadataExtensions
17
-
18
-
19
- @pytest.fixture(scope="module")
20
- def app_config(app_config):
21
- """Override conftest.py's app_config"""
22
- app_config["ILS_RECORDS_METADATA_NAMESPACES"] = {
23
- "document": {
24
- "accelerator_experiments": {
25
- "@context": "https://example.com/accelerator_experiments/terms"
26
- },
27
- "standard_status": {
28
- "@context": "https://example.com/standard_status/terms"
29
- },
30
- }
31
- }
32
-
33
- app_config["ILS_RECORDS_METADATA_EXTENSIONS"] = {
34
- "document": {
35
- "accelerator_experiments_accelerator": {
36
- "elasticsearch": "keyword",
37
- "marshmallow": SanitizedUnicode(required=True),
38
- },
39
- "accelerator_experiments_project": {
40
- "elasticsearch": "text",
41
- "marshmallow": SanitizedUnicode(),
42
- },
43
- "accelerator_experiments_number_in_sequence": {
44
- "elasticsearch": "long",
45
- "marshmallow": Integer(),
46
- },
47
- "accelerator_experiments_scientific_sequence": {
48
- "elasticsearch": "long",
49
- "marshmallow": List(Integer()),
50
- },
51
- "standard_status_original_presentation_date": {
52
- "elasticsearch": "date",
53
- "marshmallow": DateString(),
54
- },
55
- "standard_status_right_or_wrong": {
56
- "elasticsearch": "boolean",
57
- "marshmallow": Bool(),
58
- },
59
- }
60
- }
61
-
62
- return app_config
63
-
64
-
65
- def assert_unordered_equality(array_dict1, array_dict2):
66
- array1 = sorted(array_dict1, key=lambda d: d["key"])
67
- array2 = sorted(array_dict2, key=lambda d: d["key"])
68
- assert array1 == array2
69
-
70
-
71
- def test_metadata_extensions(db, es, testdata):
72
- """Tests that a Record is indexed into Elasticsearch properly.
73
- - Tests that the before_record_index_hook is registered properly.
74
- - Tests add_es_metadata_extensions.
75
- - Tests jsonschema validates correctly
76
- - Tests that retrieved record document is fine.
77
- NOTE:
78
- - es fixture depends on appctx fixture, so we are in app context
79
- - this test requires a running ES instance
80
- """
81
- document = testdata["documents"][0]
82
- data = {
83
- "extensions": {
84
- "accelerator_experiments_accelerator": "LHCb",
85
- "accelerator_experiments_project": "A project for experiment.",
86
- "accelerator_experiments_number_in_sequence": 3,
87
- "accelerator_experiments_scientific_sequence": [1, 1, 2, 3, 5, 8],
88
- "standard_status_original_presentation_date": "2019-02-14",
89
- "standard_status_right_or_wrong": True,
90
- }
91
- }
92
- document.update(data)
93
- document.validate()
94
- db.session.commit()
95
- indexer = RecordIndexer()
96
- index_result = indexer.index(document)
97
-
98
- _index = index_result["_index"]
99
- _doc = index_result["_type"]
100
- _id = index_result["_id"]
101
- es_doc = es.get(index=_index, doc_type=_doc, id=_id)
102
- source = es_doc["_source"]
103
- expected_keywords = [
104
- {"key": "accelerator_experiments_accelerator", "value": "LHCb"},
105
- ]
106
- expected_texts = [
107
- {
108
- "key": "accelerator_experiments_project",
109
- "value": "A project for experiment.",
110
- },
111
- ]
112
- expected_longs = [
113
- {"key": "accelerator_experiments_number_in_sequence", "value": 3},
114
- {
115
- "key": "accelerator_experiments_scientific_sequence",
116
- "value": [1, 1, 2, 3, 5, 8],
117
- },
118
- ]
119
- expected_dates = [
120
- {
121
- "key": "standard_status_original_presentation_date",
122
- "value": "2019-02-14",
123
- },
124
- ]
125
- expected_booleans = [
126
- {"key": "standard_status_right_or_wrong", "value": True},
127
- ]
128
- assert_unordered_equality(source["extensions_keywords"], expected_keywords)
129
- assert_unordered_equality(source["extensions_texts"], expected_texts)
130
- assert_unordered_equality(source["extensions_longs"], expected_longs)
131
- assert_unordered_equality(source["extensions_dates"], expected_dates)
132
- assert_unordered_equality(source["extensions_booleans"], expected_booleans)
133
-
134
-
135
- def test_extensions():
136
- """Test metadata extensions schema."""
137
- ILS_RECORDS_METADATA_NAMESPACES = {
138
- "accelerator_experiments": {
139
- "@context": "https://example.com/accelerator_experiments/terms"
140
- },
141
- "standard_status": {
142
- "@context": "https://example.com/standard_status/terms"
143
- },
144
- }
145
-
146
- ILS_RECORDS_METADATA_EXTENSIONS = {
147
- "accelerator_experiments_accelerator": {
148
- "elasticsearch": "keyword",
149
- "marshmallow": SanitizedUnicode(required=True),
150
- },
151
- "accelerator_experiments_project": {
152
- "elasticsearch": "text",
153
- "marshmallow": SanitizedUnicode(),
154
- },
155
- "accelerator_experiments_number_in_sequence": {
156
- "elasticsearch": "long",
157
- "marshmallow": Integer(),
158
- },
159
- "accelerator_experiments_scientific_sequence": {
160
- "elasticsearch": "long",
161
- "marshmallow": List(Integer()),
162
- },
163
- "standard_status_original_presentation_date": {
164
- "elasticsearch": "date",
165
- "marshmallow": DateString(),
166
- },
167
- "standard_status_right_or_wrong": {
168
- "elasticsearch": "boolean",
169
- "marshmallow": Bool(),
170
- },
171
- }
172
-
173
- extensions = MetadataExtensions(
174
- ILS_RECORDS_METADATA_NAMESPACES, ILS_RECORDS_METADATA_EXTENSIONS
175
- )
176
- ExtensionsSchema = extensions.to_schema()
177
-
178
- # Minimal if not absent
179
- valid_minimal = {"accelerator_experiments_accelerator": "LHCb"}
180
-
181
- data = ExtensionsSchema().load(valid_minimal)
182
-
183
- assert data == valid_minimal
184
-
185
- # Full
186
- valid_full = {
187
- "accelerator_experiments_accelerator": "LHCb",
188
- "accelerator_experiments_project": "A project for experiment.",
189
- "accelerator_experiments_number_in_sequence": 3,
190
- "accelerator_experiments_scientific_sequence": [1, 1, 2, 3, 5, 8],
191
- "standard_status_original_presentation_date": "2019-02-14",
192
- "standard_status_right_or_wrong": True,
193
- }
194
-
195
- data = ExtensionsSchema().load(valid_full)
196
-
197
- assert data == valid_full
198
-
199
- # Invalid
200
- invalid_number_in_sequence = {
201
- "accelerator_experiments_accelerator": "LHCb",
202
- "accelerator_experiments_scientific_sequence": [1, "l", 2, 3, 5, 8],
203
- }
204
- with pytest.raises(ValidationError):
205
- data = ExtensionsSchema().load(invalid_number_in_sequence)