'P1', 'type' => 'application', 'description' => null, 'features' => ['backup'], 'status' => 'missing', 'details' => null, ], [ 'key' => 'P2', 'type' => 'delegated', 'description' => null, 'features' => ['backup'], 'status' => 'missing', 'details' => null, ], [ 'key' => 'P3', 'type' => 'application', 'description' => null, 'features' => ['backup', 'drift'], 'status' => 'granted', 'details' => null, ], [ 'key' => 'P4', 'type' => 'application', 'description' => null, 'features' => ['drift'], 'status' => 'missing', 'details' => null, ], [ 'key' => 'P5', 'type' => 'application', 'description' => null, 'features' => ['backup', 'backup'], 'status' => 'missing', 'details' => null, ], ]; $impacts = TenantRequiredPermissionsViewModelBuilder::deriveFeatureImpacts($rows); $byFeature = collect($impacts)->keyBy('feature')->all(); expect($byFeature['backup'])->toMatchArray([ 'feature' => 'backup', 'missing' => 3, 'required_application' => 3, 'required_delegated' => 1, 'blocked' => true, ]); expect($byFeature['drift'])->toMatchArray([ 'feature' => 'drift', 'missing' => 1, 'required_application' => 2, 'required_delegated' => 0, 'blocked' => true, ]); });