import { describe, expect, it } from 'vitest';

import { resolveSendMetadata, safeDynamicMetadata } from '../metadata';

describe('resolveSendMetadata', () => {
  it('passes static metadata through when there is no contributor', () => {
    const result = resolveSendMetadata({ locale: 'en' }, undefined);
    expect(result).toEqual({ locale: 'en' });
  });

  it('returns undefined when both static and dynamic are absent', () => {
    expect(resolveSendMetadata(undefined, undefined)).toBeUndefined();
  });

  it('merges dynamic metadata over static metadata', () => {
    const result = resolveSendMetadata(
      { locale: 'en', slug: 'proj' },
      () => ({ pageContext: { url: '/x' } }),
    );
    expect(result).toEqual({
      locale: 'en',
      slug: 'proj',
      pageContext: { url: '/x' },
    });
  });

  it('lets dynamic keys win on collision', () => {
    const result = resolveSendMetadata(
      { locale: 'en' },
      () => ({ locale: 'fr' }),
    );
    expect(result).toEqual({ locale: 'fr' });
  });

  it('passes static through when the contributor returns undefined', () => {
    const result = resolveSendMetadata({ locale: 'en' }, () => undefined);
    expect(result).toEqual({ locale: 'en' });
  });

  it('does not break the send when the contributor throws', () => {
    const result = resolveSendMetadata({ locale: 'en' }, () => {
      throw new Error('capture failed');
    });
    // Falls back to static metadata — the send must still proceed.
    expect(result).toEqual({ locale: 'en' });
  });

  it('produces a fresh object each call (no shared mutation)', () => {
    const getDynamic = () => ({ n: 1 });
    const a = resolveSendMetadata({ locale: 'en' }, getDynamic);
    const b = resolveSendMetadata({ locale: 'en' }, getDynamic);
    expect(a).not.toBe(b);
    expect(a).toEqual(b);
  });
});

describe('safeDynamicMetadata', () => {
  it('returns the contributor result', () => {
    expect(safeDynamicMetadata(() => ({ a: 1 }))).toEqual({ a: 1 });
  });

  it('swallows a throw and returns undefined', () => {
    expect(
      safeDynamicMetadata(() => {
        throw new Error('boom');
      }),
    ).toBeUndefined();
  });
});
