Automated PR provided by Codex via Gitea API. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #482
77 lines
3.7 KiB
PHP
77 lines
3.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Models\OperationRun;
|
|
use App\Models\ProviderConnection;
|
|
use App\Models\TenantConfigurationResourceEvidence;
|
|
use App\Models\TenantConfigurationResourceType;
|
|
use App\Services\Graph\GraphContractRegistry;
|
|
use App\Services\TenantConfiguration\CoverageEvidenceWriter;
|
|
use App\Services\TenantConfiguration\CoverageResourceUpserter;
|
|
use App\Services\TenantConfiguration\CoverageSourceContractResolver;
|
|
use App\Services\TenantConfiguration\GenericPayloadNormalizer;
|
|
use App\Services\TenantConfiguration\ResourceTypeRegistry;
|
|
use App\Support\OperationRunOutcome;
|
|
use App\Support\OperationRunStatus;
|
|
use App\Support\OperationRunType;
|
|
|
|
it('upserts concrete resources and appends immutable evidence snapshots', function (): void {
|
|
app(ResourceTypeRegistry::class)->syncDefaults();
|
|
config()->set('graph_contracts.types.assignmentFilter.volatile_fields', ['@odata.etag']);
|
|
|
|
[$user, $tenant] = createMinimalUserWithTenant(role: 'owner');
|
|
$connection = ProviderConnection::factory()->withCredential()->create([
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'managed_environment_id' => (int) $tenant->getKey(),
|
|
]);
|
|
$run = OperationRun::factory()->withUser($user)->forTenant($tenant)->create([
|
|
'type' => OperationRunType::TenantConfigurationCapture->value,
|
|
'status' => OperationRunStatus::Running->value,
|
|
'outcome' => OperationRunOutcome::Pending->value,
|
|
]);
|
|
$resourceType = TenantConfigurationResourceType::query()
|
|
->where('canonical_type', 'deviceAndAppManagementAssignmentFilter')
|
|
->firstOrFail();
|
|
$decision = app(CoverageSourceContractResolver::class)->resolve($resourceType);
|
|
$normalizer = new GenericPayloadNormalizer;
|
|
|
|
$firstPayload = ['id' => 'resource-1', 'displayName' => 'Resource', '@odata.etag' => 'one'];
|
|
$resource = app(CoverageResourceUpserter::class)->upsert($tenant, $connection, $resourceType, $firstPayload, $decision->sourceMetadata);
|
|
$firstNormalized = $normalizer->normalize($firstPayload, ['@odata.etag']);
|
|
|
|
app(CoverageEvidenceWriter::class)->append(
|
|
resource: $resource,
|
|
resourceType: $resourceType,
|
|
providerConnection: $connection,
|
|
operationRun: $run,
|
|
decision: $decision,
|
|
rawPayload: $firstPayload,
|
|
normalizedPayload: $firstNormalized,
|
|
payloadHash: $normalizer->payloadHash($firstNormalized),
|
|
permissionContext: ['scopes_granted' => []],
|
|
);
|
|
|
|
$secondPayload = ['id' => 'resource-1', 'displayName' => 'Resource updated', '@odata.etag' => 'two'];
|
|
$sameResource = app(CoverageResourceUpserter::class)->upsert($tenant, $connection, $resourceType, $secondPayload, $decision->sourceMetadata);
|
|
$secondNormalized = $normalizer->normalize($secondPayload, ['@odata.etag']);
|
|
$secondEvidence = app(CoverageEvidenceWriter::class)->append(
|
|
resource: $sameResource,
|
|
resourceType: $resourceType,
|
|
providerConnection: $connection,
|
|
operationRun: $run,
|
|
decision: $decision,
|
|
rawPayload: $secondPayload,
|
|
normalizedPayload: $secondNormalized,
|
|
payloadHash: $normalizer->payloadHash($secondNormalized),
|
|
permissionContext: ['scopes_granted' => []],
|
|
);
|
|
|
|
expect($sameResource->getKey())->toBe($resource->getKey())
|
|
->and(TenantConfigurationResourceEvidence::query()->where('resource_id', $resource->getKey())->count())->toBe(2)
|
|
->and($sameResource->fresh()->latest_evidence_id)->toBe((int) $secondEvidence->getKey())
|
|
->and($secondEvidence->operation_run_id)->toBe((int) $run->getKey())
|
|
->and($secondEvidence->source_metadata['source_contract_key'])->toBe('assignmentFilter')
|
|
->and($secondEvidence->normalized_payload)->not->toHaveKey('@odata.etag');
|
|
});
|