import '@angular/compiler';
import { Injector, runInInjectionContext } from '@angular/core';
import { Apollo } from 'apollo-angular';
import { gql } from 'graphql-tag';
import { of } from 'rxjs';
import { queryGet } from './query-get';

const MOCK_QUERY = gql`
  query GetTags($query: QueryStatement, $constraint: QueryStatement) {
    objects: iamGetTags(query: $query, constraint: $constraint) {
      id
      name
    }
  }
`;

interface Tag {
  id: string;
  name: string;
}

describe('queryGet', () => {
  let apolloQuerySpy: ReturnType<typeof vi.fn>;
  let injector: Injector;

  beforeEach(() => {
    apolloQuerySpy = vi
      .fn()
      .mockReturnValue(of({ data: { objects: [{ id: '1', name: 'Tag A' }] } }));

    injector = Injector.create({
      providers: [{ provide: Apollo, useValue: { query: apolloQuerySpy } }],
    });
  });

  function run(fields?: string, variables?: Record<string, unknown>) {
    return runInInjectionContext(injector, () =>
      queryGet<Tag>(MOCK_QUERY, 'objects', fields, variables as never),
    );
  }

  it('emits the list under the given key', () => {
    let result: Tag[] = [];
    run().subscribe((r) => (result = r));
    expect(result).toEqual([{ id: '1', name: 'Tag A' }]);
  });

  it('emits an empty array when the key is missing', () => {
    apolloQuerySpy.mockReturnValue(of({ data: {} }));
    let result: Tag[] = [{ id: 'x', name: 'x' }];
    run().subscribe((r) => (result = r));
    expect(result).toEqual([]);
  });

  it('passes headers into the context', () => {
    run(undefined, { headers: { 'X-Tenant-Id': 'abc' } }).subscribe();
    const arg = apolloQuerySpy.mock.calls[0][0];
    expect(arg.context).toEqual({ headers: { 'X-Tenant-Id': 'abc' } });
  });
});
