'use strict';

var expect = require('expect.js')
  , JsonpReceiver = require('../../lib/transport/receiver/jsonp')
  , XhrReceiver = require('../../lib/transport/receiver/xhr')
  , XhrFake = require('../../lib/transport/sender/xhr-fake')
  , utils = require('../../lib/utils/iframe')
  ;

describe('Receivers', function () {
  describe('jsonp', function () {
    var oldTimeout = JsonpReceiver.timeout;
    var oldScriptTimeout = JsonpReceiver.scriptErrorTimeout;
    var scriptFunc = JsonpReceiver.prototype._createScript;
    before(function () {
      JsonpReceiver.prototype._createScript = function () {};
      JsonpReceiver.timeout = 300;
    });
    after(function () {
      JsonpReceiver.timeout = oldTimeout;
      JsonpReceiver.scriptErrorTimeout = oldScriptTimeout;
      JsonpReceiver.prototype._createScript = scriptFunc;
    });

    it('receives data', function (done) {
      JsonpReceiver.prototype._createScript = function () {
        var self = this;
        setTimeout(function () {
          global[utils.WPrefix][self.id]('datadata');
        }, 5);
      };
      var jpr = new JsonpReceiver('test');
      jpr.on('close', function (code, reason) {
        expect(reason).to.equal('network');
        done();
      });
      jpr.on('message', function (msg) {
        expect(msg).to.equal('datadata');
      });
    });

    it('will timeout', function (done) {
      this.timeout(500);
      JsonpReceiver.prototype._createScript = function () {
        var self = this;
        setTimeout(function () {
          global[utils.WPrefix][self.id]('datadata');
        }, 400);
      };

      var jpr = new JsonpReceiver('test');
      jpr.on('close', function (code, reason) {
        expect(reason).to.contain('timeout');
        done();
      });
      jpr.on('message', function () {
        expect().fail('No message should be sent');
      });
    });

    it('aborts without sending a message', function (done) {
      JsonpReceiver.prototype._createScript = function () {
        var self = this;
        setTimeout(function () {
          global[utils.WPrefix][self.id]('datadata');
        }, 200);
      };
      var jpr = new JsonpReceiver('test');
      jpr.on('close', function (code, reason) {
        expect(reason).to.contain('aborted');
        done();
      });
      jpr.on('message', function () {
        expect().fail('No message should be sent');
      });
      jpr.abort();
    });

    it('will not report error if onerror triggered right before onreadystatechange (IE9)', function (done) {
      JsonpReceiver.scriptErrorTimeout = 300;
      JsonpReceiver.prototype._createScript = function () {
        var self = this;
        // simulate a normal JSONP response
        setTimeout(function () {
          self.loadedOkay = true;
          global[utils.WPrefix][self.id]('datadata');
        }, 200);
      };

      var jpr = new JsonpReceiver('test');
      jpr.on('close', function (code, reason) {
        expect(reason).to.equal('network');
        done();
      });
      jpr.on('message', function (msg) {
        expect(msg).to.equal('datadata');
      });

      // simulate script error
      jpr._scriptError();
    });

    it('will not report error if onerror triggered right after onreadystatechange (IE9)', function (done) {
      JsonpReceiver.scriptErrorTimeout = 100;
      JsonpReceiver.prototype._createScript = function () {
        var self = this;
        // simulate a normal JSONP response
        setTimeout(function () {
          self.loadedOkay = true;
          global[utils.WPrefix][self.id]('datadata');
        }, 100);
      };

      var jpr = new JsonpReceiver('test');
      jpr.on('close', function (code, reason) {
        expect(reason).to.equal('network');
        done();
      });
      jpr.on('message', function (msg) {
        expect(msg).to.equal('datadata');
      });

      // simulate script error
      setTimeout(function () {
        jpr._scriptError();
      }, 100);
    });
  });

  describe('xhr', function () {
    var oldTimeout;
    before(function () {
      oldTimeout = XhrFake.timeout;
      XhrFake.timeout = 100;
    });
    after(function () {
      XhrFake.timeout = oldTimeout;
    });

    it('emits multiple messages for multi-line response', function (done) {
      var xhr = new XhrReceiver('test', XhrFake);
      var i = 0, responses = ['test', 'multiple', 'lines', '{}'];
      xhr.on('message', function (msg) {
        expect(msg).to.equal(responses[i]);
        i++;
      });
      xhr.on('close', function (code, reason) {
        expect(reason).to.equal('network');
        done();
      });
      xhr._chunkHandler(200, 'test\nmultiple\nlines');
    });

    it('emits no messages for an empty string response', function (done) {
      var xhr = new XhrReceiver('test', XhrFake);
      var i = 0, responses = ['{}'];
      xhr.on('message', function (msg) {
        expect(i).to.be.lessThan(responses.length);
        expect(msg).to.equal(responses[i]);
        i++;
      });
      xhr.on('close', function (code, reason) {
        expect(reason).to.equal('network');
        done();
      });
      xhr._chunkHandler(200, '');
    });

    it('aborts without sending a message', function (done) {
      var xhr = new XhrReceiver('test', XhrFake);
      xhr.on('message', function () {
        expect().fail();
      });
      xhr.on('close', function (code, reason) {
        expect(reason).to.equal('user');
        done();
      });
      xhr.abort();
    });
  });
});

@@ -1516,32 +1516,82 @@
 t(function () %7B%0A
+          if (global%5Butils.WPrefix%5D%5Bself.id%5D) %7B%0A  
           global
@@ -1620,32 +1620,44 @@
 d%5D('datadata');%0A
+          %7D%0A
         %7D, 400);
@@ -2110,32 +2110,82 @@
 t(function () %7B%0A
+          if (global%5Butils.WPrefix%5D%5Bself.id%5D) %7B%0A  
           global
@@ -2214,32 +2214,44 @@
 d%5D('datadata');%0A
+          %7D%0A
         %7D, 200);
@@ -4081,33 +4081,33 @@
 ror();%0A      %7D, 
-1
+2
 00);%0A    %7D);%0A  %7D

Handle if jsonp callback has been cleanup up