Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

iota-gateway

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

iota-gateway - npm Package Compare versions

Comparing version 0.0.1 to 0.1.0

dist/neighbor.d.ts

29

dist/gateway.d.ts

@@ -0,15 +1,28 @@

/// <reference types="node" />
import { Transaction, Hash } from 'iota-tangle';
import { EventEmitter } from 'events';
import { Neighbor } from './neighbor';
import { Transport } from './transport';
export declare class Gateway {
export interface Data {
transaction: Transaction;
requestHash: Hash;
}
export declare class Gateway extends EventEmitter {
private _neighbors;
private _transports;
private _neighborsTransportsMap;
private _isRunning;
private _transports;
private _onTransportReceive;
private _onTransportError;
constructor(params: {
transports: Transport[];
neighbors?: Neighbor[];
transports?: Transport[];
});
send(transaction: Transaction, params: {
neighbor: string;
requestHash: Hash;
}): Promise<void>;
readonly isRunning: boolean;
getNeighbor(neighborAddress: string): Neighbor | null;
addNeighbor(neighbor: Neighbor): Promise<void>;
removeNeighbor(neighbor: Neighbor): Promise<void>;
run(): Promise<void>;
stop(): Promise<void>;
shutdown(): Promise<void>;
send(data: Data, neighborAddress: string): Promise<void>;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class Gateway {
const events_1 = require("events");
class Gateway extends events_1.EventEmitter {
constructor(params) {
super();
this._isRunning = false;
this._transports = params.transports;
this._onTransportReceive = null;
this._onTransportError = null;
const transports = params.transports || [];
const neighbors = params.neighbors || [];
if (!transports.length) {
throw new Error('You should provide at least one transport for the gateway!');
}
const neighborsTransportsMap = new Map();
NEIGHBOR_LOOP: for (const neighbor of neighbors) {
for (const transport of transports) {
if (transport.supports(neighbor)) {
neighborsTransportsMap.set(neighbor, transport);
continue NEIGHBOR_LOOP;
}
}
throw new Error(`Couldn't find a transport for the neighbor '${neighbor.address}'!`);
}
this._transports = transports;
this._neighbors = neighbors;
this._neighborsTransportsMap = neighborsTransportsMap;
}
async send(transaction, params) {
get isRunning() {
return this._isRunning;
}
getNeighbor(neighborAddress) {
for (const neighbor of this._neighbors) {
if (neighbor.match(neighborAddress)) {
return neighbor;
}
}
return null;
}
async addNeighbor(neighbor) {
if (this._neighborsTransportsMap.has(neighbor)) {
throw new Error(`Couldn't add a neighbor: the neighbor '${neighbor.address}' already exists!`);
}
for (const transport of this._transports) {
if (transport.supports(neighbor)) {
if (this._isRunning) {
await transport.addNeighbor(neighbor);
}
this._neighborsTransportsMap.set(neighbor, transport);
this._neighbors.push(neighbor);
return;
}
}
throw new Error(`Couldn't find a transport for the neighbor '${neighbor.address}'!`);
}
async removeNeighbor(neighbor) {
if (!this._neighborsTransportsMap.has(neighbor)) {
throw new Error(`Couldn't remove a neighbor: the neighbor '${neighbor.address}' doesn't exists!`);
}
if (this._isRunning) {
await this._neighborsTransportsMap.get(neighbor).removeNeighbor(neighbor);
}
this._neighborsTransportsMap.delete(neighbor);
this._neighbors.splice(this._neighbors.indexOf(neighbor), 1);
}
async run() {

@@ -15,18 +71,65 @@ if (this._isRunning) {

try {
await Promise.all(this._transports.map(t => t.run(() => { })));
await Promise.all(this._transports.map(async (transport) => {
await transport.run();
}));
await Promise.all(this._neighbors.map(async (neighbor) => {
await this._neighborsTransportsMap.get(neighbor).addNeighbor(neighbor);
}));
const onTransportReceive = (data, neighbor) => this.emit('receive', data, neighbor.address);
const onTransportError = (error) => this.emit('error', error);
for (const transport of this._transports) {
transport.on('receive', onTransportReceive);
transport.on('error', onTransportError);
}
this._onTransportReceive = onTransportReceive;
this._onTransportError = onTransportError;
}
catch (error) {
await Promise.all(this._transports.map(t => t.stop()));
await Promise.all(this._neighbors.map(async (neighbor) => {
try {
await this._neighborsTransportsMap.get(neighbor).removeNeighbor(neighbor);
}
catch (error) { }
}));
await Promise.all(this._transports.map(async (transport) => {
try {
await transport.shutdown();
}
catch (error) { }
}));
throw error;
}
this.emit('run');
this._isRunning = true;
}
async stop() {
async shutdown() {
if (!this._isRunning) {
throw new Error('The gateway is not running!');
}
await Promise.all(this._transports.map(t => t.stop()));
await Promise.all(this._neighbors.map((neighbor) => {
return this._neighborsTransportsMap.get(neighbor).removeNeighbor(neighbor);
}));
await Promise.all(this._transports.map((transport) => {
return transport.shutdown();
}));
for (const transport of this._transports) {
transport.removeListener('receive', this._onTransportReceive);
transport.removeListener('error', this._onTransportError);
}
this._onTransportReceive = null;
this._onTransportError = null;
this.emit('shutdown');
this._isRunning = false;
}
async send(data, neighborAddress) {
if (!this._isRunning) {
throw new Error("Can't send a data: the gateway is not running!");
}
const neighbor = this.getNeighbor(neighborAddress);
if (!neighbor) {
throw new Error(`Neighbor is not found for address '${neighborAddress}'!`);
}
await this._neighborsTransportsMap.get(neighbor).send(data, neighbor);
}
}
exports.Gateway = Gateway;

@@ -1,5 +0,4 @@

export { Gateway } from './gateway';
export { Gateway, Data } from './gateway';
export { Neighbor } from './neighbor';
export { Transport } from './transport';
export { Packer } from './packer';
export { Transport, ReceiveCallback } from './transport';
export { TcpTransport } from './tcp-transport';
export { UdpTransport } from './udp-transport';

@@ -5,9 +5,7 @@ "use strict";

exports.Gateway = gateway_1.Gateway;
var neighbor_1 = require("./neighbor");
exports.Neighbor = neighbor_1.Neighbor;
var transport_1 = require("./transport");
exports.Transport = transport_1.Transport;
var packer_1 = require("./packer");
exports.Packer = packer_1.Packer;
var transport_1 = require("./transport");
exports.Transport = transport_1.Transport;
var tcp_transport_1 = require("./tcp-transport");
exports.TcpTransport = tcp_transport_1.TcpTransport;
var udp_transport_1 = require("./udp-transport");
exports.UdpTransport = udp_transport_1.UdpTransport;
/// <reference types="node" />
import { Transaction, Hash, Factory } from 'iota-tangle';
import { Factory } from 'iota-tangle';
import { Data } from './gateway';
export declare const TRANSCTION_OFFSET = 0;

@@ -8,6 +9,2 @@ export declare const TRANSACTION_SIZE: number;

export declare const PACKET_SIZE: number;
export interface PacketData {
transaction: Transaction;
requestHash: Hash;
}
export declare class Packer {

@@ -19,4 +16,4 @@ private _factory;

readonly packetSize: number;
pack(data: PacketData): Buffer;
unpack(packet: Buffer): PacketData;
pack(data: Data): Buffer;
unpack(packet: Buffer): Data;
}

@@ -1,15 +0,13 @@

import { Transaction, Hash } from 'iota-tangle';
export interface ReceiveCallback {
(transaction: Transaction, params: {
neighbor: string;
requestHash?: Hash;
}): void;
/// <reference types="node" />
import { EventEmitter } from 'events';
import { Data } from './gateway';
import { Neighbor } from './neighbor';
export declare abstract class Transport extends EventEmitter {
readonly abstract isRunning: boolean;
abstract supports(neighbor: Neighbor): boolean;
abstract run(): Promise<void>;
abstract shutdown(): Promise<void>;
abstract addNeighbor(neighbor: Neighbor): Promise<void>;
abstract removeNeighbor(neighbor: Neighbor): Promise<void>;
abstract send(data: Data, neighbor: Neighbor): Promise<void>;
}
export declare abstract class Transport {
abstract send(transaction: Transaction, {neighbor: string, requestHash: Hash}: {
neighbor: any;
requestHash: any;
}): Promise<void>;
abstract run(cb: ReceiveCallback): Promise<void>;
abstract stop(): Promise<void>;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class Transport {
const events_1 = require("events");
class Transport extends events_1.EventEmitter {
}
exports.Transport = Transport;
{
"name": "iota-gateway",
"version": "0.0.1",
"version": "0.1.0",
"description": "Network gateway for IOTA",

@@ -5,0 +5,0 @@ "main": "./dist/index.js",

import { Transaction, Hash } from 'iota-tangle'
import { EventEmitter } from 'events'
import { Neighbor } from './neighbor'
import { Transport } from './transport'
import { Packer } from './packer'
export class Gateway {
export interface Data { transaction: Transaction, requestHash: Hash }
private _isRunning: boolean = false
export class Gateway extends EventEmitter {
private _neighbors: Neighbor[]
private _transports: Transport[]
private _neighborsTransportsMap: Map<Neighbor, Transport>
private _isRunning: boolean = false
private _onTransportReceive: ((data: Data, neighbor: Neighbor) => void)|null = null
private _onTransportError: ((error: any) => void)|null = null
constructor(params: {
transports: Transport[]
neighbors?: Neighbor[]
transports?: Transport[]
}) {
this._transports = params.transports
super()
const transports = params.transports || []
const neighbors = params.neighbors || []
if (!transports.length) {
throw new Error('You should provide at least one transport for the gateway!')
}
const neighborsTransportsMap = new Map<Neighbor, Transport>()
NEIGHBOR_LOOP: for (const neighbor of neighbors) {
for (const transport of transports) {
if (transport.supports(neighbor)) {
neighborsTransportsMap.set(neighbor, transport)
continue NEIGHBOR_LOOP
}
}
throw new Error(`Couldn't find a transport for the neighbor '${neighbor.address}'!`)
}
this._transports = transports
this._neighbors = neighbors
this._neighborsTransportsMap = neighborsTransportsMap
}
async send(transaction: Transaction, params: { neighbor: string, requestHash: Hash }): Promise<void> {
get isRunning(): boolean {
return this._isRunning
}
getNeighbor(neighborAddress: string): Neighbor|null {
for (const neighbor of this._neighbors) {
if (neighbor.match(neighborAddress)) {
return neighbor
}
}
return null
}
async addNeighbor(neighbor: Neighbor): Promise<void> {
if (this._neighborsTransportsMap.has(neighbor)) {
throw new Error(`Couldn't add a neighbor: the neighbor '${neighbor.address}' already exists!`)
}
for (const transport of this._transports) {
if (transport.supports(neighbor)) {
if (this._isRunning) {
await transport.addNeighbor(neighbor)
}
this._neighborsTransportsMap.set(neighbor, transport)
this._neighbors.push(neighbor)
return
}
}
throw new Error(`Couldn't find a transport for the neighbor '${neighbor.address}'!`)
}
async removeNeighbor(neighbor: Neighbor): Promise<void> {
if (!this._neighborsTransportsMap.has(neighbor)) {
throw new Error(`Couldn't remove a neighbor: the neighbor '${neighbor.address}' doesn't exists!`)
}
if (this._isRunning) {
await this._neighborsTransportsMap.get(neighbor).removeNeighbor(neighbor)
}
this._neighborsTransportsMap.delete(neighbor)
this._neighbors.splice(this._neighbors.indexOf(neighbor), 1)
}
async run(): Promise<void> {

@@ -27,12 +108,43 @@ if (this._isRunning) {

try {
await Promise.all(this._transports.map(t => t.run(() => {})))
await Promise.all(this._transports.map(async (transport: Transport) => {
await transport.run()
}))
await Promise.all(this._neighbors.map(async (neighbor: Neighbor) => {
await this._neighborsTransportsMap.get(neighbor).addNeighbor(neighbor)
}))
const onTransportReceive = (data: Data, neighbor: Neighbor) => this.emit('receive', data, neighbor.address)
const onTransportError = (error: any) => this.emit('error', error)
for (const transport of this._transports) {
transport.on('receive', onTransportReceive)
transport.on('error', onTransportError)
}
this._onTransportReceive = onTransportReceive
this._onTransportError = onTransportError
} catch (error) {
await Promise.all(this._transports.map(t => t.stop()))
await Promise.all(this._neighbors.map(async (neighbor: Neighbor) => {
try {
await this._neighborsTransportsMap.get(neighbor).removeNeighbor(neighbor)
} catch (error) {}
}))
await Promise.all(this._transports.map(async (transport: Transport) => {
try {
await transport.shutdown()
} catch (error) {}
}))
throw error
}
this.emit('run')
this._isRunning = true
}
async stop(): Promise<void> {
async shutdown(): Promise<void> {
if (!this._isRunning) {

@@ -42,6 +154,36 @@ throw new Error('The gateway is not running!')

await Promise.all(this._transports.map(t => t.stop()))
await Promise.all(this._neighbors.map((neighbor: Neighbor) => {
return this._neighborsTransportsMap.get(neighbor).removeNeighbor(neighbor)
}))
await Promise.all(this._transports.map((transport: Transport) => {
return transport.shutdown()
}))
for (const transport of this._transports) {
transport.removeListener('receive', this._onTransportReceive)
transport.removeListener('error', this._onTransportError)
}
this._onTransportReceive = null
this._onTransportError = null
this.emit('shutdown')
this._isRunning = false
}
async send(data: Data, neighborAddress: string): Promise<void> {
if (!this._isRunning) {
throw new Error("Can't send a data: the gateway is not running!")
}
const neighbor = this.getNeighbor(neighborAddress)
if (!neighbor) {
throw new Error(`Neighbor is not found for address '${neighborAddress}'!`)
}
await this._neighborsTransportsMap.get(neighbor).send(data, neighbor)
}
}

@@ -1,6 +0,4 @@

export { Gateway } from './gateway'
export { Gateway, Data } from './gateway'
export { Neighbor } from './neighbor'
export { Transport } from './transport'
export { Packer } from './packer'
export { Transport, ReceiveCallback } from './transport'
export { TcpTransport } from './tcp-transport'
export { UdpTransport } from './udp-transport'
import { Transaction, Hash, Factory } from 'iota-tangle'
import { Data } from './gateway'

@@ -11,7 +12,2 @@ export const TRANSCTION_OFFSET = 0

export interface PacketData {
transaction: Transaction
requestHash: Hash
}
export class Packer {

@@ -28,3 +24,3 @@ private _factory: Factory

pack(data: PacketData): Buffer {
pack(data: Data): Buffer {
const buffer = Buffer.alloc(PACKET_SIZE)

@@ -38,3 +34,3 @@

unpack(packet: Buffer): PacketData {
unpack(packet: Buffer): Data {
const transactionBytes = packet.slice(TRANSCTION_OFFSET, TRANSCTION_OFFSET + TRANSACTION_SIZE)

@@ -41,0 +37,0 @@ const hashBytes = packet.slice(REQUEST_HASH_OFFSET, REQUEST_HASH_OFFSET + REQUEST_HASH_SIZE)

import { Transaction, Hash } from 'iota-tangle'
import { EventEmitter } from 'events'
import { parse as parseUrl } from 'url'
import { Data } from './gateway'
import { Neighbor } from './neighbor'
export interface ReceiveCallback {
(transaction: Transaction, params: { neighbor: string, requestHash?: Hash }): void
export abstract class Transport extends EventEmitter {
abstract get isRunning(): boolean
abstract supports(neighbor: Neighbor): boolean
abstract async run(): Promise<void>
abstract async shutdown(): Promise<void>
abstract async addNeighbor(neighbor: Neighbor): Promise<void>
abstract async removeNeighbor(neighbor: Neighbor): Promise<void>
abstract async send(data: Data, neighbor: Neighbor): Promise<void>
}
export abstract class Transport {
abstract async send(transaction: Transaction, { neighbor: string, requestHash: Hash }): Promise<void>
abstract async run(cb: ReceiveCallback): Promise<void>
abstract async stop(): Promise<void>
}
import { expect, use }from 'chai'
import { spy, stub } from 'sinon'
import { spy, stub, SinonSpy } from 'sinon'

@@ -7,5 +7,8 @@ use(require('chai-as-promised'))

import { Gateway } from '../src/gateway'
import { Transaction, Hash } from 'iota-tangle'
import { Gateway, Data } from '../src/gateway'
import { Transport } from '../src/transport'
import { TransportStub } from './utils'
import { Neighbor } from '../src/neighbor'
import { TransportStub, NeighborStub, generateHash, generateTransaction } from './utils'
import { setTimeout } from 'timers';

@@ -15,16 +18,16 @@ describe("Gateway", () => {

let transports: Transport[]
let neighbors: Neighbor[]
beforeEach(() => {
neighbors = [
new NeighborStub({ address: 'address1' }),
new NeighborStub({ address: 'address2' }),
]
beforeEach(() => {
transports = [
new TransportStub(),
new TransportStub(),
new TransportStub({ supports: (n) => n === neighbors[0] }),
new TransportStub({ supports: (n) => n === neighbors[1] || n.address.startsWith('1234') }),
]
for (const transport of transports) {
transport.run = spy()
transport.stop = spy()
}
gateway = new Gateway({ transports })
gateway = new Gateway({ neighbors, transports })
})

@@ -34,4 +37,21 @@

describe("run()", () => {
it("should call run() method of all gateway's transports", async () => {
for (let transport of transports) {
let runEventCallback: SinonSpy
let receiveEventCallback: SinonSpy
let errorEventCallback: SinonSpy
beforeEach(() => {
for (const transport of transports) {
spy(transport, 'run')
spy(transport, 'addNeighbor')
spy(transport, 'removeNeighbor')
spy(transport, 'shutdown')
}
gateway.on('run', runEventCallback = spy())
gateway.on('receive', receiveEventCallback = spy())
gateway.on('error', errorEventCallback = spy())
})
it("should launch all transports", async () => {
for (const transport of transports) {
expect(transport.run).to.not.have.been.called

@@ -43,6 +63,68 @@ }

for (let transport of transports) {
expect(transport.run).to.have.been.called
expect(transport.run).to.have.been.calledWith()
}
})
it("should make isRunning flag return true", async () => {
expect(gateway.isRunning).to.be.false
await expect(gateway.run()).to.be.fulfilled
expect(gateway.isRunning).to.be.true
})
it("should add neighbors to transports", async () => {
for (const transport of transports) {
expect(transport.addNeighbor).to.not.have.been.called
}
await expect(gateway.run()).to.be.fulfilled
expect(transports[0].addNeighbor).to.have.been.calledWith(neighbors[0])
expect(transports[1].addNeighbor).to.have.been.calledWith(neighbors[1])
expect(transports[0].addNeighbor).to.not.have.been.calledWith(neighbors[1])
expect(transports[1].addNeighbor).to.not.have.been.calledWith(neighbors[0])
})
it("should emit 'run' event", async () => {
expect(runEventCallback).to.not.have.been.called
await expect(gateway.run()).to.be.fulfilled
expect(runEventCallback).to.have.been.called
})
it("should start receiving data from transports", async () => {
await expect(gateway.run()).to.be.fulfilled
expect(receiveEventCallback).to.not.have.been.called
const data = { transaction: generateTransaction(), requestHash: generateHash() }
const neighbor = neighbors[0]
transports[0].emit('receive', data, neighbor)
expect(receiveEventCallback).to.have.been.called
const [emittedData, emittedNeighborAddress] = receiveEventCallback.args[0]
expect(emittedData).to.equal(data)
expect(emittedNeighborAddress).to.equal(neighbor.address)
})
it("should start receiving errors from transports", async () => {
await expect(gateway.run()).to.be.fulfilled
expect(errorEventCallback).to.not.have.been.called
const error = new Error('Some error')
transports[0].emit('error', error)
expect(errorEventCallback).to.have.been.called
const [emittedError] = errorEventCallback.args[0]
expect(emittedError).to.equal(error)
})
it("should be rejected if some of the transports run() calls was rejected", async () => {

@@ -55,4 +137,4 @@ transports[0].run = stub().resolves()

it("should call stop() methods of all gateway's transports " +
"if some of the transports run() calls was rejected", async () => {
it("should shutdown all the gateway's transports " +
"if there were an error while lanching the gatway", async () => {

@@ -63,3 +145,3 @@ transports[0].run = stub().rejects()

for (let transport of transports) {
expect(transport.stop).to.not.have.been.called
expect(transport.removeNeighbor).to.not.have.been.called
}

@@ -70,6 +152,25 @@

for (let transport of transports) {
expect(transport.stop).to.have.been.called
expect(transport.shutdown).to.have.been.called
}
})
it("should remove neighbors from all transports " +
"if there were an error while lanching the gatway", async () => {
transports[0].addNeighbor = stub().rejects()
transports[1].addNeighbor = stub().resolves()
for (let transport of transports) {
expect(transport.removeNeighbor).to.not.have.been.called
}
await expect(gateway.run()).to.be.rejected
expect(transports[0].removeNeighbor).to.have.been.calledWith(neighbors[0])
expect(transports[1].removeNeighbor).to.have.been.calledWith(neighbors[1])
expect(transports[0].removeNeighbor).to.not.have.been.calledWith(neighbors[1])
expect(transports[1].removeNeighbor).to.not.have.been.calledWith(neighbors[0])
})
it("should be rejected if server is already started", async () => {

@@ -81,29 +182,274 @@ await expect(gateway.run()).to.not.be.rejected

describe("stop()", () => {
it("should call stop() method of all gateway's transports", async () => {
describe("shutdown()", () => {
let receiveEventCallback: SinonSpy
let errorEventCallback: SinonSpy
let shutdownEventCallback: SinonSpy
beforeEach(async () => {
await gateway.run()
})
beforeEach(() => {
for (const transport of transports) {
spy(transport, 'removeNeighbor')
spy(transport, 'shutdown')
}
gateway.on('receive', receiveEventCallback = spy())
gateway.on('error', errorEventCallback = spy())
gateway.on('shutdown', shutdownEventCallback = spy())
})
it("should shutdown all the gateway's transports", async () => {
for (let transport of transports) {
expect(transport.stop).to.not.have.been.called
expect(transport.shutdown).to.not.have.been.called
}
await expect(gateway.stop()).to.be.fulfilled
await expect(gateway.shutdown()).to.be.fulfilled
for (let transport of transports) {
expect(transport.stop).to.have.been.called
expect(transport.shutdown).to.have.been.called
}
})
it("should be rejected if some of the transports stop() calls was rejected", async () => {
transports[0].stop = stub().resolves()
transports[1].stop = stub().rejects()
it("should make isRunning flag return false", async () => {
expect(gateway.isRunning).to.be.true
await expect(gateway.shutdown()).to.be.fulfilled
expect(gateway.isRunning).to.be.false
})
await expect(gateway.stop()).to.be.rejected
it("should remove neighbors from all transports ", async () => {
for (let transport of transports) {
expect(transport.removeNeighbor).to.not.have.been.called
}
await expect(gateway.shutdown()).to.be.fulfilled
expect(transports[0].removeNeighbor).to.have.been.calledWith(neighbors[0])
expect(transports[1].removeNeighbor).to.have.been.calledWith(neighbors[1])
expect(transports[0].removeNeighbor).to.not.have.been.calledWith(neighbors[1])
expect(transports[1].removeNeighbor).to.not.have.been.calledWith(neighbors[0])
})
it("should stop receiving data from transports", async () => {
await expect(gateway.shutdown()).to.be.fulfilled
expect(receiveEventCallback).to.not.have.been.called
const data = { transaction: generateTransaction(), requestHash: generateHash() }
const neighbor = neighbors[0]
transports[0].emit('receive', data, neighbor)
expect(receiveEventCallback).to.not.have.been.called
})
it("should stop receiving errors from transports", async () => {
await expect(gateway.shutdown()).to.be.fulfilled
expect(errorEventCallback).to.not.have.been.called
const error = new Error('Some error')
transports[0].once('error', () => {})
transports[0].emit('error', error)
expect(errorEventCallback).to.not.have.been.called
})
it("should emit 'shutdown' event", async () => {
expect(shutdownEventCallback).to.not.have.been.called
await expect(gateway.shutdown()).to.be.fulfilled
expect(shutdownEventCallback).to.have.been.called
})
it("should be rejected if some of the transports shutdown() method calls was rejected", async () => {
transports[0].shutdown = stub().resolves()
transports[1].shutdown = stub().rejects()
await expect(gateway.shutdown()).to.be.rejected
})
it("should be rejected if the gateway is not running", async () => {
await expect(gateway.stop()).to.be.rejected
await expect(gateway.shutdown()).to.be.fulfilled
await expect(gateway.shutdown()).to.be.rejected
})
})
describe("send(data, neighbor)", () => {
let data: Data
let receiveEventCallback: SinonSpy
let errorEventCallback: SinonSpy
let shutdownEventCallback: SinonSpy
beforeEach(async () => {
data = { transaction: generateTransaction(), requestHash: generateHash() }
await gateway.run()
})
beforeEach(() => {
for (const transport of transports) {
spy(transport, 'send')
}
})
it("should delegate sending of data to the specified neighbor", async () => {
expect(transports[0].send).to.not.have.been.called
expect(transports[0].send).to.not.have.been.called
await expect(gateway.send(data, neighbors[0].address)).to.have.been.fulfilled
expect(transports[0].send).to.have.been.calledWith(data, neighbors[0])
expect(transports[1].send).to.not.have.been.called
})
it("shoudl be rejected if the gateway is not running'", async () => {
await expect(gateway.shutdown()).to.have.been.fulfilled
await expect(gateway.send(data, neighbors[0].address)).to.have.been.rejected
})
it("should be rejected if a neighbor doesn't exist for specified address", async () => {
await expect(gateway.send(data, '1234.1234.1234.1243')).to.have.been.rejected
for (const transport of transports) {
expect(transport.send).to.not.have.been.called
}
})
})
describe("addNeighbor(neighbor)", () => {
let neighbor: Neighbor
beforeEach(async () => {
neighbor = new NeighborStub({ address: '1234.1234.1234.1234' })
await gateway.run()
for (const transport of transports) {
spy(transport, 'addNeighbor')
}
})
it("should add neighbor to the gateway", async () => {
expect(gateway.getNeighbor(neighbor.address)).to.be.null
await expect(gateway.addNeighbor(neighbor)).to.be.fulfilled
expect(gateway.getNeighbor(neighbor.address)).to.equal(neighbor)
})
it("should add specified neighbor to the transport if the gateway is running", async () => {
expect(transports[0].addNeighbor).to.not.have.been.called
expect(transports[1].addNeighbor).to.not.have.been.called
await expect(gateway.addNeighbor(neighbor)).to.be.fulfilled
expect(transports[0].addNeighbor).to.not.have.been.called
expect(transports[1].addNeighbor).to.have.been.calledWith(neighbor)
})
it("should not add specified neighbor to the transport if the gateway is not running", async () => {
await expect(gateway.shutdown()).to.be.fulfilled
expect(transports[0].addNeighbor).to.not.have.been.called
expect(transports[1].addNeighbor).to.not.have.been.called
await expect(gateway.addNeighbor(neighbor)).to.be.fulfilled
expect(transports[0].addNeighbor).to.not.have.been.called
expect(transports[1].addNeighbor).to.not.have.been.called
})
it("should be rejected if there were an error while adding neighbor to the transport ", async () => {
transports[1].addNeighbor = stub().rejects()
expect(transports[0].addNeighbor).to.not.have.been.called
expect(transports[1].addNeighbor).to.not.have.been.called
await expect(gateway.addNeighbor(neighbor)).to.be.rejected
expect(transports[0].addNeighbor).to.not.have.been.called
expect(transports[1].addNeighbor).to.have.been.calledWith(neighbor)
})
it("should be rejected if there is no transport that supports specified neighbor", async () => {
await expect(gateway.addNeighbor(new NeighborStub({ address: '4321.12.12.12' }))).to.be.rejected
})
it("should be rejected if there specified neighbor has been already added to the gateway", async () => {
await expect(gateway.addNeighbor(neighbor)).to.be.fulfilled
await expect(gateway.addNeighbor(neighbor)).to.be.rejected
})
})
describe("removeNeighbor(neighbor)", () => {
let neighbor: Neighbor
beforeEach(async () => {
neighbor = new NeighborStub({ address: '1234.1234.1234.1234' })
await gateway.addNeighbor(neighbor)
for (const transport of transports) {
spy(transport, 'removeNeighbor')
}
})
it("should remove the neighbor from the gateway", async () => {
expect(gateway.getNeighbor(neighbor.address)).to.equal(neighbor)
await expect(gateway.removeNeighbor(neighbor)).to.be.fulfilled
expect(gateway.getNeighbor(neighbor.address)).to.be.null
})
it("should be rejected if specified neighbor doesn't exist", async () => {
await expect(gateway.removeNeighbor(new NeighborStub({ address: '1234.555.55.55' }))).to.be.rejected
})
it("should remove the neighbor from the transport if the gateway is running", async () => {
await expect(gateway.run()).to.be.fulfilled
expect(transports[0].removeNeighbor).to.not.have.been.called
expect(transports[1].removeNeighbor).to.not.have.been.called
await expect(gateway.removeNeighbor(neighbor)).to.be.fulfilled
expect(transports[0].removeNeighbor).to.not.have.been.called
expect(transports[1].removeNeighbor).to.have.been.calledWith(neighbor)
})
it("should be rejected if there were an error while removing the neighbor from the transport", async () => {
transports[1].removeNeighbor = stub().rejects()
await expect(gateway.run()).to.be.fulfilled
expect(transports[0].removeNeighbor).to.not.have.been.called
expect(transports[1].removeNeighbor).to.not.have.been.called
await expect(gateway.removeNeighbor(neighbor)).to.be.rejected
expect(transports[0].removeNeighbor).to.not.have.been.called
expect(transports[1].removeNeighbor).to.have.been.calledWith(neighbor)
})
it("should not remove the neighbor from the transport if the gateway is not running", async () => {
expect(transports[0].removeNeighbor).to.not.have.been.called
expect(transports[1].removeNeighbor).to.not.have.been.called
await expect(gateway.removeNeighbor(neighbor)).to.be.fulfilled
expect(transports[0].removeNeighbor).to.not.have.been.called
expect(transports[1].removeNeighbor).to.not.have.been.called
})
})
})

@@ -14,2 +14,3 @@ import { expect } from 'chai'

beforeEach(() => {

@@ -24,2 +25,3 @@ serializer = new Serializer()

describe('pack(packetData)', () => {

@@ -40,2 +42,3 @@ it('should pack the specified transaction and transaction hash into a packet of bytes', () => {

describe('unpack(packet)', () => {

@@ -42,0 +45,0 @@ it('should unpack the specified packet', () => {

import { Transaction, Hash, Factory, Serializer } from 'iota-tangle'
import { Transport, ReceiveCallback } from '../src/transport'
import { Data } from '../src/gateway'
import { Transport } from '../src/transport'
import { Neighbor } from '../src/neighbor'

@@ -7,6 +9,2 @@ const serializer = new Serializer()

export class TransportStub extends Transport {
async run(cb: ReceiveCallback): Promise<void> {}
async stop(): Promise<void> {}
}

@@ -21,2 +19,3 @@ export function generateTransaction(): Transaction {

export function generateHash(): Hash {

@@ -30,44 +29,46 @@ const buffer = Buffer.alloc(49)

// export function generateTransaction(params: any = {}) {
// if (params.message && params.message.length < 2187) {
// params.message = params.message.padEnd(2187, '9')
// }
// return Object.assign({}, {
// hash: 'IBQHNXPILYG9K9PFBZYZDTVHHQNEBENUKRAVMO9DJEGQ9VDIUAWU9FORBFZDSDBWOLWNFGCYVLEG99999',
// address: 'CQNSCEPCDQNMWFYIVRZDSYKPFQLKPOSIXFZCKGTGDROGMDXMYHOR9JRUDZLXHOALXEAZWWLEXRJBLCWVC',
// branch: 'EMEKOFNNGJDAZJWPWIZHIYQQCFWLBNNVCAEEJ9RDML9SHXUTDOKKBMRGHZWJIGYHUEKSZMMTAIWS99999',
// trunk: 'YFEPOAXZKPAXQHMPIFGTNMTVFY9OHIBOIUVQVZYVNMEERVQCPU9UPJOGVM9D9X9YFLLFCSFVOXLK99999',
// bundle: 'QLXDGLLXQIHPXYEKBPFHOSDFIXQRJCZVYVC9TOKBLRWYH9TWXCNGKI9N9RDBHLUBZGGFVWGIZU9Y9VDQW',
// message: (
// 'MINEIOTADOTCOM9MANUAL9PAYOUT999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '9999999999999999999999999999999999999999999999999999999999999999999999999999999' +
// '999999999999999999999999999999999999999999999999999999'
// )
// }, params)
// }
export class NeighborStub extends Neighbor {
private _address: string
constructor(params: { address: string }) {
super()
this._address = params.address
}
get address(): string {
return this._address
}
}
export class TransportStub extends Transport {
private _isRunning = false
private _supports: Function
get isRunning() {
return this._isRunning
}
constructor(params: { supports: Function }) {
super()
this._supports = params.supports
}
supports(neighbor: Neighbor): boolean {
return this._supports(neighbor)
}
async addNeighbor(neighbor: Neighbor): Promise<void> {}
async removeNeighbor(neighbor: Neighbor): Promise<void> {}
async send(data: Data, neighbor: Neighbor): Promise<void> {}
async run(): Promise<void> {
this._isRunning = true
}
async shutdown(): Promise<void> {
this._isRunning = false
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc