Skip to main content
Glama
security.test.ts17.2 kB
/** * @vitest-environment node */ import { ReportType, ReportStatus, ReportTrend, SeverityDistribution, SecurityIssueStat, ComplianceReport, VulnerabilitySeverity, PackageVersionType, VulnerabilityReachability, VulnerabilityFixability, Package, PackageVersion, Vulnerability, VulnerabilityOccurrence, DependencyVulnerabilitiesParams, VulnerabilitiesResponse, } from '../../models/security'; describe('Security Models', () => { describe('Enum Types', () => { describe('ReportType', () => { it('should define the correct report types', () => { // Compliance-specific report types expect(ReportType.OWASP_TOP_10).toBe('OWASP_TOP_10'); expect(ReportType.SANS_TOP_25).toBe('SANS_TOP_25'); expect(ReportType.MISRA_C).toBe('MISRA_C'); // General report types expect(ReportType.CODE_COVERAGE).toBe('CODE_COVERAGE'); expect(ReportType.CODE_HEALTH_TREND).toBe('CODE_HEALTH_TREND'); expect(ReportType.ISSUE_DISTRIBUTION).toBe('ISSUE_DISTRIBUTION'); expect(ReportType.ISSUES_PREVENTED).toBe('ISSUES_PREVENTED'); expect(ReportType.ISSUES_AUTOFIXED).toBe('ISSUES_AUTOFIXED'); }); it('should have the correct number of values', () => { expect(Object.keys(ReportType).length).toBe(8); }); }); describe('ReportStatus', () => { it('should define the correct report statuses', () => { expect(ReportStatus.PASSING).toBe('PASSING'); expect(ReportStatus.FAILING).toBe('FAILING'); expect(ReportStatus.NOOP).toBe('NOOP'); }); it('should have the correct number of values', () => { expect(Object.keys(ReportStatus).length).toBe(3); }); }); }); describe('Type Definitions', () => { describe('VulnerabilitySeverity', () => { it('should allow valid severity levels', () => { const severities: VulnerabilitySeverity[] = ['NONE', 'LOW', 'MEDIUM', 'HIGH', 'CRITICAL']; severities.forEach((severity) => { expect(typeof severity).toBe('string'); }); }); }); describe('PackageVersionType', () => { it('should allow valid version types', () => { const versionTypes: PackageVersionType[] = ['SEMVER', 'ECOSYSTEM', 'GIT']; versionTypes.forEach((type) => { expect(typeof type).toBe('string'); }); }); }); describe('VulnerabilityReachability', () => { it('should allow valid reachability types', () => { const reachabilityTypes: VulnerabilityReachability[] = [ 'REACHABLE', 'UNREACHABLE', 'UNKNOWN', ]; reachabilityTypes.forEach((type) => { expect(typeof type).toBe('string'); }); }); }); describe('VulnerabilityFixability', () => { it('should allow valid fixability types', () => { const fixabilityTypes: VulnerabilityFixability[] = [ 'ERROR', 'UNFIXABLE', 'GENERATING_FIX', 'POSSIBLY_FIXABLE', 'MANUALLY_FIXABLE', 'AUTO_FIXABLE', ]; fixabilityTypes.forEach((type) => { expect(typeof type).toBe('string'); }); }); }); }); describe('Interface Type Checking', () => { describe('ReportTrend', () => { it('should validate a report trend with all fields', () => { const trend: ReportTrend = { label: 'Last 30 days', value: 85.5, changePercentage: 3.2, }; expect(trend.label).toBe('Last 30 days'); expect(trend.value).toBe(85.5); expect(trend.changePercentage).toBe(3.2); }); it('should allow optional fields to be undefined', () => { const trend: ReportTrend = {}; expect(trend.label).toBeUndefined(); expect(trend.value).toBeUndefined(); expect(trend.changePercentage).toBeUndefined(); }); }); describe('SeverityDistribution', () => { it('should validate a severity distribution', () => { const distribution: SeverityDistribution = { critical: 5, major: 15, minor: 30, total: 50, }; expect(distribution.critical).toBe(5); expect(distribution.major).toBe(15); expect(distribution.minor).toBe(30); expect(distribution.total).toBe(50); }); }); describe('SecurityIssueStat', () => { it('should validate a security issue stat', () => { const stat: SecurityIssueStat = { key: 'A1:2017', title: 'Injection', occurrence: { critical: 2, major: 5, minor: 10, total: 17, }, }; expect(stat.key).toBe('A1:2017'); expect(stat.title).toBe('Injection'); expect(stat.occurrence.total).toBe(17); }); }); describe('ComplianceReport', () => { it('should validate a complete compliance report', () => { const report: ComplianceReport = { key: ReportType.OWASP_TOP_10, title: 'OWASP Top 10', currentValue: 85.5, status: ReportStatus.PASSING, securityIssueStats: [ { key: 'A1:2017', title: 'Injection', occurrence: { critical: 0, major: 0, minor: 0, total: 0, }, }, { key: 'A2:2017', title: 'Broken Authentication', occurrence: { critical: 1, major: 2, minor: 0, total: 3, }, }, ], trends: [ { label: 'Last 30 days', value: 82.3, changePercentage: 3.2, }, ], }; expect(report.key).toBe(ReportType.OWASP_TOP_10); expect(report.title).toBe('OWASP Top 10'); expect(report.currentValue).toBe(85.5); expect(report.status).toBe(ReportStatus.PASSING); expect(report.securityIssueStats.length).toBe(2); expect(report.securityIssueStats[1].key).toBe('A2:2017'); expect(report.trends?.[0].changePercentage).toBe(3.2); }); it('should allow optional fields to be undefined', () => { const report: ComplianceReport = { key: ReportType.SANS_TOP_25, title: 'SANS Top 25', securityIssueStats: [], }; expect(report.currentValue).toBeUndefined(); expect(report.status).toBeUndefined(); expect(report.trends).toBeUndefined(); }); }); describe('Package', () => { it('should validate a complete package', () => { const pkg: Package = { id: 'pkg_123', ecosystem: 'NPM', name: 'lodash', purl: 'pkg:npm/lodash@4.17.21', }; expect(pkg.id).toBe('pkg_123'); expect(pkg.ecosystem).toBe('NPM'); expect(pkg.name).toBe('lodash'); expect(pkg.purl).toBe('pkg:npm/lodash@4.17.21'); }); it('should allow optional fields to be undefined', () => { const pkg: Package = { id: 'pkg_123', ecosystem: 'NPM', name: 'lodash', }; expect(pkg.purl).toBeUndefined(); }); }); describe('PackageVersion', () => { it('should validate a complete package version', () => { const version: PackageVersion = { id: 'ver_123', version: '4.17.21', versionType: 'SEMVER', }; expect(version.id).toBe('ver_123'); expect(version.version).toBe('4.17.21'); expect(version.versionType).toBe('SEMVER'); }); it('should allow optional fields to be undefined', () => { const version: PackageVersion = { id: 'ver_123', version: '4.17.21', }; expect(version.versionType).toBeUndefined(); }); }); describe('Vulnerability', () => { it('should validate a complete vulnerability', () => { const vulnerability: Vulnerability = { id: 'vuln_123', identifier: 'CVE-2022-1234', aliases: ['GHSA-abcd-efgh-ijkl'], summary: 'Prototype pollution vulnerability', details: 'A detailed description of the vulnerability...', publishedAt: '2022-05-15T10:30:00Z', updatedAt: '2022-06-01T14:45:00Z', withdrawnAt: undefined, severity: 'HIGH', cvssV2Vector: 'AV:N/AC:L/Au:N/C:P/I:P/A:P', cvssV2BaseScore: 7.5, cvssV2Severity: 'HIGH', cvssV3Vector: 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H', cvssV3BaseScore: 9.8, cvssV3Severity: 'CRITICAL', cvssV4Vector: 'CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H', cvssV4BaseScore: 10.0, cvssV4Severity: 'CRITICAL', epssScore: 0.85, epssPercentile: 0.95, introducedVersions: ['4.0.0'], fixedVersions: ['4.17.21'], referenceUrls: ['https://nvd.nist.gov/vuln/detail/CVE-2022-1234'], }; expect(vulnerability.id).toBe('vuln_123'); expect(vulnerability.identifier).toBe('CVE-2022-1234'); expect(vulnerability.aliases).toContain('GHSA-abcd-efgh-ijkl'); expect(vulnerability.severity).toBe('HIGH'); expect(vulnerability.cvssV3BaseScore).toBe(9.8); expect(vulnerability.cvssV3Severity).toBe('CRITICAL'); expect(vulnerability.epssScore).toBe(0.85); expect(vulnerability.introducedVersions).toContain('4.0.0'); expect(vulnerability.fixedVersions).toContain('4.17.21'); }); it('should allow optional fields to be undefined', () => { const vulnerability: Vulnerability = { id: 'vuln_123', identifier: 'CVE-2022-1234', aliases: [], publishedAt: '2022-05-15T10:30:00Z', updatedAt: '2022-06-01T14:45:00Z', severity: 'HIGH', introducedVersions: [], fixedVersions: [], referenceUrls: [], }; expect(vulnerability.summary).toBeUndefined(); expect(vulnerability.details).toBeUndefined(); expect(vulnerability.withdrawnAt).toBeUndefined(); expect(vulnerability.cvssV2Vector).toBeUndefined(); expect(vulnerability.cvssV2BaseScore).toBeUndefined(); expect(vulnerability.cvssV2Severity).toBeUndefined(); expect(vulnerability.cvssV3Vector).toBeUndefined(); expect(vulnerability.cvssV3BaseScore).toBeUndefined(); expect(vulnerability.cvssV3Severity).toBeUndefined(); expect(vulnerability.cvssV4Vector).toBeUndefined(); expect(vulnerability.cvssV4BaseScore).toBeUndefined(); expect(vulnerability.cvssV4Severity).toBeUndefined(); expect(vulnerability.epssScore).toBeUndefined(); expect(vulnerability.epssPercentile).toBeUndefined(); }); }); describe('VulnerabilityOccurrence', () => { it('should validate a complete vulnerability occurrence', () => { const occurrence: VulnerabilityOccurrence = { id: 'occ_123', package: { id: 'pkg_123', ecosystem: 'NPM', name: 'lodash', purl: 'pkg:npm/lodash', }, packageVersion: { id: 'ver_123', version: '4.17.20', versionType: 'SEMVER', }, vulnerability: { id: 'vuln_123', identifier: 'CVE-2022-1234', aliases: ['GHSA-abcd-efgh-ijkl'], publishedAt: '2022-05-15T10:30:00Z', updatedAt: '2022-06-01T14:45:00Z', severity: 'HIGH', introducedVersions: ['4.0.0'], fixedVersions: ['4.17.21'], referenceUrls: [], }, reachability: 'REACHABLE', fixability: 'AUTO_FIXABLE', }; expect(occurrence.id).toBe('occ_123'); expect(occurrence.package.name).toBe('lodash'); expect(occurrence.packageVersion.version).toBe('4.17.20'); expect(occurrence.vulnerability.identifier).toBe('CVE-2022-1234'); expect(occurrence.reachability).toBe('REACHABLE'); expect(occurrence.fixability).toBe('AUTO_FIXABLE'); }); }); describe('DependencyVulnerabilitiesParams', () => { it('should validate dependency vulnerabilities params', () => { const params: DependencyVulnerabilitiesParams = { projectKey: 'project_123', first: 10, after: 'cursor123', }; expect(params.projectKey).toBe('project_123'); expect(params.first).toBe(10); expect(params.after).toBe('cursor123'); }); }); describe('VulnerabilitiesResponse', () => { it('should validate vulnerabilities response structure', () => { const response: VulnerabilitiesResponse = { edges: [ { node: { id: 'occ_123', package: { id: 'pkg_123', ecosystem: 'NPM', name: 'lodash', purl: 'pkg:npm/lodash', }, packageVersion: { id: 'ver_123', version: '4.17.20', versionType: 'SEMVER', }, vulnerability: { id: 'vuln_123', identifier: 'CVE-2022-1234', aliases: [], publishedAt: '2022-05-15T10:30:00Z', updatedAt: '2022-06-01T14:45:00Z', severity: 'HIGH', introducedVersions: [], fixedVersions: [], referenceUrls: [], }, reachability: 'REACHABLE', fixability: 'AUTO_FIXABLE', }, cursor: 'cursor123', }, ], pageInfo: { hasNextPage: true, hasPreviousPage: false, startCursor: 'cursor123', endCursor: 'cursor123', }, totalCount: 1, }; expect(response.edges.length).toBe(1); expect(response.edges[0].node.id).toBe('occ_123'); expect(response.edges[0].node.package.name).toBe('lodash'); expect(response.pageInfo.hasNextPage).toBe(true); expect(response.totalCount).toBe(1); }); it('should validate empty response', () => { const response: VulnerabilitiesResponse = { edges: [], pageInfo: { hasNextPage: false, hasPreviousPage: false, startCursor: null, endCursor: null, }, totalCount: 0, }; expect(response.edges.length).toBe(0); expect(response.totalCount).toBe(0); }); }); }); // Test JSON serialization and deserialization describe('JSON Serialization & Deserialization', () => { it('should correctly serialize and deserialize vulnerability object', () => { const original: Vulnerability = { id: 'vuln_123', identifier: 'CVE-2022-1234', aliases: ['GHSA-abcd-efgh-ijkl'], summary: 'Prototype pollution vulnerability', details: 'A detailed description of the vulnerability...', publishedAt: '2022-05-15T10:30:00Z', updatedAt: '2022-06-01T14:45:00Z', severity: 'HIGH', cvssV3Vector: 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H', cvssV3BaseScore: 9.8, cvssV3Severity: 'CRITICAL', introducedVersions: ['4.0.0'], fixedVersions: ['4.17.21'], referenceUrls: ['https://nvd.nist.gov/vuln/detail/CVE-2022-1234'], }; const json = JSON.stringify(original); const deserialized = JSON.parse(json) as Vulnerability; expect(deserialized).toEqual(original); expect(deserialized.id).toBe('vuln_123'); expect(deserialized.severity).toBe('HIGH'); expect(deserialized.cvssV3Severity).toBe('CRITICAL'); }); it('should correctly serialize and deserialize compliance report', () => { const original: ComplianceReport = { key: ReportType.OWASP_TOP_10, title: 'OWASP Top 10', currentValue: 85.5, status: ReportStatus.PASSING, securityIssueStats: [ { key: 'A1:2017', title: 'Injection', occurrence: { critical: 0, major: 0, minor: 0, total: 0, }, }, ], trends: [ { label: 'Last 30 days', value: 82.3, changePercentage: 3.2, }, ], }; const json = JSON.stringify(original); const deserialized = JSON.parse(json) as ComplianceReport; expect(deserialized).toEqual(original); expect(deserialized.key).toBe(ReportType.OWASP_TOP_10); expect(deserialized.status).toBe(ReportStatus.PASSING); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sapientpants/deepsource-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server