78 lines
2.7 KiB
TypeScript
78 lines
2.7 KiB
TypeScript
|
|
/**
|
||
|
|
* updateUser persists the optional signing-identity override
|
||
|
|
* (user_profiles.signing_email): lowercased on the way in, and cleared to NULL
|
||
|
|
* when an empty string is supplied.
|
||
|
|
*/
|
||
|
|
import { afterAll, describe, expect, it, vi } from 'vitest';
|
||
|
|
import { eq } from 'drizzle-orm';
|
||
|
|
|
||
|
|
import { db } from '@/lib/db';
|
||
|
|
import { account, roles, user, userProfiles } from '@/lib/db/schema';
|
||
|
|
import { auth } from '@/lib/auth';
|
||
|
|
import { createUser, updateUser } from '@/lib/services/users.service';
|
||
|
|
import { makePort, makeAuditMeta } from '../helpers/factories';
|
||
|
|
|
||
|
|
describe('updateUser - signing_email override', () => {
|
||
|
|
const createdUserIds: string[] = [];
|
||
|
|
|
||
|
|
afterAll(async () => {
|
||
|
|
for (const id of createdUserIds) {
|
||
|
|
await db.delete(account).where(eq(account.userId, id));
|
||
|
|
await db.delete(userProfiles).where(eq(userProfiles.userId, id));
|
||
|
|
await db.delete(user).where(eq(user.id, id));
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
async function makeUser(): Promise<{ userId: string; portId: string }> {
|
||
|
|
const resetSpy = vi
|
||
|
|
.spyOn(auth.api, 'requestPasswordReset')
|
||
|
|
.mockResolvedValue({ status: true } as never);
|
||
|
|
try {
|
||
|
|
const port = await makePort();
|
||
|
|
const role = await db.query.roles.findFirst({ where: eq(roles.name, 'sales_manager') });
|
||
|
|
if (!role) throw new Error('sales_manager role not seeded');
|
||
|
|
const created = await createUser(
|
||
|
|
port.id,
|
||
|
|
{
|
||
|
|
email: `signemail-${Date.now()}-${Math.random().toString(36).slice(2, 6)}@example.test`,
|
||
|
|
name: 'Abbie May',
|
||
|
|
displayName: 'Abbie May',
|
||
|
|
roleId: role.id,
|
||
|
|
sendSetupEmail: true,
|
||
|
|
residentialAccess: false,
|
||
|
|
},
|
||
|
|
makeAuditMeta(),
|
||
|
|
);
|
||
|
|
createdUserIds.push(created.userId);
|
||
|
|
return { userId: created.userId, portId: port.id };
|
||
|
|
} finally {
|
||
|
|
resetSpy.mockRestore();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
async function readSigningEmail(userId: string): Promise<string | null> {
|
||
|
|
const row = await db.query.userProfiles.findFirst({
|
||
|
|
where: eq(userProfiles.userId, userId),
|
||
|
|
});
|
||
|
|
return row?.signingEmail ?? null;
|
||
|
|
}
|
||
|
|
|
||
|
|
it('persists a signing email, lowercased', async () => {
|
||
|
|
const { userId, portId } = await makeUser();
|
||
|
|
|
||
|
|
await updateUser(userId, portId, { signingEmail: 'SALES@PortNimara.com' }, makeAuditMeta());
|
||
|
|
|
||
|
|
expect(await readSigningEmail(userId)).toBe('sales@portnimara.com');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('clears the override when an empty string is supplied', async () => {
|
||
|
|
const { userId, portId } = await makeUser();
|
||
|
|
await updateUser(userId, portId, { signingEmail: 'sales@portnimara.com' }, makeAuditMeta());
|
||
|
|
expect(await readSigningEmail(userId)).toBe('sales@portnimara.com');
|
||
|
|
|
||
|
|
await updateUser(userId, portId, { signingEmail: '' }, makeAuditMeta());
|
||
|
|
|
||
|
|
expect(await readSigningEmail(userId)).toBeNull();
|
||
|
|
});
|
||
|
|
});
|