Skip to content

Commit 5a495ad

Browse files
committed
Add tests for cocoapods, cpan, and swid validation
Adds comprehensive test coverage for the new validation rules: - cocoapods: Tests for whitespace, plus character, and period prefix restrictions in name component - cpan: Tests for uppercase namespace requirement and optional namespace behavior - swid: Tests for required tag_id qualifier, empty value handling, and GUID lowercase requirement Tests cover both throwing and non-throwing validation modes.
1 parent 2eab1ee commit 5a495ad

File tree

1 file changed

+185
-0
lines changed

1 file changed

+185
-0
lines changed

test/package-url.test.mts

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3418,6 +3418,191 @@ describe('PackageURL', () => {
34183418
const result3 = validateType('type@invalid', false)
34193419
expect(result3).toBe(false)
34203420
})
3421+
3422+
it('should validate cocoapods name restrictions', () => {
3423+
// Test name with whitespace
3424+
expect(
3425+
() => new PackageURL('cocoapods', null, 'Pod Name', null, null, null),
3426+
).toThrow('cocoapods "name" component cannot contain whitespace')
3427+
3428+
// Test name with plus character
3429+
expect(
3430+
() => new PackageURL('cocoapods', null, 'Pod+Name', null, null, null),
3431+
).toThrow(
3432+
'cocoapods "name" component cannot contain a plus (+) character',
3433+
)
3434+
3435+
// Test name beginning with period
3436+
expect(
3437+
() => new PackageURL('cocoapods', null, '.PodName', null, null, null),
3438+
).toThrow('cocoapods "name" component cannot begin with a period')
3439+
3440+
// Test valid cocoapods name
3441+
const validPurl = new PackageURL(
3442+
'cocoapods',
3443+
null,
3444+
'AFNetworking',
3445+
'4.0.0',
3446+
null,
3447+
null,
3448+
)
3449+
expect(validPurl.toString()).toBe('pkg:cocoapods/[email protected]')
3450+
3451+
// Test non-throwing mode
3452+
const result1 = (PurlType['cocoapods'] as any).validate(
3453+
{ name: 'Pod Name' },
3454+
false,
3455+
)
3456+
expect(result1).toBe(false)
3457+
3458+
const result2 = (PurlType['cocoapods'] as any).validate(
3459+
{ name: 'Pod+Name' },
3460+
false,
3461+
)
3462+
expect(result2).toBe(false)
3463+
3464+
const result3 = (PurlType['cocoapods'] as any).validate(
3465+
{ name: '.PodName' },
3466+
false,
3467+
)
3468+
expect(result3).toBe(false)
3469+
})
3470+
3471+
it('should validate cpan namespace requirements', () => {
3472+
// Test lowercase namespace
3473+
expect(
3474+
() =>
3475+
new PackageURL('cpan', 'author', 'Module-Name', null, null, null),
3476+
).toThrow('cpan "namespace" component must be UPPERCASE')
3477+
3478+
// Test mixed case namespace
3479+
expect(
3480+
() =>
3481+
new PackageURL('cpan', 'Author', 'Module-Name', null, null, null),
3482+
).toThrow('cpan "namespace" component must be UPPERCASE')
3483+
3484+
// Test valid cpan with uppercase namespace
3485+
const validPurl = new PackageURL(
3486+
'cpan',
3487+
'AUTHOR',
3488+
'Module-Name',
3489+
'1.0.0',
3490+
null,
3491+
null,
3492+
)
3493+
expect(validPurl.toString()).toBe('pkg:cpan/AUTHOR/[email protected]')
3494+
3495+
// Test valid cpan without namespace (namespace is optional)
3496+
const validPurl2 = new PackageURL(
3497+
'cpan',
3498+
null,
3499+
'DateTime',
3500+
'1.55',
3501+
null,
3502+
null,
3503+
)
3504+
expect(validPurl2.toString()).toBe('pkg:cpan/[email protected]')
3505+
3506+
// Test non-throwing mode
3507+
const result1 = (PurlType['cpan'] as any).validate(
3508+
{ name: 'Module-Name', namespace: 'author' },
3509+
false,
3510+
)
3511+
expect(result1).toBe(false)
3512+
3513+
const result2 = (PurlType['cpan'] as any).validate(
3514+
{ name: 'Module-Name', namespace: 'Author' },
3515+
false,
3516+
)
3517+
expect(result2).toBe(false)
3518+
})
3519+
3520+
it('should validate swid qualifier requirements', () => {
3521+
// Test missing tag_id qualifier
3522+
expect(
3523+
() =>
3524+
new PackageURL(
3525+
'swid',
3526+
'Acme',
3527+
'example.com/Enterprise+Server',
3528+
'1.0.0',
3529+
{},
3530+
null,
3531+
),
3532+
).toThrow('swid requires a "tag_id" qualifier')
3533+
3534+
// Test empty tag_id (whitespace gets normalized away, so this tests missing tag_id)
3535+
expect(
3536+
() =>
3537+
new PackageURL(
3538+
'swid',
3539+
'Acme',
3540+
'example.com/Enterprise+Server',
3541+
'1.0.0',
3542+
{ tag_id: ' ' },
3543+
null,
3544+
),
3545+
).toThrow('swid requires a "tag_id" qualifier')
3546+
3547+
// Test uppercase GUID tag_id
3548+
expect(
3549+
() =>
3550+
new PackageURL(
3551+
'swid',
3552+
'Acme',
3553+
'example.com/Enterprise+Server',
3554+
'1.0.0',
3555+
{ tag_id: '75B8C285-FA7B-485B-B199-4745E3004D0D' },
3556+
null,
3557+
),
3558+
).toThrow('swid "tag_id" qualifier must be lowercase when it is a GUID')
3559+
3560+
// Test valid swid with lowercase GUID
3561+
const validPurl = new PackageURL(
3562+
'swid',
3563+
'Acme',
3564+
'example.com/Enterprise+Server',
3565+
'1.0.0',
3566+
{ tag_id: '75b8c285-fa7b-485b-b199-4745e3004d0d' },
3567+
null,
3568+
)
3569+
expect(validPurl.toString()).toContain(
3570+
'pkg:swid/Acme/example.com%2FEnterprise%[email protected]?tag_id=75b8c285-fa7b-485b-b199-4745e3004d0d',
3571+
)
3572+
3573+
// Test valid swid with non-GUID tag_id (mixed case allowed)
3574+
const validPurl2 = new PackageURL(
3575+
'swid',
3576+
'Acme',
3577+
'example.com/Enterprise+Server',
3578+
'1.0.0',
3579+
{ tag_id: 'CustomTagId123' },
3580+
null,
3581+
)
3582+
expect(validPurl2.toString()).toContain('tag_id=CustomTagId123')
3583+
3584+
// Test non-throwing mode
3585+
const result1 = (PurlType['swid'] as any).validate(
3586+
{ name: 'test', qualifiers: undefined },
3587+
false,
3588+
)
3589+
expect(result1).toBe(false)
3590+
3591+
const result2 = (PurlType['swid'] as any).validate(
3592+
{ name: 'test', qualifiers: { tag_id: ' ' } },
3593+
false,
3594+
)
3595+
expect(result2).toBe(false)
3596+
3597+
const result3 = (PurlType['swid'] as any).validate(
3598+
{
3599+
name: 'test',
3600+
qualifiers: { tag_id: '75B8C285-FA7B-485B-B199-4745E3004D0D' },
3601+
},
3602+
false,
3603+
)
3604+
expect(result3).toBe(false)
3605+
})
34213606
})
34223607
})
34233608
})

0 commit comments

Comments
 (0)