fix(social): normalize username lookup on POST /api/social/requests

Registration canonicalizes usernames to lowercase (auth.ts:32),
but the friend-request endpoint compared with strict eq() against
raw user input, so 'Bob' returned 404 even when 'bob' existed.
Trim and lowercase before lookup, matching the rest of the auth
boundary. Empty-after-trim now returns 400 (was: 404).

Tests appended to social.test.ts as a second describe block
sharing the harness from Task 1.
This commit is contained in:
Jannis Braun
2026-04-25 19:14:31 +02:00
parent e99e0e7862
commit 5f5590a3c9
2 changed files with 62 additions and 2 deletions
+54
View File
@@ -159,3 +159,57 @@ describe('GET /api/social/search — filter hygiene', () => {
expect(out.map(u => u.id)).toContain('u1');
});
});
describe('POST /api/social/requests — case-insensitive username lookup', () => {
let app: FastifyInstance;
beforeEach(async () => {
sqlite = new Database(':memory:');
testDb = drizzle(sqlite, { schema });
applyMigrations(sqlite);
seedUser({ id: CALLER_ID, username: 'caller' });
// Target stored canonically lowercase, as registration would write it.
seedUser({ id: 'target-id', username: 'bob' });
app = await buildApp();
});
async function sendRequest(username: string) {
return app.inject({
method: 'POST',
url: '/api/social/requests',
payload: { username },
});
}
it('finds the target when the caller types the exact stored handle', async () => {
const res = await sendRequest('bob');
expect(res.statusCode).toBe(201);
const inserted = testDb.select().from(schema.friendRequests)
.where(eq(schema.friendRequests.toId, 'target-id')).get();
expect(inserted).toBeTruthy();
});
it('finds the target when the caller types a mixed-case handle', async () => {
const res = await sendRequest('Bob');
expect(res.statusCode).toBe(201);
const inserted = testDb.select().from(schema.friendRequests)
.where(eq(schema.friendRequests.toId, 'target-id')).get();
expect(inserted).toBeTruthy();
});
it('finds the target when the caller types an all-uppercase handle', async () => {
const res = await sendRequest('BOB');
expect(res.statusCode).toBe(201);
});
it('trims surrounding whitespace before lookup', async () => {
const res = await sendRequest(' bob ');
expect(res.statusCode).toBe(201);
});
it('returns 404 when the handle does not exist', async () => {
const res = await sendRequest('nobody');
expect(res.statusCode).toBe(404);
expect(JSON.parse(res.body).error).toBe('User not found');
});
});