Release v1.1.0 #79
6 changed files with 77 additions and 23 deletions
28
.env.testing
Normal file
28
.env.testing
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
APP_NAME=Laravel
|
||||||
|
APP_ENV=testing
|
||||||
|
APP_KEY=base64:5VABFQKtzx6flRFn7rQUQYI/G8xLnkUSYPVaYz2s/4M=
|
||||||
|
APP_DEBUG=true
|
||||||
|
APP_URL=http://localhost
|
||||||
|
|
||||||
|
APP_MAINTENANCE_DRIVER=file
|
||||||
|
|
||||||
|
BCRYPT_ROUNDS=4
|
||||||
|
|
||||||
|
LOG_CHANNEL=stack
|
||||||
|
LOG_STACK=single
|
||||||
|
|
||||||
|
DB_CONNECTION=sqlite
|
||||||
|
DB_DATABASE=:memory:
|
||||||
|
|
||||||
|
SESSION_DRIVER=array
|
||||||
|
|
||||||
|
BROADCAST_CONNECTION=log
|
||||||
|
FILESYSTEM_DISK=local
|
||||||
|
QUEUE_CONNECTION=sync
|
||||||
|
|
||||||
|
CACHE_STORE=array
|
||||||
|
|
||||||
|
MAIL_MAILER=array
|
||||||
|
|
||||||
|
PULSE_ENABLED=false
|
||||||
|
TELESCOPE_ENABLED=false
|
||||||
|
|
@ -61,7 +61,6 @@ public function casts(): array
|
||||||
|
|
||||||
public function isValid(): bool
|
public function isValid(): bool
|
||||||
{
|
{
|
||||||
// Article is valid if it passed validation and wasn't rejected
|
|
||||||
return $this->validated_at !== null && ! $this->isRejected();
|
return $this->validated_at !== null && ! $this->isRejected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
24
phpunit.xml
24
phpunit.xml
|
|
@ -18,17 +18,17 @@
|
||||||
</include>
|
</include>
|
||||||
</source>
|
</source>
|
||||||
<php>
|
<php>
|
||||||
<env name="APP_ENV" value="testing"/>
|
<env name="APP_ENV" value="testing" force="true"/>
|
||||||
<env name="APP_KEY" value="base64:5VABFQKtzx6flRFn7rQUQYI/G8xLnkUSYPVaYz2s/4M="/>
|
<server name="APP_ENV" value="testing" force="true"/>
|
||||||
<env name="APP_MAINTENANCE_DRIVER" value="file"/>
|
<server name="APP_MAINTENANCE_DRIVER" value="file" force="true"/>
|
||||||
<env name="BCRYPT_ROUNDS" value="4"/>
|
<server name="BCRYPT_ROUNDS" value="4" force="true"/>
|
||||||
<env name="CACHE_STORE" value="array"/>
|
<server name="CACHE_STORE" value="array" force="true"/>
|
||||||
<env name="DB_CONNECTION" value="sqlite"/>
|
<server name="DB_CONNECTION" value="sqlite" force="true"/>
|
||||||
<env name="DB_DATABASE" value=":memory:"/>
|
<server name="DB_DATABASE" value=":memory:" force="true"/>
|
||||||
<env name="MAIL_MAILER" value="array"/>
|
<server name="MAIL_MAILER" value="array" force="true"/>
|
||||||
<env name="PULSE_ENABLED" value="false"/>
|
<server name="PULSE_ENABLED" value="false" force="true"/>
|
||||||
<env name="QUEUE_CONNECTION" value="sync"/>
|
<server name="QUEUE_CONNECTION" value="sync" force="true"/>
|
||||||
<env name="SESSION_DRIVER" value="array"/>
|
<server name="SESSION_DRIVER" value="array" force="true"/>
|
||||||
<env name="TELESCOPE_ENABLED" value="false"/>
|
<server name="TELESCOPE_ENABLED" value="false" force="true"/>
|
||||||
</php>
|
</php>
|
||||||
</phpunit>
|
</phpunit>
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
use App\Models\Article;
|
use App\Models\Article;
|
||||||
use App\Models\Feed;
|
use App\Models\Feed;
|
||||||
use App\Models\Log;
|
use App\Models\Log;
|
||||||
|
use App\Models\Setting;
|
||||||
use App\Models\PlatformChannel;
|
use App\Models\PlatformChannel;
|
||||||
use App\Services\Log\LogSaver;
|
use App\Services\Log\LogSaver;
|
||||||
use App\Services\Article\ArticleFetcher;
|
use App\Services\Article\ArticleFetcher;
|
||||||
|
|
@ -175,7 +176,10 @@ public function test_exception_logged_event_is_dispatched(): void
|
||||||
|
|
||||||
public function test_validate_article_listener_processes_new_article(): void
|
public function test_validate_article_listener_processes_new_article(): void
|
||||||
{
|
{
|
||||||
Event::fake([ArticleReadyToPublish::class]);
|
Event::fake([ArticleApproved::class]);
|
||||||
|
|
||||||
|
// Disable approvals so listener auto-approves valid articles
|
||||||
|
Setting::setBool('enable_publishing_approvals', false);
|
||||||
|
|
||||||
$feed = Feed::factory()->create();
|
$feed = Feed::factory()->create();
|
||||||
$article = Article::factory()->create([
|
$article = Article::factory()->create([
|
||||||
|
|
@ -200,8 +204,8 @@ public function test_validate_article_listener_processes_new_article(): void
|
||||||
$listener->handle($event);
|
$listener->handle($event);
|
||||||
|
|
||||||
$article->refresh();
|
$article->refresh();
|
||||||
$this->assertNotEquals('pending', $article->approval_status);
|
$this->assertEquals('approved', $article->approval_status);
|
||||||
$this->assertContains($article->approval_status, ['approved', 'rejected']);
|
Event::assertDispatched(ArticleApproved::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test removed - PublishApprovedArticle and ArticleReadyToPublish classes no longer exist
|
// Test removed - PublishApprovedArticle and ArticleReadyToPublish classes no longer exist
|
||||||
|
|
|
||||||
|
|
@ -46,15 +46,26 @@ public function test_is_valid_returns_false_when_approval_status_is_rejected():
|
||||||
$this->assertFalse($article->isValid());
|
$this->assertFalse($article->isValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_is_valid_returns_true_when_approval_status_is_approved(): void
|
public function test_is_valid_returns_true_when_validated_and_not_rejected(): void
|
||||||
{
|
{
|
||||||
$article = Article::factory()->make([
|
$article = Article::factory()->make([
|
||||||
'approval_status' => 'approved',
|
'approval_status' => 'approved',
|
||||||
|
'validated_at' => now(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertTrue($article->isValid());
|
$this->assertTrue($article->isValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_is_valid_returns_false_when_not_validated(): void
|
||||||
|
{
|
||||||
|
$article = Article::factory()->make([
|
||||||
|
'approval_status' => 'approved',
|
||||||
|
'validated_at' => null,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertFalse($article->isValid());
|
||||||
|
}
|
||||||
|
|
||||||
public function test_is_approved_returns_true_for_approved_status(): void
|
public function test_is_approved_returns_true_for_approved_status(): void
|
||||||
{
|
{
|
||||||
$article = Article::factory()->make(['approval_status' => 'approved']);
|
$article = Article::factory()->make(['approval_status' => 'approved']);
|
||||||
|
|
@ -149,10 +160,12 @@ public function test_can_be_published_requires_approval_when_approvals_enabled()
|
||||||
|
|
||||||
$pendingArticle = Article::factory()->make([
|
$pendingArticle = Article::factory()->make([
|
||||||
'approval_status' => 'pending',
|
'approval_status' => 'pending',
|
||||||
|
'validated_at' => now(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$approvedArticle = Article::factory()->make([
|
$approvedArticle = Article::factory()->make([
|
||||||
'approval_status' => 'approved',
|
'approval_status' => 'approved',
|
||||||
|
'validated_at' => now(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertFalse($pendingArticle->canBePublished());
|
$this->assertFalse($pendingArticle->canBePublished());
|
||||||
|
|
@ -165,7 +178,8 @@ public function test_can_be_published_returns_true_when_approvals_disabled(): vo
|
||||||
Setting::where('key', 'enable_publishing_approvals')->delete();
|
Setting::where('key', 'enable_publishing_approvals')->delete();
|
||||||
|
|
||||||
$article = Article::factory()->make([
|
$article = Article::factory()->make([
|
||||||
'approval_status' => 'approved', // Only approved articles can be published
|
'approval_status' => 'approved',
|
||||||
|
'validated_at' => now(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertTrue($article->canBePublished());
|
$this->assertTrue($article->canBePublished());
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,8 @@ public function test_publish_to_routed_channels_returns_empty_collection_when_no
|
||||||
$feed = Feed::factory()->create();
|
$feed = Feed::factory()->create();
|
||||||
$article = Article::factory()->create([
|
$article = Article::factory()->create([
|
||||||
'feed_id' => $feed->id,
|
'feed_id' => $feed->id,
|
||||||
'approval_status' => 'approved'
|
'approval_status' => 'approved',
|
||||||
|
'validated_at' => now()
|
||||||
]);
|
]);
|
||||||
$extractedData = ['title' => 'Test Title'];
|
$extractedData = ['title' => 'Test Title'];
|
||||||
|
|
||||||
|
|
@ -79,6 +80,7 @@ public function test_publish_to_routed_channels_skips_routes_without_active_acco
|
||||||
$article = Article::factory()->create([
|
$article = Article::factory()->create([
|
||||||
'feed_id' => $feed->id,
|
'feed_id' => $feed->id,
|
||||||
'approval_status' => 'approved',
|
'approval_status' => 'approved',
|
||||||
|
'validated_at' => now(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Create a route with a channel but no active accounts
|
// Create a route with a channel but no active accounts
|
||||||
|
|
@ -105,7 +107,8 @@ public function test_publish_to_routed_channels_successfully_publishes_to_channe
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
$feed = Feed::factory()->create();
|
$feed = Feed::factory()->create();
|
||||||
$article = Article::factory()->create(['feed_id' => $feed->id, 'approval_status' => 'approved']);
|
$article = Article::factory()->create(['feed_id' => $feed->id, 'approval_status' => 'approved',
|
||||||
|
'validated_at' => now()]);
|
||||||
|
|
||||||
$platformInstance = PlatformInstance::factory()->create();
|
$platformInstance = PlatformInstance::factory()->create();
|
||||||
$channel = PlatformChannel::factory()->create(['platform_instance_id' => $platformInstance->id]);
|
$channel = PlatformChannel::factory()->create(['platform_instance_id' => $platformInstance->id]);
|
||||||
|
|
@ -151,7 +154,8 @@ public function test_publish_to_routed_channels_handles_publishing_failure_grace
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
$feed = Feed::factory()->create();
|
$feed = Feed::factory()->create();
|
||||||
$article = Article::factory()->create(['feed_id' => $feed->id, 'approval_status' => 'approved']);
|
$article = Article::factory()->create(['feed_id' => $feed->id, 'approval_status' => 'approved',
|
||||||
|
'validated_at' => now()]);
|
||||||
|
|
||||||
$platformInstance = PlatformInstance::factory()->create();
|
$platformInstance = PlatformInstance::factory()->create();
|
||||||
$channel = PlatformChannel::factory()->create(['platform_instance_id' => $platformInstance->id]);
|
$channel = PlatformChannel::factory()->create(['platform_instance_id' => $platformInstance->id]);
|
||||||
|
|
@ -192,7 +196,8 @@ public function test_publish_to_routed_channels_publishes_to_multiple_routes():
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
$feed = Feed::factory()->create();
|
$feed = Feed::factory()->create();
|
||||||
$article = Article::factory()->create(['feed_id' => $feed->id, 'approval_status' => 'approved']);
|
$article = Article::factory()->create(['feed_id' => $feed->id, 'approval_status' => 'approved',
|
||||||
|
'validated_at' => now()]);
|
||||||
|
|
||||||
$platformInstance = PlatformInstance::factory()->create();
|
$platformInstance = PlatformInstance::factory()->create();
|
||||||
$channel1 = PlatformChannel::factory()->create(['platform_instance_id' => $platformInstance->id]);
|
$channel1 = PlatformChannel::factory()->create(['platform_instance_id' => $platformInstance->id]);
|
||||||
|
|
@ -247,7 +252,8 @@ public function test_publish_to_routed_channels_filters_out_failed_publications(
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
$feed = Feed::factory()->create();
|
$feed = Feed::factory()->create();
|
||||||
$article = Article::factory()->create(['feed_id' => $feed->id, 'approval_status' => 'approved']);
|
$article = Article::factory()->create(['feed_id' => $feed->id, 'approval_status' => 'approved',
|
||||||
|
'validated_at' => now()]);
|
||||||
|
|
||||||
$platformInstance = PlatformInstance::factory()->create();
|
$platformInstance = PlatformInstance::factory()->create();
|
||||||
$channel1 = PlatformChannel::factory()->create(['platform_instance_id' => $platformInstance->id]);
|
$channel1 = PlatformChannel::factory()->create(['platform_instance_id' => $platformInstance->id]);
|
||||||
|
|
@ -305,6 +311,7 @@ public function test_publish_skips_duplicate_when_url_already_posted_to_channel(
|
||||||
$article = Article::factory()->create([
|
$article = Article::factory()->create([
|
||||||
'feed_id' => $feed->id,
|
'feed_id' => $feed->id,
|
||||||
'approval_status' => 'approved',
|
'approval_status' => 'approved',
|
||||||
|
'validated_at' => now(),
|
||||||
'url' => 'https://example.com/article-1',
|
'url' => 'https://example.com/article-1',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
@ -356,6 +363,7 @@ public function test_publish_skips_duplicate_when_title_already_posted_to_channe
|
||||||
$article = Article::factory()->create([
|
$article = Article::factory()->create([
|
||||||
'feed_id' => $feed->id,
|
'feed_id' => $feed->id,
|
||||||
'approval_status' => 'approved',
|
'approval_status' => 'approved',
|
||||||
|
'validated_at' => now(),
|
||||||
'url' => 'https://example.com/article-new-url',
|
'url' => 'https://example.com/article-new-url',
|
||||||
'title' => 'Breaking News: Something Happened',
|
'title' => 'Breaking News: Something Happened',
|
||||||
]);
|
]);
|
||||||
|
|
@ -408,6 +416,7 @@ public function test_publish_proceeds_when_no_duplicate_exists(): void
|
||||||
$article = Article::factory()->create([
|
$article = Article::factory()->create([
|
||||||
'feed_id' => $feed->id,
|
'feed_id' => $feed->id,
|
||||||
'approval_status' => 'approved',
|
'approval_status' => 'approved',
|
||||||
|
'validated_at' => now(),
|
||||||
'url' => 'https://example.com/unique-article',
|
'url' => 'https://example.com/unique-article',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue