calculate([ 'overall_status' => 'granted', 'permissions' => [ ['key' => 'Perm.A', 'type' => 'application', 'status' => 'granted', 'features' => ['a']], ['key' => 'Perm.B', 'type' => 'application', 'status' => 'granted', 'features' => ['b']], ], ]); expect($result)->toBe(100); }); it('returns 86 for 12 of 14 granted', function (): void { $calculator = new PostureScoreCalculator; $permissions = []; for ($i = 0; $i < 12; $i++) { $permissions[] = ['key' => "Perm.$i", 'type' => 'application', 'status' => 'granted', 'features' => []]; } for ($i = 12; $i < 14; $i++) { $permissions[] = ['key' => "Perm.$i", 'type' => 'application', 'status' => 'missing', 'features' => []]; } $result = $calculator->calculate([ 'overall_status' => 'missing', 'permissions' => $permissions, ]); expect($result)->toBe(86); }); it('returns 0 when all permissions are missing', function (): void { $calculator = new PostureScoreCalculator; $result = $calculator->calculate([ 'overall_status' => 'missing', 'permissions' => [ ['key' => 'Perm.A', 'type' => 'application', 'status' => 'missing', 'features' => ['a']], ['key' => 'Perm.B', 'type' => 'application', 'status' => 'missing', 'features' => ['b']], ], ]); expect($result)->toBe(0); }); it('returns 100 when 0 permissions required', function (): void { $calculator = new PostureScoreCalculator; $result = $calculator->calculate([ 'overall_status' => 'granted', 'permissions' => [], ]); expect($result)->toBe(100); }); it('returns 100 for single granted permission', function (): void { $calculator = new PostureScoreCalculator; $result = $calculator->calculate([ 'overall_status' => 'granted', 'permissions' => [ ['key' => 'Perm.A', 'type' => 'application', 'status' => 'granted', 'features' => ['a']], ], ]); expect($result)->toBe(100); }); it('returns 0 for single missing permission', function (): void { $calculator = new PostureScoreCalculator; $result = $calculator->calculate([ 'overall_status' => 'missing', 'permissions' => [ ['key' => 'Perm.A', 'type' => 'application', 'status' => 'missing', 'features' => ['a']], ], ]); expect($result)->toBe(0); }); it('rounds correctly for 1 of 3 granted (33)', function (): void { $calculator = new PostureScoreCalculator; $result = $calculator->calculate([ 'overall_status' => 'missing', 'permissions' => [ ['key' => 'A', 'type' => 'application', 'status' => 'granted', 'features' => []], ['key' => 'B', 'type' => 'application', 'status' => 'missing', 'features' => []], ['key' => 'C', 'type' => 'application', 'status' => 'missing', 'features' => []], ], ]); expect($result)->toBe(33); }); it('rounds correctly for 2 of 3 granted (67)', function (): void { $calculator = new PostureScoreCalculator; $result = $calculator->calculate([ 'overall_status' => 'missing', 'permissions' => [ ['key' => 'A', 'type' => 'application', 'status' => 'granted', 'features' => []], ['key' => 'B', 'type' => 'application', 'status' => 'granted', 'features' => []], ['key' => 'C', 'type' => 'application', 'status' => 'missing', 'features' => []], ], ]); expect($result)->toBe(67); }); it('returns integer not float', function (): void { $calculator = new PostureScoreCalculator; $result = $calculator->calculate([ 'overall_status' => 'missing', 'permissions' => [ ['key' => 'A', 'type' => 'application', 'status' => 'granted', 'features' => []], ['key' => 'B', 'type' => 'application', 'status' => 'missing', 'features' => []], ['key' => 'C', 'type' => 'application', 'status' => 'missing', 'features' => []], ], ]); expect($result)->toBeInt(); }); it('returns 50 for 7 of 14 granted', function (): void { $calculator = new PostureScoreCalculator; $permissions = []; for ($i = 0; $i < 7; $i++) { $permissions[] = ['key' => "Perm.$i", 'type' => 'application', 'status' => 'granted', 'features' => []]; } for ($i = 7; $i < 14; $i++) { $permissions[] = ['key' => "Perm.$i", 'type' => 'application', 'status' => 'missing', 'features' => []]; } $result = $calculator->calculate([ 'overall_status' => 'missing', 'permissions' => $permissions, ]); expect($result)->toBe(50); });