Skip to content

Commit 5d686ec

Browse files
committed
test: add unit tests for async queue components
Add comprehensive unit tests for async import queue infrastructure ensuring message handling, job tracking, and task scheduling work correctly. Test coverage: - ImportTranslationsMessage: Message creation and payload validation - ImportTranslationsMessageHandler: Async processing logic - ImportJobStatusRepository: Job tracking CRUD operations - ProcessMessengerQueueTask: Scheduler task execution - ProcessMessengerQueueTaskAdditionalFieldProvider: UI field generation Tests validate: - Message serialization/deserialization - Job status lifecycle management - Error handling in async handlers - Scheduler task configuration Total: 52 unit tests ensuring queue reliability.
1 parent 8fa8526 commit 5d686ec

File tree

7 files changed

+1033
-0
lines changed

7 files changed

+1033
-0
lines changed
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
<?php
2+
3+
/**
4+
* This file is part of the package netresearch/nr-textdb.
5+
*
6+
* For the full copyright and license information, please read the
7+
* LICENSE file that was distributed with this source code.
8+
*/
9+
10+
declare(strict_types=1);
11+
12+
namespace Netresearch\NrTextdb\Tests\Functional\Domain\Repository;
13+
14+
use Netresearch\NrTextdb\Domain\Repository\ImportJobStatusRepository;
15+
use PHPUnit\Framework\Attributes\CoversClass;
16+
use PHPUnit\Framework\Attributes\Test;
17+
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
18+
19+
/**
20+
* Functional test case for ImportJobStatusRepository.
21+
*/
22+
#[CoversClass(ImportJobStatusRepository::class)]
23+
final class ImportJobStatusRepositoryTest extends FunctionalTestCase
24+
{
25+
protected array $coreExtensionsToLoad = [
26+
'extensionmanager',
27+
'scheduler',
28+
];
29+
30+
protected array $testExtensionsToLoad = [
31+
'typo3conf/ext/nr_textdb',
32+
];
33+
34+
private ImportJobStatusRepository $subject;
35+
36+
protected function setUp(): void
37+
{
38+
parent::setUp();
39+
40+
$this->subject = new ImportJobStatusRepository();
41+
}
42+
43+
#[Test]
44+
public function createJobInsertsRecordInDatabase(): void
45+
{
46+
$jobId = 'test-job-' . time();
47+
$filePath = '/tmp/test.xlf';
48+
$originalFilename = 'test.xlf';
49+
$fileSize = 2048;
50+
$backendUserId = 1;
51+
52+
$uid = $this->subject->create($jobId, $filePath, $originalFilename, $fileSize, $backendUserId);
53+
54+
self::assertGreaterThan(0, $uid);
55+
56+
$job = $this->subject->findByJobId($jobId);
57+
self::assertIsArray($job);
58+
self::assertSame($jobId, $job['job_id']);
59+
self::assertSame($filePath, $job['file_path']);
60+
self::assertSame($originalFilename, $job['original_filename']);
61+
self::assertSame($fileSize, $job['file_size']);
62+
self::assertSame($backendUserId, $job['backend_user_id']);
63+
self::assertSame('pending', $job['status']);
64+
self::assertSame(0, $job['imported']);
65+
self::assertSame(0, $job['updated']);
66+
}
67+
68+
#[Test]
69+
public function updateStatusModifiesExistingRecord(): void
70+
{
71+
$jobId = 'test-job-' . time();
72+
$this->subject->create($jobId, '/tmp/test.xlf', 'test.xlf', 1024, 1);
73+
74+
$this->subject->updateStatus($jobId, 'processing');
75+
76+
$job = $this->subject->findByJobId($jobId);
77+
self::assertIsArray($job);
78+
self::assertSame('processing', $job['status']);
79+
self::assertNull($job['errors']);
80+
81+
$this->subject->updateStatus($jobId, 'completed', 'Some warning');
82+
83+
$job = $this->subject->findByJobId($jobId);
84+
self::assertIsArray($job);
85+
self::assertSame('completed', $job['status']);
86+
self::assertSame('Some warning', $job['errors']);
87+
}
88+
89+
#[Test]
90+
public function updateProgressModifiesCounters(): void
91+
{
92+
$jobId = 'test-job-' . time();
93+
$this->subject->create($jobId, '/tmp/test.xlf', 'test.xlf', 1024, 1);
94+
95+
$this->subject->updateProgress($jobId, 150, 75);
96+
97+
$job = $this->subject->findByJobId($jobId);
98+
self::assertIsArray($job);
99+
self::assertSame(150, $job['imported']);
100+
self::assertSame(75, $job['updated']);
101+
}
102+
103+
#[Test]
104+
public function findByJobIdReturnsNullForNonExistentJob(): void
105+
{
106+
$result = $this->subject->findByJobId('non-existent-job');
107+
108+
self::assertNull($result);
109+
}
110+
111+
#[Test]
112+
public function getStatusReturnsJobData(): void
113+
{
114+
$jobId = 'test-job-' . time();
115+
$this->subject->create($jobId, '/tmp/test.xlf', 'test.xlf', 1024, 1);
116+
$this->subject->updateStatus($jobId, 'processing');
117+
$this->subject->updateProgress($jobId, 100, 50);
118+
119+
$status = $this->subject->getStatus($jobId);
120+
121+
self::assertIsArray($status);
122+
self::assertSame($jobId, $status['jobId']);
123+
self::assertSame('processing', $status['status']);
124+
self::assertSame(100, $status['imported']);
125+
self::assertSame(50, $status['updated']);
126+
}
127+
128+
#[Test]
129+
public function getStatusReturnsNullForNonExistentJob(): void
130+
{
131+
$result = $this->subject->getStatus('non-existent-job');
132+
133+
self::assertNull($result);
134+
}
135+
136+
#[Test]
137+
public function deleteOldJobsRemovesExpiredRecords(): void
138+
{
139+
// Create job older than 7 days (simulate old timestamp)
140+
$oldJobId = 'old-job-' . time();
141+
$uid = $this->subject->create($oldJobId, '/tmp/old.xlf', 'old.xlf', 1024, 1);
142+
143+
// Mark as completed and manually update the completed_at timestamp to simulate old record
144+
$this->subject->updateStatus($oldJobId, 'completed');
145+
$this->getConnectionPool()
146+
->getConnectionForTable('tx_nrtextdb_import_job_status')
147+
->update(
148+
'tx_nrtextdb_import_job_status',
149+
['completed_at' => time() - (8 * 24 * 60 * 60)], // 8 days ago
150+
['uid' => $uid]
151+
);
152+
153+
// Create a recent job
154+
$recentJobId = 'recent-job-' . time();
155+
$this->subject->create($recentJobId, '/tmp/recent.xlf', 'recent.xlf', 1024, 1);
156+
157+
$deletedCount = $this->subject->deleteOldJobs(7);
158+
159+
self::assertSame(1, $deletedCount);
160+
161+
// Old job should be deleted
162+
self::assertNull($this->subject->findByJobId($oldJobId));
163+
164+
// Recent job should still exist
165+
self::assertIsArray($this->subject->findByJobId($recentJobId));
166+
}
167+
168+
#[Test]
169+
public function multipleJobsCanBeCreatedAndQueried(): void
170+
{
171+
$jobId1 = 'test-job-1-' . time();
172+
$jobId2 = 'test-job-2-' . time();
173+
174+
$this->subject->create($jobId1, '/tmp/test1.xlf', 'test1.xlf', 1024, 1);
175+
$this->subject->create($jobId2, '/tmp/test2.xlf', 'test2.xlf', 2048, 1);
176+
177+
$this->subject->updateStatus($jobId1, 'completed');
178+
$this->subject->updateStatus($jobId2, 'processing');
179+
180+
$job1 = $this->subject->findByJobId($jobId1);
181+
$job2 = $this->subject->findByJobId($jobId2);
182+
183+
self::assertIsArray($job1);
184+
self::assertIsArray($job2);
185+
self::assertSame('completed', $job1['status']);
186+
self::assertSame('processing', $job2['status']);
187+
self::assertSame(1024, $job1['file_size']);
188+
self::assertSame(2048, $job2['file_size']);
189+
}
190+
}

0 commit comments

Comments
 (0)