Testing and code quality context for Jest, React Testing Library, ESLint, and test patterns. Use when writing tests or fixing linting issues.
70%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./fleet-skills/testing/SKILL.mdTechnologies: Jest, React Testing Library, Supertest, ESLint
| Document | Topics Covered |
|---|---|
docs/development/LINTING.md | ESLint setup, auto-fix, IDE integration |
docs/development/BACKEND.md | Backend testing patterns |
docs/development/FRONTEND.md | Frontend testing patterns |
# Unit tests (in-memory DBs — no services needed, default)
cd backend && npm test
cd backend && npm run test:coverage
./dev.sh test # same, runs inside Docker container
# Integration tests (real Docker Compose services)
./dev.sh up # start mongo + postgres first
./dev.sh test:integration # INTEGRATION_TEST=true npm test --forceExit
# or manually:
INTEGRATION_TEST=true npm --prefix backend test -- --forceExit
# Frontend tests
cd frontend && npm test
cd frontend && npm run test:coverage
# Linting
npm run lint
npm run lint:fixbackend/__tests__/setup.js switches between two modes:
INTEGRATION_TEST not set (default): sets PG_HOST=undefined and MONGO_URI=undefined → triggers in-memory MongoDB Memory Server + pg-memINTEGRATION_TEST=true: connects to real services:
localhost:27017 (db: commonly-test)localhost:5432 (db: commonly-test, user: postgres, no SSL)./dev.sh up to be running firstOverride connection strings via env vars: MONGO_URI, PG_HOST, PG_PORT, PG_DATABASE, PG_USER, PG_PASSWORD.
backend/__tests__/service/two-way-integration-e2e.test.js (23 tests)
backend/__tests__/service/integrations-e2e.test.jsbackend/__tests__/service/clawdbot-e2e.test.jsbackend/__tests__/contracts/integrationProvider.contract.test.js.backend/__tests__/unit/routes/integrations.catalog.test.js.backend/__tests__/unit/routes/integrations.validation.test.js.backend/__tests__/unit/routes/pods.context.test.js.backend/__tests__/unit/services/podContextService.test.js.backend/__tests__/unit/services/podSkillService.test.js.describe('MessageService', () => {
it('should create a message', async () => {
const message = await MessageService.create({
podId: 'pod123',
userId: 'user123',
content: 'Hello'
});
expect(message.content).toBe('Hello');
});
});describe('POST /api/messages', () => {
it('should create message', async () => {
const res = await request(app)
.post('/api/messages')
.set('Authorization', `Bearer ${token}`)
.send({ podId: 'pod123', content: 'Hello' });
expect(res.status).toBe(201);
});
});describe('ChatRoom', () => {
it('renders messages', async () => {
render(<ChatRoom podId="123" />);
await waitFor(() => {
expect(screen.getByText('Hello')).toBeInTheDocument();
});
});
});jest.mock('axios');
axios.get.mockResolvedValue({ data: mockMessages });// Mock summarizer to avoid Gemini API calls
jest.mock('../../services/summarizerService', () => ({
generateSummary: jest.fn().mockResolvedValue('AI-generated summary.'),
summarizePosts: jest.fn().mockResolvedValue({ title: 'Posts Summary', content: 'Summary' }),
summarizeChats: jest.fn().mockResolvedValue({ title: 'Chats Summary', content: 'Summary' }),
}));
// Mock external APIs
jest.mock('axios');
global.fetch = jest.fn();const { hash, randomSecret } = require('../../utils/secret');
const createIngestToken = async (integrationId) => {
const token = `cm_int_${randomSecret(16)}`;
const tokenHash = hash(token);
await Integration.findByIdAndUpdate(integrationId, {
$push: {
ingestTokens: {
tokenHash,
label: 'Test Token',
createdBy: testUser._id,
createdAt: new Date(),
},
},
});
return token;
};// Install agent
await request(app)
.post('/api/registry/install')
.set('Authorization', `Bearer ${authToken}`)
.send({
agentName: 'commonly-bot',
podId: testPod._id.toString(),
scopes: ['context:read', 'summaries:read', 'messages:write'],
});
// Get runtime token
const tokenRes = await request(app)
.post(`/api/registry/pods/${testPod._id}/agents/commonly-bot/runtime-tokens`)
.set('Authorization', `Bearer ${authToken}`)
.send({ label: 'Test Token' });
const runtimeToken = tokenRes.body.token;
// Post message as agent
await request(app)
.post(`/api/agents/runtime/pods/${testPod._id}/messages`)
.set('Authorization', `Bearer ${runtimeToken}`)
.send({ content: 'Summary content', messageType: 'text' });// Install multiple agents on same pod
await Promise.all([
request(app).post('/api/registry/install').set('Authorization', `Bearer ${authToken}`)
.send({ agentName: 'commonly-bot', podId: testPod._id.toString(), scopes: [...] }),
request(app).post('/api/registry/install').set('Authorization', `Bearer ${authToken}`)
.send({ agentName: 'clawdbot', podId: testPod._id.toString(), scopes: [...] }),
]);
// Enqueue events for each agent
await AgentEventService.enqueue({ agentName: 'commonly-bot', podId, type: 'discord.summary', payload: {...} });
await AgentEventService.enqueue({ agentName: 'clawdbot', podId, type: 'integration.summary', payload: {...} });
// Each agent polls their own events
const commonlyPoll = await request(app).get('/api/agents/runtime/events')
.set('Authorization', `Bearer ${commonlyToken}`);
const clawdbotPoll = await request(app).get('/api/agents/runtime/events')
.set('Authorization', `Bearer ${clawdbotToken}`);// .eslintrc.js
module.exports = {
extends: ['eslint:recommended', 'plugin:react/recommended'],
rules: {
'no-unused-vars': 'error',
'no-console': 'warn'
}
};Skill catalog is generated into docs/skills/awesome-agent-skills-index.json.
Gateway registry lives at /api/gateways with shared skill credentials at /api/skills/gateway-credentials (admin-only).
Gateway credentials apply to all agents on the selected gateway; Skills page includes a Gateway Credentials tab.
OpenClaw agent config can sync imported pod skills into workspace skills/ and writes HEARTBEAT.md per agent workspace.
Social/activity route coverage now includes:
backend/__tests__/unit/routes/users.social.test.js (user follow/unfollow routes)backend/__tests__/unit/routes/activity.read.test.js (unread count + mark-read routes)backend/__tests__/unit/routes/posts.test.js extended for thread follow routes.Team-Commonly/commonly
931b8ff
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.