import connection_pool from '../networking/connection_pool';
import packet from '../networking/packet';
import connection from '../networking/connection';

jest.mock('../networking/connection');

test(`construction fails if pool size is <= 1`, () => {
  expect(() => new connection_pool(1)).toThrow(Error);
  expect(() => new connection_pool(0)).toThrow(Error);
  expect(() => new connection_pool(-1)).toThrow(Error);
});

test(`error on socket release is ignored`, async () => {
  const conn = new connection_pool(2, '', 20000);
  let invoked = false;
  jest.spyOn(conn.pool, 'acquire').mockImplementation(() => {
    return {
      release: () => {
        invoked = true;
        throw new Error('mock release error');
      },
    };
  });

  const mock_send = jest.fn();
  connection.prototype.send = async () => {
    return mock_send();
  };
  mock_send.mockResolvedValue(0);

  expect(await conn.send('', new packet())).toEqual(0);
  expect(invoked).toBeTruthy();
});

test(`connection pool send fails if socket acquire fails`, async () => {
  const conn = new connection_pool(2, '', 20000);
  jest.spyOn(conn.pool, 'acquire').mockImplementation(() => {
    throw new Error('mock acquire exception');
  });

  await expect(conn.send('', new packet())).rejects.toThrow(Error);
});

test(`connection pool send fails when connection send fails`, async () => {
  const conn = new connection_pool(2, '', 20000);
  jest.spyOn(conn.pool, 'acquire').mockImplementation(() => {
    return {
      release: () => {},
    };
  });

  const mock_send = jest.fn();
  connection.prototype.send = async () => {
    return mock_send();
  };
  mock_send.mockRejectedValue(new Error('mock send failed'));

  await expect(conn.send('', new packet())).rejects.toThrow(Error);
});
