Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 110 additions & 0 deletions backend/src/access-control/access-control.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { Test, TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { AccessControlService } from './access-control.service';
import { AccessPermission } from './access-control.entity';

describe('AccessControlService', () => {
let service: AccessControlService;
let repo: Repository<AccessPermission>;

const mockPermission = {
id: 'uuid-1',
grantorAddress: 'GGRANTOR...',
granteeAddress: 'GGRANTEE...',
resourceId: 'resource-1',
accessExpiry: Math.floor(Date.now() / 1000) + 3600,
isActive: true,
grantedAt: new Date(),
metadata: null,
};

const mockRepo = {
create: jest.fn().mockReturnValue(mockPermission),
save: jest.fn().mockResolvedValue(mockPermission),
find: jest.fn().mockResolvedValue([mockPermission]),
findOne: jest.fn().mockResolvedValue(mockPermission),
};

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
AccessControlService,
{ provide: getRepositoryToken(AccessPermission), useValue: mockRepo },
],
}).compile();

service = module.get<AccessControlService>(AccessControlService);
repo = module.get<Repository<AccessPermission>>(getRepositoryToken(AccessPermission));
});

it('should be defined', () => {
expect(service).toBeDefined();
});

describe('create', () => {
it('should create an access permission', async () => {
const dto = {
grantorAddress: 'GGRANTOR...',
granteeAddress: 'GGRANTEE...',
resourceId: 'resource-1',
accessExpiry: Math.floor(Date.now() / 1000) + 3600,
};
const result = await service.create(dto as any);
expect(result).toEqual(mockPermission);
});
});

describe('findAll', () => {
it('should return all permissions', async () => {
const result = await service.findAll();
expect(result).toEqual([mockPermission]);
});
});

describe('findOne', () => {
it('should return permission by id', async () => {
const result = await service.findOne('uuid-1');
expect(result).toEqual(mockPermission);
});

it('should throw on missing permission', async () => {
jest.spyOn(repo, 'findOne').mockResolvedValueOnce(null);
await expect(service.findOne('missing')).rejects.toThrow();
});
});

describe('revoke', () => {
it('should set isActive to false', async () => {
const result = await service.revoke('uuid-1');
expect(result.isActive).toBe(false);
});
});

describe('checkAccess', () => {
it('should return true for active permission within expiry', async () => {
const result = await service.checkAccess('GGRANTEE...', 'resource-1');
expect(result).toBe(true);
});

it('should return false when no permission exists', async () => {
jest.spyOn(repo, 'findOne').mockResolvedValueOnce(null);
const result = await service.checkAccess('GUNKNOWN...', 'resource-1');
expect(result).toBe(false);
});
});

describe('findByGrantee', () => {
it('should find permissions by grantee', async () => {
const result = await service.findByGrantee('GGRANTEE...');
expect(result).toEqual([mockPermission]);
});
});

describe('findByGrantor', () => {
it('should find permissions by grantor', async () => {
const result = await service.findByGrantor('GGRANTOR...');
expect(result).toEqual([mockPermission]);
});
});
});
115 changes: 115 additions & 0 deletions backend/src/data-sharing/data-sharing.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { Test, TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { DataSharingService } from './data-sharing.service';
import { SharedData } from './data-sharing.entity';

describe('DataSharingService', () => {
let service: DataSharingService;
let repo: Repository<SharedData>;

const mockSharedData = {
id: 'uuid-1',
ownerAddress: 'GOWNER...',
recipientAddress: 'GRECIPIENT...',
documentHash: '0xdoc...',
encryptedKey: '0xenc...',
accessExpiry: Math.floor(Date.now() / 1000) + 86400,
isActive: true,
sharedAt: new Date(),
metadata: null,
};

const mockRepo = {
create: jest.fn().mockReturnValue(mockSharedData),
save: jest.fn().mockResolvedValue(mockSharedData),
find: jest.fn().mockResolvedValue([mockSharedData]),
findOne: jest.fn().mockResolvedValue(mockSharedData),
};

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
DataSharingService,
{ provide: getRepositoryToken(SharedData), useValue: mockRepo },
],
}).compile();

service = module.get<DataSharingService>(DataSharingService);
repo = module.get<Repository<SharedData>>(getRepositoryToken(SharedData));
});

it('should be defined', () => {
expect(service).toBeDefined();
});

describe('create', () => {
it('should create shared data record', async () => {
const dto = {
ownerAddress: 'GOWNER...',
recipientAddress: 'GRECIPIENT...',
documentHash: '0xdoc...',
encryptedKey: '0xenc...',
accessExpiry: Math.floor(Date.now() / 1000) + 86400,
};
const result = await service.create(dto as any);
expect(result).toEqual(mockSharedData);
});
});

