diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3945219a..fd0a6a8f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -60,6 +60,7 @@ Changed - Raise ``update_cache()`` exception for ``synccache`` in debug mode (#1375) - **Timeline** - Update ``get_object_link()`` usage for ``PluginObjectLink`` return data (#1343) + - Rename ``ProjectEvent*`` models to ``TimelineEvent*`` (#1414) - **Userprofile** - Disable global user settings on target site in ``UserSettingsForm`` (#1329) diff --git a/docs/source/dev_project_app.rst b/docs/source/dev_project_app.rst index b49eda59..165b1bc5 100644 --- a/docs/source/dev_project_app.rst +++ b/docs/source/dev_project_app.rst @@ -905,8 +905,8 @@ with the name of your application as specified in its ``ProjectAppPlugin``. .. code-block:: python - from timeline.models import ProjectEvent - ProjectEvent.objects.filter(app='app_name').delete() + from timeline.models import TimelineEvent + TimelineEvent.objects.filter(app='app_name').delete() Next you should delete existing database objects defined by the models in your app. This is also most easily done via the Django shell. Example: diff --git a/docs/source/major_changes.rst b/docs/source/major_changes.rst index 20f7c35b..8912b7b5 100644 --- a/docs/source/major_changes.rst +++ b/docs/source/major_changes.rst @@ -27,6 +27,7 @@ Release Highlights - Rewrite sodarcache REST API views - Rename AppSettingAPI "app_name" arguments to "plugin_name" - Plugin API return data updates and deprecations +- Rename timeline app models - Rename base test classes - Remove Python v3.8 support - Remove SAML SSO support @@ -153,6 +154,18 @@ in this release: REST API conventions regarding URLs and return data. See the API documentation and refactor your client code accordingly. +Timeline Models Renamed +----------------------- + +Models in the timeline app have been renamed from ``ProjectEvent*`` to +``TimelineEvent*``. This is done to better reflect the fact that events are not +necessarily tied to projects. + +If your site only accesses these models through ``TimelineAPI`` and +``TimelineAPI.get_model()``, which is the strongly recommended way, no changes +should be required. + + AppSettingAPI Plugin Name Arguments Updated ------------------------------------------- diff --git a/projectroles/tests/test_views.py b/projectroles/tests/test_views.py index 587e92a9..37d05782 100644 --- a/projectroles/tests/test_views.py +++ b/projectroles/tests/test_views.py @@ -16,10 +16,10 @@ from test_plus.test import TestCase # Timeline dependency -from timeline.models import ProjectEvent +from timeline.models import TimelineEvent from timeline.tests.test_models import ( - ProjectEventMixin, - ProjectEventStatusMixin, + TimelineEventMixin, + TimelineEventStatusMixin, ) from projectroles.app_settings import AppSettingAPI @@ -270,8 +270,8 @@ class TestProjectSearchResultsView( ProjectMixin, RoleAssignmentMixin, ViewTestBase, - ProjectEventMixin, - ProjectEventStatusMixin, + TimelineEventMixin, + TimelineEventStatusMixin, ): """Tests for ProjectSearchResultsView""" @@ -1409,11 +1409,11 @@ class TestProjectArchiveView( @classmethod def _get_tl(cls): - return ProjectEvent.objects.filter(event_name='project_archive') + return TimelineEvent.objects.filter(event_name='project_archive') @classmethod def _get_tl_un(cls): - return ProjectEvent.objects.filter(event_name='project_unarchive') + return TimelineEvent.objects.filter(event_name='project_unarchive') def _get_alerts(self): return self.app_alert_model.objects.filter(alert_name='project_archive') @@ -4323,7 +4323,7 @@ def test_get_role_exists(self): self.make_assignment(self.project, invited_user, self.role_guest) self.assertTrue(invite.active) self.assertIsNone( - ProjectEvent.objects.filter(event_name='invite_accept').first() + TimelineEvent.objects.filter(event_name='invite_accept').first() ) with self.login(invited_user): @@ -4339,7 +4339,7 @@ def test_get_role_exists(self): self.assertFalse(invite.active) # No timeline event should be created self.assertIsNone( - ProjectEvent.objects.filter(event_name='invite_accept').first() + TimelineEvent.objects.filter(event_name='invite_accept').first() ) @@ -4548,7 +4548,7 @@ def test_post_source(self): """Test RemoteSiteCreateView POST as source site""" self.assertEqual( 0, - ProjectEvent.objects.filter( + TimelineEvent.objects.filter( event_name='target_site_create' ).count(), ) @@ -4578,7 +4578,7 @@ def test_post_source(self): model_dict = model_to_dict(site) self.assertEqual(model_dict, expected) - tl_event = ProjectEvent.objects.filter( + tl_event = TimelineEvent.objects.filter( event_name='target_site_create' ).first() self.assertEqual(tl_event.event_name, 'target_site_create') @@ -4590,7 +4590,7 @@ def test_post_target(self): """Test POST as target""" self.assertEqual( 0, - ProjectEvent.objects.filter(event_name='source_site_set').count(), + TimelineEvent.objects.filter(event_name='source_site_set').count(), ) self.assertEqual(RemoteSite.objects.all().count(), 0) values = { @@ -4619,7 +4619,7 @@ def test_post_target(self): model_dict = model_to_dict(site) self.assertEqual(model_dict, expected) - tl_event = ProjectEvent.objects.filter( + tl_event = TimelineEvent.objects.filter( event_name='source_site_set' ).first() self.assertEqual(tl_event.event_name, 'source_site_set') @@ -4695,7 +4695,7 @@ def test_post(self): """Test RemoteSiteUpdateView POST as source""" self.assertEqual( 0, - ProjectEvent.objects.filter( + TimelineEvent.objects.filter( event_name='target_site_update' ).count(), ) @@ -4725,7 +4725,7 @@ def test_post(self): model_dict = model_to_dict(site) self.assertEqual(model_dict, expected) - tl_event = ProjectEvent.objects.filter( + tl_event = TimelineEvent.objects.filter( event_name='target_site_update' ).first() self.assertEqual(tl_event.event_name, 'target_site_update') @@ -4800,7 +4800,7 @@ def test_post(self): """Test RemoteSiteDeleteView POST""" self.assertEqual( 0, - ProjectEvent.objects.filter( + TimelineEvent.objects.filter( event_name='target_site_delete' ).count(), ) @@ -4808,7 +4808,7 @@ def test_post(self): with self.login(self.user): response = self.client.post(self.url) self.assertRedirects(response, reverse('projectroles:remote_sites')) - tl_event = ProjectEvent.objects.filter( + tl_event = TimelineEvent.objects.filter( event_name='target_site_delete' ).first() self.assertEqual(tl_event.event_name, 'target_site_delete') @@ -4857,7 +4857,7 @@ def test_post_confirm(self): response = self.client.post(self.url, values) self.assertEqual( 0, - ProjectEvent.objects.filter( + TimelineEvent.objects.filter( event_name='remote_access_update' ).count(), ) @@ -4881,7 +4881,7 @@ def test_post_confirm_no_change(self): self.assertEqual( 0, - ProjectEvent.objects.filter( + TimelineEvent.objects.filter( event_name='remote_access_update' ).count(), ) @@ -4890,7 +4890,7 @@ def test_post_create(self): """Test POST to create new RemoteProject""" self.assertEqual( 0, - ProjectEvent.objects.filter( + TimelineEvent.objects.filter( event_name='remote_batch_update' ).count(), ) @@ -4915,7 +4915,7 @@ def test_post_create(self): self.assertEqual(rp.project_uuid, self.project.sodar_uuid) self.assertEqual(rp.level, SODAR_CONSTANTS['REMOTE_LEVEL_READ_INFO']) - tl_event = ProjectEvent.objects.filter( + tl_event = TimelineEvent.objects.filter( event_name='remote_batch_update' ).first() self.assertEqual(tl_event.event_name, 'remote_batch_update') @@ -4924,7 +4924,7 @@ def test_post_update(self): """Test POST to update existing RemoteProject""" self.assertEqual( 0, - ProjectEvent.objects.filter( + TimelineEvent.objects.filter( event_name='remote_batch_update' ).count(), ) @@ -4955,7 +4955,7 @@ def test_post_update(self): self.assertEqual(rp.project_uuid, self.project.sodar_uuid) self.assertEqual(rp.level, SODAR_CONSTANTS['REMOTE_LEVEL_READ_INFO']) - tl_event = ProjectEvent.objects.filter( + tl_event = TimelineEvent.objects.filter( event_name='remote_batch_update' ).first() self.assertEqual(tl_event.event_name, 'remote_batch_update') diff --git a/projectroles/tests/test_views_api.py b/projectroles/tests/test_views_api.py index ef46de64..0f181e2e 100644 --- a/projectroles/tests/test_views_api.py +++ b/projectroles/tests/test_views_api.py @@ -16,7 +16,7 @@ from test_plus.test import APITestCase # Timeline dependency -from timeline.models import ProjectEvent +from timeline.models import TimelineEvent from projectroles import views_api from projectroles.app_settings import AppSettingAPI @@ -2827,7 +2827,7 @@ def test_post_project(self): """Test TestProjectSettingSetAPIView POST with PROJECT scope setting""" self.assertEqual(AppSetting.objects.count(), 0) self.assertIsNone( - ProjectEvent.objects.filter( + TimelineEvent.objects.filter( event_name='app_setting_set_api' ).first() ) @@ -2843,7 +2843,7 @@ def test_post_project(self): self.assertEqual(AppSetting.objects.count(), 1) obj = AppSetting.objects.get(name=setting_name, project=self.project) self.assertEqual(obj.get_value(), 'value') - tl_event = ProjectEvent.objects.filter( + tl_event = TimelineEvent.objects.filter( event_name='app_setting_set_api' ).first() self.assertIsNotNone(tl_event) @@ -3078,7 +3078,7 @@ def test_post(self): """Test UserSettingSetAPIView POST""" self.assertEqual(AppSetting.objects.count(), 0) self.assertIsNone( - ProjectEvent.objects.filter( + TimelineEvent.objects.filter( event_name='app_setting_set_api' ).first() ) @@ -3095,7 +3095,7 @@ def test_post(self): obj = AppSetting.objects.get(name=setting_name, user=self.user) self.assertEqual(obj.get_value(), 'value') self.assertIsNone( - ProjectEvent.objects.filter( + TimelineEvent.objects.filter( event_name='app_setting_set_api' ).first() ) diff --git a/timeline/admin.py b/timeline/admin.py index c58d1227..44efb3e4 100644 --- a/timeline/admin.py +++ b/timeline/admin.py @@ -1,8 +1,8 @@ from django.contrib import admin -from .models import ProjectEvent, ProjectEventObjectRef, ProjectEventStatus +from .models import TimelineEvent, TimelineEventObjectRef, TimelineEventStatus -admin.site.register(ProjectEvent) -admin.site.register(ProjectEventObjectRef) -admin.site.register(ProjectEventStatus) +admin.site.register(TimelineEvent) +admin.site.register(TimelineEventObjectRef) +admin.site.register(TimelineEventStatus) diff --git a/timeline/api.py b/timeline/api.py index 8a25d8f0..25183533 100644 --- a/timeline/api.py +++ b/timeline/api.py @@ -15,8 +15,8 @@ from projectroles.utils import get_app_names from timeline.models import ( - ProjectEvent, - ProjectEventObjectRef, + TimelineEvent, + TimelineEventObjectRef, EVENT_STATUS_TYPES, OBJ_REF_UNNAMED, ) @@ -123,7 +123,7 @@ def _get_ref_description(cls, event, ref_label, app_plugin, request): Get reference object description for event description, or unknown label if not found. - :param event: ProjectEvent object + :param event: TimelineEvent object :param ref_label: Label for the reference object (string) :param app_plugin: App plugin or None :param request: Request object or None @@ -136,10 +136,10 @@ def _get_ref_description(cls, event, ref_label, app_plugin, request): # Get object reference try: - obj_ref = ProjectEventObjectRef.objects.get( + obj_ref = TimelineEventObjectRef.objects.get( event=event, label=ref_label ) - except ProjectEventObjectRef.DoesNotExist: + except TimelineEventObjectRef.DoesNotExist: return UNKNOWN_LABEL # Special case: User model @@ -238,7 +238,7 @@ def add_event( :param status_extra_data: Extra data for initial status (dict, optional) :param plugin_name: Name of plugin to which the event is related (optional, plugin with the name of the app is assumed if unset) - :return: ProjectEvent object + :return: TimelineEvent object :raise: ValueError if app_name or status_type is invalid """ if app_name not in APP_NAMES: @@ -258,7 +258,7 @@ def add_event( if user and user.is_anonymous: user = None - event = ProjectEvent() + event = TimelineEvent() event.project = project event.app = app_name event.plugin = plugin_name @@ -287,7 +287,7 @@ def get_project_events(cls, project, classified=False): :param classified: Include classified (boolean) :return: QuerySet """ - events = ProjectEvent.objects.filter(project=project) + events = TimelineEvent.objects.filter(project=project) if not classified: events = events.filter(classified=False) return events @@ -297,7 +297,7 @@ def get_event_description(cls, event, plugin_lookup=None, request=None): """ Return the description of a timeline event as HTML. - :param event: ProjectEvent object + :param event: TimelineEvent object :param plugin_lookup: App plugin lookup dict (optional) :param request: Request object (optional) :return: String (contains HTML) @@ -376,8 +376,8 @@ def get_object_link(cls, obj, project=None): @classmethod def get_models(cls): """ - Return project event model classes for custom/advanced queries. + Return timeline event model classes for custom/advanced queries. - :return: ProjectEvent, ProjectEventObjectRef + :return: TimelineEvent, TimelineEventObjectRef """ - return ProjectEvent, ProjectEventObjectRef + return TimelineEvent, TimelineEventObjectRef diff --git a/timeline/migrations/0012_rename_models.py b/timeline/migrations/0012_rename_models.py new file mode 100644 index 00000000..1316e6ff --- /dev/null +++ b/timeline/migrations/0012_rename_models.py @@ -0,0 +1,28 @@ +# Generated by Django 4.2.11 on 2024-04-17 15:55 + +from django.conf import settings +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("projectroles", "0028_populate_finder_role"), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("timeline", "0011_make_uuid_unique"), + ] + + operations = [ + migrations.RenameModel( + old_name="ProjectEvent", + new_name="TimelineEvent", + ), + migrations.RenameModel( + old_name="ProjectEventObjectRef", + new_name="TimelineEventObjectRef", + ), + migrations.RenameModel( + old_name="ProjectEventStatus", + new_name="TimelineEventStatus", + ), + ] diff --git a/timeline/models.py b/timeline/models.py index 100cecf7..f17b9a9b 100644 --- a/timeline/models.py +++ b/timeline/models.py @@ -29,8 +29,8 @@ OBJ_REF_UNNAMED = '(unnamed)' -class ProjectEventManager(models.Manager): - """Manager for custom table-level ProjectEvent queries""" +class TimelineEventManager(models.Manager): + """Manager for custom table-level TimelineEvent queries""" def get_object_events( self, project, object_model, object_uuid, order_by='-pk' @@ -44,7 +44,7 @@ def get_object_events( :param order_by: Ordering (default = pk descending) :return: QuerySet """ - return ProjectEvent.objects.filter( + return TimelineEvent.objects.filter( project=project, event_objects__object_model=object_model, event_objects__object_uuid=object_uuid, @@ -56,7 +56,7 @@ def find(self, search_terms, keywords=None): :param search_terms: Search terms (list of strings) :param keywords: Optional search keywords as key/value pairs (dict) - :return: QuerySet of ProjectEvent objects + :return: QuerySet of TimelineEvent objects """ search_limit = getattr(settings, 'TIMELINE_SEARCH_LIMIT', 250) term_query = Q() @@ -73,7 +73,7 @@ def find(self, search_terms, keywords=None): return items[:search_limit] -class ProjectEvent(models.Model): +class TimelineEvent(models.Model): """ Class representing a Project event. Can also be a site-wide event not linked to a specific project. @@ -137,7 +137,7 @@ class ProjectEvent(models.Model): ) # Set manager for custom queries - objects = ProjectEventManager() + objects = TimelineEventManager() def __str__(self): return '{}{}{}'.format( @@ -147,7 +147,7 @@ def __str__(self): ) def __repr__(self): - return 'ProjectEvent({})'.format( + return 'TimelineEvent({})'.format( ', '.join(repr(v) for v in self.get_repr_values()) ) @@ -180,9 +180,9 @@ def add_object(self, obj, label, name, extra_data=None): :param label: Label for the object in the event description (string) :param name: Name or title of the object (string) :param extra_data: Additional data related to object (dict, optional) - :return: ProjectEventObjectRef object + :return: TimelineEventObjectRef object """ - ref = ProjectEventObjectRef() + ref = TimelineEventObjectRef() ref.event = self ref.label = label if not name: @@ -207,7 +207,7 @@ def set_status(self, status_type, status_desc=None, extra_data=None): :param status_type: Status type string (see EVENT_STATUS_TYPES) :param status_desc: Description string (optional) :param extra_data: Extra data for the status (dict, optional) - :return: ProjectEventStatus object + :return: TimelineEventStatus object :raise: TypeError if status_type is invalid """ if status_type not in EVENT_STATUS_TYPES: @@ -217,7 +217,7 @@ def set_status(self, status_type, status_desc=None, extra_data=None): ) ) - status = ProjectEventStatus() + status = TimelineEventStatus() status.event = self status.status_type = status_type status.description = ( @@ -229,13 +229,13 @@ def set_status(self, status_type, status_desc=None, extra_data=None): return status -class ProjectEventObjectRef(models.Model): +class TimelineEventObjectRef(models.Model): """Class representing a reference to an object (existing or removed) related to a Timeline event status""" #: Event to which the object belongs event = models.ForeignKey( - ProjectEvent, + TimelineEvent, related_name='event_objects', help_text='Event to which the object belongs', on_delete=models.CASCADE, @@ -283,17 +283,17 @@ def __str__(self): def __repr__(self): values = self.event.get_repr_values() + [self.name] - return 'ProjectEventObjectRef({})'.format( + return 'TimelineEventObjectRef({})'.format( ', '.join(repr(v) for v in values) ) -class ProjectEventStatus(models.Model): +class TimelineEventStatus(models.Model): """Class representing a Timeline event status""" #: Event to which the status change belongs event = models.ForeignKey( - ProjectEvent, + TimelineEvent, related_name='status_changes', help_text='Event to which the status change belongs', on_delete=models.CASCADE, @@ -335,7 +335,7 @@ def __str__(self): def __repr__(self): values = self.event.get_repr_values() + [self.status_type] - return 'ProjectEventStatus({})'.format( + return 'TimelineEventStatus({})'.format( ', '.join(repr(v) for v in values) ) diff --git a/timeline/plugins.py b/timeline/plugins.py index 9009ea17..8dd0a1a9 100644 --- a/timeline/plugins.py +++ b/timeline/plugins.py @@ -11,7 +11,7 @@ from projectroles.utils import get_display_name from timeline.api import TimelineAPI -from timeline.models import ProjectEvent +from timeline.models import TimelineEvent from timeline.urls import urls_ui_project, urls_ui_site, urls_ui_admin @@ -73,7 +73,7 @@ def get_statistics(self): return { 'event_count': { 'label': 'Events', - 'value': ProjectEvent.objects.all().count(), + 'value': TimelineEvent.objects.all().count(), } } @@ -106,7 +106,7 @@ def search(self, search_terms, user, search_type=None, keywords=None): """ items = [] if not search_type or search_type == 'timeline': - events = ProjectEvent.objects.find(search_terms, keywords) + events = TimelineEvent.objects.find(search_terms, keywords) if events: items = [ event diff --git a/timeline/templates/timeline/_list_item.html b/timeline/templates/timeline/_list_item.html index da757ecd..a9eba480 100644 --- a/timeline/templates/timeline/_list_item.html +++ b/timeline/templates/timeline/_list_item.html @@ -10,12 +10,12 @@ {% get_timestamp event as event_time %} {% if event.project %} + data-url="{% url 'timeline:ajax_detail_project' timelineevent=event.sodar_uuid %}"> {{ event_time }} {% else %} + data-url="{% url 'timeline:ajax_detail_site' timelineevent=event.sodar_uuid %}"> {{ event_time }} {% endif %} @@ -46,14 +46,14 @@ {% if not details_card_mode and event.extra_data %} {% if event.project and can_view_extra_data %} + data-url="{% url 'timeline:ajax_extra_project' timelineevent=event.sodar_uuid %}"> {% elif not event.project and user.is_superuser %} + data-url="{% url 'timeline:ajax_extra_site' timelineevent=event.sodar_uuid %}"> diff --git a/timeline/templatetags/timeline_tags.py b/timeline/templatetags/timeline_tags.py index 0e58c45d..017fa2b2 100644 --- a/timeline/templatetags/timeline_tags.py +++ b/timeline/templatetags/timeline_tags.py @@ -9,7 +9,7 @@ from projectroles.plugins import ProjectAppPluginPoint from timeline.api import TimelineAPI -from timeline.models import ProjectEvent +from timeline.models import TimelineEvent logger = logging.getLogger(__name__) @@ -37,7 +37,7 @@ def get_timestamp(event): """Return printable timestamp of event in local timezone""" try: return localtime(event.get_timestamp()).strftime('%Y-%m-%d %H:%M:%S') - except Exception: # Handle error cases where ProjectEventStatus is missing + except Exception: # Handle error cases where TimelineEventStatus is missing return 'N/A' @@ -51,7 +51,7 @@ def get_event_description(event, plugin_lookup, request=None): def get_details_events(project, view_classified=False): """Return recent events for card on project details page""" c_kwargs = {'classified': False} if not view_classified else {} - return ProjectEvent.objects.filter(project=project, **c_kwargs).order_by( + return TimelineEvent.objects.filter(project=project, **c_kwargs).order_by( '-pk' )[:5] diff --git a/timeline/tests/test_api.py b/timeline/tests/test_api.py index 9ca86569..8fdb99e4 100644 --- a/timeline/tests/test_api.py +++ b/timeline/tests/test_api.py @@ -18,14 +18,14 @@ from filesfolders.tests.test_models import FolderMixin from timeline.tests.test_models import ( - ProjectEventTestBase, - ProjectEventMixin, - ProjectEventStatusMixin, + TimelineEventTestBase, + TimelineEventMixin, + TimelineEventStatusMixin, ) from timeline.models import ( - ProjectEvent, - ProjectEventStatus, - ProjectEventObjectRef, + TimelineEvent, + TimelineEventStatus, + TimelineEventObjectRef, DEFAULT_MESSAGES, ) from timeline.templatetags import timeline_tags as tags @@ -55,11 +55,11 @@ def get_request(cls, user, project): class TestTimelineAPI( TimelineAPIMixin, - ProjectEventMixin, - ProjectEventStatusMixin, + TimelineEventMixin, + TimelineEventStatusMixin, RemoteSiteMixin, FolderMixin, - ProjectEventTestBase, + TimelineEventTestBase, ): def setUp(self): super().setUp() @@ -70,8 +70,8 @@ def setUp(self): def test_add_event(self): """Test adding an event""" - self.assertEqual(ProjectEvent.objects.all().count(), 0) - self.assertEqual(ProjectEventStatus.objects.all().count(), 0) + self.assertEqual(TimelineEvent.objects.all().count(), 0) + self.assertEqual(TimelineEventStatus.objects.all().count(), 0) event = self.timeline.add_event( project=self.project, @@ -82,8 +82,8 @@ def test_add_event(self): extra_data={'test_key': 'test_val'}, ) - self.assertEqual(ProjectEvent.objects.all().count(), 1) - self.assertEqual(ProjectEventStatus.objects.all().count(), 1) # Init + self.assertEqual(TimelineEvent.objects.all().count(), 1) + self.assertEqual(TimelineEventStatus.objects.all().count(), 1) # Init expected = { 'id': event.pk, @@ -112,8 +112,8 @@ def test_add_event(self): def test_add_event_with_status(self): """Test adding an event with status""" - self.assertEqual(ProjectEvent.objects.all().count(), 0) - self.assertEqual(ProjectEventStatus.objects.all().count(), 0) + self.assertEqual(TimelineEvent.objects.all().count(), 0) + self.assertEqual(TimelineEventStatus.objects.all().count(), 0) event = self.timeline.add_event( project=self.project, @@ -128,8 +128,8 @@ def test_add_event_with_status(self): ) status = event.get_status() - self.assertEqual(ProjectEvent.objects.all().count(), 1) - self.assertEqual(ProjectEventStatus.objects.all().count(), 2) + self.assertEqual(TimelineEvent.objects.all().count(), 1) + self.assertEqual(TimelineEventStatus.objects.all().count(), 2) expected_event = { 'id': event.pk, @@ -158,8 +158,8 @@ def test_add_event_with_status(self): def test_add_event_custom_init(self): """Test adding an event with custom INIT status""" custom_init_desc = 'Custom init' - self.assertEqual(ProjectEvent.objects.all().count(), 0) - self.assertEqual(ProjectEventStatus.objects.all().count(), 0) + self.assertEqual(TimelineEvent.objects.all().count(), 0) + self.assertEqual(TimelineEventStatus.objects.all().count(), 0) event = self.timeline.add_event( project=self.project, @@ -172,8 +172,8 @@ def test_add_event_custom_init(self): status_desc=custom_init_desc, ) - self.assertEqual(ProjectEvent.objects.all().count(), 1) - self.assertEqual(ProjectEventStatus.objects.all().count(), 1) # Init + self.assertEqual(TimelineEvent.objects.all().count(), 1) + self.assertEqual(TimelineEventStatus.objects.all().count(), 1) # Init status = event.get_status() expected_status = { @@ -188,8 +188,8 @@ def test_add_event_custom_init(self): def test_add_event_no_user(self): """Test adding an event with no user""" - self.assertEqual(ProjectEvent.objects.all().count(), 0) - self.assertEqual(ProjectEventStatus.objects.all().count(), 0) + self.assertEqual(TimelineEvent.objects.all().count(), 0) + self.assertEqual(TimelineEventStatus.objects.all().count(), 0) event = self.timeline.add_event( project=self.project, @@ -200,8 +200,8 @@ def test_add_event_no_user(self): extra_data={'test_key': 'test_val'}, ) - self.assertEqual(ProjectEvent.objects.all().count(), 1) - self.assertEqual(ProjectEventStatus.objects.all().count(), 1) + self.assertEqual(TimelineEvent.objects.all().count(), 1) + self.assertEqual(TimelineEventStatus.objects.all().count(), 1) expected = { 'id': event.pk, @@ -219,8 +219,8 @@ def test_add_event_no_user(self): def test_add_event_anon_user(self): """Test adding an event with AnonymousUser""" - self.assertEqual(ProjectEvent.objects.all().count(), 0) - self.assertEqual(ProjectEventStatus.objects.all().count(), 0) + self.assertEqual(TimelineEvent.objects.all().count(), 0) + self.assertEqual(TimelineEventStatus.objects.all().count(), 0) event = self.timeline.add_event( project=self.project, @@ -231,14 +231,14 @@ def test_add_event_anon_user(self): extra_data={'test_key': 'test_val'}, ) - self.assertEqual(ProjectEvent.objects.all().count(), 1) - self.assertEqual(ProjectEventStatus.objects.all().count(), 1) + self.assertEqual(TimelineEvent.objects.all().count(), 1) + self.assertEqual(TimelineEventStatus.objects.all().count(), 1) self.assertIsNone(event.user) def test_add_event_invalid_app(self): """Test adding an event with an invalid app name (should fail)""" - self.assertEqual(ProjectEvent.objects.all().count(), 0) - self.assertEqual(ProjectEventStatus.objects.all().count(), 0) + self.assertEqual(TimelineEvent.objects.all().count(), 0) + self.assertEqual(TimelineEventStatus.objects.all().count(), 0) with self.assertRaises(ValueError): self.timeline.add_event( @@ -250,13 +250,13 @@ def test_add_event_invalid_app(self): extra_data={'test_key': 'test_val'}, ) - self.assertEqual(ProjectEvent.objects.all().count(), 0) - self.assertEqual(ProjectEventStatus.objects.all().count(), 0) + self.assertEqual(TimelineEvent.objects.all().count(), 0) + self.assertEqual(TimelineEventStatus.objects.all().count(), 0) def test_add_event_invalid_status(self): """Test adding an event with an invalid status type""" - self.assertEqual(ProjectEvent.objects.all().count(), 0) - self.assertEqual(ProjectEventStatus.objects.all().count(), 0) + self.assertEqual(TimelineEvent.objects.all().count(), 0) + self.assertEqual(TimelineEventStatus.objects.all().count(), 0) with self.assertRaises(ValueError): self.timeline.add_event( @@ -269,12 +269,12 @@ def test_add_event_invalid_status(self): extra_data={'test_key': 'test_val'}, ) - self.assertEqual(ProjectEvent.objects.all().count(), 0) - self.assertEqual(ProjectEventStatus.objects.all().count(), 0) + self.assertEqual(TimelineEvent.objects.all().count(), 0) + self.assertEqual(TimelineEventStatus.objects.all().count(), 0) def test_add_object(self): """Test adding an object to an event""" - self.assertEqual(ProjectEventObjectRef.objects.all().count(), 0) + self.assertEqual(TimelineEventObjectRef.objects.all().count(), 0) event = self.timeline.add_event( project=self.project, @@ -292,7 +292,7 @@ def test_add_object(self): extra_data={'test_key': 'test_val'}, ) - self.assertEqual(ProjectEventObjectRef.objects.all().count(), 1) + self.assertEqual(TimelineEventObjectRef.objects.all().count(), 1) expected = { 'id': ref.pk, 'event': event.pk, diff --git a/timeline/tests/test_models.py b/timeline/tests/test_models.py index b50c0196..231f2906 100644 --- a/timeline/tests/test_models.py +++ b/timeline/tests/test_models.py @@ -13,9 +13,9 @@ ) from timeline.models import ( - ProjectEvent, - ProjectEventObjectRef, - ProjectEventStatus, + TimelineEvent, + TimelineEventObjectRef, + TimelineEventStatus, OBJ_REF_UNNAMED, ) @@ -29,8 +29,8 @@ PROJECT_TYPE_PROJECT = SODAR_CONSTANTS['PROJECT_TYPE_PROJECT'] -class ProjectEventMixin: - """Helper mixin for ProjectEvent creation""" +class TimelineEventMixin: + """Helper mixin for TimelineEvent creation""" @classmethod def make_event( @@ -54,13 +54,13 @@ def make_event( 'extra_data': extra_data or {}, 'plugin': plugin, } - result = ProjectEvent(**values) + result = TimelineEvent(**values) result.save() return result -class ProjectEventObjectRefMixin: - """Helper mixin for ProjectEventObjectRef creation""" +class TimelineEventObjectRefMixin: + """Helper mixin for TimelineEventObjectRef creation""" @classmethod def make_object_ref(cls, event, obj, label, name, uuid, extra_data=None): @@ -72,13 +72,13 @@ def make_object_ref(cls, event, obj, label, name, uuid, extra_data=None): 'object_uuid': uuid, 'extra_data': extra_data or {}, } - result = ProjectEventObjectRef(**values) + result = TimelineEventObjectRef(**values) result.save() return result -class ProjectEventStatusMixin: - """Helper mixin for ProjectEventStatus creation""" +class TimelineEventStatusMixin: + """Helper mixin for TimelineEventStatus creation""" @classmethod def make_event_status( @@ -90,12 +90,12 @@ def make_event_status( 'description': description, 'extra_data': extra_data or {'test': 'test'}, } - result = ProjectEventStatus(**values) + result = TimelineEventStatus(**values) result.save() return result -class ProjectEventTestBase( +class TimelineEventTestBase( ProjectMixin, RoleMixin, RoleAssignmentMixin, TestCase ): def setUp(self): @@ -112,11 +112,11 @@ def setUp(self): ) -class TestProjectEvent( - ProjectEventMixin, - ProjectEventStatusMixin, - ProjectEventObjectRefMixin, - ProjectEventTestBase, +class TestTimelineEvent( + TimelineEventMixin, + TimelineEventStatusMixin, + TimelineEventObjectRefMixin, + TimelineEventTestBase, ): def setUp(self): super().setUp() @@ -140,7 +140,7 @@ def setUp(self): ) def test_initialization(self): - """Test ProjectEvent initialization""" + """Test TimelineEvent initialization""" expected = { 'id': self.event.pk, 'project': self.project.pk, @@ -156,7 +156,7 @@ def test_initialization(self): self.assertEqual(model_to_dict(self.event), expected) def test_initialization_no_project(self): - """Test ProjectEvent initialization with no project""" + """Test TimelineEvent initialization with no project""" self.event = self.make_event( project=None, app='projectroles', @@ -181,7 +181,7 @@ def test_initialization_no_project(self): self.assertEqual(model_to_dict(self.event), expected) def test_initialization_no_user(self): - """Test ProjectEvent initialization with no user""" + """Test TimelineEvent initialization with no user""" self.event = self.make_event( project=self.project, app='projectroles', @@ -206,7 +206,7 @@ def test_initialization_no_user(self): self.assertEqual(model_to_dict(self.event), expected) def test_initialization_plugin(self): - """Test ProjectEvent initialization with specific plugin name""" + """Test TimelineEvent initialization with specific plugin name""" self.event = self.make_event( project=None, app='projectroles', @@ -232,26 +232,26 @@ def test_initialization_plugin(self): self.assertEqual(model_to_dict(self.event), expected) def test_str(self): - """Test ProjectEvent __str__()""" + """Test TimelineEvent __str__()""" expected = 'TestProject: test_event/owner' self.assertEqual(str(self.event), expected) def test_str_no_user(self): - """Test ProjectEvent __str__() with no user""" + """Test TimelineEvent __str__() with no user""" self.event.user = None self.event.save() expected = 'TestProject: test_event' self.assertEqual(str(self.event), expected) def test_str_no_project(self): - """Test ProjectEvent __str__() with no project""" + """Test TimelineEvent __str__() with no project""" self.event.project = None self.event.save() expected = 'test_event/owner' self.assertEqual(str(self.event), expected) def test_str_no_project_no_user(self): - """Test ProjectEvent __str__() with no project or user""" + """Test TimelineEvent __str__() with no project or user""" self.event.project = None self.event.user = None self.event.save() @@ -259,30 +259,30 @@ def test_str_no_project_no_user(self): self.assertEqual(str(self.event), expected) def test_repr(self): - """Test ProjectEventStatus __repr__()""" - expected = "ProjectEvent('TestProject', 'test_event', 'owner')" + """Test TimelineEvent __repr__()""" + expected = "TimelineEvent('TestProject', 'test_event', 'owner')" self.assertEqual(repr(self.event), expected) def test_repr_no_user(self): - """Test ProjectEventStatus __repr__() with no user""" + """Test TimelineEvent __repr__() with no user""" self.event.user = None self.event.save() - expected = "ProjectEvent('TestProject', 'test_event', 'N/A')" + expected = "TimelineEvent('TestProject', 'test_event', 'N/A')" self.assertEqual(repr(self.event), expected) def test_repr_no_project(self): - """Test ProjectEventStatus __repr__() with no project""" + """Test TimelineEvent __repr__() with no project""" self.event.project = None self.event.save() - expected = "ProjectEvent('N/A', 'test_event', 'owner')" + expected = "TimelineEvent('N/A', 'test_event', 'owner')" self.assertEqual(repr(self.event), expected) def test_repr_no_project_no_user(self): - """Test ProjectEventStatus __repr__() with no project or user""" + """Test TimelineEvent __repr__() with no project or user""" self.event.project = None self.event.user = None self.event.save() - expected = "ProjectEvent('N/A', 'test_event', 'N/A')" + expected = "TimelineEvent('N/A', 'test_event', 'N/A')" self.assertEqual(repr(self.event), expected) def test_add_object(self): @@ -316,31 +316,31 @@ def test_add_object_no_name(self): self.assertEqual(new_obj.name, OBJ_REF_UNNAMED) def test_find_name(self): - """Test ProjectEvent.find() with event name""" - objects = ProjectEvent.objects.find(['test_event']) + """Test TimelineEvent.find() with event name""" + objects = TimelineEvent.objects.find(['test_event']) self.assertEqual(len(objects), 1) self.assertEqual(objects[0], self.event) def test_find_description(self): - """Test ProjectEvent.find() with event description""" - objects = ProjectEvent.objects.find(['description']) + """Test TimelineEvent.find() with event description""" + objects = TimelineEvent.objects.find(['description']) self.assertEqual(len(objects), 1) self.assertEqual(objects[0], self.event) def test_find_object(self): - """Test ProjectEvent.find() with object reference""" - objects = ProjectEvent.objects.find(['test_object_name']) + """Test TimelineEvent.find() with object reference""" + objects = TimelineEvent.objects.find(['test_object_name']) self.assertEqual(len(objects), 1) self.assertEqual(objects[0], self.event) def test_find_fail(self): - """Test ProjectEvent.find() with no matches""" - objects = ProjectEvent.objects.find(['asdfasdfafasdf']) + """Test TimelineEvent.find() with no matches""" + objects = TimelineEvent.objects.find(['asdfasdfafasdf']) self.assertEqual(len(objects), 0) -class TestProjectEventObjectRef( - ProjectEventMixin, ProjectEventObjectRefMixin, ProjectEventTestBase +class TestTimelineEventObjectRef( + TimelineEventMixin, TimelineEventObjectRefMixin, TimelineEventTestBase ): def setUp(self): super().setUp() @@ -363,7 +363,7 @@ def setUp(self): ) def test_initialization(self): - """Test ProjectEventObject initialization""" + """Test TimelineEventObjectRef initialization""" expected = { 'id': self.obj_ref.pk, 'event': self.event.pk, @@ -376,21 +376,21 @@ def test_initialization(self): self.assertEqual(model_to_dict(self.obj_ref), expected) def test__str__(self): - """Test ProjectEventObject __str__()""" + """Test TimelineEventObjectRef __str__()""" expected = 'TestProject: test_event/owner (test_name)' self.assertEqual(str(self.obj_ref), expected) def test__repr__(self): - """Test ProjectEventObject __repr__()""" + """Test TimelineEventObjectRef __repr__()""" expected = ( - "ProjectEventObjectRef('TestProject', 'test_event', " + "TimelineEventObjectRef('TestProject', 'test_event', " "'owner', 'test_name')" ) self.assertEqual(repr(self.obj_ref), expected) def test_get_object_events(self): - """Test get_object_events() in ProjectEventManager""" - events = ProjectEvent.objects.get_object_events( + """Test get_object_events() in TimelineEventManager""" + events = TimelineEvent.objects.get_object_events( project=self.project, object_model=self.obj_ref.object_model, object_uuid=self.obj_ref.object_uuid, @@ -399,8 +399,8 @@ def test_get_object_events(self): self.assertEqual(events[0], self.event) -class TestProjectEventStatus( - ProjectEventMixin, ProjectEventStatusMixin, ProjectEventTestBase +class TestTimelineEventStatus( + TimelineEventMixin, TimelineEventStatusMixin, TimelineEventTestBase ): def setUp(self): super().setUp() @@ -427,7 +427,7 @@ def setUp(self): ) def test_initialization(self): - """Test ProjectEventStatus init""" + """Test TimelineEventStatus init""" expected = { 'id': self.event_status_ok.pk, 'sodar_uuid': self.event_status_ok.sodar_uuid, @@ -439,7 +439,7 @@ def test_initialization(self): self.assertEqual(model_to_dict(self.event_status_ok), expected) def test_initialization_no_user(self): - """Test ProjectEventStatus without user""" + """Test TimelineEventStatus without user""" expected = { 'id': self.event_status_ok.pk, 'sodar_uuid': self.event_status_ok.sodar_uuid, @@ -460,7 +460,7 @@ def test_initialization_no_user(self): self.assertEqual(model_to_dict(self.event_status_ok), expected) def test__str__(self): - """Test ProjectEventStatus __str__()""" + """Test TimelineEventStatus __str__()""" expected = 'TestProject: test_event/owner (OK)' self.assertEqual(str(self.event_status_ok), expected) @@ -472,9 +472,9 @@ def test__str__no_user(self): self.assertEqual(str(self.event_status_ok), expected) def test__repr__(self): - """Test ProjectEventStatus __repr__()""" + """Test TimelineEventStatus __repr__()""" expected = ( - "ProjectEventStatus('TestProject', 'test_event', 'owner', 'OK')" + "TimelineEventStatus('TestProject', 'test_event', 'owner', 'OK')" ) self.assertEqual(repr(self.event_status_ok), expected) @@ -483,12 +483,12 @@ def test__repr__no_user(self): self.event.user = None self.event.save() expected = ( - "ProjectEventStatus('TestProject', 'test_event', 'N/A', 'OK')" + "TimelineEventStatus('TestProject', 'test_event', 'N/A', 'OK')" ) self.assertEqual(repr(self.event_status_ok), expected) def test_get_status(self): - """Test the get_status() function of ProjectEvent""" + """Test TimelineEventStatus get_status()""" status = self.event.get_status() expected = { 'id': status.pk, @@ -501,25 +501,25 @@ def test_get_status(self): self.assertEqual(model_to_dict(status), expected) def test_get_timestamp(self): - """Test the get_timestamp() function of ProjectEvent""" + """Test TimelineEventStatus get_timestamp()""" timestamp = self.event.get_timestamp() self.assertEqual(timestamp, self.event_status_ok.timestamp) def test_get_status_changes(self): - """Test the get_status_changes() function of ProjectEvent""" + """Test TimelineEventStatus get_status_changes()""" status_changes = self.event.get_status_changes() self.assertEqual(status_changes.count(), 2) self.assertEqual(status_changes[0], self.event_status_submit) def test_get_status_changes_reverse(self): - """Test the get_status_changes() function of ProjectEvent with + """Test the get_status_changes() function of TimelineEvent with reverse=True""" status_changes = self.event.get_status_changes(reverse=True) self.assertEqual(status_changes.count(), 2) self.assertEqual(status_changes[0], self.event_status_ok) def test_set_status(self): - """Test the set_status() function of ProjectEvent""" + """Test TimelineEventStatus set_status()""" new_status = self.event.set_status( 'FAILED', status_desc='FAILED', extra_data={'test_key': 'test_val'} ) diff --git a/timeline/tests/test_permissions_ajax.py b/timeline/tests/test_permissions_ajax.py index 20be81f1..b72f8885 100644 --- a/timeline/tests/test_permissions_ajax.py +++ b/timeline/tests/test_permissions_ajax.py @@ -7,13 +7,13 @@ from projectroles.tests.test_permissions import ProjectPermissionTestBase from timeline.tests.test_models import ( - ProjectEventMixin, - ProjectEventStatusMixin, + TimelineEventMixin, + TimelineEventStatusMixin, ) class TestProjectEventDetailAjaxView( - ProjectEventMixin, ProjectEventStatusMixin, ProjectPermissionTestBase + TimelineEventMixin, TimelineEventStatusMixin, ProjectPermissionTestBase ): """Tests for ProjectEventDetailAjaxView permissions""" @@ -25,7 +25,7 @@ def setUp(self): self.make_event_status(self.event, 'OK') self.url = reverse( 'timeline:ajax_detail_project', - kwargs={'projectevent': self.event.sodar_uuid}, + kwargs={'timelineevent': self.event.sodar_uuid}, ) def test_get(self): @@ -116,7 +116,7 @@ def test_get_classified_anon(self): class TestSiteEventDetailAjaxView( - ProjectEventMixin, ProjectEventStatusMixin, ProjectPermissionTestBase + TimelineEventMixin, TimelineEventStatusMixin, ProjectPermissionTestBase ): """Tests for SiteEventDetailAjaxView permissions""" @@ -129,7 +129,7 @@ def setUp(self): self.regular_user = self.make_user('regular_user') self.url = reverse( 'timeline:ajax_detail_site', - kwargs={'projectevent': self.event.sodar_uuid}, + kwargs={'timelineevent': self.event.sodar_uuid}, ) def test_get(self): @@ -160,7 +160,7 @@ def test_get_classified_anon(self): class TestProjectEventExtraAjaxView( - ProjectEventMixin, ProjectEventStatusMixin, ProjectPermissionTestBase + TimelineEventMixin, TimelineEventStatusMixin, ProjectPermissionTestBase ): """Tests for ProjectEventExtraAjaxView permissions""" @@ -172,7 +172,7 @@ def setUp(self): self.make_event_status(self.event, 'OK') self.url = reverse( 'timeline:ajax_extra_project', - kwargs={'projectevent': self.event.sodar_uuid}, + kwargs={'timelineevent': self.event.sodar_uuid}, ) def test_get(self): @@ -263,7 +263,7 @@ def test_get_classified_anon(self): class TestSiteEventExtraAjaxView( - ProjectEventMixin, ProjectEventStatusMixin, ProjectPermissionTestBase + TimelineEventMixin, TimelineEventStatusMixin, ProjectPermissionTestBase ): """Tests for SiteEventExtraAjaxView permissions""" @@ -280,7 +280,7 @@ def setUp(self): self.regular_user = self.make_user('regular_user') self.url = reverse( 'timeline:ajax_extra_site', - kwargs={'projectevent': self.event.sodar_uuid}, + kwargs={'timelineevent': self.event.sodar_uuid}, ) def test_get(self): @@ -310,7 +310,7 @@ def test_get_classified_anon(self): class TestEventStatusExtraAjaxViewProject( - ProjectEventMixin, ProjectEventStatusMixin, ProjectPermissionTestBase + TimelineEventMixin, TimelineEventStatusMixin, ProjectPermissionTestBase ): """Tests for EventStatusExtraAjaxView permissions with a project event""" @@ -391,7 +391,7 @@ def test_get_classified_anon(self): class TestEventStatusExtraAjaxViewSite( - ProjectEventMixin, ProjectEventStatusMixin, ProjectPermissionTestBase + TimelineEventMixin, TimelineEventStatusMixin, ProjectPermissionTestBase ): """Tests for EventStatusExtraAjaxView permissions with a site event""" diff --git a/timeline/tests/test_templatetags.py b/timeline/tests/test_templatetags.py index bd44dbf5..fa45aed5 100644 --- a/timeline/tests/test_templatetags.py +++ b/timeline/tests/test_templatetags.py @@ -8,14 +8,14 @@ # Projectroles dependency from projectroles.plugins import get_app_plugin, get_backend_api -from timeline.models import ProjectEvent, DEFAULT_MESSAGES +from timeline.models import TimelineEvent, DEFAULT_MESSAGES from timeline.templatetags import timeline_tags as tags from timeline.tests.test_api import TimelineAPIMixin from timeline.tests.test_models import ( - ProjectEventTestBase, - ProjectEventMixin, - ProjectEventStatusMixin, - ProjectEventObjectRefMixin, + TimelineEventTestBase, + TimelineEventMixin, + TimelineEventStatusMixin, + TimelineEventObjectRefMixin, ) @@ -26,10 +26,10 @@ class TestTemplateTags( TimelineAPIMixin, - ProjectEventMixin, - ProjectEventStatusMixin, - ProjectEventObjectRefMixin, - ProjectEventTestBase, + TimelineEventMixin, + TimelineEventStatusMixin, + TimelineEventObjectRefMixin, + TimelineEventTestBase, ): """Tests for timeline template tags""" @@ -86,7 +86,7 @@ def test_get_event_description_no_request(self): def test_get_details_events(self): """Test get_details_events()""" - self.assertEqual(ProjectEvent.objects.count(), 1) + self.assertEqual(TimelineEvent.objects.count(), 1) self.assertEqual(len(tags.get_details_events(self.project)), 1) # Create 5 additional events for a total of 6 for _ in range(5): @@ -102,7 +102,7 @@ def test_get_details_events(self): status_type='OK', description=DEFAULT_MESSAGES['OK'], ) - self.assertEqual(ProjectEvent.objects.count(), 6) + self.assertEqual(TimelineEvent.objects.count(), 6) self.assertEqual(len(tags.get_details_events(self.project)), 5) def test_get_details_events_classified_disabled(self): @@ -121,7 +121,7 @@ def test_get_details_events_classified_disabled(self): status_type='OK', description=DEFAULT_MESSAGES['OK'], ) - self.assertEqual(ProjectEvent.objects.count(), 2) + self.assertEqual(TimelineEvent.objects.count(), 2) self.assertEqual(len(tags.get_details_events(self.project)), 1) def test_get_details_events_classified_enabled(self): diff --git a/timeline/tests/test_ui.py b/timeline/tests/test_ui.py index 671dbfab..c63f34f4 100644 --- a/timeline/tests/test_ui.py +++ b/timeline/tests/test_ui.py @@ -16,8 +16,8 @@ from projectroles.tests.test_ui import UITestBase from timeline.tests.test_models import ( - ProjectEventMixin, - ProjectEventStatusMixin, + TimelineEventMixin, + TimelineEventStatusMixin, ) @@ -31,7 +31,7 @@ class TestProjectListView( - ProjectEventMixin, ProjectEventStatusMixin, UITestBase + TimelineEventMixin, TimelineEventStatusMixin, UITestBase ): """Tests for the timeline project list view UI""" @@ -147,7 +147,9 @@ def test_render_details(self): self.assert_element_count(expected, url, 'sodar-tl-list-event') -class TestSiteListView(ProjectEventMixin, ProjectEventStatusMixin, UITestBase): +class TestSiteListView( + TimelineEventMixin, TimelineEventStatusMixin, UITestBase +): """Tests for the timeline site-wide list view UI""" def setUp(self): @@ -243,7 +245,9 @@ def test_object_button(self): pass -class TestAdminListView(ProjectEventMixin, ProjectEventStatusMixin, UITestBase): +class TestAdminListView( + TimelineEventMixin, TimelineEventStatusMixin, UITestBase +): """Test for the timeline view of all events in UI""" def setUp(self): @@ -294,7 +298,7 @@ def test_badge(self): self.assertIsNotNone(self.selenium.find_element(By.CLASS_NAME, 'badge')) -class TestModals(ProjectEventMixin, ProjectEventStatusMixin, UITestBase): +class TestModals(TimelineEventMixin, TimelineEventStatusMixin, UITestBase): """Test UI of modals in timeline event list""" def setUp(self): @@ -430,7 +434,7 @@ def test_copy_button(self): btn.click() -class TestSearch(ProjectEventMixin, ProjectEventStatusMixin, UITestBase): +class TestSearch(TimelineEventMixin, TimelineEventStatusMixin, UITestBase): """Tests for the project search UI functionalities""" def setUp(self): diff --git a/timeline/tests/test_views.py b/timeline/tests/test_views.py index 64fa91c8..52b85011 100644 --- a/timeline/tests/test_views.py +++ b/timeline/tests/test_views.py @@ -7,9 +7,9 @@ from projectroles.plugins import get_backend_api from timeline.tests.test_models import ( - ProjectEventTestBase, - ProjectEventMixin, - ProjectEventStatusMixin, + TimelineEventTestBase, + TimelineEventMixin, + TimelineEventStatusMixin, ) @@ -23,7 +23,7 @@ class ViewTestBase( - ProjectEventMixin, ProjectEventStatusMixin, ProjectEventTestBase + TimelineEventMixin, TimelineEventStatusMixin, TimelineEventTestBase ): """Base class for timeline view testing""" diff --git a/timeline/tests/test_views_ajax.py b/timeline/tests/test_views_ajax.py index c049a61c..907987ad 100644 --- a/timeline/tests/test_views_ajax.py +++ b/timeline/tests/test_views_ajax.py @@ -14,11 +14,11 @@ from timeline.models import DEFAULT_MESSAGES from timeline.views_ajax import EventExtraDataMixin from timeline.templatetags.timeline_tags import get_status_style -from timeline.tests.test_models import ProjectEventMixin +from timeline.tests.test_models import TimelineEventMixin class TimelineAjaxViewTestBase( - ProjectMixin, RoleAssignmentMixin, ProjectEventMixin, ViewTestBase + ProjectMixin, RoleAssignmentMixin, TimelineEventMixin, ViewTestBase ): """Base class for timeline Ajax API view tests""" @@ -59,7 +59,7 @@ def setUp(self): ) self.url = reverse( 'timeline:ajax_detail_project', - kwargs={'projectevent': self.event.sodar_uuid}, + kwargs={'timelineevent': self.event.sodar_uuid}, ) def test_get(self): @@ -130,7 +130,7 @@ def setUp(self): ) self.url = reverse( 'timeline:ajax_extra_project', - kwargs={'projectevent': self.event.sodar_uuid}, + kwargs={'timelineevent': self.event.sodar_uuid}, ) def test_get(self): @@ -178,7 +178,7 @@ def test_get(self): response = self.client.get( reverse( 'timeline:ajax_detail_site', - kwargs={'projectevent': self.event.sodar_uuid}, + kwargs={'timelineevent': self.event.sodar_uuid}, ), ) self.assertEqual(response.status_code, 200) @@ -241,7 +241,7 @@ def test_get(self): response = self.client.get( reverse( 'timeline:ajax_extra_site', - kwargs={'projectevent': self.event.sodar_uuid}, + kwargs={'timelineevent': self.event.sodar_uuid}, ), ) self.assertEqual(response.status_code, 200) diff --git a/timeline/urls.py b/timeline/urls.py index 287fa50d..127b41cd 100644 --- a/timeline/urls.py +++ b/timeline/urls.py @@ -43,22 +43,22 @@ # Ajax API views urls_ajax = [ path( - route='ajax/detail/', + route='ajax/detail/', view=views_ajax.ProjectEventDetailAjaxView.as_view(), name='ajax_detail_project', ), path( - route='ajax/detail/site/', + route='ajax/detail/site/', view=views_ajax.SiteEventDetailAjaxView.as_view(), name='ajax_detail_site', ), path( - route='ajax/extra/', + route='ajax/extra/', view=views_ajax.ProjectEventExtraAjaxView.as_view(), name='ajax_extra_project', ), path( - route='ajax/extra/site/', + route='ajax/extra/site/', view=views_ajax.SiteEventExtraAjaxView.as_view(), name='ajax_extra_site', ), diff --git a/timeline/views.py b/timeline/views.py index 109dea19..5aa47824 100644 --- a/timeline/views.py +++ b/timeline/views.py @@ -13,7 +13,7 @@ ProjectPermissionMixin, ) -from timeline.models import ProjectEvent +from timeline.models import TimelineEvent # Local variables @@ -50,7 +50,7 @@ def get_queryset(self): ) ) or (not project_uuid and not self.request.user.is_superuser): set_kwargs['classified'] = False - return ProjectEvent.objects.filter(**set_kwargs).order_by('-pk') + return TimelineEvent.objects.filter(**set_kwargs).order_by('-pk') class ProjectTimelineView( @@ -65,7 +65,7 @@ class ProjectTimelineView( permission_required = 'timeline.view_timeline' template_name = 'timeline/timeline.html' - model = ProjectEvent + model = TimelineEvent paginate_by = getattr(settings, 'TIMELINE_PAGINATION', DEFAULT_PAGINATION) @@ -76,7 +76,7 @@ class SiteTimelineView( permission_required = 'timeline.view_site_timeline' template_name = 'timeline/timeline_site.html' - model = ProjectEvent + model = TimelineEvent paginate_by = getattr(settings, 'TIMELINE_PAGINATION', DEFAULT_PAGINATION) @@ -90,11 +90,11 @@ def get_context_data(self, *args, **kwargs): return context def get_queryset(self): - return ProjectEvent.objects.order_by('-pk') + return TimelineEvent.objects.order_by('-pk') permission_required = 'timeline.view_site_admin' template_name = 'timeline/timeline_site.html' - model = ProjectEvent + model = TimelineEvent paginate_by = getattr(settings, 'TIMELINE_PAGINATION', DEFAULT_PAGINATION) @@ -117,7 +117,7 @@ def get_queryset(self): sodar_uuid=self.kwargs['project'] ).first() classified_perm = 'timeline.view_classified_event' - queryset = ProjectEvent.objects.get_object_events( + queryset = TimelineEvent.objects.get_object_events( project=project, object_model=self.kwargs['object_model'], object_uuid=self.kwargs['object_uuid'], diff --git a/timeline/views_ajax.py b/timeline/views_ajax.py index 8426cfa5..13181cd8 100644 --- a/timeline/views_ajax.py +++ b/timeline/views_ajax.py @@ -15,7 +15,7 @@ SODARBaseAjaxView, ) -from timeline.models import ProjectEvent, ProjectEventStatus +from timeline.models import TimelineEvent, TimelineEventStatus from timeline.templatetags.timeline_tags import get_status_style @@ -40,7 +40,7 @@ def get_event_details(self, event, request): """ Return event details. - :param event: ProjectEvent object + :param event: TimelineEvent object :param request: Django request object :return: Dict """ @@ -154,8 +154,8 @@ def _html_print_array(self, array, str_list, indent): def get_event_extra(self, event, status=None): """ Return event extra data. - :param event: ProjectEvent object - :param status: ProjectEventStatus object + :param event: TimelineEvent object + :param status: TimelineEventStatus object :return: JSON-serializable dict """ extra = status.extra_data if status else event.extra_data @@ -178,8 +178,8 @@ class ProjectEventDetailAjaxView(EventDetailMixin, SODARBaseProjectAjaxView): permission_required = 'timeline.view_timeline' def get(self, request, *args, **kwargs): - event = ProjectEvent.objects.filter( - sodar_uuid=self.kwargs['projectevent'] + event = TimelineEvent.objects.filter( + sodar_uuid=self.kwargs['timelineevent'] ).first() if event.classified and not request.user.has_perm( 'timeline.view_classified_event', event.project @@ -194,8 +194,8 @@ class ProjectEventExtraAjaxView(EventExtraDataMixin, SODARBaseProjectAjaxView): permission_required = 'timeline.view_event_extra_data' def get(self, request, *args, **kwargs): - event = ProjectEvent.objects.filter( - sodar_uuid=self.kwargs['projectevent'] + event = TimelineEvent.objects.filter( + sodar_uuid=self.kwargs['timelineevent'] ).first() if event.classified and not request.user.has_perm( 'timeline.view_classified_event', event.project @@ -211,8 +211,8 @@ class SiteEventDetailAjaxView(EventDetailMixin, SODARBasePermissionAjaxView): permission_required = 'timeline.view_site_timeline' def get(self, request, *args, **kwargs): - event = ProjectEvent.objects.filter( - sodar_uuid=self.kwargs['projectevent'] + event = TimelineEvent.objects.filter( + sodar_uuid=self.kwargs['timelineevent'] ).first() if event.classified and not request.user.has_perm( 'timeline.view_classified_site_event' @@ -227,8 +227,8 @@ class SiteEventExtraAjaxView(EventExtraDataMixin, SODARBasePermissionAjaxView): permission_required = 'timeline.view_event_extra_data' def get(self, request, *args, **kwargs): - event = ProjectEvent.objects.filter( - sodar_uuid=self.kwargs['projectevent'] + event = TimelineEvent.objects.filter( + sodar_uuid=self.kwargs['timelineevent'] ).first() if event.classified and not request.user.has_perm( 'timeline.view_classified_site_event' @@ -241,7 +241,7 @@ class EventStatusExtraAjaxView(EventExtraDataMixin, SODARBaseAjaxView): """Ajax view for retrieving event status extra data for events""" def get(self, request, *args, **kwargs): - status = ProjectEventStatus.objects.filter( + status = TimelineEventStatus.objects.filter( sodar_uuid=self.kwargs['eventstatus'] ).first() event = status.event