import { HttpClient, provideHttpClient, withInterceptors } from '@angular/common/http';
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
import { TestBed } from '@angular/core/testing';
import {
  AUTH_ALLOWED_ORIGINS,
  AUTH_PUBLIC_URL_PREFIXES,
  AUTH_TOKEN_SOURCE,
  authTokenInterceptor,
} from './auth-token.interceptor';

describe('authTokenInterceptor', () => {
  let http: HttpClient;
  let controller: HttpTestingController;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        provideHttpClient(withInterceptors([authTokenInterceptor])),
        provideHttpClientTesting(),
        { provide: AUTH_TOKEN_SOURCE, useValue: { getToken: () => 'secret-token' } },
        { provide: AUTH_ALLOWED_ORIGINS, useValue: ['https://api.example.com'] },
        { provide: AUTH_PUBLIC_URL_PREFIXES, useValue: ['/public/'] },
      ],
    });
    http = TestBed.inject(HttpClient);
    controller = TestBed.inject(HttpTestingController);
  });

  afterEach(() => controller.verify());

  it('adds the token to same-origin API requests', () => {
    http.get('/api/payments').subscribe();
    const request = controller.expectOne('/api/payments');
    expect(request.request.headers.get('Authorization')).toBe('Bearer secret-token');
    request.flush({});
  });

  it('adds the token only to explicitly allowed absolute origins', () => {
    http.get('https://api.example.com/payments').subscribe();
    const allowed = controller.expectOne('https://api.example.com/payments');
    expect(allowed.request.headers.get('Authorization')).toBe('Bearer secret-token');
    allowed.flush({});

    http.get('https://third-party.example/payments').subscribe();
    const blocked = controller.expectOne('https://third-party.example/payments');
    expect(blocked.request.headers.has('Authorization')).toBe(false);
    blocked.flush({});
  });

  it('does not add credentials to configured public endpoints', () => {
    http.get('/public/session').subscribe();
    const request = controller.expectOne('/public/session');
    expect(request.request.headers.has('Authorization')).toBe(false);
    request.flush({});
  });
});
