238 lines
6.2 KiB
TypeScript
238 lines
6.2 KiB
TypeScript
import { describe, test, expect, beforeEach } from 'vitest';
|
|
import { Activities, StoreInMemory } from '../../src/storage';
|
|
|
|
describe('Activities', () => {
|
|
let store: StoreInMemory;
|
|
let activities: Activities;
|
|
|
|
beforeEach(async () => {
|
|
activities = await Activities.fromStores(StoreInMemory.from());
|
|
});
|
|
|
|
test('should add activity with auto-generated timestamp', async () => {
|
|
const activity = {
|
|
name: 'WalletName',
|
|
entityId: 'wallet1',
|
|
value: 'Test Wallet',
|
|
};
|
|
|
|
await activities.add(activity);
|
|
|
|
const storedActivity = activities.get('WalletName', 'wallet1');
|
|
expect(storedActivity).toBeDefined();
|
|
expect(storedActivity?.timestamp).toBeDefined();
|
|
expect(storedActivity?.value).toBe('Test Wallet');
|
|
});
|
|
|
|
test('should preserve provided timestamp', async () => {
|
|
const timestamp = BigInt(1234567890000);
|
|
const activity = {
|
|
timestamp,
|
|
name: 'WalletName',
|
|
entityId: 'wallet1',
|
|
value: 'Test Wallet',
|
|
};
|
|
|
|
await activities.add(activity);
|
|
|
|
const storedActivity = activities.get('WalletName', 'wallet1');
|
|
expect(storedActivity?.timestamp).toBe(timestamp);
|
|
});
|
|
|
|
test('should update existing activity with newer timestamp', async () => {
|
|
const oldTimestamp = BigInt(1000);
|
|
const newTimestamp = BigInt(2000);
|
|
|
|
await activities.add({
|
|
timestamp: oldTimestamp,
|
|
name: 'WalletName',
|
|
entityId: 'wallet1',
|
|
value: 'Old Name',
|
|
});
|
|
|
|
await activities.add({
|
|
timestamp: newTimestamp,
|
|
name: 'WalletName',
|
|
entityId: 'wallet1',
|
|
value: 'New Name',
|
|
});
|
|
|
|
const activity = activities.get('WalletName', 'wallet1');
|
|
|
|
expect(activity?.value).toBe('New Name');
|
|
expect(activity?.timestamp).toBe(newTimestamp);
|
|
});
|
|
|
|
test('should honor first-seen policy', async () => {
|
|
activities.registerPolicy('TransactionFirstSeen', (existing, newer) => {
|
|
return existing || newer;
|
|
});
|
|
|
|
const oldTimestamp = BigInt(1000);
|
|
const newTimestamp = BigInt(2000);
|
|
|
|
await activities.add({
|
|
timestamp: oldTimestamp,
|
|
name: 'TransactionFirstSeen',
|
|
entityId: 'tx1',
|
|
value: 'First Value',
|
|
});
|
|
|
|
await activities.add({
|
|
timestamp: newTimestamp,
|
|
name: 'TransactionFirstSeen',
|
|
entityId: 'tx1',
|
|
value: 'Second Value',
|
|
});
|
|
|
|
const activity = activities.get('TransactionFirstSeen', 'tx1');
|
|
|
|
expect(activity?.value).toBe('First Value');
|
|
expect(activity?.timestamp).toBe(oldTimestamp);
|
|
});
|
|
|
|
test('should handle custom policy with comparison function', async () => {
|
|
// Policy that keeps activity with highest value
|
|
activities.registerPolicy('CustomType', (existing, newer) => {
|
|
if (!existing) return newer;
|
|
return existing.timestamp < newer.timestamp ? existing : newer;
|
|
});
|
|
|
|
await activities.add({
|
|
timestamp: BigInt(1000),
|
|
name: 'CustomType',
|
|
entityId: 'custom1',
|
|
value: 50,
|
|
});
|
|
|
|
await activities.add({
|
|
timestamp: BigInt(2000),
|
|
name: 'CustomType',
|
|
entityId: 'custom1',
|
|
value: 30,
|
|
});
|
|
|
|
const activity = activities.get('CustomType', 'custom1');
|
|
|
|
expect(activity?.value).toBe(50);
|
|
});
|
|
|
|
test('should process multiple activities in chronological order', async () => {
|
|
const testActivities = [
|
|
{
|
|
timestamp: BigInt(3000),
|
|
name: 'WalletName',
|
|
entityId: 'wallet1',
|
|
value: 'Name 3',
|
|
},
|
|
{
|
|
timestamp: BigInt(1000),
|
|
name: 'WalletName',
|
|
entityId: 'wallet1',
|
|
value: 'Name 1',
|
|
},
|
|
{
|
|
timestamp: BigInt(2000),
|
|
name: 'WalletName',
|
|
entityId: 'wallet1',
|
|
value: 'Name 2',
|
|
},
|
|
];
|
|
|
|
for (const activity of testActivities) {
|
|
await activities.add(activity);
|
|
}
|
|
|
|
const finalActivity = activities.get('WalletName', 'wallet1');
|
|
|
|
expect(finalActivity?.value).toBe('Name 3');
|
|
});
|
|
|
|
test('should handle multiple activity types independently', async () => {
|
|
await activities.add({
|
|
timestamp: BigInt(1000),
|
|
name: 'WalletName',
|
|
entityId: 'wallet1',
|
|
value: 'My Wallet',
|
|
});
|
|
|
|
await activities.add({
|
|
timestamp: BigInt(2000),
|
|
name: 'WalletDescription',
|
|
entityId: 'wallet1',
|
|
value: 'My Description',
|
|
});
|
|
|
|
expect(activities.get('WalletName', 'wallet1')?.value).toBe('My Wallet');
|
|
expect(activities.get('WalletDescription', 'wallet1')?.value).toBe(
|
|
'My Description',
|
|
);
|
|
});
|
|
|
|
test('should update snapshot immediately when activity is added', async () => {
|
|
const activity = {
|
|
timestamp: BigInt(1000),
|
|
name: 'WalletName',
|
|
entityId: 'wallet1',
|
|
value: 'Test Wallet',
|
|
};
|
|
|
|
await activities.add(activity);
|
|
|
|
// Check snapshot without calling compileSnapshot
|
|
const storedActivity = activities.get('WalletName', 'wallet1');
|
|
expect(storedActivity?.value).toBe('Test Wallet');
|
|
});
|
|
|
|
test('should handle missing timestamp gracefully', async () => {
|
|
const activity = {
|
|
name: 'WalletName',
|
|
entityId: 'wallet1',
|
|
value: 'Test Wallet',
|
|
};
|
|
|
|
await activities.add(activity);
|
|
const storedActivity = activities.get('WalletName', 'wallet1');
|
|
|
|
expect(storedActivity).toBeDefined();
|
|
expect(storedActivity?.timestamp).toBeDefined();
|
|
expect(typeof storedActivity?.timestamp).toBe('bigint');
|
|
});
|
|
|
|
/*
|
|
test('should cleanup old activities from store when newer versions are added', async () => {
|
|
// Add first activity
|
|
await activities.add({
|
|
timestamp: BigInt(1000),
|
|
type: 'WalletName',
|
|
id: 'wallet1',
|
|
value: 'Old Name',
|
|
});
|
|
|
|
expect(Object.keys(await store.all()).length).toBe(1);
|
|
|
|
// Add newer version - should trigger cleanup of old version
|
|
await activities.add({
|
|
timestamp: BigInt(2000),
|
|
type: 'WalletName',
|
|
id: 'wallet1',
|
|
value: 'New Name',
|
|
});
|
|
|
|
// Should still be 1 as old activity was culled
|
|
expect(Object.keys(await store.all()).length).toBe(1);
|
|
|
|
// Add different type
|
|
await activities.add({
|
|
timestamp: BigInt(1500),
|
|
type: 'WalletDescription',
|
|
id: 'wallet1',
|
|
value: 'Description',
|
|
});
|
|
|
|
// Should now have 2 activities
|
|
expect(Object.keys(await store.all()).length).toBe(2);
|
|
});
|
|
*/
|
|
});
|