newsie
Version:
An NNTP Client Library targeting NodeJS. It supports the authentication, TLS encryption, base NNTP commands, and more.
229 lines (203 loc) • 6.03 kB
text/typescript
/* tslint:disable:no-object-literal-type-assertion */
import * as net from 'net'
import * as tls from 'tls'
import { GroupResponse } from '../src'
import Client from '../src/Client'
import { Server } from '../src/MockServer'
describe('session administration', () => {
let server
let client
beforeEach(async () => {
server = new Server()
await server.listen()
client = new Client({
host: 'localhost',
port: server.getListeningPort()
})
})
afterEach(() => {
client.disconnect()
return server.close()
})
test('client connects and disconnects from server', async () => {
const greeting = await client.connect()
expect(greeting).toEqual({
code: 200,
comment: 'posting permitted',
description: 'Service available, posting allowed',
socket: expect.any(net.Socket)
})
const leave = await client.quit()
expect(leave).toEqual({
code: 205,
comment: 'NNTP Service exits normally',
description: 'Connection closing'
})
})
test('client connects, upgrades to TLS', async () => {
client = new Client({
host: 'localhost',
port: server.getListeningPort(),
tlsOptions: {
rejectUnauthorized: false
}
})
await client.connect()
server.addHandler((socket, line) => {
expect(line).toBe('STARTTLS\r\n')
socket.write('382 begin tls negotiation now\r\n')
server.upgradeTls()
return true
})
let response = await client.startTls()
expect(response).toEqual({
code: 382,
comment: 'begin tls negotiation now',
description: 'Continue with TLS negotiation',
socket: expect.any(tls.TLSSocket)
})
expect(response.socket.getPeerCertificate().fingerprint).toBe(
'D4:B6:C3:4F:90:C1:85:82:A3:53:E6:F7:DB:6B:95:85:3D:E9:E2:FF'
)
server.resetHandlers()
server.addSimpleHandler(command => {
expect(command).toBe('LISTGROUP')
return '211 2000 3000234 3002322 misc.test list follows\r\n3000234\r\n.\r\n'
})
response = await client.listGroup()
expect(response).toEqual({
code: 211,
comment: 'list follows',
description: 'Article numbers follow (multi-line)',
group: {
number: 2000,
low: 3000234,
high: 3002322,
name: 'misc.test',
articleNumbers: [3000234]
}
} as GroupResponse)
})
test.skip('client connects directly to TLS server', async () => {
await server.upgradeTls()
client = new Client({
host: 'localhost',
port: server.getListeningPort(),
tlsPort: true,
tlsOptions: {
rejectUnauthorized: false
}
})
const response = await client.connect()
expect(response).toEqual({
code: 200,
comment: 'posting permitted',
description: 'Service available, posting allowed',
socket: expect.any(tls.TLSSocket)
})
// expect(response.socket.getPeerCertificate().fingerprint)
// .toBe('D4:B6:C3:4F:90:C1:85:82:A3:53:E6:F7:DB:6B:95:85:3D:E9:E2:FF')
//
// server.resetHandlers()
// server.addSimpleHandler(command => {
// expect(command).toBe('LISTGROUP')
// return '211 2000 3000234 3002322 misc.test list follows\r\n3000234\r\n.\r\n'
// })
//
// response = await client.listGroup()
// expect(response).toEqual({
// code: 211,
// comment: 'list follows',
// description: 'Article numbers follow (multi-line)',
// number: 2000,
// low: 3000234,
// high: 3002322,
// group: 'misc.test',
// articleNumbers: [
// 3000234
// ]
// })
})
})
describe('connected', () => {
let server
let client
let handler
function reply(msg) {
if (msg instanceof Array) {
msg = msg.join('\r\n')
}
handler.mockReturnValue(`${msg}\r\n`)
}
beforeEach(async () => {
server = new Server()
await server.listen()
client = new Client({
host: 'localhost',
port: server.getListeningPort()
})
handler = jest.fn()
server.addSimpleHandler(handler)
await client.connect()
})
afterEach(() => {
client.disconnect()
return server.close()
})
describe('6.1. Group and Article Selection', () => {
describe('6.1.2. LISTGROUP', () => {
test('411 example', async () => {
reply('411 newsgroup not found')
let caught = false
return client
.listGroup('misc.test')
.catch(response => {
expect(response).toEqual({
code: 411,
comment: 'newsgroup not found',
description: 'No such newsgroup'
})
caught = true
})
.then(() => {
expect(caught).toBe(true)
})
})
test('412 example', async () => {
reply('412 none selected')
let caught = false
return client
.listGroup()
.catch(response => {
expect(response).toEqual({
code: 412,
comment: 'none selected',
description: 'No newsgroup selected'
})
caught = true
})
.then(() => {
expect(caught).toBe(true)
})
})
})
})
describe('6.3. Article Posting', () => {
describe.skip('6.3.1 POST', () => {})
describe.skip('6.3.1 IHAVE', () => {})
})
describe('7. Information Commands', () => {
describe('7.3. NEWGROUPS', () => {})
describe.skip('7.4. NEWNEWS', () => {})
describe.skip('7.5. TIME', () => {})
describe('7.6. The LIST Commands', () => {
describe.skip('7.6.1. LIST', () => {})
describe.skip('7.6.2. Standard LIST Keywords', () => {})
describe.skip('7.6.3. LIST ACTIVE', () => {})
describe.skip('7.6.4. LIST ACTIVE.TIMES', () => {})
describe.skip('7.6.5. LIST DISTRIB.PATS', () => {})
describe.skip('7.6.6. LIST NEWSGROUPS', () => {})
})
})
describe('8. Article Field Access Commands', () => {})
})