diff --git a/app/Support/Navigation.php b/app/Support/Navigation.php index 05200c3c83..33e58fb026 100644 --- a/app/Support/Navigation.php +++ b/app/Support/Navigation.php @@ -82,9 +82,6 @@ class Navigation */ public function addPeriod(Carbon $theDate, string $repeatFreq, int $skip = 0): Carbon { - $date = clone $theDate; - $add = ($skip + 1); - $functionMap = [ '1D' => Periodicity::Daily, 'daily' => Periodicity::Daily, @@ -219,11 +216,8 @@ class Navigation return $date; } if ('half-year' === $repeatFreq || '6M' === $repeatFreq) { - $month = $date->month; - $date->startOfYear(); - if ($month >= 7) { - $date->addMonths(6); - } + $skipTo = $date->month > 7 ? 6 : 0; + $date->startOfYear()->addMonths($skipTo); return $date; } diff --git a/tests/unit/Support/NavigationTest.php b/tests/unit/Support/NavigationAddPeriodTest.php similarity index 94% rename from tests/unit/Support/NavigationTest.php rename to tests/unit/Support/NavigationAddPeriodTest.php index 29f8b9938a..4ce3aa5d40 100644 --- a/tests/unit/Support/NavigationTest.php +++ b/tests/unit/Support/NavigationAddPeriodTest.php @@ -1,5 +1,24 @@ + * + * This file is part of Firefly III (https://github.com/firefly-iii). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + declare(strict_types=1); namespace Tests\unit\Support; @@ -14,7 +33,7 @@ use PHPUnit\Framework\TestCase; * @group support * @group navigation */ -class NavigationTest extends TestCase +class NavigationAddPeriodTest extends TestCase { private Navigation $navigation; diff --git a/tests/unit/Support/NavigationStartOfPeriodTest.php b/tests/unit/Support/NavigationStartOfPeriodTest.php new file mode 100644 index 0000000000..a473e60f55 --- /dev/null +++ b/tests/unit/Support/NavigationStartOfPeriodTest.php @@ -0,0 +1,106 @@ + + * + * This file is part of Firefly III (https://github.com/firefly-iii). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +declare(strict_types=1); + +namespace Tests\unit\Support; + +use Carbon\Carbon; +use FireflyIII\Support\Navigation; +use Illuminate\Support\Facades\Log; +use PHPUnit\Framework\TestCase; + +/** + * @group unit-test + * @group support + * @group navigation + */ +class NavigationStartOfPeriodTest extends TestCase +{ + private Navigation $navigation; + + public function __construct(string $name) + { + parent::__construct($name); + $this->navigation = new Navigation(); + } + + public static function provideDates(): array + { + return [ + 'custom' => ['frequency' => 'custom', 'from' => Carbon::now(), 'expected' => Carbon::now()], + '1D' => ['frequency' => '1D', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()], + 'daily' => ['frequency' => 'daily', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()], + '1W' => ['frequency' => '1W', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfWeek()], + 'week' => ['frequency' => 'week', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfWeek()], + 'weekly' => ['frequency' => 'weekly', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfWeek()], + 'month' => ['frequency' => 'month', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfMonth()], + '1M' => ['frequency' => '1M', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfMonth()], + 'monthly' => ['frequency' => 'monthly', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfMonth()], + '3M' => ['frequency' => '3M', 'from' => Carbon::now(), 'expected' => Carbon::now()->firstOfQuarter()], + 'quarter' => ['frequency' => 'quarter', 'from' => Carbon::now(), 'expected' => Carbon::now()->firstOfQuarter()], + 'quarterly' => ['frequency' => 'quarterly', 'from' => Carbon::now(), 'expected' => Carbon::now()->firstOfQuarter()], + 'year' => ['frequency' => 'year', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfYear()], + 'yearly' => ['frequency' => 'yearly', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfYear()], + '1Y' => ['frequency' => '1Y', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfYear()], + 'half-year' => ['frequency' => 'half-year', 'from' => Carbon::parse('2023-05-20'), 'expected' => Carbon::parse('2023-01-01')->startOfYear()], + '6M' => ['frequency' => '6M', 'from' => Carbon::parse('2023-08-20'), 'expected' => Carbon::parse('2023-07-01')], + 'last7' => ['frequency' => 'last7', 'from' => Carbon::now(), 'expected' => Carbon::now()->subDays(7)->startOfDay()], + 'last30' => ['frequency' => 'last30', 'from' => Carbon::now(), 'expected' => Carbon::now()->subDays(30)->startOfDay()], + 'last90' => ['frequency' => 'last90', 'from' => Carbon::now(), 'expected' => Carbon::now()->subDays(90)->startOfDay()], + 'last365' => ['frequency' => 'last365', 'from' => Carbon::now(), 'expected' => Carbon::now()->subDays(365)->startOfDay()], + 'MTD' => ['frequency' => 'MTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfMonth()->startOfDay()], + 'QTD' => ['frequency' => 'QTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->firstOfQuarter()->startOfDay()], + 'YTD' => ['frequency' => 'YTD', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfYear()->startOfDay()], + ]; + } + + /** + * @dataProvider provideDates + */ + public function testGivenADateAndFrequencyWhenCalculateTheDateThenReturnsTheExpectedDateSuccessful(string $frequency, Carbon $from, Carbon $expected) + { + $period = $this->navigation->startOfPeriod($from, $frequency); + $this->assertEquals($expected->toDateString(), $period->toDateString()); + } + + public static function provideUnknownFrequencies(): array + { + return [ + '1day' => ['frequency' => '1day', 'from' => Carbon::now(), 'expected' => Carbon::now()], + 'unknown' => ['frequency' => 'unknown', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()], + 'empty' => ['frequency' => '', 'from' => Carbon::now(), 'expected' => Carbon::now()->startOfDay()], + ]; + } + + /** + * @dataProvider provideUnknownFrequencies + */ + public function testGivenADateAndUnknownFrequencyWhenCalculateTheDateThenReturnsTheSameDateSuccessful(string $frequency, Carbon $from, Carbon $expected) + { + Log::shouldReceive('error') + ->with(sprintf('Cannot do startOfPeriod for $repeat_freq "%s"', $frequency)) + ->andReturnNull(); + + $period = $this->navigation->startOfPeriod($from, $frequency); + $this->assertEquals($expected->toDateString(), $period->toDateString()); + } +}