Weekly reporting view (#1892)

This commit is contained in:
Kevin Papst
2020-08-16 12:20:33 +02:00
committed by GitHub
parent 2449a1e8bf
commit 2d4cfbe821
39 changed files with 1130 additions and 248 deletions

View File

@@ -10,6 +10,7 @@
namespace App\Tests\Controller;
use App\Entity\User;
use App\Tests\DataFixtures\TimesheetFixtures;
/**
* @group integration
@@ -21,6 +22,16 @@ class ReportingControllerTest extends ControllerBaseTest
$this->assertUrlIsSecured('/reporting');
}
public function testWeekByUserIsSecure()
{
$this->assertUrlIsSecured('/reporting/week_by_user');
}
public function testMonthByUserIsSecure()
{
$this->assertUrlIsSecured('/reporting/month_by_user');
}
public function testMonthlyListIsSecure()
{
$this->assertUrlIsSecured('/reporting/monthly_users_list');
@@ -31,17 +42,53 @@ class ReportingControllerTest extends ControllerBaseTest
$this->assertUrlIsSecuredForRole(User::ROLE_USER, '/reporting/monthly_users_list');
}
public function testDefaultUsersMonthReport()
protected function importReportingFixture(string $role)
{
$fixture = new TimesheetFixtures();
$fixture->setAmount(50);
$fixture->setAmountRunning(10);
$fixture->setUser($this->getUserByRole($role));
$fixture->setStartDate(new \DateTime());
$this->importFixture($fixture);
}
public function testRedirectForDefaultReportUrl()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
$this->assertAccessIsGranted($client, '/reporting/');
$this->importReportingFixture(User::ROLE_USER);
$this->request($client, '/reporting/');
$this->assertIsRedirect($client, $this->createUrl('/reporting/week_by_user'));
$client->followRedirect();
self::assertStringContainsString('<div class="box-body user-week-reporting-box', $client->getResponse()->getContent());
}
public function testUserWeekReport()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_SUPER_ADMIN);
$this->importReportingFixture(User::ROLE_SUPER_ADMIN);
$this->assertAccessIsGranted($client, '/reporting/week_by_user?user=4&date=12999119191');
self::assertStringContainsString('<div class="box-body user-week-reporting-box', $client->getResponse()->getContent());
$option = $client->getCrawler()->filterXPath("//select[@id='user']/option[@selected]");
self::assertEquals(4, $option->attr('value'));
}
public function testUserMonthReport()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
$this->importReportingFixture(User::ROLE_USER);
$this->assertAccessIsGranted($client, '/reporting/month_by_user?user=4&date=12999119191');
self::assertStringContainsString('<div class="box-body user-month-reporting-box', $client->getResponse()->getContent());
$select = $client->getCrawler()->filterXPath("//select[@id='user']");
self::assertEquals(0, $select->count());
}
public function testMonthlyUsersReport()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_TEAMLEAD);
$this->importReportingFixture(User::ROLE_TEAMLEAD);
$this->assertAccessIsGranted($client, '/reporting/monthly_users_list');
self::assertStringContainsString('<div class="box-body monthly-user-list-reporting-box', $client->getResponse()->getContent());
$select = $client->getCrawler()->filterXPath("//select[@id='user']");
self::assertEquals(0, $select->count());
}
}

View File

@@ -9,6 +9,7 @@
namespace App\Tests\Entity;
use App\Constants;
use App\Entity\Activity;
use App\Entity\ActivityMeta;
use App\Entity\Project;
@@ -58,6 +59,9 @@ class ActivityTest extends TestCase
$this->assertInstanceOf(Activity::class, $sut->setColor('#fffccc'));
$this->assertEquals('#fffccc', $sut->getColor());
$this->assertInstanceOf(Activity::class, $sut->setColor(Constants::DEFAULT_COLOR));
$this->assertNull($sut->getColor());
$this->assertInstanceOf(Activity::class, $sut->setBudget(12345.67));
$this->assertEquals(12345.67, $sut->getBudget());

View File

@@ -9,6 +9,7 @@
namespace App\Tests\Entity;
use App\Constants;
use App\Entity\Customer;
use App\Entity\CustomerMeta;
use App\Entity\Team;
@@ -72,6 +73,9 @@ class CustomerTest extends TestCase
self::assertInstanceOf(Customer::class, $sut->setColor('#fffccc'));
self::assertEquals('#fffccc', $sut->getColor());
self::assertInstanceOf(Customer::class, $sut->setColor(Constants::DEFAULT_COLOR));
self::assertNull($sut->getColor());
self::assertInstanceOf(Customer::class, $sut->setCompany('test company'));
self::assertEquals('test company', $sut->getCompany());

View File

@@ -9,6 +9,7 @@
namespace App\Tests\Entity;
use App\Constants;
use App\Entity\Customer;
use App\Entity\Project;
use App\Entity\ProjectMeta;
@@ -82,6 +83,9 @@ class ProjectTest extends TestCase
self::assertInstanceOf(Project::class, $sut->setColor('#fffccc'));
self::assertEquals('#fffccc', $sut->getColor());
self::assertInstanceOf(Project::class, $sut->setColor(Constants::DEFAULT_COLOR));
self::assertNull($sut->getColor());
self::assertInstanceOf(Project::class, $sut->setVisible(false));
self::assertFalse($sut->isVisible());

View File

@@ -0,0 +1,43 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Tests\Reporting;
use App\Entity\User;
use App\Reporting\DateByUser;
use PHPUnit\Framework\TestCase;
/**
* @covers \App\Reporting\DateByUser
*/
abstract class AbstractDateByUserTest extends TestCase
{
abstract protected function createSut(): DateByUser;
public function testEmptyObject()
{
$sut = $this->createSut();
self::assertNull($sut->getDate());
self::assertNull($sut->getUser());
}
public function testSetter()
{
$date = new \DateTime('2019-05-27');
$user = new User();
$user->setAlias('sdfsdfdsdf');
$sut = $this->createSut();
self::assertInstanceOf(DateByUser::class, $sut->setDate($date));
self::assertInstanceOf(DateByUser::class, $sut->setUser($user));
self::assertSame($date, $sut->getDate());
self::assertSame($user, $sut->getUser());
}
}

View File

@@ -0,0 +1,25 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Tests\Reporting;
use App\Reporting\DateByUser;
use App\Reporting\MonthByUser;
/**
* @covers \App\Reporting\MonthByUser
* @covers \App\Reporting\DateByUser
*/
class MonthByUserTest extends AbstractDateByUserTest
{
protected function createSut(): DateByUser
{
return new MonthByUser();
}
}

View File

@@ -0,0 +1,25 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Tests\Reporting;
use App\Reporting\DateByUser;
use App\Reporting\WeekByUser;
/**
* @covers \App\Reporting\WeekByUser
* @covers \App\Reporting\DateByUser
*/
class WeekByUserTest extends AbstractDateByUserTest
{
protected function createSut(): DateByUser
{
return new WeekByUser();
}
}

View File

@@ -0,0 +1,158 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Tests\Timesheet;
use App\Timesheet\DateTimeFactory;
use DateTime;
use DateTimeZone;
use PHPUnit\Framework\TestCase;
/**
* @covers \App\Timesheet\DateTimeFactory
*/
class DateTimeFactoryTest extends TestCase
{
public const TEST_TIMEZONE = 'Europe/London';
protected function createDateTimeFactory(?string $timezone = null): DateTimeFactory
{
if (null === $timezone) {
return new DateTimeFactory();
}
return new DateTimeFactory(new DateTimeZone($timezone));
}
public function testGetTimezone()
{
$sut = $this->createDateTimeFactory(self::TEST_TIMEZONE);
$this->assertEquals(self::TEST_TIMEZONE, $sut->getTimezone()->getName());
}
public function testGetTimezoneWithFallbackTimezone()
{
$sut = $this->createDateTimeFactory();
$this->assertEquals(date_default_timezone_get(), $sut->getTimezone()->getName());
}
public function testGetStartOfMonth()
{
$expected = new DateTime('now', new DateTimeZone(self::TEST_TIMEZONE));
$sut = $this->createDateTimeFactory(self::TEST_TIMEZONE);
$dateTime = $sut->getStartOfMonth();
$this->assertEquals(0, $dateTime->format('H'));
$this->assertEquals(0, $dateTime->format('i'));
$this->assertEquals(0, $dateTime->format('s'));
$this->assertEquals(1, $dateTime->format('d'));
$this->assertEquals($expected->format('m'), $dateTime->format('m'));
$this->assertEquals($expected->format('Y'), $dateTime->format('Y'));
$this->assertEquals(self::TEST_TIMEZONE, $dateTime->getTimezone()->getName());
}
public function testGetEndOfMonth()
{
$expected = new DateTime('last day of this month', new DateTimeZone(self::TEST_TIMEZONE));
$sut = $this->createDateTimeFactory(self::TEST_TIMEZONE);
$dateTime = $sut->getEndOfMonth();
$this->assertEquals(23, $dateTime->format('H'));
$this->assertEquals(59, $dateTime->format('i'));
$this->assertEquals(59, $dateTime->format('s'));
$this->assertEquals($expected->format('d'), $dateTime->format('d'));
$this->assertEquals($expected->format('m'), $dateTime->format('m'));
$this->assertEquals($expected->format('Y'), $dateTime->format('Y'));
$this->assertEquals(self::TEST_TIMEZONE, $dateTime->getTimezone()->getName());
}
public function testGetStartOfWeek()
{
$expected = new DateTime('2018-07-26 16:47:31', new DateTimeZone(self::TEST_TIMEZONE));
$sut = $this->createDateTimeFactory(self::TEST_TIMEZONE);
$dateTime = $sut->getStartOfWeek($expected);
$this->assertEquals(0, $dateTime->format('H'));
$this->assertEquals(0, $dateTime->format('i'));
$this->assertEquals(0, $dateTime->format('s'));
$this->assertEquals(23, $dateTime->format('d'));
$this->assertEquals(1, $dateTime->format('N'));
$this->assertEquals('Monday', $dateTime->format('l'));
$this->assertEquals($expected->format('m'), $dateTime->format('m'));
$this->assertEquals($expected->format('Y'), $dateTime->format('Y'));
$this->assertEquals(self::TEST_TIMEZONE, $dateTime->getTimezone()->getName());
$expected = new DateTime('now', new DateTimeZone(self::TEST_TIMEZONE));
$dateTime = $sut->getStartOfWeek();
$this->assertEquals(0, $dateTime->format('H'));
$this->assertEquals(0, $dateTime->format('i'));
$this->assertEquals(0, $dateTime->format('s'));
$this->assertEquals(1, $dateTime->format('N'));
$this->assertEquals('Monday', $dateTime->format('l'));
$this->assertEquals($expected->format('m'), $dateTime->format('m'));
$this->assertEquals($expected->format('Y'), $dateTime->format('Y'));
$this->assertEquals(self::TEST_TIMEZONE, $dateTime->getTimezone()->getName());
}
public function testGetEndOfWeek()
{
$expected = new DateTime('2018-07-26 16:47:31', new DateTimeZone(self::TEST_TIMEZONE));
$sut = $this->createDateTimeFactory(self::TEST_TIMEZONE);
$dateTime = $sut->getEndOfWeek($expected);
$this->assertEquals(23, $dateTime->format('H'));
$this->assertEquals(59, $dateTime->format('i'));
$this->assertEquals(59, $dateTime->format('s'));
$this->assertEquals(29, $dateTime->format('d'));
$this->assertEquals(7, $dateTime->format('N'));
$this->assertEquals('Sunday', $dateTime->format('l'));
$this->assertEquals($expected->format('m'), $dateTime->format('m'));
$this->assertEquals($expected->format('Y'), $dateTime->format('Y'));
$this->assertEquals(self::TEST_TIMEZONE, $dateTime->getTimezone()->getName());
$expected = new DateTime('now', new DateTimeZone(self::TEST_TIMEZONE));
$dateTime = $sut->getEndOfWeek();
$this->assertEquals(23, $dateTime->format('H'));
$this->assertEquals(59, $dateTime->format('i'));
$this->assertEquals(59, $dateTime->format('s'));
$this->assertEquals(7, $dateTime->format('N'));
$this->assertEquals('Sunday', $dateTime->format('l'));
$this->assertEquals($expected->format('m'), $dateTime->format('m'));
$this->assertEquals($expected->format('Y'), $dateTime->format('Y'));
$this->assertEquals(self::TEST_TIMEZONE, $dateTime->getTimezone()->getName());
}
public function testCreateDateTime()
{
$sut = $this->createDateTimeFactory(self::TEST_TIMEZONE);
$dateTime = $sut->createDateTime('2015-07-24 13:45:21');
$this->assertEquals(13, $dateTime->format('H'));
$this->assertEquals(45, $dateTime->format('i'));
$this->assertEquals(21, $dateTime->format('s'));
$this->assertEquals('24', $dateTime->format('d'));
$this->assertEquals('07', $dateTime->format('m'));
$this->assertEquals('2015', $dateTime->format('Y'));
$this->assertEquals(self::TEST_TIMEZONE, $dateTime->getTimezone()->getName());
}
public function testCreateDateTimeWithDefaultValue()
{
$expected = new DateTime('now', new DateTimeZone(self::TEST_TIMEZONE));
$sut = $this->createDateTimeFactory(self::TEST_TIMEZONE);
$dateTime = $sut->createDateTime();
$difference = $expected->getTimestamp() - $dateTime->getTimestamp();
// poor test, but there shouldn't be more than 2 seconds between the creation of two DateTime objects
$this->assertTrue(2 >= $difference);
}
}

View File

@@ -14,80 +14,27 @@ use App\Timesheet\UserDateTimeFactory;
use PHPUnit\Framework\TestCase;
/**
* @covers \App\Timesheet\DateTimeFactory
* @covers \App\Timesheet\UserDateTimeFactory
*/
class UserDateTimeFactoryTest extends TestCase
{
public const TEST_TIMEZONE = 'Europe/London';
public const TEST_TIMEZONE = 'Africa/Asmara';
protected function createDateTimeFactory(?string $timezone = null): UserDateTimeFactory
protected function createUserDateTimeFactory(?string $timezone = null): UserDateTimeFactory
{
return (new UserDateTimeFactoryFactory($this))->create($timezone);
}
public function testGetTimezone()
{
$sut = $this->createDateTimeFactory(self::TEST_TIMEZONE);
$sut = $this->createUserDateTimeFactory(self::TEST_TIMEZONE);
$this->assertEquals(self::TEST_TIMEZONE, $sut->getTimezone()->getName());
}
public function testGetTimezoneWithFallbackTimezone()
{
$sut = $this->createDateTimeFactory();
$sut = $this->createUserDateTimeFactory();
$this->assertEquals(date_default_timezone_get(), $sut->getTimezone()->getName());
}
public function testGetStartOfMonth()
{
$expected = new \DateTime('now', new \DateTimeZone(self::TEST_TIMEZONE));
$sut = $this->createDateTimeFactory(self::TEST_TIMEZONE);
$dateTime = $sut->getStartOfMonth();
$this->assertEquals(0, $dateTime->format('H'));
$this->assertEquals(0, $dateTime->format('i'));
$this->assertEquals(0, $dateTime->format('s'));
$this->assertEquals(1, $dateTime->format('d'));
$this->assertEquals($expected->format('m'), $dateTime->format('m'));
$this->assertEquals($expected->format('Y'), $dateTime->format('Y'));
$this->assertEquals(self::TEST_TIMEZONE, $dateTime->getTimezone()->getName());
}
public function testGetEndOfMonth()
{
$expected = new \DateTime('last day of this month', new \DateTimeZone(self::TEST_TIMEZONE));
$sut = $this->createDateTimeFactory(self::TEST_TIMEZONE);
$dateTime = $sut->getEndOfMonth();
$this->assertEquals(23, $dateTime->format('H'));
$this->assertEquals(59, $dateTime->format('i'));
$this->assertEquals(59, $dateTime->format('s'));
$this->assertEquals($expected->format('d'), $dateTime->format('d'));
$this->assertEquals($expected->format('m'), $dateTime->format('m'));
$this->assertEquals($expected->format('Y'), $dateTime->format('Y'));
$this->assertEquals(self::TEST_TIMEZONE, $dateTime->getTimezone()->getName());
}
public function testCreateDateTime()
{
$sut = $this->createDateTimeFactory(self::TEST_TIMEZONE);
$dateTime = $sut->createDateTime('2015-07-24 13:45:21');
$this->assertEquals(13, $dateTime->format('H'));
$this->assertEquals(45, $dateTime->format('i'));
$this->assertEquals(21, $dateTime->format('s'));
$this->assertEquals('24', $dateTime->format('d'));
$this->assertEquals('07', $dateTime->format('m'));
$this->assertEquals('2015', $dateTime->format('Y'));
$this->assertEquals(self::TEST_TIMEZONE, $dateTime->getTimezone()->getName());
}
public function testCreateDateTimeWithDefaultValue()
{
$expected = new \DateTime('now', new \DateTimeZone(self::TEST_TIMEZONE));
$sut = $this->createDateTimeFactory(self::TEST_TIMEZONE);
$dateTime = $sut->createDateTime();
$difference = $expected->getTimestamp() - $dateTime->getTimestamp();
// poor test, but there shouldn't be more than 2 seconds between the creation of two DateTime objects
$this->assertTrue(2 >= $difference);
}
}

View File

@@ -139,20 +139,27 @@ class DateExtensionsTest extends TestCase
/**
* @dataProvider getMonthNameTestData
*/
public function testMonthName(string $locale, string $date, string $expectedName)
public function testMonthName(string $locale, string $date, string $expectedName, bool $withYear = false)
{
$sut = $this->getSut($locale, []);
self::assertEquals($expectedName, $sut->monthName(new \DateTime($date)));
self::assertEquals($expectedName, $sut->monthName(new \DateTime($date), $withYear));
}
public function getMonthNameTestData()
{
return [
['de', '2020-07-09 23:59:59', 'Juli'],
['en', '2020-07-09 23:59:59', 'July'],
['de', 'January 2016', 'Januar'],
['en', 'January 2016', 'January'],
['en', '2016-12-23', 'December'],
['de', '2020-07-09 23:59:59', 'Juli', false],
['en', '2020-07-09 23:59:59', 'July', false],
['de', 'January 2016', 'Januar', false],
['en', 'January 2016', 'January', false],
['en', '2016-12-23', 'December', false],
['ru', '2016-12-23', 'декабрь', false],
['de', '2020-07-09 23:59:59', 'Juli 2020', true],
['en', '2020-07-09 23:59:59', 'July 2020', true],
['de', 'January 2016', 'Januar 2016', true],
['en', 'January 2016', 'January 2016', true],
['en', '2015-12-23', 'December 2015', true],
['ru', '2015-12-23', 'декабрь 2015', true],
];
}

View File

@@ -9,6 +9,9 @@
namespace App\Tests\Twig;
use App\Entity\Activity;
use App\Entity\Customer;
use App\Entity\Project;
use App\Entity\User;
use App\Twig\Extensions;
use PHPUnit\Framework\TestCase;
@@ -27,7 +30,7 @@ class ExtensionsTest extends TestCase
public function testGetFilters()
{
$filters = ['docu_link', 'multiline_indent'];
$filters = ['docu_link', 'multiline_indent', 'color'];
$sut = $this->getSut();
$twigFilters = $sut->getFilters();
$this->assertCount(\count($filters), $twigFilters);
@@ -116,4 +119,39 @@ sdfsdf' . PHP_EOL . "\n" .
$sut = $this->getSut();
self::assertEquals(implode("\n", $expected), $sut->multilineIndent($string, $indent));
}
public function testColor()
{
$sut = $this->getSut();
$globalActivity = new Activity();
self::assertNull($sut->color($globalActivity));
$globalActivity->setColor('#000001');
self::assertEquals('#000001', $sut->color($globalActivity));
$customer = new Customer();
self::assertNull($sut->color($customer));
$customer->setColor('#000004');
self::assertEquals('#000004', $sut->color($customer));
$project = new Project();
self::assertNull($sut->color($project));
$project->setCustomer($customer);
self::assertEquals('#000004', $sut->color($project));
$project->setColor('#000003');
self::assertEquals('#000003', $sut->color($project));
$activity = new Activity();
self::assertNull($sut->color($activity));
$activity->setProject($project);
self::assertEquals('#000003', $sut->color($activity));
$activity->setColor('#000002');
self::assertEquals('#000002', $sut->color($activity));
}
}

View File

@@ -57,6 +57,6 @@ class ReportingExtensionTest extends TestCase
$sut = $this->getSut(true);
$reports = $sut->getAvailableReports(new User());
self::assertIsArray($reports);
self::assertCount(2, $reports);
self::assertCount(3, $reports);
}
}