From 71d679cc5eab3bb8faba3e0f4c8c936b31b02812 Mon Sep 17 00:00:00 2001 From: w33b Date: Tue, 4 Aug 2026 21:00:01 +0200 Subject: [PATCH] Update tests --- database/schema/mysql-schema.sql | 545 ++++++++++++++++++ phpunit.xml | 7 +- tests/Feature/Auth/AuthenticationTest.php | 54 -- tests/Feature/Auth/EmailVerificationTest.php | 58 -- .../Feature/Auth/PasswordConfirmationTest.php | 44 -- tests/Feature/Auth/PasswordResetTest.php | 73 --- tests/Feature/Auth/PasswordUpdateTest.php | 51 -- tests/Feature/Auth/RegistrationTest.php | 31 - tests/Feature/ContactFormTest.php | 36 ++ tests/Feature/GalleryServiceTest.php | 2 +- tests/Feature/Livewire/LikeButtonTest.php | 60 ++ .../Feature/Livewire/PlaylistOverviewTest.php | 14 +- tests/Feature/PlaylistCreationTest.php | 36 ++ tests/Feature/ProfileTest.php | 99 ---- tests/Feature/PublicPagesTest.php | 46 ++ tests/Feature/StatsPageTest.php | 16 + tests/RefreshDatabase.php | 30 + tests/Support/AltchaPayload.php | 46 ++ 18 files changed, 822 insertions(+), 426 deletions(-) create mode 100644 database/schema/mysql-schema.sql delete mode 100644 tests/Feature/Auth/AuthenticationTest.php delete mode 100644 tests/Feature/Auth/EmailVerificationTest.php delete mode 100644 tests/Feature/Auth/PasswordConfirmationTest.php delete mode 100644 tests/Feature/Auth/PasswordResetTest.php delete mode 100644 tests/Feature/Auth/PasswordUpdateTest.php delete mode 100644 tests/Feature/Auth/RegistrationTest.php create mode 100644 tests/Feature/ContactFormTest.php create mode 100644 tests/Feature/Livewire/LikeButtonTest.php create mode 100644 tests/Feature/PlaylistCreationTest.php delete mode 100644 tests/Feature/ProfileTest.php create mode 100644 tests/Feature/PublicPagesTest.php create mode 100644 tests/Feature/StatsPageTest.php create mode 100644 tests/RefreshDatabase.php create mode 100644 tests/Support/AltchaPayload.php diff --git a/database/schema/mysql-schema.sql b/database/schema/mysql-schema.sql new file mode 100644 index 0000000..b8b7c95 --- /dev/null +++ b/database/schema/mysql-schema.sql @@ -0,0 +1,545 @@ +/*M!999999\- enable the sandbox mode */ +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +DROP TABLE IF EXISTS `alerts`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `alerts` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `type` int(11) NOT NULL, + `text` text NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `comments`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `comments` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `user_id` bigint(20) unsigned NOT NULL, + `commentable_type` varchar(255) NOT NULL, + `commentable_id` varchar(255) NOT NULL, + `body` text NOT NULL, + `parent_id` bigint(20) unsigned DEFAULT NULL, + `deleted_by_moderator_id` bigint(20) DEFAULT NULL, + `deleted_at` timestamp NULL DEFAULT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `comments_commentable_type_commentable_id_index` (`commentable_type`,`commentable_id`), + KEY `comments_user_id_foreign` (`user_id`), + KEY `comments_parent_id_foreign` (`parent_id`), + CONSTRAINT `comments_parent_id_foreign` FOREIGN KEY (`parent_id`) REFERENCES `comments` (`id`) ON DELETE CASCADE, + CONSTRAINT `comments_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `contacts`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `contacts` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `email` varchar(255) NOT NULL, + `subject` varchar(255) NOT NULL, + `message` text NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `downloads`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `downloads` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `episode_id` bigint(20) unsigned NOT NULL, + `type` char(5) NOT NULL, + `url` varchar(255) NOT NULL, + `size` double DEFAULT NULL, + `count` bigint(20) NOT NULL DEFAULT 0, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `downloads_episode_id_type_unique` (`episode_id`,`type`), + KEY `downloads_episode_id_index` (`episode_id`), + CONSTRAINT `downloads_episode_id_foreign` FOREIGN KEY (`episode_id`) REFERENCES `episodes` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `episode_subtitles`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `episode_subtitles` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `episode_id` bigint(20) unsigned NOT NULL, + `subtitle_id` bigint(20) unsigned NOT NULL, + PRIMARY KEY (`id`), + KEY `episode_subtitles_episode_id_index` (`episode_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `episodes`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `episodes` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `title` varchar(255) NOT NULL, + `title_search` varchar(255) NOT NULL, + `title_jpn` varchar(255) NOT NULL, + `slug` varchar(255) NOT NULL, + `hentai_id` int(11) NOT NULL, + `studios_id` int(11) NOT NULL, + `episode` int(11) NOT NULL, + `description` text NOT NULL, + `url` varchar(255) NOT NULL, + `cover_url` varchar(255) NOT NULL, + `view_count` bigint(20) unsigned NOT NULL DEFAULT 0, + `interpolated` tinyint(1) NOT NULL DEFAULT 0, + `interpolated_uhd` tinyint(1) NOT NULL DEFAULT 0, + `dmca_takedown` tinyint(1) NOT NULL DEFAULT 0, + `release_date` date DEFAULT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + `is_dvd_aspect` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`), + KEY `episode_view_count_index` (`view_count`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `failed_jobs`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `failed_jobs` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `uuid` varchar(255) NOT NULL, + `connection` text NOT NULL, + `queue` text NOT NULL, + `payload` longtext NOT NULL, + `exception` longtext NOT NULL, + `failed_at` timestamp NOT NULL DEFAULT current_timestamp(), + PRIMARY KEY (`id`), + UNIQUE KEY `failed_jobs_uuid_unique` (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `gallery`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `gallery` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `hentai_id` int(11) NOT NULL, + `episode_id` int(11) NOT NULL, + `image_url` varchar(255) NOT NULL, + `thumbnail_url` varchar(255) NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `gallery_hentai_id_index` (`hentai_id`), + KEY `gallery_episode_id_index` (`episode_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `hentais`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `hentais` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `slug` varchar(255) NOT NULL, + `description` text NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `jobs`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `jobs` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `queue` varchar(255) NOT NULL, + `payload` longtext NOT NULL, + `attempts` tinyint(3) unsigned NOT NULL, + `reserved_at` int(10) unsigned DEFAULT NULL, + `available_at` int(10) unsigned NOT NULL, + `created_at` int(10) unsigned NOT NULL, + PRIMARY KEY (`id`), + KEY `jobs_queue_index` (`queue`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `markable_likes`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `markable_likes` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `user_id` bigint(20) unsigned NOT NULL, + `markable_type` varchar(255) NOT NULL, + `markable_id` bigint(20) unsigned NOT NULL, + `value` varchar(255) DEFAULT NULL, + `metadata` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`metadata`)), + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `markable_likes_markable_type_markable_id_index` (`markable_type`,`markable_id`), + KEY `markable_likes_user_id_foreign` (`user_id`), + CONSTRAINT `markable_likes_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `migrations`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `migrations` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `migration` varchar(255) NOT NULL, + `batch` int(11) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `mod_logs`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `mod_logs` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `moderator` varchar(255) NOT NULL, + `data` text NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `notifications`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `notifications` ( + `id` char(36) NOT NULL, + `type` varchar(255) NOT NULL, + `notifiable_type` varchar(255) NOT NULL, + `notifiable_id` bigint(20) unsigned NOT NULL, + `data` text NOT NULL, + `read_at` timestamp NULL DEFAULT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `notifications_notifiable_type_notifiable_id_index` (`notifiable_type`,`notifiable_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `passkeys`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `passkeys` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `authenticatable_id` bigint(20) unsigned NOT NULL, + `name` text NOT NULL, + `credential_id` text NOT NULL, + `data` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL CHECK (json_valid(`data`)), + `last_used_at` timestamp NULL DEFAULT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `passkeys_authenticatable_fk` (`authenticatable_id`), + CONSTRAINT `passkeys_authenticatable_fk` FOREIGN KEY (`authenticatable_id`) REFERENCES `users` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `password_reset_tokens`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `password_reset_tokens` ( + `email` varchar(255) NOT NULL, + `token` varchar(255) NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`email`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `playlist_episodes`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `playlist_episodes` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `position` int(11) DEFAULT NULL, + `playlist_id` bigint(20) unsigned NOT NULL, + `episode_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `playlist_episodes_playlist_id_episode_id_unique` (`playlist_id`,`episode_id`), + KEY `playlist_episodes_playlist_id_index` (`playlist_id`), + CONSTRAINT `playlist_episodes_playlist_id_foreign` FOREIGN KEY (`playlist_id`) REFERENCES `playlists` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `playlists`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `playlists` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `user_id` bigint(20) unsigned NOT NULL, + `name` varchar(255) NOT NULL, + `is_private` tinyint(1) NOT NULL DEFAULT 1, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `playlists_user_id_index` (`user_id`), + CONSTRAINT `playlists_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `popular_daily`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `popular_daily` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `episode_id` int(11) NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `popular_monthly`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `popular_monthly` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `episode_id` int(11) NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `popular_weekly`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `popular_weekly` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `episode_id` int(11) NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `site_backgrounds`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `site_backgrounds` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `date_start` date NOT NULL, + `date_end` date NOT NULL, + `default` tinyint(1) NOT NULL DEFAULT 0, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `studios`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `studios` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `name` tinytext NOT NULL, + `slug` tinytext NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `subtitles`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `subtitles` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `name` tinytext NOT NULL, + `slug` tinytext NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `tagging_tag_groups`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `tagging_tag_groups` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `slug` varchar(125) NOT NULL, + `name` varchar(125) NOT NULL, + PRIMARY KEY (`id`), + KEY `tagging_tag_groups_slug_index` (`slug`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `tagging_tagged`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `tagging_tagged` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `taggable_id` int(10) unsigned NOT NULL, + `taggable_type` varchar(125) NOT NULL, + `tag_name` varchar(125) NOT NULL, + `tag_slug` varchar(125) NOT NULL, + PRIMARY KEY (`id`), + KEY `tagging_tagged_taggable_id_index` (`taggable_id`), + KEY `tagging_tagged_taggable_type_index` (`taggable_type`), + KEY `tagging_tagged_tag_slug_index` (`tag_slug`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `tagging_tags`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `tagging_tags` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `slug` varchar(125) NOT NULL, + `name` varchar(125) NOT NULL, + `suggest` tinyint(1) NOT NULL DEFAULT 0, + `count` int(10) unsigned NOT NULL DEFAULT 0, + `tag_group_id` int(10) unsigned DEFAULT NULL, + `description` text DEFAULT NULL, + `locale` varchar(5) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `tagging_tags_slug_index` (`slug`), + KEY `tagging_tags_tag_group_id_foreign` (`tag_group_id`), + CONSTRAINT `tagging_tags_tag_group_id_foreign` FOREIGN KEY (`tag_group_id`) REFERENCES `tagging_tag_groups` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `user_downloads`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `user_downloads` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `user_id` bigint(20) unsigned NOT NULL, + `episode_id` bigint(20) unsigned NOT NULL, + `interpolated` tinyint(1) NOT NULL DEFAULT 0, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `user_downloads_user_id_index` (`user_id`), + KEY `user_downloads_episode_id_index` (`episode_id`), + CONSTRAINT `user_downloads_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `users`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `users` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `discord_id` bigint(20) unsigned DEFAULT NULL, + `matrix_id` varchar(255) DEFAULT NULL, + `name` varchar(255) NOT NULL, + `email` varchar(255) DEFAULT NULL, + `email_verified_at` timestamp NULL DEFAULT NULL, + `password` varchar(255) DEFAULT NULL, + `remember_token` varchar(100) DEFAULT NULL, + `avatar` varchar(255) DEFAULT NULL, + `discord_avatar` varchar(255) DEFAULT NULL, + `locale` varchar(10) DEFAULT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + `roles` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`roles`)), + `search_design` tinyint(1) NOT NULL DEFAULT 1, + `home_top_design` tinyint(1) NOT NULL DEFAULT 0, + `home_middle_design` tinyint(1) NOT NULL DEFAULT 1, + `tag_blacklist` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`tag_blacklist`)), + `downloads_left` tinyint(1) NOT NULL DEFAULT 5, + PRIMARY KEY (`id`), + UNIQUE KEY `users_email_unique` (`email`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `video_engagement`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `video_engagement` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `episode_id` bigint(20) unsigned NOT NULL, + `user_id` bigint(20) unsigned NOT NULL, + `segment` smallint(5) unsigned NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `video_engagement_episode_id_user_id_segment_unique` (`episode_id`,`user_id`,`segment`), + KEY `video_engagement_user_id_foreign` (`user_id`), + CONSTRAINT `video_engagement_episode_id_foreign` FOREIGN KEY (`episode_id`) REFERENCES `episodes` (`id`) ON DELETE CASCADE, + CONSTRAINT `video_engagement_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `watched`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `watched` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `user_id` bigint(20) unsigned NOT NULL, + `episode_id` int(11) NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `watched_user_id_index` (`user_id`), + CONSTRAINT `watched_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +/*M!999999\- enable the sandbox mode */ +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (1,'2014_01_07_073615_create_tagged_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (2,'2014_01_07_073615_create_tags_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (3,'2014_10_12_000000_create_users_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (4,'2014_10_12_100000_create_password_reset_tokens_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (5,'2016_06_29_073615_create_tag_groups_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (6,'2016_06_29_073615_update_tags_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (7,'2018_06_30_113500_create_comments_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (8,'2019_08_19_000000_create_failed_jobs_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (9,'2019_12_14_000001_create_personal_access_tokens_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (10,'2020_03_13_083515_add_description_to_tags_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (11,'2022_07_30_160525_create_contact_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (12,'2023_01_05_142617_update_users_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (13,'2023_04_06_101123_add_roles_to_users_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (14,'2023_05_25_121158_add_remember_token_to_users_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (15,'2023_05_26_165816_create_discord_access_tokens_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (16,'2023_05_27_055058_remove_refresh_token_from_users_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (17,'2023_06_11_062809_update_users_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (18,'2023_08_10_145324_create_likes_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (19,'2023_08_10_145325_add_hstream_base_tables',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (20,'2023_08_10_145326_import_old_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (21,'2023_08_10_190926_update_hstream_tables',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (22,'2023_08_12_130605_add_user_settings',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (23,'2023_08_13_200327_create_playlist_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (24,'2023_08_15_170207_create_alerts_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (25,'2023_10_03_150330_add_patreon_to_users_table',2); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (26,'2023_10_03_152048_add_4k_downloads_to_episode_table',2); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (27,'2023_10_03_230727_migrate_4k_downloads',3); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (28,'2023_11_30_150101_create_jobs_table',4); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (29,'2023_12_19_200302_created_watched_table',5); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (30,'2024_01_07_184928_add_blacklist_to_users_table',6); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (31,'2024_02_06_110910_add_interpolated_to_episode_table',7); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (32,'2024_02_18_110521_optimization',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (33,'2024_02_29_110046_create_torrents_table',9); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (34,'2024_03_05_205036_create_subtitles_table',10); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (35,'2024_03_05_211627_create_episode_subtitles_table',10); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (36,'2024_04_05_123805_add_description_to_episode_table',11); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (37,'2024_04_05_145706_rename_tables',11); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (38,'2024_05_10_135107_add_interpolated_download_to_episodes_table',12); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (39,'2024_06_25_141635_add_banned_to_users_table',13); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (40,'2024_07_15_143013_drop_legacy_stream_from_episodes_table',14); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (41,'2024_07_15_145809_drop_resolution_from_episodes_table',14); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (42,'2024_07_18_102838_add_aspect_ratio_to_episodes_table',14); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (43,'2024_07_29_134619_create_downloads_table',15); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (44,'2024_07_30_135107_add_count_to_downloads_table',15); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (45,'2024_07_30_194424_fix_slugs',15); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (46,'2024_10_13_131743_add_download_count_to_users_table',16); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (47,'2024_10_21_194317_add_title_search_to_epiosdes_table',17); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (48,'2024_10_27_102415_create_user_downloads_table',17); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (49,'2024_11_17_153334_create_site_backgrounds_table',18); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (50,'2024_11_25_163029_create_notifications_table',19); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (51,'2024_12_13_200252_add_interpolated_qhd_to_episodes_table',20); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (52,'2025_01_04_222655_add_interpolated_uhd_to_episodes_table',21); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (53,'2025_04_25_143357_fix_playlist_episode_positions',22); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (54,'2025_05_30_203455_fix_discord_oauth',22); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (55,'2025_09_21_215923_add_unique_constraint_to_downloads_table',23); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (56,'2025_09_22_113103_drop_torrents_table',23); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (57,'2025_12_19_205600_add_dmca_to_episodes_table',24); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (58,'2026_01_06_161620_fix_discord_oauth_system',25); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (59,'2026_01_08_213625_fix_database_structure',25); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (60,'2026_01_10_120521_migrate_comments_table',26); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (61,'2023_04_22_143828_add_locale_to_tagging_tags_table',27); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (62,'2026_01_11_151205_add_locale_to_users_table',27); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (63,'2026_01_11_184725_migrate_to_user_roles',27); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (64,'2026_02_17_222326_add_matrix_id_to_users_table',28); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (65,'2026_04_21_131052_create_passkeys_table',29); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (66,'2026_05_04_135331_add_subscription_key_to_users_table',30); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (67,'2026_05_06_144901_add_deleted_by_moderator_to_comments_table',31); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (68,'2026_05_06_181115_create_mod_logs_table',31); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (73,'2026_07_18_115452_drop_subscription_key_from_users_table',32); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (74,'2026_07_19_141500_create_video_engagement_table',32); diff --git a/phpunit.xml b/phpunit.xml index 7fb08b5..2c6bb6c 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -19,12 +19,15 @@ - + - + + + + diff --git a/tests/Feature/Auth/AuthenticationTest.php b/tests/Feature/Auth/AuthenticationTest.php deleted file mode 100644 index 13dcb7c..0000000 --- a/tests/Feature/Auth/AuthenticationTest.php +++ /dev/null @@ -1,54 +0,0 @@ -get('/login'); - - $response->assertStatus(200); - } - - public function test_users_can_authenticate_using_the_login_screen(): void - { - $user = User::factory()->create(); - - $response = $this->post('/login', [ - 'email' => $user->email, - 'password' => 'password', - ]); - - $this->assertAuthenticated(); - $response->assertRedirect(route('dashboard', absolute: false)); - } - - public function test_users_can_not_authenticate_with_invalid_password(): void - { - $user = User::factory()->create(); - - $this->post('/login', [ - 'email' => $user->email, - 'password' => 'wrong-password', - ]); - - $this->assertGuest(); - } - - public function test_users_can_logout(): void - { - $user = User::factory()->create(); - - $response = $this->actingAs($user)->post('/logout'); - - $this->assertGuest(); - $response->assertRedirect('/'); - } -} diff --git a/tests/Feature/Auth/EmailVerificationTest.php b/tests/Feature/Auth/EmailVerificationTest.php deleted file mode 100644 index 705570b..0000000 --- a/tests/Feature/Auth/EmailVerificationTest.php +++ /dev/null @@ -1,58 +0,0 @@ -unverified()->create(); - - $response = $this->actingAs($user)->get('/verify-email'); - - $response->assertStatus(200); - } - - public function test_email_can_be_verified(): void - { - $user = User::factory()->unverified()->create(); - - Event::fake(); - - $verificationUrl = URL::temporarySignedRoute( - 'verification.verify', - now()->addMinutes(60), - ['id' => $user->id, 'hash' => sha1($user->email)] - ); - - $response = $this->actingAs($user)->get($verificationUrl); - - Event::assertDispatched(Verified::class); - $this->assertTrue($user->fresh()->hasVerifiedEmail()); - $response->assertRedirect(route('dashboard', absolute: false).'?verified=1'); - } - - public function test_email_is_not_verified_with_invalid_hash(): void - { - $user = User::factory()->unverified()->create(); - - $verificationUrl = URL::temporarySignedRoute( - 'verification.verify', - now()->addMinutes(60), - ['id' => $user->id, 'hash' => sha1('wrong-email')] - ); - - $this->actingAs($user)->get($verificationUrl); - - $this->assertFalse($user->fresh()->hasVerifiedEmail()); - } -} diff --git a/tests/Feature/Auth/PasswordConfirmationTest.php b/tests/Feature/Auth/PasswordConfirmationTest.php deleted file mode 100644 index ff85721..0000000 --- a/tests/Feature/Auth/PasswordConfirmationTest.php +++ /dev/null @@ -1,44 +0,0 @@ -create(); - - $response = $this->actingAs($user)->get('/confirm-password'); - - $response->assertStatus(200); - } - - public function test_password_can_be_confirmed(): void - { - $user = User::factory()->create(); - - $response = $this->actingAs($user)->post('/confirm-password', [ - 'password' => 'password', - ]); - - $response->assertRedirect(); - $response->assertSessionHasNoErrors(); - } - - public function test_password_is_not_confirmed_with_invalid_password(): void - { - $user = User::factory()->create(); - - $response = $this->actingAs($user)->post('/confirm-password', [ - 'password' => 'wrong-password', - ]); - - $response->assertSessionHasErrors(); - } -} diff --git a/tests/Feature/Auth/PasswordResetTest.php b/tests/Feature/Auth/PasswordResetTest.php deleted file mode 100644 index aa50350..0000000 --- a/tests/Feature/Auth/PasswordResetTest.php +++ /dev/null @@ -1,73 +0,0 @@ -get('/forgot-password'); - - $response->assertStatus(200); - } - - public function test_reset_password_link_can_be_requested(): void - { - Notification::fake(); - - $user = User::factory()->create(); - - $this->post('/forgot-password', ['email' => $user->email]); - - Notification::assertSentTo($user, ResetPassword::class); - } - - public function test_reset_password_screen_can_be_rendered(): void - { - Notification::fake(); - - $user = User::factory()->create(); - - $this->post('/forgot-password', ['email' => $user->email]); - - Notification::assertSentTo($user, ResetPassword::class, function ($notification) { - $response = $this->get('/reset-password/'.$notification->token); - - $response->assertStatus(200); - - return true; - }); - } - - public function test_password_can_be_reset_with_valid_token(): void - { - Notification::fake(); - - $user = User::factory()->create(); - - $this->post('/forgot-password', ['email' => $user->email]); - - Notification::assertSentTo($user, ResetPassword::class, function ($notification) use ($user) { - $response = $this->post('/reset-password', [ - 'token' => $notification->token, - 'email' => $user->email, - 'password' => 'password', - 'password_confirmation' => 'password', - ]); - - $response - ->assertSessionHasNoErrors() - ->assertRedirect(route('login')); - - return true; - }); - } -} diff --git a/tests/Feature/Auth/PasswordUpdateTest.php b/tests/Feature/Auth/PasswordUpdateTest.php deleted file mode 100644 index ca28c6c..0000000 --- a/tests/Feature/Auth/PasswordUpdateTest.php +++ /dev/null @@ -1,51 +0,0 @@ -create(); - - $response = $this - ->actingAs($user) - ->from('/profile') - ->put('/password', [ - 'current_password' => 'password', - 'password' => 'new-password', - 'password_confirmation' => 'new-password', - ]); - - $response - ->assertSessionHasNoErrors() - ->assertRedirect('/profile'); - - $this->assertTrue(Hash::check('new-password', $user->refresh()->password)); - } - - public function test_correct_password_must_be_provided_to_update_password(): void - { - $user = User::factory()->create(); - - $response = $this - ->actingAs($user) - ->from('/profile') - ->put('/password', [ - 'current_password' => 'wrong-password', - 'password' => 'new-password', - 'password_confirmation' => 'new-password', - ]); - - $response - ->assertSessionHasErrorsIn('updatePassword', 'current_password') - ->assertRedirect('/profile'); - } -} diff --git a/tests/Feature/Auth/RegistrationTest.php b/tests/Feature/Auth/RegistrationTest.php deleted file mode 100644 index 1489d0e..0000000 --- a/tests/Feature/Auth/RegistrationTest.php +++ /dev/null @@ -1,31 +0,0 @@ -get('/register'); - - $response->assertStatus(200); - } - - public function test_new_users_can_register(): void - { - $response = $this->post('/register', [ - 'name' => 'Test User', - 'email' => 'test@example.com', - 'password' => 'password', - 'password_confirmation' => 'password', - ]); - - $this->assertAuthenticated(); - $response->assertRedirect(route('dashboard', absolute: false)); - } -} diff --git a/tests/Feature/ContactFormTest.php b/tests/Feature/ContactFormTest.php new file mode 100644 index 0000000..3394894 --- /dev/null +++ b/tests/Feature/ContactFormTest.php @@ -0,0 +1,36 @@ +post('/contact', []) + ->assertSessionHasErrors(['name', 'email', 'message', 'subject', 'altcha']); + } + + public function test_valid_contact_submission_creates_row(): void + { + $this->post('/contact', [ + 'name' => 'Jane Doe', + 'email' => 'jane@example.com', + 'subject' => 'Bug report', + 'message' => 'The search page looks broken on mobile.', + 'altcha' => AltchaPayload::valid(), + ])->assertRedirect(); + + $this->assertDatabaseHas('contacts', [ + 'name' => 'Jane Doe', + 'email' => 'jane@example.com', + 'subject' => 'Bug report', + 'message' => 'The search page looks broken on mobile.', + ]); + } +} diff --git a/tests/Feature/GalleryServiceTest.php b/tests/Feature/GalleryServiceTest.php index c88abcd..fe977ce 100644 --- a/tests/Feature/GalleryServiceTest.php +++ b/tests/Feature/GalleryServiceTest.php @@ -7,10 +7,10 @@ use App\Models\Gallery; use App\Models\Hentai; use App\Models\Studios; use App\Services\GalleryService; -use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Http\Request; use Illuminate\Http\UploadedFile; use Illuminate\Support\Facades\Storage; +use Tests\RefreshDatabase; use Tests\TestCase; class GalleryServiceTest extends TestCase diff --git a/tests/Feature/Livewire/LikeButtonTest.php b/tests/Feature/Livewire/LikeButtonTest.php new file mode 100644 index 0000000..bae6480 --- /dev/null +++ b/tests/Feature/Livewire/LikeButtonTest.php @@ -0,0 +1,60 @@ +create(); + $studio = Studios::factory()->create(); + + return Episode::factory()->create([ + 'hentai_id' => $hentai->id, + 'studios_id' => $studio->id, + ]); + } + + public function test_guest_like_is_a_noop(): void + { + $episode = $this->makeEpisode(); + + Livewire::test(LikeButton::class, ['episode' => $episode]) + ->call('like'); + + $this->assertDatabaseCount('markable_likes', 0); + } + + public function test_user_can_toggle_like(): void + { + $episode = $this->makeEpisode(); + $user = User::factory()->create(); + $this->actingAs($user); + + Livewire::test(LikeButton::class, ['episode' => $episode]) + ->call('like') + ->assertSet('liked', true) + ->assertSet('likeCount', 1); + + $this->assertTrue(Like::has($episode, $user)); + + Livewire::test(LikeButton::class, ['episode' => $episode->fresh()]) + ->call('like') + ->assertSet('liked', false) + ->assertSet('likeCount', 0); + + $this->assertFalse(Like::has($episode, $user)); + } +} diff --git a/tests/Feature/Livewire/PlaylistOverviewTest.php b/tests/Feature/Livewire/PlaylistOverviewTest.php index 5a43422..17537ea 100644 --- a/tests/Feature/Livewire/PlaylistOverviewTest.php +++ b/tests/Feature/Livewire/PlaylistOverviewTest.php @@ -10,26 +10,14 @@ use App\Models\Playlist; use App\Models\PlaylistEpisode; use App\Models\Studios; use App\Models\User; -use Illuminate\Foundation\Testing\RefreshDatabase; -use Illuminate\Foundation\Testing\RefreshDatabaseState; use Livewire\Livewire; +use Tests\RefreshDatabase; use Tests\TestCase; class PlaylistOverviewTest extends TestCase { use RefreshDatabase; - /** - * The repo's post-launch data-fix migrations (e.g. 2026_01_08_213625) - * assume a populated production schema and fail on a fresh database, so - * the "testing" database is provisioned from a production schema dump - * instead of running migrate:fresh. - */ - protected function migrateDatabases(): void - { - RefreshDatabaseState::$migrated = true; - } - private function makePlaylist(int $episodeCount = 1): array { $user = User::factory()->create(); diff --git a/tests/Feature/PlaylistCreationTest.php b/tests/Feature/PlaylistCreationTest.php new file mode 100644 index 0000000..c25d3c5 --- /dev/null +++ b/tests/Feature/PlaylistCreationTest.php @@ -0,0 +1,36 @@ +create(); + + $this->actingAs($user) + ->post('/create-playlist', ['name' => 'My List', 'visiblity' => 'private']) + ->assertRedirect(route('profile.playlists')); + + $this->assertDatabaseHas('playlists', [ + 'user_id' => $user->id, + 'name' => 'My List', + 'is_private' => true, + ]); + } + + public function test_playlist_requires_a_name(): void + { + $user = User::factory()->create(); + + $this->actingAs($user) + ->post('/create-playlist', []) + ->assertSessionHasErrors('name'); + } +} diff --git a/tests/Feature/ProfileTest.php b/tests/Feature/ProfileTest.php deleted file mode 100644 index 252fdcc..0000000 --- a/tests/Feature/ProfileTest.php +++ /dev/null @@ -1,99 +0,0 @@ -create(); - - $response = $this - ->actingAs($user) - ->get('/profile'); - - $response->assertOk(); - } - - public function test_profile_information_can_be_updated(): void - { - $user = User::factory()->create(); - - $response = $this - ->actingAs($user) - ->patch('/profile', [ - 'name' => 'Test User', - 'email' => 'test@example.com', - ]); - - $response - ->assertSessionHasNoErrors() - ->assertRedirect('/profile'); - - $user->refresh(); - - $this->assertSame('Test User', $user->name); - $this->assertSame('test@example.com', $user->email); - $this->assertNull($user->email_verified_at); - } - - public function test_email_verification_status_is_unchanged_when_the_email_address_is_unchanged(): void - { - $user = User::factory()->create(); - - $response = $this - ->actingAs($user) - ->patch('/profile', [ - 'name' => 'Test User', - 'email' => $user->email, - ]); - - $response - ->assertSessionHasNoErrors() - ->assertRedirect('/profile'); - - $this->assertNotNull($user->refresh()->email_verified_at); - } - - public function test_user_can_delete_their_account(): void - { - $user = User::factory()->create(); - - $response = $this - ->actingAs($user) - ->delete('/profile', [ - 'password' => 'password', - ]); - - $response - ->assertSessionHasNoErrors() - ->assertRedirect('/'); - - $this->assertGuest(); - $this->assertNull($user->fresh()); - } - - public function test_correct_password_must_be_provided_to_delete_account(): void - { - $user = User::factory()->create(); - - $response = $this - ->actingAs($user) - ->from('/profile') - ->delete('/profile', [ - 'password' => 'wrong-password', - ]); - - $response - ->assertSessionHasErrorsIn('userDeletion', 'password') - ->assertRedirect('/profile'); - - $this->assertNotNull($user->fresh()); - } -} diff --git a/tests/Feature/PublicPagesTest.php b/tests/Feature/PublicPagesTest.php new file mode 100644 index 0000000..0f1caef --- /dev/null +++ b/tests/Feature/PublicPagesTest.php @@ -0,0 +1,46 @@ +get('/login')->assertOk(); + } + + public function test_search_page_renders(): void + { + $this->get('/search')->assertOk(); + } + + public function test_contact_page_renders(): void + { + $this->get('/contact')->assertOk(); + } + + public function test_guest_is_redirected_to_login(): void + { + $this->get('/user/profile')->assertRedirect(route('login')); + } + + public function test_random_redirects_when_episode_exists(): void + { + $hentai = Hentai::factory()->create(); + $studio = Studios::factory()->create(); + $episode = Episode::factory()->create([ + 'hentai_id' => $hentai->id, + 'studios_id' => $studio->id, + ]); + + $this->get('/random')->assertRedirect(route('hentai.index', $episode->slug)); + } +} diff --git a/tests/Feature/StatsPageTest.php b/tests/Feature/StatsPageTest.php new file mode 100644 index 0000000..cde668d --- /dev/null +++ b/tests/Feature/StatsPageTest.php @@ -0,0 +1,16 @@ +get('/stats')->assertOk(); + } +} diff --git a/tests/RefreshDatabase.php b/tests/RefreshDatabase.php new file mode 100644 index 0000000..6c5e662 --- /dev/null +++ b/tests/RefreshDatabase.php @@ -0,0 +1,30 @@ +createChallenge(new CreateChallengeOptions( + algorithm: $pbkdf2, + cost: 5000, + counter: $counter, + expiresAt: time() + 600, + )); + + $solution = $altcha->solveChallenge(new SolveChallengeOptions( + challenge: $challenge, + algorithm: $pbkdf2, + start: $counter, + step: 1, + timeout: 5, + )); + + return base64_encode(json_encode([ + 'challenge' => $challenge->toArray(), + 'solution' => $solution->toArray(), + ])); + } +}