describe('findAll', () => {
it('should return all shared data', async () => {
const result = await service.findAll();
expect(result).toEqual([mockSharedData]);
});
});

describe('findOne', () => {
it('should return shared data by id', async () => {
const result = await service.findOne('uuid-1');
expect(result).toEqual(mockSharedData);
});

it('should throw on missing shared data', async () => {
jest.spyOn(repo, 'findOne').mockResolvedValueOnce(null);
await expect(service.findOne('missing')).rejects.toThrow();
});
});

describe('revoke', () => {
it('should set isActive to false', async () => {
const result = await service.revoke('uuid-1');
expect(result.isActive).toBe(false);
});
});

describe('isShareActive', () => {
it('should return true for active share within expiry', async () => {
const result = await service.isShareActive('uuid-1');
expect(result).toBe(true);
});
});

describe('extendShare', () => {
it('should extend the access expiry', async () => {
const result = await service.extendShare('uuid-1', 3600);
expect(result.accessExpiry).toBe(
mockSharedData.accessExpiry + 3600,
);
});
});

describe('findByOwner', () => {
it('should find by owner address', async () => {
const result = await service.findByOwner('GOWNER...');
expect(result).toEqual([mockSharedData]);
});
});

describe('findByRecipient', () => {
it('should find by recipient address', async () => {
const result = await service.findByRecipient('GRECIPIENT...');
expect(result).toEqual([mockSharedData]);
});
});
});
115 changes: 115 additions & 0 deletions backend/src/identity/identity.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { Test, TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { IdentityService } from './identity.service';
import { Identity } from './identity.entity';

describe('IdentityService', () => {
let service: IdentityService;
let repo: Repository<Identity>;

const mockIdentity = {
id: 'uuid-1',
walletAddress: 'GABCD...1234',
documentHash: '0xabcd...',
ipfsCid: 'QmTest123',
verificationStatus: false,
revoked: false,
metadata: null,
createdAt: new Date(),
updatedAt: new Date(),
};

const mockRepo = {
create: jest.fn().mockReturnValue(mockIdentity),
save: jest.fn().mockResolvedValue(mockIdentity),
find: jest.fn().mockResolvedValue([mockIdentity]),
findOne: jest.fn().mockResolvedValue(mockIdentity),
findAndCount: jest.fn().mockResolvedValue([[mockIdentity], 1]),
remove: jest.fn().mockResolvedValue(mockIdentity),
};

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
IdentityService,
{ provide: getRepositoryToken(Identity), useValue: mockRepo },
],
}).compile();

service = module.get<IdentityService>(IdentityService);
repo = module.get<Repository<Identity>>(getRepositoryToken(Identity));
});

it('should be defined', () => {
expect(service).toBeDefined();
});

describe('create', () => {
it('should create and return an identity', async () => {
const dto = {
walletAddress: 'GABCD...1234',
documentHash: '0xabcd...',
ipfsCid: 'QmTest123',
};
const result = await service.create(dto as any);
expect(result).toEqual(mockIdentity);
expect(repo.create).toHaveBeenCalledWith(dto);
expect(repo.save).toHaveBeenCalled();
});
});

describe('findAll', () => {
it('should return paginated results', async () => {
const result = await service.findAll();
expect(result.data).toEqual([mockIdentity]);
expect(result.total).toBe(1);
});

it('should filter by wallet address', async () => {
await service.findAll('GABCD...1234');
expect(repo.findAndCount).toHaveBeenCalled();
});
});

describe('findOne', () => {
it('should return an identity by id', async () => {
const result = await service.findOne('uuid-1');
expect(result).toEqual(mockIdentity);
});

it('should throw NotFoundException if not found', async () => {
jest.spyOn(repo, 'findOne').mockResolvedValueOnce(null);
await expect(service.findOne('missing')).rejects.toThrow();
});
});

describe('update', () => {
it('should update and return identity', async () => {
const dto = { ipfsCid: 'QmUpdated' };
const result = await service.update('uuid-1', dto as any);
expect(result).toEqual(mockIdentity);
});
});

describe('revoke', () => {
it('should set revoked to true', async () => {
const result = await service.revoke('uuid-1');
expect(result.revoked).toBe(true);
});
});

describe('remove', () => {
it('should delete identity', async () => {
await service.remove('uuid-1');
expect(repo.remove).toHaveBeenCalled();
});
});

describe('findByDocumentHash', () => {
it('should find by document hash', async () => {
const result = await service.findByDocumentHash('0xabcd...');
expect(result).toEqual(mockIdentity);
});
});
});
Loading
Loading