import '@angular/compiler';
import { Injector, runInInjectionContext } from '@angular/core';
import { Apollo } from 'apollo-angular';
import { gql } from 'graphql-tag';
import { of } from 'rxjs';
import { mutateDeleteById } from './mutate-delete-by-id';

const MOCK_MUTATION = gql`
  mutation DeleteTagById($id: ID!) {
    iamDeleteTagById(id: $id) {
      id
    }
  }
`;

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

  beforeEach(() => {
    apolloMutateSpy = vi.fn().mockReturnValue(of({ data: { iamDeleteTagById: { id: '1' } } }));
    injector = Injector.create({
      providers: [{ provide: Apollo, useValue: { mutate: apolloMutateSpy } }],
    });
  });

  function run(id: string, headers?: Record<string, string>) {
    return runInInjectionContext(injector, () => mutateDeleteById(MOCK_MUTATION, id, headers));
  }

  it('calls apollo.mutate with the id', () => {
    run('42').subscribe();
    expect(apolloMutateSpy).toHaveBeenCalledWith({
      mutation: MOCK_MUTATION,
      variables: { id: '42' },
      context: { headers: undefined },
    });
  });

  it('forwards custom headers to the mutation context', () => {
    run('42', { 'X-Tenant-Id': 'abc' }).subscribe();
    const arg = apolloMutateSpy.mock.calls[0][0];
    expect(arg.context).toEqual({ headers: { 'X-Tenant-Id': 'abc' } });
  });

  it('returns the apollo mutation observable', () => {
    let emitted: unknown;
    run('42').subscribe((r) => (emitted = r));
    expect(emitted).toEqual({ data: { iamDeleteTagById: { id: '1' } } });
  });
});
