Getting Started with Testing
Quick start guide to writing tests in Savvi Studio
Quick Start
# 1. Verify prerequisites
psql --version # PostgreSQL 14+
node --version # Node.js 18+
# 2. Run existing tests
pnpm test tests/integration
# 3. Write your first test
# See example below
Prerequisites
- ✅ PostgreSQL 14+ installed and running
- ✅ Node.js 18+ and pnpm
- ✅ Environment configured (
.env.test) - ✅ Database migrations applied
→ Full setup guide: Setup Environment Task
Your First Test
Create tests/integration/auth/my-first-test.test.ts:
import { describe, expect } from 'vitest';
import test from '../test';
import { createUserWithOrgSetup } from '../setup/factories/database-fixtures';
import { queryUserAccessCache } from '../setup/utilities';
describe('My First Test', () => {
test('should create user and verify access', async ({ asSystem }) => {
await asSystem(async (client) => {
// Use factory to create test data
const { user, org } = await createUserWithOrgSetup(client);
// Use utility to query access
const access = await queryUserAccessCache(client, user.id);
// Verify results
expect(access.length).toBeGreaterThan(0);
expect(user.data.email).toContain('@test.com');
});
});
});
Run it:
pnpm test tests/integration/auth/my-first-test.test.ts
Core Concepts
1. Test Fixtures
Test fixtures provide execution contexts:
// System privileges (for setup/teardown)
await asSystem(async (client) => { /* ... */ });
// User session context
await asUser(userId, orgId, async (client) => { /* ... */ });
// Admin privileges
await asAdmin(userId, orgId, async (client) => { /* ... */ });
→ Full API: Test Fixtures Reference
2. Factory Functions
Factories create test data with sensible defaults:
// Create user with organization
const { user, org } = await createUserWithOrgSetup(client);
// Create resource with permission
const { resourceNodeId } = await createResourceWithPermission(client, {
userNodeId: user.nodeId,
permissionLevel: 'write'
});
// Create complete workspace
const workspace = await setupTestWorkspace(client, {
includeTeam: true,
resourceCount: 3
});
→ Full API: Factories & Utilities Reference
3. Query Utilities
Utilities provide common query operations:
// Query user access
const access = await queryUserAccessCache(client, userId);
// Check permissions
const hasAccess = await checkUserHasAccess(client, nodeId);
const canManage = await checkUserCanManage(client, nodeId);
const isAdmin = await checkUserIsAdmin(client, nodeId);
// Refresh cache
await refreshUserAccessCache(client, userId);
→ Full API: Factories & Utilities Reference
Common Commands
# Run all tests
pnpm test
# Run integration tests only
pnpm test tests/integration
# Run specific domain
pnpm test tests/integration/auth
# Watch mode (auto-rerun on changes)
pnpm test -- --watch
# Coverage report
pnpm test -- --coverage
# Debug mode (verbose output)
pnpm test -- --reporter=verbose
# Stop on first failure
pnpm test -- --bail=1
Common Patterns
Pattern 1: Create and Test User Access
test('user access pattern', async ({ asSystem }) => {
await asSystem(async (client) => {
// Create test data
const { user, org } = await createUserWithOrgSetup(client);
const { resourceNodeId } = await createResourceWithPermission(client, {
userNodeId: user.nodeId,
permissionLevel: 'write'
});
// Verify access
await refreshUserAccessCache(client, user.id);
const access = await queryUserAccessCache(client, user.id, resourceNodeId);
expect(access.length).toBeGreaterThan(0);
expect(access[0]?.min_permission).toBe('auth.read.write');
});
});
Pattern 2: Test as Specific User
test('user context pattern', async ({ asUser, asSystem }) => {
let userId: string;
let nodeId: string;
// Setup as system
await asSystem(async (client) => {
const { user } = await createUserWithOrgSetup(client);
userId = user.id;
const { resourceNodeId } = await createResourceWithPermission(client, {
userNodeId: user.nodeId,
permissionLevel: 'read'
});
nodeId = resourceNodeId;
});
// Test as user
await asUser(userId, 'org-id', async (client) => {
const hasAccess = await checkUserHasAccess(client, nodeId);
expect(hasAccess).toBe(true);
});
});
Pattern 3: Complete Workspace Setup
test('workspace pattern', async ({ asSystem }) => {
await asSystem(async (client) => {
const workspace = await setupTestWorkspace(client, {
includeTeam: true,
resourceCount: 3,
resourceType: 'test.document',
resourcePermission: 'write'
});
expect(workspace.user).toBeDefined();
expect(workspace.org).toBeDefined();
expect(workspace.team).toBeDefined();
expect(workspace.resources).toHaveLength(3);
});
});
Essential Imports
// Test fixtures
import test from '../test';
import { generateTestId } from '@/test-utils-integration/utils/graph-fixtures';
// Factory functions
import {
createUserWithOrgSetup,
createResourceWithPermission,
setupTestWorkspace
} from '../setup/factories/database-fixtures';
// Query utilities
import {
queryUserAccessCache,
refreshUserAccessCache,
checkUserHasAccess,
checkUserCanManage,
checkUserIsAdmin
} from '../setup/utilities';
// Cleanup utilities
import {
cleanupTestData,
deleteNodesByType
} from '../setup/utilities/cleanup-helpers';
Troubleshooting
Common Issues
Connection refused:
# PostgreSQL not running
brew services start postgresql # macOS
sudo systemctl start postgresql # Linux
Database doesn't exist:
createdb savvi_studio_test
Permission denied:
ALTER USER postgres CREATEDB;
→ More help: Troubleshooting Guide
Next Steps
Learn the Infrastructure
- Test Fixtures - Complete fixture API
- Factories & Utilities - 42+ functions reference
- Database Testing - Database patterns
- Integration Testing - Integration patterns
See Examples
- Common Scenarios - 23+ practical examples
- Examples Directory - Working code examples
Implementation Tasks
- Setup Environment - Full environment setup
- All Tasks - Implementation guides
Quick Reference
Available Fixtures
| Fixture | Purpose | Example |
|---|---|---|
asSystem |
System privileges | Setup, cleanup, admin operations |
asUser |
User session | Testing user permissions |
asAdmin |
Admin privileges | Testing admin features |
systemClient |
Direct client | Low-level operations |
graph |
Graph operations | Testing graph queries |
graphAsRoot |
Root graph ops | Graph setup |
studio |
Studio operations | Testing studio API |
studioAsRoot |
Root studio ops | Studio setup |
assertions |
Assertions | Common assertions |
Key Factory Functions
createUserWithOrgSetup()- User with organizationcreateResourceWithPermission()- Resource with granted permissionsetupTestWorkspace()- Complete test environmentcreateNodeWithType()- Create node with typecreateConnectedNodes()- Two connected nodes
Key Query Utilities
queryUserAccessCache()- Query access cacherefreshUserAccessCache()- Update access cachecheckUserHasAccess()- Check read accesscheckUserCanManage()- Check write accesscheckUserIsAdmin()- Check admin accessgetCurrentUserId()- Get session usergetCurrentRole()- Get session role
Ready to dive deeper? → Integration Testing Guide