
commit 547cb9690a5dfb0059d07e6d71a198d24189dd96 Author: Serene Han <keroserene+git@gmail.com> Date: Sun Feb 7 08:32:41 2016 -0800 more jasmine specs for proxypair, ui, and snowflake coffee files --- proxy/Cakefile | 2 ++ proxy/broker.coffee | 1 - proxy/proxypair.coffee | 9 +++-- proxy/snowflake.coffee | 32 +++++++---------- proxy/spec/proxypair.spec.coffee | 16 +-------- proxy/spec/snowflake.spec.coffee | 60 ++++++++++++++++++++++++++++++++ proxy/spec/ui.spec.coffee | 75 ++++++++++++++++++++++++++++++++++++++++ proxy/spec/util.spec.coffee | 12 +------ proxy/ui.coffee | 8 ++--- 9 files changed, 159 insertions(+), 56 deletions(-) diff --git a/proxy/Cakefile b/proxy/Cakefile index 97d7978..88d142b 100644 --- a/proxy/Cakefile +++ b/proxy/Cakefile @@ -13,7 +13,9 @@ FILES = [ ] FILES_SPEC = [ 'spec/util.spec.coffee' + 'spec/ui.spec.coffee' 'spec/proxypair.spec.coffee' + 'spec/snowflake.spec.coffee' ] FILES_ALL = FILES.concat FILES_SPEC OUTFILE = 'build/snowflake.coffee' diff --git a/proxy/broker.coffee b/proxy/broker.coffee index 2cc39f7..acd5a5f 100644 --- a/proxy/broker.coffee +++ b/proxy/broker.coffee @@ -24,7 +24,6 @@ class Broker constructor: (@url) -> @clients = 0 @id = genSnowflakeID() - dbg 'Contacting Broker at ' + @url + '\nSnowflake ID: ' + @id # Ensure url has the right protocol + trailing slash. @url = 'https://' + @url if 0 != @url.indexOf('https://', 0) @url += '/' if '/' != @url.substr -1 diff --git a/proxy/proxypair.coffee b/proxy/proxypair.coffee index 83dc353..e7adfb9 100644 --- a/proxy/proxypair.coffee +++ b/proxy/proxypair.coffee @@ -5,7 +5,6 @@ Represents a single: ### - class ProxyPair MAX_BUFFER: 10 * 1024 * 1024 @@ -58,15 +57,15 @@ class ProxyPair channel.onopen = => log 'WebRTC DataChannel opened!' snowflake.state = MODE.WEBRTC_READY - ui.setActive true + snowflake.ui.setActive true # This is the point when the WebRTC datachannel is done, so the next step # is to establish websocket to the server. @connectRelay() channel.onclose = -> log 'WebRTC DataChannel closed.' - ui.setStatus 'disconnected.' + snowflake.ui.setStatus 'disconnected.' + snowflake.ui.setActive false snowflake.state = MODE.INIT - ui.setActive false # Change this for multiplexing. snowflake.reset() channel.onerror = -> log 'Data channel error!' @@ -79,7 +78,7 @@ class ProxyPair @relay.label = 'websocket-relay' @relay.onopen = => log @relay.label + ' connected!' - ui.setStatus 'connected' + snowflake.ui.setStatus 'connected' @relay.onclose = @onClose @relay.onerror = @onError @relay.onmessage = @onRelayToClientMessage diff --git a/proxy/snowflake.coffee b/proxy/snowflake.coffee index e49b375..0df1904 100644 --- a/proxy/snowflake.coffee +++ b/proxy/snowflake.coffee @@ -21,8 +21,6 @@ if 'undefined' != typeof window && window.location COPY_PASTE_ENABLED = Params.getBool(query, 'manual', false) else window = {} -# HEADLESS is true if we are running not in a browser with a DOM. -HEADLESS = 'undefined' == typeof(document) # Bytes per second. Set to undefined to disable limit. DEFAULT_RATE_LIMIT = DEFAULT_RATE_LIMIT || undefined @@ -59,7 +57,7 @@ class Snowflake state: MODE.INIT retries: 0 - constructor: (@broker) -> + constructor: (@broker, @ui) -> rateLimitBytes = undefined if 'off' != query['ratelimit'] rateLimitBytes = Params.getByteCount(query, 'ratelimit', @@ -89,8 +87,8 @@ class Snowflake return if COPY_PASTE_ENABLED timer = null # Temporary countdown. - countdown = (msg, sec) -> - ui.setStatus msg + ' (Retrying in ' + sec + ' seconds...)' + countdown = (msg, sec) => + @ui.setStatus msg + ' (Retrying in ' + sec + ' seconds...)' sec-- if sec >= 0 setTimeout((-> countdown(msg, sec)), 1000) @@ -101,8 +99,8 @@ class Snowflake clearTimeout timer msg = 'polling for client... ' msg += '[retries: ' + @retries + ']' if @retries > 0 - ui.setStatus msg - recv = broker.getClientOffer() + @ui.setStatus msg + recv = @broker.getClientOffer() @retries++ recv.then (desc) => offer = JSON.parse desc @@ -132,14 +130,12 @@ class Snowflake pair.onCleanup = (event) => # Delete from the list of active proxy pairs. @proxyPairs.splice(@proxyPairs.indexOf(pair), 1) - # @badge.endProxy() if @badge try pair.begin() catch err log 'ERROR: ProxyPair exception while connecting.' log err return - # @badge.beginProxy if @badge cease: -> while @proxyPairs.length > 0 @@ -148,12 +144,10 @@ class Snowflake disable: -> log 'Disabling Snowflake.' @cease() - # @badge.disable() if @badge die: -> log 'Snowflake died.' @cease() - # @badge.die() if @badge # Close all existing ProxyPairs and begin finding new clients from scratch. reset: -> @@ -163,8 +157,6 @@ class Snowflake @beginWebRTC() snowflake = null -broker = null -ui = null # Signalling channel - just tells user to copy paste to the peer. # Eventually this should go over the broker. @@ -190,19 +182,19 @@ Signalling = # Log to both console and UI if applicable. log = (msg) -> console.log 'Snowflake: ' + msg - ui.log msg + snowflake.ui.log msg -dbg = (msg) -> log msg if true == ui.debug +dbg = (msg) -> log msg if true == snowflake.ui.debug init = -> ui = new UI() - log '== snowflake proxy ==' - log 'Copy-Paste mode detected.' if COPY_PASTE_ENABLED brokerUrl = Params.getString(query, 'broker', DEFAULT_BROKER) broker = new Broker brokerUrl - snowflake = new Snowflake(broker) - # window.snowflake = snowflake - # window.ui = ui + snowflake = new Snowflake broker, ui + + dbg 'Contacting Broker at ' + broker.url + '\nSnowflake ID: ' + broker.id + log '== snowflake proxy ==' + log 'Copy-Paste mode detected.' if COPY_PASTE_ENABLED relayAddr = Params.getAddress(query, 'relay', DEFAULT_RELAY) snowflake.setRelayAddr relayAddr diff --git a/proxy/spec/proxypair.spec.coffee b/proxy/spec/proxypair.spec.coffee index 261d38d..162c0b4 100644 --- a/proxy/spec/proxypair.spec.coffee +++ b/proxy/spec/proxypair.spec.coffee @@ -1,27 +1,13 @@ ### -jasmine tests for Snowflake +jasmine tests for Snowflake proxypair ### -# Stubs to fake browser functionality. -class PeerConnection -class WebSocket - OPEN: 1 - CLOSED: 0 -ui = - log: -> - setActive: -> -log = -> describe 'ProxyPair', -> fakeRelay = Parse.address '0.0.0.0:12345' rateLimit = new DummyRateLimit() destination = [] fakeClient = send: (d) -> destination.push d - # Fake snowflake to interact with - snowflake = { - broker: - sendAnswer: -> - } pp = new ProxyPair(fakeClient, fakeRelay, rateLimit) it 'begins webrtc connection', -> diff --git a/proxy/spec/snowflake.spec.coffee b/proxy/spec/snowflake.spec.coffee new file mode 100644 index 0000000..be1601b --- /dev/null +++ b/proxy/spec/snowflake.spec.coffee @@ -0,0 +1,60 @@ +### +jasmine tests for Snowflake +### + +query = {} +# Fake browser functionality: +class PeerConnection +class RTCSessionDescription + type: 'offer' +class WebSocket + OPEN: 1 + CLOSED: 0 +log = -> +class FakeUI + log: -> + setActive: -> + setStatus: -> +fakeUI = new FakeUI() +class FakeBroker + getClientOffer: -> new Promise((F,R) -> {}) +# Fake snowflake to interact with +snowflake = + ui: fakeUI + broker: + sendAnswer: -> + +describe 'Snowflake', -> + + it 'constructs correctly', -> + s = new Snowflake({ fake: 'broker' }, fakeUI) + query['ratelimit'] = 'off' + expect(s.rateLimit).not.toBeNull() + expect(s.broker).toEqual { fake: 'broker' } + expect(s.ui).not.toBeNull() + expect(s.retries).toBe 0 + + it 'sets relay address correctly', -> + s = new Snowflake(null, fakeUI) + s.setRelayAddr 'foo' + expect(s.relayAddr).toEqual 'foo' + + it 'initalizes WebRTC connection', -> + s = new Snowflake(new FakeBroker(), fakeUI) + spyOn(s.broker, 'getClientOffer').and.callThrough() + s.beginWebRTC() + expect(s.retries).toBe 1 + expect(s.broker.getClientOffer).toHaveBeenCalled() + + it 'receives SDP offer', -> + s = new Snowflake(new FakeBroker(), fakeUI) + s.proxyPair = { receiveWebRTCOffer: -> } + spyOn(s.proxyPair, 'receiveWebRTCOffer').and.returnValue true + spyOn(s, 'sendAnswer') + s.receiveOffer 'foo' + expect(s.sendAnswer).toHaveBeenCalled() + + it 'can make a proxypair', -> + s = new Snowflake(new FakeBroker(), fakeUI) + s.makeProxyPair() + expect(s.proxyPairs.length).toBe 2 diff --git a/proxy/spec/ui.spec.coffee b/proxy/spec/ui.spec.coffee new file mode 100644 index 0000000..1628d83 --- /dev/null +++ b/proxy/spec/ui.spec.coffee @@ -0,0 +1,75 @@ +### +jasmine tests for Snowflake UI +### + +document = + getElementById: (id) -> + +describe 'UI', -> + + it 'activates debug mode when badge does not exist', -> + spyOn(document, 'getElementById').and.callFake (id) -> + return null if 'badge' == id + return { + focus: -> + } + u = new UI() + expect(u.debug).toBe true + expect(document.getElementById.calls.count()).toEqual 5 + expect(u.$status).not.toBeNull() + expect(u.$msglog).not.toBeNull() + expect(u.$send).not.toBeNull() + expect(u.$input).not.toBeNull() + + it 'is not debug mode when badge exists', -> + spyOn(document, 'getElementById').and.callFake (id) -> + return {} if 'badge' == id + return null + u = new UI() + expect(u.debug).toBe false + expect(document.getElementById).toHaveBeenCalled() + expect(document.getElementById.calls.count()).toEqual 1 + expect(u.$status).toBeNull() + expect(u.$msglog).toBeNull() + expect(u.$send).toBeNull() + expect(u.$input).toBeNull() + + it 'sets status message only when in debug mode', -> + u = new UI() + u.$status = { innerHTML: '' } + u.debug = false + u.setStatus('test') + expect(u.$status.innerHTML).toEqual '' + u.debug = true + u.setStatus('test') + expect(u.$status.innerHTML).toEqual 'Status: test' + + it 'sets message log css correctly for debug mode', -> + u = new UI() + u.debug = true + u.$msglog = {} + u.setActive true + expect(u.$msglog.className).toEqual 'active' + u.setActive false + expect(u.$msglog.className).toEqual '' + + it 'sets badge css correctly for non-debug mode', -> + u = new UI() + u.debug = false + u.$badge = {} + u.setActive true + expect(u.$badge.className).toEqual 'active' + u.setActive false + expect(u.$badge.className).toEqual '' + + it 'logs to the textarea correctly, only when debug mode', -> + u = new UI() + u.$msglog = { value: '', scrollTop: 0, scrollHeight: 1337 } + u.debug = false + u.log 'test' + expect(u.$msglog.value).toEqual '' + expect(u.$msglog.scrollTop).toEqual 0 + u.debug = true + u.log 'test' + expect(u.$msglog.value).toEqual 'test\n' + expect(u.$msglog.scrollTop).toEqual 1337 diff --git a/proxy/spec/util.spec.coffee b/proxy/spec/util.spec.coffee index a4281e9..07b712b 100644 --- a/proxy/spec/util.spec.coffee +++ b/proxy/spec/util.spec.coffee @@ -1,17 +1,7 @@ ### -jasmine tests for Snowflake +jasmine tests for Snowflake utils ### -# Stubs to fake browser functionality. -class PeerConnection -class WebSocket - OPEN: 1 - CLOSED: 0 -ui = - log: -> - setActive: -> -log = -> - describe 'BuildUrl', -> it 'should parse just protocol and host', -> expect(buildUrl('http', 'example.com')).toBe 'http://example.com' diff --git a/proxy/ui.coffee b/proxy/ui.coffee index f951f67..cb25216 100644 --- a/proxy/ui.coffee +++ b/proxy/ui.coffee @@ -6,10 +6,10 @@ class UI debug = false # True when there's no badge # DOM elements references. - $msglog = null - $send = null - $input = null - $status = null + $msglog: null + $send: null + $input: null + $status: null constructor: -> @$badge = document.getElementById('badge')