Skip to content

Commit d5cfadd

Browse files
authored
Merge pull request #1371 from qtomlinson/qt/fix_validator
Add gradleplugin type to coordinates schema
2 parents 989eb0d + 9833051 commit d5cfadd

File tree

2 files changed

+201
-0
lines changed

2 files changed

+201
-0
lines changed

schemas/coordinates-1.0.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
"golang",
4747
"mavencentral",
4848
"mavengoogle",
49+
"gradleplugin",
4950
"nuget",
5051
"rubygems",
5152
"pypi",

test/schemas/validatorTest.js

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
// (c) Copyright 2025, SAP SE and ClearlyDefined contributors. Licensed under the MIT license.
2+
// SPDX-License-Identifier: MIT
3+
4+
const chai = require('chai')
5+
const { expect } = chai
6+
const validator = require('../../schemas/validator')
7+
8+
describe('Validator - Coordinates Schema Tests', () => {
9+
describe('Valid coordinates validation', () => {
10+
const validCoordinatesByType = [
11+
{
12+
type: 'npm',
13+
coordinates: [
14+
{ type: 'npm', provider: 'npmjs', name: 'redis', revision: '0.1.0' },
15+
{ type: 'npm', provider: 'npmjs', namespace: '@types', name: 'node', revision: '18.11.9' }
16+
]
17+
},
18+
{
19+
type: 'conda',
20+
coordinates: [
21+
{
22+
type: 'conda',
23+
provider: 'conda-forge',
24+
namespace: 'linux-aarch64',
25+
name: 'numpy',
26+
revision: '1.16.6-py36hdc1b780_0'
27+
},
28+
{
29+
type: 'condasrc',
30+
provider: 'conda-forge',
31+
name: 'bzip2',
32+
revision: '1.0.8'
33+
}
34+
]
35+
},
36+
{
37+
type: 'crate',
38+
coordinates: [{ type: 'crate', provider: 'cratesio', name: 'ratatui', revision: '0.26.0' }]
39+
},
40+
{
41+
type: 'deb',
42+
coordinates: [
43+
{ type: 'deb', provider: 'debian', name: 'mini-httpd', revision: '1.30-0.2_arm64' },
44+
{ type: 'debsrc', provider: 'debian', name: 'mini-httpd', revision: '1.30-0.2' }
45+
]
46+
},
47+
{
48+
type: 'git',
49+
coordinates: [
50+
{ type: 'git', provider: 'gitlab', namespace: 'gitlab-org', name: 'gitlab', revision: '15.6.0-ee' },
51+
{
52+
type: 'git',
53+
provider: 'github',
54+
namespace: 'ratatui-org',
55+
name: 'ratatui',
56+
revision: 'bcf43688ec4a13825307aef88f3cdcd007b32641'
57+
}
58+
]
59+
},
60+
{
61+
type: 'go',
62+
coordinates: [{ type: 'go', provider: 'golang', namespace: 'rsc.io', name: 'quote', revision: 'v1.3.0' }]
63+
},
64+
{
65+
type: 'maven',
66+
coordinates: [
67+
{
68+
type: 'maven',
69+
provider: 'mavencentral',
70+
namespace: 'org.apache.httpcomponents',
71+
name: 'httpcore',
72+
revision: '4.4.16'
73+
},
74+
{
75+
type: 'maven',
76+
provider: 'mavengoogle',
77+
namespace: 'android.arch.lifecycle',
78+
name: 'common',
79+
revision: '1.0.1'
80+
},
81+
{
82+
type: 'maven',
83+
provider: 'gradleplugin',
84+
namespace: 'io.github.lognet',
85+
name: 'grpc-spring-boot-starter-gradle-plugin',
86+
revision: '4.6.0'
87+
},
88+
{
89+
type: 'sourcearchive',
90+
provider: 'mavencentral',
91+
namespace: 'org.apache.httpcomponents',
92+
name: 'httpcore',
93+
revision: '4.1'
94+
}
95+
]
96+
},
97+
{
98+
type: 'composer',
99+
coordinates: [
100+
{
101+
type: 'composer',
102+
provider: 'packagist',
103+
namespace: 'symfony',
104+
name: 'polyfill-mbstring',
105+
revision: 'v1.28.0'
106+
}
107+
]
108+
},
109+
{
110+
type: 'nuget',
111+
coordinates: [{ type: 'nuget', provider: 'nuget', name: 'NuGet.Protocol', revision: '6.7.1' }]
112+
},
113+
{
114+
type: 'pod',
115+
coordinates: [
116+
{ type: 'pod', provider: 'cocoapods', name: 'SoftButton', revision: '0.1.0' },
117+
{ type: 'pod', provider: 'cocoapods', name: 'xcbeautify', revision: '0.9.1' }
118+
]
119+
},
120+
{
121+
type: 'pypi',
122+
coordinates: [
123+
{ type: 'pypi', provider: 'pypi', name: 'platformdirs', revision: '4.2.0' },
124+
{ type: 'pypi', provider: 'pypi', name: 'sdbus', revision: '0.12.0' }
125+
]
126+
},
127+
{
128+
type: 'gem',
129+
coordinates: [{ type: 'gem', provider: 'rubygems', name: 'sorbet', revision: '0.5.11226' }]
130+
}
131+
]
132+
133+
// Test valid coordinate examples for each type
134+
validCoordinatesByType.forEach(({ type, coordinates }) => {
135+
it(`validates valid ${type} coordinates`, () => {
136+
coordinates.forEach((coord, index) => {
137+
const isValid = validator.validate('coordinates-1.0', coord)
138+
expect(isValid, `Failed for ${type} coordinate ${index}: ${JSON.stringify(coord)}`).to.be.true
139+
expect(validator.errors).to.be.null
140+
})
141+
})
142+
})
143+
})
144+
145+
describe('Invalid coordinates validation', () => {
146+
// Invalid coordinate examples for each error type
147+
const invalidCoordinatesByType = [
148+
{
149+
type: 'missing-required-fields',
150+
coordinates: [
151+
{ provider: 'npmjs', name: 'test', revision: '1.0.0' }, // missing type
152+
{ type: 'npm', revision: '1.0.0' }, // missing name
153+
{ type: 'npm', name: 'test' } // missing revision
154+
]
155+
},
156+
{
157+
type: 'invalid-field-values',
158+
coordinates: [
159+
{ type: 'invalid', name: 'test', revision: '1.0.0' }, // invalid type
160+
{ type: 'npm', provider: 'invalid', name: 'test', revision: '1.0.0' } // invalid provider
161+
]
162+
},
163+
{
164+
type: 'invalid-field-types',
165+
coordinates: [
166+
{ type: null, name: 'test', revision: '1.0.0' }, // null type
167+
{ type: 123, name: 'test', revision: '1.0.0' }, // numeric type
168+
{ type: 'npm', provider: ['npmjs'], name: 'test', revision: '1.0.0' }, // array provider
169+
{ type: 'npm', name: true, revision: '1.0.0' }, // boolean name
170+
{ type: 'npm', name: 'test', revision: 123 } // numeric revision
171+
]
172+
},
173+
{
174+
type: 'additional-properties',
175+
coordinates: [
176+
{ type: 'npm', name: 'test', revision: '1.0.0', invalid: 'property' },
177+
{ type: 'npm', name: 'test', revision: '1.0.0', extra: 'field', another: 'invalid' }
178+
]
179+
},
180+
{
181+
type: 'invalid-input-types',
182+
coordinates: [null, undefined, 'string', 123, [], true, false]
183+
}
184+
]
185+
186+
// Test invalid coordinate examples for each error type
187+
invalidCoordinatesByType.forEach(({ type, coordinates }) => {
188+
it(`rejects coordinates with ${type}`, () => {
189+
coordinates.forEach((coord, index) => {
190+
const isValid = validator.validate('coordinates-1.0', coord)
191+
expect(isValid, `Expected coordinate to be invalid for ${type} case ${index}: ${JSON.stringify(coord)}`).to.be
192+
.false
193+
expect(validator.errors).to.not.be.null
194+
expect(validator.errors).to.be.an('array')
195+
expect(validator.errors.length).to.be.greaterThan(0)
196+
})
197+
})
198+
})
199+
})
200+
})

0 commit comments

Comments
 (0)