create([ 'title' => 'Draft', 'body' => 'HIDDEN', 'sort_order' => 1, 'is_published' => false, ]); LoginScreenNews::query()->create([ 'title' => 'Late', 'body' => "SERVERALERT:\n\n|cFF111111Late|r", 'sort_order' => 20, 'is_published' => true, ]); LoginScreenNews::query()->create([ 'title' => 'Early', 'body' => '|cFF222222Early|r', 'sort_order' => 10, 'is_published' => true, ]); $response = $this->get(route('launcher.login-news.show')); $response->assertOk(); $response->assertHeader('Content-Type', 'text/plain; charset=UTF-8'); $response->assertContent( LoginScreenNewsService::FEED_HEADER ."\n\n|cFF222222Early|r\n" .LoginScreenNewsService::SECTION_SEPARATOR ."\n|cFF111111Late|r\n" ); } public function test_public_feed_returns_fallback_message_when_no_news_is_published(): void { LoginScreenNews::query()->create([ 'title' => 'Draft', 'body' => 'HIDDEN', 'sort_order' => 0, 'is_published' => false, ]); $response = $this->get(route('launcher.login-news.show')); $response->assertOk(); $response->assertContent( LoginScreenNewsService::FEED_HEADER ."\n\n" .LoginScreenNewsService::EMPTY_MESSAGE ."\n" ); } public function test_regular_player_cannot_open_admin_news_page(): void { $response = $this->actingAs($this->makeUser(0))->get(route('admin.login-screen-news.index')); $response->assertForbidden(); } public function test_admin_can_open_admin_news_page(): void { LoginScreenNews::query()->create([ 'title' => 'Wrath Update', 'body' => '|cFF00D1FFWrath update|r', 'sort_order' => 0, 'is_published' => true, ]); $response = $this->actingAs($this->makeUser(3))->get(route('admin.login-screen-news.index')); $response->assertOk(); $response->assertSee('Новости логин-экрана WoW'); $response->assertSee('Wrath Update'); $response->assertSee(route('launcher.login-news.show'), false); } public function test_admin_page_always_renders_feed_link_with_http_scheme(): void { $response = $this->withServerVariables([ 'HTTP_X_FORWARDED_PROTO' => 'https', 'HTTP_X_FORWARDED_HOST' => 'moon-well.online', 'HTTP_X_FORWARDED_PORT' => 443, 'HTTP_HOST' => 'moon-well.online', 'REMOTE_ADDR' => '127.0.0.1', ])->actingAs($this->makeUser(3))->get(route('admin.login-screen-news.index')); $response->assertOk(); $response->assertSee('http://moon-well.online/launcher/login-news.txt', false); } public function test_admin_can_create_update_and_delete_news_item(): void { $admin = $this->makeUser(3); $createResponse = $this->from(route('admin.login-screen-news.index')) ->actingAs($admin) ->post(route('admin.login-screen-news.store'), [ 'title' => 'Launch Notice', 'body' => '|cFFFFD700Server launch tonight|r', 'sort_order' => 5, 'is_published' => '1', ]); $createResponse->assertRedirect(route('admin.login-screen-news.index')); $createResponse->assertSessionHas('status', 'Новость для логин-экрана добавлена.'); $this->assertDatabaseHas('login_screen_news', [ 'title' => 'Launch Notice', 'sort_order' => 5, 'is_published' => 1, 'created_by_username' => 'ADMIN', 'updated_by_username' => 'ADMIN', ]); $newsItem = LoginScreenNews::query()->firstOrFail(); $updateResponse = $this->from(route('admin.login-screen-news.index')) ->actingAs($admin) ->patch(route('admin.login-screen-news.update', $newsItem), [ 'title' => 'Launch Notice Updated', 'body' => '|cFFFFD700Server launch moved to Friday|r', 'sort_order' => 8, ]); $updateResponse->assertRedirect(route('admin.login-screen-news.index')); $updateResponse->assertSessionHas('status', 'Новость для логин-экрана обновлена.'); $this->assertDatabaseHas('login_screen_news', [ 'id' => $newsItem->id, 'title' => 'Launch Notice Updated', 'sort_order' => 8, 'is_published' => 0, ]); $deleteResponse = $this->from(route('admin.login-screen-news.index')) ->actingAs($admin) ->delete(route('admin.login-screen-news.destroy', $newsItem)); $deleteResponse->assertRedirect(route('admin.login-screen-news.index')); $deleteResponse->assertSessionHas('status', 'Новость для логин-экрана удалена.'); $this->assertDatabaseMissing('login_screen_news', [ 'id' => $newsItem->id, ]); } private function makeUser(int $gmLevel): GameAccountUser { return new GameAccountUser( id: 1, username: 'ADMIN', email: 'ADMIN@EXAMPLE.COM', regMail: 'ADMIN@EXAMPLE.COM', gmLevel: $gmLevel, locked: false, lastLoginAt: '2026-03-13 18:00:00', joinedAt: '2026-03-12 12:00:00', saltHex: str_repeat('AA', 32), verifierHex: str_repeat('BB', 32), ); } }