32 Commits
c8afd9959a
...
57d7a69309
Author | SHA1 | Message | Date |
---|---|---|---|
Sheogorath |
57d7a69309
|
Merge release 0.2.0 from develop
|
5 years ago |
Sheogorath |
ca9c0e53ea
|
Release version 0.2.0
|
5 years ago |
Jenkins | 86846431d6 |
Merge commit 'a80271ec20af85a403d9f3b8e04ada00d1fbc019' into HEAD
|
5 years ago |
Sheogorath |
a80271ec20
|
Improve install instructions
|
5 years ago |
Jenkins | 79f32062c1 |
Merge commit 'b0d5e41bd9f3675ef8442c0d0e99f92639110d74' into HEAD
|
5 years ago |
Sheogorath |
b0d5e41bd9
|
Add ability to send messages to channel
|
5 years ago |
Jenkins | c2a0b891e4 |
Merge commit '353ca60a003f7545adc2e957e944304726d94a47' into HEAD
|
5 years ago |
Sheogorath |
353ca60a00
|
Fix NICK command behaviour to RFC
according to the RFC the correct response to the NICK command then it's changing a nickname is to send a NICK command to the user from the original nickname. This patch changes the behaviour and removes a duplicate declearation of the function. |
5 years ago |
Jenkins | 754ab056f6 |
Merge commit '46efd787345dbbb814eaef6d11ba60e23ff42f99' into HEAD
|
5 years ago |
Sheogorath |
46efd78734
|
Fix nickname error responses to match RFC
|
5 years ago |
Sheogorath |
0251dda8ad
|
Add sendMsg function to channel class
This function implements sending messages to all users in a channel while sending the channel name as target to the user's socket. |
5 years ago |
Jenkins | 54ae018c1e |
Merge commit 'fd860b54eea4adade9eb1d46b66c507134151d34' into HEAD
|
5 years ago |
Sheogorath |
fd860b54ee
|
Implement channel parting on the channel object
This patch allows the channel to part users from it. This provides the basics for the future implementation of the PART command. |
5 years ago |
Sheogorath |
e879f3814e
|
Add real unit tests for channel
Before we tested channel implicitly by running it through the tests on the server.js. After some learning today, it's time to add an own set of unit tests to channel. |
5 years ago |
Jenkins | 1346da5a1b |
Merge commit 'ba6a424bfe2e20fa2200ed94087e28e85aa0b955' into HEAD
|
5 years ago |
Sheogorath |
ba6a424bfe
|
Implement non-direct messages to users
In order to send channel messages, we need to set a different target than the user himself. This patch adds a new parameter `to` to the `sendMsg()` function of the user object and allows to provide a string as target. This uses by default the user's nickname as target, which makes the parameter optional and doesn't break the existing interface. |
5 years ago |
Jenkins | e68a23ecc3 |
Merge commit 'b55e1cc810d08a7294642615b4b9a6be4152f47b' into HEAD
|
5 years ago |
Sheogorath |
b55e1cc810
|
Add basic unit test file for users
After learning today that testing the leaves is more important, some fixing for the unit test coverage towards users. Time to do better. |
5 years ago |
Sheogorath |
b7bc3f3d4c
|
Remove external grab into the object
This change removes server object interacting with an internal variable from the user object creation and reduces the amount of code from 3 to 1 line. This also simplifies future testing. |
5 years ago |
Sheogorath |
4ac6e94b60
|
Remove unused setPassword function
|
5 years ago |
Jenkins | 4d08dfe4e3 |
Merge commit 'a9c6b0d1dc13ea24d58c938de710c52423265dbc' into HEAD
|
5 years ago |
Sheogorath |
a9c6b0d1dc
|
Rework user.sendMsg() to use user.sendRaw()
|
5 years ago |
Jenkins | 27ba643205 |
Merge commit '394384689b7d8467c5b4a96cd187499bebb33d3e' into HEAD
|
5 years ago |
Sheogorath |
394384689b
|
Add ability to join channel with multiple users
Joining channels allone is nice, but defeats the purpose of channels. This patch adds the ability to join a channel with multiple users. |
5 years ago |
Sheogorath |
233a9aef72
|
Add concept of channels and allow users to create them
|
5 years ago |
Jenkins | a13bb4368d |
Merge commit 'd61f97d0348e08a5123ae8826c5d5a530f17a4a2' into HEAD
|
5 years ago |
wayne | d61f97d034 |
added: do not expect a error message for successful QUIT commands
|
5 years ago |
Jenkins | 5c9fabc9ae |
Merge commit 'f816cd1adad6c29df25c97b754bed59c30862206' into HEAD
|
5 years ago |
wayne | f816cd1ada |
added test case to not send to unregistered users
|
5 years ago |
Jenkins | d189abba50 |
Merge commit '6ffedcd74e47cd0c71119200cb5078a41b2e2ef5' into HEAD
|
5 years ago |
Sheogorath |
6ffedcd74e
|
Add test for wrong password
|
5 years ago |
Sheogorath |
0768520839
|
Fix password comand behavior to match real protocol
|
5 years ago |
12 changed files with 492 additions and 98 deletions
-
19README.md
-
2package.json
-
32src/channel.js
-
49src/server.js
-
29src/user.js
-
58test/channel.js
-
72test/command_join.js
-
4test/command_nick.js
-
39test/command_pass.js
-
71test/command_privmsg.js
-
1test/command_quit.js
-
84test/user.js
@ -0,0 +1,32 @@ |
|||
function Channel(name) { |
|||
this.name = name |
|||
this.userlist = [] |
|||
|
|||
this.join = function(user) { |
|||
let channel = this |
|||
this.userlist.push(user) |
|||
this.userlist.forEach(function(item) { |
|||
item.sendRaw(`:${user.nickname} JOIN ${channel.name}`) |
|||
}) |
|||
} |
|||
|
|||
this.part = function(user) { |
|||
let channel = this |
|||
let userIndex = this.userlist.indexOf(user) |
|||
if (userIndex >= 0) { |
|||
this.userlist.forEach(function(item) { |
|||
item.sendRaw(`:${user.nickname} PART ${channel.name}`) |
|||
}) |
|||
this.userlist.splice(index, 1) |
|||
} |
|||
} |
|||
|
|||
this.sendMsg = function(from, message) { |
|||
const channel = this |
|||
this.userlist.forEach(function(item) { |
|||
item.sendMsg(from, message, channel.name) |
|||
}) |
|||
} |
|||
} |
|||
|
|||
module.exports = Channel |
@ -0,0 +1,58 @@ |
|||
const assert = require('assert'); |
|||
const Channel = require("../src/channel.js"); |
|||
|
|||
describe('Channel', function () { |
|||
describe('#contructor()', function () { |
|||
it("should create a channel", function () { |
|||
const channel = new Channel("#testchan") |
|||
assert.equal(typeof channel, 'object') |
|||
}) |
|||
}) |
|||
|
|||
describe('#join(user)', function () { |
|||
it("should add the user to a channel and send a JOIN command to the user", function (done) { |
|||
const channel = new Channel("#testchan") |
|||
let mockedUser = {nickname: "some_nick"} |
|||
mockedUser.sendRaw = function(data) { |
|||
assert.equal(data, ":some_nick JOIN #testchan") |
|||
done() |
|||
} |
|||
channel.join(mockedUser) |
|||
}) |
|||
}) |
|||
|
|||
describe('#part(user)', function () { |
|||
it("should remove a user from a channel and send a PART command to the user", function (done) { |
|||
const channel = new Channel("#testchan") |
|||
let mockedUser = {nickname: "some_nick"} |
|||
mockedUser.sendRaw = function(data) { |
|||
// we expect a PART message from our user to the channel (including us)
|
|||
if (data.indexOf("PART") >= 0) { |
|||
assert.equal(data, ":some_nick PART #testchan") |
|||
done() |
|||
} |
|||
} |
|||
// we can't part a channel without joining it first
|
|||
channel.join(mockedUser) |
|||
|
|||
channel.part(mockedUser) |
|||
}) |
|||
}) |
|||
|
|||
describe('#sendMsg(from, message)', function () { |
|||
it("should remove a user from a channel and send a PART command to the user", function (done) { |
|||
const channel = new Channel("#testchan") |
|||
let mockedUser = {nickname: "some_nick", sendRaw: function() {}} |
|||
mockedUser.sendMsg = function(from, message, to) { |
|||
assert.equal(from, mockedUser) |
|||
assert.equal(message, "test message") |
|||
assert.equal(to, "#testchan") |
|||
done() |
|||
} |
|||
// we can't part a channel without joining it first
|
|||
channel.join(mockedUser) |
|||
|
|||
channel.sendMsg(mockedUser, "test message") |
|||
}) |
|||
}) |
|||
}) |
@ -0,0 +1,72 @@ |
|||
const assert = require('assert'); |
|||
const EventEmitter = require('events'); |
|||
const IRCServer = require("../src/server.js"); |
|||
|
|||
describe("JOIN OK", function () { |
|||
it("should handle a JOIN command -> JOIN #testchan", function (done) { |
|||
const server = IRCServer.create() |
|||
let mockedSock = new EventEmitter() |
|||
mockedSock.address = function () { |
|||
return {port: 12346, family: 'IPv4', address: '127.0.0.1'} |
|||
} |
|||
mockedSock.write = function (data) { |
|||
let answer = data.toString("ascii") |
|||
if (answer.indexOf("JOIN") >= 0) { |
|||
assert.equal(answer, ":some_nick JOIN #testchan\r\n") |
|||
done() |
|||
} |
|||
} |
|||
mockedSock.destroy = function () { |
|||
done("Destroyed socket without answering") |
|||
} |
|||
|
|||
server.emit("connection", mockedSock) |
|||
mockedSock.emit('data', Buffer.from("NICK some_nick\r\n", "ascii")) |
|||
mockedSock.emit('data', Buffer.from("USER guest tolmoon tolsun :Ronnie Reagan\r\n", "ascii")) |
|||
mockedSock.emit('data', Buffer.from("JOIN #testchan\r\n", "ascii")) |
|||
}) |
|||
|
|||
it("should handle a JOIN command for more than one user -> JOIN #testchan and send join events to all channel members", function (done) { |
|||
const server = IRCServer.create() |
|||
// helper to count join messages for channel
|
|||
// we should see 2 of them
|
|||
let counter = 0 |
|||
let mockedSock1 = new EventEmitter() |
|||
mockedSock1.address = function () { |
|||
return {port: 12346, family: 'IPv4', address: '127.0.0.1'} |
|||
} |
|||
mockedSock1.write = function (data) { |
|||
let answer = data.toString("ascii") |
|||
if (answer.indexOf("JOIN") >= 0 && counter === 1) { |
|||
assert.equal(answer, ":other_nick JOIN #testchan\r\n") |
|||
done() |
|||
} |
|||
if (answer === ":some_nick JOIN #testchan\r\n") { |
|||
counter++ |
|||
} |
|||
} |
|||
mockedSock1.destroy = function () { |
|||
done("Destroyed socket without answering") |
|||
} |
|||
|
|||
let mockedSock2 = new EventEmitter() |
|||
mockedSock2.address = function () { |
|||
return {port: 12346, family: 'IPv4', address: '127.0.0.1'} |
|||
} |
|||
mockedSock2.write = function (data) { |
|||
return |
|||
} |
|||
mockedSock2.destroy = function () { |
|||
done("Destroyed socket without answering") |
|||
} |
|||
|
|||
server.emit("connection", mockedSock1) |
|||
server.emit("connection", mockedSock2) |
|||
mockedSock1.emit('data', Buffer.from("NICK some_nick\r\n", "ascii")) |
|||
mockedSock1.emit('data', Buffer.from("USER guest tolmoon tolsun :Ronnie Reagan\r\n", "ascii")) |
|||
mockedSock1.emit('data', Buffer.from("JOIN #testchan\r\n", "ascii")) |
|||
mockedSock2.emit('data', Buffer.from("NICK other_nick\r\n", "ascii")) |
|||
mockedSock2.emit('data', Buffer.from("USER guest tolmoon tolsun :Ronnie Reagan\r\n", "ascii")) |
|||
mockedSock2.emit('data', Buffer.from("JOIN #testchan\r\n", "ascii")) |
|||
}) |
|||
}) |
@ -0,0 +1,84 @@ |
|||
const assert = require('assert'); |
|||
const User = require("../src/user.js"); |
|||
|
|||
describe('User', function () { |
|||
describe('#contructor()', function () { |
|||
it("should create a user while no password is required", function () { |
|||
let mockedSock = {} |
|||
const user = new User(mockedSock, true) |
|||
assert.equal(typeof user, 'object') |
|||
}) |
|||
|
|||
it("should create a user while password is required", function () { |
|||
let mockedSock = {} |
|||
const user = new User(mockedSock, false) |
|||
assert.equal(typeof user, 'object') |
|||
}) |
|||
}) |
|||
|
|||
describe('#sendMsg(from, message, to)', function() { |
|||
it("should send a message to the user's socket with the user himself as target", function (done) { |
|||
let mockedSock = {write: function (data) { |
|||
assert.equal(data, ":some_nick PRIVMSG some_nick :test message\r\n") |
|||
done() |
|||
}} |
|||
const user = new User(mockedSock, true) |
|||
user.setNickname("some_nick") |
|||
user.register("some_nick") |
|||
user.sendMsg(user, "test message") |
|||
}) |
|||
|
|||
it("should send a message to the user's socket with a different target", function (done) { |
|||
let mockedSock = {write: function (data) { |
|||
assert.equal(data, ":some_nick PRIVMSG #testchan :test message\r\n") |
|||
done() |
|||
}} |
|||
const user = new User(mockedSock, true) |
|||
user.setNickname("some_nick") |
|||
user.register("some_nick") |
|||
user.sendMsg(user, "test message", "#testchan") |
|||
}) |
|||
}) |
|||
|
|||
describe('#sendRaw(message)', function() { |
|||
it("should send a raw command to the user's socket", function(done) { |
|||
let mockedSock = {write: function (data) { |
|||
assert.equal(data, ":irc.example.com TEST this :command with parameters\r\n") |
|||
done() |
|||
}} |
|||
const user = new User(mockedSock, true) |
|||
user.setNickname("some_nick") |
|||
user.register("some_nick") |
|||
user.sendRaw(":irc.example.com TEST this :command with parameters") |
|||
}) |
|||
}) |
|||
|
|||
describe('#closeConnection()', function() { |
|||
it("should call destroy on user's socket", function(done) { |
|||
let mockedSock = {destroy: function () { |
|||
done() |
|||
}} |
|||
const user = new User(mockedSock, true) |
|||
user.closeConnection() |
|||
}) |
|||
}) |
|||
|
|||
describe('#setNickname(nickname)', function() { |
|||
it('should not answer on inital setting of nickname', function () { |
|||
let mockedSock = {} |
|||
const user = new User(mockedSock, true) |
|||
user.setNickname("some_nick") |
|||
assert.equal(user.getNickname(), "some_nick") |
|||
}) |
|||
|
|||
it('should answer with NICK message from original nick on rename', function (done) { |
|||
let mockedSock = {write: function (data) { |
|||
assert.equal(data, ":some_nick NICK changed_nick\r\n") |
|||
done() |
|||
}} |
|||
const user = new User(mockedSock, true) |
|||
user.setNickname("some_nick") |
|||
user.setNickname("changed_nick") |
|||
}) |
|||
}) |
|||
}) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue