microsoft/hve-core

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
feat/context-working

Branches

Tags

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

Clone

HTTPS

Download ZIP

scripts/tests/plugins/Validate-Marketplace.Tests.ps1

414lines · modecode

1#Requires -Modules Pester
2# Copyright (c) Microsoft Corporation.
3# SPDX-License-Identifier: MIT
4
5BeforeAll {
6 . $PSScriptRoot/../../plugins/Validate-Marketplace.ps1
7}
8
9Describe 'Test-PluginSourceFormat' {
10 It 'Returns empty string for valid source' {
11 $result = Test-PluginSourceFormat -Source 'hve-core'
12 $result | Should -BeNullOrEmpty
13 }
14
15 It 'Returns error for source with forward slash' {
16 $result = Test-PluginSourceFormat -Source 'path/to/plugin'
17 $result | Should -BeLike '*must not contain path separators*'
18 }
19
20 It 'Returns error for source with backslash' {
21 $result = Test-PluginSourceFormat -Source 'path\to\plugin'
22 $result | Should -BeLike '*must not contain path separators*'
23 }
24
25 It 'Returns error for source with relative path prefix' {
26 $result = Test-PluginSourceFormat -Source './my-plugin'
27 $result | Should -BeLike '*must not contain*'
28 }
29}
30
31Describe 'Test-PluginSourceDirectory' {
32 BeforeAll {
33 $script:pluginsRoot = Join-Path $TestDrive 'plugins'
34 New-Item -ItemType Directory -Path (Join-Path $script:pluginsRoot 'existing-plugin') -Force | Out-Null
35 }
36
37 It 'Returns empty string when directory exists' {
38 $result = Test-PluginSourceDirectory -Source 'existing-plugin' -PluginsRoot $script:pluginsRoot
39 $result | Should -BeNullOrEmpty
40 }
41
42 It 'Returns error when directory does not exist' {
43 $result = Test-PluginSourceDirectory -Source 'missing-plugin' -PluginsRoot $script:pluginsRoot
44 $result | Should -BeLike '*plugin source directory not found*'
45 }
46}
47
48Describe 'Invoke-MarketplaceValidation - missing manifest' {
49 BeforeAll {
50 $script:repoRoot = Join-Path $TestDrive 'repo-no-manifest'
51 New-Item -ItemType Directory -Path $script:repoRoot -Force | Out-Null
52 }
53
54 It 'Returns failure when marketplace.json does not exist' {
55 $result = Invoke-MarketplaceValidation -RepoRoot $script:repoRoot
56 $result.Success | Should -BeFalse
57 $result.ErrorCount | Should -Be 1
58 }
59}
60
61Describe 'Invoke-MarketplaceValidation - invalid JSON' {
62 BeforeAll {
63 $script:repoRoot = Join-Path $TestDrive 'repo-bad-json'
64 $manifestDir = Join-Path $script:repoRoot '.github/plugin'
65 New-Item -ItemType Directory -Path $manifestDir -Force | Out-Null
66 Set-Content -Path (Join-Path $manifestDir 'marketplace.json') -Value '{ invalid json }'
67 }
68
69 It 'Returns failure for malformed JSON' {
70 $result = Invoke-MarketplaceValidation -RepoRoot $script:repoRoot
71 $result.Success | Should -BeFalse
72 $result.ErrorCount | Should -Be 1
73 }
74}
75
76Describe 'Invoke-MarketplaceValidation - missing required fields' {
77 BeforeAll {
78 $script:repoRoot = Join-Path $TestDrive 'repo-missing-fields'
79 $manifestDir = Join-Path $script:repoRoot '.github/plugin'
80 New-Item -ItemType Directory -Path $manifestDir -Force | Out-Null
81 # Missing 'owner' and 'plugins'
82 $json = @{ name = 'test'; metadata = @{ description = 'd'; version = '1.0.0'; pluginRoot = 'plugins' } } | ConvertTo-Json -Depth 5
83 Set-Content -Path (Join-Path $manifestDir 'marketplace.json') -Value $json
84 }
85
86 It 'Returns errors for missing top-level fields' {
87 $result = Invoke-MarketplaceValidation -RepoRoot $script:repoRoot
88 $result.Success | Should -BeFalse
89 $result.ErrorCount | Should -BeGreaterOrEqual 2
90 }
91}
92
93Describe 'Invoke-MarketplaceValidation - missing metadata fields' {
94 BeforeAll {
95 $script:repoRoot = Join-Path $TestDrive 'repo-missing-metadata'
96 $manifestDir = Join-Path $script:repoRoot '.github/plugin'
97 New-Item -ItemType Directory -Path $manifestDir -Force | Out-Null
98 $pluginsDir = Join-Path $script:repoRoot 'plugins/my-plugin'
99 New-Item -ItemType Directory -Path $pluginsDir -Force | Out-Null
100 # metadata missing 'version' and 'pluginRoot'
101 $json = @{
102 name = 'test'
103 metadata = @{ description = 'd' }
104 owner = @{ name = 'owner' }
105 plugins = @(@{ name = 'my-plugin'; source = 'my-plugin'; description = 'd'; version = '1.0.0' })
106 } | ConvertTo-Json -Depth 5
107 Set-Content -Path (Join-Path $manifestDir 'marketplace.json') -Value $json
108 }
109
110 It 'Returns errors for missing metadata fields' {
111 $result = Invoke-MarketplaceValidation -RepoRoot $script:repoRoot
112 $result.Success | Should -BeFalse
113 $result.ErrorCount | Should -BeGreaterOrEqual 2
114 }
115}
116
117Describe 'Invoke-MarketplaceValidation - missing owner name' {
118 BeforeAll {
119 $script:repoRoot = Join-Path $TestDrive 'repo-missing-owner'
120 $manifestDir = Join-Path $script:repoRoot '.github/plugin'
121 New-Item -ItemType Directory -Path $manifestDir -Force | Out-Null
122 $pluginsDir = Join-Path $script:repoRoot 'plugins/my-plugin'
123 New-Item -ItemType Directory -Path $pluginsDir -Force | Out-Null
124 Set-Content -Path (Join-Path $script:repoRoot 'package.json') -Value '{"version":"1.0.0"}'
125 $json = @{
126 name = 'test'
127 metadata = @{ description = 'd'; version = '1.0.0'; pluginRoot = 'plugins' }
128 owner = @{}
129 plugins = @(@{ name = 'my-plugin'; source = 'my-plugin'; description = 'd'; version = '1.0.0' })
130 } | ConvertTo-Json -Depth 5
131 Set-Content -Path (Join-Path $manifestDir 'marketplace.json') -Value $json
132 }
133
134 It 'Returns error for missing owner name' {
135 $result = Invoke-MarketplaceValidation -RepoRoot $script:repoRoot
136 $result.Success | Should -BeFalse
137 $result.ErrorCount | Should -BeGreaterOrEqual 1
138 }
139}
140
141Describe 'Invoke-MarketplaceValidation - version mismatch' {
142 BeforeAll {
143 $script:repoRoot = Join-Path $TestDrive 'repo-version-mismatch'
144 $manifestDir = Join-Path $script:repoRoot '.github/plugin'
145 New-Item -ItemType Directory -Path $manifestDir -Force | Out-Null
146 $pluginsDir = Join-Path $script:repoRoot 'plugins/my-plugin'
147 New-Item -ItemType Directory -Path $pluginsDir -Force | Out-Null
148 Set-Content -Path (Join-Path $script:repoRoot 'package.json') -Value '{"version":"2.0.0"}'
149 $json = @{
150 name = 'test'
151 metadata = @{ description = 'd'; version = '1.0.0'; pluginRoot = 'plugins' }
152 owner = @{ name = 'owner' }
153 plugins = @(@{ name = 'my-plugin'; source = 'my-plugin'; description = 'd'; version = '1.0.0' })
154 } | ConvertTo-Json -Depth 5
155 Set-Content -Path (Join-Path $manifestDir 'marketplace.json') -Value $json
156 }
157
158 It 'Returns error when metadata version does not match package.json' {
159 $result = Invoke-MarketplaceValidation -RepoRoot $script:repoRoot
160 $result.Success | Should -BeFalse
161 $result.ErrorCount | Should -BeGreaterOrEqual 1
162 }
163}
164
165Describe 'Invoke-MarketplaceValidation - empty plugins array' {
166 BeforeAll {
167 $script:repoRoot = Join-Path $TestDrive 'repo-empty-plugins'
168 $manifestDir = Join-Path $script:repoRoot '.github/plugin'
169 New-Item -ItemType Directory -Path $manifestDir -Force | Out-Null
170 Set-Content -Path (Join-Path $script:repoRoot 'package.json') -Value '{"version":"1.0.0"}'
171 $json = @{
172 name = 'test'
173 metadata = @{ description = 'd'; version = '1.0.0'; pluginRoot = 'plugins' }
174 owner = @{ name = 'owner' }
175 plugins = @()
176 } | ConvertTo-Json -Depth 5
177 Set-Content -Path (Join-Path $manifestDir 'marketplace.json') -Value $json
178 }
179
180 It 'Returns error for empty plugins array' {
181 $result = Invoke-MarketplaceValidation -RepoRoot $script:repoRoot
182 $result.Success | Should -BeFalse
183 $result.ErrorCount | Should -BeGreaterOrEqual 1
184 }
185}
186
187Describe 'Invoke-MarketplaceValidation - duplicate plugin names' {
188 BeforeAll {
189 $script:repoRoot = Join-Path $TestDrive 'repo-dupes'
190 $manifestDir = Join-Path $script:repoRoot '.github/plugin'
191 New-Item -ItemType Directory -Path $manifestDir -Force | Out-Null
192 New-Item -ItemType Directory -Path (Join-Path $script:repoRoot 'plugins/my-plugin') -Force | Out-Null
193 Set-Content -Path (Join-Path $script:repoRoot 'package.json') -Value '{"version":"1.0.0"}'
194 $json = @{
195 name = 'test'
196 metadata = @{ description = 'd'; version = '1.0.0'; pluginRoot = 'plugins' }
197 owner = @{ name = 'owner' }
198 plugins = @(
199 @{ name = 'my-plugin'; source = 'my-plugin'; description = 'd1'; version = '1.0.0' }
200 @{ name = 'my-plugin'; source = 'my-plugin'; description = 'd2'; version = '1.0.0' }
201 )
202 } | ConvertTo-Json -Depth 5
203 Set-Content -Path (Join-Path $manifestDir 'marketplace.json') -Value $json
204 }
205
206 It 'Returns error for duplicate plugin names' {
207 $result = Invoke-MarketplaceValidation -RepoRoot $script:repoRoot
208 $result.Success | Should -BeFalse
209 $result.ErrorCount | Should -BeGreaterOrEqual 1
210 }
211}
212
213Describe 'Invoke-MarketplaceValidation - plugin source errors' {
214 BeforeAll {
215 $script:repoRoot = Join-Path $TestDrive 'repo-source-errors'
216 $manifestDir = Join-Path $script:repoRoot '.github/plugin'
217 New-Item -ItemType Directory -Path $manifestDir -Force | Out-Null
218 Set-Content -Path (Join-Path $script:repoRoot 'package.json') -Value '{"version":"1.0.0"}'
219 $json = @{
220 name = 'test'
221 metadata = @{ description = 'd'; version = '1.0.0'; pluginRoot = 'plugins' }
222 owner = @{ name = 'owner' }
223 plugins = @(
224 @{ name = 'bad/source'; source = 'bad/source'; description = 'd'; version = '1.0.0' }
225 )
226 } | ConvertTo-Json -Depth 5
227 Set-Content -Path (Join-Path $manifestDir 'marketplace.json') -Value $json
228 }
229
230 It 'Returns error for plugin with path separator in source' {
231 $result = Invoke-MarketplaceValidation -RepoRoot $script:repoRoot
232 $result.Success | Should -BeFalse
233 $result.ErrorCount | Should -BeGreaterOrEqual 1
234 }
235}
236
237Describe 'Invoke-MarketplaceValidation - name-source mismatch' {
238 BeforeAll {
239 $script:repoRoot = Join-Path $TestDrive 'repo-name-mismatch'
240 $manifestDir = Join-Path $script:repoRoot '.github/plugin'
241 New-Item -ItemType Directory -Path $manifestDir -Force | Out-Null
242 New-Item -ItemType Directory -Path (Join-Path $script:repoRoot 'plugins/actual-source') -Force | Out-Null
243 Set-Content -Path (Join-Path $script:repoRoot 'package.json') -Value '{"version":"1.0.0"}'
244 $json = @{
245 name = 'test'
246 metadata = @{ description = 'd'; version = '1.0.0'; pluginRoot = 'plugins' }
247 owner = @{ name = 'owner' }
248 plugins = @(
249 @{ name = 'display-name'; source = 'actual-source'; description = 'd'; version = '1.0.0' }
250 )
251 } | ConvertTo-Json -Depth 5
252 Set-Content -Path (Join-Path $manifestDir 'marketplace.json') -Value $json
253 }
254
255 It 'Returns error when plugin name does not match source' {
256 $result = Invoke-MarketplaceValidation -RepoRoot $script:repoRoot
257 $result.Success | Should -BeFalse
258 $result.ErrorCount | Should -BeGreaterOrEqual 1
259 }
260}
261
262Describe 'Invoke-MarketplaceValidation - plugin version mismatch' {
263 BeforeAll {
264 $script:repoRoot = Join-Path $TestDrive 'repo-plugin-version'
265 $manifestDir = Join-Path $script:repoRoot '.github/plugin'
266 New-Item -ItemType Directory -Path $manifestDir -Force | Out-Null
267 New-Item -ItemType Directory -Path (Join-Path $script:repoRoot 'plugins/my-plugin') -Force | Out-Null
268 Set-Content -Path (Join-Path $script:repoRoot 'package.json') -Value '{"version":"2.0.0"}'
269 $json = @{
270 name = 'test'
271 metadata = @{ description = 'd'; version = '2.0.0'; pluginRoot = 'plugins' }
272 owner = @{ name = 'owner' }
273 plugins = @(
274 @{ name = 'my-plugin'; source = 'my-plugin'; description = 'd'; version = '1.0.0' }
275 )
276 } | ConvertTo-Json -Depth 5
277 Set-Content -Path (Join-Path $manifestDir 'marketplace.json') -Value $json
278 }
279
280 It 'Returns error when plugin version does not match package.json' {
281 $result = Invoke-MarketplaceValidation -RepoRoot $script:repoRoot
282 $result.Success | Should -BeFalse
283 $result.ErrorCount | Should -BeGreaterOrEqual 1
284 }
285}
286
287Describe 'Invoke-MarketplaceValidation - missing plugin fields' {
288 BeforeAll {
289 $script:repoRoot = Join-Path $TestDrive 'repo-missing-plugin-fields'
290 $manifestDir = Join-Path $script:repoRoot '.github/plugin'
291 New-Item -ItemType Directory -Path $manifestDir -Force | Out-Null
292 Set-Content -Path (Join-Path $script:repoRoot 'package.json') -Value '{"version":"1.0.0"}'
293 # Plugin missing 'description' and 'version'
294 $json = @{
295 name = 'test'
296 metadata = @{ description = 'd'; version = '1.0.0'; pluginRoot = 'plugins' }
297 owner = @{ name = 'owner' }
298 plugins = @(
299 @{ name = 'my-plugin'; source = 'my-plugin' }
300 )
301 } | ConvertTo-Json -Depth 5
302 Set-Content -Path (Join-Path $manifestDir 'marketplace.json') -Value $json
303 }
304
305 It 'Returns errors for missing plugin-level fields' {
306 $result = Invoke-MarketplaceValidation -RepoRoot $script:repoRoot
307 $result.Success | Should -BeFalse
308 $result.ErrorCount | Should -BeGreaterOrEqual 2
309 }
310}
311
312Describe 'Invoke-MarketplaceValidation - valid manifest' {
313 BeforeAll {
314 $script:repoRoot = Join-Path $TestDrive 'repo-valid'
315 $manifestDir = Join-Path $script:repoRoot '.github/plugin'
316 New-Item -ItemType Directory -Path $manifestDir -Force | Out-Null
317 New-Item -ItemType Directory -Path (Join-Path $script:repoRoot 'plugins/my-plugin') -Force | Out-Null
318 Set-Content -Path (Join-Path $script:repoRoot 'package.json') -Value '{"version":"1.0.0"}'
319 $json = @{
320 name = 'test'
321 metadata = @{ description = 'd'; version = '1.0.0'; pluginRoot = 'plugins' }
322 owner = @{ name = 'owner' }
323 plugins = @(
324 @{ name = 'my-plugin'; source = 'my-plugin'; description = 'A plugin'; version = '1.0.0' }
325 )
326 } | ConvertTo-Json -Depth 5
327 Set-Content -Path (Join-Path $manifestDir 'marketplace.json') -Value $json
328 }
329
330 It 'Returns success for a valid manifest' {
331 $result = Invoke-MarketplaceValidation -RepoRoot $script:repoRoot
332 $result.Success | Should -BeTrue
333 $result.ErrorCount | Should -Be 0
334 }
335
336 It 'Returns success with multiple valid plugins' {
337 New-Item -ItemType Directory -Path (Join-Path $script:repoRoot 'plugins/other-plugin') -Force | Out-Null
338 $json = @{
339 name = 'test'
340 metadata = @{ description = 'd'; version = '1.0.0'; pluginRoot = 'plugins' }
341 owner = @{ name = 'owner' }
342 plugins = @(
343 @{ name = 'my-plugin'; source = 'my-plugin'; description = 'A plugin'; version = '1.0.0' }
344 @{ name = 'other-plugin'; source = 'other-plugin'; description = 'Another'; version = '1.0.0' }
345 )
346 } | ConvertTo-Json -Depth 5
347 $manifestDir = Join-Path $script:repoRoot '.github/plugin'
348 Set-Content -Path (Join-Path $manifestDir 'marketplace.json') -Value $json
349
350 $result = Invoke-MarketplaceValidation -RepoRoot $script:repoRoot
351 $result.Success | Should -BeTrue
352 $result.ErrorCount | Should -Be 0
353 }
354}
355
356Describe 'Invoke-MarketplaceValidation - JSON output' {
357 BeforeEach {
358 $script:repoRoot = Join-Path $TestDrive 'repo-json-output'
359 $script:manifestDir = Join-Path $script:repoRoot '.github/plugin'
360 New-Item -ItemType Directory -Path $script:manifestDir -Force | Out-Null
361 New-Item -ItemType Directory -Path (Join-Path $script:repoRoot 'plugins/my-plugin') -Force | Out-Null
362 Set-Content -Path (Join-Path $script:repoRoot 'package.json') -Value '{"version":"1.0.0"}'
363 }
364
365 It 'Writes report with expected schema for valid plugin validation' {
366 $outputPath = Join-Path $TestDrive 'logs/marketplace-validation-results.json'
367 $json = @{
368 name = 'test'
369 metadata = @{ description = 'd'; version = '1.0.0'; pluginRoot = 'plugins' }
370 owner = @{ name = 'owner' }
371 plugins = @(
372 @{ name = 'my-plugin'; source = 'my-plugin'; description = 'A plugin'; version = '1.0.0' }
373 )
374 } | ConvertTo-Json -Depth 5
375 Set-Content -Path (Join-Path $script:manifestDir 'marketplace.json') -Value $json
376
377 $result = Invoke-MarketplaceValidation -RepoRoot $script:repoRoot -OutputPath $outputPath
378 $report = Get-Content -Path $outputPath -Raw | ConvertFrom-Json
379
380 $result.Success | Should -BeTrue
381 $report.Timestamp | Should -Not -BeNullOrEmpty
382 { [DateTimeOffset]::Parse($report.Timestamp) } | Should -Not -Throw
383 $report.ErrorCount | Should -Be 0
384 $report.Results.Count | Should -Be 1
385 $report.Results[0].PluginName | Should -Be 'my-plugin'
386 $report.Results[0].IsValid | Should -BeTrue
387 $report.Results[0].Errors | Should -BeNullOrEmpty
388 $report.Results[0].Warnings | Should -BeNullOrEmpty
389 }
390
391 It 'Writes per-plugin errors into JSON results' {
392 $outputPath = Join-Path $TestDrive 'logs/marketplace-validation-results.json'
393 New-Item -ItemType Directory -Path (Join-Path $script:repoRoot 'plugins/actual-source') -Force | Out-Null
394 $json = @{
395 name = 'test'
396 metadata = @{ description = 'd'; version = '1.0.0'; pluginRoot = 'plugins' }
397 owner = @{ name = 'owner' }
398 plugins = @(
399 @{ name = 'display-name'; source = 'actual-source'; description = 'A plugin'; version = '1.0.0' }
400 )
401 } | ConvertTo-Json -Depth 5
402 Set-Content -Path (Join-Path $script:manifestDir 'marketplace.json') -Value $json
403
404 $result = Invoke-MarketplaceValidation -RepoRoot $script:repoRoot -OutputPath $outputPath
405 $report = Get-Content -Path $outputPath -Raw | ConvertFrom-Json
406 $pluginResult = @($report.Results | Where-Object { $_.PluginName -eq 'display-name' })[0]
407
408 $result.Success | Should -BeFalse
409 $report.ErrorCount | Should -BeGreaterThan 0
410 $pluginResult.IsValid | Should -BeFalse
411 $pluginResult.Errors | Should -Contain "name does not match source 'actual-source'"
412 $pluginResult.Warnings | Should -BeNullOrEmpty
413 }
414}
415