This PR completes Feature 014 (Enrollment & Autopilot). Adds normalization for: Autopilot deployment profiles (windowsAutopilotDeploymentProfile) Enrollment Status Page / ESP (windowsEnrollmentStatusPage) Enrollment Restrictions (enrollmentRestriction, restore remains preview-only) Improves settings readability: Autopilot OOBE settings are expanded into readable key/value entries Enrollment restriction platform restrictions are shown as explicit fields (with sensible defaults) Array/list values render as badges (avoids Blade rendering crashes on non-string values) Fixes enrollment configuration type collisions during sync: Canonical type resolution prevents enrollmentRestriction from “claiming” ESP items Safe reclassification updates existing wrong rows instead of skipping Enhances reclassification command: Can detect ESP even if a policy has no local versions (fetches snapshot from Graph) Dry-run by default; apply with --write Tests Added/updated unit + Filament feature tests for normalization and UI rendering. Preview-only enforcement for enrollment restrictions is covered. Targeted test suite and Pint are green. Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local> Reviewed-on: #20
74 lines
2.3 KiB
PHP
74 lines
2.3 KiB
PHP
<?php
|
|
|
|
use App\Models\Policy;
|
|
use App\Models\Tenant;
|
|
use App\Services\Graph\GraphClientInterface;
|
|
use App\Services\Graph\GraphResponse;
|
|
use App\Services\Intune\PolicySyncService;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Mockery\MockInterface;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
test('policy sync does not let enrollmentRestriction claim ESP items and reclassifies existing wrong rows', function () {
|
|
$tenant = Tenant::create([
|
|
'tenant_id' => 'tenant-sync-collision',
|
|
'name' => 'Tenant Sync Collision',
|
|
'metadata' => [],
|
|
'is_current' => true,
|
|
]);
|
|
|
|
$tenant->makeCurrent();
|
|
|
|
// Simulate an older bug: ESP row was synced under enrollmentRestriction.
|
|
$wrong = Policy::create([
|
|
'tenant_id' => $tenant->id,
|
|
'external_id' => 'esp-1',
|
|
'policy_type' => 'enrollmentRestriction',
|
|
'display_name' => 'ESP Misclassified',
|
|
'platform' => 'all',
|
|
]);
|
|
|
|
$this->mock(GraphClientInterface::class, function (MockInterface $mock) {
|
|
$espPayload = [
|
|
'id' => 'esp-1',
|
|
'displayName' => 'Enrollment Status Page',
|
|
'@odata.type' => '#microsoft.graph.windows10EnrollmentCompletionPageConfiguration',
|
|
'deviceEnrollmentConfigurationType' => 'windows10EnrollmentCompletionPageConfiguration',
|
|
];
|
|
|
|
$mock->shouldReceive('listPolicies')
|
|
->andReturnUsing(function (string $policyType) use ($espPayload) {
|
|
if ($policyType === 'enrollmentRestriction') {
|
|
// Shared endpoint can return ESP items if unfiltered.
|
|
return new GraphResponse(true, [$espPayload]);
|
|
}
|
|
|
|
if ($policyType === 'windowsEnrollmentStatusPage') {
|
|
return new GraphResponse(true, [$espPayload]);
|
|
}
|
|
|
|
return new GraphResponse(true, []);
|
|
});
|
|
});
|
|
|
|
$service = app(PolicySyncService::class);
|
|
|
|
$service->syncPolicies($tenant, [
|
|
[
|
|
'type' => 'enrollmentRestriction',
|
|
'platform' => 'all',
|
|
'filter' => null,
|
|
],
|
|
[
|
|
'type' => 'windowsEnrollmentStatusPage',
|
|
'platform' => 'all',
|
|
'filter' => null,
|
|
],
|
|
]);
|
|
|
|
$wrong->refresh();
|
|
|
|
expect($wrong->policy_type)->toBe('windowsEnrollmentStatusPage');
|
|
});
|