/*global define*/
/*jslint browser:true*/
define([
    'testsuite/qunit',
    'testsuite/qunit-fixture!./orderstatus-test',
    'testsuite/sinon',
    'jquery',
    'de_epages/sageone/ui/orderstatus',
    'ep/ui/input'
], function ( QUnit, fixture, sinon, $, orderstatus ) {

  'use strict';
  var timeout = 500;
  QUnit.module("de_epages/sageone/ui/orderstatus", {
    setup: fixture.init,
    teardown: fixture.destroy
  });
  /**************************************************************************/
  QUnit.asyncTest('test shop disconnected json response', function(assert) {
    var expectedResponseOrderStatus = '{ }';
    var httpCodeOrderStatus = 200;
    var expectedResponseShopStatus = '{ "ShopStatus":"disconnected" }';
    var httpCodeShopStatus = 200;
    prepareTestServer(expectedResponseOrderStatus, httpCodeOrderStatus, expectedResponseShopStatus, httpCodeShopStatus);

    orderstatus(123); // call SUT

    setTimeout(function () {
      assert.ok(!$('#SageOneSyncButton').is(":visible"), 'check if the sync button is not visible');
      assert.ok(!$('#SageOneError').is(":visible"), 'check if the error message box is not visible');
      assert.ok(!$('#SageOneInfo').is(":visible"), 'check if the info message box is not visible');
      QUnit.start();
    }, timeout);
  });
  /**************************************************************************/
  QUnit.asyncTest('test 500 orderstatus notOk', function(assert) {
    var expectedResponseOrderStatus = '{ }';
    var httpCodeOrderStatus = 500;
    var expectedResponseShopStatus = '{ "ShopStatus":"connected" }';
    var httpCodeShopStatus = 200;
    prepareTestServer(expectedResponseOrderStatus, httpCodeOrderStatus, expectedResponseShopStatus, httpCodeShopStatus);

    orderstatus(123); // call SUT

    setTimeout(function () {
      assert.ok($('#SageOneSyncButton').is(":visible"), 'check if the sync button is visible');
      assert.ok(!$('#SageOneError').is(":visible"), 'check if the error message box is not visible');
      assert.ok(!$('#SageOneInfo').is(":visible"), 'check if the info message box is not visible');
      QUnit.start();
    }, timeout);
  });
  /**************************************************************************/
  QUnit.asyncTest('test 500 shopstatus notOk', function(assert) {
    var expectedResponseOrderStatus = '{ }';
    var httpCodeOrderStatus = 200;
    var expectedResponseShopStatus = '{ }';
    var httpCodeShopStatus = 500;
    prepareTestServer(expectedResponseOrderStatus, httpCodeOrderStatus, expectedResponseShopStatus, httpCodeShopStatus);

    orderstatus(123); // call SUT

    setTimeout(function () {
      assert.ok(!$('#SageOneSyncButton').is(":visible"), 'check if the sync button is not visible');
      assert.ok(!$('#SageOneError').is(":visible"), 'check if the error message box is not visible');
      assert.ok(!$('#SageOneInfo').is(":visible"), 'check if the info message box is not visible');
      QUnit.start();
    }, timeout);
  });
/**************************************************************************/
  QUnit.asyncTest('test unknown Status with message', function(assert) {
    var expectedResponseOrderStatus = '{ "Status":"unknown Status", "StatusMessage":"some error message"}';
    var httpCodeOrderStatus = 200;
    var expectedResponseShopStatus = '{ "ShopStatus":"connected" }';
    var httpCodeShopStatus = 200;
    prepareTestServer(expectedResponseOrderStatus, httpCodeOrderStatus, expectedResponseShopStatus, httpCodeShopStatus);

    orderstatus(123); // call SUT

    setTimeout(function () {
      assert.ok( $('#SageOneErrorType').hasClass('sage-one-unknown-error'), 'checks if the correct class was set to "sage-one-unknown-status"' );
      assert.ok( ($('#SageOneErrorType').text().length > 0), 'checks if the text is defined' );

      assert.ok( $('#SageOneErrorMessage').hasClass('sage-one-unknown-error'), 'checks if the correct class was set to "sage-one-unknown-status"' );
      assert.equal( $('#SageOneErrorMessage').text(), 'some error message', 'correct error message for "rejected_ep" case' );

      assert.ok($('#SageOneSyncButton').is(":visible"), 'check if the sync button is visible');
      assert.ok($('#SageOneError').is(":visible"), 'check if the error message box is visible');
      assert.ok(!$('#SageOneInfo').is(":visible"), 'check if the info message box is not visible');
      QUnit.start();
    }, timeout);
  });

  /**************************************************************************/
  QUnit.asyncTest('test unknown Status with undefined message', function(assert) {
    var expectedResponseOrderStatus = '{ "Status":"unknown Status" }';
    var httpCodeOrderStatus = 200;
    var expectedResponseShopStatus = '{ "ShopStatus":"connected" }';
    var httpCodeShopStatus = 200;
    prepareTestServer(expectedResponseOrderStatus, httpCodeOrderStatus, expectedResponseShopStatus, httpCodeShopStatus);

    orderstatus(123); // call SUT

    setTimeout(function () {
      assert.ok( $('#SageOneErrorType').hasClass('sage-one-unknown-error'), 'checks if the correct class was set to "sage-one-unknown-status"' );
      assert.ok( ($('#SageOneErrorType').text().length > 0), 'checks if the text is defined' );

      assert.ok( $('#SageOneErrorMessage').hasClass('sage-one-unknown-error'), 'checks if the correct class was set to "sage-one-unknown-status"' );
      assert.ok( ($('#SageOneErrorMessage').text().length > 0), 'checks if the text is defined' );

      assert.ok($('#SageOneSyncButton').is(":visible"), 'check if the sync button is visible');
      assert.ok($('#SageOneError').is(":visible"), 'check if the error message box is visible');
      assert.ok(!$('#SageOneInfo').is(":visible"), 'check if the info message box is not visible');
      QUnit.start();
    }, timeout);
  });

  /**************************************************************************/
  QUnit.asyncTest('test unknown Status with "null" message', function(assert) {;
    var expectedResponseOrderStatus = '{ "Status":"unknown Status", "StatusMessage":null }';
    var httpCodeOrderStatus = 200;
    var expectedResponseShopStatus = '{ "ShopStatus":"connected" }';
    var httpCodeShopStatus = 200;
    prepareTestServer(expectedResponseOrderStatus, httpCodeOrderStatus, expectedResponseShopStatus, httpCodeShopStatus);

    orderstatus(123); // call SUT

    setTimeout(function () {
      assert.ok( $('#SageOneErrorType').hasClass('sage-one-unknown-error'), 'checks if the correct class was set to "sage-one-unknown-status"' );
      assert.ok( ($('#SageOneErrorType').text().length > 0), 'checks if the text is defined' );

      assert.ok( $('#SageOneErrorMessage').hasClass('sage-one-unknown-error'), 'checks if the correct class was set to "sage-one-unknown-status"' );
      assert.ok( ($('#SageOneErrorMessage').text().length > 0), 'checks if the text is defined' );

      assert.ok($('#SageOneSyncButton').is(":visible"), 'check if the sync button is visible');
      assert.ok($('#SageOneError').is(":visible"), 'check if the error message box is visible');
      assert.ok(!$('#SageOneInfo').is(":visible"), 'check if the info message box is not visible');
      QUnit.start();
    }, timeout);
  });

  /**************************************************************************/
  QUnit.asyncTest('test unknown Status with empty string message', function(assert) {
    var expectedResponseOrderStatus = '{ "Status":"unknown Status", "StatusMessage":"" }';
    var httpCodeOrderStatus = 200;
    var expectedResponseShopStatus = '{ "ShopStatus":"connected" }';
    var httpCodeShopStatus = 200;
    prepareTestServer(expectedResponseOrderStatus, httpCodeOrderStatus, expectedResponseShopStatus, httpCodeShopStatus);

    orderstatus(123); // call SUT

    setTimeout(function () {
      assert.ok( $('#SageOneErrorType').hasClass('sage-one-unknown-error'), 'checks if the correct class was set to "sage-one-unknown-status"' );
      assert.ok( ($('#SageOneErrorType').text().length > 0), 'checks if the text is defined' );

      assert.ok( $('#SageOneErrorMessage').hasClass('sage-one-unknown-error'), 'checks if the correct class was set to "sage-one-unknown-status"' );
      assert.ok( ($('#SageOneErrorMessage').text().length > 0), 'checks if the text is defined' );

      assert.ok($('#SageOneSyncButton').is(":visible"), 'check if the sync button is visible');
      assert.ok($('#SageOneError').is(":visible"), 'check if the error message box is visible');
      assert.ok(!$('#SageOneInfo').is(":visible"), 'check if the info message box is not visible');
      QUnit.start();
    }, timeout);
  });

  /**************************************************************************/
  QUnit.asyncTest('test when something went wrong on sage', function(assert) {
    var expectedResponseOrderStatus = '{ "Status":"rejected_sage", "StatusMessage":"original error message from sage" }';
    var httpCodeOrderStatus = 200;
    var expectedResponseShopStatus = '{ "ShopStatus":"connected" }';
    var httpCodeShopStatus = 200;
    prepareTestServer(expectedResponseOrderStatus, httpCodeOrderStatus, expectedResponseShopStatus, httpCodeShopStatus);

    orderstatus(123); // call SUT

    setTimeout(function () {
      assert.ok( $('#SageOneErrorType').hasClass('sage-one-external-error'), 'checks if the correct class was set to "sage-one-external-status"' );
      assert.ok( ($('#SageOneErrorType').text().length > 0), 'checks if the text is defined' );

      assert.ok( $('#SageOneErrorMessage').hasClass('sage-one-external-error'), 'checks if the correct class was set to "sage-one-external-status"' );
      assert.equal( $('#SageOneErrorMessage').text(), 'original error message from sage', 'correct error message for "rejected_sage" case' );

      assert.ok($('#SageOneSyncButton').is(":visible"), 'check if the sync button is visible');
      assert.ok($('#SageOneError').is(":visible"), 'check if the error message box is visible');
      assert.ok(!$('#SageOneInfo').is(":visible"), 'check if the info message box is not visible');
      QUnit.start();
    }, timeout);
  });

  /**************************************************************************/
  QUnit.asyncTest('test when something went wrong when synchronizing orders', function(assert) {
    var expectedResponseOrderStatus = '{ "Status":"conflicted" }';
    var httpCodeOrderStatus = 200;
    var expectedResponseShopStatus = '{ "ShopStatus":"connected" }';
    var httpCodeShopStatus = 200;
    prepareTestServer(expectedResponseOrderStatus, httpCodeOrderStatus, expectedResponseShopStatus, httpCodeShopStatus);

    orderstatus(123); // call SUT

    setTimeout(function () {
      assert.ok( $('#SageOneErrorType').hasClass('sage-one-internal-error-conflicted'), 'checks if the correct class was set to "sage-one-external-status"' );
      assert.ok( ($('#SageOneErrorType').text().length > 0), 'checks if the text is defined' );

      assert.ok( $('#SageOneErrorMessage').hasClass('sage-one-internal-error-conflicted'), 'checks if the correct class was set to "sage-one-external-status"' );
      assert.ok( ($('#SageOneErrorType').text().length > 0), 'checks if the text is defined' );

      assert.ok($('#SageOneSyncButton').is(":visible"), 'check if the sync button is visible');
      assert.ok($('#SageOneError').is(":visible"), 'check if the error message box is visible');
      assert.ok(!$('#SageOneInfo').is(":visible"), 'check if the info message box is not visible');
      QUnit.start();
    }, timeout);
  });

  /**************************************************************************/
  QUnit.asyncTest('test when something went wrong on epagesj - unsupported_lineitem error', function(assert) {
    var expectedResponseOrderStatus = '{ "Status":"rejected_ep", "StatusMessage":"unsupported_lineitem" }';
    var httpCodeOrderStatus = 200;
    var expectedResponseShopStatus = '{ "ShopStatus":"connected" }';
    var httpCodeShopStatus = 200;
    prepareTestServer(expectedResponseOrderStatus, httpCodeOrderStatus, expectedResponseShopStatus, httpCodeShopStatus);

    orderstatus(123); // call SUT

    setTimeout(function () {
      assert.ok( $('#SageOneErrorType').hasClass('sage-one-internal-error'), 'checks if the correct class was set to "sage-one-internal-status"' );
      assert.ok( ($('#SageOneErrorType').text().length > 0), 'checks if the text is defined' );

      assert.ok( $('#SageOneErrorMessage').hasClass('sage-one-internal-error'), 'checks if the correct class was set to "sage-one-internal-status"' );
      assert.ok( ($('#SageOneErrorMessage').text().length > 0), 'checks if the text is defined' );

      assert.ok($('#SageOneSyncButton').is(":visible"), 'check if the sync button is visible');
      assert.ok($('#SageOneError').is(":visible"), 'check if the error message box is visible');
      assert.ok(!$('#SageOneInfo').is(":visible"), 'check if the info message box is not visible');
      QUnit.start();
    }, timeout);
  });

/**************************************************************************/
  QUnit.asyncTest('test when something went wrong on epagesj - unkown error with message', function(assert) {
    var expectedResponseOrderStatus = '{ "Status":"rejected_ep", "StatusMessage":"some error message" }';
    var httpCodeOrderStatus = 200;
    var expectedResponseShopStatus = '{ "ShopStatus":"connected" }';
    var httpCodeShopStatus = 200;
    prepareTestServer(expectedResponseOrderStatus, httpCodeOrderStatus, expectedResponseShopStatus, httpCodeShopStatus);

    orderstatus(123); // call SUT

    setTimeout(function () {
      assert.ok( $('#SageOneErrorType').hasClass('sage-one-internal-error'), 'checks if the correct class was set to "sage-one-internal-status"' );
      assert.ok( ($('#SageOneErrorType').text().length > 0), 'checks if the text is defined' );

      assert.ok( $('#SageOneErrorMessage').hasClass('sage-one-internal-error'), 'checks if the correct class was set to "sage-one-internal-status"' );
      assert.equal( $('#SageOneErrorMessage').text(), 'some error message', 'correct error message for "rejected_ep" case' );

      assert.ok($('#SageOneSyncButton').is(":visible"), 'check if the sync button is visible');
      assert.ok($('#SageOneError').is(":visible"), 'check if the error message box is visible');
      assert.ok(!$('#SageOneInfo').is(":visible"), 'check if the info message box is not visible');
      QUnit.start();
    }, timeout);
  });

  /**************************************************************************/
  QUnit.asyncTest('test when something went wrong on epagesj - unkown error "null" message', function(assert) {
    var expectedResponseOrderStatus = '{ "Status":"rejected_ep", "StatusMessage":null }';
    var httpCodeOrderStatus = 200;
    var expectedResponseShopStatus = '{ "ShopStatus":"connected" }';
    var httpCodeShopStatus = 200;
    prepareTestServer(expectedResponseOrderStatus, httpCodeOrderStatus, expectedResponseShopStatus, httpCodeShopStatus);

    orderstatus(123); // call SUT

    setTimeout(function () {
      assert.ok( $('#SageOneErrorType').hasClass('sage-one-internal-error'), 'checks if the correct class was set to "sage-one-internal-status"' );
      assert.ok( ($('#SageOneErrorType').text().length > 0), 'checks if the text is defined' );

      assert.ok( $('#SageOneErrorMessage').hasClass('sage-one-internal-error'), 'checks if the correct class was set to "sage-one-internal-status"' );
      assert.ok( ($('#SageOneErrorMessage').text().length > 0), 'checks if the text is defined' );

      assert.ok($('#SageOneSyncButton').is(":visible"), 'check if the sync button is visible');
      assert.ok($('#SageOneError').is(":visible"), 'check if the error message box is visible');
      assert.ok(!$('#SageOneInfo').is(":visible"), 'check if the info message box is not visible');
      QUnit.start();
    }, timeout);
  });
  
  /**************************************************************************/
  QUnit.asyncTest('test when something went wrong on epagesj - unkown error with empty string message', function(assert) {
    var expectedResponseOrderStatus = '{ "Status":"rejected_ep", "StatusMessage":null }';
    var httpCodeOrderStatus = 200;
    var expectedResponseShopStatus = '{ "ShopStatus":"connected" }';
    var httpCodeShopStatus = 200;
    prepareTestServer(expectedResponseOrderStatus, httpCodeOrderStatus, expectedResponseShopStatus, httpCodeShopStatus);

    orderstatus(123); // call SUT

    setTimeout(function () {
      assert.ok( $('#SageOneErrorType').hasClass('sage-one-internal-error'), 'checks if the correct class was set to "sage-one-internal-status"' );
      assert.ok( ($('#SageOneErrorType').text().length > 0), 'checks if the text is defined' );

      assert.ok( $('#SageOneErrorMessage').hasClass('sage-one-internal-error'), 'checks if the correct class was set to "sage-one-internal-status"' );
      assert.ok( ($('#SageOneErrorMessage').text().length > 0), 'checks if the text is defined' );

      assert.ok($('#SageOneSyncButton').is(":visible"), 'check if the sync button is visible');
      assert.ok($('#SageOneError').is(":visible"), 'check if the error message box is visible');
      assert.ok(!$('#SageOneInfo').is(":visible"), 'check if the info message box is not visible');
      QUnit.start();
    }, timeout);
  });

  /**************************************************************************/
  QUnit.asyncTest('test when something went wrong on epagesj - unkown error without message', function(assert) {
    var expectedResponseOrderStatus = '{ "Status":"rejected_ep" }';
    var httpCodeOrderStatus = 200;
    var expectedResponseShopStatus = '{ "ShopStatus":"connected" }';
    var httpCodeShopStatus = 200;
    prepareTestServer(expectedResponseOrderStatus, httpCodeOrderStatus, expectedResponseShopStatus, httpCodeShopStatus);

    orderstatus(123); // call SUT

    setTimeout(function () {
      assert.ok( $('#SageOneErrorType').hasClass('sage-one-internal-error'), 'checks if the correct class was set to "sage-one-internal-status"' );
      assert.ok( ($('#SageOneErrorType').text().length > 0), 'checks if the text is defined' );

      assert.ok( $('#SageOneErrorMessage').hasClass('sage-one-internal-error'), 'checks if the correct class was set to "sage-one-internal-status"' );
      assert.ok( ($('#SageOneErrorMessage').text().length > 0), 'checks if the text is defined' );

      assert.ok($('#SageOneSyncButton').is(":visible"), 'check if the sync button is visible');
      assert.ok($('#SageOneError').is(":visible"), 'check if the error message box is visible');
      assert.ok(!$('#SageOneInfo').is(":visible"), 'check if the info message box is not visible');
      QUnit.start();
    }, timeout);
  });

  /**************************************************************************/
  QUnit.asyncTest('test when order was paid', function(assert) {
    var expectedResponseOrderStatus = '{ "Status":"paid", "SageInvoiceReference":"InvoiceID", "LastStatusChange":"ATimeStamp" }';
    var httpCodeOrderStatus = 200;
    var expectedResponseShopStatus = '{ "ShopStatus":"connected" }';
    var httpCodeShopStatus = 200;
    prepareTestServer(expectedResponseOrderStatus, httpCodeOrderStatus, expectedResponseShopStatus, httpCodeShopStatus);

    orderstatus(123); // call SUT

    setTimeout(function () {
      assert.ok( $('#InvoiceNumber').hasClass('sage-one-paid-status'), 'checks if the correct class was set to "sage-one-paid-status"' );
      assert.equal( $('#InvoiceNumber').text(), 'InvoiceID', 'check the invoice number when order was paid' );

      assert.ok( $('#InvoiceStatus').hasClass('sage-one-paid-status'), 'checks if the correct class was set to "sage-one-paid-status"' );
      assert.ok( ($('#InvoiceStatus').text().length > 0), 'checks if the text is defined' );

      assert.ok( $('#LastStatusChange').hasClass('sage-one-paid-status'), 'checks if the correct class was set to "sage-one-paid-status"' );
      assert.equal( $('#LastStatusChange').text(), 'ATimeStamp', 'check the timestamp of the last status changed' );

      assert.ok($('#SageOneSyncButton').is(":visible"), 'check if the sync button is visible');
      assert.ok($('#SageOneInfo').is(":visible"), 'check if the info message box is visible');
      assert.ok(!$('#SageOneError').is(":visible"), 'check if the error message box is not visible');
      QUnit.start();
    }, timeout);
  });

  /**************************************************************************/
  QUnit.asyncTest('test when order was published', function(assert) {
    var expectedResponseOrderStatus = '{ "Status":"published", "SageInvoiceReference":"InvoiceID", "LastStatusChange":"ATimeStamp" }';
    var httpCodeOrderStatus = 200;
    var expectedResponseShopStatus = '{ "ShopStatus":"connected" }';
    var httpCodeShopStatus = 200;
    prepareTestServer(expectedResponseOrderStatus, httpCodeOrderStatus, expectedResponseShopStatus, httpCodeShopStatus);

    orderstatus(123); // call SUT

    setTimeout(function () {
      assert.ok( $('#InvoiceNumber').hasClass('sage-one-published-status'), 'checks if the correct class was set to "sage-one-published-status"' );
      assert.equal( $('#InvoiceNumber').text(), 'InvoiceID', 'check the invoice number when order was paid' );

      assert.ok( $('#InvoiceStatus').hasClass('sage-one-published-status'), 'checks if the correct class was set to "sage-one-published-status"' );
      assert.ok( ($('#InvoiceStatus').text().length > 0), 'checks if the text is defined' );

      assert.ok( $('#LastStatusChange').hasClass('sage-one-published-status'), 'checks if the correct class was set to "sage-one-published-status"' );
      assert.equal( $('#LastStatusChange').text(), 'ATimeStamp', 'check the timestamp of the last status changed' );

      assert.ok($('#SageOneSyncButton').is(":visible"), 'check if the sync button is visible');
      assert.ok($('#SageOneInfo').is(":visible"), 'check if the info message box is visible');
      assert.ok(!$('#SageOneError').is(":visible"), 'check if the error message box is not visible');
      QUnit.start();
    }, timeout);
  });

/*****************************************************************************
 * helpers
 ****************************************************************************/
  function prepareTestServer ( responseOrderStatus, httpStatusOrderStatus, responseShopStatus, httpStatusShopStatus ){
 // We have to fake (use sinon.js) the POST request to get data
    var sandbox = sinon.sandbox.create(),
        server = sandbox.useFakeServer();

    server.autoRespond = true;
    server.autoRespondAfter = 400;
    server.respondWith('GET', /.*ViewAction=JSONSageOneOrderStatus.*/, [httpStatusOrderStatus, {
          'Content-Type': 'application/json'
        }, responseOrderStatus
    ]);
    server.respondWith('GET', /.*ViewAction=JSONSageOneShopStatus.*/, [httpStatusShopStatus, {
          'Content-Type': 'application/json'
        }, responseShopStatus
    ]);
  }
});