import { describe, it, expect } from 'vitest';
import { AggregateRoot } from '../aggregate-root';
import { type DomainEvent } from '../domain-event';

class TestAggregate extends AggregateRoot {
  doSomething(): void {
    this.addDomainEvent({
      eventName: 'TestHappened',
      occurredAt: new Date(),
      aggregateId: this.id,
    });
  }
}

describe('AggregateRoot', () => {
  it('should collect domain events', () => {
    const agg = new TestAggregate('agg-1');
    agg.doSomething();
    agg.doSomething();
    expect(agg.domainEvents).toHaveLength(2);
    expect(agg.domainEvents[0]!.eventName).toBe('TestHappened');
  });

  it('should clear domain events and return them', () => {
    const agg = new TestAggregate('agg-1');
    agg.doSomething();
    const events = agg.clearDomainEvents();
    expect(events).toHaveLength(1);
    expect(agg.domainEvents).toHaveLength(0);
  });

  it('should return a copy of domain events (not mutable reference)', () => {
    const agg = new TestAggregate('agg-1');
    agg.doSomething();
    const events = agg.domainEvents;
    (events as DomainEvent[]).push({
      eventName: 'Fake',
      occurredAt: new Date(),
      aggregateId: 'x',
    });
    expect(agg.domainEvents).toHaveLength(1);
  });
});
