-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #256 from ArmaForces/nearest-mission-modlist
Show nearest mission modlist on the modlist list page
- Loading branch information
Showing
8 changed files
with
265 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,17 @@ | ||
<div class="row my-3"> | ||
<div class="col-12"> | ||
<h2> | ||
{% block page_title %}{% endblock %} | ||
</h2> | ||
<h6> | ||
{% block page_subtitle %}{% endblock %} | ||
</h6> | ||
</div> | ||
<div class="col-12 mt-2 text-right"> | ||
{% block page_actions %}{% endblock %} | ||
</div> | ||
{% block page_title_row %} | ||
<div class="col-12"> | ||
<h2> | ||
{% block page_title %}{% endblock %} | ||
</h2> | ||
<h6> | ||
{% block page_subtitle %}{% endblock %} | ||
</h6> | ||
</div> | ||
{% endblock %} | ||
{% block page_actions_row %} | ||
<div class="col-12 mt-2 text-right"> | ||
{% block page_actions %}{% endblock %} | ||
</div> | ||
{% endblock %} | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,75 @@ | ||
{% extends 'card.html.twig' %} | ||
{% extends 'container.html.twig' %} | ||
|
||
{% block content %} | ||
{% embed '_partial/_page_header.html.twig' %} | ||
{% block page_title %} | ||
{{ 'Mod lists'|trans }} | ||
{% endblock %} | ||
{% endembed %} | ||
{% if nextMission %} | ||
<div class="container card bg-dark mt-4"> | ||
{% embed '_partial/_page_header.html.twig' %} | ||
{% block page_title %} | ||
{{ 'Today\'s mission'|trans }}: {{ nextMission.title }} | ||
{% endblock %} | ||
{% block page_subtitle %} | ||
|
||
{% embed '_partial/_table.html.twig' %} | ||
{% import '_macro/common_macro.html.twig' as commonMacro %} | ||
{% import '_macro/table_macro.html.twig' as tableMacro %} | ||
{{ 'Download mod list'|trans }}: | ||
{% if nextMissionModList %} | ||
<a href="{{ path('app_mod_list_public_customize', { name: nextMissionModList.name }) }}"> | ||
{{ nextMissionModList.name }} | ||
<i class="fas fa-download" ></i> | ||
</a> | ||
{% else %} | ||
{{ nextMission.modlist }} | ||
{% endif %} | ||
{% endblock %} | ||
|
||
{% block table_head %} | ||
<tr> | ||
<th scope="col">#</th> | ||
<th scope="col"></th> | ||
<th scope="col" class="w-100">{{ 'Mod list name'|trans }}</th> | ||
<th scope="col">{{ 'Last updated at'|trans }}</th> | ||
<th></th> | ||
</tr> | ||
{% endblock %} | ||
{% block table_body %} | ||
{# @var modList \App\Entity\ModList\ModList #} | ||
{% for modList in modLists %} | ||
<tr data-row-action-url="{{ path('app_mod_list_public_customize', { name: modList.name }) }}"> | ||
<th scope="row">{{ loop.index }}</th> | ||
<td> | ||
{% if modList.approved %} | ||
{{ tableMacro.icon('fas fa-check', 'Mod list approved'|trans) }} | ||
{% endif %} | ||
</td> | ||
<td> | ||
{{ modList.name }} | ||
{% block page_actions_row %}{% endblock %} | ||
{% endembed %} | ||
</div> | ||
{% endif %} | ||
|
||
{# @var dlc \App\Entity\Dlc\Dlc #} | ||
{% for dlc in modList.dlcs %} | ||
{{ commonMacro.dlc_icon(dlc) }} | ||
{% endfor %} | ||
</td> | ||
<td>{{ tableMacro.format_date(modList.lastUpdatedAt) }}</td> | ||
<td class="text-right"> | ||
{{ tableMacro.row_action(path('app_mod_list_public_customize', { name: modList.name }), 'fas fa-download', 'Download mod list'|trans) }} | ||
</td> | ||
<div class="container card bg-dark mt-4"> | ||
{% embed '_partial/_page_header.html.twig' %} | ||
{% block page_title %} | ||
{{ 'Mod lists'|trans }} | ||
{% endblock %} | ||
{% endembed %} | ||
|
||
{% embed '_partial/_table.html.twig' %} | ||
{% import '_macro/common_macro.html.twig' as commonMacro %} | ||
{% import '_macro/table_macro.html.twig' as tableMacro %} | ||
|
||
{% block table_head %} | ||
<tr> | ||
<th scope="col">#</th> | ||
<th scope="col"></th> | ||
<th scope="col" class="w-100">{{ 'Mod list name'|trans }}</th> | ||
<th scope="col">{{ 'Last updated at'|trans }}</th> | ||
<th></th> | ||
</tr> | ||
{% endfor %} | ||
{% endblock %} | ||
{% endembed %} | ||
{% endblock %} | ||
{% block table_body %} | ||
{# @var modList \App\Entity\ModList\ModList #} | ||
{% for modList in modLists %} | ||
<tr data-row-action-url="{{ path('app_mod_list_public_customize', { name: modList.name }) }}"> | ||
<th scope="row">{{ loop.index }}</th> | ||
<td> | ||
{% if modList.approved %} | ||
{{ tableMacro.icon('fas fa-check', 'Mod list approved'|trans) }} | ||
{% endif %} | ||
</td> | ||
<td> | ||
{{ modList.name }} | ||
|
||
{# @var dlc \App\Entity\Dlc\Dlc #} | ||
{% for dlc in modList.dlcs %} | ||
{{ commonMacro.dlc_icon(dlc) }} | ||
{% endfor %} | ||
</td> | ||
<td>{{ tableMacro.format_date(modList.lastUpdatedAt) }}</td> | ||
<td class="text-right"> | ||
{{ tableMacro.row_action(path('app_mod_list_public_customize', { name: modList.name }), 'fas fa-download', 'Download mod list'|trans) }} | ||
</td> | ||
</tr> | ||
{% endfor %} | ||
{% endblock %} | ||
{% endembed %} | ||
</div> | ||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Tests\Unit\Service; | ||
|
||
use App\Service\Mission\Enum\MissionStateEnum; | ||
use App\Service\Mission\MissionClient; | ||
use App\Service\Mission\MissionStore; | ||
use PHPUnit\Framework\TestCase; | ||
use Symfony\Contracts\HttpClient\HttpClientInterface; | ||
use Symfony\Contracts\HttpClient\ResponseInterface; | ||
|
||
/** | ||
* @internal | ||
* @covers \App\Service\Mission\MissionClient | ||
*/ | ||
final class MissionClientTest extends TestCase | ||
{ | ||
/** | ||
* @test | ||
* @dataProvider provideCurrentMissionsData | ||
*/ | ||
public function getCurrentMission(array $missionData, ?string $expectedTitle): void | ||
{ | ||
$mockHttpClient = $this->mockHttpClient($missionData); | ||
$mockStore = $this->getMockBuilder(MissionStore::class) | ||
->disableOriginalConstructor() | ||
->getMock() | ||
; | ||
|
||
$client = new MissionClient($mockHttpClient, $mockStore, 'https://2137.xd'); | ||
|
||
$currentMission = $client->getCurrentMission(); | ||
|
||
if ($expectedTitle) { | ||
static::assertSame($expectedTitle, $currentMission->getTitle()); | ||
} else { | ||
static::assertNull($currentMission); | ||
} | ||
} | ||
|
||
public function provideCurrentMissionsData(): array | ||
{ | ||
$now = new \DateTimeImmutable(); | ||
$dateFormat = 'Y-m-d\TH:i:s'; | ||
|
||
return | ||
[ | ||
'current mission available' => [[ | ||
[ | ||
'id' => 1, | ||
'title' => 'Mission in future 1', | ||
'date' => $now->add(new \DateInterval('P2D'))->format($dateFormat), | ||
'closeDate' => $now->add(new \DateInterval('P1D'))->format($dateFormat), | ||
'description' => '', | ||
'modlistName' => '', | ||
'image' => '', | ||
'freeSlots' => 0, | ||
'allSlots' => 0, | ||
'state' => MissionStateEnum::OPEN, | ||
], | ||
[ | ||
'id' => 2, | ||
'title' => 'Current mission', | ||
'date' => $now->add(new \DateInterval('PT1H'))->format($dateFormat), | ||
'closeDate' => $now->sub(new \DateInterval('P1D'))->format($dateFormat), | ||
'description' => '', | ||
'modlistName' => '', | ||
'image' => '', | ||
'freeSlots' => 0, | ||
'allSlots' => 0, | ||
'state' => MissionStateEnum::OPEN, | ||
], | ||
[ | ||
'id' => 3, | ||
'title' => 'Old mission 1', | ||
'date' => $now->sub(new \DateInterval('P2D'))->format($dateFormat), | ||
'closeDate' => $now->sub(new \DateInterval('P3D'))->format($dateFormat), | ||
'description' => '', | ||
'modlistName' => '', | ||
'image' => '', | ||
'freeSlots' => 0, | ||
'allSlots' => 0, | ||
'state' => MissionStateEnum::ARCHIVED, | ||
], | ||
], 'Current mission'], | ||
'no current mission' => [[ | ||
[ | ||
'id' => 1, | ||
'title' => 'Mission in future 1', | ||
'date' => $now->add(new \DateInterval('P2D'))->format($dateFormat), | ||
'closeDate' => $now->add(new \DateInterval('P1D'))->format($dateFormat), | ||
'description' => '', | ||
'modlistName' => '', | ||
'image' => '', | ||
'freeSlots' => 0, | ||
'allSlots' => 0, | ||
'state' => MissionStateEnum::OPEN, | ||
], | ||
[ | ||
'id' => 2, | ||
'title' => 'Old mission 1', | ||
'date' => $now->sub(new \DateInterval('P2D'))->format($dateFormat), | ||
'closeDate' => $now->sub(new \DateInterval('P3D'))->format($dateFormat), | ||
'description' => '', | ||
'modlistName' => '', | ||
'image' => '', | ||
'freeSlots' => 0, | ||
'allSlots' => 0, | ||
'state' => MissionStateEnum::ARCHIVED, | ||
], | ||
[], // empty element will explode the deserialization process, so this basically makes sure that we're not iterating more than we should ;) | ||
], null], | ||
'empty data' => [[], null], | ||
]; | ||
} | ||
|
||
private function mockHttpClient(array $responsePayload): HttpClientInterface | ||
{ | ||
$response = $this->createMock(ResponseInterface::class); | ||
$response->method('getStatusCode')->willReturn(200); | ||
$response->method('getContent')->willReturn(json_encode($responsePayload, JSON_THROW_ON_ERROR)); | ||
|
||
$httpClient = $this->createMock(HttpClientInterface::class); | ||
$httpClient->method('request')->willReturn($response); | ||
|
||
return $httpClient; | ||
} | ||
} |
Oops, something went wrong.