* Increase coverage * Add comprehensive LLM development documentation - Add CLAUDE.md as main documentation index - Create 8 detailed documentation files in docs/: - architecture.md: Tech stack, data models, auth system - directory-structure.md: Complete file tree with paths - backend-patterns.md: Module architecture and patterns - database.md: Models, migrations, and workflows - development-workflow.md: Setup and daily development - code-conventions.md: Style guide and best practices - testing.md: Test organization and patterns - common-tasks.md: How-to guides for frequent tasks - Update .gitignore to allow project-level CLAUDE.md - 4,285 lines of comprehensive documentation - Organized for easy navigation with cross-links - LLM-optimized with absolute paths and code examples * fixup! Add comprehensive LLM development documentation
154 lines
5.2 KiB
JavaScript
154 lines
5.2 KiB
JavaScript
const BaseRepository = require('../../../shared/database/BaseRepository');
|
|
const { User } = require('../../../models');
|
|
const bcrypt = require('bcrypt');
|
|
|
|
describe('BaseRepository', () => {
|
|
let repo;
|
|
|
|
beforeAll(() => {
|
|
repo = new BaseRepository(User);
|
|
});
|
|
|
|
describe('create', () => {
|
|
it('should create a record', async () => {
|
|
const hash = await bcrypt.hash('pass', 10);
|
|
const user = await repo.create({
|
|
email: 'base-repo@test.com',
|
|
password_digest: hash,
|
|
});
|
|
expect(user.id).toBeDefined();
|
|
expect(user.email).toBe('base-repo@test.com');
|
|
});
|
|
});
|
|
|
|
describe('findById', () => {
|
|
it('should find a record by primary key', async () => {
|
|
const hash = await bcrypt.hash('pass', 10);
|
|
const created = await repo.create({
|
|
email: 'findbyid@test.com',
|
|
password_digest: hash,
|
|
});
|
|
const found = await repo.findById(created.id);
|
|
expect(found).not.toBeNull();
|
|
expect(found.email).toBe('findbyid@test.com');
|
|
});
|
|
|
|
it('should return null for non-existent id', async () => {
|
|
const found = await repo.findById(999999);
|
|
expect(found).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('findOne', () => {
|
|
it('should find a record by where clause', async () => {
|
|
const hash = await bcrypt.hash('pass', 10);
|
|
await repo.create({
|
|
email: 'findone@test.com',
|
|
password_digest: hash,
|
|
});
|
|
const found = await repo.findOne({ email: 'findone@test.com' });
|
|
expect(found).not.toBeNull();
|
|
expect(found.email).toBe('findone@test.com');
|
|
});
|
|
|
|
it('should return null when no match', async () => {
|
|
const found = await repo.findOne({ email: 'nonexistent@test.com' });
|
|
expect(found).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('findAll', () => {
|
|
it('should return all matching records', async () => {
|
|
const hash = await bcrypt.hash('pass', 10);
|
|
await repo.create({
|
|
email: 'findall1@test.com',
|
|
password_digest: hash,
|
|
});
|
|
await repo.create({
|
|
email: 'findall2@test.com',
|
|
password_digest: hash,
|
|
});
|
|
const all = await repo.findAll();
|
|
expect(all.length).toBeGreaterThanOrEqual(2);
|
|
});
|
|
|
|
it('should filter with where clause', async () => {
|
|
const hash = await bcrypt.hash('pass', 10);
|
|
await repo.create({
|
|
email: 'specific@test.com',
|
|
password_digest: hash,
|
|
});
|
|
const results = await repo.findAll({ email: 'specific@test.com' });
|
|
expect(results).toHaveLength(1);
|
|
expect(results[0].email).toBe('specific@test.com');
|
|
});
|
|
});
|
|
|
|
describe('update', () => {
|
|
it('should update instance fields', async () => {
|
|
const hash = await bcrypt.hash('pass', 10);
|
|
const user = await repo.create({
|
|
email: 'update@test.com',
|
|
password_digest: hash,
|
|
});
|
|
await repo.update(user, { email: 'updated@test.com' });
|
|
await user.reload();
|
|
expect(user.email).toBe('updated@test.com');
|
|
});
|
|
});
|
|
|
|
describe('destroy', () => {
|
|
it('should delete a record', async () => {
|
|
const hash = await bcrypt.hash('pass', 10);
|
|
const user = await repo.create({
|
|
email: 'destroy@test.com',
|
|
password_digest: hash,
|
|
});
|
|
const id = user.id;
|
|
await repo.destroy(user);
|
|
const found = await repo.findById(id);
|
|
expect(found).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('count', () => {
|
|
it('should count all records', async () => {
|
|
const hash = await bcrypt.hash('pass', 10);
|
|
await repo.create({
|
|
email: 'count1@test.com',
|
|
password_digest: hash,
|
|
});
|
|
const c = await repo.count();
|
|
expect(c).toBeGreaterThanOrEqual(1);
|
|
});
|
|
|
|
it('should count with where clause', async () => {
|
|
const hash = await bcrypt.hash('pass', 10);
|
|
await repo.create({
|
|
email: 'countfilter@test.com',
|
|
password_digest: hash,
|
|
});
|
|
const c = await repo.count({ email: 'countfilter@test.com' });
|
|
expect(c).toBe(1);
|
|
});
|
|
});
|
|
|
|
describe('exists', () => {
|
|
it('should return true when record exists', async () => {
|
|
const hash = await bcrypt.hash('pass', 10);
|
|
await repo.create({
|
|
email: 'exists@test.com',
|
|
password_digest: hash,
|
|
});
|
|
const result = await repo.exists({ email: 'exists@test.com' });
|
|
expect(result).toBe(true);
|
|
});
|
|
|
|
it('should return false when record does not exist', async () => {
|
|
const result = await repo.exists({
|
|
email: 'doesnotexist@test.com',
|
|
});
|
|
expect(result).toBe(false);
|
|
});
|
|
});
|
|
});
|