microsoft/hve-core

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
feat/devcontainer-python-uv-887

Branches

Tags

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

Clone

HTTPS

Download ZIP

scripts/tests/linting/Test-CopyrightHeaders.Tests.ps1

519lines · modecode

1#Requires -Modules Pester
2# Copyright (c) Microsoft Corporation.
3# SPDX-License-Identifier: MIT
4<#
5.SYNOPSIS
6 Pester tests for Test-CopyrightHeaders.ps1 script
7.DESCRIPTION
8 Tests for copyright header validation script:
9 - Files with valid headers
10 - Files missing copyright line
11 - Files missing SPDX line
12 - Files with incorrect line positions
13 - Parameter validation
14#>
15
16BeforeAll {
17 $script:ScriptPath = Join-Path $PSScriptRoot '../../linting/Test-CopyrightHeaders.ps1'
18 $script:FixturesPath = Join-Path $PSScriptRoot '../Fixtures/CopyrightHeaders'
19 $script:CIHelpersPath = Join-Path $PSScriptRoot '../../lib/Modules/CIHelpers.psm1'
20
21 # Import modules for mocking
22 Import-Module $script:CIHelpersPath -Force
23
24 # Create test fixtures directory
25 if (-not (Test-Path $script:FixturesPath)) {
26 New-Item -ItemType Directory -Path $script:FixturesPath -Force | Out-Null
27 }
28
29 . $script:ScriptPath
30}
31
32AfterAll {
33 Remove-Module CIHelpers -Force -ErrorAction SilentlyContinue
34 # Cleanup test fixtures
35 if (Test-Path $script:FixturesPath) {
36 Remove-Item -Path $script:FixturesPath -Recurse -Force -ErrorAction SilentlyContinue
37 }
38}
39
40#region Test Fixtures Setup
41
42Describe 'Test-CopyrightHeaders Test Fixtures' -Tag 'Setup' {
43 BeforeAll {
44 # Valid file with both headers
45 $validContent = @"
46#!/usr/bin/env pwsh
47# Copyright (c) Microsoft Corporation.
48# SPDX-License-Identifier: MIT
49
50Write-Host "Hello World"
51"@
52
53 # File missing copyright
54 $missingCopyrightContent = @"
55#!/usr/bin/env pwsh
56# SPDX-License-Identifier: MIT
57
58Write-Host "Hello World"
59"@
60
61 # File missing SPDX
62 $missingSpdxContent = @"
63#!/usr/bin/env pwsh
64# Copyright (c) Microsoft Corporation.
65
66Write-Host "Hello World"
67"@
68
69 # File missing both headers
70 $missingBothContent = @"
71#!/usr/bin/env pwsh
72
73Write-Host "Hello World"
74"@
75
76 # Valid file with #Requires statement
77 $validWithRequiresContent = @"
78#!/usr/bin/env pwsh
79#Requires -Version 7.0
80# Copyright (c) Microsoft Corporation.
81# SPDX-License-Identifier: MIT
82
83Write-Host "Hello World"
84"@
85
86 # Create fixture files
87 Set-Content -Path (Join-Path $script:FixturesPath 'valid.ps1') -Value $validContent
88 Set-Content -Path (Join-Path $script:FixturesPath 'missing-copyright.ps1') -Value $missingCopyrightContent
89 Set-Content -Path (Join-Path $script:FixturesPath 'missing-spdx.ps1') -Value $missingSpdxContent
90 Set-Content -Path (Join-Path $script:FixturesPath 'missing-both.ps1') -Value $missingBothContent
91 Set-Content -Path (Join-Path $script:FixturesPath 'valid-with-requires.ps1') -Value $validWithRequiresContent
92 }
93
94 It 'Creates test fixture files' {
95 Test-Path (Join-Path $script:FixturesPath 'valid.ps1') | Should -BeTrue
96 Test-Path (Join-Path $script:FixturesPath 'missing-copyright.ps1') | Should -BeTrue
97 Test-Path (Join-Path $script:FixturesPath 'missing-spdx.ps1') | Should -BeTrue
98 Test-Path (Join-Path $script:FixturesPath 'missing-both.ps1') | Should -BeTrue
99 Test-Path (Join-Path $script:FixturesPath 'valid-with-requires.ps1') | Should -BeTrue
100 }
101}
102
103#endregion
104
105#region Valid Header Tests
106
107Describe 'Test-CopyrightHeaders Valid Files' -Tag 'Unit' {
108 BeforeAll {
109 # Ensure fixtures exist
110 $validContent = @"
111#!/usr/bin/env pwsh
112# Copyright (c) Microsoft Corporation.
113# SPDX-License-Identifier: MIT
114
115Write-Host "Hello World"
116"@
117 if (-not (Test-Path $script:FixturesPath)) {
118 New-Item -ItemType Directory -Path $script:FixturesPath -Force | Out-Null
119 }
120 Set-Content -Path (Join-Path $script:FixturesPath 'valid.ps1') -Value $validContent
121 }
122
123 It 'Detects valid headers in file' {
124 $outputPath = Join-Path $script:FixturesPath 'results.json'
125 Invoke-CopyrightHeaderCheck -Path $script:FixturesPath -FileExtensions @('valid.ps1') -OutputPath $outputPath
126
127 $results = Get-Content $outputPath | ConvertFrom-Json
128 $validFile = $results.results | Where-Object { $_.file -like '*valid.ps1' }
129
130 $validFile.hasCopyright | Should -BeTrue
131 $validFile.hasSpdx | Should -BeTrue
132 $validFile.valid | Should -BeTrue
133 }
134
135 It 'Handles files with #Requires statement' {
136 $validWithRequiresContent = @"
137#!/usr/bin/env pwsh
138#Requires -Version 7.0
139# Copyright (c) Microsoft Corporation.
140# SPDX-License-Identifier: MIT
141
142Write-Host "Hello World"
143"@
144 Set-Content -Path (Join-Path $script:FixturesPath 'valid-with-requires.ps1') -Value $validWithRequiresContent
145
146 $outputPath = Join-Path $script:FixturesPath 'results-requires.json'
147 Invoke-CopyrightHeaderCheck -Path $script:FixturesPath -FileExtensions @('valid-with-requires.ps1') -OutputPath $outputPath
148
149 $results = Get-Content $outputPath | ConvertFrom-Json
150 $validFile = $results.results | Where-Object { $_.file -like '*valid-with-requires.ps1' }
151
152 $validFile.valid | Should -BeTrue
153 }
154}
155
156#endregion
157
158#region Missing Header Tests
159
160Describe 'Test-CopyrightHeaders Missing Headers' -Tag 'Unit' {
161 BeforeAll {
162 if (-not (Test-Path $script:FixturesPath)) {
163 New-Item -ItemType Directory -Path $script:FixturesPath -Force | Out-Null
164 }
165 }
166
167 It 'Detects missing copyright line' {
168 $content = @"
169#!/usr/bin/env pwsh
170# SPDX-License-Identifier: MIT
171
172Write-Host "Hello World"
173"@
174 Set-Content -Path (Join-Path $script:FixturesPath 'missing-copyright.ps1') -Value $content
175
176 $outputPath = Join-Path $script:FixturesPath 'results-missing-copyright.json'
177 Invoke-CopyrightHeaderCheck -Path $script:FixturesPath -FileExtensions @('missing-copyright.ps1') -OutputPath $outputPath
178
179 $results = Get-Content $outputPath | ConvertFrom-Json
180 $file = $results.results | Where-Object { $_.file -like '*missing-copyright.ps1' }
181
182 $file.hasCopyright | Should -BeFalse
183 $file.hasSpdx | Should -BeTrue
184 $file.valid | Should -BeFalse
185 }
186
187 It 'Detects missing SPDX line' {
188 $content = @"
189#!/usr/bin/env pwsh
190# Copyright (c) Microsoft Corporation.
191
192Write-Host "Hello World"
193"@
194 Set-Content -Path (Join-Path $script:FixturesPath 'missing-spdx.ps1') -Value $content
195
196 $outputPath = Join-Path $script:FixturesPath 'results-missing-spdx.json'
197 Invoke-CopyrightHeaderCheck -Path $script:FixturesPath -FileExtensions @('missing-spdx.ps1') -OutputPath $outputPath
198
199 $results = Get-Content $outputPath | ConvertFrom-Json
200 $file = $results.results | Where-Object { $_.file -like '*missing-spdx.ps1' }
201
202 $file.hasCopyright | Should -BeTrue
203 $file.hasSpdx | Should -BeFalse
204 $file.valid | Should -BeFalse
205 }
206
207 It 'Detects missing both headers' {
208 $content = @"
209#!/usr/bin/env pwsh
210
211Write-Host "Hello World"
212"@
213 Set-Content -Path (Join-Path $script:FixturesPath 'missing-both.ps1') -Value $content
214
215 $outputPath = Join-Path $script:FixturesPath 'results-missing-both.json'
216 Invoke-CopyrightHeaderCheck -Path $script:FixturesPath -FileExtensions @('missing-both.ps1') -OutputPath $outputPath
217
218 $results = Get-Content $outputPath | ConvertFrom-Json
219 $file = $results.results | Where-Object { $_.file -like '*missing-both.ps1' }
220
221 $file.hasCopyright | Should -BeFalse
222 $file.hasSpdx | Should -BeFalse
223 $file.valid | Should -BeFalse
224 }
225
226 It 'Detects headers at incorrect line positions (too late in file)' {
227 # Headers appearing after line 15 should not be detected
228 $content = @"
229#!/usr/bin/env pwsh
230# Line 2
231# Line 3
232# Line 4
233# Line 5
234# Line 6
235# Line 7
236# Line 8
237# Line 9
238# Line 10
239# Line 11
240# Line 12
241# Line 13
242# Line 14
243# Line 15
244# Line 16
245# Copyright (c) Microsoft Corporation.
246# SPDX-License-Identifier: MIT
247
248Write-Host "Headers too late"
249"@
250 Set-Content -Path (Join-Path $script:FixturesPath 'headers-too-late.ps1') -Value $content
251
252 $outputPath = Join-Path $script:FixturesPath 'results-headers-too-late.json'
253 Invoke-CopyrightHeaderCheck -Path $script:FixturesPath -FileExtensions @('headers-too-late.ps1') -OutputPath $outputPath
254
255 $results = Get-Content $outputPath | ConvertFrom-Json
256 $file = $results.results | Where-Object { $_.file -like '*headers-too-late.ps1' }
257
258 # Headers should NOT be found because they're past line 15
259 $file.hasCopyright | Should -BeFalse
260 $file.hasSpdx | Should -BeFalse
261 $file.valid | Should -BeFalse
262 }
263}
264
265#endregion
266
267#region Parameter Tests
268
269Describe 'Test-CopyrightHeaders Parameters' -Tag 'Unit' {
270 It 'Accepts Path parameter' {
271 { Invoke-CopyrightHeaderCheck -Path $script:FixturesPath -OutputPath (Join-Path $script:FixturesPath 'test.json') } | Should -Not -Throw
272 }
273
274 It 'Accepts FileExtensions parameter' {
275 { Invoke-CopyrightHeaderCheck -Path $script:FixturesPath -FileExtensions @('*.ps1') -OutputPath (Join-Path $script:FixturesPath 'test.json') } | Should -Not -Throw
276 }
277
278 It 'Accepts ExcludePaths parameter' {
279 { Invoke-CopyrightHeaderCheck -Path $script:FixturesPath -ExcludePaths @('node_modules') -OutputPath (Join-Path $script:FixturesPath 'test.json') } | Should -Not -Throw
280 }
281
282 It 'Throws with FailOnMissing when files missing headers' {
283 $content = @"
284#!/usr/bin/env pwsh
285Write-Host "No headers"
286"@
287 Set-Content -Path (Join-Path $script:FixturesPath 'no-headers.ps1') -Value $content
288
289 { Invoke-CopyrightHeaderCheck -Path $script:FixturesPath -FileExtensions @('no-headers.ps1') -OutputPath (Join-Path $script:FixturesPath 'fail-test.json') -FailOnMissing } | Should -Throw '*missing required headers*'
290 }
291}
292
293#endregion
294
295#region CI Annotation Tests
296
297Describe 'Test-CopyrightHeaders CI Annotations' -Tag 'Unit' {
298 BeforeAll {
299 if (-not (Test-Path $script:FixturesPath)) {
300 New-Item -ItemType Directory -Path $script:FixturesPath -Force | Out-Null
301 }
302 }
303
304 BeforeEach {
305 Mock Write-CIAnnotation {}
306 Mock Write-CIStepSummary {}
307 }
308
309 It 'Calls Write-CIAnnotation for each failing file' {
310 $missingBoth = @"
311#!/usr/bin/env pwsh
312Write-Host "No headers"
313"@
314 $missingSpdx = @"
315#!/usr/bin/env pwsh
316# Copyright (c) Microsoft Corporation.
317Write-Host "Missing SPDX"
318"@
319 Set-Content -Path (Join-Path $script:FixturesPath 'ci-missing1.ps1') -Value $missingBoth
320 Set-Content -Path (Join-Path $script:FixturesPath 'ci-missing2.ps1') -Value $missingSpdx
321
322 Invoke-CopyrightHeaderCheck -Path $script:FixturesPath -FileExtensions @('ci-missing1.ps1', 'ci-missing2.ps1') -OutputPath (Join-Path $script:FixturesPath 'ci-ann.json')
323
324 Should -Invoke Write-CIAnnotation -Times 2 -Exactly
325 }
326
327 It 'Does not call Write-CIAnnotation for passing files' {
328 $valid = @"
329#!/usr/bin/env pwsh
330# Copyright (c) Microsoft Corporation.
331# SPDX-License-Identifier: MIT
332Write-Host "Valid"
333"@
334 Set-Content -Path (Join-Path $script:FixturesPath 'ci-valid.ps1') -Value $valid
335
336 Invoke-CopyrightHeaderCheck -Path $script:FixturesPath -FileExtensions @('ci-valid.ps1') -OutputPath (Join-Path $script:FixturesPath 'ci-ann-valid.json')
337
338 Should -Invoke Write-CIAnnotation -Times 0 -Exactly
339 }
340
341 It 'Annotation message includes missing header types' {
342 $missingSpdx = @"
343#!/usr/bin/env pwsh
344# Copyright (c) Microsoft Corporation.
345Write-Host "Missing SPDX"
346"@
347 Set-Content -Path (Join-Path $script:FixturesPath 'ci-spdx-only.ps1') -Value $missingSpdx
348
349 Invoke-CopyrightHeaderCheck -Path $script:FixturesPath -FileExtensions @('ci-spdx-only.ps1') -OutputPath (Join-Path $script:FixturesPath 'ci-ann-spdx.json')
350
351 Should -Invoke Write-CIAnnotation -Times 1 -Exactly -ParameterFilter {
352 $Message -like '*SPDX*' -and $Level -eq 'Warning' -and
353 $File -eq ([System.IO.Path]::GetFullPath((Join-Path $script:FixturesPath 'ci-spdx-only.ps1')))
354 }
355 }
356
357 It 'Annotation message lists both header types when both missing' {
358 $missingBoth = @"
359#!/usr/bin/env pwsh
360Write-Host "No headers"
361"@
362 Set-Content -Path (Join-Path $script:FixturesPath 'ci-both-missing.ps1') -Value $missingBoth
363
364 Invoke-CopyrightHeaderCheck -Path $script:FixturesPath -FileExtensions @('ci-both-missing.ps1') -OutputPath (Join-Path $script:FixturesPath 'ci-ann-both.json')
365
366 Should -Invoke Write-CIAnnotation -Times 1 -Exactly -ParameterFilter {
367 $Message -like '*copyright*' -and $Message -like '*SPDX*' -and $Level -eq 'Warning'
368 }
369 }
370
371 It 'Annotation uses Warning level' {
372 $missing = @"
373#!/usr/bin/env pwsh
374Write-Host "No headers"
375"@
376 Set-Content -Path (Join-Path $script:FixturesPath 'ci-warn.ps1') -Value $missing
377
378 Invoke-CopyrightHeaderCheck -Path $script:FixturesPath -FileExtensions @('ci-warn.ps1') -OutputPath (Join-Path $script:FixturesPath 'ci-ann-warn.json')
379
380 Should -Invoke Write-CIAnnotation -Times 1 -Exactly -ParameterFilter {
381 $Level -eq 'Warning' -and $Line -eq 1
382 }
383 }
384}
385
386#endregion
387
388#region CI Step Summary Tests
389
390Describe 'Test-CopyrightHeaders Step Summary' -Tag 'Unit' {
391 BeforeAll {
392 if (-not (Test-Path $script:FixturesPath)) {
393 New-Item -ItemType Directory -Path $script:FixturesPath -Force | Out-Null
394 }
395 }
396
397 BeforeEach {
398 Mock Write-CIAnnotation {}
399 Mock Write-CIStepSummary {}
400 }
401
402 It 'Calls Write-CIStepSummary when all files pass' {
403 $valid = @"
404#!/usr/bin/env pwsh
405# Copyright (c) Microsoft Corporation.
406# SPDX-License-Identifier: MIT
407Write-Host "Valid"
408"@
409 Set-Content -Path (Join-Path $script:FixturesPath 'ci-sum-valid.ps1') -Value $valid
410
411 Invoke-CopyrightHeaderCheck -Path $script:FixturesPath -FileExtensions @('ci-sum-valid.ps1') -OutputPath (Join-Path $script:FixturesPath 'ci-sum-valid.json')
412
413 Should -Invoke Write-CIStepSummary -Times 2 -Exactly
414 Should -Invoke Write-CIStepSummary -Times 1 -Exactly -ParameterFilter {
415 $Content -like '*Passed*'
416 }
417 }
418
419 It 'Calls Write-CIStepSummary with failure table when files fail' {
420 $missing = @"
421#!/usr/bin/env pwsh
422Write-Host "No headers"
423"@
424 Set-Content -Path (Join-Path $script:FixturesPath 'ci-sum-fail.ps1') -Value $missing
425
426 Invoke-CopyrightHeaderCheck -Path $script:FixturesPath -FileExtensions @('ci-sum-fail.ps1') -OutputPath (Join-Path $script:FixturesPath 'ci-sum-fail.json')
427
428 Should -Invoke Write-CIStepSummary -Times 2 -Exactly
429 Should -Invoke Write-CIStepSummary -Times 1 -Exactly -ParameterFilter {
430 $Content -like '*Failed*' -and $Content -like '*Missing Headers*'
431 }
432 }
433
434 It 'Summary contains compliance metrics' {
435 $missing = @"
436#!/usr/bin/env pwsh
437Write-Host "No headers"
438"@
439 Set-Content -Path (Join-Path $script:FixturesPath 'ci-sum-metrics.ps1') -Value $missing
440
441 Invoke-CopyrightHeaderCheck -Path $script:FixturesPath -FileExtensions @('ci-sum-metrics.ps1') -OutputPath (Join-Path $script:FixturesPath 'ci-sum-metrics.json')
442
443 Should -Invoke Write-CIStepSummary -Times 1 -Exactly -ParameterFilter {
444 $Content -like '*Total Files*' -and $Content -like '*Compliance*'
445 }
446 }
447
448 It 'Summary header always emitted' {
449 $valid = @"
450#!/usr/bin/env pwsh
451# Copyright (c) Microsoft Corporation.
452# SPDX-License-Identifier: MIT
453Write-Host "Valid"
454"@
455 Set-Content -Path (Join-Path $script:FixturesPath 'ci-sum-header.ps1') -Value $valid
456
457 Invoke-CopyrightHeaderCheck -Path $script:FixturesPath -FileExtensions @('ci-sum-header.ps1') -OutputPath (Join-Path $script:FixturesPath 'ci-sum-header.json')
458
459 Should -Invoke Write-CIStepSummary -Times 1 -Exactly -ParameterFilter {
460 $Content -like '*Copyright Header Validation*'
461 }
462 }
463}
464
465#endregion
466
467#region Output Format Tests
468
469Describe 'Test-CopyrightHeaders Output Format' -Tag 'Unit' {
470 BeforeAll {
471 $content = @"
472#!/usr/bin/env pwsh
473# Copyright (c) Microsoft Corporation.
474# SPDX-License-Identifier: MIT
475
476Write-Host "Test"
477"@
478 if (-not (Test-Path $script:FixturesPath)) {
479 New-Item -ItemType Directory -Path $script:FixturesPath -Force | Out-Null
480 }
481 Set-Content -Path (Join-Path $script:FixturesPath 'output-test.ps1') -Value $content
482
483 $script:OutputPath = Join-Path $script:FixturesPath 'output-format.json'
484 Invoke-CopyrightHeaderCheck -Path $script:FixturesPath -FileExtensions @('output-test.ps1') -OutputPath $script:OutputPath
485 }
486
487 It 'Outputs valid JSON' {
488 { Get-Content $script:OutputPath | ConvertFrom-Json } | Should -Not -Throw
489 }
490
491 It 'Contains required fields' {
492 $results = Get-Content $script:OutputPath | ConvertFrom-Json
493
494 $results.PSObject.Properties.Name | Should -Contain 'timestamp'
495 $results.PSObject.Properties.Name | Should -Contain 'totalFiles'
496 $results.PSObject.Properties.Name | Should -Contain 'filesWithHeaders'
497 $results.PSObject.Properties.Name | Should -Contain 'filesMissingHeaders'
498 $results.PSObject.Properties.Name | Should -Contain 'results'
499 }
500
501 It 'Contains compliance percentage' {
502 $results = Get-Content $script:OutputPath | ConvertFrom-Json
503
504 $results.PSObject.Properties.Name | Should -Contain 'compliancePercentage'
505 $results.compliancePercentage | Should -BeOfType [double]
506 }
507
508 It 'Results contain file details' {
509 $results = Get-Content $script:OutputPath | ConvertFrom-Json
510
511 $results.results.Count | Should -BeGreaterThan 0
512 $results.results[0].PSObject.Properties.Name | Should -Contain 'file'
513 $results.results[0].PSObject.Properties.Name | Should -Contain 'hasCopyright'
514 $results.results[0].PSObject.Properties.Name | Should -Contain 'hasSpdx'
515 $results.results[0].PSObject.Properties.Name | Should -Contain 'valid'
516 }
517}
518
519#endregion
520