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());
+ }
+}