Backend Generated Unit Test Reports - bounswe/bounswe2026group4 GitHub Wiki

Backend Generated Unit Test Reports

Auto-generated: 2026-04-29 18:07 UTC โ€” CI run

๐Ÿ“„ View full HTML report


โœ… All passed  ยท  1133 passed  ยท  0 failed  ยท  0 skipped  ยท  1133 total  ยท  13.07 s

Full test list
Test Status Duration
TestBadge::test_badge_can_be_created โœ… passed 0 ms
TestBadge::test_criteria_threshold_defaults_to_zero โœ… passed 0 ms
TestBadge::test_badge_name_must_be_unique โœ… passed 0 ms
TestBadge::test_all_criteria_types_are_accepted โœ… passed 0 ms
TestBadge::test_str_returns_name โœ… passed 0 ms
TestUserBadge::test_user_badge_can_be_created โœ… passed 0 ms
TestUserBadge::test_awarded_at_is_set_automatically โœ… passed 0 ms
TestUserBadge::test_same_badge_cannot_be_awarded_twice โœ… passed 0 ms
TestUserBadge::test_different_users_can_earn_same_badge โœ… passed 0 ms
TestUserBadge::test_user_can_earn_multiple_different_badges โœ… passed 0 ms
TestUserBadge::test_user_badge_deleted_when_user_is_deleted โœ… passed 0 ms
TestUserBadge::test_user_badge_deleted_when_badge_is_deleted โœ… passed 0 ms
TestUserBadge::test_str_contains_badge_name โœ… passed 0 ms
TestPointTransaction::test_transaction_can_be_created โœ… passed 0 ms
TestPointTransaction::test_created_at_is_set_automatically โœ… passed 0 ms
TestPointTransaction::test_positive_amount_stored_correctly โœ… passed 0 ms
TestPointTransaction::test_negative_amount_stored_correctly โœ… passed 0 ms
TestPointTransaction::test_story_set_null_when_story_is_deleted โœ… passed 0 ms
TestPointTransaction::test_transaction_deleted_when_user_is_deleted โœ… passed 0 ms
TestPointTransaction::test_user_can_have_multiple_transactions โœ… passed 0 ms
TestPointTransaction::test_point_values_match_requirements โœ… passed 0 ms
TestPointTransaction::test_str_contains_sign_amount_and_event_type โœ… passed 0 ms
TestComment::test_comment_can_be_created โœ… passed 0 ms
TestComment::test_is_anonymized_defaults_to_false โœ… passed 0 ms
TestComment::test_created_at_is_set_automatically โœ… passed 0 ms
TestComment::test_comment_appears_in_story_reverse_relation โœ… passed 0 ms
TestComment::test_comment_appears_in_user_reverse_relation โœ… passed 0 ms
TestComment::test_comment_deleted_when_story_is_deleted โœ… passed 0 ms
TestComment::test_author_becomes_null_when_user_is_deleted โœ… passed 0 ms
TestComment::test_comment_row_survives_author_deletion โœ… passed 0 ms
TestLike::test_like_can_be_created โœ… passed 0 ms
TestLike::test_created_at_is_set_automatically โœ… passed 0 ms
TestLike::test_duplicate_like_raises_integrity_error โœ… passed 0 ms
TestLike::test_different_users_can_like_same_story โœ… passed 0 ms
TestLike::test_same_user_can_like_different_stories โœ… passed 0 ms
TestLike::test_like_deleted_when_user_is_deleted โœ… passed 0 ms
TestLike::test_like_deleted_when_story_is_deleted โœ… passed 0 ms
TestLike::test_like_count_increments_when_like_is_created โœ… passed 0 ms
TestLike::test_like_count_increments_for_each_new_like โœ… passed 0 ms
TestLike::test_like_count_decrements_when_like_is_deleted โœ… passed 0 ms
TestLike::test_like_count_returns_to_zero_after_all_likes_removed โœ… passed 0 ms
TestSavedStory::test_saved_story_can_be_created โœ… passed 0 ms
TestSavedStory::test_saved_at_is_set_automatically โœ… passed 0 ms
TestSavedStory::test_duplicate_save_raises_integrity_error โœ… passed 0 ms
TestSavedStory::test_different_users_can_save_same_story โœ… passed 0 ms
TestSavedStory::test_save_deleted_when_user_is_deleted โœ… passed 0 ms
TestSavedStory::test_save_deleted_when_story_is_deleted โœ… passed 0 ms
TestSavedStory::test_user_saved_stories_accessible_via_reverse_relation โœ… passed 0 ms
TestSavedStory::test_save_count_increments_when_story_is_saved โœ… passed 0 ms
TestSavedStory::test_save_count_increments_for_each_save โœ… passed 0 ms
TestSavedStory::test_save_count_decrements_when_save_is_removed โœ… passed 0 ms
TestSavedStory::test_save_count_returns_to_zero_after_all_saves_removed โœ… passed 0 ms
TestCommentResponseSerializer::test_response_serializer_with_author โœ… passed 0 ms
TestCommentResponseSerializer::test_response_serializer_anonymized โœ… passed 0 ms
TestCommentResponseSerializer::test_response_serializer_includes_required_fields โœ… passed 0 ms
TestCommentResponseSerializer::test_response_serializer_hides_username_when_private โœ… passed 0 ms
TestCommentResponseSerializer::test_response_serializer_shows_username_when_public โœ… passed 0 ms
TestLikeResponseSerializer::test_contains_expected_fields โœ… passed 0 ms
TestLikeResponseSerializer::test_story_id_matches โœ… passed 0 ms
TestLikeResponseSerializer::test_id_matches โœ… passed 0 ms
TestGetStoryComments::test_returns_queryset_for_published_story โœ… passed 0 ms
TestGetStoryComments::test_returns_empty_queryset_when_no_comments โœ… passed 0 ms
TestGetStoryComments::test_returns_comments_belonging_to_story โœ… passed 0 ms
TestGetStoryComments::test_ordered_oldest_first โœ… passed 0 ms
TestGetStoryComments::test_nonexistent_story_raises_404 โœ… passed 0 ms
TestGetStoryComments::test_removed_story_raises_404 โœ… passed 0 ms
TestGetStoryComments::test_draft_story_raises_404 โœ… passed 0 ms
TestGetStoryComments::test_does_not_return_comments_from_other_stories โœ… passed 0 ms
TestCreateComment::test_create_comment_on_published_story โœ… passed 0 ms
TestCreateComment::test_create_comment_on_removed_story_raises_404 โœ… passed 0 ms
TestCreateComment::test_create_comment_on_nonexistent_story_raises_404 โœ… passed 0 ms
TestCreateComment::test_create_comment_persists_to_db โœ… passed 0 ms
TestDeleteComment::test_delete_comment_removes_from_db โœ… passed 0 ms
TestAddLike::test_creates_like โœ… passed 0 ms
TestAddLike::test_returns_like_instance โœ… passed 0 ms
TestAddLike::test_like_linked_to_correct_story โœ… passed 0 ms
TestAddLike::test_like_linked_to_correct_user โœ… passed 0 ms
TestAddLike::test_nonexistent_story_raises_404 โœ… passed 0 ms
TestAddLike::test_removed_story_raises_404 โœ… passed 0 ms
TestAddLike::test_duplicate_like_raises_validation_error โœ… passed 0 ms
TestRemoveLike::test_removes_like_from_db โœ… passed 0 ms
TestRemoveLike::test_not_liked_raises_404 โœ… passed 0 ms
TestRemoveLike::test_nonexistent_story_raises_404 โœ… passed 0 ms
TestRemoveLike::test_removed_story_raises_404 โœ… passed 0 ms
TestAddBookmark::test_creates_saved_story โœ… passed 0 ms
TestAddBookmark::test_returns_saved_story_instance โœ… passed 0 ms
TestAddBookmark::test_bookmark_linked_to_correct_story โœ… passed 0 ms
TestAddBookmark::test_bookmark_linked_to_correct_user โœ… passed 0 ms
TestAddBookmark::test_increments_save_count โœ… passed 0 ms
TestAddBookmark::test_duplicate_returns_existing_not_created โœ… passed 0 ms
TestAddBookmark::test_duplicate_does_not_double_increment_save_count โœ… passed 0 ms
TestAddBookmark::test_nonexistent_story_raises_404 โœ… passed 0 ms
TestAddBookmark::test_removed_story_raises_404 โœ… passed 0 ms
TestAddBookmark::test_draft_story_raises_404 โœ… passed 0 ms
TestRemoveBookmark::test_deletes_saved_story_row โœ… passed 0 ms
TestRemoveBookmark::test_decrements_save_count โœ… passed 0 ms
TestRemoveBookmark::test_not_bookmarked_is_noop โœ… passed 0 ms
TestRemoveBookmark::test_nonexistent_story_raises_404 โœ… passed 0 ms
TestRemoveBookmark::test_removed_story_can_be_unbookmarked โœ… passed 0 ms
TestRemoveBookmark::test_draft_story_can_be_unbookmarked โœ… passed 0 ms
TestStoryCommentCreate::test_create_comment_success โœ… passed 0 ms
TestStoryCommentCreate::test_create_comment_unauthenticated โœ… passed 0 ms
TestStoryCommentCreate::test_create_comment_blank_text โœ… passed 0 ms
TestStoryCommentCreate::test_create_comment_story_not_found โœ… passed 0 ms
TestStoryCommentCreate::test_create_comment_removed_story โœ… passed 0 ms
TestStoryCommentCreate::test_create_comment_response_contains_expected_fields โœ… passed 0 ms
TestCommentDelete::test_delete_comment_by_author โœ… passed 0 ms
TestCommentDelete::test_delete_comment_by_admin โœ… passed 0 ms
TestCommentDelete::test_delete_comment_by_other_user โœ… passed 0 ms
TestCommentDelete::test_delete_comment_unauthenticated โœ… passed 0 ms
TestCommentDelete::test_delete_comment_not_found โœ… passed 0 ms
TestStoryLike::test_like_story_success โœ… passed 0 ms
TestStoryLike::test_like_updates_story_like_count โœ… passed 0 ms
TestStoryLike::test_like_response_contains_expected_fields โœ… passed 0 ms
TestStoryLike::test_like_story_unauthenticated โœ… passed 0 ms
TestStoryLike::test_like_story_not_found โœ… passed 0 ms
TestStoryLike::test_like_removed_story_returns_404 โœ… passed 0 ms
TestStoryLike::test_duplicate_like_returns_400 โœ… passed 0 ms
TestStoryUnlike::test_unlike_story_success โœ… passed 0 ms
TestStoryUnlike::test_unlike_decrements_like_count โœ… passed 0 ms
TestStoryUnlike::test_unlike_story_unauthenticated โœ… passed 0 ms
TestStoryUnlike::test_unlike_story_not_liked_returns_404 โœ… passed 0 ms
TestStoryUnlike::test_unlike_story_not_found โœ… passed 0 ms
TestStoryCommentList::test_returns_200_for_unauthenticated โœ… passed 0 ms
TestStoryCommentList::test_returns_200_for_authenticated โœ… passed 0 ms
TestStoryCommentList::test_response_is_paginated โœ… passed 0 ms
TestStoryCommentList::test_returns_empty_list_when_no_comments โœ… passed 0 ms
TestStoryCommentList::test_returns_comments_for_story โœ… passed 0 ms
TestStoryCommentList::test_result_contains_expected_fields โœ… passed 0 ms
TestStoryCommentList::test_comments_ordered_oldest_first โœ… passed 0 ms
TestStoryCommentList::test_story_not_found_returns_404 โœ… passed 0 ms
TestStoryCommentList::test_removed_story_returns_404 โœ… passed 0 ms
TestStoryCommentList::test_anonymized_comment_shows_null_author โœ… passed 0 ms
TestStoryCommentList::test_private_username_author_shows_null_in_list โœ… passed 0 ms
TestStoryCommentList::test_public_username_author_shows_username_in_list โœ… passed 0 ms
TestStoryCommentList::test_only_returns_comments_for_requested_story โœ… passed 0 ms
TestStoryBookmark::test_bookmark_success_returns_201 โœ… passed 0 ms
TestStoryBookmark::test_bookmark_increments_save_count โœ… passed 0 ms
TestStoryBookmark::test_bookmark_response_contains_expected_fields โœ… passed 0 ms
TestStoryBookmark::test_duplicate_bookmark_returns_200 โœ… passed 0 ms
TestStoryBookmark::test_duplicate_bookmark_does_not_increment_save_count โœ… passed 0 ms
TestStoryBookmark::test_bookmark_unauthenticated_returns_401 โœ… passed 0 ms
TestStoryBookmark::test_bookmark_story_not_found_returns_404 โœ… passed 0 ms
TestStoryBookmark::test_bookmark_removed_story_returns_404 โœ… passed 0 ms
TestStoryUnbookmark::test_unbookmark_success_returns_204 โœ… passed 0 ms
TestStoryUnbookmark::test_unbookmark_decrements_save_count โœ… passed 0 ms
TestStoryUnbookmark::test_unbookmark_not_bookmarked_returns_204 โœ… passed 0 ms
TestStoryUnbookmark::test_unbookmark_unauthenticated_returns_401 โœ… passed 0 ms
TestStoryUnbookmark::test_unbookmark_story_not_found_returns_404 โœ… passed 0 ms
TestStoryUnbookmark::test_unbookmark_removed_story_returns_204 โœ… passed 0 ms
TestMediaItem::test_media_item_can_be_created โœ… passed 0 ms
TestMediaItem::test_order_defaults_to_zero โœ… passed 0 ms
TestMediaItem::test_uploaded_at_is_set_automatically โœ… passed 0 ms
TestMediaItem::test_all_media_types_are_accepted โœ… passed 0 ms
TestMediaItem::test_file_size_is_stored_correctly โœ… passed 0 ms
TestMediaItem::test_cascade_deletes_when_story_is_deleted โœ… passed 0 ms
TestMediaItem::test_story_can_have_multiple_media_items โœ… passed 0 ms
TestMediaItem::test_items_ordered_by_order_field_ascending โœ… passed 0 ms
TestMediaItem::test_str_includes_type_and_filename โœ… passed 0 ms
TestMediaItemResponseSerializer::test_contains_expected_fields โœ… passed 0 ms
TestMediaItemResponseSerializer::test_url_is_built_from_request_context โœ… passed 0 ms
TestMediaItemResponseSerializer::test_url_falls_back_to_relative_without_request โœ… passed 0 ms
TestUploadStoryImage::test_creates_media_item โœ… passed 0 ms
TestUploadStoryImage::test_media_type_is_image โœ… passed 0 ms
TestUploadStoryImage::test_story_is_set โœ… passed 0 ms
TestUploadStoryImage::test_file_size_is_stored โœ… passed 0 ms
TestUploadStoryImage::test_original_filename_is_stored โœ… passed 0 ms
TestUploadStoryImage::test_returns_media_item_instance โœ… passed 0 ms
TestUploadStoryMedia::test_creates_media_item โœ… passed 0 ms
TestUploadStoryMedia::test_audio_media_type_stored โœ… passed 0 ms
TestUploadStoryMedia::test_video_media_type_stored โœ… passed 0 ms
TestUploadStoryMedia::test_story_is_set โœ… passed 0 ms
TestUploadStoryMedia::test_file_size_is_stored โœ… passed 0 ms
TestUploadStoryMedia::test_original_filename_is_stored โœ… passed 0 ms
TestUploadStoryMedia::test_returns_media_item_instance โœ… passed 0 ms
TestStoryImageUpload::test_upload_success โœ… passed 0 ms
TestStoryImageUpload::test_upload_response_contains_expected_fields โœ… passed 0 ms
TestStoryImageUpload::test_upload_unauthenticated_returns_401 โœ… passed 0 ms
TestStoryImageUpload::test_upload_by_non_owner_returns_403 โœ… passed 0 ms
TestStoryImageUpload::test_upload_story_not_found_returns_404 โœ… passed 0 ms
TestStoryImageUpload::test_upload_to_removed_story_returns_404 โœ… passed 0 ms
TestStoryImageUpload::test_upload_invalid_type_gif_returns_400 โœ… passed 0 ms
TestStoryImageUpload::test_spoofed_extension_returns_400 โœ… passed 0 ms
TestStoryImageUpload::test_upload_oversized_file_returns_400 โœ… passed 0 ms
TestStoryImageUpload::test_upload_png_accepted โœ… passed 0 ms
TestStoryImageUpload::test_upload_stores_correct_metadata โœ… passed 0 ms
TestStoryImageUpload::test_upload_draft_story_allowed โœ… passed 0 ms
TestStoryMediaUpload::test_upload_audio_success โœ… passed 0 ms
TestStoryMediaUpload::test_upload_video_success โœ… passed 0 ms
TestStoryMediaUpload::test_response_contains_expected_fields โœ… passed 0 ms
TestStoryMediaUpload::test_audio_media_type_in_response โœ… passed 0 ms
TestStoryMediaUpload::test_video_media_type_in_response โœ… passed 0 ms
TestStoryMediaUpload::test_unauthenticated_returns_401 โœ… passed 0 ms
TestStoryMediaUpload::test_non_owner_returns_403 โœ… passed 0 ms
TestStoryMediaUpload::test_story_not_found_returns_404 โœ… passed 0 ms
TestStoryMediaUpload::test_removed_story_returns_404 โœ… passed 0 ms
TestStoryMediaUpload::test_unsupported_type_returns_400 โœ… passed 0 ms
TestStoryMediaUpload::test_spoofed_extension_returns_400 โœ… passed 0 ms
TestStoryMediaUpload::test_upload_stores_correct_metadata โœ… passed 0 ms
TestNotification::test_notification_can_be_created โœ… passed 0 ms
TestNotification::test_is_read_defaults_to_false โœ… passed 0 ms
TestNotification::test_created_at_is_set_automatically โœ… passed 0 ms
TestNotification::test_all_notification_types_are_accepted โœ… passed 0 ms
TestNotification::test_notification_deleted_when_recipient_is_deleted โœ… passed 0 ms
TestNotification::test_actor_set_null_when_actor_user_is_deleted โœ… passed 0 ms
TestNotification::test_story_set_null_when_story_is_deleted โœ… passed 0 ms
TestNotification::test_unread_notifications_ordered_before_read โœ… passed 0 ms
TestNotification::test_str_contains_type_and_recipient_pk โœ… passed 0 ms
TestNotificationPreference::test_preference_can_be_created โœ… passed 0 ms
TestNotificationPreference::test_is_enabled_defaults_to_true โœ… passed 0 ms
TestNotificationPreference::test_preference_can_be_disabled โœ… passed 0 ms
TestNotificationPreference::test_duplicate_type_per_user_raises_integrity_error โœ… passed 0 ms
TestNotificationPreference::test_different_types_for_same_user_are_allowed โœ… passed 0 ms
TestNotificationPreference::test_preferences_deleted_when_user_is_deleted โœ… passed 0 ms
TestIsNotificationEnabled::test_enabled_by_default_when_no_preference_row โœ… passed 0 ms
TestIsNotificationEnabled::test_returns_false_when_preference_disabled โœ… passed 0 ms
TestIsNotificationEnabled::test_returns_true_when_preference_enabled โœ… passed 0 ms
TestIsNotificationEnabled::test_returns_false_when_notifications_muted_regardless_of_per_type_pref โœ… passed 0 ms
TestIsNotificationEnabled::test_returns_false_when_notifications_muted_with_no_preference_row โœ… passed 0 ms
TestCreateNotification::test_create_notification_returns_notification โœ… passed 0 ms
TestCreateNotification::test_create_notification_persists_to_db โœ… passed 0 ms
TestCreateNotification::test_create_notification_suppressed_when_actor_is_recipient โœ… passed 0 ms
TestCreateNotification::test_create_notification_suppressed_when_type_disabled โœ… passed 0 ms
TestCreateNotification::test_create_notification_without_actor_succeeds โœ… passed 0 ms
TestGetNotifications::test_returns_only_recipient_notifications โœ… passed 0 ms
TestGetNotifications::test_unread_notifications_come_before_read โœ… passed 0 ms
TestMarkNotificationRead::test_mark_as_read โœ… passed 0 ms
TestMarkNotificationRead::test_mark_as_unread โœ… passed 0 ms
TestDeleteNotification::test_delete_single_notification โœ… passed 0 ms
TestDeleteNotification::test_delete_does_not_affect_other_notifications โœ… passed 0 ms
TestDeleteAllNotifications::test_clears_all_user_notifications โœ… passed 0 ms
TestDeleteAllNotifications::test_does_not_delete_other_users_notifications โœ… passed 0 ms
TestGetAllPreferences::test_all_types_default_to_true_when_no_rows_exist โœ… passed 0 ms
TestGetAllPreferences::test_reflects_saved_disabled_preference โœ… passed 0 ms
TestGetAllPreferences::test_reflects_saved_enabled_preference โœ… passed 0 ms
TestGetAllPreferences::test_unset_types_remain_true_when_some_rows_exist โœ… passed 0 ms
TestUpdatePreferences::test_creates_preference_row_for_new_type โœ… passed 0 ms
TestUpdatePreferences::test_updates_existing_preference_row โœ… passed 0 ms
TestUpdatePreferences::test_updates_multiple_types_at_once โœ… passed 0 ms
TestUpdatePreferences::test_sets_notifications_muted_on_user โœ… passed 0 ms
TestUpdatePreferences::test_unsets_notifications_muted_on_user โœ… passed 0 ms
TestUpdatePreferences::test_does_not_touch_notifications_muted_when_not_provided โœ… passed 0 ms
TestNewCommentSignal::test_new_comment_creates_notification_for_story_author โœ… passed 0 ms
TestNewCommentSignal::test_new_comment_sets_actor_and_story_references โœ… passed 0 ms
TestNewCommentSignal::test_author_commenting_on_own_story_does_not_notify โœ… passed 0 ms
TestNewCommentSignal::test_private_username_commenter_shows_someone_and_no_actor โœ… passed 0 ms
TestNewLikeSignal::test_new_like_creates_notification_for_story_author โœ… passed 0 ms
TestNewLikeSignal::test_new_like_sets_actor_and_story_references โœ… passed 0 ms
TestNewLikeSignal::test_author_liking_own_story_does_not_notify โœ… passed 0 ms
TestNewLikeSignal::test_private_username_liker_shows_someone_and_no_actor โœ… passed 0 ms
TestNewFollowerSignal::test_new_follow_creates_notification_for_followed_user โœ… passed 0 ms
TestNewFollowerSignal::test_new_follow_sets_actor โœ… passed 0 ms
TestNewFollowerSignal::test_private_username_follower_shows_someone_and_no_actor โœ… passed 0 ms
TestBadgeEarnedSignal::test_badge_earned_creates_notification โœ… passed 0 ms
TestBadgeEarnedSignal::test_badge_earned_has_no_actor โœ… passed 0 ms
TestNewStoryPublishedSignal::test_new_published_story_notifies_all_followers โœ… passed 0 ms
TestNewStoryPublishedSignal::test_new_published_story_no_notification_when_no_followers โœ… passed 0 ms
TestNewStoryPublishedSignal::test_draft_story_does_not_notify_followers โœ… passed 0 ms
TestNewStoryPublishedSignal::test_private_username_author_shows_someone_and_no_actor โœ… passed 0 ms
TestStoryRemovedSignal::test_story_removed_creates_notification_for_author โœ… passed 0 ms
TestStoryRemovedSignal::test_story_removed_sets_story_reference โœ… passed 0 ms
TestStoryRemovedSignal::test_saving_already_removed_story_does_not_duplicate_notification โœ… passed 0 ms
TestStoryRemovedSignal::test_status_change_not_to_removed_does_not_notify โœ… passed 0 ms
TestReportResolvedSignal::test_report_resolved_creates_notification_for_reporter โœ… passed 0 ms
TestReportResolvedSignal::test_report_dismissed_creates_notification_for_reporter โœ… passed 0 ms
TestReportResolvedSignal::test_saving_already_resolved_report_does_not_duplicate_notification โœ… passed 0 ms
TestReportResolvedSignal::test_pending_report_update_does_not_notify โœ… passed 0 ms
TestNotificationListView::test_list_requires_authentication โœ… passed 0 ms
TestNotificationListView::test_list_returns_own_notifications โœ… passed 0 ms
TestNotificationListView::test_list_response_contains_expected_fields โœ… passed 0 ms
TestNotificationListView::test_list_actor_contains_id_and_username โœ… passed 0 ms
TestNotificationListView::test_list_unread_notifications_appear_before_read โœ… passed 0 ms
TestNotificationListView::test_list_empty_inbox_returns_empty_list โœ… passed 0 ms
TestNotificationListView::test_list_notification_with_null_actor_serializes_correctly โœ… passed 0 ms
TestNotificationClearAllView::test_clear_all_requires_authentication โœ… passed 0 ms
TestNotificationClearAllView::test_clear_all_removes_all_user_notifications โœ… passed 0 ms
TestNotificationClearAllView::test_clear_all_does_not_affect_other_users_notifications โœ… passed 0 ms
TestNotificationMarkReadView::test_mark_read_requires_authentication โœ… passed 0 ms
TestNotificationMarkReadView::test_mark_notification_as_read โœ… passed 0 ms
TestNotificationMarkReadView::test_mark_notification_as_unread โœ… passed 0 ms
TestNotificationMarkReadView::test_mark_read_on_other_users_notification_returns_404 โœ… passed 0 ms
TestNotificationMarkReadView::test_mark_read_with_missing_body_returns_400 โœ… passed 0 ms
TestNotificationMarkReadView::test_mark_read_nonexistent_notification_returns_404 โœ… passed 0 ms
TestNotificationDetailView::test_delete_requires_authentication โœ… passed 0 ms
TestNotificationDetailView::test_delete_own_notification โœ… passed 0 ms
TestNotificationDetailView::test_delete_other_users_notification_returns_404 โœ… passed 0 ms
TestNotificationDetailView::test_delete_nonexistent_notification_returns_404 โœ… passed 0 ms
TestNotificationPreferenceView::test_get_requires_authentication โœ… passed 0 ms
TestNotificationPreferenceView::test_patch_requires_authentication โœ… passed 0 ms
TestNotificationPreferenceView::test_get_returns_all_types_defaulting_to_true โœ… passed 0 ms
TestNotificationPreferenceView::test_get_includes_notifications_muted_false_by_default โœ… passed 0 ms
TestNotificationPreferenceView::test_get_reflects_saved_disabled_preference โœ… passed 0 ms
TestNotificationPreferenceView::test_patch_updates_single_type โœ… passed 0 ms
TestNotificationPreferenceView::test_patch_updates_multiple_types โœ… passed 0 ms
TestNotificationPreferenceView::test_patch_sets_notifications_muted โœ… passed 0 ms
TestNotificationPreferenceView::test_patch_notifications_muted_suppresses_create_notification โœ… passed 0 ms
TestNotificationPreferenceView::test_patch_with_empty_body_returns_200_and_unchanged_state โœ… passed 0 ms
TestNotificationPreferenceView::test_patch_with_invalid_field_is_ignored โœ… passed 0 ms
TestReport::test_report_on_story_can_be_created โœ… passed 0 ms
TestReport::test_report_on_comment_can_be_created โœ… passed 0 ms
TestReport::test_status_defaults_to_pending โœ… passed 0 ms
TestReport::test_resolution_outcome_defaults_to_blank โœ… passed 0 ms
TestReport::test_created_at_is_set_automatically โœ… passed 0 ms
TestReport::test_resolved_at_defaults_to_none โœ… passed 0 ms
TestReport::test_all_report_reasons_are_accepted โœ… passed 0 ms
TestReport::test_reporter_set_null_when_user_is_deleted โœ… passed 0 ms
TestReport::test_report_deleted_when_story_is_deleted โœ… passed 0 ms
TestReport::test_report_deleted_when_comment_is_deleted โœ… passed 0 ms
TestReport::test_duplicate_story_report_by_same_user_raises โœ… passed 0 ms
TestReport::test_duplicate_comment_report_by_same_user_raises โœ… passed 0 ms
TestReport::test_different_users_can_report_same_story โœ… passed 0 ms
TestReport::test_same_user_can_report_story_and_comment_separately โœ… passed 0 ms
TestReport::test_str_contains_pk_and_reason โœ… passed 0 ms
TestStoryModel::test_create_story_with_required_fields_succeeds โœ… passed 0 ms
TestStoryModel::test_create_story_without_user_succeeds โœ… passed 0 ms
TestStoryModel::test_create_story_defaults_to_published_status โœ… passed 0 ms
TestStoryModel::test_contributor_visible_defaults_to_true โœ… passed 0 ms
TestStoryModel::test_moderation_reason_defaults_to_empty_string โœ… passed 0 ms
TestStoryModel::test_like_count_and_save_count_default_to_zero โœ… passed 0 ms
TestStoryModel::test_region_defaults_to_empty_string โœ… passed 0 ms
TestStoryModel::test_create_story_with_region โœ… passed 0 ms
TestStoryModel::test_create_story_with_year_range_time_type โœ… passed 0 ms
TestStoryModel::test_create_story_with_decade_time_type โœ… passed 0 ms
TestStoryModel::test_create_story_with_approximate_year_time_type โœ… passed 0 ms
TestStoryModel::test_story_user_set_null_after_account_deletion โœ… passed 0 ms
TestStoryModel::test_story_str_returns_title โœ… passed 0 ms
TestStoryModel::test_create_story_with_removed_status โœ… passed 0 ms
TestStoryModel::test_create_story_with_draft_status โœ… passed 0 ms
TestStoryModel::test_create_story_with_blank_title_fails_validation โœ… passed 0 ms
TestStoryModel::test_clean_raises_when_year_range_missing_year_end โœ… passed 0 ms
TestStoryModel::test_clean_raises_when_exact_year_missing_year โœ… passed 0 ms
TestStoryModel::test_create_story_with_exact_date_only โœ… passed 0 ms
TestStoryModel::test_create_story_with_exact_date_and_time โœ… passed 0 ms
TestStoryModel::test_clean_raises_when_exact_date_missing_date_value โœ… passed 0 ms
TestStoryFeedSerializer::test_returns_all_required_card_fields โœ… passed 0 ms
TestStoryFeedSerializer::test_returns_preview_text_truncated_to_20_words โœ… passed 0 ms
TestStoryFeedSerializer::test_returns_full_text_when_narrative_is_shorter_than_20_words โœ… passed 0 ms
TestStoryFeedSerializer::test_shows_contributor_name_when_visible โœ… passed 0 ms
TestStoryFeedSerializer::test_hides_contributor_name_when_not_visible โœ… passed 0 ms
TestStoryFeedSerializer::test_contributor_name_is_none_when_user_is_anonymized โœ… passed 0 ms
TestStoryFeedSerializer::test_returns_correct_title_and_location โœ… passed 0 ms
TestStoryFeedSerializer::test_returns_year_range_fields โœ… passed 0 ms
TestStoryFeedSerializer::test_returns_correct_status โœ… passed 0 ms
TestStorySerializerFields::test_serializer_contains_expected_fields โœ… passed 0 ms
TestStorySerializerFields::test_read_only_fields_are_not_writable โœ… passed 0 ms
TestStorySerializerFields::test_contributor_name_returns_username_when_visible โœ… passed 0 ms
TestStorySerializerFields::test_contributor_name_is_none_when_not_visible โœ… passed 0 ms
TestStorySerializerFields::test_contributor_name_is_none_when_user_is_anonymized โœ… passed 0 ms
TestStorySerializerValidation::test_validate_status_blocks_removed โœ… passed 0 ms
TestStorySerializerValidation::test_validate_status_allows_draft โœ… passed 0 ms
TestStorySerializerValidation::test_validate_status_allows_published โœ… passed 0 ms
TestStorySerializerValidation::test_validate_raises_when_exact_year_and_year_missing โœ… passed 0 ms
TestStorySerializerValidation::test_validate_raises_when_year_range_missing_year_start โœ… passed 0 ms
TestStorySerializerValidation::test_validate_raises_when_year_range_missing_year_end โœ… passed 0 ms
TestStorySerializerValidation::test_validate_passes_for_valid_year_range โœ… passed 0 ms
TestStorySerializerValidation::test_validate_raises_when_exact_date_missing_date_value โœ… passed 0 ms
TestStorySerializerValidation::test_validate_passes_for_exact_date_without_time โœ… passed 0 ms
TestStorySerializerValidation::test_validate_passes_for_exact_date_with_time โœ… passed 0 ms
TestStorySerializerValidation::test_partial_update_validate_uses_existing_instance_values โœ… passed 0 ms
TestStorySerializerCreate::test_create_persists_story_with_correct_user โœ… passed 0 ms
TestStorySerializerCreate::test_create_returns_story_instance โœ… passed 0 ms
TestStorySerializerUpdate::test_update_changes_specified_fields โœ… passed 0 ms
TestStorySerializerUpdate::test_update_does_not_change_unspecified_fields โœ… passed 0 ms
TestStoryDetailSerializer::test_media_items_is_empty_list_when_no_media โœ… passed 0 ms
TestStoryDetailSerializer::test_media_items_contains_uploaded_files โœ… passed 0 ms
TestStoryDetailSerializer::test_media_items_ordered_by_order_field โœ… passed 0 ms
TestStoryDetailSerializer::test_media_item_url_is_absolute_when_request_in_context โœ… passed 0 ms
TestStorySerializerUserInteractionFields::test_user_has_liked_is_false_when_no_request_context โœ… passed 0 ms
TestStorySerializerUserInteractionFields::test_user_has_liked_is_true_when_user_liked โœ… passed 0 ms
TestStorySerializerUserInteractionFields::test_user_has_liked_is_false_when_user_not_liked โœ… passed 0 ms
TestStorySerializerUserInteractionFields::test_user_has_saved_is_true_when_user_saved โœ… passed 0 ms
TestStorySerializerUserInteractionFields::test_user_has_saved_is_false_when_user_not_saved โœ… passed 0 ms
TestStorySerializerUserInteractionFields::test_reads_user_has_liked_from_annotation_when_present โœ… passed 0 ms
TestStorySerializerUserInteractionFields::test_reads_user_has_saved_from_annotation_when_present โœ… passed 0 ms
TestStoryFeedSerializerUserInteractionFields::test_user_has_liked_is_false_when_no_request_context โœ… passed 0 ms
TestStoryFeedSerializerUserInteractionFields::test_user_has_liked_is_true_when_user_liked โœ… passed 0 ms
TestStoryFeedSerializerUserInteractionFields::test_user_has_liked_is_false_when_user_not_liked โœ… passed 0 ms
TestStoryFeedSerializerUserInteractionFields::test_user_has_saved_is_true_when_user_saved โœ… passed 0 ms
TestStoryFeedSerializerUserInteractionFields::test_user_has_saved_is_false_when_user_not_saved โœ… passed 0 ms
TestStoryFeedSerializerUserInteractionFields::test_reads_user_has_liked_from_annotation_when_present โœ… passed 0 ms
TestStoryFeedSerializerUserInteractionFields::test_reads_user_has_saved_from_annotation_when_present โœ… passed 0 ms
TestStoryMapGeoJSONSerializer::test_feature_has_required_geojson_keys โœ… passed 0 ms
TestStoryMapGeoJSONSerializer::test_geometry_is_point_with_coordinates โœ… passed 0 ms
TestStoryMapGeoJSONSerializer::test_coordinates_are_lng_lat_order โœ… passed 0 ms
TestStoryMapGeoJSONSerializer::test_coordinates_are_float_not_decimal_strings โœ… passed 0 ms
TestStoryMapGeoJSONSerializer::test_properties_contains_required_fields โœ… passed 0 ms
TestStoryMapGeoJSONSerializer::test_properties_contains_year_range_fields โœ… passed 0 ms
TestStoryMapGeoJSONSerializer::test_many_true_returns_list_of_features โœ… passed 0 ms
TestStorySerializerTags::test_tag_ids_accepted_on_create โœ… passed 0 ms
TestStorySerializerTags::test_tag_ids_optional_on_create โœ… passed 0 ms
TestStorySerializerTags::test_tag_ids_max_3_enforced โœ… passed 0 ms
TestStorySerializerTags::test_tag_ids_duplicate_rejected โœ… passed 0 ms
TestStorySerializerTags::test_tag_ids_nonexistent_rejected โœ… passed 0 ms
TestStorySerializerTags::test_tags_read_field_present_in_output โœ… passed 0 ms
TestStorySerializerTags::test_tag_ids_absent_in_patch_leaves_tags_unchanged โœ… passed 0 ms
TestStorySerializerTags::test_empty_tag_ids_in_patch_is_valid โœ… passed 0 ms
TestStoryDetailSerializerTemporalCoverage::test_both_fields_present_in_output โœ… passed 0 ms
TestStoryDetailSerializerTemporalCoverage::test_exact_year โœ… passed 0 ms
TestStoryDetailSerializerTemporalCoverage::test_approximate_year โœ… passed 0 ms
TestStoryDetailSerializerTemporalCoverage::test_decade โœ… passed 0 ms
TestStoryDetailSerializerTemporalCoverage::test_year_range โœ… passed 0 ms
TestStoryDetailSerializerTemporalCoverage::test_fields_are_read_only โœ… passed 0 ms
TestStoryDetailSerializerTemporalCoverage::test_exact_date_without_time โœ… passed 0 ms
TestStoryDetailSerializerTemporalCoverage::test_exact_date_with_time โœ… passed 0 ms
TestGetStoryFeed::test_returns_only_published_stories โœ… passed 0 ms
TestGetStoryFeed::test_excludes_removed_stories โœ… passed 0 ms
TestGetStoryFeed::test_excludes_draft_stories โœ… passed 0 ms
TestGetStoryFeed::test_with_no_filters_returns_all_published โœ… passed 0 ms
TestGetStoryFeed::test_sorts_by_most_recent โœ… passed 0 ms
TestGetStoryFeed::test_sorts_by_most_popular โœ… passed 0 ms
TestGetStoryFeed::test_filters_by_year_from โœ… passed 0 ms
TestGetStoryFeed::test_filters_by_year_to โœ… passed 0 ms
TestGetStoryFeed::test_filters_by_year_from_and_year_to โœ… passed 0 ms
TestGetStoryFeed::test_filters_year_range_stories_by_year_from โœ… passed 0 ms
TestGetStoryFeed::test_filters_year_range_stories_by_year_to โœ… passed 0 ms
TestGetStoryFeed::test_excludes_year_range_story_entirely_outside_window โœ… passed 0 ms
TestGetStoryFeed::test_filters_by_location_name_exact_match โœ… passed 0 ms
TestGetStoryFeed::test_filters_by_location_name_case_insensitive โœ… passed 0 ms
TestGetStoryFeed::test_filters_by_location_name_partial_match โœ… passed 0 ms
TestGetStoryFeed::test_location_filter_excludes_non_matching โœ… passed 0 ms
TestGetStoryFeed::test_combined_year_and_location_filter โœ… passed 0 ms
TestCreateStory::test_create_story_returns_story_instance โœ… passed 0 ms
TestCreateStory::test_create_story_persists_to_database โœ… passed 0 ms
TestCreateStory::test_create_story_sets_correct_user โœ… passed 0 ms
TestCreateStory::test_create_story_sets_correct_fields โœ… passed 0 ms
TestCreateStory::test_create_story_with_null_user โœ… passed 0 ms
TestUpdateStory::test_update_story_returns_story_instance โœ… passed 0 ms
TestUpdateStory::test_update_story_persists_changes โœ… passed 0 ms
TestUpdateStory::test_update_story_does_not_affect_unspecified_fields โœ… passed 0 ms
TestUpdateStory::test_update_story_can_change_status_to_draft โœ… passed 0 ms
TestGetStorySearch::test_get_story_search_matches_title โœ… passed 0 ms
TestGetStorySearch::test_get_story_search_matches_location_name โœ… passed 0 ms
TestGetStorySearch::test_get_story_search_is_case_insensitive โœ… passed 0 ms
TestGetStorySearch::test_get_story_search_with_empty_query_returns_empty โœ… passed 0 ms
TestGetStorySearch::test_get_story_search_with_whitespace_only_query_returns_empty โœ… passed 0 ms
TestGetStorySearch::test_get_story_search_excludes_removed_stories โœ… passed 0 ms
TestGetStorySearch::test_get_story_search_excludes_draft_stories โœ… passed 0 ms
TestGetStorySearch::test_get_story_search_returns_no_results_when_no_match โœ… passed 0 ms
TestGetStorySearch::test_get_story_search_returns_multiple_matches โœ… passed 0 ms
TestGetStorySearch::test_get_story_search_filters_by_year_from โœ… passed 0 ms
TestGetStorySearch::test_get_story_search_filters_by_year_to โœ… passed 0 ms
TestGetStorySearch::test_get_story_search_filters_by_year_from_and_year_to โœ… passed 0 ms
TestGetStorySearch::test_get_story_search_filters_by_location โœ… passed 0 ms
TestGetStorySearch::test_get_story_search_excludes_non_matching_location โœ… passed 0 ms
TestGetStorySearch::test_get_story_search_combined_text_year_and_location โœ… passed 0 ms
TestGetStoryFeedTagFilter::test_feed_tag_filter_returns_matching_stories โœ… passed 0 ms
TestGetStoryFeedTagFilter::test_feed_tag_filter_excludes_non_matching_stories โœ… passed 0 ms
TestGetStoryFeedTagFilter::test_feed_tag_filter_is_case_insensitive โœ… passed 0 ms
TestGetStoryFeedTagFilter::test_feed_tag_filter_combined_with_year_filter โœ… passed 0 ms
TestGetStoryFeedTagFilter::test_feed_tag_filter_combined_with_location_filter โœ… passed 0 ms
TestGetStoryFeedTagFilter::test_feed_tag_filter_does_not_return_duplicates โœ… passed 0 ms
TestGetStorySearchTagFilter::test_search_tag_param_narrows_results โœ… passed 0 ms
TestGetStorySearchTagFilter::test_search_tag_param_excludes_untagged โœ… passed 0 ms
TestGetStorySearchTagFilter::test_search_tag_and_q_both_must_match โœ… passed 0 ms
TestDeleteStory::test_delete_removes_story_from_db โœ… passed 0 ms
TestDeleteStory::test_delete_returns_none โœ… passed 0 ms
TestCreateStoryWithTags::test_create_story_with_tag_ids_attaches_tags โœ… passed 0 ms
TestCreateStoryWithTags::test_create_story_with_tag_ids_increments_story_count โœ… passed 0 ms
TestCreateStoryWithTags::test_create_story_without_tag_ids_creates_no_story_tags โœ… passed 0 ms
TestCreateStoryWithTags::test_create_story_with_empty_tag_ids_creates_no_story_tags โœ… passed 0 ms
TestUpdateStoryWithTags::test_update_story_syncs_tags_when_provided โœ… passed 0 ms
TestUpdateStoryWithTags::test_update_story_leaves_tags_when_tag_ids_not_provided โœ… passed 0 ms
TestUpdateStoryWithTags::test_update_story_removes_all_tags_when_empty_list_provided โœ… passed 0 ms
TestUpdateStoryWithTags::test_update_story_decrements_story_count_for_removed_tags โœ… passed 0 ms
TestGetStoryFeedGeoFilter::test_returns_story_within_radius โœ… passed 0 ms
TestGetStoryFeedGeoFilter::test_excludes_story_outside_radius โœ… passed 0 ms
TestGetStoryFeedGeoFilter::test_larger_radius_includes_more_stories โœ… passed 0 ms
TestGetStoryFeedGeoFilter::test_omitting_geo_params_returns_all_stories โœ… passed 0 ms
TestGetStoryFeedGeoFilter::test_geo_filter_combined_with_year_filter โœ… passed 0 ms
TestGetStoryFeedGeoFilter::test_geo_filter_combined_with_tag_filter โœ… passed 0 ms
TestGetStoryFeedGeoFilter::test_geo_filter_result_is_queryset_compatible_with_annotate โœ… passed 0 ms
TestGetStoryFeedGeoFilter::test_geo_filter_preserves_sort_by_popular_ordering โœ… passed 0 ms
TestGetStoryFeedGeoFilter::test_geo_filter_returns_empty_when_no_stories_within_radius โœ… passed 0 ms
TestGetStoryFeedGeoFilter::test_geo_filter_excludes_draft_stories_within_radius โœ… passed 0 ms
TestGetStorySearchGeoFilter::test_returns_matching_story_within_radius โœ… passed 0 ms
TestGetStorySearchGeoFilter::test_excludes_matching_story_outside_radius โœ… passed 0 ms
TestGetStorySearchGeoFilter::test_geo_filter_does_not_include_non_matching_nearby_story โœ… passed 0 ms
TestGetStorySearchGeoFilter::test_omitting_geo_params_returns_all_matching_stories โœ… passed 0 ms
TestGetStorySearchGeoFilter::test_geo_filter_result_is_queryset_compatible_with_annotate โœ… passed 0 ms
TestStoryFeedView::test_returns_200_for_unauthenticated_user โœ… passed 0 ms
TestStoryFeedView::test_returns_200_for_authenticated_user โœ… passed 0 ms
TestStoryFeedView::test_returns_paginated_response_shape โœ… passed 0 ms
TestStoryFeedView::test_returns_paginated_results โœ… passed 0 ms
TestStoryFeedView::test_second_page_returns_remaining_results โœ… passed 0 ms
TestStoryFeedView::test_sorts_by_recent_by_default โœ… passed 0 ms
TestStoryFeedView::test_excludes_removed_stories โœ… passed 0 ms
TestStoryFeedView::test_excludes_draft_stories โœ… passed 0 ms
TestStoryFeedView::test_filters_by_year_from โœ… passed 0 ms
TestStoryFeedView::test_filters_by_year_to โœ… passed 0 ms
TestStoryFeedView::test_filters_by_year_from_and_year_to โœ… passed 0 ms
TestStoryFeedView::test_filters_by_location โœ… passed 0 ms
TestStoryFeedView::test_location_filter_is_case_insensitive โœ… passed 0 ms
TestStoryFeedView::test_returns_empty_list_when_no_stories_match โœ… passed 0 ms
TestStoryFeedView::test_returns_empty_list_when_no_stories_exist โœ… passed 0 ms
TestStoryFeedView::test_result_contains_expected_card_fields โœ… passed 0 ms
TestStoryFeedView::test_returns_400_for_invalid_sort_by โœ… passed 0 ms
TestStoryFeedView::test_returns_400_for_non_integer_year_from โœ… passed 0 ms
TestStoryFeedView::test_returns_400_when_year_from_greater_than_year_to โœ… passed 0 ms
TestStoryFeedView::test_feed_tag_filter_returns_only_tagged_stories โœ… passed 0 ms
TestStoryFeedView::test_feed_tag_filter_returns_empty_when_no_match โœ… passed 0 ms
TestStoryFeedView::test_feed_tag_and_location_filter_combined โœ… passed 0 ms
TestStoryListView::test_guest_can_list_stories โœ… passed 0 ms
TestStoryListView::test_list_returns_paginated_response_shape โœ… passed 0 ms
TestStoryListView::test_list_excludes_draft_stories โœ… passed 0 ms
TestStoryListView::test_list_excludes_removed_stories โœ… passed 0 ms
TestStoryCreateView::test_authenticated_user_can_create_story โœ… passed 0 ms
TestStoryCreateView::test_guest_cannot_create_story โœ… passed 0 ms
TestStoryCreateView::test_create_assigns_authenticated_user โœ… passed 0 ms
TestStoryCreateView::test_create_returns_400_for_removed_status โœ… passed 0 ms
TestStoryCreateView::test_create_returns_400_when_year_missing_for_exact_time_type โœ… passed 0 ms
TestStoryDetailView::test_guest_can_retrieve_story โœ… passed 0 ms
TestStoryDetailView::test_owner_can_partially_update_story โœ… passed 0 ms
TestStoryDetailView::test_non_owner_cannot_update_story โœ… passed 0 ms
TestStoryDetailView::test_admin_can_update_any_story โœ… passed 0 ms
TestStoryDetailView::test_guest_cannot_update_story โœ… passed 0 ms
TestStorySearchView::test_search_endpoint_returns_200_for_unauthenticated_user โœ… passed 0 ms
TestStorySearchView::test_search_endpoint_returns_results_matching_title โœ… passed 0 ms
TestStorySearchView::test_search_endpoint_returns_results_matching_location_name โœ… passed 0 ms
TestStorySearchView::test_search_endpoint_returns_400_when_q_is_missing โœ… passed 0 ms
TestStorySearchView::test_search_endpoint_returns_400_when_q_is_blank โœ… passed 0 ms
TestStorySearchView::test_search_endpoint_returns_empty_list_when_no_match โœ… passed 0 ms
TestStorySearchView::test_search_endpoint_excludes_removed_stories โœ… passed 0 ms
TestStorySearchView::test_search_filters_by_year_from โœ… passed 0 ms
TestStorySearchView::test_search_filters_by_year_to โœ… passed 0 ms
TestStorySearchView::test_search_filters_by_location โœ… passed 0 ms
TestStorySearchView::test_search_with_combined_filters โœ… passed 0 ms
TestStorySearchView::test_search_returns_400_for_invalid_year_range โœ… passed 0 ms
TestStorySearchView::test_search_returns_400_for_invalid_sort_by โœ… passed 0 ms
TestStorySearchView::test_search_tag_filter_narrows_results โœ… passed 0 ms
TestStorySearchView::test_search_tag_filter_returns_empty_when_tag_missing โœ… passed 0 ms
TestStorySearchView::test_search_tag_and_q_both_must_match โœ… passed 0 ms
TestStoryMapView::test_returns_200_without_authentication โœ… passed 0 ms
TestStoryMapView::test_response_is_feature_collection โœ… passed 0 ms
TestStoryMapView::test_response_is_not_paginated โœ… passed 0 ms
TestStoryMapView::test_each_story_is_a_geojson_feature โœ… passed 0 ms
TestStoryMapView::test_coordinates_are_lng_lat_order โœ… passed 0 ms
TestStoryMapView::test_only_published_stories_appear โœ… passed 0 ms
TestStoryMapView::test_empty_feature_collection_when_no_published_stories โœ… passed 0 ms
TestStoryMapView::test_returns_all_stories_without_pagination โœ… passed 0 ms
TestStoryMapView::test_year_from_filter_excludes_older_stories โœ… passed 0 ms
TestStoryMapView::test_year_to_filter_excludes_newer_stories โœ… passed 0 ms
TestStoryMapView::test_location_filter_is_case_insensitive โœ… passed 0 ms
TestStoryMapView::test_invalid_year_range_returns_400 โœ… passed 0 ms
TestStoryMapView::test_narrative_not_exposed_in_properties โœ… passed 0 ms
TestStoryMapView::test_map_tag_filter_returns_only_tagged_stories โœ… passed 0 ms
TestStoryMapView::test_map_tag_filter_returns_empty_when_no_match โœ… passed 0 ms
TestStoryDetailMediaItems::test_get_story_detail_includes_media_items_field โœ… passed 0 ms
TestStoryDetailMediaItems::test_get_story_detail_media_items_empty_when_no_media โœ… passed 0 ms
TestStoryDetailMediaItems::test_get_story_detail_media_items_contains_uploaded_images โœ… passed 0 ms
TestStoryDetailUserInteraction::test_user_has_liked_false_for_unauthenticated โœ… passed 0 ms
TestStoryDetailUserInteraction::test_user_has_liked_true_after_like โœ… passed 0 ms
TestStoryFeedUserInteraction::test_feed_user_has_liked_false_for_unauthenticated โœ… passed 0 ms
TestStoryFeedUserInteraction::test_feed_user_has_liked_true_after_like โœ… passed 0 ms
TestStoryDelete::test_owner_can_delete_own_story โœ… passed 0 ms
TestStoryDelete::test_admin_can_delete_any_story โœ… passed 0 ms
TestStoryDelete::test_other_user_cannot_delete_story โœ… passed 0 ms
TestStoryDelete::test_unauthenticated_cannot_delete_story โœ… passed 0 ms
TestStoryDelete::test_delete_nonexistent_story_returns_404 โœ… passed 0 ms
TestStoryDelete::test_delete_returns_no_body โœ… passed 0 ms
TestStoryTagAssignment::test_create_story_with_tag_ids_returns_tags_in_response โœ… passed 0 ms
TestStoryTagAssignment::test_create_story_increments_tag_story_count โœ… passed 0 ms
TestStoryTagAssignment::test_create_story_with_too_many_tags_returns_400 โœ… passed 0 ms
TestStoryTagAssignment::test_create_story_with_nonexistent_tag_id_returns_400 โœ… passed 0 ms
TestStoryTagAssignment::test_create_story_with_duplicate_tag_ids_returns_400 โœ… passed 0 ms
TestStoryTagAssignment::test_patch_story_adds_tag โœ… passed 0 ms
TestStoryTagAssignment::test_patch_story_removes_old_tag_and_adds_new โœ… passed 0 ms
TestStoryTagAssignment::test_patch_story_without_tag_ids_leaves_existing_tags โœ… passed 0 ms
TestStoryTagAssignment::test_patch_story_with_empty_tag_ids_removes_all_tags โœ… passed 0 ms
TestStoryTagAssignment::test_story_list_response_includes_tags_field โœ… passed 0 ms
TestStoryTagAssignment::test_story_detail_response_includes_tags_field โœ… passed 0 ms
TestStoryFeedViewGeoFilter::test_geo_filter_returns_only_nearby_stories โœ… passed 0 ms
TestStoryFeedViewGeoFilter::test_geo_filter_unauthenticated_returns_200 โœ… passed 0 ms
TestStoryFeedViewGeoFilter::test_geo_filter_empty_results_when_no_stories_nearby โœ… passed 0 ms
TestStoryFeedViewGeoFilter::test_geo_filter_latitude_only_returns_400 โœ… passed 0 ms
TestStoryFeedViewGeoFilter::test_geo_filter_latitude_and_longitude_without_radius_returns_400 โœ… passed 0 ms
TestStoryFeedViewGeoFilter::test_geo_filter_invalid_latitude_returns_400 โœ… passed 0 ms
TestStoryFeedViewGeoFilter::test_geo_filter_invalid_longitude_returns_400 โœ… passed 0 ms
TestStoryFeedViewGeoFilter::test_geo_filter_zero_radius_returns_400 โœ… passed 0 ms
TestStoryFeedViewGeoFilter::test_geo_filter_negative_radius_returns_400 โœ… passed 0 ms
TestStoryFeedViewGeoFilter::test_geo_filter_combined_with_year_filter โœ… passed 0 ms
TestStoryFeedViewGeoFilter::test_geo_filter_combined_with_tag_filter โœ… passed 0 ms
TestStoryMapViewGeoFilter::test_geo_filter_returns_only_nearby_features โœ… passed 0 ms
TestStoryMapViewGeoFilter::test_geo_filter_unauthenticated_returns_200 โœ… passed 0 ms
TestStoryMapViewGeoFilter::test_geo_filter_missing_one_param_returns_400 โœ… passed 0 ms
TestStoryMapViewGeoFilter::test_geo_filter_invalid_latitude_returns_400 โœ… passed 0 ms
TestStoryMapViewGeoFilter::test_geo_filter_empty_results_when_no_stories_nearby โœ… passed 0 ms
TestStoryMapViewGeoFilter::test_geo_filter_returns_geojson_feature_collection โœ… passed 0 ms
TestStorySearchViewGeoFilter::test_geo_filter_returns_only_nearby_matching_stories โœ… passed 0 ms
TestStorySearchViewGeoFilter::test_geo_filter_unauthenticated_returns_200 โœ… passed 0 ms
TestStorySearchViewGeoFilter::test_geo_filter_missing_one_param_returns_400 โœ… passed 0 ms
TestStorySearchViewGeoFilter::test_geo_filter_invalid_latitude_returns_400 โœ… passed 0 ms
TestStorySearchViewGeoFilter::test_geo_filter_empty_results_when_no_matching_stories_nearby โœ… passed 0 ms
TestTag::test_tag_can_be_created โœ… passed 0 ms
TestTag::test_is_predefined_defaults_to_false โœ… passed 0 ms
TestTag::test_story_count_defaults_to_zero โœ… passed 0 ms
TestTag::test_str_returns_name โœ… passed 0 ms
TestTag::test_tag_name_must_be_unique โœ… passed 0 ms
TestTag::test_valid_single_lowercase_word โœ… passed 0 ms
TestTag::test_valid_hyphen_separated_words โœ… passed 0 ms
TestTag::test_valid_name_with_digits โœ… passed 0 ms
TestTag::test_valid_digits_only โœ… passed 0 ms
TestTag::test_invalid_uppercase_raises โœ… passed 0 ms
TestTag::test_invalid_spaces_raises โœ… passed 0 ms
TestTag::test_invalid_leading_hyphen_raises โœ… passed 0 ms
TestTag::test_invalid_trailing_hyphen_raises โœ… passed 0 ms
TestTag::test_invalid_double_hyphen_raises โœ… passed 0 ms
TestTag::test_invalid_special_characters_raise โœ… passed 0 ms
TestStoryTag::test_story_tag_can_be_created โœ… passed 0 ms
TestStoryTag::test_duplicate_story_tag_raises_integrity_error โœ… passed 0 ms
TestStoryTag::test_same_tag_on_different_stories_is_allowed โœ… passed 0 ms
TestStoryTag::test_different_tags_on_same_story_is_allowed โœ… passed 0 ms
TestStoryTag::test_cascade_deletes_when_story_is_deleted โœ… passed 0 ms
TestStoryTag::test_cascade_deletes_when_tag_is_deleted โœ… passed 0 ms
TestStoryTag::test_story_can_hold_three_tags โœ… passed 0 ms
TestTagSerializer::test_valid_slug_format_is_accepted โœ… passed 0 ms
TestTagSerializer::test_valid_single_word_is_accepted โœ… passed 0 ms
TestTagSerializer::test_valid_name_with_digits_is_accepted โœ… passed 0 ms
TestTagSerializer::test_uppercase_is_normalized_to_lowercase โœ… passed 0 ms
TestTagSerializer::test_spaces_are_converted_to_hyphens โœ… passed 0 ms
TestTagSerializer::test_underscores_are_converted_to_hyphens โœ… passed 0 ms
TestTagSerializer::test_mixed_case_spaces_normalized โœ… passed 0 ms
TestTagSerializer::test_special_characters_are_stripped โœ… passed 0 ms
TestTagSerializer::test_leading_and_trailing_hyphens_are_stripped โœ… passed 0 ms
TestTagSerializer::test_consecutive_hyphens_are_collapsed โœ… passed 0 ms
TestTagSerializer::test_empty_string_is_rejected โœ… passed 0 ms
TestTagSerializer::test_whitespace_only_is_rejected โœ… passed 0 ms
TestTagSerializer::test_all_special_chars_is_rejected โœ… passed 0 ms
TestTagSerializer::test_missing_name_field_is_rejected โœ… passed 0 ms
TestTagSerializer::test_id_is_read_only โœ… passed 0 ms
TestTagSerializer::test_is_predefined_is_read_only โœ… passed 0 ms
TestTagSerializer::test_story_count_is_read_only โœ… passed 0 ms
TestListTags::test_returns_created_tags โœ… passed 0 ms
TestListTags::test_filters_predefined_true โœ… passed 0 ms
TestListTags::test_filters_predefined_false โœ… passed 0 ms
TestListTags::test_filters_by_q โœ… passed 0 ms
TestListTags::test_combined_filter_predefined_and_q โœ… passed 0 ms
TestListTags::test_ordered_by_story_count_desc_then_name โœ… passed 0 ms
TestListTags::test_q_is_case_insensitive โœ… passed 0 ms
TestCreateTag::test_creates_new_tag โœ… passed 0 ms
TestCreateTag::test_duplicate_returns_existing_tag โœ… passed 0 ms
TestCreateTag::test_normalizes_name_before_lookup โœ… passed 0 ms
TestCreateTag::test_admin_flag_sets_is_predefined_on_creation โœ… passed 0 ms
TestCreateTag::test_user_creation_sets_is_predefined_false โœ… passed 0 ms
TestCreateTag::test_does_not_overwrite_is_predefined_on_existing_tag โœ… passed 0 ms
TestDeleteTag::test_deletes_tag โœ… passed 0 ms
TestDeleteTag::test_cascade_deletes_story_tags โœ… passed 0 ms
TestAttachTagsToStory::test_creates_story_tag_rows โœ… passed 0 ms
TestAttachTagsToStory::test_increments_story_count โœ… passed 0 ms
TestAttachTagsToStory::test_skips_already_linked_tags โœ… passed 0 ms
TestAttachTagsToStory::test_does_not_double_increment_for_existing_link โœ… passed 0 ms
TestAttachTagsToStory::test_attach_tags_to_story_handles_integrity_error_gracefully โœ… passed 0 ms
TestSyncStoryTags::test_adds_new_tags โœ… passed 0 ms
TestSyncStoryTags::test_increments_story_count_on_add โœ… passed 0 ms
TestSyncStoryTags::test_removes_old_tags โœ… passed 0 ms
TestSyncStoryTags::test_decrements_story_count_on_remove โœ… passed 0 ms
TestSyncStoryTags::test_empty_list_removes_all_tags โœ… passed 0 ms
TestSyncStoryTags::test_unchanged_tags_not_recreated โœ… passed 0 ms
TestSyncStoryTags::test_sync_story_tags_handles_integrity_error_gracefully โœ… passed 0 ms
TestStoryCountSignals::test_story_count_decremented_on_individual_story_delete โœ… passed 0 ms
TestStoryCountSignals::test_story_count_decremented_on_bulk_story_delete โœ… passed 0 ms
TestTagListView::test_unauthenticated_can_list_tags โœ… passed 0 ms
TestTagListView::test_returns_all_tags_by_default โœ… passed 0 ms
TestTagListView::test_is_predefined_true_returns_only_predefined โœ… passed 0 ms
TestTagListView::test_is_predefined_false_returns_only_user_created โœ… passed 0 ms
TestTagListView::test_q_filters_by_name โœ… passed 0 ms
TestTagListView::test_combined_is_predefined_and_q_filter โœ… passed 0 ms
TestTagListView::test_response_contains_expected_fields โœ… passed 0 ms
TestTagCreateView::test_registered_user_creates_new_tag โœ… passed 0 ms
TestTagCreateView::test_duplicate_returns_200_with_existing_tag โœ… passed 0 ms
TestTagCreateView::test_mixed_case_input_normalized_and_matched โœ… passed 0 ms
TestTagCreateView::test_admin_creates_tag_with_is_predefined_true โœ… passed 0 ms
TestTagCreateView::test_unauthenticated_cannot_create_tag โœ… passed 0 ms
TestTagCreateView::test_invalid_name_after_normalization_returns_400 โœ… passed 0 ms
TestTagCreateView::test_is_predefined_field_in_request_is_ignored โœ… passed 0 ms
TestTagDeleteView::test_admin_deletes_tag โœ… passed 0 ms
TestTagDeleteView::test_registered_user_cannot_delete_tag โœ… passed 0 ms
TestTagDeleteView::test_unauthenticated_cannot_delete_tag โœ… passed 0 ms
TestTagDeleteView::test_delete_unknown_pk_returns_404 โœ… passed 0 ms
TestUserManager::test_create_user_sets_fields_correctly โœ… passed 0 ms
TestUserManager::test_create_user_hashes_password โœ… passed 0 ms
TestUserManager::test_create_user_normalizes_email โœ… passed 0 ms
TestUserManager::test_create_user_requires_email โœ… passed 0 ms
TestUserManager::test_create_user_requires_username โœ… passed 0 ms
TestUserManager::test_create_superuser_sets_admin_fields โœ… passed 0 ms
TestUserManager::test_email_must_be_unique โœ… passed 0 ms
TestUserManager::test_username_must_be_unique โœ… passed 0 ms
TestUserNewFields::test_is_username_public_defaults_to_true โœ… passed 0 ms
TestUserNewFields::test_is_username_public_can_be_set_false โœ… passed 0 ms
TestUserNewFields::test_total_points_defaults_to_zero โœ… passed 0 ms
TestUserNewFields::test_total_points_persists_large_value โœ… passed 0 ms
TestUserNewFields::test_total_points_can_store_negative_value โœ… passed 0 ms
TestUserProfile::test_profile_can_be_created_for_user โœ… passed 0 ms
TestUserProfile::test_privacy_flags_default_to_true โœ… passed 0 ms
TestUserProfile::test_optional_text_fields_default_to_blank โœ… passed 0 ms
TestUserProfile::test_first_name_and_last_name_store_correctly โœ… passed 0 ms
TestUserProfile::test_is_name_public_can_be_set_false โœ… passed 0 ms
TestUserProfile::test_optional_nullable_fields_default_to_none โœ… passed 0 ms
TestUserProfile::test_birth_date_stores_and_retrieves_correctly โœ… passed 0 ms
TestUserProfile::test_profile_str_contains_username โœ… passed 0 ms
TestUserProfile::test_profile_is_deleted_when_user_is_deleted โœ… passed 0 ms
TestUserProfile::test_one_user_cannot_have_two_profiles โœ… passed 0 ms
TestUserProfile::test_profile_privacy_flags_can_be_toggled โœ… passed 0 ms
TestEmailVerificationCode::test_generate_code_returns_six_digits โœ… passed 0 ms
TestEmailVerificationCode::test_code_is_not_expired_when_fresh โœ… passed 0 ms
TestEmailVerificationCode::test_code_is_expired_when_past_expiry โœ… passed 0 ms
TestEmailVerificationCode::test_code_defaults_to_unused โœ… passed 0 ms
TestEmailVerificationCode::test_code_is_linked_to_user โœ… passed 0 ms
TestEmailVerificationCode::test_str_representation โœ… passed 0 ms
TestFollowModel::test_follow_can_be_created โœ… passed 0 ms
TestFollowModel::test_str_representation โœ… passed 0 ms
TestFollowModel::test_unique_constraint_prevents_duplicate โœ… passed 0 ms
TestFollowModel::test_deleting_follower_cascades โœ… passed 0 ms
TestFollowModel::test_deleting_followed_cascades โœ… passed 0 ms
TestRegisterSerializer::test_valid_data_passes โœ… passed 0 ms
TestRegisterSerializer::test_email_is_lowercased โœ… passed 0 ms
TestRegisterSerializer::test_duplicate_email_fails โœ… passed 0 ms
TestRegisterSerializer::test_duplicate_username_fails โœ… passed 0 ms
TestRegisterSerializer::test_passwords_must_match โœ… passed 0 ms
TestRegisterSerializer::test_short_password_fails โœ… passed 0 ms
TestRegisterSerializer::test_password_without_digit_fails โœ… passed 0 ms
TestRegisterSerializer::test_password_without_uppercase_fails โœ… passed 0 ms
TestRegisterSerializer::test_password_without_lowercase_fails โœ… passed 0 ms
TestRegisterSerializer::test_username_too_short_fails โœ… passed 0 ms
TestRegisterSerializer::test_invalid_email_format_fails โœ… passed 0 ms
TestRegisterSerializer::test_password_is_write_only โœ… passed 0 ms
TestPublicUserProfileSerializer::test_contains_required_fields โœ… passed 0 ms
TestPublicUserProfileSerializer::test_username_visible_when_public โœ… passed 0 ms
TestPublicUserProfileSerializer::test_username_hidden_when_private โœ… passed 0 ms
TestPublicUserProfileSerializer::test_published_story_count_is_correct โœ… passed 0 ms
TestPublicUserProfileSerializer::test_location_visible_when_flag_true โœ… passed 0 ms
TestPublicUserProfileSerializer::test_location_hidden_when_flag_false โœ… passed 0 ms
TestPublicUserProfileSerializer::test_bio_always_returned_when_profile_exists โœ… passed 0 ms
TestPublicUserProfileSerializer::test_birth_year_hidden_when_flag_false โœ… passed 0 ms
TestPublicUserProfileSerializer::test_birth_year_returns_integer_year_only โœ… passed 0 ms
TestPublicUserProfileSerializer::test_no_profile_returns_null_for_optional_fields โœ… passed 0 ms
TestPublicUserProfileSerializer::test_profile_photo_returns_absolute_url_when_public โœ… passed 0 ms
TestPublicUserProfileSerializer::test_profile_photo_hidden_when_is_photo_public_false โœ… passed 0 ms
TestPublicUserProfileSerializer::test_first_name_and_last_name_visible_when_is_name_public_true โœ… passed 0 ms
TestPublicUserProfileSerializer::test_first_name_and_last_name_hidden_when_is_name_public_false โœ… passed 0 ms
TestPublicUserProfileSerializer::test_first_name_null_when_no_profile โœ… passed 0 ms
TestCurrentUserSerializer::test_contains_all_expected_fields โœ… passed 0 ms
TestCurrentUserSerializer::test_field_values_match_user โœ… passed 0 ms
TestCurrentUserSerializer::test_profile_is_none_when_no_profile_exists โœ… passed 0 ms
TestCurrentUserSerializer::test_profile_nested_when_profile_exists โœ… passed 0 ms
TestCurrentUserSerializer::test_profile_returns_all_privacy_flags_to_owner โœ… passed 0 ms
TestCurrentUserSerializer::test_profile_birth_date_returned_as_full_date_not_year_only โœ… passed 0 ms
TestCurrentUserSerializer::test_profile_photo_none_when_not_set โœ… passed 0 ms
TestCurrentUserSerializer::test_profile_photo_returns_absolute_url_with_request_context โœ… passed 0 ms
TestCurrentUserSerializer::test_profile_returns_name_fields_to_owner โœ… passed 0 ms
TestUpdateCurrentUserSerializer::test_valid_new_username_passes โœ… passed 0 ms
TestUpdateCurrentUserSerializer::test_same_username_as_own_passes โœ… passed 0 ms
TestUpdateCurrentUserSerializer::test_duplicate_username_from_other_user_fails โœ… passed 0 ms
TestUpdateCurrentUserSerializer::test_username_too_short_fails โœ… passed 0 ms
TestUpdateCurrentUserSerializer::test_empty_data_passes โœ… passed 0 ms
TestUpdateCurrentUserSerializer::test_profile_only_passes โœ… passed 0 ms
TestUpdateCurrentUserSerializer::test_split_validated_data_separates_user_and_profile_fields โœ… passed 0 ms
TestUpdateCurrentUserSerializer::test_split_validated_data_empty_profile_when_not_provided โœ… passed 0 ms
TestUpdateCurrentUserSerializer::test_protected_fields_are_silently_ignored โœ… passed 0 ms
TestDeleteAccountSerializer::test_valid_data_with_hard_delete_true_passes โœ… passed 0 ms
TestDeleteAccountSerializer::test_valid_data_with_hard_delete_false_passes โœ… passed 0 ms
TestDeleteAccountSerializer::test_hard_delete_defaults_to_true โœ… passed 0 ms
TestDeleteAccountSerializer::test_refresh_is_optional โœ… passed 0 ms
TestDeleteAccountSerializer::test_refresh_with_token_passes โœ… passed 0 ms
TestDeleteAccountSerializer::test_password_is_write_only โœ… passed 0 ms
TestDeleteAccountSerializer::test_missing_password_fails โœ… passed 0 ms
TestDeleteAccountSerializer::test_wrong_password_fails โœ… passed 0 ms
TestDeleteAccountSerializer::test_wrong_password_error_message_is_clear โœ… passed 0 ms
TestRegisterUser::test_creates_user โœ… passed 0 ms
TestRegisterUser::test_password_is_hashed โœ… passed 0 ms
TestRegisterUser::test_creates_verification_code โœ… passed 0 ms
TestRegisterUser::test_user_is_active_on_registration โœ… passed 0 ms
TestRegisterUser::test_email_is_not_verified_on_registration โœ… passed 0 ms
TestLoginUser::test_returns_tokens_on_valid_credentials โœ… passed 0 ms
TestLoginUser::test_returns_user_info โœ… passed 0 ms
TestLoginUser::test_wrong_password_raises_auth_failed โœ… passed 0 ms
TestLoginUser::test_wrong_email_raises_auth_failed โœ… passed 0 ms
TestLoginUser::test_wrong_email_and_wrong_password_same_error โœ… passed 0 ms
TestLoginUser::test_inactive_user_cannot_login โœ… passed 0 ms
TestLoginUser::test_inactive_user_gets_same_error_as_invalid_credentials โœ… passed 0 ms
TestLogoutUser::test_valid_refresh_token_is_blacklisted โœ… passed 0 ms
TestLogoutUser::test_blacklisted_token_raises_validation_error โœ… passed 0 ms
TestLogoutUser::test_invalid_token_raises_validation_error โœ… passed 0 ms
TestGetPublicProfile::test_returns_user_for_valid_id โœ… passed 0 ms
TestGetPublicProfile::test_raises_404_for_nonexistent_user โœ… passed 0 ms
TestGetPublicProfile::test_annotates_published_story_count โœ… passed 0 ms
TestGetPublicProfile::test_zero_published_stories โœ… passed 0 ms
TestGetPublicProfile::test_profile_is_prefetched โœ… passed 0 ms
TestGetPublicProfile::test_inactive_user_raises_404 โœ… passed 0 ms
TestGetOwnProfile::test_returns_correct_user โœ… passed 0 ms
TestGetOwnProfile::test_creates_profile_when_not_exists โœ… passed 0 ms
TestGetOwnProfile::test_profile_accessible_via_relation โœ… passed 0 ms
TestGetOwnProfile::test_idempotent_when_profile_already_exists โœ… passed 0 ms
TestUpdateOwnProfile::test_updates_user_fields โœ… passed 0 ms
TestUpdateOwnProfile::test_updates_is_username_public โœ… passed 0 ms
TestUpdateOwnProfile::test_updates_profile_fields โœ… passed 0 ms
TestUpdateOwnProfile::test_creates_profile_when_not_exists_on_profile_update โœ… passed 0 ms
TestUpdateOwnProfile::test_updates_both_user_and_profile_fields โœ… passed 0 ms
TestUpdateOwnProfile::test_returns_user_with_profile_prefetched โœ… passed 0 ms
TestUpdateOwnProfile::test_empty_fields_returns_user_unchanged โœ… passed 0 ms
TestUpdateOwnProfile::test_does_not_create_profile_when_profile_fields_empty โœ… passed 0 ms
TestUpdateOwnProfile::test_persists_profile_privacy_flags โœ… passed 0 ms
TestUploadProfilePhoto::test_upload_jpeg_succeeds โœ… passed 0 ms
TestUploadProfilePhoto::test_upload_png_succeeds โœ… passed 0 ms
TestUploadProfilePhoto::test_wrong_mime_type_raises_validation_error โœ… passed 0 ms
TestUploadProfilePhoto::test_oversized_file_raises_validation_error โœ… passed 0 ms
TestUploadProfilePhoto::test_creates_profile_if_not_exists โœ… passed 0 ms
TestUploadProfilePhoto::test_replace_removes_old_file_from_storage โœ… passed 0 ms
TestUploadProfilePhoto::test_replace_stores_new_file โœ… passed 0 ms
TestDeleteAccount::test_hard_delete_removes_user โœ… passed 0 ms
TestDeleteAccount::test_hard_delete_removes_stories โœ… passed 0 ms
TestDeleteAccount::test_hard_delete_deletes_profile_photo_file โœ… passed 0 ms
TestDeleteAccount::test_hard_delete_with_no_photo_does_not_raise โœ… passed 0 ms
TestDeleteAccount::test_hard_delete_with_no_stories_does_not_raise โœ… passed 0 ms
TestDeleteAccount::test_soft_delete_deactivates_user โœ… passed 0 ms
TestDeleteAccount::test_soft_delete_anonymizes_stories โœ… passed 0 ms
TestDeleteAccount::test_soft_delete_preserves_story_data โœ… passed 0 ms
TestDeleteAccount::test_soft_delete_does_not_delete_user_row โœ… passed 0 ms
TestDeleteAccount::test_blacklists_refresh_token_on_hard_delete โœ… passed 0 ms
TestDeleteAccount::test_blacklists_refresh_token_on_soft_delete โœ… passed 0 ms
TestDeleteAccount::test_empty_refresh_token_does_not_raise โœ… passed 0 ms
TestDeleteAccount::test_already_blacklisted_token_does_not_raise โœ… passed 0 ms
TestDeleteAccount::test_malformed_refresh_token_does_not_raise โœ… passed 0 ms
TestDeleteAccount::test_hard_delete_removes_user_comments_on_other_stories โœ… passed 0 ms
TestDeleteAccount::test_hard_delete_deletes_story_media_files โœ… passed 0 ms
TestDeleteAccount::test_hard_delete_with_no_comments_does_not_raise โœ… passed 0 ms
TestDeleteAccount::test_soft_delete_does_not_remove_user_comments โœ… passed 0 ms
TestDeleteProfilePhoto::test_clears_photo_field โœ… passed 0 ms
TestDeleteProfilePhoto::test_deletes_file_from_storage โœ… passed 0 ms
TestDeleteProfilePhoto::test_no_op_when_no_profile_exists โœ… passed 0 ms
TestDeleteProfilePhoto::test_no_op_when_profile_has_no_photo โœ… passed 0 ms
TestFollowUser::test_creates_follow_record โœ… passed 0 ms
TestFollowUser::test_returns_follow_instance โœ… passed 0 ms
TestFollowUser::test_refollow_returns_created_false โœ… passed 0 ms
TestFollowUser::test_self_follow_raises_validation_error โœ… passed 0 ms
TestFollowUser::test_unknown_followed_id_raises_404 โœ… passed 0 ms
TestFollowUser::test_inactive_target_raises_404 โœ… passed 0 ms
TestUnfollowUser::test_removes_follow_record โœ… passed 0 ms
TestUnfollowUser::test_unfollow_non_followed_is_noop โœ… passed 0 ms
TestUnfollowUser::test_unknown_followed_id_raises_404 โœ… passed 0 ms
TestGetPublicProfileFollowCounts::test_followers_count_is_zero_initially โœ… passed 0 ms
TestGetPublicProfileFollowCounts::test_following_count_is_zero_initially โœ… passed 0 ms
TestGetPublicProfileFollowCounts::test_followers_count_increments_after_follow โœ… passed 0 ms
TestGetPublicProfileFollowCounts::test_following_count_increments_after_follow โœ… passed 0 ms
TestGetPublicProfileFollowCounts::test_followers_count_decrements_after_unfollow โœ… passed 0 ms
TestGetPublicProfileFollowCounts::test_followers_count_excludes_inactive_follower โœ… passed 0 ms
TestGetPublicProfileFollowCounts::test_following_count_excludes_inactive_followed โœ… passed 0 ms
TestGetUserBookmarks::test_returns_bookmarked_stories โœ… passed 0 ms
TestGetUserBookmarks::test_returns_only_published_stories โœ… passed 0 ms
TestGetUserBookmarks::test_empty_when_no_bookmarks โœ… passed 0 ms
TestGetUserBookmarks::test_ordered_most_recently_saved_first โœ… passed 0 ms
TestGetUserBookmarks::test_only_returns_own_bookmarks โœ… passed 0 ms
TestGetUserBookmarks::test_nonexistent_user_raises_404 โœ… passed 0 ms
TestGetUserBookmarks::test_inactive_user_raises_404 โœ… passed 0 ms
TestGetUserBookmarks::test_non_owner_raises_permission_denied โœ… passed 0 ms
TestRegisterView::test_register_success โœ… passed 0 ms
TestRegisterView::test_register_creates_user_in_db โœ… passed 0 ms
TestRegisterView::test_register_duplicate_email_returns_400 โœ… passed 0 ms
TestRegisterView::test_register_weak_password_returns_400 โœ… passed 0 ms
TestRegisterView::test_register_mismatched_passwords_returns_400 โœ… passed 0 ms
TestRegisterView::test_response_does_not_contain_password โœ… passed 0 ms
TestLoginView::test_login_success_returns_tokens โœ… passed 0 ms
TestLoginView::test_login_returns_user_info โœ… passed 0 ms
TestLoginView::test_login_wrong_password_returns_401 โœ… passed 0 ms
TestLoginView::test_login_wrong_email_returns_401 โœ… passed 0 ms
TestLoginView::test_login_wrong_email_and_wrong_password_same_message โœ… passed 0 ms
TestLoginView::test_response_does_not_contain_password โœ… passed 0 ms
TestLoginView::test_login_rate_limit_returns_429_after_limit โœ… passed 0 ms
TestLogoutView::test_logout_success_returns_204 โœ… passed 0 ms
TestLogoutView::test_logout_without_auth_returns_401 โœ… passed 0 ms
TestLogoutView::test_logout_blacklisted_token_returns_400 โœ… passed 0 ms
TestTokenRefreshView::test_refresh_returns_new_access_token โœ… passed 0 ms
TestTokenRefreshView::test_refresh_with_invalid_token_fails โœ… passed 0 ms
TestTokenRefreshView::test_refresh_with_blacklisted_token_fails โœ… passed 0 ms
TestTokenRefreshView::test_refresh_rotates_refresh_token โœ… passed 0 ms
TestUserPublicProfileView::test_returns_200_for_existing_user โœ… passed 0 ms
TestUserPublicProfileView::test_returns_404_for_nonexistent_user โœ… passed 0 ms
TestUserPublicProfileView::test_accessible_without_authentication โœ… passed 0 ms
TestUserPublicProfileView::test_response_contains_expected_fields โœ… passed 0 ms
TestUserPublicProfileView::test_username_visible_when_public โœ… passed 0 ms
TestUserPublicProfileView::test_username_hidden_when_private โœ… passed 0 ms
TestUserPublicProfileView::test_published_story_count_reflects_published_stories โœ… passed 0 ms
TestUserPublicProfileView::test_profile_photo_hidden_when_flag_false โœ… passed 0 ms
TestUserPublicProfileView::test_location_hidden_when_flag_false โœ… passed 0 ms
TestUserPublicProfileView::test_location_visible_when_flag_true โœ… passed 0 ms
TestUserPublicProfileView::test_bio_always_returned_when_profile_exists โœ… passed 0 ms
TestUserPublicProfileView::test_birth_year_hidden_when_flag_false โœ… passed 0 ms
TestUserPublicProfileView::test_birth_year_returns_integer_year_only โœ… passed 0 ms
TestUserPublicProfileView::test_inactive_user_returns_404 โœ… passed 0 ms
TestUserPublicProfileView::test_no_profile_returns_null_for_optional_fields โœ… passed 0 ms
TestUserPublicProfileView::test_name_visible_when_is_name_public_true โœ… passed 0 ms
TestUserPublicProfileView::test_name_hidden_when_is_name_public_false โœ… passed 0 ms
TestUserPublicProfileView::test_name_null_when_no_profile โœ… passed 0 ms
TestCurrentUserView::test_get_unauthenticated_returns_401 โœ… passed 0 ms
TestCurrentUserView::test_get_authenticated_returns_200 โœ… passed 0 ms
TestCurrentUserView::test_get_response_has_success_and_data_envelope โœ… passed 0 ms
TestCurrentUserView::test_get_response_contains_expected_fields โœ… passed 0 ms
TestCurrentUserView::test_get_returns_private_fields_to_owner โœ… passed 0 ms
TestCurrentUserView::test_get_creates_profile_if_not_exists โœ… passed 0 ms
TestCurrentUserView::test_get_profile_nested_when_profile_exists โœ… passed 0 ms
TestCurrentUserView::test_get_profile_includes_all_privacy_flags โœ… passed 0 ms
TestCurrentUserView::test_patch_unauthenticated_returns_401 โœ… passed 0 ms
TestCurrentUserView::test_patch_username_returns_200 โœ… passed 0 ms
TestCurrentUserView::test_patch_username_updates_in_db โœ… passed 0 ms
TestCurrentUserView::test_patch_response_contains_updated_username โœ… passed 0 ms
TestCurrentUserView::test_patch_profile_fields_returns_200 โœ… passed 0 ms
TestCurrentUserView::test_patch_profile_fields_updates_in_db โœ… passed 0 ms
TestCurrentUserView::test_patch_creates_profile_when_not_exists โœ… passed 0 ms
TestCurrentUserView::test_patch_protected_fields_are_ignored โœ… passed 0 ms
TestCurrentUserView::test_patch_duplicate_username_returns_400 โœ… passed 0 ms
TestCurrentUserView::test_patch_empty_body_returns_200 โœ… passed 0 ms
TestCurrentUserView::test_patch_response_has_success_and_data_envelope โœ… passed 0 ms
TestCurrentUserView::test_patch_profile_photo_is_ignored โœ… passed 0 ms
TestCurrentUserView::test_patch_name_fields_updates_in_db โœ… passed 0 ms
TestCurrentUserView::test_patch_is_name_public_updates_in_db โœ… passed 0 ms
TestCurrentUserView::test_get_profile_includes_name_fields_for_owner โœ… passed 0 ms
TestProfilePhotoView::test_upload_jpeg_returns_200 โœ… passed 0 ms
TestProfilePhotoView::test_upload_png_returns_200 โœ… passed 0 ms
TestProfilePhotoView::test_upload_response_contains_photo_url โœ… passed 0 ms
TestProfilePhotoView::test_upload_photo_url_is_absolute โœ… passed 0 ms
TestProfilePhotoView::test_upload_saves_photo_to_profile โœ… passed 0 ms
TestProfilePhotoView::test_upload_unsupported_mime_type_returns_400 โœ… passed 0 ms
TestProfilePhotoView::test_upload_unsupported_mime_type_error_references_photo_field โœ… passed 0 ms
TestProfilePhotoView::test_upload_oversized_file_returns_400 โœ… passed 0 ms
TestProfilePhotoView::test_upload_oversized_file_error_references_photo_field โœ… passed 0 ms
TestProfilePhotoView::test_upload_without_file_returns_400 โœ… passed 0 ms
TestProfilePhotoView::test_upload_unauthenticated_returns_401 โœ… passed 0 ms
TestProfilePhotoView::test_delete_after_upload_returns_204 โœ… passed 0 ms
TestProfilePhotoView::test_delete_clears_photo_field โœ… passed 0 ms
TestProfilePhotoView::test_delete_when_no_photo_returns_204 โœ… passed 0 ms
TestProfilePhotoView::test_delete_unauthenticated_returns_401 โœ… passed 0 ms
TestProfilePhotoView::test_photo_hidden_on_public_profile_after_toggling_flag_off โœ… passed 0 ms
TestProfilePhotoView::test_photo_visible_on_public_profile_after_toggling_flag_back_on โœ… passed 0 ms
TestDeleteAccountView::test_delete_unauthenticated_returns_401 โœ… passed 0 ms
TestDeleteAccountView::test_hard_delete_returns_204 โœ… passed 0 ms
TestDeleteAccountView::test_hard_delete_removes_user_from_db โœ… passed 0 ms
TestDeleteAccountView::test_hard_delete_removes_stories โœ… passed 0 ms
TestDeleteAccountView::test_soft_delete_returns_204 โœ… passed 0 ms
TestDeleteAccountView::test_soft_delete_deactivates_user โœ… passed 0 ms
TestDeleteAccountView::test_soft_delete_anonymizes_stories โœ… passed 0 ms
TestDeleteAccountView::test_with_refresh_token_blacklists_it โœ… passed 0 ms
TestDeleteAccountView::test_without_refresh_token_still_returns_204 โœ… passed 0 ms
TestDeleteAccountView::test_wrong_password_returns_400 โœ… passed 0 ms
TestDeleteAccountView::test_wrong_password_error_references_password_field โœ… passed 0 ms
TestDeleteAccountView::test_missing_password_returns_400 โœ… passed 0 ms
TestFollowView::test_first_follow_returns_201 โœ… passed 0 ms
TestFollowView::test_first_follow_response_shape โœ… passed 0 ms
TestFollowView::test_refollow_returns_200 โœ… passed 0 ms
TestFollowView::test_self_follow_returns_400 โœ… passed 0 ms
TestFollowView::test_unauthenticated_post_returns_401 โœ… passed 0 ms
TestFollowView::test_post_unknown_user_returns_404 โœ… passed 0 ms
TestFollowView::test_unfollow_returns_204 โœ… passed 0 ms
TestFollowView::test_unfollow_idempotent_returns_204 โœ… passed 0 ms
TestFollowView::test_unauthenticated_delete_returns_401 โœ… passed 0 ms
TestFollowView::test_delete_unknown_user_returns_404 โœ… passed 0 ms
TestFollowerListView::test_unauthenticated_returns_200 โœ… passed 0 ms
TestFollowerListView::test_unknown_user_returns_404 โœ… passed 0 ms
TestFollowerListView::test_inactive_user_returns_404 โœ… passed 0 ms
TestFollowerListView::test_response_is_paginated โœ… passed 0 ms
TestFollowerListView::test_lists_correct_followers โœ… passed 0 ms
TestFollowerListView::test_non_follower_not_in_list โœ… passed 0 ms
TestFollowerListView::test_inactive_follower_excluded_from_list โœ… passed 0 ms
TestFollowerListView::test_result_contains_expected_fields โœ… passed 0 ms
TestFollowingListView::test_unauthenticated_returns_200 โœ… passed 0 ms
TestFollowingListView::test_unknown_user_returns_404 โœ… passed 0 ms
TestFollowingListView::test_inactive_user_returns_404 โœ… passed 0 ms
TestFollowingListView::test_response_is_paginated โœ… passed 0 ms
TestFollowingListView::test_lists_correct_following โœ… passed 0 ms
TestFollowingListView::test_not_following_returns_empty โœ… passed 0 ms
TestFollowingListView::test_inactive_following_excluded_from_list โœ… passed 0 ms
TestFollowingListView::test_result_contains_expected_fields โœ… passed 0 ms
TestPublicProfileFollowCounts::test_profile_includes_count_fields โœ… passed 0 ms
TestPublicProfileFollowCounts::test_counts_are_zero_initially โœ… passed 0 ms
TestPublicProfileFollowCounts::test_followers_count_reflects_state โœ… passed 0 ms
TestPublicProfileFollowCounts::test_following_count_reflects_state โœ… passed 0 ms
TestPublicProfileFollowCounts::test_followers_count_excludes_inactive_follower โœ… passed 0 ms
TestPublicProfileFollowCounts::test_following_count_excludes_inactive_followed โœ… passed 0 ms
TestUserBookmarksView::test_owner_retrieves_bookmarks_returns_200 โœ… passed 0 ms
TestUserBookmarksView::test_response_is_paginated โœ… passed 0 ms
TestUserBookmarksView::test_empty_bookmarks_returns_empty_results โœ… passed 0 ms
TestUserBookmarksView::test_results_ordered_most_recently_saved_first โœ… passed 0 ms
TestUserBookmarksView::test_removed_stories_excluded โœ… passed 0 ms
TestUserBookmarksView::test_response_contains_story_feed_fields โœ… passed 0 ms
TestUserBookmarksView::test_unauthenticated_returns_401 โœ… passed 0 ms
TestUserBookmarksView::test_other_user_returns_403 โœ… passed 0 ms
TestUserBookmarksView::test_user_not_found_returns_404 โœ… passed 0 ms
TestUserBookmarksView::test_inactive_user_returns_404 โœ… passed 0 ms
TestCommentCreateSerializer::test_create_serializer_valid โœ… passed 0 ms
TestCommentCreateSerializer::test_create_serializer_blank_text_fails โœ… passed 0 ms
TestCommentCreateSerializer::test_create_serializer_missing_text_fails โœ… passed 0 ms
TestCommentCreateSerializer::test_create_serializer_whitespace_only_text_fails โœ… passed 0 ms
TestImageUploadSerializer::test_valid_jpeg_passes โœ… passed 0 ms
TestImageUploadSerializer::test_valid_png_passes โœ… passed 0 ms
TestImageUploadSerializer::test_gif_rejected_by_mime_detection โœ… passed 0 ms
TestImageUploadSerializer::test_spoofed_gif_declared_as_jpeg_rejected โœ… passed 0 ms
TestImageUploadSerializer::test_spoofed_bmp_declared_as_jpeg_rejected โœ… passed 0 ms
TestImageUploadSerializer::test_oversized_file_rejected โœ… passed 0 ms
TestImageUploadSerializer::test_exactly_2mb_is_accepted โœ… passed 0 ms
TestImageUploadSerializer::test_error_message_mentions_jpeg_and_png โœ… passed 0 ms
TestMediaFileUploadSerializer::test_valid_mp3_passes โœ… passed 0 ms
TestMediaFileUploadSerializer::test_valid_wav_passes โœ… passed 0 ms
TestMediaFileUploadSerializer::test_valid_mp4_passes โœ… passed 0 ms
TestMediaFileUploadSerializer::test_valid_webm_passes โœ… passed 0 ms
TestMediaFileUploadSerializer::test_image_rejected โœ… passed 0 ms
TestMediaFileUploadSerializer::test_mp3_media_type_is_audio โœ… passed 0 ms
TestMediaFileUploadSerializer::test_mp4_media_type_is_video โœ… passed 0 ms
TestMediaFileUploadSerializer::test_oversized_audio_rejected โœ… passed 0 ms
TestMediaFileUploadSerializer::test_oversized_video_rejected โœ… passed 0 ms
TestMediaFileUploadSerializer::test_error_message_mentions_accepted_formats โœ… passed 0 ms
TestSearchQuerySerializer::test_valid_query_passes โœ… passed 0 ms
TestSearchQuerySerializer::test_missing_q_fails โœ… passed 0 ms
TestSearchQuerySerializer::test_empty_string_fails โœ… passed 0 ms
TestSearchQuerySerializer::test_whitespace_only_fails โœ… passed 0 ms
TestSearchQuerySerializer::test_single_character_passes โœ… passed 0 ms
TestSearchQuerySerializer::test_valid_with_all_filter_params โœ… passed 0 ms
TestSearchQuerySerializer::test_year_from_greater_than_year_to_fails โœ… passed 0 ms
TestSearchQuerySerializer::test_invalid_sort_by_fails โœ… passed 0 ms
TestSearchQuerySerializer::test_defaults_sort_by_to_recent_when_omitted โœ… passed 0 ms
TestSearchQuerySerializer::test_filter_params_are_optional โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_all_three_geo_params_is_valid โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_no_geo_params_is_valid โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_no_geo_params_with_other_filters_is_valid โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_radius_km_accepts_common_values โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_geo_params_combined_with_year_filter_is_valid โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_geo_params_combined_with_tag_filter_is_valid โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_latitude_only_is_invalid โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_longitude_only_is_invalid โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_radius_km_only_is_invalid โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_latitude_and_longitude_without_radius_is_invalid โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_latitude_and_radius_without_longitude_is_invalid โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_longitude_and_radius_without_latitude_is_invalid โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_latitude_above_90_is_invalid โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_latitude_below_minus_90_is_invalid โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_latitude_at_boundary_values_is_valid โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_longitude_above_180_is_invalid โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_longitude_below_minus_180_is_invalid โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_longitude_at_boundary_values_is_valid โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_radius_km_of_zero_is_invalid โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_radius_km_negative_is_invalid โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_geo_and_year_cross_field_validation_coexist โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_search_serializer_inherits_geo_validation โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_search_serializer_accepts_all_three_geo_params โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_radius_km_at_max_is_valid โœ… passed 0 ms
TestFeedQuerySerializerGeoValidation::test_radius_km_above_max_is_invalid โœ… passed 0 ms
TestToEdtf::test_exact_year โœ… passed 0 ms
TestToEdtf::test_approximate_year โœ… passed 0 ms
TestToEdtf::test_decade โœ… passed 0 ms
TestToEdtf::test_decade_formula โœ… passed 0 ms
TestToEdtf::test_year_range โœ… passed 0 ms
TestToEdtf::test_negative_exact_year โœ… passed 0 ms
TestToEdtf::test_negative_approximate_year โœ… passed 0 ms
TestToEdtf::test_negative_decade โœ… passed 0 ms
TestToEdtf::test_unknown_time_type_raises_value_error โœ… passed 0 ms
TestToEdtf::test_none_year_raises_value_error_for_exact_year โœ… passed 0 ms
TestToEdtf::test_exact_date_without_time โœ… passed 0 ms
TestToEdtf::test_exact_date_with_time โœ… passed 0 ms
TestToEdtf::test_exact_date_none_date_value_raises โœ… passed 0 ms
TestToIso8601::test_exact_year โœ… passed 0 ms
TestToIso8601::test_approximate_year_strips_approximation โœ… passed 0 ms
TestToIso8601::test_decade โœ… passed 0 ms
TestToIso8601::test_decade_formula โœ… passed 0 ms
TestToIso8601::test_year_range โœ… passed 0 ms
TestToIso8601::test_negative_exact_year โœ… passed 0 ms
TestToIso8601::test_negative_approximate_year โœ… passed 0 ms
TestToIso8601::test_negative_decade โœ… passed 0 ms
TestToIso8601::test_unknown_time_type_raises_value_error โœ… passed 0 ms
TestToIso8601::test_none_year_raises_value_error_for_exact_year โœ… passed 0 ms
TestToIso8601::test_exact_date_without_time โœ… passed 0 ms
TestToIso8601::test_exact_date_with_time โœ… passed 0 ms
TestToIso8601::test_exact_date_none_date_value_raises โœ… passed 0 ms
TestNormalizeTagName::test_lowercase โœ… passed 0 ms
TestNormalizeTagName::test_spaces_to_hyphens โœ… passed 0 ms
TestNormalizeTagName::test_underscores_to_hyphens โœ… passed 0 ms
TestNormalizeTagName::test_strips_special_characters โœ… passed 0 ms
TestNormalizeTagName::test_collapses_consecutive_hyphens โœ… passed 0 ms
TestNormalizeTagName::test_strips_leading_and_trailing_hyphens โœ… passed 0 ms
TestNormalizeTagName::test_mixed_input โœ… passed 0 ms
TestCanManageOwnProfile::test_owner_can_manage_own_profile โœ… passed 0 ms
TestCanManageOwnProfile::test_admin_can_manage_any_profile โœ… passed 0 ms
TestCanManageOwnProfile::test_registered_user_cannot_manage_other_profile โœ… passed 0 ms
TestCanManageOwnProfile::test_unauthenticated_user_is_denied_at_request_level โœ… passed 0 ms
TestLoginSerializer::test_valid_data_passes โœ… passed 0 ms
TestLoginSerializer::test_missing_email_fails โœ… passed 0 ms
TestLoginSerializer::test_missing_password_fails โœ… passed 0 ms
TestLoginSerializer::test_password_is_write_only โœ… passed 0 ms
TestProfilePhotoSerializer::test_valid_jpeg_passes โœ… passed 0 ms
TestProfilePhotoSerializer::test_valid_png_passes โœ… passed 0 ms
TestProfilePhotoSerializer::test_missing_file_fails โœ… passed 0 ms
TestProfilePhotoSerializer::test_non_image_file_fails โœ… passed 0 ms
TestCustomExceptionHandler::test_validation_error_single_field โœ… passed 0 ms
TestCustomExceptionHandler::test_validation_error_multiple_fields โœ… passed 0 ms
TestCustomExceptionHandler::test_validation_error_multiple_messages_on_one_field โœ… passed 0 ms
TestCustomExceptionHandler::test_auth_error_uses_detail โœ… passed 0 ms
TestCustomExceptionHandler::test_permission_denied_uses_detail โœ… passed 0 ms
TestCustomExceptionHandler::test_non_field_errors_as_list โœ… passed 0 ms
TestCustomExceptionHandler::test_non_drf_exception_returns_none โœ… passed 0 ms
TestHaversineKm::test_same_point_returns_zero โœ… passed 0 ms
TestHaversineKm::test_known_distance_istanbul_to_ankara โœ… passed 0 ms
TestHaversineKm::test_symmetry โœ… passed 0 ms
TestHaversineKm::test_returns_positive_value_for_distinct_points โœ… passed 0 ms
TestHaversineKm::test_one_degree_latitude_is_approximately_111km โœ… passed 0 ms
TestHaversineKm::test_equator_crossing โœ… passed 0 ms
TestBoundingBox::test_returns_bounding_box_namedtuple โœ… passed 0 ms
TestBoundingBox::test_lat_min_less_than_lat_max โœ… passed 0 ms
TestBoundingBox::test_lng_min_less_than_lng_max โœ… passed 0 ms
TestBoundingBox::test_center_point_is_within_box โœ… passed 0 ms
TestBoundingBox::test_larger_radius_produces_larger_box โœ… passed 0 ms
TestBoundingBox::test_near_north_pole_does_not_raise โœ… passed 0 ms
TestBoundingBox::test_near_south_pole_does_not_raise โœ… passed 0 ms
TestBoundingBox::test_lat_clamped_to_90 โœ… passed 0 ms
TestBoundingBox::test_lng_clamped_to_180 โœ… passed 0 ms
TestBoundingBox::test_lng_clamped_to_minus_180 โœ… passed 0 ms
TestBoundingBox::test_points_within_radius_are_inside_box โœ… passed 0 ms
TestIsRegisteredUser::test_registered_user_is_allowed โœ… passed 0 ms
TestIsRegisteredUser::test_admin_is_allowed โœ… passed 0 ms
TestIsRegisteredUser::test_unauthenticated_is_denied โœ… passed 0 ms
TestIsAdminUser::test_admin_is_allowed โœ… passed 0 ms
TestIsAdminUser::test_registered_user_is_denied โœ… passed 0 ms
TestIsAdminUser::test_unauthenticated_is_denied โœ… passed 0 ms
TestIsGuest::test_unauthenticated_is_allowed โœ… passed 0 ms
TestIsGuest::test_authenticated_registered_user_is_denied โœ… passed 0 ms
TestIsGuest::test_authenticated_admin_is_denied โœ… passed 0 ms
TestIsOwnerOrAdmin::test_unauthenticated_is_denied_at_request_level โœ… passed 0 ms
TestIsOwnerOrAdmin::test_owner_can_access_own_object โœ… passed 0 ms
TestIsOwnerOrAdmin::test_admin_can_access_any_object โœ… passed 0 ms
TestIsOwnerOrAdmin::test_non_owner_is_denied โœ… passed 0 ms
TestIsOwnerOrAdmin::test_owner_via_fk_attribute โœ… passed 0 ms
TestIsOwnerOrAdmin::test_non_owner_via_fk_attribute_is_denied โœ… passed 0 ms
TestValidatePasswordStrength::test_valid_password_passes โœ… passed 0 ms
TestValidatePasswordStrength::test_too_short_raises โœ… passed 0 ms
TestValidatePasswordStrength::test_no_digit_raises โœ… passed 0 ms
TestValidatePasswordStrength::test_no_uppercase_raises โœ… passed 0 ms
TestValidatePasswordStrength::test_no_lowercase_raises โœ… passed 0 ms
TestValidatePasswordStrength::test_multiple_violations_returns_all_errors โœ… passed 0 ms
โš ๏ธ **GitHub.com Fallback** โš ๏ธ