Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unit tests #77

Merged
merged 5 commits into from
May 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:

strategy:
matrix:
node-version: [16.x, 18.x, 19.x]
node-version: [16.x, 18.x, 19.x, 20.x]

steps:
- uses: actions/checkout@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/integration-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:

strategy:
matrix:
node-version: [16.x, 18.x, 19.x]
node-version: [16.x, 18.x, 19.x, 20.x]
winston-version: [2x, 3x]

steps:
Expand Down
3 changes: 2 additions & 1 deletion babel.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module.exports = {
presets: ['@babel/preset-typescript', '@babel/preset-env'],
ignore: ['src/winston-logstash.test.ts',
'src/winston-logstash-latest.test.ts'],
'src/winston-logstash-latest.test.ts',
'src/connection.test.ts', 'src/manager.test.ts'],
targets: 'node 6',
};
2 changes: 1 addition & 1 deletion lib/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ class PlainConnection extends Connection {
connect() {
super.connect();
this.socket = new _net.Socket();
this.socket.connect(this.port, this.host);
super.addEventListeners(this.socket);
this.socket.on('connect', super.socketOnConnect.bind(this));
this.socket.connect(this.port, this.host);
}
}
exports.PlainConnection = PlainConnection;
Expand Down
16 changes: 10 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

63 changes: 63 additions & 0 deletions src/connection.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Connection, PlainConnection, SecureConnection } from './connection';
import { Manager } from './manager';
import net from 'net';
import tls from 'tls';
import { EventEmitter } from 'events';
import { sslFilePath } from '../test/test_helper'

jest.mock('net');
jest.mock('tls');
jest.mock('./manager');

const MockedNet = net as jest.Mocked<typeof net>;
const MockedTls = tls as jest.Mocked<typeof tls>;
const MockedManager = Manager as jest.MockedClass<typeof Manager>;

beforeEach(() => {
MockedNet.Socket.mockClear();
MockedTls.connect.mockClear();
MockedManager.mockClear();
});

describe('Connection', () => {
// @ts-ignore
const manager = new Manager();
const options = { host: 'localhost', port: 12345 };
const connection = new Connection(options, manager);

test('initializes with provided options', () => {
// @ts-ignore
expect(connection.host).toBe(options.host);
// @ts-ignore
expect(connection.port).toBe(options.port);
});

test('can send a message', () => {
const socket = new EventEmitter() as net.Socket;
// @ts-ignore
socket.readyState = 'open';
socket.write = jest.fn().mockReturnValue(true);
// @ts-ignore
connection.socket = socket;
const message = 'test message';
const callback = jest.fn();

const result = connection.send(message, callback);

expect(result).toBe(true);
expect(socket.write).toHaveBeenCalledWith(Buffer.from(message), callback);
});

test('can close connection', () => {
const socket = new EventEmitter() as net.Socket;
socket.removeAllListeners = jest.fn();
socket.destroy = jest.fn();
// @ts-ignore
connection.socket = socket;

connection.close();

expect(socket.removeAllListeners).toHaveBeenCalled();
expect(socket.destroy).toHaveBeenCalled();
});
});
4 changes: 2 additions & 2 deletions src/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class Connection {
protected socket: Socket | undefined;
protected host: string;
protected port: number;
protected manager: any;
protected manager: Manager;
protected action: ConnectionActions;

constructor(options: WinstonModuleTransportOptions, manager: Manager) {
Expand Down Expand Up @@ -93,9 +93,9 @@ export class PlainConnection extends Connection {
connect() {
super.connect();
this.socket = new Socket();
this.socket.connect(this.port, this.host);
super.addEventListeners(this.socket);
this.socket.on('connect', super.socketOnConnect.bind(this));
this.socket.connect(this.port, this.host);
}
}

Expand Down
70 changes: 70 additions & 0 deletions src/manager.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { Manager } from './manager';
import { Connection, PlainConnection, SecureConnection } from './connection';

jest.mock('./connection');

const MockedConnection = Connection as jest.MockedClass<typeof Connection>;
const MockedPlainConnection = PlainConnection as jest.MockedClass<typeof PlainConnection>;
const MockedSecureConnection = SecureConnection as jest.MockedClass<typeof SecureConnection>;

describe('Manager', () => {
const options = {
host: 'localhost',
port: 12345,
ssl_enable: false,
max_connect_retries: 4,
timeout_connect_retries: 100
};

beforeEach(() => {
MockedConnection.mockClear();
MockedPlainConnection.mockClear();
MockedSecureConnection.mockClear();
});

test('initializes with provided options', () => {
const manager = new Manager(options);
expect(manager.options).toBe(options);
expect(manager.useSecureConnection).toBe(options.ssl_enable);
expect(manager.maxConnectRetries).toBe(options.max_connect_retries);
expect(manager.timeoutConnectRetries).toBe(options.timeout_connect_retries);
});

test('creates plain connection', () => {
const manager = new Manager(options);
manager.start();
expect(PlainConnection).toHaveBeenCalledTimes(1);
expect(SecureConnection).toHaveBeenCalledTimes(0);
});

test('creates secure connection', () => {
const manager = new Manager({ ...options, ssl_enable: true });
manager.start();
expect(PlainConnection).toHaveBeenCalledTimes(0);
expect(SecureConnection).toHaveBeenCalledTimes(1);
});

test('logs an entry', () => {
const logEntry = 'test log entry';
const callback = jest.fn();
const manager = new Manager(options);
manager.connection = new PlainConnection(options, manager);
manager.connection.send = jest.fn().mockReturnValue(true);
manager.log(logEntry, callback);
expect(manager.logQueue).toHaveLength(1);
expect(manager.logQueue[0][0]).toBe(logEntry);
});

test('flushes log queue', () => {
const logEntry = 'test log entry';
const callback = jest.fn();
const manager = new Manager(options);
manager.connection = new PlainConnection(options, manager);
manager.connection.send = jest.fn().mockReturnValue(true);
manager.connection.readyToSend = jest.fn().mockReturnValue(true);
manager.logQueue.push([logEntry, callback]);
manager.flush();
expect(manager.logQueue).toHaveLength(0);
expect(manager.connection.send).toHaveBeenCalledWith(logEntry + '\n', expect.any(Function));
});
});