Compare commits
2 commits
de42bdca38
...
d17d98a5ec
| Author | SHA1 | Date | |
|---|---|---|---|
| d17d98a5ec | |||
| e58badf70e |
5 changed files with 62 additions and 5 deletions
|
|
@ -17,7 +17,7 @@ public function definition(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'name' => $this->faker->words(3, true),
|
'name' => $this->faker->words(3, true),
|
||||||
'url' => $this->faker->url(),
|
'url' => $this->faker->unique()->url(),
|
||||||
'type' => $this->faker->randomElement(['website', 'rss']),
|
'type' => $this->faker->randomElement(['website', 'rss']),
|
||||||
'provider' => $this->faker->randomElement(['vrt', 'belga']),
|
'provider' => $this->faker->randomElement(['vrt', 'belga']),
|
||||||
'language_id' => null,
|
'language_id' => null,
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,9 @@ class LanguageFactory extends Factory
|
||||||
public function definition(): array
|
public function definition(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'short_code' => $this->faker->unique()->languageCode(),
|
// Not a real language code: tests hardcode 'en', 'fr', 'nl' and
|
||||||
|
// others, and faker's pool would collide with them.
|
||||||
|
'short_code' => 'x-'.$this->faker->unique()->numerify('####'),
|
||||||
'name' => $this->faker->unique()->word(),
|
'name' => $this->faker->unique()->word(),
|
||||||
'native_name' => $this->faker->optional()->word(),
|
'native_name' => $this->faker->optional()->word(),
|
||||||
'is_active' => true,
|
'is_active' => true,
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ public function definition(): array
|
||||||
return [
|
return [
|
||||||
'platform' => PlatformEnum::LEMMY,
|
'platform' => PlatformEnum::LEMMY,
|
||||||
'instance_url' => 'https://lemmy.'.$this->faker->domainName(),
|
'instance_url' => 'https://lemmy.'.$this->faker->domainName(),
|
||||||
'username' => $this->faker->userName(),
|
'username' => $this->faker->unique()->userName(),
|
||||||
'password' => 'test-password',
|
'password' => 'test-password',
|
||||||
'settings' => [],
|
'settings' => [],
|
||||||
'is_active' => true,
|
'is_active' => true,
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ public function definition(): array
|
||||||
return [
|
return [
|
||||||
'platform' => 'lemmy',
|
'platform' => 'lemmy',
|
||||||
'name' => $this->faker->words(2, true),
|
'name' => $this->faker->words(2, true),
|
||||||
'url' => $this->faker->url(),
|
'url' => $this->faker->unique()->url(),
|
||||||
'is_active' => true,
|
'is_active' => true,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
@ -34,7 +34,7 @@ public function lemmy(): static
|
||||||
return $this->state(fn (array $attributes) => [
|
return $this->state(fn (array $attributes) => [
|
||||||
'platform' => 'lemmy',
|
'platform' => 'lemmy',
|
||||||
'name' => 'Lemmy '.$this->faker->word(),
|
'name' => 'Lemmy '.$this->faker->word(),
|
||||||
'url' => 'https://lemmy.'.$this->faker->domainName(),
|
'url' => 'https://lemmy.'.$this->faker->unique()->domainName(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
use Illuminate\Foundation\Queue\Queueable;
|
use Illuminate\Foundation\Queue\Queueable;
|
||||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
use Mockery;
|
use Mockery;
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
|
@ -35,6 +36,11 @@ class PublishNextArticleJobTest extends TestCase
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
|
// The daily cap counts from startOfDay, so tests placing publications a
|
||||||
|
// couple of hours back land on the previous day when run after midnight.
|
||||||
|
Carbon::setTestNow('2026-07-15 12:00:00');
|
||||||
|
|
||||||
$this->notificationService = new NotificationService;
|
$this->notificationService = new NotificationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -319,6 +325,54 @@ public function test_daily_cap_counts_each_channel_publication_separately(): voi
|
||||||
$this->assertTrue(true);
|
$this->assertTrue(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_daily_cap_counts_from_midnight_not_a_rolling_window(): void
|
||||||
|
{
|
||||||
|
Carbon::setTestNow('2026-07-15 01:00:00');
|
||||||
|
|
||||||
|
$this->createApprovedRouteArticle();
|
||||||
|
|
||||||
|
ArticlePublication::factory()->count(3)->create(['published_at' => Carbon::parse('2026-07-14 23:00:00')]);
|
||||||
|
Setting::setArticlePublishingInterval(0);
|
||||||
|
Setting::setDailyPublishCap(3);
|
||||||
|
|
||||||
|
$articleFetcherMock = Mockery::mock(FetchArticleDataAction::class);
|
||||||
|
$articleFetcherMock->shouldReceive('execute')
|
||||||
|
->once()
|
||||||
|
->andReturn(['title' => 'Test Article', 'description' => 'Test description']);
|
||||||
|
|
||||||
|
$publishingServiceMock = Mockery::mock(ArticlePublishingService::class);
|
||||||
|
$publishingServiceMock->shouldReceive('publishRouteArticle')
|
||||||
|
->once()
|
||||||
|
->andReturn(PublishOutcome::published($this->makePublication()));
|
||||||
|
|
||||||
|
$job = new PublishNextArticleJob;
|
||||||
|
$job->handle(new PublishRouteArticleAction($articleFetcherMock, $publishingServiceMock, $this->notificationService));
|
||||||
|
|
||||||
|
$this->assertTrue(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_daily_cap_counts_a_publication_just_after_midnight(): void
|
||||||
|
{
|
||||||
|
Carbon::setTestNow('2026-07-15 01:00:00');
|
||||||
|
|
||||||
|
$this->createApprovedRouteArticle();
|
||||||
|
|
||||||
|
ArticlePublication::factory()->count(3)->create(['published_at' => Carbon::parse('2026-07-15 00:30:00')]);
|
||||||
|
Setting::setArticlePublishingInterval(0);
|
||||||
|
Setting::setDailyPublishCap(3);
|
||||||
|
|
||||||
|
$articleFetcherMock = Mockery::mock(FetchArticleDataAction::class);
|
||||||
|
$publishingServiceMock = Mockery::mock(ArticlePublishingService::class);
|
||||||
|
|
||||||
|
$articleFetcherMock->shouldNotReceive('execute');
|
||||||
|
$publishingServiceMock->shouldNotReceive('publishRouteArticle');
|
||||||
|
|
||||||
|
$job = new PublishNextArticleJob;
|
||||||
|
$job->handle(new PublishRouteArticleAction($articleFetcherMock, $publishingServiceMock, $this->notificationService));
|
||||||
|
|
||||||
|
$this->assertTrue(true);
|
||||||
|
}
|
||||||
|
|
||||||
public function test_handle_ignores_publications_from_previous_days(): void
|
public function test_handle_ignores_publications_from_previous_days(): void
|
||||||
{
|
{
|
||||||
$this->createApprovedRouteArticle();
|
$this->createApprovedRouteArticle();
|
||||||
|
|
@ -572,6 +626,7 @@ public function test_job_can_be_serialized(): void
|
||||||
|
|
||||||
protected function tearDown(): void
|
protected function tearDown(): void
|
||||||
{
|
{
|
||||||
|
Carbon::setTestNow();
|
||||||
Mockery::close();
|
Mockery::close();
|
||||||
parent::tearDown();
|
parent::tearDown();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue