import reducer, { compareUsers, getSortedChannels } from '../channels'; import { connect } from '../networks'; import * as actions from '../actions'; describe('channel reducer', () => { it('removes channels on PART', () => { let state = { srv1: { chan1: {}, chan2: {}, chan3: {} }, srv2: { chan1: {} } }; state = reducer(state, { type: actions.PART, network: 'srv1', channels: ['chan1', 'chan3'] }); expect(state).toEqual({ srv1: { chan2: {} }, srv2: { chan1: {} } }); }); it('handles SOCKET_PART', () => { let state = reducer(undefined, socket_join('srv', 'chan1', 'nick1')); state = reducer(state, socket_join('srv', 'chan1', 'nick2')); state = reducer(state, socket_join('srv', 'chan2', 'nick2')); state = reducer(state, { type: actions.socket.PART, network: 'srv', channel: 'chan1', user: 'nick2' }); expect(state).toEqual({ srv: { chan1: { name: 'chan1', joined: true, users: [{ mode: '', nick: 'nick1', renderName: 'nick1' }] }, chan2: { name: 'chan2', joined: true, users: [{ mode: '', nick: 'nick2', renderName: 'nick2' }] } } }); }); it('handles SOCKET_JOIN', () => { const state = reducer(undefined, socket_join('srv', 'chan1', 'nick1')); expect(state).toEqual({ srv: { chan1: { name: 'chan1', joined: true, users: [{ mode: '', nick: 'nick1', renderName: 'nick1' }] } } }); }); it('handles SOCKET_QUIT', () => { let state = reducer(undefined, socket_join('srv', 'chan1', 'nick1')); state = reducer(state, socket_join('srv', 'chan1', 'nick2')); state = reducer(state, socket_join('srv', 'chan2', 'nick2')); state = reducer(state, { type: actions.socket.QUIT, network: 'srv', user: 'nick2' }); expect(state).toEqual({ srv: { chan1: { name: 'chan1', joined: true, users: [{ mode: '', nick: 'nick1', renderName: 'nick1' }] }, chan2: { name: 'chan2', joined: true, users: [] } } }); }); it('handles KICKED', () => { let state = reducer( undefined, connect({ host: 'srv', nick: 'nick2' }) ); state = reducer(state, socket_join('srv', 'chan1', 'nick1')); state = reducer(state, socket_join('srv', 'chan1', 'nick2')); state = reducer(state, socket_join('srv', 'chan2', 'nick2')); state = reducer(state, { type: actions.KICKED, network: 'srv', channel: 'chan2', user: 'nick2', self: true }); expect(state).toEqual({ srv: { chan1: { name: 'chan1', joined: true, users: [ { mode: '', nick: 'nick1', renderName: 'nick1' }, { mode: '', nick: 'nick2', renderName: 'nick2' } ] }, chan2: { name: 'chan2', joined: false, users: [] } } }); state = reducer(state, { type: actions.KICKED, network: 'srv', channel: 'chan1', user: 'nick1' }); expect(state).toEqual({ srv: { chan1: { name: 'chan1', joined: true, users: [{ mode: '', nick: 'nick2', renderName: 'nick2' }] }, chan2: { name: 'chan2', joined: false, users: [] } } }); }); it('handles SOCKET_NICK', () => { let state = reducer(undefined, socket_join('srv', 'chan1', 'nick1')); state = reducer(state, socket_join('srv', 'chan1', 'nick2')); state = reducer(state, socket_join('srv', 'chan2', 'nick2')); state = reducer(state, { type: actions.socket.NICK, network: 'srv', oldNick: 'nick1', newNick: 'nick3' }); expect(state).toEqual({ srv: { chan1: { name: 'chan1', joined: true, users: [ { mode: '', nick: 'nick3', renderName: 'nick3' }, { mode: '', nick: 'nick2', renderName: 'nick2' } ] }, chan2: { name: 'chan2', joined: true, users: [{ mode: '', nick: 'nick2', renderName: 'nick2' }] } } }); }); it('handles SOCKET_USERS', () => { let state = reducer(undefined, socket_join('srv', 'chan1', 'nick1')); state = reducer(state, { type: actions.socket.USERS, network: 'srv', channel: 'chan1', users: ['user3', 'user2', '@user4', 'user1', '+user5'] }); expect(state).toEqual({ srv: { chan1: { name: 'chan1', joined: true, users: [ { mode: '', nick: 'user3', renderName: 'user3' }, { mode: '', nick: 'user2', renderName: 'user2' }, { mode: 'o', nick: 'user4', renderName: '@user4' }, { mode: '', nick: 'user1', renderName: 'user1' }, { mode: 'v', nick: 'user5', renderName: '+user5' } ] } } }); }); it('handles SOCKET_TOPIC', () => { let state = reducer(undefined, socket_join('srv', 'chan1', 'nick1')); state = reducer(state, { type: actions.socket.TOPIC, network: 'srv', channel: 'chan1', topic: 'the topic' }); expect(state).toMatchObject({ srv: { chan1: { topic: 'the topic' } } }); }); it('handles SOCKET_MODE', () => { let state = reducer(undefined, socket_join('srv', 'chan1', 'nick1')); state = reducer(state, socket_join('srv', 'chan1', 'nick2')); state = reducer(state, socket_join('srv', 'chan2', 'nick2')); state = reducer(state, socket_mode('srv', 'chan1', 'nick1', 'o', '')); expect(state).toMatchObject({ srv: { chan1: { users: [ { mode: 'o', nick: 'nick1', renderName: '@nick1' }, { mode: '', nick: 'nick2', renderName: 'nick2' } ] }, chan2: { users: [{ mode: '', nick: 'nick2', renderName: 'nick2' }] } } }); state = reducer(state, socket_mode('srv', 'chan1', 'nick1', 'v', 'o')); state = reducer(state, socket_mode('srv', 'chan1', 'nick2', 'o', '')); state = reducer(state, socket_mode('srv', 'chan2', 'not_there', 'x', '')); expect(state).toMatchObject({ srv: { chan1: { users: [ { mode: 'v', nick: 'nick1', renderName: '+nick1' }, { mode: 'o', nick: 'nick2', renderName: '@nick2' } ] }, chan2: { users: [{ mode: '', nick: 'nick2', renderName: 'nick2' }] } } }); }); it('handles channels from INIT', () => { const state = reducer(undefined, { type: actions.INIT, channels: [ { network: 'srv', name: 'chan1', topic: 'the topic' }, { network: 'srv', name: 'chan2', joined: true }, { network: 'srv2', name: 'chan1' } ] }); expect(state).toEqual({ srv: { chan1: { name: 'chan1', topic: 'the topic', users: [] }, chan2: { name: 'chan2', joined: true, users: [] } }, srv2: { chan1: { name: 'chan1', users: [] } } }); }); it('handles networks from INIT', () => { const state = reducer(undefined, { type: actions.INIT, networks: [{ host: '127.0.0.1' }, { host: 'thehost' }] }); expect(state).toEqual({ '127.0.0.1': {}, thehost: {} }); }); it('optimistically adds the network on CONNECT', () => { const state = reducer( undefined, connect({ host: '127.0.0.1', nick: 'nick' }) ); expect(state).toEqual({ '127.0.0.1': {} }); }); it('removes the network on DISCONNECT', () => { let state = { srv: {}, srv2: {} }; state = reducer(state, { type: actions.DISCONNECT, network: 'srv2' }); expect(state).toEqual({ srv: {} }); }); }); function socket_join(network, channel, user) { return { type: actions.socket.JOIN, network, user, channels: [channel] }; } function socket_mode(network, channel, user, add, remove) { return { type: actions.socket.MODE, network, channel, user, add, remove }; } describe('compareUsers()', () => { it('compares users correctly', () => { expect( [ { renderName: 'user5' }, { renderName: '@user2' }, { renderName: 'user3' }, { renderName: 'user2' }, { renderName: '+user1' }, { renderName: '~bob' }, { renderName: '%apples' }, { renderName: '&cake' } ].sort(compareUsers) ).toEqual([ { renderName: '~bob' }, { renderName: '&cake' }, { renderName: '@user2' }, { renderName: '%apples' }, { renderName: '+user1' }, { renderName: 'user2' }, { renderName: 'user3' }, { renderName: 'user5' } ]); }); }); describe('getSortedChannels', () => { it('sorts networks and channels', () => { expect( getSortedChannels({ channels: { 'bob.com': {}, '127.0.0.1': { '#chan1': { name: '#chan1', users: [], topic: 'cake' }, '#pie': { name: '#pie' }, '##apples': { name: '##apples' } } } }) ).toEqual([ { address: '127.0.0.1', channels: [ { name: '##apples' }, { name: '#chan1', users: [], topic: 'cake' }, { name: '#pie' } ] }, { address: 'bob.com', channels: [] } ]); }); });