|
DXP4800PLUS-B5F8
5 Signs You Have Successfully Hur DXP4800PLUS-B5F8
5 Signs You Have Successfully Hurt a Narcissist; - [EMAIL] - Gmail
(66) Inbox | [EMAIL] | Proton Mail
Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 241,72 € (472,76 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com
Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 241,72 € (472,76 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com
Today's Deals
Today's Deals
architecture - screenpipe docs
architecture - screenpipe docs
[CircleCI] Workflow failed: jiminny / app on JY-20157-AJ-report-not-send-notification - [EMAIL] - Gmail
[CircleCI] Workflow failed: jiminny / app on JY-20157-AJ-report-not-send-notification - [EMAIL] - Gmail
Screenpipe — Archive
Screenpipe — Archive
SQLite Web: archive.db
SQLite Web: archive.db
SQLite Web: db.sqlite
SQLite Web: db.sqlite
Claude Platform
Claude Platform
rescue time detailed overview - Google Search
rescue time detailed overview - Google Search
Hey @louis030195 Ill check during my - screenpipe.com
Hey @louis030195 Ill check during my - screenpipe.com
GitHub - screenpipe/screenpipe: Run agents that work for you based on what you do. AI finally knows what you are doing · GitHub
GitHub - screenpipe/screenpipe: Run agents that work for you based on what you do. AI finally knows what you are doing · GitHub
Gong Pricing in 2026: Costs, Plans & Is It Worth It?
Gong Pricing in 2026: Costs, Plans & Is It Worth It?
(132) Damien Rice & Lisa Hannigan - 9 Crimes - 2006-11-17 - YouTube
Mute tab
(132) Damien Rice & Lisa Hannigan - 9 Crimes - 2006-11-17 - YouTube
New Tab
New Tab
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
22°
C
New York City
Open menu
Do you want to see the weather for your location?
Do you want to see the weather for your location?
Not now
Not now
Yes
Yes
Mozilla Firefox
Search with Google or enter address
Search with Google or enter address
Browse faster with Firefox
Browse faster with Firefox
Firefox helps pages load faster and tabs feel smoother to keep up with the way you browse.
Find out how
Find out how
Not now
Not now
Inbox (3) - [EMAIL] - Gmail
Inbox (3) - [EMAIL] - Gmail
Open context menu for Inbox (3) - [EMAIL] - Gmail
Screenpipe — Archive
Screenpipe — Archive
Open context menu for Screenpipe — Archive
(132) YouTube
(132) YouTube
Open context menu for (132) YouTube
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Open context menu for DXP4800PLUS-B5F8
Screenpipe — Archive
Screenpipe — Archive
Open context menu for Screenpipe — Archive
Shameless • HBO Max
Shameless • HBO Max
Open context menu for Shameless • HBO Max
Denník N - Nezávislý denník
Denník N - Nezávislý denník
Open context menu for Denník N - Nezávislý denník
Твърд диск, Western Digital Red 6TB Plus ( 3.5", 256MB, 5400
Твърд диск, Western Digital Red 6TB Plus ( 3.5", 256MB, 5400
Open context menu for Твърд диск, Western Digital Red 6TB Plus ( 3.5", 256MB, 5400
Customize
Customize...
|
Firefox
|
Personal — Mozilla Firefox
|
NULL
|
76263
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
TrackAutomatedReportGeneratedEventTest
Run 'TrackAutomatedReportGeneratedEventTest'
Debug 'TrackAutomatedReportGeneratedEventTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
43
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Jiminny\Component\Queue\Constants;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\Contracts\UserContract;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use Illuminate\Support\Facades\Log;
class TrackAutomatedReportGeneratedEvent implements ShouldQueue
{
use InteractsWithQueue;
private const string EVENT_NAME_AUTOMATED_REPORT = 'automated-report-generated';
private const string EVENT_NAME_ASK_JIMINNY_REPORT = 'ask-jiminny-report-generated';
public string $queue = Constants::QUEUE_DELAYABLE;
public function __construct(
private readonly UserPilotClient $userPilotClient,
private readonly AutomatedReportsService $automatedReportsService,
) {
}
public function handle(AutomatedReportGenerated $event): void
{
if (config('services.userpilot.token') === null) {
return;
}
$automatedReport = $event->automatedReport;
$payload = $this->buildPayload($automatedReport);
$eventName = $this->resolveEventName($automatedReport);
$users = $this->resolveUsers($automatedReport);
if (empty($users)) {
Log::warning('[UserPilot] No recipients found for automated report', [
'report_id' => $automatedReport->getId(),
'is_ask_jiminny' => $automatedReport->isAskJiminnyReport(),
]);
return;
}
Log::info('[UserPilot] Sending automated report event', [
'report_id' => $automatedReport->getId(),
'event_name' => $eventName,
'recipient_count' => count($users),
]);
try {
foreach ($users as $user) {
$this->userPilotClient->track($user, $eventName, $payload);
}
} catch (GuzzleException $e) {
Log::error('[UserPilot] Failed to send automated report event', [
'report_id' => $automatedReport->getId(),
'error' => $e->getMessage(),
]);
$this->release(3600);
}
}
/**
* @return array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – TrackAutomatedReportGeneratedEventTest faVsco.js – TrackAutomatedReportGeneratedEventTest.php...
|
NULL
|
76264
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
TrackAutomatedReportGeneratedEventTest
Run 'TrackAutomatedReportGeneratedEventTest'
Debug 'TrackAutomatedReportGeneratedEventTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
43
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Jiminny\Component\Queue\Constants;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\Contracts\UserContract;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use Illuminate\Support\Facades\Log;
class TrackAutomatedReportGeneratedEvent implements ShouldQueue
{
use InteractsWithQueue;
private const string EVENT_NAME_AUTOMATED_REPORT = 'automated-report-generated';
private const string EVENT_NAME_ASK_JIMINNY_REPORT = 'ask-jiminny-report-generated';
public string $queue = Constants::QUEUE_DELAYABLE;
public function __construct(
private readonly UserPilotClient $userPilotClient,
private readonly AutomatedReportsService $automatedReportsService,
) {
}
public function handle(AutomatedReportGenerated $event): void
{
if (config('services.userpilot.token') === null) {
return;
}
$automatedReport = $event->automatedReport;
$payload = $this->buildPayload($automatedReport);
$eventName = $this->resolveEventName($automatedReport);
$users = $this->resolveUsers($automatedReport);
if (empty($users)) {
Log::warning('[UserPilot] No recipients found for automated report', [
'report_id' => $automatedReport->getId(),
'is_ask_jiminny' => $automatedReport->isAskJiminnyReport(),
]);
return;
}
Log::info('[UserPilot] Sending automated report event', [
'report_id' => $automatedReport->getId(),
'event_name' => $eventName,
'recipient_count' => count($users),
]);
try {
foreach ($users as $user) {
$this->userPilotClient->track($user, $eventName, $payload);
}
} catch (GuzzleException $e) {
Log::error('[UserPilot] Failed to send automated report event', [
'report_id' => $automatedReport->getId(),
'error' => $e->getMessage(),
]);
$this->release(3600);
}
}
/**
* @return array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – TrackAutomatedReportGeneratedEventTest faVsco.js – TrackAutomatedReportGeneratedEventTest.php...
|
NULL
|
76265
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
TrackAutomatedReportGeneratedEventTest
Run 'TrackAutomatedReportGeneratedEventTest'
Debug 'TrackAutomatedReportGeneratedEventTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Code changed:
Hide...
|
PhpStorm
|
faVsco.js – TrackAutomatedReportGeneratedEventTest faVsco.js – TrackAutomatedReportGeneratedEventTest.php...
|
NULL
|
76266
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
TrackAutomatedReportGeneratedEventTest
Run 'TrackAutomatedReportGeneratedEventTest'
Debug 'TrackAutomatedReportGeneratedEventTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Code changed:
Hide
Sync Changes...
|
PhpStorm
|
faVsco.js – TrackAutomatedReportGeneratedEventTest faVsco.js – TrackAutomatedReportGeneratedEventTest.php...
|
NULL
|
76267
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
TrackAutomatedReportGeneratedEventTest
Run 'TrackAutomatedReportGeneratedEventTest'
Debug 'TrackAutomatedReportGeneratedEventTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
43
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Jiminny\Component\Queue\Constants;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\Contracts\UserContract;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use Illuminate\Support\Facades\Log;
class TrackAutomatedReportGeneratedEvent implements ShouldQueue
{
use InteractsWithQueue;
private const string EVENT_NAME_AUTOMATED_REPORT = 'automated-report-generated';
private const string EVENT_NAME_ASK_JIMINNY_REPORT = 'ask-jiminny-report-generated';
public string $queue = Constants::QUEUE_DELAYABLE;
public function __construct(
private readonly UserPilotClient $userPilotClient,
private readonly AutomatedReportsService $automatedReportsService,
) {
}
public function handle(AutomatedReportGenerated $event): void
{
if (config('services.userpilot.token') === null) {
return;
}
$automatedReport = $event->automatedReport;
$payload = $this->buildPayload($automatedReport);
$eventName = $this->resolveEventName($automatedReport);
$users = $this->resolveUsers($automatedReport);
if (empty($users)) {
Log::warning('[UserPilot] No recipients found for automated report', [
'report_id' => $automatedReport->getId(),
'is_ask_jiminny' => $automatedReport->isAskJiminnyReport(),
]);
return;
}
Log::info('[UserPilot] Sending automated report event', [
'report_id' => $automatedReport->getId(),
'event_name' => $eventName,
'recipient_count' => count($users),
]);
try {
foreach ($users as $user) {
$this->userPilotClient->track($user, $eventName, $payload);
}
} catch (GuzzleException $e) {
Log::error('[UserPilot] Failed to send automated report event', [
'report_id' => $automatedReport->getId(),
'error' => $e->getMessage(),
]);
$this->release(3600);
}
}
/**
* @return array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – TrackAutomatedReportGeneratedEventTest faVsco.js – TrackAutomatedReportGeneratedEventTest.php...
|
NULL
|
76268
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
TrackAutomatedReportGeneratedEventTest
Run 'TrackAutomatedReportGeneratedEventTest'
Debug 'TrackAutomatedReportGeneratedEventTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
43
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Jiminny\Component\Queue\Constants;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\Contracts\UserContract;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use Illuminate\Support\Facades\Log;
class TrackAutomatedReportGeneratedEvent implements ShouldQueue
{
use InteractsWithQueue;
private const string EVENT_NAME_AUTOMATED_REPORT = 'automated-report-generated';
private const string EVENT_NAME_ASK_JIMINNY_REPORT = 'ask-jiminny-report-generated';
public string $queue = Constants::QUEUE_DELAYABLE;
public function __construct(
private readonly UserPilotClient $userPilotClient,
private readonly AutomatedReportsService $automatedReportsService,
) {
}
public function handle(AutomatedReportGenerated $event): void
{
if (config('services.userpilot.token') === null) {
return;
}
$automatedReport = $event->automatedReport;
$payload = $this->buildPayload($automatedReport);
$eventName = $this->resolveEventName($automatedReport);
$users = $this->resolveUsers($automatedReport);
if (empty($users)) {
Log::warning('[UserPilot] No recipients found for automated report', [
'report_id' => $automatedReport->getId(),
'is_ask_jiminny' => $automatedReport->isAskJiminnyReport(),
]);
return;
}
Log::info('[UserPilot] Sending automated report event', [
'report_id' => $automatedReport->getId(),
'event_name' => $eventName,
'recipient_count' => count($users),
]);
try {
foreach ($users as $user) {
$this->userPilotClient->track($user, $eventName, $payload);
}
} catch (GuzzleException $e) {
Log::error('[UserPilot] Failed to send automated report event', [
'report_id' => $automatedReport->getId(),
'error' => $e->getMessage(),
]);
$this->release(3600);
}
}
/**
* @return array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – TrackAutomatedReportGeneratedEventTest faVsco.js – TrackAutomatedReportGeneratedEventTest.php...
|
NULL
|
76269
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
TrackAutomatedReportGeneratedEventTest
Run 'TrackAutomatedReportGeneratedEventTest'
Debug 'TrackAutomatedReportGeneratedEventTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Mail\Reports;
use Jiminny\Mail\Mailable;
use Jiminny\Mail\Reports\ReportNotGenerated;
use Mockery;
use ReflectionClass;
use Tests\TestCase;
class ReportNotGeneratedTest extends TestCase
{
private string $reportName;
private string $periodName;
private string $reportsPageUrl;
private string $mailSubject;
private ReportNotGenerated $mailable;
protected function setUp(): void
{
parent::setUp();
$this->reportName = 'Exec Summary';
$this->periodName = 'Q3 2025';
$this->reportsPageUrl = '[URL_WITH_CREDENTIALS] array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – ReportNotGeneratedTest.php
|
NULL
|
76270
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
TrackAutomatedReportGeneratedEventTest
Run 'TrackAutomatedReportGeneratedEventTest'
Debug 'TrackAutomatedReportGeneratedEventTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Mail\Reports;
use Jiminny\Mail\Mailable;
use Jiminny\Mail\Reports\ReportNotGenerated;
use Mockery;
use ReflectionClass;
use Tests\TestCase;
class ReportNotGeneratedTest extends TestCase
{
private string $reportName;
private string $periodName;
private string $reportsPageUrl;
private string $mailSubject;
private ReportNotGenerated $mailable;
protected function setUp(): void
{
parent::setUp();
$this->reportName = 'Exec Summary';
$this->periodName = 'Q3 2025';
$this->reportsPageUrl = '[URL_WITH_CREDENTIALS] array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – ReportNotGeneratedTest.php
|
NULL
|
76271
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
TrackAutomatedReportGeneratedEventTest
Run 'TrackAutomatedReportGeneratedEventTest'
Debug 'TrackAutomatedReportGeneratedEventTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Mail\Reports;
use Jiminny\Mail\Mailable;
use Jiminny\Mail\Reports\ReportNotGenerated;
use Mockery;
use ReflectionClass;
use Tests\TestCase;
class ReportNotGeneratedTest extends TestCase
{
private string $reportName;
private string $periodName;
private string $reportsPageUrl;
private string $mailSubject;
private ReportNotGenerated $mailable;
protected function setUp(): void
{
parent::setUp();
$this->reportName = 'Exec Summary';
$this->periodName = 'Q3 2025';
$this->reportsPageUrl = '[URL_WITH_CREDENTIALS] array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – ReportNotGeneratedTest.php
|
NULL
|
76272
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
TrackAutomatedReportGeneratedEventTest
Run 'TrackAutomatedReportGeneratedEventTest'
Debug 'TrackAutomatedReportGeneratedEventTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Mail\Reports;
use Jiminny\Mail\Mailable;
use Jiminny\Mail\Reports\ReportNotGenerated;
use Mockery;
use ReflectionClass;
use Tests\TestCase;
class ReportNotGeneratedTest extends TestCase
{
private string $reportName;
private string $periodName;
private string $reportsPageUrl;
private string $mailSubject;
private ReportNotGenerated $mailable;
protected function setUp(): void
{
parent::setUp();
$this->reportName = 'Exec Summary';
$this->periodName = 'Q3 2025';
$this->reportsPageUrl = '[URL_WITH_CREDENTIALS] array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – ReportNotGeneratedTest.php
|
NULL
|
76273
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
ReportNotGeneratedTest
Rerun 'PHPUnit: ReportNotGeneratedTest'
Debug 'ReportNotGeneratedTest'
Stop 'ReportNotGeneratedTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Mail\Reports;
use Jiminny\Mail\Mailable;
use Jiminny\Mail\Reports\ReportNotGenerated;
use Mockery;
use ReflectionClass;
use Tests\TestCase;
class ReportNotGeneratedTest extends TestCase
{
private string $reportName;
private string $periodName;
private string $reportsPageUrl;
private string $mailSubject;
private ReportNotGenerated $mailable;
protected function setUp(): void
{
parent::setUp();
$this->reportName = 'Exec Summary';
$this->periodName = 'Q3 2025';
$this->reportsPageUrl = '[URL_WITH_CREDENTIALS] array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – ReportNotGeneratedTest.php
|
NULL
|
76274
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
ReportNotGeneratedTest
Rerun 'PHPUnit: ReportNotGeneratedTest'
Debug 'ReportNotGeneratedTest'
Stop 'ReportNotGeneratedTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Mail\Reports;
use Jiminny\Mail\Mailable;
use Jiminny\Mail\Reports\ReportNotGenerated;
use Mockery;
use ReflectionClass;
use Tests\TestCase;
class ReportNotGeneratedTest extends TestCase
{
private string $reportName;
private string $periodName;
private string $reportsPageUrl;
private string $mailSubject;
private ReportNotGenerated $mailable;
protected function setUp(): void
{
parent::setUp();
$this->reportName = 'Exec Summary';
$this->periodName = 'Q3 2025';
$this->reportsPageUrl = '[URL_WITH_CREDENTIALS] array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – ReportNotGeneratedTest.php
|
NULL
|
76275
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
ReportNotGeneratedTest
Rerun 'PHPUnit: ReportNotGeneratedTest'
Debug 'ReportNotGeneratedTest'
Stop 'ReportNotGeneratedTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Tests\Unit\Mail\Reports;
use Jiminny\Mail\Mailable;
use Jiminny\Mail\Reports\ReportNotGenerated;
use Mockery;
use ReflectionClass;
use Tests\TestCase;
class ReportNotGeneratedTest extends TestCase
{
private string $reportName;
private string $periodName;
private string $reportsPageUrl;
private string $mailSubject;
private ReportNotGenerated $mailable;
protected function setUp(): void
{
parent::setUp();
$this->reportName = 'Exec Summary';
$this->periodName = 'Q3 2025';
$this->reportsPageUrl = '[URL_WITH_CREDENTIALS] array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}...
|
PhpStorm
|
faVsco.js – ReportNotGeneratedTest.php
|
NULL
|
76276
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
ReportNotGeneratedTest
Run 'ReportNotGeneratedTest'
Debug 'ReportNotGeneratedTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Exception;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Mail;
use Jiminny\Jobs\AutomatedReports\SendReportNotGeneratedMailJob;
use Jiminny\Mail\Reports\ReportNotGenerated;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
use Tests\TestCase;
class SendReportNotGeneratedMailJobTest extends TestCase
{
private LoggerInterface&MockObject $logger;
private SendReportNotGeneratedMailJob $job;
private string $reportUuid = 'test-uuid';
private string $recipientEmail;
private string $recipientName;
private string $reportName;
private string $periodName;
private string $reportsPageUrl;
protected function setUp(): void
{
parent::setUp();
$this->recipientEmail = '[EMAIL]';
$this->recipientName = 'Test User';
$this->reportName = 'Exec Summary';
$this->periodName = 'Q3 2025';
$this->reportsPageUrl = '[URL_WITH_CREDENTIALS] array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – SendReportNotGeneratedMailJobTest.php
|
NULL
|
76277
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
ReportNotGeneratedTest
Run 'ReportNotGeneratedTest'
Debug 'ReportNotGeneratedTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
Analyzing…
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Exception;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Mail;
use Jiminny\Jobs\AutomatedReports\SendReportNotGeneratedMailJob;
use Jiminny\Mail\Reports\ReportNotGenerated;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
use Tests\TestCase;
class SendReportNotGeneratedMailJobTest extends TestCase
{
private LoggerInterface&MockObject $logger;
private SendReportNotGeneratedMailJob $job;
private string $reportUuid = 'test-uuid';
private string $recipientEmail;
private string $recipientName;
private string $reportName;
private string $periodName;
private string $reportsPageUrl;
protected function setUp(): void
{
parent::setUp();
$this->recipientEmail = '[EMAIL]';
$this->recipientName = 'Test User';
$this->reportName = 'Exec Summary';
$this->periodName = 'Q3 2025';
$this->reportsPageUrl = '[URL_WITH_CREDENTIALS] array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – SendReportNotGeneratedMailJobTest.php
|
NULL
|
76278
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
ReportNotGeneratedTest
Run 'ReportNotGeneratedTest'
Debug 'ReportNotGeneratedTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
3
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Exception;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Mail;
use Jiminny\Jobs\AutomatedReports\SendReportNotGeneratedMailJob;
use Jiminny\Mail\Reports\ReportNotGenerated;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
use Tests\TestCase;
class SendReportNotGeneratedMailJobTest extends TestCase
{
private LoggerInterface&MockObject $logger;
private SendReportNotGeneratedMailJob $job;
private string $reportUuid = 'test-uuid';
private string $recipientEmail;
private string $recipientName;
private string $reportName;
private string $periodName;
private string $reportsPageUrl;
protected function setUp(): void
{
parent::setUp();
$this->recipientEmail = '[EMAIL]';
$this->recipientName = 'Test User';
$this->reportName = 'Exec Summary';
$this->periodName = 'Q3 2025';
$this->reportsPageUrl = '[URL_WITH_CREDENTIALS] array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – SendReportNotGeneratedMailJobTest.php
|
NULL
|
76279
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
ReportNotGeneratedTest
Run 'ReportNotGeneratedTest'
Debug 'ReportNotGeneratedTest'...
|
PhpStorm
|
faVsco.js – SendReportNotGeneratedMailJobTest.php
|
NULL
|
76280
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
ReportNotGeneratedTest
Run 'ReportNotGeneratedTest'
Debug 'ReportNotGeneratedTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
3
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Exception;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Mail;
use Jiminny\Jobs\AutomatedReports\SendReportNotGeneratedMailJob;
use Jiminny\Mail\Reports\ReportNotGenerated;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
use Tests\TestCase;
class SendReportNotGeneratedMailJobTest extends TestCase
{
private LoggerInterface&MockObject $logger;
private SendReportNotGeneratedMailJob $job;
private string $reportUuid = 'test-uuid';
private string $recipientEmail;
private string $recipientName;
private string $reportName;
private string $periodName;
private string $reportsPageUrl;
protected function setUp(): void
{
parent::setUp();
$this->recipientEmail = '[EMAIL]';
$this->recipientName = 'Test User';
$this->reportName = 'Exec Summary';
$this->periodName = 'Q3 2025';
$this->reportsPageUrl = '[URL_WITH_CREDENTIALS] array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – SendReportNotGeneratedMailJobTest.php
|
NULL
|
76281
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
ReportNotGeneratedTest
Run 'ReportNotGeneratedTest'
Debug 'ReportNotGeneratedTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
<?php
declare(strict_types=1);
namespace Tests\Unit\Mail\Reports;
use Jiminny\Mail\Mailable;
use Jiminny\Mail\Reports\ReportNotGenerated;
use Mockery;
use ReflectionClass;
use Tests\TestCase;
class ReportNotGeneratedTest extends TestCase
{
private string $reportName;
private string $periodName;
private string $reportsPageUrl;
private string $mailSubject;
private ReportNotGenerated $mailable;
protected function setUp(): void
{
parent::setUp();
$this->reportName = 'Exec Summary';
$this->periodName = 'Q3 2025';
$this->reportsPageUrl = '[URL_WITH_CREDENTIALS] array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – ReportNotGeneratedTest.php
|
NULL
|
76282
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
ReportNotGeneratedTest
Run 'ReportNotGeneratedTest'
Debug 'ReportNotGeneratedTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
<?php
declare(strict_types=1);
namespace Tests\Unit\Mail\Reports;
use Jiminny\Mail\Mailable;
use Jiminny\Mail\Reports\ReportNotGenerated;
use Mockery;
use ReflectionClass;
use Tests\TestCase;
class ReportNotGeneratedTest extends TestCase
{
private string $reportName;
private string $periodName;
private string $reportsPageUrl;
private string $mailSubject;
private ReportNotGenerated $mailable;
protected function setUp(): void
{
parent::setUp();
$this->reportName = 'Exec Summary';
$this->periodName = 'Q3 2025';
$this->reportsPageUrl = '[URL_WITH_CREDENTIALS] array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – ReportNotGeneratedTest.php
|
NULL
|
76283
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
ReportNotGeneratedTest
Run 'ReportNotGeneratedTest'
Debug 'ReportNotGeneratedTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
3
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Exception;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Mail;
use Jiminny\Jobs\AutomatedReports\SendReportNotGeneratedMailJob;
use Jiminny\Mail\Reports\ReportNotGenerated;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
use Tests\TestCase;
class SendReportNotGeneratedMailJobTest extends TestCase
{
private LoggerInterface&MockObject $logger;
private SendReportNotGeneratedMailJob $job;
private string $reportUuid = 'test-uuid';
private string $recipientEmail;
private string $recipientName;
private string $reportName;
private string $periodName;
private string $reportsPageUrl;
protected function setUp(): void
{
parent::setUp();
$this->recipientEmail = '[EMAIL]';
$this->recipientName = 'Test User';
$this->reportName = 'Exec Summary';
$this->periodName = 'Q3 2025';
$this->reportsPageUrl = '[URL_WITH_CREDENTIALS] array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – SendReportNotGeneratedMailJobTest.php
|
NULL
|
76284
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
ReportNotGeneratedTest
Run 'ReportNotGeneratedTest'
Debug 'ReportNotGeneratedTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
3
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Exception;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Mail;
use Jiminny\Jobs\AutomatedReports\SendReportNotGeneratedMailJob;
use Jiminny\Mail\Reports\ReportNotGenerated;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
use Tests\TestCase;
class SendReportNotGeneratedMailJobTest extends TestCase
{
private LoggerInterface&MockObject $logger;
private SendReportNotGeneratedMailJob $job;
private string $reportUuid = 'test-uuid';
private string $recipientEmail;
private string $recipientName;
private string $reportName;
private string $periodName;
private string $reportsPageUrl;
protected function setUp(): void
{
parent::setUp();
$this->recipientEmail = '[EMAIL]';
$this->recipientName = 'Test User';
$this->reportName = 'Exec Summary';
$this->periodName = 'Q3 2025';
$this->reportsPageUrl = '[URL_WITH_CREDENTIALS] array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – SendReportNotGeneratedMailJobTest.php
|
NULL
|
76285
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
SendReportNotGeneratedMailJobTes…edFormat
Run 'SendReportNotGeneratedMailJobTest.testUniqueIdReturnsExpectedFormat'
Debug 'SendReportNotGeneratedMailJobTest.testUniqueIdReturnsExpectedFormat'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
3
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Exception;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Mail;
use Jiminny\Jobs\AutomatedReports\SendReportNotGeneratedMailJob;
use Jiminny\Mail\Reports\ReportNotGenerated;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
use Tests\TestCase;
class SendReportNotGeneratedMailJobTest extends TestCase
{
private LoggerInterface&MockObject $logger;
private SendReportNotGeneratedMailJob $job;
private string $reportUuid = 'test-uuid';
private string $recipientEmail;
private string $recipientName;
private string $reportName;
private string $periodName;
private string $reportsPageUrl;
protected function setUp(): void
{
parent::setUp();
$this->recipientEmail = '[EMAIL]';
$this->recipientName = 'Test User';
$this->reportName = 'Exec Summary';
$this->periodName = 'Q3 2025';
$this->reportsPageUrl = '[URL_WITH_CREDENTIALS] array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – SendReportNotGeneratedMailJobTest.php
|
NULL
|
76286
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
SendReportNotGeneratedMailJobTes…edFormat
Run 'SendReportNotGeneratedMailJobTest.testUniqueIdReturnsExpectedFormat'
Debug 'SendReportNotGeneratedMailJobTest.testUniqueIdReturnsExpectedFormat'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
3
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Exception;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Mail;
use Jiminny\Jobs\AutomatedReports\SendReportNotGeneratedMailJob;
use Jiminny\Mail\Reports\ReportNotGenerated;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
use Tests\TestCase;
class SendReportNotGeneratedMailJobTest extends TestCase
{
private LoggerInterface&MockObject $logger;
private SendReportNotGeneratedMailJob $job;
private string $reportUuid = 'test-uuid';
private string $recipientEmail;
private string $recipientName;
private string $reportName;
private string $periodName;
private string $reportsPageUrl;
protected function setUp(): void
{
parent::setUp();
$this->recipientEmail = '[EMAIL]';
$this->recipientName = 'Test User';
$this->reportName = 'Exec Summary';
$this->periodName = 'Q3 2025';
$this->reportsPageUrl = '[URL_WITH_CREDENTIALS] array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – SendReportNotGeneratedMailJobTest.php
|
NULL
|
76287
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
SendReportNotGeneratedMailJobTes…edFormat
Run 'SendReportNotGeneratedMailJobTest.testUniqueIdReturnsExpectedFormat'
Debug 'SendReportNotGeneratedMailJobTest.testUniqueIdReturnsExpectedFormat'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
4
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Exception;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\DomainException;
use Jiminny\Services\Telephony\ClientTokenGenerator;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Models\Team;
use Jiminny\Models\Participant;
use Sentry;
use Twilio\Exceptions\ConfigurationException;
class ClientTokenController extends Controller
{
/**
* @var ClientTokenGenerator
*/
protected $generator;
/**
* Create a new controller instance.
*/
public function __construct(ClientTokenGenerator $generator, Response $response)
{
parent::__construct($response);
$this->generator = $generator;
}
/**
* Rest method for generating a client token for outbound telephony and video.
*
*
* @return array|Response
*/
public function generateToken(Team $team, ?Participant $participant = null)
{
Log::info('[' . __METHOD__ . '] Generating token for team ', ['team_id' => $team->getId()]);
$this->request->validate([
'type' => 'required|in:softphone,ice',
]);
Log::info('[' . __METHOD__ . '] Token type: ', [
'type' => $this->request->input('type'),
'team_id' => $team->getId(),
]);
$tokenType = $this->request->input('type');
try {
switch ($tokenType) {
case 'ice':
try {
return $this->response->withArray($this->generateIce($team, 3600 * 4));
} catch (Exception $exception) {
Sentry::captureException($exception);
return $this->response->withArray([]);
}
case 'softphone':
try {
Log::info('[' . __METHOD__ . '] Generating softphone token for team ', [
'team_id' => $team->getId(),
]);
return $this->response->withArray([
'token' => $this->generateVoice($team, $team->twilio_softphone_sid, 3600 * 4),
]);
} catch (Exception $exception) {
Sentry::captureException($exception);
Log::error('[' . __METHOD__ . '] Error generating softphone token for team ', [
'team_id' => $team->getId(),
'exception' => $exception->getMessage(),
]);
return $this->response->withArray([]);
}
}
Log::info('[' . __METHOD__ . '] Invalid token type requested.', [
'type' => $tokenType,
'team_id' => $team->getId(),
]);
throw new DomainException('Invalid token type requested.');
} catch (Exception $exception) {
Sentry::captureException($exception);
Log::error('[' . __METHOD__ . '] Error generating token for team ', [
'team_id' => $team->getId(),
'exception' => $exception->getMessage(),
]);
return $this->response->errorInternalError(
'We are having difficulty preparing the connection. Please refresh your page and try again.'
);
}
}
private function generateVoice(Team $team, string $sid, int $ttl): string
{
return $this->generator->generateVoice($team, $sid, $ttl);
}
/**
* @throws ConfigurationException
*/
private function generateIce(Team $team, int $ttl): array
{
try {
$items = $this->generator->generateIce($team, $ttl);
return array_map(function ($item) {
$item['urls'] = $item['url'];
unset($item['url']);
return $item;
}, $items);
} catch (ConfigurationException $exception) {
Log::error('[' . __METHOD__ . '] ' . $exception->getMessage());
throw $exception;
}
}
}
Code changed:...
|
PhpStorm
|
faVsco.js – SendReportNotGeneratedMailJobTest.php
|
NULL
|
76288
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
SendReportNotGeneratedMailJobTes…edFormat
Run 'SendReportNotGeneratedMailJobTest.testUniqueIdReturnsExpectedFormat'
Debug 'SendReportNotGeneratedMailJobTest.testUniqueIdReturnsExpectedFormat'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
4
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Exception;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\DomainException;
use Jiminny\Services\Telephony\ClientTokenGenerator;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Models\Team;
use Jiminny\Models\Participant;
use Sentry;
use Twilio\Exceptions\ConfigurationException;
class ClientTokenController extends Controller
{
/**
* @var ClientTokenGenerator
*/
protected $generator;
/**
* Create a new controller instance.
*/
public function __construct(ClientTokenGenerator $generator, Response $response)
{
parent::__construct($response);
$this->generator = $generator;
}
/**
* Rest method for generating a client token for outbound telephony and video.
*
*
* @return array|Response
*/
public function generateToken(Team $team, ?Participant $participant = null)
{
Log::info('[' . __METHOD__ . '] Generating token for team ', ['team_id' => $team->getId()]);
$this->request->validate([
'type' => 'required|in:softphone,ice',
]);
Log::info('[' . __METHOD__ . '] Token type: ', [
'type' => $this->request->input('type'),
'team_id' => $team->getId(),
]);
$tokenType = $this->request->input('type');
try {
switch ($tokenType) {
case 'ice':
try {
return $this->response->withArray($this->generateIce($team, 3600 * 4));
} catch (Exception $exception) {
Sentry::captureException($exception);
return $this->response->withArray([]);
}
case 'softphone':
try {
Log::info('[' . __METHOD__ . '] Generating softphone token for team ', [
'team_id' => $team->getId(),
]);
return $this->response->withArray([
'token' => $this->generateVoice($team, $team->twilio_softphone_sid, 3600 * 4),
]);
} catch (Exception $exception) {
Sentry::captureException($exception);
Log::error('[' . __METHOD__ . '] Error generating softphone token for team ', [
'team_id' => $team->getId(),
'exception' => $exception->getMessage(),
]);
return $this->response->withArray([]);
}
}
Log::info('[' . __METHOD__ . '] Invalid token type requested.', [
'type' => $tokenType,
'team_id' => $team->getId(),
]);
throw new DomainException('Invalid token type requested.');
} catch (Exception $exception) {
Sentry::captureException($exception);
Log::error('[' . __METHOD__ . '] Error generating token for team ', [
'team_id' => $team->getId(),
'exception' => $exception->getMessage(),
]);
return $this->response->errorInternalError(
'We are having difficulty preparing the connection. Please refresh your page and try again.'
);
}
}
private function generateVoice(Team $team, string $sid, int $ttl): string
{
return $this->generator->generateVoice($team, $sid, $ttl);
}
/**
* @throws ConfigurationException
*/
private function generateIce(Team $team, int $ttl): array
{
try {
$items = $this->generator->generateIce($team, $ttl);
return array_map(function ($item) {
$item['urls'] = $item['url'];
unset($item['url']);
return $item;
}, $items);
} catch (ConfigurationException $exception) {
Log::error('[' . __METHOD__ . '] ' . $exception->getMessage());
throw $exception;
}
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
43
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Jiminny\Component\Queue\Constants;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\Contracts\UserContract;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use Illuminate\Support\Facades\Log;
class TrackAutomatedReportGeneratedEvent implements ShouldQueue
{
use InteractsWithQueue;
private const string EVENT_NAME_AUTOMATED_REPORT = 'automated-report-generated';
private const string EVENT_NAME_ASK_JIMINNY_REPORT = 'ask-jiminny-report-generated';
public string $queue = Constants::QUEUE_DELAYABLE;
public function __construct(
private readonly UserPilotClient $userPilotClient,
private readonly AutomatedReportsService $automatedReportsService,
) {
}
public function handle(AutomatedReportGenerated $event): void
{
if (config('services.userpilot.token') === null) {
return;
}
$automatedReport = $event->automatedReport;
$payload = $this->buildPayload($automatedReport);
$eventName = $this->resolveEventName($automatedReport);
$users = $this->resolveUsers($automatedReport);
if (empty($users)) {
Log::warning('[UserPilot] No recipients found for automated report', [
'report_id' => $automatedReport->getId(),
'is_ask_jiminny' => $automatedReport->isAskJiminnyReport(),
]);
return;
}
Log::info('[UserPilot] Sending automated report event', [
'report_id' => $automatedReport->getId(),
'event_name' => $eventName,
'recipient_count' => count($users),
]);
try {
foreach ($users as $user) {
$this->userPilotClient->track($user, $eventName, $payload);
}
} catch (GuzzleException $e) {
Log::error('[UserPilot] Failed to send automated report event', [
'report_id' => $automatedReport->getId(),
'error' => $e->getMessage(),
]);
$this->release(3600);
}
}
/**
* @return array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – SendReportNotGeneratedMailJobTest.php
|
NULL
|
76289
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
SendReportNotGeneratedMailJobTes…edFormat
Run 'SendReportNotGeneratedMailJobTest.testUniqueIdReturnsExpectedFormat'
Debug 'SendReportNotGeneratedMailJobTest.testUniqueIdReturnsExpectedFormat'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
4
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Exception;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\DomainException;
use Jiminny\Services\Telephony\ClientTokenGenerator;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Models\Team;
use Jiminny\Models\Participant;
use Sentry;
use Twilio\Exceptions\ConfigurationException;
class ClientTokenController extends Controller
{
/**
* @var ClientTokenGenerator
*/
protected $generator;
/**
* Create a new controller instance.
*/
public function __construct(ClientTokenGenerator $generator, Response $response)
{
parent::__construct($response);
$this->generator = $generator;
}
/**
* Rest method for generating a client token for outbound telephony and video.
*
*
* @return array|Response
*/
public function generateToken(Team $team, ?Participant $participant = null)
{
Log::info('[' . __METHOD__ . '] Generating token for team ', ['team_id' => $team->getId()]);
$this->request->validate([
'type' => 'required|in:softphone,ice',
]);
Log::info('[' . __METHOD__ . '] Token type: ', [
'type' => $this->request->input('type'),
'team_id' => $team->getId(),
]);
$tokenType = $this->request->input('type');
try {
switch ($tokenType) {
case 'ice':
try {
return $this->response->withArray($this->generateIce($team, 3600 * 4));
} catch (Exception $exception) {
Sentry::captureException($exception);
return $this->response->withArray([]);
}
case 'softphone':
try {
Log::info('[' . __METHOD__ . '] Generating softphone token for team ', [
'team_id' => $team->getId(),
]);
return $this->response->withArray([
'token' => $this->generateVoice($team, $team->twilio_softphone_sid, 3600 * 4),
]);
} catch (Exception $exception) {
Sentry::captureException($exception);
Log::error('[' . __METHOD__ . '] Error generating softphone token for team ', [
'team_id' => $team->getId(),
'exception' => $exception->getMessage(),
]);
return $this->response->withArray([]);
}
}
Log::info('[' . __METHOD__ . '] Invalid token type requested.', [
'type' => $tokenType,
'team_id' => $team->getId(),
]);
throw new DomainException('Invalid token type requested.');
} catch (Exception $exception) {
Sentry::captureException($exception);
Log::error('[' . __METHOD__ . '] Error generating token for team ', [
'team_id' => $team->getId(),
'exception' => $exception->getMessage(),
]);
return $this->response->errorInternalError(
'We are having difficulty preparing the connection. Please refresh your page and try again.'
);
}
}
private function generateVoice(Team $team, string $sid, int $ttl): string
{
return $this->generator->generateVoice($team, $sid, $ttl);
}
/**
* @throws ConfigurationException
*/
private function generateIce(Team $team, int $ttl): array
{
try {
$items = $this->generator->generateIce($team, $ttl);
return array_map(function ($item) {
$item['urls'] = $item['url'];
unset($item['url']);
return $item;
}, $items);
} catch (ConfigurationException $exception) {
Log::error('[' . __METHOD__ . '] ' . $exception->getMessage());
throw $exception;
}
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
43
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Jiminny\Component\Queue\Constants;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\Contracts\UserContract;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use Illuminate\Support\Facades\Log;
class TrackAutomatedReportGeneratedEvent implements ShouldQueue
{
use InteractsWithQueue;
private const string EVENT_NAME_AUTOMATED_REPORT = 'automated-report-generated';
private const string EVENT_NAME_ASK_JIMINNY_REPORT = 'ask-jiminny-report-generated';
public string $queue = Constants::QUEUE_DELAYABLE;
public function __construct(
private readonly UserPilotClient $userPilotClient,
private readonly AutomatedReportsService $automatedReportsService,
) {
}
public function handle(AutomatedReportGenerated $event): void
{
if (config('services.userpilot.token') === null) {
return;
}
$automatedReport = $event->automatedReport;
$payload = $this->buildPayload($automatedReport);
$eventName = $this->resolveEventName($automatedReport);
$users = $this->resolveUsers($automatedReport);
if (empty($users)) {
Log::warning('[UserPilot] No recipients found for automated report', [
'report_id' => $automatedReport->getId(),
'is_ask_jiminny' => $automatedReport->isAskJiminnyReport(),
]);
return;
}
Log::info('[UserPilot] Sending automated report event', [
'report_id' => $automatedReport->getId(),
'event_name' => $eventName,
'recipient_count' => count($users),
]);
try {
foreach ($users as $user) {
$this->userPilotClient->track($user, $eventName, $payload);
}
} catch (GuzzleException $e) {
Log::error('[UserPilot] Failed to send automated report event', [
'report_id' => $automatedReport->getId(),
'error' => $e->getMessage(),
]);
$this->release(3600);
}
}
/**
* @return array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – ClientTokenController.php
|
NULL
|
76290
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
SendReportNotGeneratedMailJobTes…edFormat
Run 'SendReportNotGeneratedMailJobTest.testUniqueIdReturnsExpectedFormat'
Debug 'SendReportNotGeneratedMailJobTest.testUniqueIdReturnsExpectedFormat'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Exception;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Mail;
use Jiminny\Jobs\AutomatedReports\SendReportNotGeneratedMailJob;
use Jiminny\Mail\Reports\ReportNotGenerated;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
use Tests\TestCase;
class SendReportNotGeneratedMailJobTest extends TestCase
{
private LoggerInterface&MockObject $logger;
private SendReportNotGeneratedMailJob $job;
private string $reportUuid = 'test-uuid';
private string $recipientEmail;
private string $recipientName;
private string $reportName;
private string $periodName;
private string $reportsPageUrl;
protected function setUp(): void
{
parent::setUp();
$this->recipientEmail = '[EMAIL]';
$this->recipientName = 'Test User';
$this->reportName = 'Exec Summary';
$this->periodName = 'Q3 2025';
$this->reportsPageUrl = '[URL_WITH_CREDENTIALS] array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – SendReportNotGeneratedMailJobTest.php
|
NULL
|
76291
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
SendReportNotGeneratedMailJobTes…edFormat
Run 'SendReportNotGeneratedMailJobTest.testUniqueIdReturnsExpectedFormat'
Debug 'SendReportNotGeneratedMailJobTest.testUniqueIdReturnsExpectedFormat'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
3
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Exception;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Mail;
use Jiminny\Jobs\AutomatedReports\SendReportNotGeneratedMailJob;
use Jiminny\Mail\Reports\ReportNotGenerated;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
use Tests\TestCase;
class SendReportNotGeneratedMailJobTest extends TestCase
{
private LoggerInterface&MockObject $logger;
private SendReportNotGeneratedMailJob $job;
private string $reportUuid = 'test-uuid';
private string $recipientEmail;
private string $recipientName;
private string $reportName;
private string $periodName;
private string $reportsPageUrl;
protected function setUp(): void
{
parent::setUp();
$this->recipientEmail = '[EMAIL]';
$this->recipientName = 'Test User';
$this->reportName = 'Exec Summary';
$this->periodName = 'Q3 2025';
$this->reportsPageUrl = '[URL_WITH_CREDENTIALS] array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – SendReportNotGeneratedMailJobTest.php
|
NULL
|
76292
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
SendReportNotGeneratedMailJobTes…edFormat
Run 'SendReportNotGeneratedMailJobTest.testUniqueIdReturnsExpectedFormat'
Debug 'SendReportNotGeneratedMailJobTest.testUniqueIdReturnsExpectedFormat'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
4
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Exception;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\DomainException;
use Jiminny\Services\Telephony\ClientTokenGenerator;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Models\Team;
use Jiminny\Models\Participant;
use Sentry;
use Twilio\Exceptions\ConfigurationException;
class ClientTokenController extends Controller
{
/**
* @var ClientTokenGenerator
*/
protected $generator;
/**
* Create a new controller instance.
*/
public function __construct(ClientTokenGenerator $generator, Response $response)
{
parent::__construct($response);
$this->generator = $generator;
}
/**
* Rest method for generating a client token for outbound telephony and video.
*
*
* @return array|Response
*/
public function generateToken(Team $team, ?Participant $participant = null)
{
Log::info('[' . __METHOD__ . '] Generating token for team ', ['team_id' => $team->getId()]);
$this->request->validate([
'type' => 'required|in:softphone,ice',
]);
Log::info('[' . __METHOD__ . '] Token type: ', [
'type' => $this->request->input('type'),
'team_id' => $team->getId(),
]);
$tokenType = $this->request->input('type');
try {
switch ($tokenType) {
case 'ice':
try {
return $this->response->withArray($this->generateIce($team, 3600 * 4));
} catch (Exception $exception) {
Sentry::captureException($exception);
return $this->response->withArray([]);
}
case 'softphone':
try {
Log::info('[' . __METHOD__ . '] Generating softphone token for team ', [
'team_id' => $team->getId(),
]);
return $this->response->withArray([
'token' => $this->generateVoice($team, $team->twilio_softphone_sid, 3600 * 4),
]);
} catch (Exception $exception) {
Sentry::captureException($exception);
Log::error('[' . __METHOD__ . '] Error generating softphone token for team ', [
'team_id' => $team->getId(),
'exception' => $exception->getMessage(),
]);
return $this->response->withArray([]);
}
}
Log::info('[' . __METHOD__ . '] Invalid token type requested.', [
'type' => $tokenType,
'team_id' => $team->getId(),
]);
throw new DomainException('Invalid token type requested.');
} catch (Exception $exception) {
Sentry::captureException($exception);
Log::error('[' . __METHOD__ . '] Error generating token for team ', [
'team_id' => $team->getId(),
'exception' => $exception->getMessage(),
]);
return $this->response->errorInternalError(
'We are having difficulty preparing the connection. Please refresh your page and try again.'
);
}
}
private function generateVoice(Team $team, string $sid, int $ttl): string
{
return $this->generator->generateVoice($team, $sid, $ttl);
}
/**
* @throws ConfigurationException
*/
private function generateIce(Team $team, int $ttl): array
{
try {
$items = $this->generator->generateIce($team, $ttl);
return array_map(function ($item) {
$item['urls'] = $item['url'];
unset($item['url']);
return $item;
}, $items);
} catch (ConfigurationException $exception) {
Log::error('[' . __METHOD__ . '] ' . $exception->getMessage());
throw $exception;
}
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
43
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Jiminny\Component\Queue\Constants;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\Contracts\UserContract;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use Illuminate\Support\Facades\Log;
class TrackAutomatedReportGeneratedEvent implements ShouldQueue
{
use InteractsWithQueue;
private const string EVENT_NAME_AUTOMATED_REPORT = 'automated-report-generated';
private const string EVENT_NAME_ASK_JIMINNY_REPORT = 'ask-jiminny-report-generated';
public string $queue = Constants::QUEUE_DELAYABLE;
public function __construct(
private readonly UserPilotClient $userPilotClient,
private readonly AutomatedReportsService $automatedReportsService,
) {
}
public function handle(AutomatedReportGenerated $event): void
{
if (config('services.userpilot.token') === null) {
return;
}
$automatedReport = $event->automatedReport;
$payload = $this->buildPayload($automatedReport);
$eventName = $this->resolveEventName($automatedReport);
$users = $this->resolveUsers($automatedReport);
if (empty($users)) {
Log::warning('[UserPilot] No recipients found for automated report', [
'report_id' => $automatedReport->getId(),
'is_ask_jiminny' => $automatedReport->isAskJiminnyReport(),
]);
return;
}
Log::info('[UserPilot] Sending automated report event', [
'report_id' => $automatedReport->getId(),
'event_name' => $eventName,
'recipient_count' => count($users),
]);
try {
foreach ($users as $user) {
$this->userPilotClient->track($user, $eventName, $payload);
}
} catch (GuzzleException $e) {
Log::error('[UserPilot] Failed to send automated report event', [
'report_id' => $automatedReport->getId(),
'error' => $e->getMessage(),
]);
$this->release(3600);
}
}
/**
* @return array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – ClientTokenController.php
|
NULL
|
76293
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
SendReportNotGeneratedMailJobTes…edFormat
Run 'SendReportNotGeneratedMailJobTest.testUniqueIdReturnsExpectedFormat'
Debug 'SendReportNotGeneratedMailJobTest.testUniqueIdReturnsExpectedFormat'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
4
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Http\Controllers\API;
use Exception;
use Illuminate\Support\Facades\Log;
use Jiminny\Exceptions\DomainException;
use Jiminny\Services\Telephony\ClientTokenGenerator;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Models\Team;
use Jiminny\Models\Participant;
use Sentry;
use Twilio\Exceptions\ConfigurationException;
class ClientTokenController extends Controller
{
/**
* @var ClientTokenGenerator
*/
protected $generator;
/**
* Create a new controller instance.
*/
public function __construct(ClientTokenGenerator $generator, Response $response)
{
parent::__construct($response);
$this->generator = $generator;
}
/**
* Rest method for generating a client token for outbound telephony and video.
*
*
* @return array|Response
*/
public function generateToken(Team $team, ?Participant $participant = null)
{
Log::info('[' . __METHOD__ . '] Generating token for team ', ['team_id' => $team->getId()]);
$this->request->validate([
'type' => 'required|in:softphone,ice',
]);
Log::info('[' . __METHOD__ . '] Token type: ', [
'type' => $this->request->input('type'),
'team_id' => $team->getId(),
]);
$tokenType = $this->request->input('type');
try {
switch ($tokenType) {
case 'ice':
try {
return $this->response->withArray($this->generateIce($team, 3600 * 4));
} catch (Exception $exception) {
Sentry::captureException($exception);
return $this->response->withArray([]);
}
case 'softphone':
try {
Log::info('[' . __METHOD__ . '] Generating softphone token for team ', [
'team_id' => $team->getId(),
]);
return $this->response->withArray([
'token' => $this->generateVoice($team, $team->twilio_softphone_sid, 3600 * 4),
]);
} catch (Exception $exception) {
Sentry::captureException($exception);
Log::error('[' . __METHOD__ . '] Error generating softphone token for team ', [
'team_id' => $team->getId(),
'exception' => $exception->getMessage(),
]);
return $this->response->withArray([]);
}
}
Log::info('[' . __METHOD__ . '] Invalid token type requested.', [
'type' => $tokenType,
'team_id' => $team->getId(),
]);
throw new DomainException('Invalid token type requested.');
} catch (Exception $exception) {
Sentry::captureException($exception);
Log::error('[' . __METHOD__ . '] Error generating token for team ', [
'team_id' => $team->getId(),
'exception' => $exception->getMessage(),
]);
return $this->response->errorInternalError(
'We are having difficulty preparing the connection. Please refresh your page and try again.'
);
}
}
private function generateVoice(Team $team, string $sid, int $ttl): string
{
return $this->generator->generateVoice($team, $sid, $ttl);
}
/**
* @throws ConfigurationException
*/
private function generateIce(Team $team, int $ttl): array
{
try {
$items = $this->generator->generateIce($team, $ttl);
return array_map(function ($item) {
$item['urls'] = $item['url'];
unset($item['url']);
return $item;
}, $items);
} catch (ConfigurationException $exception) {
Log::error('[' . __METHOD__ . '] ' . $exception->getMessage());
throw $exception;
}
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
43
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Jiminny\Component\Queue\Constants;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\Contracts\UserContract;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use Illuminate\Support\Facades\Log;
class TrackAutomatedReportGeneratedEvent implements ShouldQueue
{
use InteractsWithQueue;
private const string EVENT_NAME_AUTOMATED_REPORT = 'automated-report-generated';
private const string EVENT_NAME_ASK_JIMINNY_REPORT = 'ask-jiminny-report-generated';
public string $queue = Constants::QUEUE_DELAYABLE;
public function __construct(
private readonly UserPilotClient $userPilotClient,
private readonly AutomatedReportsService $automatedReportsService,
) {
}
public function handle(AutomatedReportGenerated $event): void
{
if (config('services.userpilot.token') === null) {
return;
}
$automatedReport = $event->automatedReport;
$payload = $this->buildPayload($automatedReport);
$eventName = $this->resolveEventName($automatedReport);
$users = $this->resolveUsers($automatedReport);
if (empty($users)) {
Log::warning('[UserPilot] No recipients found for automated report', [
'report_id' => $automatedReport->getId(),
'is_ask_jiminny' => $automatedReport->isAskJiminnyReport(),
]);
return;
}
Log::info('[UserPilot] Sending automated report event', [
'report_id' => $automatedReport->getId(),
'event_name' => $eventName,
'recipient_count' => count($users),
]);
try {
foreach ($users as $user) {
$this->userPilotClient->track($user, $eventName, $payload);
}
} catch (GuzzleException $e) {
Log::error('[UserPilot] Failed to send automated report event', [
'report_id' => $automatedReport->getId(),
'error' => $e->getMessage(),
]);
$this->release(3600);
}
}
/**
* @return array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – ClientTokenController.php
|
NULL
|
76294
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
SendReportNotGeneratedMailJobTes…edFormat
Run 'SendReportNotGeneratedMailJobTest.testUniqueIdReturnsExpectedFormat'
Debug 'SendReportNotGeneratedMailJobTest.testUniqueIdReturnsExpectedFormat'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
43
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Jiminny\Component\Queue\Constants;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\Contracts\UserContract;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use Illuminate\Support\Facades\Log;
class TrackAutomatedReportGeneratedEvent implements ShouldQueue
{
use InteractsWithQueue;
private const string EVENT_NAME_AUTOMATED_REPORT = 'automated-report-generated';
private const string EVENT_NAME_ASK_JIMINNY_REPORT = 'ask-jiminny-report-generated';
public string $queue = Constants::QUEUE_DELAYABLE;
public function __construct(
private readonly UserPilotClient $userPilotClient,
private readonly AutomatedReportsService $automatedReportsService,
) {
}
public function handle(AutomatedReportGenerated $event): void
{
if (config('services.userpilot.token') === null) {
return;
}
$automatedReport = $event->automatedReport;
$payload = $this->buildPayload($automatedReport);
$eventName = $this->resolveEventName($automatedReport);
$users = $this->resolveUsers($automatedReport);
if (empty($users)) {
Log::warning('[UserPilot] No recipients found for automated report', [
'report_id' => $automatedReport->getId(),
'is_ask_jiminny' => $automatedReport->isAskJiminnyReport(),
]);
return;
}
Log::info('[UserPilot] Sending automated report event', [
'report_id' => $automatedReport->getId(),
'event_name' => $eventName,
'recipient_count' => count($users),
]);
try {
foreach ($users as $user) {
$this->userPilotClient->track($user, $eventName, $payload);
}
} catch (GuzzleException $e) {
Log::error('[UserPilot] Failed to send automated report event', [
'report_id' => $automatedReport->getId(),
'error' => $e->getMessage(),
]);
$this->release(3600);
}
}
/**
* @return array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – TrackAutomatedReportGeneratedEventTest faVsco.js – TrackAutomatedReportGeneratedEventTest.php...
|
NULL
|
76295
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
SendReportNotGeneratedMailJobTes…edFormat
Run 'SendReportNotGeneratedMailJobTest.testUniqueIdReturnsExpectedFormat'
Debug 'SendReportNotGeneratedMailJobTest.testUniqueIdReturnsExpectedFormat'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
43
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Jiminny\Component\Queue\Constants;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\Contracts\UserContract;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use Illuminate\Support\Facades\Log;
class TrackAutomatedReportGeneratedEvent implements ShouldQueue
{
use InteractsWithQueue;
private const string EVENT_NAME_AUTOMATED_REPORT = 'automated-report-generated';
private const string EVENT_NAME_ASK_JIMINNY_REPORT = 'ask-jiminny-report-generated';
public string $queue = Constants::QUEUE_DELAYABLE;
public function __construct(
private readonly UserPilotClient $userPilotClient,
private readonly AutomatedReportsService $automatedReportsService,
) {
}
public function handle(AutomatedReportGenerated $event): void
{
if (config('services.userpilot.token') === null) {
return;
}
$automatedReport = $event->automatedReport;
$payload = $this->buildPayload($automatedReport);
$eventName = $this->resolveEventName($automatedReport);
$users = $this->resolveUsers($automatedReport);
if (empty($users)) {
Log::warning('[UserPilot] No recipients found for automated report', [
'report_id' => $automatedReport->getId(),
'is_ask_jiminny' => $automatedReport->isAskJiminnyReport(),
]);
return;
}
Log::info('[UserPilot] Sending automated report event', [
'report_id' => $automatedReport->getId(),
'event_name' => $eventName,
'recipient_count' => count($users),
]);
try {
foreach ($users as $user) {
$this->userPilotClient->track($user, $eventName, $payload);
}
} catch (GuzzleException $e) {
Log::error('[UserPilot] Failed to send automated report event', [
'report_id' => $automatedReport->getId(),
'error' => $e->getMessage(),
]);
$this->release(3600);
}
}
/**
* @return array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – TrackAutomatedReportGeneratedEventTest faVsco.js – TrackAutomatedReportGeneratedEventTest.php...
|
NULL
|
76296
|
|
Run
Firefox• 0FileEditViewHistory→BookmarksProfile Run
Firefox• 0FileEditViewHistory→BookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com•Daily - Platform - now100% K78 • Fri 24 Apr 9:46:13|=Pop out this videoNikolay NikolovStefka StoyanovaGalya DimitrovaLukas Kovalik9:46 AM | Daily - Platform• 0:27...
|
PhpStorm
|
Run
|
NULL
|
76297
|
|
Run
DMSActivityMorerireroxToolsHelpcalMistorbookma Run
DMSActivityMorerireroxToolsHelpcalMistorbookmarksJiminny …..vXStarredi• jiminny-x-integrati..8 platform-inner-teamE) Channels# ai-chapter# ai-team# alerts# backend# c-learning-peoplei confusion-clinic# curiosity_labadeal-insichts-dev# engineering# frontend# general# infra-changes# jiminny-bg8 people-with-copilo...8 people-with-zoom-# platform-team# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the Deople of iimi...ProtllesWindow& platform-inner-...& 10MessagesChannel OverviewMoreYesterdayjinnylaop Aor 22nd Added by GitHubNikolay Ivanov 3:24 PMнякой нещо да е настроивал по githubactions. Почна да прави къмити вместо менбез да съм му разрешевал?https:/github.com/lminnv/app/pull/1200//changes/a68f42f210859f838a4fdced451f750627besoioИли нещо аз не разбирам?0AA0e 20 replies Last reply 18...Nikolay Yankov 3:50PMreplied to a uhread: някои нешо ла е насто..лол. ами предлагам маи ла му заораним лапускам към всички ла вилятNikolav Yankov 9.38 AMЩе се забавя за дейлито. Започнете без Мен.Aneliva Angelova 9:43 AMIДобро утро, няма да успея да вляза влейлито. Пествам ньлжовете.Message & platform-inner-team+ Aa I..•) New TabAl reports promotion pages by nik• JY-9712 | Nuges to expire after on8 Jiminnyu Userpilot Logged-activityJY-20157 add not enough activ XPipelines - jiminny/app+ New Tab©github.com/jimjiminny / app 8<> Code87 Pull requests 31( Agents |© Actions•• Wiki © Security and quality 32 ~ Insights 3 Settings@ On April 24 we'll start using GitHub Copilot interaction data for Al model training unless you opt out. Review this update and manage your preferences in your GitHub account settings.JY-20157 add not enough activities notification #12011 •$1 Open LakyLak wants to merge 2 commits into master from JY-20157-AJ-report-not-send-notification@) Conversation o• Commits 2|- Checks 21E Files changed 13A © All commits +Q Filter files...apo/Console/Commands/Reports/AutomatedReportsCommand.ohp@ -61,21 +61,29 @ public function handle(): intv = Console/Commands/Renorts|Snow = Carbon: : now();E AutomatedReportsCommand...v Jobs/AutomatedReportsE RequestGenerateAskJiminnyR...SendReportNotGeneratedMail...v @ Listeners/AutomatedReports/U….E TrackAutomatedReportGener...v # Mail/ReportsS1sMondav = Snow->1SMonday)S1sr1rstDayUtMonth = Snow->day === 1;ScurrentMonth = Snow->month.// Check if the current month is a quarterly month (January, April, July, October)$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [+ ReportNotGenerated.ohp |"1SMonday' => S1SMonday,~ E Services/Kiosk/AutomatedRepo…..AskJiminnyReportActivityServ…'isFirstDay0fMonth' => SisFirstDay0fMonth,'currentMonth' => ScurrentMonth.E AutomatedReportsService.php'isQuarterlyMonth' => SisQuarterlyMonth,~E resources/views/emails/reportsreport-not-generated.blade.php/I Process dailv revortsl• F tests/UnitSthis->processReports(AutomatedReportsService::FREQUENCYDAILY):~ Jobs/AutomatedReportsE ReguestGenerateAsk JiminnvR....v = listeners/AutomatedRenorts/U.₴ TrackAutomatedReportGener..v E Services/Kiosk/AutomatedRepo…..E AskJiminnyReportActivityServ....AutomatedReportsServiceActi…./ Process weekly renorts on Mondavcif (SisMondav) {64 +67 +74 +86 +@40@ Daily - Platform - nowQ Type to search100% C4 8• Fri 24 Apr 9:46:13• Checks pending Code • (Preview) -+384 -52 9000C 0 I 13 viewedSubmit review+10 -2 mane [ Viewed0 ...Snow = Carhon:.nowdSisMondav = Snow->1SMonday)"Sisweekend = $now->isWeekend():SisFirstDay0fMonth = Snow->day === 1;ScurrentMonth = Snow->month.SisManualTrigger = $this->option('report-id') !== null;// Check if the current month is a quarterly month (January, April, July, October)$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);Sthis->loager->info(self::L0G PREFIX . ' Checkina conditions'. [I"isMonday' => SisMonday,'isweekend' => $isWeekend,'isFirstDay0fMonth' => $isFirstDay0fMonth,'currentMonth' => ScurrentMonth.l'isQuarterlyMonth' => SisQuarterlyMonth,/ Process dailv renorts on weekdavs onlv (skio Saturdav/Sundav)...// Manual triggers via --report-id bypass the weekend skip.if (I Sisweekend || SisManualTriager) {Sthis->processReports(AutomatedReportsService::FREQUENCY_DAILY):} else {ISthis->logger->info(self::L0G PREFIX . ' Skipping daily reports on weekend'):/ Process weekly renorts on Mondavslif (SisMonday) {...
|
PhpStorm
|
Run
|
NULL
|
76298
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
TrackAutomatedReportGeneratedEventTest
Run 'TrackAutomatedReportGeneratedEventTest'
Debug 'TrackAutomatedReportGeneratedEventTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
43
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Jiminny\Component\Queue\Constants;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\Contracts\UserContract;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use Illuminate\Support\Facades\Log;
class TrackAutomatedReportGeneratedEvent implements ShouldQueue
{
use InteractsWithQueue;
private const string EVENT_NAME_AUTOMATED_REPORT = 'automated-report-generated';
private const string EVENT_NAME_ASK_JIMINNY_REPORT = 'ask-jiminny-report-generated';
public string $queue = Constants::QUEUE_DELAYABLE;
public function __construct(
private readonly UserPilotClient $userPilotClient,
private readonly AutomatedReportsService $automatedReportsService,
) {
}
public function handle(AutomatedReportGenerated $event): void
{
if (config('services.userpilot.token') === null) {
return;
}
$automatedReport = $event->automatedReport;
$payload = $this->buildPayload($automatedReport);
$eventName = $this->resolveEventName($automatedReport);
$users = $this->resolveUsers($automatedReport);
if (empty($users)) {
Log::warning('[UserPilot] No recipients found for automated report', [
'report_id' => $automatedReport->getId(),
'is_ask_jiminny' => $automatedReport->isAskJiminnyReport(),
]);
return;
}
Log::info('[UserPilot] Sending automated report event', [
'report_id' => $automatedReport->getId(),
'event_name' => $eventName,
'recipient_count' => count($users),
]);
try {
foreach ($users as $user) {
$this->userPilotClient->track($user, $eventName, $payload);
}
} catch (GuzzleException $e) {
Log::error('[UserPilot] Failed to send automated report event', [
'report_id' => $automatedReport->getId(),
'error' => $e->getMessage(),
]);
$this->release(3600);
}
}
/**
* @return array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – TrackAutomatedReportGeneratedEventTest faVsco.js – TrackAutomatedReportGeneratedEventTest.php...
|
NULL
|
76299
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
TrackAutomatedReportGeneratedEventTest
Run 'TrackAutomatedReportGeneratedEventTest'
Debug 'TrackAutomatedReportGeneratedEventTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
43
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Jiminny\Component\Queue\Constants;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\Contracts\UserContract;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use Illuminate\Support\Facades\Log;
class TrackAutomatedReportGeneratedEvent implements ShouldQueue
{
use InteractsWithQueue;
private const string EVENT_NAME_AUTOMATED_REPORT = 'automated-report-generated';
private const string EVENT_NAME_ASK_JIMINNY_REPORT = 'ask-jiminny-report-generated';
public string $queue = Constants::QUEUE_DELAYABLE;
public function __construct(
private readonly UserPilotClient $userPilotClient,
private readonly AutomatedReportsService $automatedReportsService,
) {
}
public function handle(AutomatedReportGenerated $event): void
{
if (config('services.userpilot.token') === null) {
return;
}
$automatedReport = $event->automatedReport;
$payload = $this->buildPayload($automatedReport);
$eventName = $this->resolveEventName($automatedReport);
$users = $this->resolveUsers($automatedReport);
if (empty($users)) {
Log::warning('[UserPilot] No recipients found for automated report', [
'report_id' => $automatedReport->getId(),
'is_ask_jiminny' => $automatedReport->isAskJiminnyReport(),
]);
return;
}
Log::info('[UserPilot] Sending automated report event', [
'report_id' => $automatedReport->getId(),
'event_name' => $eventName,
'recipient_count' => count($users),
]);
try {
foreach ($users as $user) {
$this->userPilotClient->track($user, $eventName, $payload);
}
} catch (GuzzleException $e) {
Log::error('[UserPilot] Failed to send automated report event', [
'report_id' => $automatedReport->getId(),
'error' => $e->getMessage(),
]);
$this->release(3600);
}
}
/**
* @return array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – TrackAutomatedReportGeneratedEventTest faVsco.js – TrackAutomatedReportGeneratedEventTest.php...
|
NULL
|
76300
|
|
Firefox• 0FileEditViewHistory→BookmarksProfilesToo Firefox• 0FileEditViewHistory→BookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com•Daily - Platform - now100% K78 • Fri 24 Apr 9:46:13|=Pop out this videoNikolay NikolovStefka StoyanovaGalya DimitrovaLukas Kovalik9:46 AM | Daily - Platform• 0:27...
|
PhpStorm
|
Commit Changes
|
NULL
|
76301
|
|
DMSActivityMorerireroxToolsHelpcalMistorbookmarksJ DMSActivityMorerireroxToolsHelpcalMistorbookmarksJiminny …..vXStarredi• jiminny-x-integrati..8 platform-inner-teamE) Channels# ai-chapter# ai-team# alerts# backend# c-learning-peoplei confusion-clinic# curiosity_labadeal-insichts-dev# engineering# frontend# general# infra-changes# jiminny-bg8 people-with-copilo...8 people-with-zoom-# platform-team# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the Deople of iimi...ProtllesWindow& platform-inner-...& 10MessagesChannel OverviewMoreYesterdayjinnylaop Aor 22nd Added by GitHubNikolay Ivanov 3:24 PMнякой нещо да е настроивал по githubactions. Почна да прави къмити вместо менбез да съм му разрешевал?https:/github.com/lminnv/app/pull/1200//changes/a68f42f210859f838a4fdced451f750627besoioИли нещо аз не разбирам?0AA0e 20 replies Last reply 18...Nikolay Yankov 3:50PMreplied to a uhread: някои нешо ла е насто..лол. ами предлагам маи ла му заораним лапускам към всички ла вилятNikolav Yankov 9.38 AMЩе се забавя за дейлито. Започнете без Мен.Aneliva Angelova 9:43 AMIДобро утро, няма да успея да вляза влейлито. Пествам ньлжовете.Message & platform-inner-team+ Aa I..•) New TabAl reports promotion pages by nik• JY-9712 | Nuges to expire after on8 Jiminnyu Userpilot Logged-activityJY-20157 add not enough activ XPipelines - jiminny/app+ New Tab©github.com/jimjiminny / app 8<> Code87 Pull requests 31( Agents |© Actions•• Wiki © Security and quality 32 ~ Insights 3 Settings@ On April 24 we'll start using GitHub Copilot interaction data for Al model training unless you opt out. Review this update and manage your preferences in your GitHub account settings.JY-20157 add not enough activities notification #12011 •$1 Open LakyLak wants to merge 2 commits into master from JY-20157-AJ-report-not-send-notification@) Conversation o• Commits 2|- Checks 21E Files changed 13A © All commits +Q Filter files...apo/Console/Commands/Reports/AutomatedReportsCommand.ohp@ -61,21 +61,29 @ public function handle(): intv = Console/Commands/Renorts|Snow = Carbon: : now();E AutomatedReportsCommand...v Jobs/AutomatedReportsE RequestGenerateAskJiminnyR...SendReportNotGeneratedMail...v @ Listeners/AutomatedReports/U….E TrackAutomatedReportGener...v # Mail/ReportsS1sMondav = Snow->1SMonday)S1sr1rstDayUtMonth = Snow->day === 1;ScurrentMonth = Snow->month.// Check if the current month is a quarterly month (January, April, July, October)$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [+ ReportNotGenerated.ohp |"1SMonday' => S1SMonday,~ E Services/Kiosk/AutomatedRepo…..AskJiminnyReportActivityServ…'isFirstDay0fMonth' => SisFirstDay0fMonth,'currentMonth' => ScurrentMonth.E AutomatedReportsService.php'isQuarterlyMonth' => SisQuarterlyMonth,~E resources/views/emails/reportsreport-not-generated.blade.php/I Process dailv revortsl• F tests/UnitSthis->processReports(AutomatedReportsService::FREQUENCYDAILY):~ Jobs/AutomatedReportsE ReguestGenerateAsk JiminnvR....v = listeners/AutomatedRenorts/U.₴ TrackAutomatedReportGener..v E Services/Kiosk/AutomatedRepo…..E AskJiminnyReportActivityServ....AutomatedReportsServiceActi…./ Process weekly renorts on Mondavcif (SisMondav) {64 +67 +74 +86 +@40@ Daily - Platform - nowQ Type to search100% C4 8• Fri 24 Apr 9:46:13• Checks pending Code • (Preview) -+384 -52 9000C 0 I 13 viewedSubmit review+10 -2 mane [ Viewed0 ...Snow = Carhon:.nowdSisMondav = Snow->1SMonday)"Sisweekend = $now->isWeekend():SisFirstDay0fMonth = Snow->day === 1;ScurrentMonth = Snow->month.SisManualTrigger = $this->option('report-id') !== null;// Check if the current month is a quarterly month (January, April, July, October)$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);Sthis->loager->info(self::L0G PREFIX . ' Checkina conditions'. [I"isMonday' => SisMonday,'isweekend' => $isWeekend,'isFirstDay0fMonth' => $isFirstDay0fMonth,'currentMonth' => ScurrentMonth.l'isQuarterlyMonth' => SisQuarterlyMonth,/ Process dailv renorts on weekdavs onlv (skio Saturdav/Sundav)...// Manual triggers via --report-id bypass the weekend skip.if (I Sisweekend || SisManualTriager) {Sthis->processReports(AutomatedReportsService::FREQUENCY_DAILY):} else {ISthis->logger->info(self::L0G PREFIX . ' Skipping daily reports on weekend'):/ Process weekly renorts on Mondavslif (SisMonday) {...
|
PhpStorm
|
Commit Changes
|
NULL
|
76302
|
|
Diff
Changelist:
Changelist:
Changes
Show Diff
Rol Diff
Changelist:
Changelist:
Changes
Show Diff
Rollback...
Refresh
Group By
Expand All
Collapse All
8 files, folder partially checked
app 4 files, folder not checked
config 1 file, folder not checked
tests/Unit 2 files, folder checked
Jobs/AutomatedReports 1 file, folder checked
SendReportNotGeneratedMailJobTest.php, class checked
Mail/Reports 1 file, folder checked
ReportNotGeneratedTest.php, class checked
.env.local not checked
app 4 files, folder not checked
config 1 file, folder not checked
tests/Unit 2 files, folder checked
Jobs/AutomatedReports 1 file, folder checked
SendReportNotGeneratedMailJobTest.php, class checked
Mail/Reports 1 file, folder checked
ReportNotGeneratedTest.php, class checked
Jobs/AutomatedReports 1 file, folder checked
SendReportNotGeneratedMailJobTest.php, class checked
SendReportNotGeneratedMailJobTest.php, class checked
Mail/Reports 1 file, folder checked
ReportNotGeneratedTest.php, class checked
ReportNotGeneratedTest.php, class checked
.env.local not checked
Unversioned Files 8 files not checked
2 added
JY-20157 move user pilot tracking changes to separated PR
Commit Message
Commit Message History
Git
Author:
Author:
Amend commit
Sign-off commit
Create extra commit with file movements
Commit Checks
Update copyright
Reformat code
Rearrange code
Optimize imports
Cleanup
Choose profile
Check malicious dependencies
Run external formatter
Configure
Perform SonarQube for IDE analysis
Find unused view files
Run Git hooks
Advanced Commit Checks
Analyze code
Choose profile
Check TODO
Configure
After Commit
Upload files to:
Upload files to:
<None>
Always use selected server or group of servers
Previous Difference
Next Difference
Jump to Source
Compare Previous File
Compare Next File
Go to Changed File…
Side-by-side viewer
Do not ignore
Highlight words
Collapse Unchanged Fragments
Disable Editing
Settings
Help
Current version
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Exception;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Mail;
use Jiminny\Jobs\AutomatedReports\SendReportNotGeneratedMailJob;
use Jiminny\Mail\Reports\ReportNotGenerated;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
use Tests\TestCase;
class SendReportNotGeneratedMailJobTest extends TestCase
{
private LoggerInterface&MockObject $logger;
private SendReportNotGeneratedMailJob $job;
private string $reportUuid = 'test-uuid';
private string $recipientEmail;
private string $recipientName;
private string $reportName;
private string $periodName;
private string $reportsPageUrl;
protected function setUp(): void
{
parent::setUp();
$this->recipientEmail = '[EMAIL]';
$this->recipientName = 'Test User';
$this->reportName = 'Exec Summary';
$this->periodName = 'Q3 2025';
$this->reportsPageUrl = 'https://app.jiminny.com/reports';
$this->logger = $this->createMock(LoggerInterface::class);
Config::set('app.env', 'testing');
Mail::fake();
$this->job = new SendReportNotGeneratedMailJob(
$this->reportUuid,
$this->recipientEmail,
$this->recipientName,
$this->reportName,
$this->periodName,
$this->reportsPageUrl
);
}
public function testUniqueIdReturnsExpectedFormat(): void
{
$expected = $this->reportUuid . '_not_generated_' . $this->recipientEmail;
$this->assertEquals($expected, $this->job->uniqueId());
}
public function testHandleSendsEmailSuccessfully(): void
{
Config::set('mail.from.address', '[EMAIL]');
Config::set('mail.from.name', 'Jiminny');
Config::set('jiminny.deploy_region', 'us');
Config::set('logos.cdn.header', 'https://cdn.test.com/header.png');
Config::set('logos.cdn.footer', 'https://cdn.test.com/footer.png');
$this->logger->expects($this->once())
->method('info')
->with('[Send Report Not Generated Mail] Email sent', [
'uuid' => $this->reportUuid,
'email' => $this->recipientEmail,
'recipientName' => $this->recipientName,
]);
$this->job->handle($this->logger);
Mail::assertQueued(ReportNotGenerated::class, function ($mail) {
return $mail->hasTo($this->recipientEmail);
});
}
public function testHandleLogsErrorAndRetriesOnException(): void
{
Mail::shouldReceive('mailer')
->with('postmark')
->andReturnSelf()
->shouldReceive('to')
->with($this->recipientEmail)
->andThrow(new Exception('SMTP error'));
$this->logger->expects($this->once())
->method('error')
->with('[Send Report Not Generated Mail] Error sending email', $this->callback(function ($context) {
return $context['uuid'] === $this->reportUuid
&& $context['email'] === $this->recipientEmail
&& $context['error'] === 'SMTP error'
&& isset($context['trace']);
}));
$jobMock = $this->getMockBuilder(SendReportNotGeneratedMailJob::class)
->setConstructorArgs([
$this->reportUuid,
$this->recipientEmail,
$this->recipientName,
$this->reportName,
$this->periodName,
$this->reportsPageUrl,
])
->onlyMethods(['release'])
->getMock();
$jobMock->expects($this->once())
->method('release')
->with(60);
$jobMock->handle($this->logger);
}
public function testHandleFailsJobAfterMaxAttempts(): void
{
Mail::shouldReceive('mailer')
->with('postmark')
->andReturnSelf()
->shouldReceive('to')
->with($this->recipientEmail)
->andThrow(new Exception('SMTP error'));
$this->logger->expects($this->once())
->method('error');
$jobMock = $this->getMockBuilder(SendReportNotGeneratedMailJob::class)
->setConstructorArgs([
$this->reportUuid,
$this->recipientEmail,
$this->recipientName,
$this->reportName,
$this->periodName,
$this->reportsPageUrl,
])
->onlyMethods(['attempts', 'fail'])
->getMock();
$jobMock->expects($this->atLeastOnce())
->method('attempts')
->willReturn(3);
$jobMock->expects($this->once())
->method('fail')
->with($this->isInstanceOf(Exception::class));
$jobMock->handle($this->logger);
}
public function testJobPropertiesAreSetCorrectly(): void
{
$this->assertEquals(3, $this->job->tries);
$this->assertEquals([60, 300, 600], $this->job->backoff);
$this->assertEquals(60, $this->job->timeout);
}
public function testHandleUsesCorrectBackoffForSecondAttempt(): void
{
Mail::shouldReceive('mailer')
->with('postmark')
->andReturnSelf()
->shouldReceive('to')
->andThrow(new Exception('SMTP error'));
$this->logger->expects($this->once())
->method('error');
$jobMock = $this->getMockBuilder(SendReportNotGeneratedMailJob::class)
->setConstructorArgs([
$this->reportUuid,
$this->recipientEmail,
$this->recipientName,
$this->reportName,
$this->periodName,
$this->reportsPageUrl,
])
->onlyMethods(['attempts', 'release'])
->getMock();
$jobMock->expects($this->atLeastOnce())
->method('attempts')
->willReturn(2);
$jobMock->expects($this->once())
->method('release')
->with(300);
$jobMock->handle($this->logger);
}
}
Help
Cancel
Commit
Commit
Commit Changes...
|
PhpStorm
|
Commit Changes
|
NULL
|
76303
|
|
Diff
Changelist:
Changelist:
Changes
Show Diff
Rol Diff
Changelist:
Changelist:
Changes
Show Diff
Rollback...
Refresh
Group By
Expand All
Collapse All
8 files, folder partially checked
app 4 files, folder not checked
config 1 file, folder not checked
tests/Unit 2 files, folder checked
Jobs/AutomatedReports 1 file, folder checked
SendReportNotGeneratedMailJobTest.php, class checked
Mail/Reports 1 file, folder checked
ReportNotGeneratedTest.php, class checked
.env.local not checked
app 4 files, folder not checked
config 1 file, folder not checked
tests/Unit 2 files, folder checked
Jobs/AutomatedReports 1 file, folder checked
SendReportNotGeneratedMailJobTest.php, class checked
Mail/Reports 1 file, folder checked
ReportNotGeneratedTest.php, class checked
Jobs/AutomatedReports 1 file, folder checked
SendReportNotGeneratedMailJobTest.php, class checked
SendReportNotGeneratedMailJobTest.php, class checked
Mail/Reports 1 file, folder checked
ReportNotGeneratedTest.php, class checked
ReportNotGeneratedTest.php, class checked
.env.local not checked
Unversioned Files 8 files not checked
2 added
JY-20157 move user pilot tracking changes to separated PR
Commit Message
Commit Message History
Git
Author:
Author:
Amend commit
Sign-off commit
Create extra commit with file movements
Commit Checks
Update copyright
Reformat code
Rearrange code
Optimize imports
Cleanup
Choose profile
Check malicious dependencies
Run external formatter
Configure
Perform SonarQube for IDE analysis
Find unused view files
Run Git hooks
Advanced Commit Checks
Analyze code
Choose profile
Check TODO
Configure
After Commit
Upload files to:
Upload files to:
<None>
Always use selected server or group of servers
Previous Difference
Next Difference
Jump to Source
Compare Previous File
Compare Next File
Go to Changed File…
Side-by-side viewer
Do not ignore
Highlight words
Collapse Unchanged Fragments
Disable Editing
Settings
Help
Current version
<?php
declare(strict_types=1);
namespace Tests\Unit\Jobs\AutomatedReports;
use Exception;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Mail;
use Jiminny\Jobs\AutomatedReports\SendReportNotGeneratedMailJob;
use Jiminny\Mail\Reports\ReportNotGenerated;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
use Tests\TestCase;
class SendReportNotGeneratedMailJobTest extends TestCase
{
private LoggerInterface&MockObject $logger;
private SendReportNotGeneratedMailJob $job;
private string $reportUuid = 'test-uuid';
private string $recipientEmail;
private string $recipientName;
private string $reportName;
private string $periodName;
private string $reportsPageUrl;
protected function setUp(): void
{
parent::setUp();
$this->recipientEmail = '[EMAIL]';
$this->recipientName = 'Test User';
$this->reportName = 'Exec Summary';
$this->periodName = 'Q3 2025';
$this->reportsPageUrl = 'https://app.jiminny.com/reports';
$this->logger = $this->createMock(LoggerInterface::class);
Config::set('app.env', 'testing');
Mail::fake();
$this->job = new SendReportNotGeneratedMailJob(
$this->reportUuid,
$this->recipientEmail,
$this->recipientName,
$this->reportName,
$this->periodName,
$this->reportsPageUrl
);
}
public function testUniqueIdReturnsExpectedFormat(): void
{
$expected = $this->reportUuid . '_not_generated_' . $this->recipientEmail;
$this->assertEquals($expected, $this->job->uniqueId());
}
public function testHandleSendsEmailSuccessfully(): void
{
Config::set('mail.from.address', '[EMAIL]');
Config::set('mail.from.name', 'Jiminny');
Config::set('jiminny.deploy_region', 'us');
Config::set('logos.cdn.header', 'https://cdn.test.com/header.png');
Config::set('logos.cdn.footer', 'https://cdn.test.com/footer.png');
$this->logger->expects($this->once())
->method('info')
->with('[Send Report Not Generated Mail] Email sent', [
'uuid' => $this->reportUuid,
'email' => $this->recipientEmail,
'recipientName' => $this->recipientName,
]);
$this->job->handle($this->logger);
Mail::assertQueued(ReportNotGenerated::class, function ($mail) {
return $mail->hasTo($this->recipientEmail);
});
}
public function testHandleLogsErrorAndRetriesOnException(): void
{
Mail::shouldReceive('mailer')
->with('postmark')
->andReturnSelf()
->shouldReceive('to')
->with($this->recipientEmail)
->andThrow(new Exception('SMTP error'));
$this->logger->expects($this->once())
->method('error')
->with('[Send Report Not Generated Mail] Error sending email', $this->callback(function ($context) {
return $context['uuid'] === $this->reportUuid
&& $context['email'] === $this->recipientEmail
&& $context['error'] === 'SMTP error'
&& isset($context['trace']);
}));
$jobMock = $this->getMockBuilder(SendReportNotGeneratedMailJob::class)
->setConstructorArgs([
$this->reportUuid,
$this->recipientEmail,
$this->recipientName,
$this->reportName,
$this->periodName,
$this->reportsPageUrl,
])
->onlyMethods(['release'])
->getMock();
$jobMock->expects($this->once())
->method('release')
->with(60);
$jobMock->handle($this->logger);
}
public function testHandleFailsJobAfterMaxAttempts(): void
{
Mail::shouldReceive('mailer')
->with('postmark')
->andReturnSelf()
->shouldReceive('to')
->with($this->recipientEmail)
->andThrow(new Exception('SMTP error'));
$this->logger->expects($this->once())
->method('error');
$jobMock = $this->getMockBuilder(SendReportNotGeneratedMailJob::class)
->setConstructorArgs([
$this->reportUuid,
$this->recipientEmail,
$this->recipientName,
$this->reportName,
$this->periodName,
$this->reportsPageUrl,
])
->onlyMethods(['attempts', 'fail'])
->getMock();
$jobMock->expects($this->atLeastOnce())
->method('attempts')
->willReturn(3);
$jobMock->expects($this->once())
->method('fail')
->with($this->isInstanceOf(Exception::class));
$jobMock->handle($this->logger);
}
public function testJobPropertiesAreSetCorrectly(): void
{
$this->assertEquals(3, $this->job->tries);
$this->assertEquals([60, 300, 600], $this->job->backoff);
$this->assertEquals(60, $this->job->timeout);
}
public function testHandleUsesCorrectBackoffForSecondAttempt(): void
{
Mail::shouldReceive('mailer')
->with('postmark')
->andReturnSelf()
->shouldReceive('to')
->andThrow(new Exception('SMTP error'));
$this->logger->expects($this->once())
->method('error');
$jobMock = $this->getMockBuilder(SendReportNotGeneratedMailJob::class)
->setConstructorArgs([
$this->reportUuid,
$this->recipientEmail,
$this->recipientName,
$this->reportName,
$this->periodName,
$this->reportsPageUrl,
])
->onlyMethods(['attempts', 'release'])
->getMock();
$jobMock->expects($this->atLeastOnce())
->method('attempts')
->willReturn(2);
$jobMock->expects($this->once())
->method('release')
->with(300);
$jobMock->handle($this->logger);
}
}
Help
Cancel
Commit
Commit
Commit Changes...
|
PhpStorm
|
Commit Changes
|
NULL
|
76304
|
|
Commit and Push…
⌥⌘K
Firefox• 0FileEditViewHistory Commit and Push…
⌥⌘K
Firefox• 0FileEditViewHistory→BookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com•Daily - Platform - now100% K78 • Fri 24 Apr 9:46:13|=Pop out this videoNikolay NikolovStefka StoyanovaGalya DimitrovaLukas Kovalik9:46 AM | Daily - Platform• 0:27...
|
PhpStorm
|
|
NULL
|
76305
|
|
Commit and Push…
⌥⌘K
DMSActivityMorerireroxToolsHe Commit and Push…
⌥⌘K
DMSActivityMorerireroxToolsHelpcalMistorbookmarksJiminny …..vXStarredi• jiminny-x-integrati..8 platform-inner-teamE) Channels# ai-chapter# ai-team# alerts# backend# c-learning-peoplei confusion-clinic# curiosity_labadeal-insichts-dev# engineering# frontend# general# infra-changes# jiminny-bg8 people-with-copilo...8 people-with-zoom-# platform-team# platform-tickets# product_launches# random# releases# sofia-office# support# thank-yous# the Deople of iimi...ProtllesWindow& platform-inner-...& 10MessagesChannel OverviewMoreYesterdayjinnylaop Aor 22nd Added by GitHubNikolay Ivanov 3:24 PMнякой нещо да е настроивал по githubactions. Почна да прави къмити вместо менбез да съм му разрешевал?https:/github.com/lminnv/app/pull/1200//changes/a68f42f210859f838a4fdced451f750627besoioИли нещо аз не разбирам?0AA0e 20 replies Last reply 18...Nikolay Yankov 3:50PMreplied to a uhread: някои нешо ла е насто..лол. ами предлагам маи ла му заораним лапускам към всички ла вилятNikolav Yankov 9.38 AMЩе се забавя за дейлито. Започнете без Мен.Aneliva Angelova 9:43 AMIДобро утро, няма да успея да вляза влейлито. Пествам ньлжовете.Message & platform-inner-team+ Aa I..•) New TabAl reports promotion pages by nik• JY-9712 | Nuges to expire after on8 Jiminnyu Userpilot Logged-activityJY-20157 add not enough activ XPipelines - jiminny/app+ New Tab©github.com/jimjiminny / app 8<> Code87 Pull requests 31( Agents |© Actions•• Wiki © Security and quality 32 ~ Insights 3 Settings@ On April 24 we'll start using GitHub Copilot interaction data for Al model training unless you opt out. Review this update and manage your preferences in your GitHub account settings.JY-20157 add not enough activities notification #12011 •$1 Open LakyLak wants to merge 2 commits into master from JY-20157-AJ-report-not-send-notification@) Conversation o• Commits 2|- Checks 21E Files changed 13A © All commits +Q Filter files...apo/Console/Commands/Reports/AutomatedReportsCommand.ohp@ -61,21 +61,29 @ public function handle(): intv = Console/Commands/Renorts|Snow = Carbon: : now();E AutomatedReportsCommand...v Jobs/AutomatedReportsE RequestGenerateAskJiminnyR...SendReportNotGeneratedMail...v @ Listeners/AutomatedReports/U….E TrackAutomatedReportGener...v # Mail/ReportsS1sMondav = Snow->1SMonday)S1sr1rstDayUtMonth = Snow->day === 1;ScurrentMonth = Snow->month.// Check if the current month is a quarterly month (January, April, July, October)$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);$this->logger->info(self::LOG_PREFIX . ' Checking conditions', [+ ReportNotGenerated.ohp |"1SMonday' => S1SMonday,~ E Services/Kiosk/AutomatedRepo…..AskJiminnyReportActivityServ…'isFirstDay0fMonth' => SisFirstDay0fMonth,'currentMonth' => ScurrentMonth.E AutomatedReportsService.php'isQuarterlyMonth' => SisQuarterlyMonth,~E resources/views/emails/reportsreport-not-generated.blade.php/I Process dailv revortsl• F tests/UnitSthis->processReports(AutomatedReportsService::FREQUENCYDAILY):~ Jobs/AutomatedReportsE ReguestGenerateAsk JiminnvR....v = listeners/AutomatedRenorts/U.₴ TrackAutomatedReportGener..v E Services/Kiosk/AutomatedRepo…..E AskJiminnyReportActivityServ....AutomatedReportsServiceActi…./ Process weekly renorts on Mondavcif (SisMondav) {64 +67 +74 +86 +@40@ Daily - Platform - nowQ Type to search100% C4 8• Fri 24 Apr 9:46:13• Checks pending Code • (Preview) -+384 -52 9000C 0 I 13 viewedSubmit review+10 -2 mane [ Viewed0 ...Snow = Carhon:.nowdSisMondav = Snow->1SMonday)"Sisweekend = $now->isWeekend():SisFirstDay0fMonth = Snow->day === 1;ScurrentMonth = Snow->month.SisManualTrigger = $this->option('report-id') !== null;// Check if the current month is a quarterly month (January, April, July, October)$isQuarterlyMonth = in_array($currentMonth, [1, 4, 7, 10], true);Sthis->loager->info(self::L0G PREFIX . ' Checkina conditions'. [I"isMonday' => SisMonday,'isweekend' => $isWeekend,'isFirstDay0fMonth' => $isFirstDay0fMonth,'currentMonth' => ScurrentMonth.l'isQuarterlyMonth' => SisQuarterlyMonth,/ Process dailv renorts on weekdavs onlv (skio Saturdav/Sundav)...// Manual triggers via --report-id bypass the weekend skip.if (I Sisweekend || SisManualTriager) {Sthis->processReports(AutomatedReportsService::FREQUENCY_DAILY):} else {ISthis->logger->info(self::L0G PREFIX . ' Skipping daily reports on weekend'):/ Process weekly renorts on Mondavslif (SisMonday) {...
|
PhpStorm
|
|
NULL
|
76306
|
|
Code Analysis
text/html
text/html
text/html
2 file Code Analysis
text/html
text/html
text/html
2 files contain problems.<br/>No errors and 7 warnings found.<br/>Would you like to review them?
Cancel
Commit and Push
Review Code Analysis...
|
PhpStorm
|
Code Analysis
|
NULL
|
76307
|
|
2 files committed
JY-20157 move user pilot trackin 2 files committed
JY-20157 move user pilot tracking changes to separated PR
text/html
text/html
text/html
Edit Commit Message…
Project: faVsco.js, menu
#12011 on JY-20157-AJ-report-not-send-notification, menu
Start Listening for PHP Debug Connections
TrackAutomatedReportGeneratedEventTest
Run 'TrackAutomatedReportGeneratedEventTest'
Debug 'TrackAutomatedReportGeneratedEventTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
9
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
43
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Jiminny\Component\Queue\Constants;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\Contracts\UserContract;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use Illuminate\Support\Facades\Log;
class TrackAutomatedReportGeneratedEvent implements ShouldQueue
{
use InteractsWithQueue;
private const string EVENT_NAME_AUTOMATED_REPORT = 'automated-report-generated';
private const string EVENT_NAME_ASK_JIMINNY_REPORT = 'ask-jiminny-report-generated';
public string $queue = Constants::QUEUE_DELAYABLE;
public function __construct(
private readonly UserPilotClient $userPilotClient,
private readonly AutomatedReportsService $automatedReportsService,
) {
}
public function handle(AutomatedReportGenerated $event): void
{
if (config('services.userpilot.token') === null) {
return;
}
$automatedReport = $event->automatedReport;
$payload = $this->buildPayload($automatedReport);
$eventName = $this->resolveEventName($automatedReport);
$users = $this->resolveUsers($automatedReport);
if (empty($users)) {
Log::warning('[UserPilot] No recipients found for automated report', [
'report_id' => $automatedReport->getId(),
'is_ask_jiminny' => $automatedReport->isAskJiminnyReport(),
]);
return;
}
Log::info('[UserPilot] Sending automated report event', [
'report_id' => $automatedReport->getId(),
'event_name' => $eventName,
'recipient_count' => count($users),
]);
try {
foreach ($users as $user) {
$this->userPilotClient->track($user, $eventName, $payload);
}
} catch (GuzzleException $e) {
Log::error('[UserPilot] Failed to send automated report event', [
'report_id' => $automatedReport->getId(),
'error' => $e->getMessage(),
]);
$this->release(3600);
}
}
/**
* @return array<UserContract>
*/
private function resolveUsers(AutomatedReport $automatedReport): array
{
if ($automatedReport->isAskJiminnyReport()) {
$creator = $automatedReport->getCreator();
return $creator !== null ? [$creator] : [];
}
return $this->automatedReportsService->getRecipientUserObjects($automatedReport);
}
private function buildPayload(AutomatedReport $automatedReport): array
{
return [
'report_type' => $automatedReport->getType(),
'frequency' => $automatedReport->getFrequency(),
];
}
private function resolveEventName(AutomatedReport $automatedReport): string
{
if ($automatedReport->isAskJiminnyReport()) {
return self::EVENT_NAME_ASK_JIMINNY_REPORT;
}
return self::EVENT_NAME_AUTOMATED_REPORT;
}
}
+++
<?php
declare(strict_types=1);
namespace Tests\Unit\Listeners\AutomatedReports\UserPilot;
use GuzzleHttp\Exception\GuzzleException;
use Jiminny\Events\AutomatedReports\AutomatedReportGenerated;
use Jiminny\Listeners\AutomatedReports\UserPilot\TrackAutomatedReportGeneratedEvent;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\User;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
class TrackAutomatedReportGeneratedEventTest extends TestCase
{
private UserPilotClient&MockObject $userPilotClient;
private AutomatedReportsService&MockObject $automatedReportsService;
protected function setUp(): void
{
parent::setUp();
$this->userPilotClient = $this->createMock(UserPilotClient::class);
$this->automatedReportsService = $this->createMock(AutomatedReportsService::class);
}
private function makeListener(): TrackAutomatedReportGeneratedEvent
{
return new TrackAutomatedReportGeneratedEvent(
$this->userPilotClient,
$this->automatedReportsService,
);
}
private function makeEvent(AutomatedReport $report): AutomatedReportGenerated
{
return new AutomatedReportGenerated($report);
}
public function testHandleSkipsWhenUserPilotTokenIsNull(): void
{
config(['services.userpilot.token' => null]);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->never())->method('isAskJiminnyReport');
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksCreatorForAskJiminnyReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn($creator);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(123);
$this->automatedReportsService->expects($this->never())->method('getRecipientUserObjects');
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$creator,
'ask-jiminny-report-generated',
['report_type' => AutomatedReportsService::TYPE_ASK_JIMINNY, 'frequency' => 'weekly']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleSkipsTrackingWhenAskJiminnyCreatorIsNull(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(true);
$report->expects($this->once())->method('getCreator')->willReturn(null);
$report->expects($this->once())->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->expects($this->once())->method('getFrequency')->willReturn('weekly');
$report->expects($this->once())->method('getId')->willReturn(456);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleTracksAllRecipientsForExecReport(): void
{
config(['services.userpilot.token' => 'NX-token']);
$userOne = $this->createMock(User::class);
$userTwo = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(789);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$userOne, $userTwo]);
$this->userPilotClient->expects($this->exactly(2))
->method('track')
->willReturnCallback(function ($user, $eventName, $payload) use ($userOne, $userTwo) {
$this->assertTrue($user === $userOne || $user === $userTwo);
$this->assertSame('automated-report-generated', $eventName);
$this->assertSame(['report_type' => 'exec_summary', 'frequency' => 'monthly'], $payload);
return null;
});
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotTrackWhenExecReportHasNoRecipients(): void
{
config(['services.userpilot.token' => 'NX-token']);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(3))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('exec_summary');
$report->expects($this->once())->method('getFrequency')->willReturn('monthly');
$report->expects($this->once())->method('getId')->willReturn(101);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->willReturn([]);
$this->userPilotClient->expects($this->never())->method('track');
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
public function testHandleDoesNotThrowOnGuzzleException(): void
{
config(['services.userpilot.token' => 'NX-token']);
$creator = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->method('isAskJiminnyReport')->willReturn(true);
$report->method('getCreator')->willReturn($creator);
$report->method('getType')->willReturn(AutomatedReportsService::TYPE_ASK_JIMINNY);
$report->method('getFrequency')->willReturn('daily');
$report->method('getId')->willReturn(202);
$guzzleException = $this->createMock(GuzzleException::class);
$this->userPilotClient->expects($this->once())
->method('track')
->with($creator, 'ask-jiminny-report-generated', $this->anything())
->willThrowException($guzzleException);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
$this->addToAssertionCount(1);
}
public function testHandleTracksAutomatedReportWithSingleRecipient(): void
{
config(['services.userpilot.token' => 'NX-token']);
$user = $this->createMock(User::class);
$report = $this->createMock(AutomatedReport::class);
$report->expects($this->exactly(2))->method('isAskJiminnyReport')->willReturn(false);
$report->expects($this->once())->method('getType')->willReturn('team_performance');
$report->expects($this->once())->method('getFrequency')->willReturn('daily');
$report->expects($this->once())->method('getId')->willReturn(303);
$this->automatedReportsService->expects($this->once())
->method('getRecipientUserObjects')
->with($report)
->willReturn([$user]);
$this->userPilotClient->expects($this->once())
->method('track')
->with(
$user,
'automated-report-generated',
['report_type' => 'team_performance', 'frequency' => 'daily']
);
$listener = $this->makeListener();
$listener->handle($this->makeEvent($report));
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
PhpStorm
|
faVsco.js – TrackAutomatedReportGeneratedEventTest faVsco.js – TrackAutomatedReportGeneratedEventTest.php...
|
NULL
|
76308
|
|
JY-20157-AJ-report-not-send-notification → origin JY-20157-AJ-report-not-send-notification → origin : JY-20157-AJ-report-not-send-notification
JY-20157 add test coverage
Show Diff
Group By
Jump to Source
Show Details
Expand All
Collapse All
tests/Unit 2 files, folder
Jobs/AutomatedReports 1 file, folder
SendReportNotGeneratedMailJobTest.php, class
Mail/Reports 1 file, folder
ReportNotGeneratedTest.php, class
Jobs/AutomatedReports 1 file, folder
SendReportNotGeneratedMailJobTest.php, class
SendReportNotGeneratedMailJobTest.php, class
Mail/Reports 1 file, folder
ReportNotGeneratedTest.php, class
ReportNotGeneratedTest.php, class
For Commit and Push to non-protected branches, preview commits before push
Help
Push tags:...
|
PhpStorm
|
Push Commits to app
|
NULL
|
76309
|
|
Firefox• 0FileEditViewHistory→BookmarksProfilesToo Firefox• 0FileEditViewHistory→BookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com•Daily - Platform - now100% K78 • Fri 24 Apr 9:46:13|=Pop out this videoNikolay NikolovStefka StoyanovaGalya DimitrovaLukas Kovalik9:46 AM | Daily - Platform• 0:27...
|
PhpStorm
|
faVsco.js – TrackAutomatedReportGeneratedEventTest faVsco.js – TrackAutomatedReportGeneratedEventTest.php...
|
NULL
|
76310
|
|
DXP4800PLUS-B5F8
5 Signs You Have Successfully Hur DXP4800PLUS-B5F8
5 Signs You Have Successfully Hurt a Narcissist; - [EMAIL] - Gmail
(66) Inbox | [EMAIL] | Proton Mail
Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 241,72 € (472,76 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com
Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 241,72 € (472,76 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com
Today's Deals
Today's Deals
architecture - screenpipe docs
architecture - screenpipe docs
[CircleCI] Workflow failed: jiminny / app on JY-20157-AJ-report-not-send-notification - [EMAIL] - Gmail
[CircleCI] Workflow failed: jiminny / app on JY-20157-AJ-report-not-send-notification - [EMAIL] - Gmail
Screenpipe — Archive
Screenpipe — Archive
SQLite Web: archive.db
SQLite Web: archive.db
SQLite Web: db.sqlite
SQLite Web: db.sqlite
Claude Platform
Claude Platform
rescue time detailed overview - Google Search
rescue time detailed overview - Google Search
Hey @louis030195 Ill check during my - screenpipe.com
Hey @louis030195 Ill check during my - screenpipe.com
GitHub - screenpipe/screenpipe: Run agents that work for you based on what you do. AI finally knows what you are doing · GitHub
GitHub - screenpipe/screenpipe: Run agents that work for you based on what you do. AI finally knows what you are doing · GitHub
Gong Pricing in 2026: Costs, Plans & Is It Worth It?
Gong Pricing in 2026: Costs, Plans & Is It Worth It?
(132) Damien Rice & Lisa Hannigan - 9 Crimes - 2006-11-17 - YouTube
Mute tab
(132) Damien Rice & Lisa Hannigan - 9 Crimes - 2006-11-17 - YouTube
New Tab
New Tab
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
22°
C
New York City
Open menu
Do you want to see the weather for your location?
Do you want to see the weather for your location?
Not now
Not now
Yes
Yes
Mozilla Firefox
Search with Google or enter address
Search with Google or enter address
Browse faster with Firefox
Browse faster with Firefox
Firefox helps pages load faster and tabs feel smoother to keep up with the way you browse.
Find out how
Find out how
Not now
Not now
Inbox (3) - [EMAIL] - Gmail
Inbox (3) - [EMAIL] - Gmail
Open context menu for Inbox (3) - [EMAIL] - Gmail
Screenpipe — Archive
Screenpipe — Archive
Open context menu for Screenpipe — Archive
(132) YouTube
(132) YouTube
Open context menu for (132) YouTube
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Open context menu for DXP4800PLUS-B5F8
Screenpipe — Archive
Screenpipe — Archive
Open context menu for Screenpipe — Archive
Shameless • HBO Max
Shameless • HBO Max
Open context menu for Shameless • HBO Max
Denník N - Nezávislý denník
Denník N - Nezávislý denník
Open context menu for Denník N - Nezávislý denník
Твърд диск, Western Digital Red 6TB Plus ( 3.5", 256MB, 5400
Твърд диск, Western Digital Red 6TB Plus ( 3.5", 256MB, 5400
Open context menu for Твърд диск, Western Digital Red 6TB Plus ( 3.5", 256MB, 5400
Customize
Customize
http://[IP_ADDRESS]:8766...
|
Firefox
|
Personal — Mozilla Firefox
|
NULL
|
76311
|
|
DXP4800PLUS-B5F8
5 Signs You Have Successfully Hur DXP4800PLUS-B5F8
5 Signs You Have Successfully Hurt a Narcissist; - [EMAIL] - Gmail
(66) Inbox | [EMAIL] | Proton Mail
Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 241,72 € (472,76 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com
Western Digital Red Plus 3.5 6TB 5400rpm 256MB SATA3 (WD60EFPX) от 241,72 € (472,76 лв.) Вътрешен хард диск Western Digital - Pazaruvaj.com
Today's Deals
Today's Deals
architecture - screenpipe docs
architecture - screenpipe docs
[CircleCI] Workflow failed: jiminny / app on JY-20157-AJ-report-not-send-notification - [EMAIL] - Gmail
[CircleCI] Workflow failed: jiminny / app on JY-20157-AJ-report-not-send-notification - [EMAIL] - Gmail
Screenpipe — Archive
Screenpipe — Archive
SQLite Web: archive.db
SQLite Web: archive.db
SQLite Web: db.sqlite
SQLite Web: db.sqlite
Claude Platform
Claude Platform
rescue time detailed overview - Google Search
rescue time detailed overview - Google Search
Hey @louis030195 Ill check during my - screenpipe.com
Hey @louis030195 Ill check during my - screenpipe.com
GitHub - screenpipe/screenpipe: Run agents that work for you based on what you do. AI finally knows what you are doing · GitHub
GitHub - screenpipe/screenpipe: Run agents that work for you based on what you do. AI finally knows what you are doing · GitHub
Gong Pricing in 2026: Costs, Plans & Is It Worth It?
Gong Pricing in 2026: Costs, Plans & Is It Worth It?
(132) Damien Rice & Lisa Hannigan - 9 Crimes - 2006-11-17 - YouTube
Mute tab
(132) Damien Rice & Lisa Hannigan - 9 Crimes - 2006-11-17 - YouTube
New Tab
New Tab
Close tab
New Tab
Customize sidebar
Open Google Gemini (⌃X)
Open history (⇧⌘H)
Open bookmarks (⌘B)
Bitwarden
22°
C
New York City
Open menu
Do you want to see the weather for your location?
Do you want to see the weather for your location?
Not now
Not now
Yes
Yes
Mozilla Firefox
Search with Google or enter address
Search with Google or enter address
Browse faster with Firefox
Browse faster with Firefox
Firefox helps pages load faster and tabs feel smoother to keep up with the way you browse.
Find out how
Find out how
Not now
Not now
Inbox (3) - [EMAIL] - Gmail
Inbox (3) - [EMAIL] - Gmail
Open context menu for Inbox (3) - [EMAIL] - Gmail
Screenpipe — Archive
Screenpipe — Archive
Open context menu for Screenpipe — Archive
(132) YouTube
(132) YouTube
Open context menu for (132) YouTube
DXP4800PLUS-B5F8
DXP4800PLUS-B5F8
Open context menu for DXP4800PLUS-B5F8
Screenpipe — Archive
Screenpipe — Archive
Open context menu for Screenpipe — Archive
Shameless • HBO Max
Shameless • HBO Max
Open context menu for Shameless • HBO Max
Denník N - Nezávislý denník
Denník N - Nezávislý denník
Open context menu for Denník N - Nezávislý denník
Твърд диск, Western Digital Red 6TB Plus ( 3.5", 256MB, 5400
Твърд диск, Western Digital Red 6TB Plus ( 3.5", 256MB, 5400
Open context menu for Твърд диск, Western Digital Red 6TB Plus ( 3.5", 256MB, 5400
Customize
Customize
http://[IP_ADDRESS]:8766...
|
Firefox
|
Personal — Mozilla Firefox
|
NULL
|
76312
|