Files
inji-wallet/shared/VCMetadata.test.ts
Kaushik Gupta 33c6caa08a INJIMOB-3246 Code coverage for Inji-Wallet repo increase above 5% (#2108)
* INJIMOB-3246 Code coverage for Inji-Wallet repo increase above 5%

Signed-off-by: Kaushik Gupta <kausgpt97@gmail.com>

* INJIMOB-3246: added snapshot tests and coverage increased to +4%

Signed-off-by: Kaushik Gupta <kausgpt97@gmail.com>

* removed duplicated lines

Signed-off-by: Kaushik Gupta <kausgpt97@gmail.com>

* Added updateCredentialInformation tests

Signed-off-by: Kaushik Gupta <kausgpt97@gmail.com>

* added code rabbit changes

Signed-off-by: Kaushik Gupta <kausgpt97@gmail.com>

* removed platform-specific tests without mocking

Signed-off-by: Kaushik Gupta <kausgpt97@gmail.com>

* standardize mocks in VcItemContainerProfileImage tests

Signed-off-by: Kaushik Gupta <kausgpt97@gmail.com>

---------

Signed-off-by: Kaushik Gupta <kausgpt97@gmail.com>
2025-11-07 11:10:37 +05:30

500 lines
14 KiB
TypeScript

import {VCMetadata, parseMetadatas, getVCMetadata} from './VCMetadata';
import {VCFormat} from './VCFormat';
import {UUID} from './Utils';
describe('VCMetadata', () => {
describe('constructor', () => {
it('should create instance with default values', () => {
const metadata = new VCMetadata();
expect(metadata.idType).toBe('');
expect(metadata.requestId).toBe('');
expect(metadata.isPinned).toBe(false);
expect(metadata.id).toBe('');
expect(metadata.issuer).toBe('');
expect(metadata.protocol).toBe('');
expect(metadata.timestamp).toBe('');
expect(metadata.isVerified).toBe(false);
expect(metadata.mosipIndividualId).toBe('');
expect(metadata.format).toBe('');
expect(metadata.isExpired).toBe(false);
});
it('should create instance with provided values', () => {
const metadata = new VCMetadata({
idType: 'UIN',
requestId: 'req123',
isPinned: true,
id: 'id123',
issuer: 'TestIssuer',
protocol: 'OpenId4VCI',
timestamp: '2024-01-01',
isVerified: true,
mosipIndividualId: 'mosip123',
format: 'ldp_vc',
downloadKeyType: 'ED25519',
isExpired: false,
credentialType: 'NationalID',
issuerHost: 'https://test.com',
});
expect(metadata.idType).toBe('UIN');
expect(metadata.requestId).toBe('req123');
expect(metadata.isPinned).toBe(true);
expect(metadata.id).toBe('id123');
expect(metadata.issuer).toBe('TestIssuer');
expect(metadata.protocol).toBe('OpenId4VCI');
expect(metadata.timestamp).toBe('2024-01-01');
expect(metadata.isVerified).toBe(true);
expect(metadata.mosipIndividualId).toBe('mosip123');
expect(metadata.format).toBe('ldp_vc');
expect(metadata.downloadKeyType).toBe('ED25519');
expect(metadata.isExpired).toBe(false);
expect(metadata.credentialType).toBe('NationalID');
expect(metadata.issuerHost).toBe('https://test.com');
});
});
describe('fromVC', () => {
it('should create VCMetadata from VC object', () => {
const vc = {
idType: 'VID',
requestId: 'req456',
id: 'vc123',
issuer: 'Issuer1',
format: VCFormat.ldp_vc,
};
const metadata = VCMetadata.fromVC(vc);
expect(metadata.idType).toBe('VID');
expect(metadata.requestId).toBe('req456');
expect(metadata.id).toBe('vc123');
expect(metadata.issuer).toBe('Issuer1');
expect(metadata.format).toBe(VCFormat.ldp_vc);
});
it('should use default format if not provided', () => {
const vc = {id: 'vc123'};
const metadata = VCMetadata.fromVC(vc);
expect(metadata.format).toBe(VCFormat.ldp_vc);
});
it('should handle isPinned default value', () => {
const vc = {id: 'vc123'};
const metadata = VCMetadata.fromVC(vc);
expect(metadata.isPinned).toBe(false);
});
});
describe('fromVcMetadataString', () => {
it('should parse JSON string to VCMetadata', () => {
const jsonStr = JSON.stringify({
id: 'vc123',
issuer: 'TestIssuer',
format: 'ldp_vc',
});
const metadata = VCMetadata.fromVcMetadataString(jsonStr);
expect(metadata.id).toBe('vc123');
expect(metadata.issuer).toBe('TestIssuer');
expect(metadata.format).toBe('ldp_vc');
});
it('should handle object input', () => {
const obj = {
id: 'vc456',
issuer: 'AnotherIssuer',
};
const metadata = VCMetadata.fromVcMetadataString(obj);
expect(metadata.id).toBe('vc456');
expect(metadata.issuer).toBe('AnotherIssuer');
});
it('should return empty VCMetadata on parse error', () => {
const invalidJson = '{invalid json}';
const metadata = VCMetadata.fromVcMetadataString(invalidJson);
expect(metadata).toBeInstanceOf(VCMetadata);
expect(metadata.id).toBe('');
});
});
describe('isVCKey', () => {
it('should return true for valid VC key', () => {
expect(VCMetadata.isVCKey('VC_1234567890_abc123')).toBe(true);
expect(VCMetadata.isVCKey('VC_timestamp_id')).toBe(true);
});
it('should return false for invalid VC key', () => {
expect(VCMetadata.isVCKey('INVALID_KEY')).toBe(false);
expect(VCMetadata.isVCKey('VC')).toBe(false);
expect(VCMetadata.isVCKey('')).toBe(false);
expect(VCMetadata.isVCKey('VC_')).toBe(false);
});
it('should handle keys with special characters properly', () => {
expect(VCMetadata.isVCKey('VC_123_abc-def')).toBe(true);
expect(VCMetadata.isVCKey('VC_123_abc_def')).toBe(true);
});
});
describe('isFromOpenId4VCI', () => {
it('should return true when protocol is OpenId4VCI', () => {
const metadata = new VCMetadata({protocol: 'OpenId4VCI'});
expect(metadata.isFromOpenId4VCI()).toBe(true);
});
it('should return false when protocol is not OpenId4VCI', () => {
const metadata = new VCMetadata({protocol: 'OtherProtocol'});
expect(metadata.isFromOpenId4VCI()).toBe(false);
});
it('should return false when protocol is empty', () => {
const metadata = new VCMetadata();
expect(metadata.isFromOpenId4VCI()).toBe(false);
});
});
describe('getVcKey', () => {
it('should generate VC key with timestamp', () => {
const metadata = new VCMetadata({
timestamp: '1234567890',
id: 'abc123',
});
expect(metadata.getVcKey()).toBe('VC_1234567890_abc123');
});
it('should generate VC key without timestamp', () => {
const metadata = new VCMetadata({
timestamp: '',
id: 'xyz789',
});
expect(metadata.getVcKey()).toBe('VC_xyz789');
});
it('should match the VC key regex pattern', () => {
const metadata = new VCMetadata({
timestamp: '1234567890',
id: 'test-id_123',
});
const key = metadata.getVcKey();
expect(VCMetadata.isVCKey(key)).toBe(true);
});
});
describe('equals', () => {
it('should return true for equal VCMetadata instances', () => {
const metadata1 = new VCMetadata({
timestamp: '1234567890',
id: 'abc123',
});
const metadata2 = new VCMetadata({
timestamp: '1234567890',
id: 'abc123',
});
expect(metadata1.equals(metadata2)).toBe(true);
});
it('should return false for different VCMetadata instances', () => {
const metadata1 = new VCMetadata({
timestamp: '1234567890',
id: 'abc123',
});
const metadata2 = new VCMetadata({
timestamp: '0987654321',
id: 'xyz789',
});
expect(metadata1.equals(metadata2)).toBe(false);
});
it('should return true when comparing instance with itself', () => {
const metadata = new VCMetadata({
timestamp: '1234567890',
id: 'abc123',
});
expect(metadata.equals(metadata)).toBe(true);
});
});
describe('vcKeyRegExp', () => {
it('should be defined as a RegExp', () => {
expect(VCMetadata.vcKeyRegExp).toBeInstanceOf(RegExp);
});
});
});
describe('parseMetadatas', () => {
it('should be defined', () => {
expect(parseMetadatas).toBeDefined();
});
it('should parse array of metadata objects', () => {
const metadataObjects = [
{id: 'vc1', issuer: 'Issuer1'},
{id: 'vc2', issuer: 'Issuer2'},
{id: 'vc3', issuer: 'Issuer3'},
];
const result = parseMetadatas(metadataObjects);
expect(result).toHaveLength(3);
expect(result[0]).toBeInstanceOf(VCMetadata);
expect(result[0].id).toBe('vc1');
expect(result[1].id).toBe('vc2');
expect(result[2].id).toBe('vc3');
});
it('should handle empty array', () => {
const result = parseMetadatas([]);
expect(result).toEqual([]);
});
it('should create VCMetadata instances for each object', () => {
const metadataObjects = [
{id: 'test1', format: 'ldp_vc', isPinned: true},
{id: 'test2', format: 'mso_mdoc', isPinned: false},
];
const result = parseMetadatas(metadataObjects);
expect(result[0].id).toBe('test1');
expect(result[0].format).toBe('ldp_vc');
expect(result[0].isPinned).toBe(true);
expect(result[1].id).toBe('test2');
expect(result[1].format).toBe('mso_mdoc');
expect(result[1].isPinned).toBe(false);
});
});
describe('getVCMetadata', () => {
beforeEach(() => {
jest.spyOn(UUID, 'generate').mockReturnValue('test-uuid-12345');
});
afterEach(() => {
jest.restoreAllMocks();
});
it('should create VCMetadata with generated credential ID', () => {
const mockContext: any = {
selectedIssuer: {
credential_issuer_host: 'https://issuer.example.com',
issuer_id: 'TestIssuer',
protocol: 'OpenId4VCI',
},
timestamp: '1234567890',
vcMetadata: {
isVerified: false,
isExpired: false,
},
verifiableCredential: null,
credentialWrapper: {
format: VCFormat.ldp_vc,
},
selectedCredentialType: null,
};
const result = getVCMetadata(mockContext, 'ED25519');
expect(result.requestId).toContain('test-uuid-12345');
expect(result.requestId).toContain('issuer');
expect(result.issuer).toBe('TestIssuer');
expect(result.protocol).toBe('OpenId4VCI');
expect(result.timestamp).toBe('1234567890');
expect(result.downloadKeyType).toBe('ED25519');
expect(result.format).toBe(VCFormat.ldp_vc);
});
it('should handle credential_issuer when credential_issuer_host is not available', () => {
const mockContext: any = {
selectedIssuer: {
credential_issuer: 'https://backup.example.com',
issuer_id: 'BackupIssuer',
protocol: 'OpenId4VCI',
},
timestamp: '',
vcMetadata: {},
verifiableCredential: null,
credentialWrapper: {
format: VCFormat.mso_mdoc,
},
selectedCredentialType: null,
};
const result = getVCMetadata(mockContext, 'RSA');
expect(result.issuer).toBe('BackupIssuer');
expect(result.issuerHost).toBe('https://backup.example.com');
expect(result.format).toBe(VCFormat.mso_mdoc);
});
it('should use credential_issuer as fallback for issuer_id', () => {
const mockContext: any = {
selectedIssuer: {
credential_issuer_host: 'https://issuer.test.com',
credential_issuer: 'FallbackIssuer',
protocol: 'OIDC',
},
timestamp: '9876543210',
vcMetadata: {
isVerified: true,
isExpired: false,
},
verifiableCredential: null,
credentialWrapper: {
format: VCFormat.vc_sd_jwt,
},
selectedCredentialType: null,
};
const result = getVCMetadata(mockContext, 'ECDSA');
expect(result.issuer).toBe('FallbackIssuer');
expect(result.isVerified).toBe(true);
expect(result.downloadKeyType).toBe('ECDSA');
});
it('should extract issuer name from URL', () => {
const mockContext: any = {
selectedIssuer: {
credential_issuer_host: 'https://subdomain.example.org',
issuer_id: 'ExampleOrg',
protocol: 'OpenId4VCI',
},
timestamp: '',
vcMetadata: {},
verifiableCredential: null,
credentialWrapper: {format: VCFormat.ldp_vc},
selectedCredentialType: null,
};
const result = getVCMetadata(mockContext, 'ED25519');
expect(result.requestId).toContain('subdomain');
});
it('should handle invalid URL gracefully', () => {
const mockContext: any = {
selectedIssuer: {
credential_issuer_host: 'not-a-valid-url',
issuer_id: 'TestIssuer',
protocol: 'OpenId4VCI',
},
timestamp: '',
vcMetadata: {},
verifiableCredential: null,
credentialWrapper: {format: VCFormat.ldp_vc},
selectedCredentialType: null,
};
const result = getVCMetadata(mockContext, 'ED25519');
expect(result.requestId).toContain('not-a-valid-url');
expect(result.issuerHost).toBe('not-a-valid-url');
});
it('should handle Mosip VC with UIN', () => {
const mockContext: any = {
selectedIssuer: {
credential_issuer_host: 'https://mosip.example.com',
issuer_id: 'Mosip',
protocol: 'OpenId4VCI',
},
timestamp: '',
vcMetadata: {},
verifiableCredential: {
credential: {
credentialSubject: {
UIN: '1234567890',
},
},
},
credentialWrapper: {format: VCFormat.ldp_vc},
selectedCredentialType: null,
};
const result = getVCMetadata(mockContext, 'ED25519');
expect(result.mosipIndividualId).toBe('1234567890');
});
it('should handle Mosip VC with VID', () => {
const mockContext: any = {
selectedIssuer: {
credential_issuer_host: 'https://mosip.example.com',
issuer_id: 'Mosip',
protocol: 'OpenId4VCI',
},
timestamp: '',
vcMetadata: {},
verifiableCredential: {
credential: {
credentialSubject: {
VID: '9876543210',
},
},
},
credentialWrapper: {format: VCFormat.ldp_vc},
selectedCredentialType: null,
};
const result = getVCMetadata(mockContext, 'ED25519');
expect(result.mosipIndividualId).toBe('9876543210');
});
it('should set credential type when provided', () => {
const mockContext: any = {
selectedIssuer: {
credential_issuer_host: 'https://issuer.example.com',
issuer_id: 'TestIssuer',
protocol: 'OpenId4VCI',
},
timestamp: '1234567890',
vcMetadata: {},
verifiableCredential: null,
credentialWrapper: {format: VCFormat.mso_mdoc},
selectedCredentialType: 'org.iso.18013.5.1.mDL',
};
const result = getVCMetadata(mockContext, 'RSA');
expect(result.credentialType).toBeDefined();
expect(result.format).toBe(VCFormat.mso_mdoc);
});
it('should handle different key types', () => {
const mockContext: any = {
selectedIssuer: {
credential_issuer_host: 'https://issuer.example.com',
issuer_id: 'TestIssuer',
protocol: 'OpenId4VCI',
},
timestamp: '',
vcMetadata: {},
verifiableCredential: null,
credentialWrapper: {format: VCFormat.vc_sd_jwt},
selectedCredentialType: null,
};
const resultRSA = getVCMetadata(mockContext, 'RS256');
expect(resultRSA.downloadKeyType).toBe('RS256');
const resultEC = getVCMetadata(mockContext, 'ES256');
expect(resultEC.downloadKeyType).toBe('ES256');
});
});