django-spire 0.23.7__py3-none-any.whl → 0.23.9__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.
- django_spire/ai/admin.py +11 -11
- django_spire/ai/chat/apps.py +1 -0
- django_spire/ai/chat/templates/django_spire/ai/chat/widget/dialog_widget.html +1 -1
- django_spire/ai/chat/tests/factories.py +15 -0
- django_spire/ai/chat/tests/test_controller.py +45 -0
- django_spire/ai/chat/tests/test_models.py +301 -0
- django_spire/ai/chat/tests/test_prompts.py +48 -0
- django_spire/ai/chat/tests/test_responses.py +208 -0
- django_spire/ai/chat/tests/test_router/test_base_chat_router.py +66 -6
- django_spire/ai/chat/tests/test_router/test_chat_workflow.py +73 -3
- django_spire/ai/chat/tests/test_router/test_integration.py +86 -6
- django_spire/ai/chat/tests/test_router/test_intent_decoder.py +93 -1
- django_spire/ai/chat/tests/test_router/test_message_intel.py +60 -1
- django_spire/ai/chat/tests/test_router/test_spire_chat_router.py +110 -0
- django_spire/ai/chat/tests/test_urls/test_json_urls.py +202 -1
- django_spire/ai/context/tests/__init__.py +0 -0
- django_spire/ai/context/tests/test_context.py +188 -0
- django_spire/ai/decorators.py +7 -6
- django_spire/ai/prompt/tests/test_bots.py +100 -10
- django_spire/ai/prompt/tests/test_prompt_intel.py +83 -0
- django_spire/ai/prompt/tests/test_prompt_tuning.py +126 -0
- django_spire/ai/sms/decorators.py +8 -2
- django_spire/ai/sms/tests/test_sms.py +240 -16
- django_spire/ai/sms/tests/test_sms_intel.py +42 -0
- django_spire/ai/sms/tests/test_webhook.py +155 -7
- django_spire/ai/sms/views.py +23 -24
- django_spire/ai/tests/test_ai.py +131 -7
- django_spire/auth/apps.py +4 -2
- django_spire/auth/controller/controller.py +36 -23
- django_spire/auth/controller/exceptions.py +9 -0
- django_spire/auth/group/admin.py +1 -0
- django_spire/auth/group/apps.py +2 -0
- django_spire/auth/group/factories.py +17 -8
- django_spire/auth/group/forms.py +7 -0
- django_spire/auth/group/tests/test_factories.py +146 -0
- django_spire/auth/group/tests/test_forms.py +282 -0
- django_spire/auth/group/tests/test_models.py +192 -0
- django_spire/auth/group/tests/test_querysets.py +98 -0
- django_spire/auth/group/tests/test_utils.py +341 -0
- django_spire/auth/group/tests/test_views.py +377 -0
- django_spire/auth/group/urls/__init__.py +3 -1
- django_spire/auth/group/urls/form_urls.py +2 -0
- django_spire/auth/group/urls/json_urls.py +3 -0
- django_spire/auth/group/urls/page_urls.py +2 -0
- django_spire/auth/group/utils.py +6 -2
- django_spire/auth/group/views/form_views.py +6 -3
- django_spire/auth/group/views/json_views.py +6 -2
- django_spire/auth/mfa/admin.py +2 -0
- django_spire/auth/mfa/apps.py +2 -0
- django_spire/auth/mfa/forms.py +1 -0
- django_spire/auth/mfa/querysets.py +9 -2
- django_spire/auth/mfa/tests/test_models.py +233 -0
- django_spire/auth/mfa/tests/test_utils.py +106 -0
- django_spire/auth/mfa/urls/__init__.py +2 -0
- django_spire/auth/mfa/urls/page_urls.py +2 -0
- django_spire/auth/mfa/urls/redirect_urls.py +2 -0
- django_spire/auth/mfa/views/page_views.py +2 -1
- django_spire/auth/permissions/consts.py +2 -2
- django_spire/auth/permissions/decorators.py +8 -8
- django_spire/auth/permissions/permissions.py +28 -35
- django_spire/auth/permissions/tests/test_decorators.py +333 -0
- django_spire/auth/permissions/tests/test_permissions.py +337 -0
- django_spire/auth/permissions/tests/test_tools.py +305 -0
- django_spire/auth/permissions/tools.py +21 -15
- django_spire/auth/seeding/seed.py +3 -0
- django_spire/auth/seeding/seeder.py +2 -0
- django_spire/auth/tests/test_controller.py +323 -0
- django_spire/auth/tests/test_url_endpoints.py +9 -9
- django_spire/auth/tests/test_views.py +406 -0
- django_spire/auth/urls/admin_urls.py +2 -0
- django_spire/auth/urls/redirect_urls.py +2 -0
- django_spire/auth/user/apps.py +2 -0
- django_spire/auth/user/forms.py +9 -0
- django_spire/auth/user/models.py +1 -1
- django_spire/auth/user/services/services.py +1 -0
- django_spire/auth/user/tests/factories.py +14 -13
- django_spire/auth/user/tests/test_factories.py +166 -2
- django_spire/auth/user/tests/test_forms.py +573 -0
- django_spire/auth/user/tests/test_models.py +257 -0
- django_spire/auth/user/tests/test_services.py +200 -0
- django_spire/auth/user/tests/test_tools.py +153 -0
- django_spire/auth/user/tests/test_user_factories.py +139 -0
- django_spire/auth/user/tests/test_views.py +363 -0
- django_spire/auth/user/tools.py +7 -1
- django_spire/auth/user/urls/form_urls.py +3 -0
- django_spire/auth/user/urls/page_urls.py +3 -0
- django_spire/auth/user/views/form_views.py +19 -10
- django_spire/auth/user/views/page_views.py +8 -2
- django_spire/auth/views/redirect_views.py +14 -9
- django_spire/comment/admin.py +2 -0
- django_spire/comment/apps.py +2 -0
- django_spire/comment/templatetags/comment_tags.py +1 -0
- django_spire/comment/tests/test_forms.py +27 -0
- django_spire/comment/tests/test_models.py +215 -0
- django_spire/comment/tests/test_querysets.py +101 -0
- django_spire/comment/tests/test_utils.py +90 -0
- django_spire/comment/urls.py +2 -0
- django_spire/comment/utils.py +22 -13
- django_spire/comment/views.py +1 -1
- django_spire/conf.py +8 -6
- django_spire/consts.py +1 -1
- django_spire/contrib/breadcrumb/apps.py +2 -0
- django_spire/contrib/breadcrumb/breadcrumbs.py +18 -18
- django_spire/contrib/breadcrumb/tests/test_breadcrumbs.py +198 -0
- django_spire/contrib/constructor/__init__.py +3 -3
- django_spire/contrib/constructor/constructor.py +15 -15
- django_spire/contrib/constructor/django_model_constructor.py +5 -4
- django_spire/contrib/constructor/exceptions.py +5 -3
- django_spire/contrib/constructor/tests/__init__.py +0 -0
- django_spire/contrib/constructor/tests/test_constructor.py +193 -0
- django_spire/contrib/form/tests/__init__.py +0 -0
- django_spire/contrib/form/tests/test_forms.py +203 -0
- django_spire/contrib/generic_views/modal_views.py +2 -1
- django_spire/contrib/generic_views/portal_views.py +20 -19
- django_spire/contrib/generic_views/tests/__init__.py +0 -0
- django_spire/contrib/generic_views/tests/test_views.py +459 -0
- django_spire/contrib/help/apps.py +2 -0
- django_spire/contrib/help/templatetags/help.py +1 -0
- django_spire/contrib/help/tests/__init__.py +0 -0
- django_spire/contrib/help/tests/test_templatetags.py +100 -0
- django_spire/contrib/options/mixins.py +6 -5
- django_spire/contrib/options/tests/factories.py +5 -1
- django_spire/contrib/options/tests/test_options.py +234 -0
- django_spire/contrib/ordering/exceptions.py +7 -3
- django_spire/contrib/ordering/mixins.py +2 -0
- django_spire/contrib/ordering/querysets.py +3 -1
- django_spire/contrib/ordering/services/processor_service.py +8 -4
- django_spire/contrib/ordering/services/service.py +1 -2
- django_spire/contrib/ordering/tests/__init__.py +0 -0
- django_spire/contrib/ordering/tests/test_ordering.py +165 -0
- django_spire/contrib/ordering/validators.py +6 -6
- django_spire/contrib/pagination/templatetags/pagination_tags.py +12 -5
- django_spire/contrib/pagination/tests/__init__.py +0 -0
- django_spire/contrib/pagination/tests/test_pagination.py +179 -0
- django_spire/contrib/performance/decorators.py +16 -6
- django_spire/contrib/performance/tests/__init__.py +0 -0
- django_spire/contrib/performance/tests/test_performance.py +107 -0
- django_spire/contrib/queryset/enums.py +3 -1
- django_spire/contrib/queryset/filter_tools.py +10 -5
- django_spire/contrib/queryset/mixins.py +16 -16
- django_spire/contrib/queryset/tests/__init__.py +0 -0
- django_spire/contrib/queryset/tests/test_queryset.py +137 -0
- django_spire/contrib/seeding/field/base.py +13 -7
- django_spire/contrib/seeding/field/callable.py +8 -1
- django_spire/contrib/seeding/field/cleaners.py +5 -5
- django_spire/contrib/seeding/field/custom.py +20 -10
- django_spire/contrib/seeding/field/django/seeder.py +8 -6
- django_spire/contrib/seeding/field/enums.py +7 -5
- django_spire/contrib/seeding/field/override.py +16 -6
- django_spire/contrib/seeding/field/static.py +9 -2
- django_spire/contrib/seeding/field/tests/test_base.py +18 -14
- django_spire/contrib/seeding/field/tests/test_callable.py +13 -9
- django_spire/contrib/seeding/field/tests/test_cleaners.py +51 -38
- django_spire/contrib/seeding/field/tests/test_static.py +13 -9
- django_spire/contrib/seeding/intelligence/bots/seeder_generator_bot.py +2 -0
- django_spire/contrib/seeding/intelligence/intel.py +5 -1
- django_spire/contrib/seeding/intelligence/prompts/factory.py +6 -1
- django_spire/contrib/seeding/intelligence/prompts/foreign_key_selection_prompt.py +6 -1
- django_spire/contrib/seeding/intelligence/prompts/generate_django_model_seeder_prompts.py +2 -0
- django_spire/contrib/seeding/intelligence/prompts/generic_relationship_selection_prompt.py +7 -1
- django_spire/contrib/seeding/intelligence/prompts/hierarchical_selection_prompt.py +6 -2
- django_spire/contrib/seeding/intelligence/prompts/model_field_choices_prompt.py +8 -2
- django_spire/contrib/seeding/intelligence/prompts/negation_prompt.py +2 -0
- django_spire/contrib/seeding/intelligence/prompts/objective_prompt.py +6 -1
- django_spire/contrib/seeding/management/commands/seeding.py +9 -3
- django_spire/contrib/seeding/management/example.py +2 -0
- django_spire/contrib/seeding/model/base.py +16 -7
- django_spire/contrib/seeding/model/config.py +31 -15
- django_spire/contrib/seeding/model/django/config.py +13 -13
- django_spire/contrib/seeding/model/django/seeder.py +4 -4
- django_spire/contrib/seeding/model/django/tests/test_seeder.py +34 -23
- django_spire/contrib/seeding/model/enums.py +2 -0
- django_spire/contrib/seeding/tests/test_config.py +71 -0
- django_spire/contrib/seeding/tests/test_custom.py +35 -0
- django_spire/contrib/seeding/tests/test_enums.py +40 -0
- django_spire/contrib/seeding/tests/test_intel.py +32 -0
- django_spire/contrib/seeding/tests/test_override.py +63 -0
- django_spire/contrib/service/__init__.py +2 -2
- django_spire/contrib/service/django_model_service.py +16 -15
- django_spire/contrib/service/exceptions.py +5 -3
- django_spire/contrib/service/tests/__init__.py +0 -0
- django_spire/contrib/service/tests/test_service.py +153 -0
- django_spire/contrib/session/apps.py +2 -0
- django_spire/contrib/session/controller.py +48 -42
- django_spire/contrib/session/templatetags/session_tags.py +11 -2
- django_spire/contrib/session/tests/test_session_controller.py +117 -53
- django_spire/contrib/tests/__init__.py +0 -0
- django_spire/contrib/tests/test_utils.py +37 -0
- django_spire/contrib/utils.py +4 -1
- django_spire/core/apps.py +2 -0
- django_spire/core/converters/tests/test_to_data.py +353 -0
- django_spire/core/converters/tests/test_to_enums.py +61 -41
- django_spire/core/converters/tests/test_to_pydantic.py +138 -109
- django_spire/core/converters/to_data.py +29 -10
- django_spire/core/converters/to_enums.py +4 -2
- django_spire/core/converters/to_pydantic.py +22 -22
- django_spire/core/decorators.py +19 -6
- django_spire/core/forms/widgets.py +4 -0
- django_spire/core/management/commands/spire_startapp_pkg/template/app/apps.py.template +2 -0
- django_spire/core/management/commands/spire_startapp_pkg/template/app/urls/__init__.py.template +2 -0
- django_spire/core/management/commands/spire_startapp_pkg/template/app/urls/form_urls.py.template +2 -0
- django_spire/core/management/commands/spire_startapp_pkg/template/app/urls/page_urls.py.template +2 -0
- django_spire/core/maps.py +3 -1
- django_spire/core/middleware/maintenance.py +3 -3
- django_spire/core/middleware.py +8 -6
- django_spire/core/redirect/__init__.py +5 -0
- django_spire/core/redirect/generic_redirect.py +1 -2
- django_spire/core/redirect/tests/__init__.py +0 -0
- django_spire/core/redirect/tests/test_generic_redirect.py +34 -0
- django_spire/core/{tests/tests_redirect.py → redirect/tests/test_safe_redirect.py} +55 -81
- django_spire/core/shortcuts.py +3 -3
- django_spire/core/static/django_spire/css/app-layout.css +1 -1
- django_spire/core/static/django_spire/css/app-navigation.css +3 -3
- django_spire/core/static/django_spire/css/bootstrap-override.css +4 -0
- django_spire/core/tag/admin.py +12 -0
- django_spire/core/tag/intelligence/tag_set_bot.py +2 -0
- django_spire/core/tag/mixins.py +2 -0
- django_spire/core/tag/models.py +2 -0
- django_spire/core/tag/querysets.py +2 -0
- django_spire/core/tag/service/tag_service.py +6 -3
- django_spire/core/tag/tests/test_intelligence.py +9 -9
- django_spire/core/tag/tests/test_tags.py +44 -54
- django_spire/core/tag/tests/test_tools.py +191 -0
- django_spire/core/tag/tools.py +3 -0
- django_spire/core/templates/django_spire/card/card.html +5 -2
- django_spire/core/templates/django_spire/card/title_card.html +12 -4
- django_spire/core/templates/django_spire/infinite_scroll/base.html +1 -0
- django_spire/core/templates/django_spire/navigation/side_navigation.html +19 -24
- django_spire/core/templates/django_spire/page/full_page.html +46 -16
- django_spire/core/templates/django_spire/table/base.html +5 -3
- django_spire/core/templatetags/json.py +6 -2
- django_spire/core/templatetags/message.py +13 -8
- django_spire/core/templatetags/string_formating.py +8 -5
- django_spire/core/templatetags/tests/__init__.py +0 -0
- django_spire/core/templatetags/tests/test_templatetags.py +427 -0
- django_spire/core/templatetags/variable_types.py +17 -9
- django_spire/core/tests/test_cases.py +1 -1
- django_spire/core/tests/test_conf.py +43 -0
- django_spire/core/tests/test_consts.py +28 -0
- django_spire/core/tests/test_context_processors.py +93 -0
- django_spire/core/tests/test_decorators.py +95 -0
- django_spire/core/tests/test_django_spire_utils.py +56 -0
- django_spire/core/tests/test_exceptions.py +37 -0
- django_spire/core/tests/test_models.py +54 -0
- django_spire/core/tests/test_settings.py +45 -0
- django_spire/core/tests/test_shortcuts.py +74 -0
- django_spire/core/tests/test_urls.py +16 -0
- django_spire/core/tests/test_utils.py +58 -0
- django_spire/core/urls.py +4 -1
- django_spire/core/utils.py +12 -8
- django_spire/exceptions.py +16 -1
- django_spire/file/admin.py +4 -2
- django_spire/file/apps.py +8 -10
- django_spire/file/fields.py +7 -7
- django_spire/file/forms.py +1 -1
- django_spire/file/interfaces.py +15 -15
- django_spire/file/mixins.py +1 -4
- django_spire/file/models.py +3 -5
- django_spire/file/tests/factories.py +59 -0
- django_spire/file/tests/test_admin.py +69 -0
- django_spire/file/tests/test_apps.py +24 -0
- django_spire/file/tests/test_fields.py +114 -0
- django_spire/file/tests/test_forms.py +20 -0
- django_spire/file/tests/test_interfaces.py +183 -0
- django_spire/file/tests/test_models.py +82 -0
- django_spire/file/tests/test_querysets.py +102 -0
- django_spire/file/tests/test_utils.py +32 -0
- django_spire/file/tests/test_views.py +145 -0
- django_spire/file/tests/test_widgets.py +82 -0
- django_spire/file/tools.py +8 -2
- django_spire/file/views.py +7 -3
- django_spire/file/widgets.py +12 -12
- django_spire/help_desk/admin.py +15 -0
- django_spire/help_desk/apps.py +2 -0
- django_spire/help_desk/auth/controller.py +2 -0
- django_spire/help_desk/choices.py +2 -0
- django_spire/help_desk/enums.py +2 -0
- django_spire/help_desk/exceptions.py +31 -3
- django_spire/help_desk/forms.py +2 -0
- django_spire/help_desk/models.py +2 -0
- django_spire/help_desk/querysets.py +4 -1
- django_spire/help_desk/services/notification_service.py +26 -27
- django_spire/help_desk/services/service.py +2 -3
- django_spire/help_desk/tests/factories.py +8 -3
- django_spire/help_desk/tests/test_admin.py +41 -0
- django_spire/help_desk/tests/test_apps.py +41 -0
- django_spire/help_desk/tests/test_choices.py +50 -0
- django_spire/help_desk/tests/test_controller.py +87 -0
- django_spire/help_desk/tests/test_enums.py +18 -0
- django_spire/help_desk/tests/test_exceptions.py +37 -0
- django_spire/help_desk/tests/test_forms.py +89 -0
- django_spire/help_desk/tests/test_models.py +59 -0
- django_spire/help_desk/tests/test_querysets.py +38 -0
- django_spire/help_desk/tests/test_services/test_notification_service.py +15 -8
- django_spire/help_desk/tests/test_services/test_service.py +92 -0
- django_spire/help_desk/tests/test_urls/test_form_urls.py +6 -6
- django_spire/help_desk/tests/test_urls/test_page_urls.py +8 -9
- django_spire/help_desk/tests/test_views/test_form_views.py +46 -19
- django_spire/help_desk/tests/test_views/test_page_views.py +32 -9
- django_spire/help_desk/urls/__init__.py +4 -1
- django_spire/help_desk/urls/form_urls.py +3 -0
- django_spire/help_desk/urls/page_urls.py +3 -0
- django_spire/help_desk/views/form_views.py +13 -5
- django_spire/help_desk/views/page_views.py +11 -3
- django_spire/history/activity/admin.py +2 -0
- django_spire/history/activity/apps.py +3 -1
- django_spire/history/activity/mixins.py +13 -7
- django_spire/history/activity/models.py +6 -5
- django_spire/history/activity/querysets.py +2 -0
- django_spire/history/activity/tests/__init__.py +0 -0
- django_spire/history/activity/tests/test_activity.py +176 -0
- django_spire/history/admin.py +9 -2
- django_spire/history/choices.py +3 -0
- django_spire/history/models.py +5 -5
- django_spire/history/tests/test_admin.py +93 -0
- django_spire/history/tests/test_history.py +101 -0
- django_spire/history/tests/test_mixins.py +84 -0
- django_spire/history/viewed/admin.py +3 -1
- django_spire/history/viewed/apps.py +3 -1
- django_spire/history/viewed/models.py +2 -0
- django_spire/history/viewed/tests/__init__.py +0 -0
- django_spire/history/viewed/tests/test_viewed.py +46 -0
- django_spire/knowledge/auth/tests/__init__.py +0 -0
- django_spire/knowledge/auth/tests/test_controller.py +116 -0
- django_spire/knowledge/collection/admin.py +5 -1
- django_spire/knowledge/collection/models.py +3 -1
- django_spire/knowledge/collection/seeding/seed.py +1 -0
- django_spire/knowledge/collection/services/factory_service.py +10 -11
- django_spire/knowledge/collection/services/ordering_service.py +1 -2
- django_spire/knowledge/collection/services/service.py +5 -10
- django_spire/knowledge/collection/services/tag_service.py +5 -2
- django_spire/knowledge/collection/tests/factories.py +28 -1
- django_spire/knowledge/collection/tests/test_models.py +48 -0
- django_spire/knowledge/collection/tests/test_querysets.py +93 -0
- django_spire/knowledge/collection/tests/test_services/test_factory_service.py +100 -0
- django_spire/knowledge/collection/tests/test_services/test_services.py +160 -0
- django_spire/knowledge/collection/tests/test_urls/test_form_urls.py +21 -3
- django_spire/knowledge/collection/tests/test_urls/test_json_urls.py +39 -1
- django_spire/knowledge/collection/tests/test_urls/test_page_urls.py +12 -4
- django_spire/knowledge/collection/urls/__init__.py +3 -0
- django_spire/knowledge/collection/urls/form_urls.py +2 -0
- django_spire/knowledge/collection/urls/json_urls.py +2 -0
- django_spire/knowledge/collection/urls/page_urls.py +2 -0
- django_spire/knowledge/collection/views/form_views.py +4 -4
- django_spire/knowledge/collection/views/json_views.py +5 -1
- django_spire/knowledge/collection/views/page_views.py +5 -2
- django_spire/knowledge/entry/admin.py +7 -1
- django_spire/knowledge/entry/forms.py +2 -0
- django_spire/knowledge/entry/models.py +2 -0
- django_spire/knowledge/entry/seeding/seed.py +3 -0
- django_spire/knowledge/entry/services/automation_service.py +5 -4
- django_spire/knowledge/entry/services/factory_service.py +7 -5
- django_spire/knowledge/entry/services/service.py +4 -7
- django_spire/knowledge/entry/services/tag_service.py +0 -1
- django_spire/knowledge/entry/services/tool_service.py +1 -0
- django_spire/knowledge/entry/services/transformation_services.py +1 -5
- django_spire/knowledge/entry/tests/factories.py +1 -2
- django_spire/knowledge/entry/tests/test_factory_service.py +20 -0
- django_spire/knowledge/entry/tests/test_models.py +41 -0
- django_spire/knowledge/entry/tests/test_querysets.py +71 -0
- django_spire/knowledge/entry/tests/test_services.py +94 -0
- django_spire/knowledge/entry/tests/test_urls/test_form_urls.py +9 -14
- django_spire/knowledge/entry/tests/test_urls/test_json_urls.py +48 -5
- django_spire/knowledge/entry/tests/test_urls/test_page_urls.py +6 -8
- django_spire/knowledge/entry/tests/test_urls/test_template_urls.py +40 -0
- django_spire/knowledge/entry/urls/form_urls.py +2 -0
- django_spire/knowledge/entry/urls/json_urls.py +2 -0
- django_spire/knowledge/entry/urls/page_urls.py +2 -0
- django_spire/knowledge/entry/urls/template_urls.py +2 -0
- django_spire/knowledge/entry/version/block/choices.py +2 -0
- django_spire/knowledge/entry/version/block/data/data.py +1 -0
- django_spire/knowledge/entry/version/block/data/list/data.py +8 -13
- django_spire/knowledge/entry/version/block/data/list/maps.py +3 -0
- django_spire/knowledge/entry/version/block/data/list/meta.py +1 -2
- django_spire/knowledge/entry/version/block/data/list/tests/__init__.py +0 -0
- django_spire/knowledge/entry/version/block/data/list/tests/test_maps.py +32 -0
- django_spire/knowledge/entry/version/block/data/list/tests/test_meta.py +58 -0
- django_spire/knowledge/entry/version/block/data/maps.py +3 -6
- django_spire/knowledge/entry/version/block/models.py +7 -5
- django_spire/knowledge/entry/version/block/seeding/constants.py +5 -4
- django_spire/knowledge/entry/version/block/services/service.py +2 -3
- django_spire/knowledge/entry/version/block/tests/factories.py +4 -10
- django_spire/knowledge/entry/version/block/tests/test_choices.py +56 -0
- django_spire/knowledge/entry/version/block/tests/test_data.py +90 -0
- django_spire/knowledge/entry/version/block/tests/test_maps.py +37 -0
- django_spire/knowledge/entry/version/block/tests/test_models.py +55 -0
- django_spire/knowledge/entry/version/block/tests/test_querysets.py +35 -0
- django_spire/knowledge/entry/version/block/tests/test_services.py +65 -0
- django_spire/knowledge/entry/version/choices.py +2 -0
- django_spire/knowledge/entry/version/converters/converter.py +1 -1
- django_spire/knowledge/entry/version/converters/docx_converter.py +4 -7
- django_spire/knowledge/entry/version/converters/markdown_converter.py +20 -20
- django_spire/knowledge/entry/version/maps.py +4 -5
- django_spire/knowledge/entry/version/querysets.py +1 -1
- django_spire/knowledge/entry/version/seeding/seeder.py +1 -2
- django_spire/knowledge/entry/version/services/processor_service.py +5 -4
- django_spire/knowledge/entry/version/services/service.py +1 -2
- django_spire/knowledge/entry/version/tests/factories.py +2 -2
- django_spire/knowledge/entry/version/tests/test_choices.py +18 -0
- django_spire/knowledge/entry/version/tests/test_converters/test_docx_converter.py +56 -8
- django_spire/knowledge/entry/version/tests/test_converters/test_markdown_converter.py +78 -0
- django_spire/knowledge/entry/version/tests/test_maps.py +58 -0
- django_spire/knowledge/entry/version/tests/test_models.py +23 -0
- django_spire/knowledge/entry/version/tests/test_querysets.py +26 -0
- django_spire/knowledge/entry/version/tests/test_services.py +62 -0
- django_spire/knowledge/entry/version/tests/test_urls/test_json_urls.py +27 -8
- django_spire/knowledge/entry/version/tests/test_urls/test_page_urls.py +15 -8
- django_spire/knowledge/entry/version/tests/test_urls/test_redirect_urls.py +38 -0
- django_spire/knowledge/entry/version/urls/__init__.py +3 -0
- django_spire/knowledge/entry/version/urls/json_urls.py +2 -1
- django_spire/knowledge/entry/version/urls/page_urls.py +2 -0
- django_spire/knowledge/entry/version/urls/redirect_urls.py +2 -0
- django_spire/knowledge/entry/version/views/json_views.py +5 -1
- django_spire/knowledge/entry/version/views/page_views.py +10 -3
- django_spire/knowledge/entry/version/views/redirect_views.py +5 -1
- django_spire/knowledge/entry/views/form_views.py +16 -8
- django_spire/knowledge/entry/views/json_views.py +3 -1
- django_spire/knowledge/entry/views/page_views.py +8 -2
- django_spire/knowledge/entry/views/template_views.py +7 -1
- django_spire/knowledge/exceptions.py +2 -1
- django_spire/knowledge/intelligence/intel/answer_intel.py +2 -1
- django_spire/knowledge/intelligence/intel/entry_intel.py +0 -1
- django_spire/knowledge/intelligence/workflows/knowledge_workflow.py +4 -5
- django_spire/knowledge/models.py +1 -2
- django_spire/knowledge/tests/__init__.py +0 -0
- django_spire/knowledge/tests/test_templatetags.py +40 -0
- django_spire/knowledge/tests/test_urls/__init__.py +0 -0
- django_spire/knowledge/tests/test_urls/test_page_urls.py +24 -0
- django_spire/knowledge/urls/__init__.py +2 -0
- django_spire/knowledge/urls/page_urls.py +2 -0
- django_spire/knowledge/views/page_views.py +8 -3
- django_spire/notification/admin.py +3 -1
- django_spire/notification/app/admin.py +2 -0
- django_spire/notification/app/apps.py +3 -1
- django_spire/notification/app/exceptions.py +9 -2
- django_spire/notification/app/models.py +8 -4
- django_spire/notification/app/processor.py +22 -26
- django_spire/notification/app/querysets.py +2 -0
- django_spire/notification/app/tests/__init__.py +0 -0
- django_spire/notification/app/tests/factories.py +34 -0
- django_spire/notification/app/tests/test_apps.py +24 -0
- django_spire/notification/app/tests/test_models.py +72 -0
- django_spire/notification/app/tests/test_processor.py +111 -0
- django_spire/notification/app/tests/test_querysets.py +90 -0
- django_spire/notification/app/tests/test_views/__init__.py +0 -0
- django_spire/notification/app/tests/test_views/test_json_views.py +48 -0
- django_spire/notification/app/tests/test_views/test_page_views.py +19 -0
- django_spire/notification/app/urls/__init__.py +3 -1
- django_spire/notification/app/urls/json_urls.py +6 -4
- django_spire/notification/app/urls/page_urls.py +4 -3
- django_spire/notification/app/urls/template_urls.py +4 -2
- django_spire/notification/apps.py +4 -1
- django_spire/notification/email/admin.py +5 -1
- django_spire/notification/email/apps.py +3 -1
- django_spire/notification/email/exceptions.py +4 -2
- django_spire/notification/email/helper.py +5 -3
- django_spire/notification/email/models.py +4 -0
- django_spire/notification/email/processor.py +19 -15
- django_spire/notification/email/querysets.py +3 -0
- django_spire/notification/email/tests/__init__.py +0 -0
- django_spire/notification/email/tests/factories.py +35 -0
- django_spire/notification/email/tests/test_apps.py +24 -0
- django_spire/notification/email/tests/test_models.py +52 -0
- django_spire/notification/email/tests/test_processor.py +92 -0
- django_spire/notification/email/tests/test_querysets.py +43 -0
- django_spire/notification/exceptions.py +17 -2
- django_spire/notification/managers.py +7 -1
- django_spire/notification/maps.py +4 -1
- django_spire/notification/mixins.py +2 -0
- django_spire/notification/models.py +3 -1
- django_spire/notification/processors/notification.py +12 -5
- django_spire/notification/processors/processor.py +2 -0
- django_spire/notification/processors/tests/__init__.py +0 -0
- django_spire/notification/processors/tests/test_notification.py +106 -0
- django_spire/notification/push/admin.py +10 -1
- django_spire/notification/push/apps.py +3 -1
- django_spire/notification/push/models.py +2 -3
- django_spire/notification/push/tests/__init__.py +0 -0
- django_spire/notification/push/tests/test_apps.py +24 -0
- django_spire/notification/push/tests/test_models.py +28 -0
- django_spire/notification/querysets.py +7 -1
- django_spire/notification/sms/admin.py +2 -0
- django_spire/notification/sms/apps.py +4 -1
- django_spire/notification/sms/automations.py +2 -0
- django_spire/notification/sms/choices.py +2 -0
- django_spire/notification/sms/exceptions.py +19 -5
- django_spire/notification/sms/helper.py +33 -23
- django_spire/notification/sms/models.py +5 -1
- django_spire/notification/sms/processor.py +20 -20
- django_spire/notification/sms/querysets.py +2 -0
- django_spire/notification/sms/tests/factories.py +33 -0
- django_spire/notification/sms/tests/test_apps.py +24 -0
- django_spire/notification/sms/tests/test_automation.py +38 -0
- django_spire/notification/sms/tests/test_choices.py +15 -0
- django_spire/notification/sms/tests/test_consts.py +17 -0
- django_spire/notification/sms/tests/test_exceptions.py +27 -0
- django_spire/notification/sms/tests/test_helper.py +50 -0
- django_spire/notification/sms/tests/test_models.py +81 -0
- django_spire/notification/sms/tests/test_processor.py +107 -0
- django_spire/notification/sms/tests/test_tools.py +25 -11
- django_spire/notification/sms/tools.py +16 -5
- django_spire/notification/sms/urls/__init__.py +3 -1
- django_spire/notification/sms/urls/media_urls.py +2 -0
- django_spire/notification/sms/views/media_views.py +14 -4
- django_spire/notification/tests/__init__.py +0 -0
- django_spire/notification/tests/factories.py +26 -0
- django_spire/notification/tests/test_admin.py +55 -0
- django_spire/notification/tests/test_apps.py +30 -0
- django_spire/notification/tests/test_automation.py +18 -0
- django_spire/notification/tests/test_choices.py +59 -0
- django_spire/notification/tests/test_exceptions.py +58 -0
- django_spire/notification/tests/test_managers.py +100 -0
- django_spire/notification/tests/test_maps.py +31 -0
- django_spire/notification/tests/test_models.py +76 -0
- django_spire/notification/tests/test_querysets.py +184 -0
- django_spire/notification/tests/test_utils.py +23 -0
- django_spire/notification/urls.py +3 -1
- django_spire/notification/utils.py +3 -1
- django_spire/settings.py +3 -0
- django_spire/theme/tests/test_context_processor.py +15 -13
- django_spire/theme/tests/test_enums.py +2 -2
- django_spire/theme/tests/test_filesystem.py +2 -5
- django_spire/theme/tests/test_integration.py +12 -12
- django_spire/theme/tests/test_model.py +40 -38
- django_spire/theme/tests/test_views/test_json_views.py +33 -33
- django_spire/theme/urls/json_urls.py +3 -0
- django_spire/theme/urls/page_urls.py +3 -0
- django_spire/urls.py +19 -15
- django_spire/utils.py +13 -4
- {django_spire-0.23.7.dist-info → django_spire-0.23.9.dist-info}/METADATA +2 -2
- {django_spire-0.23.7.dist-info → django_spire-0.23.9.dist-info}/RECORD +534 -362
- {django_spire-0.23.7.dist-info → django_spire-0.23.9.dist-info}/licenses/LICENSE.md +1 -1
- django_spire/contrib/options/tests/test_unit.py +0 -148
- django_spire/contrib/seeding/tests/test_seeding.py +0 -25
- django_spire/core/tests/test_templatetags.py +0 -117
- django_spire/core/tests/tests_shortcuts.py +0 -73
- django_spire/history/activity/tests.py +0 -3
- django_spire/history/activity/views.py +0 -3
- django_spire/knowledge/collection/tests/test_services/test_transformation_service.py +0 -71
- django_spire/notification/app/tests.py +0 -3
- {django_spire-0.23.7.dist-info → django_spire-0.23.9.dist-info}/WHEEL +0 -0
- {django_spire-0.23.7.dist-info → django_spire-0.23.9.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from django_spire.auth.user.tests.factories import create_user
|
|
4
|
+
from django_spire.core.tests.test_cases import BaseTestCase
|
|
5
|
+
from django_spire.knowledge.collection.tests.factories import create_test_collection
|
|
6
|
+
from django_spire.knowledge.entry.models import Entry
|
|
7
|
+
from django_spire.knowledge.entry.tests.factories import create_test_entry
|
|
8
|
+
from django_spire.knowledge.entry.version.choices import EntryVersionStatusChoices
|
|
9
|
+
from django_spire.knowledge.entry.version.tests.factories import create_test_entry_version
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class EntryQuerySetTests(BaseTestCase):
|
|
13
|
+
def setUp(self):
|
|
14
|
+
super().setUp()
|
|
15
|
+
self.user = create_user(username='test_entry_queryset_user')
|
|
16
|
+
self.collection = create_test_collection()
|
|
17
|
+
self.entry = create_test_entry(collection=self.collection)
|
|
18
|
+
self.entry_version = create_test_entry_version(entry=self.entry)
|
|
19
|
+
self.entry.current_version = self.entry_version
|
|
20
|
+
self.entry.save()
|
|
21
|
+
|
|
22
|
+
def test_has_current_version(self):
|
|
23
|
+
result = Entry.objects.has_current_version()
|
|
24
|
+
assert self.entry in result
|
|
25
|
+
|
|
26
|
+
def test_has_current_version_excludes_none(self):
|
|
27
|
+
entry_without_version = create_test_entry(
|
|
28
|
+
collection=self.collection,
|
|
29
|
+
name='No Version'
|
|
30
|
+
)
|
|
31
|
+
result = Entry.objects.has_current_version()
|
|
32
|
+
assert entry_without_version not in result
|
|
33
|
+
|
|
34
|
+
def test_id_in(self):
|
|
35
|
+
entry2 = create_test_entry(collection=self.collection, name='Entry 2')
|
|
36
|
+
result = Entry.objects.id_in([self.entry.pk, entry2.pk])
|
|
37
|
+
assert self.entry in result
|
|
38
|
+
assert entry2 in result
|
|
39
|
+
|
|
40
|
+
def test_user_has_access_published(self):
|
|
41
|
+
self.entry_version.status = EntryVersionStatusChoices.PUBLISHED
|
|
42
|
+
self.entry_version.save()
|
|
43
|
+
|
|
44
|
+
result = Entry.objects.user_has_access(user=self.user)
|
|
45
|
+
assert self.entry in result
|
|
46
|
+
|
|
47
|
+
def test_user_has_access_draft_own(self):
|
|
48
|
+
self.entry_version.status = EntryVersionStatusChoices.DRAFT
|
|
49
|
+
self.entry_version.author = self.user
|
|
50
|
+
self.entry_version.save()
|
|
51
|
+
|
|
52
|
+
result = Entry.objects.user_has_access(user=self.user)
|
|
53
|
+
assert self.entry in result
|
|
54
|
+
|
|
55
|
+
def test_user_has_access_draft_other(self):
|
|
56
|
+
other_user = create_user(username='other_user')
|
|
57
|
+
self.entry_version.status = EntryVersionStatusChoices.DRAFT
|
|
58
|
+
self.entry_version.author = other_user
|
|
59
|
+
self.entry_version.save()
|
|
60
|
+
|
|
61
|
+
result = Entry.objects.user_has_access(user=self.user)
|
|
62
|
+
assert self.entry not in result
|
|
63
|
+
|
|
64
|
+
def test_get_by_version_block_id(self):
|
|
65
|
+
from django_spire.knowledge.entry.version.block.tests.factories import (
|
|
66
|
+
create_test_version_block,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
version_block = create_test_version_block(version=self.entry_version)
|
|
70
|
+
result = Entry.objects.get_by_version_block_id(version_block_id=version_block.pk)
|
|
71
|
+
assert result == self.entry
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from django_spire.core.tests.test_cases import BaseTestCase
|
|
4
|
+
from django_spire.knowledge.collection.tests.factories import create_test_collection
|
|
5
|
+
from django_spire.knowledge.entry.models import Entry
|
|
6
|
+
from django_spire.knowledge.entry.tests.factories import create_test_entry
|
|
7
|
+
from django_spire.knowledge.entry.version.tests.factories import create_test_entry_version
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class EntryServiceTests(BaseTestCase):
|
|
11
|
+
def setUp(self):
|
|
12
|
+
super().setUp()
|
|
13
|
+
self.collection = create_test_collection()
|
|
14
|
+
self.entry = create_test_entry(collection=self.collection)
|
|
15
|
+
|
|
16
|
+
def test_save_model_obj_creates_new_with_version(self):
|
|
17
|
+
entry, created = Entry.services.save_model_obj(
|
|
18
|
+
author=self.super_user,
|
|
19
|
+
name='New Entry',
|
|
20
|
+
collection=self.collection
|
|
21
|
+
)
|
|
22
|
+
assert created is True
|
|
23
|
+
assert entry.name == 'New Entry'
|
|
24
|
+
assert entry.current_version is not None
|
|
25
|
+
|
|
26
|
+
def test_save_model_obj_updates_existing(self):
|
|
27
|
+
entry_version = create_test_entry_version(entry=self.entry)
|
|
28
|
+
self.entry.current_version = entry_version
|
|
29
|
+
self.entry.save()
|
|
30
|
+
|
|
31
|
+
self.entry.services.obj = self.entry
|
|
32
|
+
updated_entry, created = self.entry.services.save_model_obj(
|
|
33
|
+
author=self.super_user,
|
|
34
|
+
name='Updated Name'
|
|
35
|
+
)
|
|
36
|
+
assert created is False
|
|
37
|
+
assert updated_entry.name == 'Updated Name'
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class EntryProcessorServiceTests(BaseTestCase):
|
|
41
|
+
def setUp(self):
|
|
42
|
+
super().setUp()
|
|
43
|
+
self.collection = create_test_collection()
|
|
44
|
+
self.entry = create_test_entry(collection=self.collection)
|
|
45
|
+
|
|
46
|
+
def test_set_deleted(self):
|
|
47
|
+
self.entry.services.processor.set_deleted()
|
|
48
|
+
self.entry.refresh_from_db()
|
|
49
|
+
assert self.entry.is_deleted is True
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class EntryToolServiceTests(BaseTestCase):
|
|
53
|
+
def setUp(self):
|
|
54
|
+
super().setUp()
|
|
55
|
+
self.collection = create_test_collection()
|
|
56
|
+
self.entry = create_test_entry(collection=self.collection)
|
|
57
|
+
|
|
58
|
+
def test_get_files_to_convert(self):
|
|
59
|
+
result = Entry.services.tool.get_files_to_convert()
|
|
60
|
+
assert result.count() == 0
|
|
61
|
+
|
|
62
|
+
def test_get_files_to_convert_json(self):
|
|
63
|
+
result = Entry.services.tool.get_files_to_convert_json()
|
|
64
|
+
assert result == '[]'
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class EntryTransformationServiceTests(BaseTestCase):
|
|
68
|
+
def setUp(self):
|
|
69
|
+
super().setUp()
|
|
70
|
+
self.collection = create_test_collection()
|
|
71
|
+
self.entry = create_test_entry(collection=self.collection)
|
|
72
|
+
self.entry_version = create_test_entry_version(entry=self.entry)
|
|
73
|
+
self.entry.current_version = self.entry_version
|
|
74
|
+
self.entry.save()
|
|
75
|
+
|
|
76
|
+
def test_to_dict(self):
|
|
77
|
+
self.entry.services.transformation.obj = self.entry
|
|
78
|
+
result = self.entry.services.transformation.to_dict()
|
|
79
|
+
|
|
80
|
+
assert result['entry_id'] == self.entry.pk
|
|
81
|
+
assert result['name'] == self.entry.name
|
|
82
|
+
assert 'version_id' in result
|
|
83
|
+
assert 'author' in result
|
|
84
|
+
assert 'status' in result
|
|
85
|
+
assert 'delete_url' in result
|
|
86
|
+
assert 'edit_url' in result
|
|
87
|
+
assert 'view_url' in result
|
|
88
|
+
|
|
89
|
+
def test_queryset_to_navigation_list(self):
|
|
90
|
+
result = Entry.services.transformation.queryset_to_navigation_list(
|
|
91
|
+
queryset=Entry.objects.filter(pk=self.entry.pk)
|
|
92
|
+
)
|
|
93
|
+
assert len(result) == 1
|
|
94
|
+
assert result[0]['entry_id'] == self.entry.pk
|
|
@@ -5,33 +5,29 @@ from django.urls import reverse
|
|
|
5
5
|
from django_spire.core.tests.test_cases import BaseTestCase
|
|
6
6
|
from django_spire.knowledge.collection.tests.factories import create_test_collection
|
|
7
7
|
from django_spire.knowledge.entry.tests.factories import create_test_entry
|
|
8
|
-
from django_spire.knowledge.entry.version.tests.factories import
|
|
9
|
-
create_test_entry_version
|
|
8
|
+
from django_spire.knowledge.entry.version.tests.factories import create_test_entry_version
|
|
10
9
|
|
|
11
10
|
|
|
12
|
-
class
|
|
11
|
+
class EntryFormUrlsTests(BaseTestCase):
|
|
13
12
|
def setUp(self):
|
|
14
13
|
super().setUp()
|
|
15
14
|
|
|
16
15
|
self.collection = create_test_collection()
|
|
17
|
-
self.test_entry = create_test_entry(
|
|
18
|
-
|
|
19
|
-
)
|
|
20
|
-
self.test_entry_version = create_test_entry_version(
|
|
21
|
-
entry=self.test_entry
|
|
22
|
-
)
|
|
16
|
+
self.test_entry = create_test_entry(collection=self.collection)
|
|
17
|
+
self.test_entry_version = create_test_entry_version(entry=self.test_entry)
|
|
23
18
|
self.test_entry.current_version = self.test_entry_version
|
|
24
19
|
self.test_entry.save()
|
|
25
20
|
|
|
26
|
-
def
|
|
21
|
+
def test_create_form_view_url_path(self):
|
|
27
22
|
response = self.client.get(
|
|
28
23
|
reverse(
|
|
29
24
|
'django_spire:knowledge:entry:form:create',
|
|
30
25
|
kwargs={'collection_pk': self.collection.pk}
|
|
31
26
|
)
|
|
32
27
|
)
|
|
33
|
-
|
|
28
|
+
assert response.status_code == 200
|
|
34
29
|
|
|
30
|
+
def test_update_form_view_url_path(self):
|
|
35
31
|
response = self.client.get(
|
|
36
32
|
reverse(
|
|
37
33
|
'django_spire:knowledge:entry:form:update',
|
|
@@ -41,8 +37,7 @@ class EntryPageUrlsTests(BaseTestCase):
|
|
|
41
37
|
}
|
|
42
38
|
)
|
|
43
39
|
)
|
|
44
|
-
|
|
45
|
-
self.assertEqual(response.status_code, 200)
|
|
40
|
+
assert response.status_code == 200
|
|
46
41
|
|
|
47
42
|
def test_import_form_view_url_path(self):
|
|
48
43
|
response = self.client.get(
|
|
@@ -51,4 +46,4 @@ class EntryPageUrlsTests(BaseTestCase):
|
|
|
51
46
|
kwargs={'collection_pk': self.collection.pk}
|
|
52
47
|
)
|
|
53
48
|
)
|
|
54
|
-
|
|
49
|
+
assert response.status_code == 200
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from django.urls import reverse
|
|
4
4
|
|
|
5
5
|
from django_spire.core.tests.test_cases import BaseTestCase
|
|
6
|
+
from django_spire.knowledge.collection.tests.factories import create_test_collection
|
|
6
7
|
from django_spire.knowledge.entry.tests.factories import create_test_entry
|
|
7
8
|
|
|
8
9
|
|
|
@@ -10,21 +11,63 @@ class EntryJsonUrlsTests(BaseTestCase):
|
|
|
10
11
|
def setUp(self):
|
|
11
12
|
super().setUp()
|
|
12
13
|
|
|
13
|
-
self.
|
|
14
|
+
self.collection = create_test_collection()
|
|
15
|
+
self.test_entry = create_test_entry(collection=self.collection)
|
|
14
16
|
|
|
15
17
|
def test_reorder_view_url_path(self):
|
|
16
18
|
response = self.client.post(
|
|
17
19
|
reverse('django_spire:knowledge:entry:json:reorder'),
|
|
18
|
-
data={
|
|
20
|
+
data={
|
|
21
|
+
'entry_id': self.test_entry.pk,
|
|
22
|
+
'order': 0,
|
|
23
|
+
'collection_id': self.collection.pk
|
|
24
|
+
},
|
|
19
25
|
content_type='application/json',
|
|
20
26
|
)
|
|
27
|
+
assert response.status_code == 200
|
|
21
28
|
|
|
22
|
-
|
|
29
|
+
def test_reorder_view_invalid_entry(self):
|
|
30
|
+
response = self.client.post(
|
|
31
|
+
reverse('django_spire:knowledge:entry:json:reorder'),
|
|
32
|
+
data={
|
|
33
|
+
'entry_id': 99999,
|
|
34
|
+
'order': 0,
|
|
35
|
+
'collection_id': self.collection.pk
|
|
36
|
+
},
|
|
37
|
+
content_type='application/json',
|
|
38
|
+
)
|
|
39
|
+
assert response.status_code == 200
|
|
40
|
+
assert response.json()['type'] == 'error'
|
|
41
|
+
|
|
42
|
+
def test_reorder_view_missing_order(self):
|
|
43
|
+
response = self.client.post(
|
|
44
|
+
reverse('django_spire:knowledge:entry:json:reorder'),
|
|
45
|
+
data={
|
|
46
|
+
'entry_id': self.test_entry.pk,
|
|
47
|
+
'collection_id': self.collection.pk
|
|
48
|
+
},
|
|
49
|
+
content_type='application/json',
|
|
50
|
+
)
|
|
51
|
+
assert response.status_code == 200
|
|
52
|
+
assert response.json()['type'] == 'error'
|
|
53
|
+
|
|
54
|
+
def test_reorder_view_invalid_collection(self):
|
|
55
|
+
response = self.client.post(
|
|
56
|
+
reverse('django_spire:knowledge:entry:json:reorder'),
|
|
57
|
+
data={
|
|
58
|
+
'entry_id': self.test_entry.pk,
|
|
59
|
+
'order': 0,
|
|
60
|
+
'collection_id': 99999
|
|
61
|
+
},
|
|
62
|
+
content_type='application/json',
|
|
63
|
+
)
|
|
64
|
+
assert response.status_code == 200
|
|
65
|
+
assert response.json()['type'] == 'error'
|
|
23
66
|
|
|
24
67
|
def test_update_files_view_url_path(self):
|
|
25
68
|
response = self.client.post(
|
|
26
69
|
reverse('django_spire:knowledge:entry:json:update_files'),
|
|
27
70
|
content_type='application/json',
|
|
28
71
|
)
|
|
29
|
-
|
|
30
|
-
|
|
72
|
+
assert response.status_code == 200
|
|
73
|
+
assert 'files_json' in response.json()
|
|
@@ -3,19 +3,18 @@ from __future__ import annotations
|
|
|
3
3
|
from django.urls import reverse
|
|
4
4
|
|
|
5
5
|
from django_spire.core.tests.test_cases import BaseTestCase
|
|
6
|
+
from django_spire.knowledge.collection.tests.factories import create_test_collection
|
|
6
7
|
from django_spire.knowledge.entry.tests.factories import create_test_entry
|
|
7
|
-
from django_spire.knowledge.entry.version.tests.factories import
|
|
8
|
-
create_test_entry_version
|
|
8
|
+
from django_spire.knowledge.entry.version.tests.factories import create_test_entry_version
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class EntryPageUrlsTests(BaseTestCase):
|
|
12
12
|
def setUp(self):
|
|
13
13
|
super().setUp()
|
|
14
14
|
|
|
15
|
-
self.
|
|
16
|
-
self.
|
|
17
|
-
|
|
18
|
-
)
|
|
15
|
+
self.collection = create_test_collection()
|
|
16
|
+
self.test_entry = create_test_entry(collection=self.collection)
|
|
17
|
+
self.test_entry_version = create_test_entry_version(entry=self.test_entry)
|
|
19
18
|
self.test_entry.current_version = self.test_entry_version
|
|
20
19
|
self.test_entry.save()
|
|
21
20
|
|
|
@@ -26,5 +25,4 @@ class EntryPageUrlsTests(BaseTestCase):
|
|
|
26
25
|
kwargs={'pk': self.test_entry.pk}
|
|
27
26
|
)
|
|
28
27
|
)
|
|
29
|
-
|
|
30
|
-
self.assertEqual(response.status_code, 200)
|
|
28
|
+
assert response.status_code == 200
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from django.urls import reverse
|
|
4
|
+
|
|
5
|
+
from django_spire.core.tests.test_cases import BaseTestCase
|
|
6
|
+
from django_spire.knowledge.collection.tests.factories import create_test_collection
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class EntryTemplateUrlsTests(BaseTestCase):
|
|
10
|
+
def setUp(self):
|
|
11
|
+
super().setUp()
|
|
12
|
+
|
|
13
|
+
self.collection = create_test_collection()
|
|
14
|
+
|
|
15
|
+
def test_file_list_view_url_path(self):
|
|
16
|
+
response = self.client.get(
|
|
17
|
+
reverse(
|
|
18
|
+
'django_spire:knowledge:entry:template:file_list',
|
|
19
|
+
kwargs={'collection_pk': self.collection.pk}
|
|
20
|
+
)
|
|
21
|
+
)
|
|
22
|
+
assert response.status_code == 200
|
|
23
|
+
|
|
24
|
+
def test_file_list_view_contains_files_json(self):
|
|
25
|
+
response = self.client.get(
|
|
26
|
+
reverse(
|
|
27
|
+
'django_spire:knowledge:entry:template:file_list',
|
|
28
|
+
kwargs={'collection_pk': self.collection.pk}
|
|
29
|
+
)
|
|
30
|
+
)
|
|
31
|
+
assert 'files_json' in response.context
|
|
32
|
+
|
|
33
|
+
def test_file_list_view_contains_breadcrumbs(self):
|
|
34
|
+
response = self.client.get(
|
|
35
|
+
reverse(
|
|
36
|
+
'django_spire:knowledge:entry:template:file_list',
|
|
37
|
+
kwargs={'collection_pk': self.collection.pk}
|
|
38
|
+
)
|
|
39
|
+
)
|
|
40
|
+
assert 'breadcrumbs' in response.context
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
|
|
4
3
|
from pydantic import model_validator, BaseModel
|
|
5
4
|
|
|
6
5
|
from django_spire.knowledge.entry.version.block.constants import SPACES_PER_INDENT
|
|
7
6
|
from django_spire.knowledge.entry.version.block.data.data import BaseEditorJsBlockData
|
|
8
|
-
from django_spire.knowledge.entry.version.block.data.list.meta import ChecklistItemMeta,
|
|
9
|
-
|
|
10
|
-
from django_spire.knowledge.entry.version.block.data.list.choices import \
|
|
11
|
-
ListEditorBlockDataStyle
|
|
7
|
+
from django_spire.knowledge.entry.version.block.data.list.meta import ChecklistItemMeta, OrderedListItemMeta
|
|
8
|
+
from django_spire.knowledge.entry.version.block.data.list.choices import ListEditorBlockDataStyle
|
|
12
9
|
|
|
13
10
|
|
|
14
11
|
class ListEditorBlockData(BaseEditorJsBlockData):
|
|
@@ -43,10 +40,10 @@ class ListItemEditorBlockData(BaseModel):
|
|
|
43
40
|
items: list[ListItemEditorBlockData] | None = []
|
|
44
41
|
|
|
45
42
|
def get_prefix(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
self,
|
|
44
|
+
style: ListEditorBlockDataStyle,
|
|
45
|
+
indent_level: int,
|
|
46
|
+
index = None
|
|
50
47
|
):
|
|
51
48
|
prefix = ' ' * indent_level * SPACES_PER_INDENT
|
|
52
49
|
|
|
@@ -54,10 +51,8 @@ class ListItemEditorBlockData(BaseModel):
|
|
|
54
51
|
index = index or 0
|
|
55
52
|
start = self.meta.start or 1
|
|
56
53
|
prefix += f'{start + index}.'
|
|
57
|
-
|
|
58
54
|
elif style == ListEditorBlockDataStyle.CHECKLIST:
|
|
59
55
|
prefix += f'[{"X" if self.meta.checked else " "}]'
|
|
60
|
-
|
|
61
56
|
else:
|
|
62
57
|
prefix += '-'
|
|
63
58
|
|
|
@@ -69,12 +64,12 @@ class ListItemEditorBlockData(BaseModel):
|
|
|
69
64
|
indent_level: int,
|
|
70
65
|
index: int
|
|
71
66
|
) -> str:
|
|
72
|
-
from django_spire.knowledge.entry.version.converters.markdown_converter import
|
|
73
|
-
MarkdownConverter
|
|
67
|
+
from django_spire.knowledge.entry.version.converters.markdown_converter import MarkdownConverter
|
|
74
68
|
|
|
75
69
|
prefix = self.get_prefix(style, indent_level, index)
|
|
76
70
|
parsed_content = MarkdownConverter.html_to_markdown(self.content)
|
|
77
71
|
render_string = f'{prefix} {parsed_content}\n'
|
|
72
|
+
|
|
78
73
|
for i, item in enumerate(self.items):
|
|
79
74
|
render_string += item.render_to_text(style, indent_level + 1, i)
|
|
80
75
|
|
|
@@ -2,11 +2,14 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from django_spire.knowledge.entry.version.block.data.list import choices, meta
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
LIST_BLOCK_DATA_META_MAP = {
|
|
6
7
|
choices.ListEditorBlockDataStyle.ORDERED: meta.OrderedListItemMeta,
|
|
7
8
|
choices.ListEditorBlockDataStyle.CHECKLIST: meta.ChecklistItemMeta,
|
|
8
9
|
choices.ListEditorBlockDataStyle.UNORDERED: None,
|
|
9
10
|
}
|
|
11
|
+
|
|
12
|
+
|
|
10
13
|
LIST_BLOCK_DATA_REVERSE_META_MAP = {
|
|
11
14
|
meta.OrderedListItemMeta: choices.ListEditorBlockDataStyle.ORDERED,
|
|
12
15
|
meta.ChecklistItemMeta: choices.ListEditorBlockDataStyle.CHECKLIST,
|
|
@@ -2,8 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from pydantic import BaseModel
|
|
4
4
|
|
|
5
|
-
from django_spire.knowledge.entry.version.block.data.list.choices import
|
|
6
|
-
OrderedListCounterType
|
|
5
|
+
from django_spire.knowledge.entry.version.block.data.list.choices import OrderedListCounterType
|
|
7
6
|
|
|
8
7
|
|
|
9
8
|
class ChecklistItemMeta(BaseModel):
|
|
File without changes
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from django_spire.core.tests.test_cases import BaseTestCase
|
|
4
|
+
from django_spire.knowledge.entry.version.block.data.list.choices import ListEditorBlockDataStyle
|
|
5
|
+
from django_spire.knowledge.entry.version.block.data.list.maps import (
|
|
6
|
+
LIST_BLOCK_DATA_META_MAP,
|
|
7
|
+
LIST_BLOCK_DATA_REVERSE_META_MAP,
|
|
8
|
+
)
|
|
9
|
+
from django_spire.knowledge.entry.version.block.data.list.meta import (
|
|
10
|
+
ChecklistItemMeta,
|
|
11
|
+
OrderedListItemMeta,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ListBlockDataMapTests(BaseTestCase):
|
|
16
|
+
def test_meta_map_ordered(self):
|
|
17
|
+
assert LIST_BLOCK_DATA_META_MAP[ListEditorBlockDataStyle.ORDERED] == OrderedListItemMeta
|
|
18
|
+
|
|
19
|
+
def test_meta_map_checklist(self):
|
|
20
|
+
assert LIST_BLOCK_DATA_META_MAP[ListEditorBlockDataStyle.CHECKLIST] == ChecklistItemMeta
|
|
21
|
+
|
|
22
|
+
def test_meta_map_unordered(self):
|
|
23
|
+
assert LIST_BLOCK_DATA_META_MAP[ListEditorBlockDataStyle.UNORDERED] is None
|
|
24
|
+
|
|
25
|
+
def test_reverse_meta_map_ordered(self):
|
|
26
|
+
assert LIST_BLOCK_DATA_REVERSE_META_MAP[OrderedListItemMeta] == ListEditorBlockDataStyle.ORDERED
|
|
27
|
+
|
|
28
|
+
def test_reverse_meta_map_checklist(self):
|
|
29
|
+
assert LIST_BLOCK_DATA_REVERSE_META_MAP[ChecklistItemMeta] == ListEditorBlockDataStyle.CHECKLIST
|
|
30
|
+
|
|
31
|
+
def test_reverse_meta_map_unordered(self):
|
|
32
|
+
assert LIST_BLOCK_DATA_REVERSE_META_MAP[None] == ListEditorBlockDataStyle.UNORDERED
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from django_spire.core.tests.test_cases import BaseTestCase
|
|
4
|
+
from django_spire.knowledge.entry.version.block.data.list.choices import OrderedListCounterType
|
|
5
|
+
from django_spire.knowledge.entry.version.block.data.list.meta import (
|
|
6
|
+
ChecklistItemMeta,
|
|
7
|
+
OrderedListItemMeta,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ChecklistItemMetaTests(BaseTestCase):
|
|
12
|
+
def test_default_unchecked(self):
|
|
13
|
+
meta = ChecklistItemMeta()
|
|
14
|
+
assert meta.checked is False
|
|
15
|
+
|
|
16
|
+
def test_checked_true(self):
|
|
17
|
+
meta = ChecklistItemMeta(checked=True)
|
|
18
|
+
assert meta.checked is True
|
|
19
|
+
|
|
20
|
+
def test_checked_false(self):
|
|
21
|
+
meta = ChecklistItemMeta(checked=False)
|
|
22
|
+
assert meta.checked is False
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class OrderedListItemMetaTests(BaseTestCase):
|
|
26
|
+
def test_default_values(self):
|
|
27
|
+
meta = OrderedListItemMeta()
|
|
28
|
+
assert meta.start is None
|
|
29
|
+
assert meta.counterType is None
|
|
30
|
+
|
|
31
|
+
def test_with_start(self):
|
|
32
|
+
meta = OrderedListItemMeta(start=5)
|
|
33
|
+
assert meta.start == 5
|
|
34
|
+
|
|
35
|
+
def test_with_counter_type_numeric(self):
|
|
36
|
+
meta = OrderedListItemMeta(counterType=OrderedListCounterType.NUMERIC)
|
|
37
|
+
assert meta.counterType == OrderedListCounterType.NUMERIC
|
|
38
|
+
|
|
39
|
+
def test_with_counter_type_upper_roman(self):
|
|
40
|
+
meta = OrderedListItemMeta(counterType=OrderedListCounterType.UPPER_ROMAN)
|
|
41
|
+
assert meta.counterType == OrderedListCounterType.UPPER_ROMAN
|
|
42
|
+
|
|
43
|
+
def test_with_counter_type_lower_roman(self):
|
|
44
|
+
meta = OrderedListItemMeta(counterType=OrderedListCounterType.LOWER_ROMAN)
|
|
45
|
+
assert meta.counterType == OrderedListCounterType.LOWER_ROMAN
|
|
46
|
+
|
|
47
|
+
def test_with_counter_type_upper_alpha(self):
|
|
48
|
+
meta = OrderedListItemMeta(counterType=OrderedListCounterType.UPPER_ALPHA)
|
|
49
|
+
assert meta.counterType == OrderedListCounterType.UPPER_ALPHA
|
|
50
|
+
|
|
51
|
+
def test_with_counter_type_lower_alpha(self):
|
|
52
|
+
meta = OrderedListItemMeta(counterType=OrderedListCounterType.LOWER_ALPHA)
|
|
53
|
+
assert meta.counterType == OrderedListCounterType.LOWER_ALPHA
|
|
54
|
+
|
|
55
|
+
def test_with_all_values(self):
|
|
56
|
+
meta = OrderedListItemMeta(start=10, counterType=OrderedListCounterType.NUMERIC)
|
|
57
|
+
assert meta.start == 10
|
|
58
|
+
assert meta.counterType == OrderedListCounterType.NUMERIC
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from django_spire.knowledge.entry.version.block.choices import BlockTypeChoices
|
|
4
|
-
from django_spire.knowledge.entry.version.block.data.heading_data import
|
|
5
|
-
|
|
6
|
-
from django_spire.knowledge.entry.version.block.data.
|
|
7
|
-
ListEditorBlockData
|
|
8
|
-
from django_spire.knowledge.entry.version.block.data.text_data import \
|
|
9
|
-
TextEditorBlockData
|
|
4
|
+
from django_spire.knowledge.entry.version.block.data.heading_data import HeadingEditorBlockData
|
|
5
|
+
from django_spire.knowledge.entry.version.block.data.list.data import ListEditorBlockData
|
|
6
|
+
from django_spire.knowledge.entry.version.block.data.text_data import TextEditorBlockData
|
|
10
7
|
|
|
11
8
|
|
|
12
9
|
EDITOR_JS_BLOCK_DATA_MAP = {
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
3
5
|
from django.db import models
|
|
4
6
|
|
|
5
7
|
from django_spire.contrib.ordering.mixins import OrderingModelMixin
|
|
6
8
|
from django_spire.history.mixins import HistoryModelMixin
|
|
7
9
|
from django_spire.knowledge.entry.version.block.choices import BlockTypeChoices
|
|
8
|
-
from django_spire.knowledge.entry.version.block.data.data import BaseEditorJsBlockData
|
|
9
10
|
from django_spire.knowledge.entry.version.block.data.maps import EDITOR_JS_BLOCK_DATA_MAP
|
|
10
|
-
from django_spire.knowledge.entry.version.block.querysets import
|
|
11
|
-
|
|
12
|
-
from django_spire.knowledge.entry.version.block.services.service import \
|
|
13
|
-
EntryVersionBlockService
|
|
11
|
+
from django_spire.knowledge.entry.version.block.querysets import EntryVersionBlockQuerySet
|
|
12
|
+
from django_spire.knowledge.entry.version.block.services.service import EntryVersionBlockService
|
|
14
13
|
from django_spire.knowledge.entry.version.models import EntryVersion
|
|
15
14
|
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from django_spire.knowledge.entry.version.block.data.data import BaseEditorJsBlockData
|
|
17
|
+
|
|
16
18
|
|
|
17
19
|
class EntryVersionBlock(HistoryModelMixin, OrderingModelMixin):
|
|
18
20
|
version = models.ForeignKey(
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
from django_spire.knowledge.entry.version.block.data.
|
|
4
|
-
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from django_spire.knowledge.entry.version.block.data.heading_data import HeadingEditorBlockData
|
|
4
|
+
from django_spire.knowledge.entry.version.block.data.text_data import TextEditorBlockData
|
|
5
|
+
|
|
5
6
|
|
|
6
7
|
LADDER_SAFETY_BLOCKS = [
|
|
7
8
|
HeadingEditorBlockData(text='Ladder Safety: A Journey Through the Heights',
|
|
@@ -3,8 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
5
|
from django_spire.contrib.service import BaseDjangoModelService
|
|
6
|
-
from django_spire.knowledge.entry.version.block.services.factory_service import
|
|
7
|
-
EntryVersionBlockFactoryService
|
|
6
|
+
from django_spire.knowledge.entry.version.block.services.factory_service import EntryVersionBlockFactoryService
|
|
8
7
|
|
|
9
8
|
if TYPE_CHECKING:
|
|
10
9
|
from django_spire.knowledge.entry.version.block.models import EntryVersionBlock
|
|
@@ -12,4 +11,4 @@ if TYPE_CHECKING:
|
|
|
12
11
|
|
|
13
12
|
class EntryVersionBlockService(BaseDjangoModelService['EntryVersionBlock']):
|
|
14
13
|
obj: EntryVersionBlock
|
|
15
|
-
factory = EntryVersionBlockFactoryService()
|
|
14
|
+
factory = EntryVersionBlockFactoryService()
|