microsoft/hve-core

Public

mirrored fromhttps://github.com/microsoft/hve-coreAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
feat/networking-agent

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

scripts/tests/security/SecurityClasses.Tests.ps1

207lines · modecode

1#Requires -Modules Pester
2# Copyright (c) Microsoft Corporation.
3# SPDX-License-Identifier: MIT
4using module ..\..\security\Modules\SecurityClasses.psm1
5
6BeforeAll {
7 Import-Module (Join-Path $PSScriptRoot '../../lib/Modules/CIHelpers.psm1') -Force
8}
9
10Describe 'DependencyViolation' -Tag 'Unit' {
11 Context 'Default constructor' {
12 It 'Initializes with empty Metadata hashtable' {
13 $v = [DependencyViolation]::new()
14 $v.Metadata | Should -BeOfType [hashtable]
15 $v.Metadata.Count | Should -Be 0
16 }
17
18 It 'Has null/default string properties' {
19 $v = [DependencyViolation]::new()
20 $v.File | Should -BeNullOrEmpty
21 $v.Name | Should -BeNullOrEmpty
22 $v.Line | Should -Be 0
23 }
24 }
25
26 Context 'Parameterized constructor' {
27 BeforeAll {
28 $script:violation = [DependencyViolation]::new(
29 'workflow.yml', 10, 'github-actions', 'actions/checkout', 'High', 'Not pinned'
30 )
31 }
32
33 It 'Sets File property' {
34 $script:violation.File | Should -Be 'workflow.yml'
35 }
36
37 It 'Sets Line property' {
38 $script:violation.Line | Should -Be 10
39 }
40
41 It 'Sets Type property' {
42 $script:violation.Type | Should -Be 'github-actions'
43 }
44
45 It 'Sets Name property' {
46 $script:violation.Name | Should -Be 'actions/checkout'
47 }
48
49 It 'Sets Severity property' {
50 $script:violation.Severity | Should -Be 'High'
51 }
52
53 It 'Sets Description property' {
54 $script:violation.Description | Should -Be 'Not pinned'
55 }
56
57 It 'Initializes Metadata as empty hashtable' {
58 $script:violation.Metadata | Should -BeOfType [hashtable]
59 $script:violation.Metadata.Count | Should -Be 0
60 }
61 }
62
63 Context 'ViolationType ValidateSet' {
64 It 'Accepts valid ViolationType values' -ForEach @(
65 @{ Value = 'Unpinned' }
66 @{ Value = 'Stale' }
67 @{ Value = 'VersionMismatch' }
68 @{ Value = 'MissingVersionComment' }
69 @{ Value = 'MissingPermissions' }
70 @{ Value = '' }
71 ) {
72 $v = [DependencyViolation]::new()
73 $v.ViolationType = $Value
74 $v.ViolationType | Should -Be $Value
75 }
76
77 It 'Rejects invalid ViolationType' {
78 $v = [DependencyViolation]::new()
79 { $v.ViolationType = 'InvalidType' } | Should -Throw
80 }
81 }
82}
83
84Describe 'ComplianceReport' -Tag 'Unit' {
85 Context 'Default constructor' {
86 BeforeAll {
87 $script:report = [ComplianceReport]::new()
88 }
89
90 It 'Sets Timestamp to current time' {
91 $script:report.Timestamp | Should -BeOfType [datetime]
92 ($script:report.Timestamp - (Get-Date)).TotalSeconds | Should -BeLessThan 5
93 }
94
95 It 'Initializes empty Violations array' {
96 $script:report.Violations | Should -HaveCount 0
97 }
98
99 It 'Initializes empty Summary hashtable' {
100 $script:report.Summary | Should -BeOfType [hashtable]
101 }
102
103 It 'Initializes empty Metadata hashtable' {
104 $script:report.Metadata | Should -BeOfType [hashtable]
105 }
106 }
107
108 Context 'Parameterized constructor' {
109 It 'Sets ScanPath' {
110 $report = [ComplianceReport]::new('/repo')
111 $report.ScanPath | Should -Be '/repo'
112 }
113
114 It 'Initializes collections' {
115 $report = [ComplianceReport]::new('/repo')
116 $report.Violations | Should -HaveCount 0
117 $report.Summary | Should -BeOfType [hashtable]
118 $report.Metadata | Should -BeOfType [hashtable]
119 }
120 }
121
122 Context 'AddViolation' {
123 It 'Appends violation and updates UnpinnedDependencies count' {
124 $report = [ComplianceReport]::new('/repo')
125 $v = [DependencyViolation]::new('f.yml', 1, 'github-actions', 'a/b', 'High', 'desc')
126 $report.AddViolation($v)
127 $report.Violations | Should -HaveCount 1
128 $report.UnpinnedDependencies | Should -Be 1
129 }
130
131 It 'Tracks multiple violations' {
132 $report = [ComplianceReport]::new('/repo')
133 $report.AddViolation([DependencyViolation]::new('a.yml', 1, 't', 'n1', 'High', 'd'))
134 $report.AddViolation([DependencyViolation]::new('b.yml', 2, 't', 'n2', 'Low', 'd'))
135 $report.Violations | Should -HaveCount 2
136 $report.UnpinnedDependencies | Should -Be 2
137 }
138 }
139
140 Context 'CalculateScore' {
141 It 'Computes percentage when TotalDependencies > 0' {
142 $report = [ComplianceReport]::new('/repo')
143 $report.TotalDependencies = 10
144 $report.PinnedDependencies = 8
145 $report.CalculateScore()
146 $report.ComplianceScore | Should -Be 80.0
147 }
148
149 It 'Returns 100 when TotalDependencies is zero' {
150 $report = [ComplianceReport]::new('/repo')
151 $report.TotalDependencies = 0
152 $report.CalculateScore()
153 $report.ComplianceScore | Should -Be 100.0
154 }
155
156 It 'Rounds to two decimal places' {
157 $report = [ComplianceReport]::new('/repo')
158 $report.TotalDependencies = 3
159 $report.PinnedDependencies = 1
160 $report.CalculateScore()
161 $report.ComplianceScore | Should -Be 33.33
162 }
163 }
164
165 Context 'ToHashtable' {
166 BeforeAll {
167 $script:report = [ComplianceReport]::new('/repo')
168 $script:report.TotalFiles = 5
169 $script:report.ScannedFiles = 3
170 $script:report.TotalDependencies = 10
171 $script:report.PinnedDependencies = 8
172 $script:report.UnpinnedDependencies = 2
173 $script:report.ComplianceScore = 80.0
174 $script:ht = $script:report.ToHashtable()
175 }
176
177 It 'Returns hashtable with 11 keys' {
178 $script:ht | Should -BeOfType [hashtable]
179 $script:ht.Keys.Count | Should -Be 11
180 }
181
182 It 'Includes all expected keys' -ForEach @(
183 @{ Key = 'ScanPath' }
184 @{ Key = 'Timestamp' }
185 @{ Key = 'TotalFiles' }
186 @{ Key = 'ScannedFiles' }
187 @{ Key = 'TotalDependencies' }
188 @{ Key = 'PinnedDependencies' }
189 @{ Key = 'UnpinnedDependencies' }
190 @{ Key = 'ComplianceScore' }
191 @{ Key = 'Violations' }
192 @{ Key = 'Summary' }
193 @{ Key = 'Metadata' }
194 ) {
195 $script:ht.ContainsKey($Key) | Should -BeTrue
196 }
197
198 It 'Formats Timestamp as ISO 8601 string' {
199 $script:ht['Timestamp'] | Should -Match (Get-StandardTimestampPattern)
200 }
201
202 It 'Preserves numeric values' {
203 $script:ht['TotalFiles'] | Should -Be 5
204 $script:ht['ComplianceScore'] | Should -Be 80.0
205 }
206 }
207}
208