diff --git a/tests/phpunit/CRM/Contribute/BAO/ContributionRecurTest.php b/tests/phpunit/CRM/Contribute/BAO/ContributionRecurTest.php index 4e018349cfab..1ba6b9dcbe8b 100644 --- a/tests/phpunit/CRM/Contribute/BAO/ContributionRecurTest.php +++ b/tests/phpunit/CRM/Contribute/BAO/ContributionRecurTest.php @@ -372,14 +372,14 @@ public function testAutoRenewalWhenOneMemberIsDeceased() { $this->validateAllCounts($membershipId1, 4); $this->validateAllCounts($membershipId2, 4); - $expectedMonth = date('m') + 4; + $expectedDate = $this->getYearAndMonthFromOffset(4); // check membership end date. foreach ([$membershipId1, $membershipId2] as $mId) { $endDate = $this->callAPISuccessGetValue('Membership', [ 'id' => $mId, 'return' => 'end_date', ]); - $this->assertEquals(date('Y-' . $expectedMonth . '-27'), $endDate, ts('End date incorrect.')); + $this->assertEquals("{$expectedDate['year']}-{$expectedDate['month']}-27", $endDate, ts('End date incorrect.')); } // At this moment Contact 2 is deceased, but we wait until payment is recorded in civi before marking the contact deceased. @@ -446,7 +446,8 @@ public function testAutoRenewalWhenOneMemberIsDeceased() { 'id' => $membershipId1, 'return' => 'end_date', ]); - $this->assertEquals(date('Y-m', strtotime('+6 months')) . '-27', $endDate, ts('End date incorrect.')); + $expectedDate = $this->getYearAndMonthFromOffset(6); + $this->assertEquals("{$expectedDate['year']}-{$expectedDate['month']}-27", $endDate, ts('End date incorrect.')); // check line item and membership payment count. $this->validateAllCounts($membershipId1, 6); $this->validateAllCounts($membershipId2, 4); @@ -479,4 +480,80 @@ public function validateAllCounts($membershipId, $count) { $this->callAPISuccessGetCount('MembershipPayment', $memPayParams, $count); } + /** + * Given a number of months offset, get the year and month. + * Note the way php arithmetic works, using strtotime('+x months') doesn't + * work because it will roll over the day accounting for different number + * of days in the month, but we want the same day of the month, x months + * from now. + * e.g. July 31 + 4 months will return Dec 1 if using php functions, but + * we want Nov 31. + * + * @param int $offset + * @param int $year Optional input year to start + * @param int $month Optional input month to start + * + * @return array + * ['year' => int, 'month' => int] + */ + private function getYearAndMonthFromOffset(int $offset, int $year = NULL, int $month = NULL) { + $dateInfo = [ + 'year' => $year ?? date('Y'), + 'month' => ($month ?? date('m')) + $offset, + ]; + if ($dateInfo['month'] > 12) { + $dateInfo['year']++; + $dateInfo['month'] -= 12; + } + if ($dateInfo['month'] < 10) { + $dateInfo['month'] = "0{$dateInfo['month']}"; + } + + return $dateInfo; + } + + /** + * Test getYearAndMonthFromOffset + * @dataProvider yearMonthProvider + * + * @param array $input + * @param array $expected + */ + public function testGetYearAndMonthFromOffset($input, $expected) { + $this->assertEquals($expected, $this->getYearAndMonthFromOffset($input[0], $input[1], $input[2])); + } + + /** + * data provider for testGetYearAndMonthFromOffset + */ + public function yearMonthProvider() { + return [ + // input = offset, year, current month + ['input' => [4, 2020, 1], 'output' => ['year' => '2020', 'month' => '05']], + ['input' => [6, 2020, 1], 'output' => ['year' => '2020', 'month' => '07']], + ['input' => [4, 2020, 2], 'output' => ['year' => '2020', 'month' => '06']], + ['input' => [6, 2020, 2], 'output' => ['year' => '2020', 'month' => '08']], + ['input' => [4, 2020, 3], 'output' => ['year' => '2020', 'month' => '07']], + ['input' => [6, 2020, 3], 'output' => ['year' => '2020', 'month' => '09']], + ['input' => [4, 2020, 4], 'output' => ['year' => '2020', 'month' => '08']], + ['input' => [6, 2020, 4], 'output' => ['year' => '2020', 'month' => '10']], + ['input' => [4, 2020, 5], 'output' => ['year' => '2020', 'month' => '09']], + ['input' => [6, 2020, 5], 'output' => ['year' => '2020', 'month' => '11']], + ['input' => [4, 2020, 6], 'output' => ['year' => '2020', 'month' => '10']], + ['input' => [6, 2020, 6], 'output' => ['year' => '2020', 'month' => '12']], + ['input' => [4, 2020, 7], 'output' => ['year' => '2020', 'month' => '11']], + ['input' => [6, 2020, 7], 'output' => ['year' => '2021', 'month' => '01']], + ['input' => [4, 2020, 8], 'output' => ['year' => '2020', 'month' => '12']], + ['input' => [6, 2020, 8], 'output' => ['year' => '2021', 'month' => '02']], + ['input' => [4, 2020, 9], 'output' => ['year' => '2021', 'month' => '01']], + ['input' => [6, 2020, 9], 'output' => ['year' => '2021', 'month' => '03']], + ['input' => [4, 2020, 10], 'output' => ['year' => '2021', 'month' => '02']], + ['input' => [6, 2020, 10], 'output' => ['year' => '2021', 'month' => '04']], + ['input' => [4, 2020, 11], 'output' => ['year' => '2021', 'month' => '03']], + ['input' => [6, 2020, 11], 'output' => ['year' => '2021', 'month' => '05']], + ['input' => [4, 2020, 12], 'output' => ['year' => '2021', 'month' => '04']], + ['input' => [6, 2020, 12], 'output' => ['year' => '2021', 'month' => '06']], + ]; + } + }