import type { ExecutionContext } from '@nestjs/common';
import { ForbiddenException } from '@nestjs/common';
import { describe, expect, it } from 'vitest';
import { fullModuleAccess } from '../access/modules';
import type { AuthenticatedUser } from './authenticated-user';
import { ReadOnlyGuard } from './read-only.guard';

function context(method: string, url: string, isReadOnly: boolean): ExecutionContext {
  const user: AuthenticatedUser = {
    id: '11111111-1111-4111-8111-111111111111',
    email: 'presentation@example.test',
    displayName: 'Presentation',
    role: 'USER',
    isReadOnly,
    subscriptionTier: null,
    accessExpiresAt: new Date('2099-01-01T00:00:00Z'),
    sessionId: 'session',
    modules: fullModuleAccess(),
  };
  return {
    switchToHttp: () => ({ getRequest: () => ({ method, url, user }) }),
  } as unknown as ExecutionContext;
}

describe('ReadOnlyGuard', () => {
  const guard = new ReadOnlyGuard();

  it('allows reads for a presentation account', () => {
    expect(guard.canActivate(context('GET', '/api/v1/state/demo', true))).toBe(true);
  });

  it('blocks every data-changing request for a presentation account', () => {
    expect(() => guard.canActivate(context('PUT', '/api/v1/state/demo', true)))
      .toThrow(ForbiddenException);
    expect(() => guard.canActivate(context('POST', '/api/v1/community/posts/1/comments', true)))
      .toThrow(ForbiddenException);
  });

  it('still permits logout and leaves normal accounts unchanged', () => {
    expect(guard.canActivate(context('POST', '/api/v1/auth/logout', true))).toBe(true);
    expect(guard.canActivate(context('DELETE', '/api/v1/portfolios/1', false))).toBe(true);
  });
});
