11, 'name' => 'Task A', 'pay_rate' => '100.00', 'month' => '2026-01' ], [ 'id' => 11, 'name' => 'Task A', 'pay_rate' => '100.00', 'month' => '2026-01' ], // duplicate [ 'id' => 11, 'name' => 'Task A', 'pay_rate' => '100.00', 'month' => '2026-02' ], [ 'id' => 12, 'name' => 'Task B', 'pay_rate' => null, 'month' => '2026-02' ], [ 'id' => 13, 'name' => 'Task C', 'pay_rate' => null ] // invalid row, no month ]; $calls = []; $tasks = WorkTimeRepository::buildClientTasksByMonth( $rows, function( $task_id, $month ) use ( &$calls ) { $calls[] = $task_id . ':' . $month; return $task_id * 10; } ); assert_true( isset( $tasks['2026-01'] ), 'Expected month 2026-01 in result.' ); assert_true( isset( $tasks['2026-02'] ), 'Expected month 2026-02 in result.' ); assert_true( count( $tasks['2026-01'] ) === 1, 'Expected duplicate tasks to be deduplicated per month.' ); assert_true( count( $tasks['2026-02'] ) === 2, 'Expected two unique tasks in month 2026-02.' ); assert_true( $tasks['2026-01'][0]['time'] === 110, 'Expected task time to come from provider.' ); assert_true( $tasks['2026-02'][0]['time'] === 110, 'Expected month-specific provider call for the same task.' ); assert_true( $tasks['2026-02'][1]['time'] === 120, 'Expected provider value for second task.' ); assert_true( count( $calls ) === 3, 'Expected provider to be called once for each unique task+month pair.' ); }