createUserWithPermission(); $timeEntryRunningLongerThanThreshold = TimeEntry::factory()->forMember($user->member)->create([ 'start' => Carbon::now()->subHours(8)->subSecond(), 'end' => null, ]); // Act $exitCode = $this->withoutMockingConsoleOutput()->artisan('time-entry:send-still-running-mails'); // Assert Mail::assertQueued(TimeEntryStillRunningMail::class, function ($mail) use ($user, $timeEntryRunningLongerThanThreshold) { return $mail->hasTo($user->user->email) && $mail->timeEntry->is($timeEntryRunningLongerThanThreshold) && $mail->user->is($user->user); }); $timeEntryRunningLongerThanThreshold->refresh(); $this->assertNotNull($timeEntryRunningLongerThanThreshold->still_active_email_sent_at); $this->assertSame(Command::SUCCESS, $exitCode); $output = Artisan::output(); $this->assertSame("Sending still running time entry emails...\n". 'Start sending email to user "'.$user->user->email.'" ('.$user->user->getKey().') for time entry '.$timeEntryRunningLongerThanThreshold->getKey()."\n". "Finished sending 1 still running time entry emails...\n", $output); } public function test_does_not_send_emails_for_not_running_time_entries(): void { // Arrange $user = $this->createUserWithPermission(); $timeEntry = TimeEntry::factory()->forMember($user->member)->create([ 'start' => Carbon::now()->subHours(8)->subSecond(), 'end' => Carbon::now(), ]); // Act $exitCode = $this->withoutMockingConsoleOutput()->artisan('time-entry:send-still-running-mails'); // Assert Mail::assertNothingOutgoing(); $timeEntry->refresh(); $this->assertNull($timeEntry->still_active_email_sent_at); $this->assertSame(Command::SUCCESS, $exitCode); $output = Artisan::output(); $this->assertSame("Sending still running time entry emails...\n". "Finished sending 0 still running time entry emails...\n", $output); } public function test_does_not_send_emails_for_running_time_entries_that_are_short_than_the_threshold(): void { // Arrange $user = $this->createUserWithPermission(); $timeEntry = TimeEntry::factory()->forMember($user->member)->create([ 'start' => Carbon::now()->subHours(8)->addMinute(), 'end' => null, ]); // Act $exitCode = $this->withoutMockingConsoleOutput()->artisan('time-entry:send-still-running-mails'); // Assert Mail::assertNothingOutgoing(); $timeEntry->refresh(); $this->assertNull($timeEntry->still_active_email_sent_at); $this->assertSame(Command::SUCCESS, $exitCode); $output = Artisan::output(); $this->assertSame("Sending still running time entry emails...\n". "Finished sending 0 still running time entry emails...\n", $output); } public function test_does_not_send_emails_for_running_time_entries_that_are_longer_than_the_threshold_but_already_received_the_email(): void { // Arrange $user = $this->createUserWithPermission(); $timeEntry = TimeEntry::factory()->forMember($user->member)->create([ 'start' => Carbon::now()->subHours(8)->subMinute(), 'end' => null, 'still_active_email_sent_at' => Carbon::now()->subMinute(), ]); // Act $exitCode = $this->withoutMockingConsoleOutput()->artisan('time-entry:send-still-running-mails'); // Assert Mail::assertNothingOutgoing(); $timeEntry->refresh(); $this->assertNotNull($timeEntry->still_active_email_sent_at); $this->assertSame(Command::SUCCESS, $exitCode); $output = Artisan::output(); $this->assertSame("Sending still running time entry emails...\n". "Finished sending 0 still running time entry emails...\n", $output); } public function test_dry_run_option_does_not_send_mails_but_outputs_what_would_happen(): void { // Arrange $user = $this->createUserWithPermission(); $timeEntryRunningLongerThanThreshold = TimeEntry::factory()->forMember($user->member)->create([ 'start' => Carbon::now()->subHours(8)->subSecond(), 'end' => null, ]); // Act $exitCode = $this->withoutMockingConsoleOutput()->artisan('time-entry:send-still-running-mails --dry-run'); // Assert Mail::assertNothingOutgoing(); $timeEntryRunningLongerThanThreshold->refresh(); $this->assertNull($timeEntryRunningLongerThanThreshold->still_active_email_sent_at); $this->assertSame(Command::SUCCESS, $exitCode); $output = Artisan::output(); $this->assertSame("Sending still running time entry emails...\n". "Running in dry-run mode. No emails will be sent and nothing will be saved to the database.\n". 'Start sending email to user "'.$user->user->email.'" ('.$user->user->getKey().') for time entry '.$timeEntryRunningLongerThanThreshold->getKey()."\n". "Finished sending 1 still running time entry emails...\n", $output); } public function test_does_not_send_emails_for_placeholder_users(): void { // Arrange $user = $this->createUserWithPermission(); $user->user->is_placeholder = true; $user->user->save(); $timeEntryRunningLongerThanThreshold = TimeEntry::factory()->forMember($user->member)->create([ 'start' => Carbon::now()->subHours(8)->subSecond(), 'end' => null, ]); // Act $exitCode = $this->withoutMockingConsoleOutput()->artisan('time-entry:send-still-running-mails'); // Assert Mail::assertNothingOutgoing(); $timeEntryRunningLongerThanThreshold->refresh(); $this->assertNull($timeEntryRunningLongerThanThreshold->still_active_email_sent_at); $this->assertSame(Command::SUCCESS, $exitCode); $output = Artisan::output(); $this->assertSame("Sending still running time entry emails...\n". "Finished sending 0 still running time entry emails...\n", $output); } }