FRE-4414: Unblock and update ShieldAI status
- Cleared cancelled blocker FRE-4428 - Updated to in_progress - Added status comment documenting delegated work to CTO/CMO Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { appRouter } from './index';
|
||||
import { getTestDb, resetTestDb } from './test-setup';
|
||||
import { getTestDb, resetTestDb, globalSqlite } from './test-setup';
|
||||
import type { TRPCContext } from './types';
|
||||
|
||||
describe('tRPC API Layer', () => {
|
||||
@@ -11,7 +11,7 @@ describe('tRPC API Layer', () => {
|
||||
beforeEach(async () => {
|
||||
await resetTestDb();
|
||||
const db = await getTestDb();
|
||||
ctx = { userId: 1, db };
|
||||
ctx = { clerkUserId: 'user_test', db };
|
||||
caller = appRouter.createCaller(ctx);
|
||||
});
|
||||
|
||||
@@ -162,4 +162,141 @@ describe('tRPC API Layer', () => {
|
||||
).rejects.toThrow('not found');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Project Sharing', () => {
|
||||
let sharedProjectId: number;
|
||||
|
||||
beforeEach(async () => {
|
||||
const project = await caller.project.createProject({
|
||||
name: 'Shared Project',
|
||||
});
|
||||
sharedProjectId = project.id;
|
||||
|
||||
// Insert a second user
|
||||
globalSqlite!.exec("INSERT INTO users (id, email, name) VALUES (2, 'user2@test.com', 'User Two');");
|
||||
});
|
||||
|
||||
it('should share a project with another user', async () => {
|
||||
const member = await caller.project.shareProject({
|
||||
projectId: sharedProjectId,
|
||||
userId: 2,
|
||||
role: 'editor',
|
||||
});
|
||||
|
||||
expect(member).toMatchObject({
|
||||
projectId: sharedProjectId,
|
||||
userId: 2,
|
||||
role: 'editor',
|
||||
});
|
||||
});
|
||||
|
||||
it('should list project members including owner', async () => {
|
||||
await caller.project.shareProject({
|
||||
projectId: sharedProjectId,
|
||||
userId: 2,
|
||||
role: 'viewer',
|
||||
});
|
||||
|
||||
const members = await caller.project.listMembers({ projectId: sharedProjectId });
|
||||
|
||||
expect(members.length).toBeGreaterThanOrEqual(2);
|
||||
const owner = members.find((m: any) => m.userId === 1 && m.role === 'owner');
|
||||
const member = members.find((m: any) => m.userId === 2 && m.role === 'viewer');
|
||||
expect(owner).toBeDefined();
|
||||
expect(member).toBeDefined();
|
||||
});
|
||||
|
||||
it('should update a member role', async () => {
|
||||
await caller.project.shareProject({
|
||||
projectId: sharedProjectId,
|
||||
userId: 2,
|
||||
role: 'viewer',
|
||||
});
|
||||
|
||||
const updated = await caller.project.updateMemberRole({
|
||||
projectId: sharedProjectId,
|
||||
userId: 2,
|
||||
role: 'admin',
|
||||
});
|
||||
|
||||
expect(updated.role).toBe('admin');
|
||||
});
|
||||
|
||||
it('should remove a member', async () => {
|
||||
await caller.project.shareProject({
|
||||
projectId: sharedProjectId,
|
||||
userId: 2,
|
||||
role: 'editor',
|
||||
});
|
||||
|
||||
const result = await caller.project.removeMember({
|
||||
projectId: sharedProjectId,
|
||||
userId: 2,
|
||||
});
|
||||
|
||||
expect(result).toEqual({ success: true });
|
||||
|
||||
const members = await caller.project.listMembers({ projectId: sharedProjectId });
|
||||
const removed = members.find((m: any) => m.userId === 2);
|
||||
expect(removed).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should throw error when sharing with yourself', async () => {
|
||||
await expect(
|
||||
caller.project.shareProject({
|
||||
projectId: sharedProjectId,
|
||||
userId: 1,
|
||||
role: 'editor',
|
||||
})
|
||||
).rejects.toThrow('yourself');
|
||||
});
|
||||
|
||||
it('should throw error when sharing duplicate user', async () => {
|
||||
await caller.project.shareProject({
|
||||
projectId: sharedProjectId,
|
||||
userId: 2,
|
||||
role: 'editor',
|
||||
});
|
||||
|
||||
await expect(
|
||||
caller.project.shareProject({
|
||||
projectId: sharedProjectId,
|
||||
userId: 2,
|
||||
role: 'viewer',
|
||||
})
|
||||
).rejects.toThrow('already a member');
|
||||
});
|
||||
|
||||
it('should allow shared members to access project', async () => {
|
||||
await caller.project.shareProject({
|
||||
projectId: sharedProjectId,
|
||||
userId: 2,
|
||||
role: 'editor',
|
||||
});
|
||||
|
||||
// Create caller for user 2
|
||||
const db = await getTestDb();
|
||||
const ctx2: TRPCContext = { userId: 2, db };
|
||||
const caller2 = appRouter.createCaller(ctx2);
|
||||
|
||||
const project = await caller2.project.getProject({ id: sharedProjectId });
|
||||
expect(project.id).toBe(sharedProjectId);
|
||||
});
|
||||
|
||||
it('should include shared projects in listProjects for member', async () => {
|
||||
await caller.project.shareProject({
|
||||
projectId: sharedProjectId,
|
||||
userId: 2,
|
||||
role: 'viewer',
|
||||
});
|
||||
|
||||
const db = await getTestDb();
|
||||
const ctx2: TRPCContext = { userId: 2, db };
|
||||
const caller2 = appRouter.createCaller(ctx2);
|
||||
|
||||
const projects = await caller2.project.listProjects();
|
||||
const found = projects.find((p: any) => p.id === sharedProjectId);
|
||||
expect(found).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user