+ describe('Clipping', function () {
+ var client;
+ beforeEach(function () {
+ client = make_rfb();
+ container.style.width = '70px';
+ container.style.height = '80px';
+ client.clipViewport = true;
+ });
+
+ it('should update display clip state when changing the property', function () {
+ var spy = sinon.spy(client._display, "clipViewport", ["set"]);
+
+ client.clipViewport = false;
+ expect(spy.set).to.have.been.calledOnce;
+ expect(spy.set).to.have.been.calledWith(false);
+ spy.set.reset();
+
+ client.clipViewport = true;
+ expect(spy.set).to.have.been.calledOnce;
+ expect(spy.set).to.have.been.calledWith(true);
+ });
+
+ it('should update the viewport when the container size changes', function () {
+ sinon.spy(client._display, "viewportChangeSize");
+
+ container.style.width = '40px';
+ container.style.height = '50px';
+ var event = new UIEvent('resize');
+ window.dispatchEvent(event);
+ clock.tick();
+
+ expect(client._display.viewportChangeSize).to.have.been.calledOnce;
+ expect(client._display.viewportChangeSize).to.have.been.calledWith(40, 50);
+ });
+
+ it('should update the viewport when the remote session resizes', function () {
+ // Simple ExtendedDesktopSize FBU message
+ var incoming = [ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xfe, 0xcc,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
+ 0x00, 0x00, 0x00, 0x00 ];
+
+ sinon.spy(client._display, "viewportChangeSize");
+
+ client._sock._websocket._receive_data(new Uint8Array(incoming));
+
+ // FIXME: Display implicitly calls viewportChangeSize() when
+ // resizing the framebuffer, hence calledTwice.
+ expect(client._display.viewportChangeSize).to.have.been.calledTwice;
+ expect(client._display.viewportChangeSize).to.have.been.calledWith(70, 80);
+ });
+
+ it('should not update the viewport if not clipping', function () {
+ client.clipViewport = false;
+ sinon.spy(client._display, "viewportChangeSize");
+
+ container.style.width = '40px';
+ container.style.height = '50px';
+ var event = new UIEvent('resize');
+ window.dispatchEvent(event);
+ clock.tick();
+
+ expect(client._display.viewportChangeSize).to.not.have.been.called;
+ });
+
+ it('should not update the viewport if scaling', function () {
+ client.scaleViewport = true;
+ sinon.spy(client._display, "viewportChangeSize");
+
+ container.style.width = '40px';
+ container.style.height = '50px';
+ var event = new UIEvent('resize');
+ window.dispatchEvent(event);
+ clock.tick();
+
+ expect(client._display.viewportChangeSize).to.not.have.been.called;
+ });
+
+ describe('Dragging', function () {
+ beforeEach(function () {
+ client.dragViewport = true;
+ sinon.spy(RFB.messages, "pointerEvent");
+ });
+
+ afterEach(function () {
+ RFB.messages.pointerEvent.restore();
+ });
+
+ it('should not send button messages when initiating viewport dragging', function () {
+ client._handleMouseButton(13, 9, 0x001);
+ expect(RFB.messages.pointerEvent).to.not.have.been.called;
+ });
+
+ it('should send button messages when release without movement', function () {
+ // Just up and down
+ client._handleMouseButton(13, 9, 0x001);
+ client._handleMouseButton(13, 9, 0x000);
+ expect(RFB.messages.pointerEvent).to.have.been.calledTwice;
+
+ RFB.messages.pointerEvent.reset();
+
+ // Small movement
+ client._handleMouseButton(13, 9, 0x001);
+ client._handleMouseMove(15, 14);
+ client._handleMouseButton(15, 14, 0x000);
+ expect(RFB.messages.pointerEvent).to.have.been.calledTwice;
+ });
+
+ it('should send button message directly when drag is disabled', function () {
+ client.dragViewport = false;
+ client._handleMouseButton(13, 9, 0x001);
+ expect(RFB.messages.pointerEvent).to.have.been.calledOnce;
+ });
+
+ it('should be initiate viewport dragging on sufficient movement', function () {
+ sinon.spy(client._display, "viewportChangePos");
+
+ // Too small movement
+
+ client._handleMouseButton(13, 9, 0x001);
+ client._handleMouseMove(18, 9);
+
+ expect(RFB.messages.pointerEvent).to.not.have.been.called;
+ expect(client._display.viewportChangePos).to.not.have.been.called;
+
+ // Sufficient movement
+
+ client._handleMouseMove(43, 9);
+
+ expect(RFB.messages.pointerEvent).to.not.have.been.called;
+ expect(client._display.viewportChangePos).to.have.been.calledOnce;
+ expect(client._display.viewportChangePos).to.have.been.calledWith(-30, 0);
+
+ client._display.viewportChangePos.reset();
+
+ // Now a small movement should move right away
+
+ client._handleMouseMove(43, 14);
+
+ expect(RFB.messages.pointerEvent).to.not.have.been.called;
+ expect(client._display.viewportChangePos).to.have.been.calledOnce;
+ expect(client._display.viewportChangePos).to.have.been.calledWith(0, -5);
+ });
+
+ it('should not send button messages when dragging ends', function () {
+ // First the movement
+
+ client._handleMouseButton(13, 9, 0x001);
+ client._handleMouseMove(43, 9);
+ client._handleMouseButton(43, 9, 0x000);
+
+ expect(RFB.messages.pointerEvent).to.not.have.been.called;
+ });
+
+ it('should terminate viewport dragging on a button up event', function () {
+ // First the dragging movement
+
+ client._handleMouseButton(13, 9, 0x001);
+ client._handleMouseMove(43, 9);
+ client._handleMouseButton(43, 9, 0x000);
+
+ // Another movement now should not move the viewport
+
+ sinon.spy(client._display, "viewportChangePos");
+
+ client._handleMouseMove(43, 59);
+
+ expect(client._display.viewportChangePos).to.not.have.been.called;
+ });
+ });
+ });
+
+ describe('Scaling', function () {
+ var client;
+ beforeEach(function () {
+ client = make_rfb();
+ container.style.width = '70px';
+ container.style.height = '80px';
+ client.scaleViewport = true;
+ });
+
+ it('should update display scale factor when changing the property', function () {
+ var spy = sinon.spy(client._display, "scale", ["set"]);
+ sinon.spy(client._display, "autoscale");
+
+ client.scaleViewport = false;
+ expect(spy.set).to.have.been.calledOnce;
+ expect(spy.set).to.have.been.calledWith(1.0);
+ expect(client._display.autoscale).to.not.have.been.called;
+
+ client.scaleViewport = true;
+ expect(client._display.autoscale).to.have.been.calledOnce;
+ expect(client._display.autoscale).to.have.been.calledWith(70, 80);
+ });
+
+ it('should update the clipping setting when changing the property', function () {
+ client.clipViewport = true;
+
+ var spy = sinon.spy(client._display, "clipViewport", ["set"]);
+
+ client.scaleViewport = false;
+ expect(spy.set).to.have.been.calledOnce;
+ expect(spy.set).to.have.been.calledWith(true);
+
+ spy.set.reset();
+
+ client.scaleViewport = true;
+ expect(spy.set).to.have.been.calledOnce;
+ expect(spy.set).to.have.been.calledWith(false);
+ });
+
+ it('should update the scaling when the container size changes', function () {
+ sinon.spy(client._display, "autoscale");
+
+ container.style.width = '40px';
+ container.style.height = '50px';
+ var event = new UIEvent('resize');
+ window.dispatchEvent(event);
+ clock.tick();
+
+ expect(client._display.autoscale).to.have.been.calledOnce;
+ expect(client._display.autoscale).to.have.been.calledWith(40, 50);
+ });
+
+ it('should update the scaling when the remote session resizes', function () {
+ // Simple ExtendedDesktopSize FBU message
+ var incoming = [ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xfe, 0xcc,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
+ 0x00, 0x00, 0x00, 0x00 ];
+
+ sinon.spy(client._display, "autoscale");
+
+ client._sock._websocket._receive_data(new Uint8Array(incoming));
+
+ expect(client._display.autoscale).to.have.been.calledOnce;
+ expect(client._display.autoscale).to.have.been.calledWith(70, 80);
+ });
+
+ it('should not update the display scale factor if not scaling', function () {
+ client.scaleViewport = false;
+
+ sinon.spy(client._display, "autoscale");
+
+ container.style.width = '40px';
+ container.style.height = '50px';
+ var event = new UIEvent('resize');
+ window.dispatchEvent(event);
+ clock.tick();
+
+ expect(client._display.autoscale).to.not.have.been.called;
+ });
+ });
+
+ describe('Remote resize', function () {
+ var client;
+ beforeEach(function () {
+ client = make_rfb();
+ client._supportsSetDesktopSize = true;
+ client.resizeSession = true;
+ container.style.width = '70px';
+ container.style.height = '80px';
+ sinon.spy(RFB.messages, "setDesktopSize");
+ });
+
+ afterEach(function () {
+ RFB.messages.setDesktopSize.restore();
+ });
+
+ it('should only request a resize when turned on', function () {
+ client.resizeSession = false;
+ expect(RFB.messages.setDesktopSize).to.not.have.been.called;
+ client.resizeSession = true;
+ expect(RFB.messages.setDesktopSize).to.have.been.calledOnce;
+ });
+
+ it('should request a resize when initially connecting', function () {
+ // Simple ExtendedDesktopSize FBU message
+ var incoming = [ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x00, 0x04, 0xff, 0xff, 0xfe, 0xcc,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00 ];
+
+ // First message should trigger a resize
+
+ client._supportsSetDesktopSize = false;
+
+ client._sock._websocket._receive_data(new Uint8Array(incoming));
+
+ expect(RFB.messages.setDesktopSize).to.have.been.calledOnce;
+ expect(RFB.messages.setDesktopSize).to.have.been.calledWith(sinon.match.object, 70, 80, 0, 0);
+
+ RFB.messages.setDesktopSize.reset();
+
+ // Second message should not trigger a resize
+
+ client._sock._websocket._receive_data(new Uint8Array(incoming));
+
+ expect(RFB.messages.setDesktopSize).to.not.have.been.called;
+ });
+
+ it('should request a resize when the container resizes', function () {
+ container.style.width = '40px';
+ container.style.height = '50px';
+ var event = new UIEvent('resize');
+ window.dispatchEvent(event);
+ clock.tick(1000);
+
+ expect(RFB.messages.setDesktopSize).to.have.been.calledOnce;
+ expect(RFB.messages.setDesktopSize).to.have.been.calledWith(sinon.match.object, 40, 50, 0, 0);
+ });
+
+ it('should not resize until the container size is stable', function () {
+ container.style.width = '20px';
+ container.style.height = '30px';
+ var event = new UIEvent('resize');
+ window.dispatchEvent(event);
+ clock.tick(400);
+
+ expect(RFB.messages.setDesktopSize).to.not.have.been.called;
+
+ container.style.width = '40px';
+ container.style.height = '50px';
+ var event = new UIEvent('resize');
+ window.dispatchEvent(event);
+ clock.tick(400);
+
+ expect(RFB.messages.setDesktopSize).to.not.have.been.called;
+
+ clock.tick(200);
+
+ expect(RFB.messages.setDesktopSize).to.have.been.calledOnce;
+ expect(RFB.messages.setDesktopSize).to.have.been.calledWith(sinon.match.object, 40, 50, 0, 0);
+ });
+
+ it('should not resize when resize is disabled', function () {
+ client._resizeSession = false;
+
+ container.style.width = '40px';
+ container.style.height = '50px';
+ var event = new UIEvent('resize');
+ window.dispatchEvent(event);
+ clock.tick(1000);
+
+ expect(RFB.messages.setDesktopSize).to.not.have.been.called;
+ });
+
+ it('should not resize when resize is not supported', function () {
+ client._supportsSetDesktopSize = false;
+
+ container.style.width = '40px';
+ container.style.height = '50px';
+ var event = new UIEvent('resize');
+ window.dispatchEvent(event);
+ clock.tick(1000);
+
+ expect(RFB.messages.setDesktopSize).to.not.have.been.called;
+ });
+
+ it('should not resize when in view only mode', function () {
+ client._viewOnly = true;
+
+ container.style.width = '40px';
+ container.style.height = '50px';
+ var event = new UIEvent('resize');
+ window.dispatchEvent(event);
+ clock.tick(1000);
+
+ expect(RFB.messages.setDesktopSize).to.not.have.been.called;
+ });
+
+ it('should not try to override a server resize', function () {
+ // Simple ExtendedDesktopSize FBU message
+ var incoming = [ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x00, 0x04, 0xff, 0xff, 0xfe, 0xcc,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00 ];
+
+ client._sock._websocket._receive_data(new Uint8Array(incoming));
+
+ expect(RFB.messages.setDesktopSize).to.not.have.been.called;
+ });
+ });
+