86 lines
4.1 KiB
PHP
86 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace Tests\Unit;
|
|
|
|
use App\Models\Opportunity;
|
|
use App\Models\User;
|
|
use App\Services\OpportunityCanonicalContract;
|
|
use App\Services\OpportunityCuration;
|
|
use App\Services\OpportunityManagement;
|
|
use App\Services\OpportunityProfileWorkflow;
|
|
use App\Services\OpportunityWorkflowTasks;
|
|
use App\Services\PortalProfileAccess;
|
|
use Illuminate\Foundation\Testing\TestCase;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Mockery;
|
|
use Symfony\Component\HttpKernel\Exception\HttpException;
|
|
|
|
class OpportunityCurationAuthorityTest extends TestCase
|
|
{
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
DB::shouldReceive('connection')->never();
|
|
}
|
|
|
|
public function test_legacy_curation_cannot_restore_a_revoked_or_replaced_legacy_authority(): void
|
|
{
|
|
$actor = new User;
|
|
$actor->id = 17;
|
|
$record = new Opportunity;
|
|
$record->owner_user_id = null;
|
|
$access = Mockery::mock(PortalProfileAccess::class);
|
|
$access->shouldReceive('canView')->once()->with($actor, $record)->andReturnTrue();
|
|
$access->shouldReceive('legacyWriteAllowed')->once()->with($actor)->andReturnFalse();
|
|
$management = Mockery::mock(OpportunityManagement::class);
|
|
$management->shouldReceive('installed')->once()->andReturnTrue();
|
|
$this->assertFalse((new OpportunityCuration($access, $management))->allowed($actor, $record));
|
|
}
|
|
|
|
public function test_native_assignment_to_another_publisher_is_not_inferred_away(): void
|
|
{
|
|
$actor = new User;
|
|
$actor->id = 17;
|
|
$record = new Opportunity;
|
|
$record->id = 1;
|
|
$record->owner_user_id = 19;
|
|
$record->organization_id = null;
|
|
$record->opportunity_category = 'investment_project';
|
|
$record->workflow_context = ['approval' => ['actor_id' => 20], 'publication_assignment' => ['assignee_user_id' => 21]];
|
|
$access = Mockery::mock(PortalProfileAccess::class);
|
|
$access->shouldReceive('canView')->once()->with($actor, $record)->andReturnTrue();
|
|
$access->shouldReceive('scoped')->once()->with($actor, 'publisher', null, 'investment_project')->andReturnTrue();
|
|
$access->shouldReceive('operational')->once()->with($actor, 'publish', 1)->andReturnTrue();
|
|
$access->shouldReceive('conflict')->once()->with($actor, $record)->andReturnFalse();
|
|
$management = Mockery::mock(OpportunityManagement::class);
|
|
$management->shouldReceive('installed')->once()->andReturnTrue();
|
|
$this->assertFalse((new OpportunityCuration($access, $management))->allowed($actor, $record));
|
|
}
|
|
|
|
public function test_native_editorial_authorisation_reuses_the_existing_fresh_mfa_requirement(): void
|
|
{
|
|
$actor = new User;
|
|
$actor->id = 17;
|
|
$record = new Opportunity;
|
|
$record->id = 1;
|
|
$record->owner_user_id = 19;
|
|
$record->organization_id = null;
|
|
$record->opportunity_category = 'investment_project';
|
|
$access = Mockery::mock(PortalProfileAccess::class);
|
|
$access->shouldReceive('authorize')->once()->with($actor, 'view', $record);
|
|
$access->shouldReceive('promoterRecordScope')->once()->with($actor, $record)->andReturnFalse();
|
|
$access->shouldReceive('scoped')->once()->with($actor, 'publisher', null, 'investment_project')->andReturnTrue();
|
|
$access->shouldReceive('operational')->once()->with($actor, 'publish', 1)->andReturnTrue();
|
|
$access->shouldReceive('conflict')->once()->with($actor, $record)->andReturnFalse();
|
|
$access->shouldReceive('mfa')->once()->with($actor)->andReturnFalse();
|
|
$flow = new OpportunityProfileWorkflow($access, Mockery::mock(OpportunityManagement::class), Mockery::mock(OpportunityCanonicalContract::class), Mockery::mock(OpportunityWorkflowTasks::class));
|
|
try {
|
|
$flow->authorizeEditorialCuration($actor, $record);
|
|
$this->fail('A stale MFA session was accepted.');
|
|
} catch (HttpException $error) {
|
|
$this->assertSame(403, $error->getStatusCode());
|
|
$this->assertSame('required', $error->getHeaders()['X-Portal-Reauthentication']);
|
|
}
|
|
}
|
|
}
|