<commit_before>describe('Core_loadData', function () {
  var id = 'testContainer';

  beforeEach(function () {
    this.$container = $('

').appendTo('body');
  });

  afterEach(function () {
    if (this.$container) {
      this.$container.remove();
    }
  });

  var arrayOfArrays = function () {
    return [
      ["", "Kia", "Nissan", "Toyota", "Honda"],
      ["2008", 10, 11, 12, 13],
      ["2009", 20, 11, 14, 13],
      ["2010", 30, 15, 12, 13]
    ];
  };

  var arrayOfObjects = function () {
    return [
      {id: 1, name: "Ted", lastName: "Right"},
      {id: 2, name: "Frank", lastName: "Honest"},
      {id: 3, name: "Joan", lastName: "Well"},
      {id: 4, name: "Sid", lastName: "Strong"},
      {id: 5, name: "Jane", lastName: "Neat"},
      {id: 6, name: "Chuck", lastName: "Jackson"},
      {id: 7, name: "Meg", lastName: "Jansen"},
      {id: 8, name: "Rob", lastName: "Norris"},
      {id: 9, name: "Sean", lastName: "O'Hara"},
      {id: 10, name: "Eve", lastName: "Branson"}
    ];
  };

  var arrayOfNestedObjects = function () {
    return [
      {id: 1, name: {
        first: "Ted",
        last: "Right"
      }},
      {id: 2, name: {
        first: "Frank",
        last: "Honest"
      }},
      {id: 3, name: {
        first: "Joan",
        last: "Well"
      }}
    ]
  };

  var htmlData = [
    ['H&M']
  ];

  it('should allow array of arrays', function () {
    handsontable();
    loadData(arrayOfArrays());
    expect(getDataAtCell(0, 2)).toEqual("Nissan");
  });

  it('should allow array of objects', function () {
    handsontable({
      columns: [
        {data: "id"},
        {data: "lastName"},
        {data: "name"}
      ]
    });
    loadData(arrayOfObjects());
    expect(getDataAtCell(0, 2)).toEqual("Ted");
  });

  it('should allow array of nested objects', function () {
    handsontable({
      data: arrayOfNestedObjects(),
      colHeaders: true,
      columns: [
        {data: "id"},
        {data: "name.last"},
        {data: "name.first"}
      ]
    });
    expect(getDataAtCell(0, 2)).toEqual("Ted");
  });

  it('should figure out default column names for array of nested objects', function () {
    handsontable({
      data: arrayOfNestedObjects(),
      colHeaders: true
    });
    expect(getDataAtCell(0, 2)).toEqual("Right");
  });

  it('should trigger onChange callback when loaded array of arrays', function () {
    var called = false;

    runs(function () {
      handsontable({
        onChange: function (changes, source) {
          if (source === 'loadData') {
            called = true;
          }
        }
      });
      loadData(arrayOfArrays());
    });

    waitsFor(function () {
      return (called === true)
    }, "onChange callback called", 100);

    runs(function () {
      expect(called).toEqual(true);
    });
  });

  it('should trigger onChange callback when loaded array of objects', function () {
    var called = false;

    runs(function () {
      handsontable({
        onChange: function (changes, source) {
          if (source === 'loadData') {
            called = true;
          }
        }
      });
      loadData(arrayOfObjects());
    });

    waitsFor(function () {
      return (called === true)
    }, "onChange callback called", 100);

    runs(function () {
      expect(called).toEqual(true);
    });
  });

  it('should trigger onChange callback when loaded array of nested objects', function () {
    var called = false;

    runs(function () {
      handsontable({
        onChange: function (changes, source) {
          if (source === 'loadData') {
            called = true;
          }
        }
      });
      loadData(arrayOfNestedObjects());
    });

    waitsFor(function () {
      return (called === true)
    }, "onChange callback called", 100);

    runs(function () {
      expect(called).toEqual(true);
    });
  });

  it('should create new rows for startRows (array of arrays)', function () {
    var called = false;
    var myData = arrayOfArrays();
    var expectedRows = myData.length * 2;

    handsontable({
      startRows: expectedRows,
      data: myData,
      onChange: function (changes, source) {
        if (source === 'loadData') {
          called = true;
        }
      }
    });

    expect(myData.length).toEqual(expectedRows);
  });

  it('should create new rows for startRows (array of nested objects)', function () {
    var called = false;
    var myData = arrayOfNestedObjects();
    var expectedRows = myData.length * 2;

    handsontable({
      startRows: expectedRows,
      data: myData,
      onChange: function (changes, source) {
        if (source === 'loadData') {
          called = true;
        }
      }
    });

    expect(myData.length).toEqual(expectedRows);
  });

  it('HTML special chars should be escaped by default', function () {
    handsontable();
    loadData(htmlData);
    expect(getCell(0, 0).innerHTML).toEqual('<b>H&M</b>');
  });

  it('HTML special chars should be escaped by default', function () {
    handsontable({
      startRows: 6,
      data: arrayOfObjects()
    });
    expect(getCell(9, 1).innerHTML).toEqual('Eve');
  });

  it('Should not invoke the cells callback multiple times with the same row/col', function(){
    var allRows = {};
    var dupsFound = 0;
    var myData = arrayOfNestedObjects();
    handsontable({
      data: myData,
      cells: function(row, col, prop) {
        if (allRows[row + '']) {
          if (0 <= allRows[row].indexOf(col)) {
            dupsFound++;
          }
        }
        allRows[row + ''] = allRows[row + ''] || [];
        allRows[row + ''].push(col);
      }
    });
    expect(dupsFound).toEqual(0);
  });

  it('Should not invoke the cells callback with bogus / non existing columns', function(){
    var bogusFound = 0;
    var myData = arrayOfObjects();
    handsontable({
      data: myData,
      cells: function(row, col, prop) {
        // out data have 3 columns so index should not be larger than 2.
        if (2 < col) {
          bogusFound++;
        }
      }
    });
    expect(bogusFound).toEqual(0);
  });

});
<commit_msg>tests: cleanup, remove test for rendering empty cells because I think it was invalid (issue #233)<commit_after>describe('Core_loadData', function () {
  var id = 'testContainer';

  beforeEach(function () {
    this.$container = $('

').appendTo('body');
  });

  afterEach(function () {
    if (this.$container) {
      this.$container.remove();
    }
  });

  var arrayOfArrays = function () {
    return [
      ["", "Kia", "Nissan", "Toyota", "Honda"],
      ["2008", 10, 11, 12, 13],
      ["2009", 20, 11, 14, 13],
      ["2010", 30, 15, 12, 13]
    ];
  };

  var arrayOfObjects = function () {
    return [
      {id: 1, name: "Ted", lastName: "Right"},
      {id: 2, name: "Frank", lastName: "Honest"},
      {id: 3, name: "Joan", lastName: "Well"},
      {id: 4, name: "Sid", lastName: "Strong"},
      {id: 5, name: "Jane", lastName: "Neat"},
      {id: 6, name: "Chuck", lastName: "Jackson"},
      {id: 7, name: "Meg", lastName: "Jansen"},
      {id: 8, name: "Rob", lastName: "Norris"},
      {id: 9, name: "Sean", lastName: "O'Hara"},
      {id: 10, name: "Eve", lastName: "Branson"}
    ];
  };

  var arrayOfNestedObjects = function () {
    return [
      {id: 1, name: {
        first: "Ted",
        last: "Right"
      }},
      {id: 2, name: {
        first: "Frank",
        last: "Honest"
      }},
      {id: 3, name: {
        first: "Joan",
        last: "Well"
      }}
    ]
  };

  var htmlData = [
    ['H&M']
  ];

  it('should allow array of arrays', function () {
    handsontable();
    loadData(arrayOfArrays());
    expect(getDataAtCell(0, 2)).toEqual("Nissan");
  });

  it('should allow array of objects', function () {
    handsontable({
      columns: [
        {data: "id"},
        {data: "lastName"},
        {data: "name"}
      ]
    });
    loadData(arrayOfObjects());
    expect(getDataAtCell(0, 2)).toEqual("Ted");
  });

  it('should allow array of nested objects', function () {
    handsontable({
      data: arrayOfNestedObjects(),
      colHeaders: true,
      columns: [
        {data: "id"},
        {data: "name.last"},
        {data: "name.first"}
      ]
    });
    expect(getDataAtCell(0, 2)).toEqual("Ted");
  });

  it('should figure out default column names for array of nested objects', function () {
    handsontable({
      data: arrayOfNestedObjects(),
      colHeaders: true
    });
    expect(getDataAtCell(0, 2)).toEqual("Right");
  });

  it('should trigger onChange callback when loaded array of arrays', function () {
    var called = false;

    runs(function () {
      handsontable({
        onChange: function (changes, source) {
          if (source === 'loadData') {
            called = true;
          }
        }
      });
      loadData(arrayOfArrays());
    });

    waitsFor(function () {
      return (called === true)
    }, "onChange callback called", 100);

    runs(function () {
      expect(called).toEqual(true);
    });
  });

  it('should trigger onChange callback when loaded array of objects', function () {
    var called = false;

    runs(function () {
      handsontable({
        onChange: function (changes, source) {
          if (source === 'loadData') {
            called = true;
          }
        }
      });
      loadData(arrayOfObjects());
    });

    waitsFor(function () {
      return (called === true)
    }, "onChange callback called", 100);

    runs(function () {
      expect(called).toEqual(true);
    });
  });

  it('should trigger onChange callback when loaded array of nested objects', function () {
    var called = false;

    runs(function () {
      handsontable({
        onChange: function (changes, source) {
          if (source === 'loadData') {
            called = true;
          }
        }
      });
      loadData(arrayOfNestedObjects());
    });

    waitsFor(function () {
      return (called === true)
    }, "onChange callback called", 100);

    runs(function () {
      expect(called).toEqual(true);
    });
  });

  it('should create new rows for startRows (array of arrays)', function () {
    var called = false;
    var myData = arrayOfArrays();
    var expectedRows = myData.length * 2;

    handsontable({
      startRows: expectedRows,
      data: myData,
      onChange: function (changes, source) {
        if (source === 'loadData') {
          called = true;
        }
      }
    });

    expect(myData.length).toEqual(expectedRows);
  });

  it('should create new rows for startRows (array of nested objects)', function () {
    var called = false;
    var myData = arrayOfNestedObjects();
    var expectedRows = myData.length * 2;

    handsontable({
      startRows: expectedRows,
      data: myData,
      onChange: function (changes, source) {
        if (source === 'loadData') {
          called = true;
        }
      }
    });

    expect(myData.length).toEqual(expectedRows);
  });

  it('HTML special chars should be escaped by default', function () {
    handsontable();
    loadData(htmlData);
    expect(getCell(0, 0).innerHTML).toEqual('<b>H&M</b>');
  });

  it('HTML special chars should be escaped by default', function () {
    handsontable({
      startRows: 6,
      data: arrayOfObjects()
    });
    expect(getCell(9, 1).innerHTML).toEqual('Eve');
  });

  //https://github.com/warpech/jquery-handsontable/pull/233
  it('Should not invoke the cells callback multiple times with the same row/col', function () {
    var allRows = {};
    var dupsFound = 0;
    var myData = arrayOfNestedObjects();
    handsontable({
      data: myData,
      cells: function (row, col, prop) {
        if (allRows[row + '']) {
          if (0 <= allRows[row].indexOf(col)) {
            dupsFound++;
          }
        }
        allRows[row + ''] = allRows[row + ''] || [];
        allRows[row + ''].push(col);
      }
    });
    expect(dupsFound).toEqual(0);
  });
});
<|endoftext|>


<commit_before>/*
 * == BSD2 LICENSE ==
 * Copyright (c) 2016, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 * == BSD2 LICENSE ==
 */

/* global beforeEach, describe, it */

var _ = require('lodash');
var expect = require('salinity').expect;

var proc = require('../../../lib/medtronic/processData.js');
var builder = require('../../../lib/objectBuilder')();
var TZOUtil = require('../../../lib/TimezoneOffsetUtil');

describe('processData.js', function() {
  var tzoUtil = new TZOUtil('GMT', '2016-12-01T00:00:00.000Z', []);
  var cfg = { builder:builder, tzoUtil: tzoUtil };
  var settings = { strokesPerUnit : 40, larger : true };

  beforeEach(function(){
    proc.init(cfg, settings);
  });

  describe('bolus', function(){

    describe('dual', function(){

      var bolus1 = {
          head: [ 1, 0, 20, 0, 1, 0, 8, 1 ],
          type: {
              value: 1,
              head_length: 8,
              name: 'BOLUS',
              date_length: 5,
              body_length: 0
          },
          date: [ 168, 234, 161, 14, 16 ],
          body: {},
          jsDate: new Date('2016-11-14T01:42:40.000Z'),
          index: 39
      };

      var bolus2 = {
        head: [ 1, 0, 20, 0, 20, 0, 8, 0 ],
        type: {
          value: 1,
          head_length: 8,
          name: 'BOLUS',
          date_length: 5,
          body_length: 0
        },
        date: [ 128, 234, 129, 14, 16 ],
        body: {},
        jsDate: new Date('2016-11-14T01:42:00.000Z'),
        index: 40
      };

      var expected = {
        time: '2016-11-14T01:42:00.000Z',
        timezoneOffset: 0,
        clockDriftOffset: 0,
        conversionOffset: 0,
        deviceTime: '2016-11-14T01:42:00',
        type: 'bolus',
        subType: 'dual/square',
        normal: 0.5,
        extended: 0.025,
        duration: 90000,
        expectedExtended: 0.5,
        expectedDuration: 1800000,
        payload: { logIndices: [40] },
        index: 40,
        jsDate: new Date('2016-11-14T01:42:00.000Z')
      };

      it('does not create two boluses when cancelled', function(){
        var result = proc.buildBolusRecords([bolus1,bolus2]);
        expect(result).deep.equals([expected]);
      });
    });
  });

  describe('cgm', function() {
    describe('low glucose suspend', function() {

      it('is suspended and resumed by user ', function() {

        var suspend1 = {
            head: [ 0x1E, 0x02 ],
            type: {
                value: 0X1E,
                name: 'PUMP_SUSPEND'
            },
            jsDate: new Date('2016-12-14T12:15:50.000Z'),
            index: 1
        };

        var suspend2 = {
            head: [ 0x1E, 0x43 ],
            type: {
                value: 0X1E,
                name: 'PUMP_SUSPEND'
            },
            jsDate: new Date('2016-12-14T12:16:07.000Z'),
            index: 2
        };

        var suspend3 = {
            head: [ 0x1E, 0x65 ],
            type: {
                value: 0X1E,
                name: 'PUMP_SUSPEND'
            },
            jsDate: new Date('2016-12-14T12:16:17.000Z'),
            index: 3
        };

        var resume1 = {
            head: [ 0x1F, 0xA6 ],
            type: {
                value: 0X1F,
                name: 'PUMP_RESUME'
            },
            jsDate: new Date('2016-12-14T12:17:08.000Z'),
            index: 4
        };

        var resume2 = {
            head: [ 0x1F, 0xC0 ],
            type: {
                value: 0X1F,
                name: 'PUMP_RESUME'
            },
            jsDate: new Date('2016-12-14T12:17:10.000Z'),
            index: 5
        };

        var expected = {
          'time': '2016-12-14T12:15:50.000Z',
          'timezoneOffset': 0,
          'clockDriftOffset': 0,
          'conversionOffset': 0,
          'deviceTime': '2016-12-14T12:15:50',
          'type': 'deviceEvent',
          'subType': 'status',
          'status': 'suspended',
          'reason': {
            'suspended': 'automatic',
            'resumed': 'manual'
          },
          'duration': 78000,
          'index': 1,
          'resumeIndex': 4,
          'payload': {
            'lgs_types': [
              'Suspend user',
              'Resume user'
            ],
            'logIndices': [
              1
            ]
          }
        };

        var result = proc.buildSuspendResumeRecords([suspend1,suspend2,suspend3,resume1,resume2]);
        expect(result[0]).to.deep.equal(expected);
      });

/*
      it('resumes automatically after two hours with no response by user', function () {

      });

      it('resumes automatically after two hours when user suspends', function() {

      });*/

    });
  });

});
<commit_msg>adding more LGS tests<commit_after>/*
 * == BSD2 LICENSE ==
 * Copyright (c) 2016, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 * == BSD2 LICENSE ==
 */

/* global beforeEach, describe, it */

var _ = require('lodash');
var expect = require('salinity').expect;

var proc = require('../../../lib/medtronic/processData.js');
var builder = require('../../../lib/objectBuilder')();
var TZOUtil = require('../../../lib/TimezoneOffsetUtil');

describe('processData.js', function() {
  var tzoUtil = new TZOUtil('GMT', '2016-12-01T00:00:00.000Z', []);
  var cfg = { builder:builder, tzoUtil: tzoUtil };
  var settings = { strokesPerUnit : 40, larger : true };

  beforeEach(function(){
    proc.init(cfg, settings);
  });

  describe('bolus', function(){

    describe('dual', function(){

      var bolus1 = {
          head: [ 1, 0, 20, 0, 1, 0, 8, 1 ],
          type: {
              value: 1,
              head_length: 8,
              name: 'BOLUS',
              date_length: 5,
              body_length: 0
          },
          date: [ 168, 234, 161, 14, 16 ],
          body: {},
          jsDate: new Date('2016-11-14T01:42:40.000Z'),
          index: 39
      };

      var bolus2 = {
        head: [ 1, 0, 20, 0, 20, 0, 8, 0 ],
        type: {
          value: 1,
          head_length: 8,
          name: 'BOLUS',
          date_length: 5,
          body_length: 0
        },
        date: [ 128, 234, 129, 14, 16 ],
        body: {},
        jsDate: new Date('2016-11-14T01:42:00.000Z'),
        index: 40
      };

      var expected = {
        time: '2016-11-14T01:42:00.000Z',
        timezoneOffset: 0,
        clockDriftOffset: 0,
        conversionOffset: 0,
        deviceTime: '2016-11-14T01:42:00',
        type: 'bolus',
        subType: 'dual/square',
        normal: 0.5,
        extended: 0.025,
        duration: 90000,
        expectedExtended: 0.5,
        expectedDuration: 1800000,
        payload: { logIndices: [40] },
        index: 40,
        jsDate: new Date('2016-11-14T01:42:00.000Z')
      };

      it('does not create two boluses when cancelled', function(){
        var result = proc.buildBolusRecords([bolus1,bolus2]);
        expect(result).deep.equals([expected]);
      });
    });
  });

  describe('deviceEvent', function() {
    describe('low glucose suspend status', function() {

      it('is suspended and resumed by user ', function() {

        var suspend1 = {
            head: [ 0x1E, 0x02 ],
            type: {
                value: 0X1E,
                name: 'PUMP_SUSPEND'
            },
            jsDate: new Date('2016-12-14T12:15:50.000Z'),
            index: 1
        };

        var suspend2 = {
            head: [ 0x1E, 0x43 ],
            type: {
                value: 0X1E,
                name: 'PUMP_SUSPEND'
            },
            jsDate: new Date('2016-12-14T12:16:07.000Z'),
            index: 2
        };

        var suspend3 = {
            head: [ 0x1E, 0x65 ],
            type: {
                value: 0X1E,
                name: 'PUMP_SUSPEND'
            },
            jsDate: new Date('2016-12-14T12:16:17.000Z'),
            index: 3
        };

        var resume1 = {
            head: [ 0x1F, 0xA6 ],
            type: {
                value: 0X1F,
                name: 'PUMP_RESUME'
            },
            jsDate: new Date('2016-12-14T12:17:08.000Z'),
            index: 4
        };

        var resume2 = {
            head: [ 0x1F, 0xC0 ],
            type: {
                value: 0X1F,
                name: 'PUMP_RESUME'
            },
            jsDate: new Date('2016-12-14T12:17:10.000Z'),
            index: 5
        };

        var expected = {
          'time': '2016-12-14T12:15:50.000Z',
          'timezoneOffset': 0,
          'clockDriftOffset': 0,
          'conversionOffset': 0,
          'deviceTime': '2016-12-14T12:15:50',
          'type': 'deviceEvent',
          'subType': 'status',
          'status': 'suspended',
          'reason': {
            'suspended': 'automatic',
            'resumed': 'manual'
          },
          'duration': 78000,
          'index': 1,
          'resumeIndex': 4,
          'payload': {
            'lgs_types': [
              'Suspend user',
              'Resume user'
            ],
            'logIndices': [
              1
            ]
          }
        };

        var result = proc.buildSuspendResumeRecords([suspend1,suspend2,suspend3,resume1,resume2]);
        expect(result[0]).to.deep.equal(expected);
      });

      it('resumes automatically after two hours with no response by user', function () {
        var suspend1 = {
            head: [ 0x1E, 0x02 ],
            type: {
                value: 0X1E,
                name: 'PUMP_SUSPEND'
            },
            jsDate: new Date('2016-12-14T15:35:51.000Z'),
            index: 1
        };

        var suspend2 = {
            head: [ 0x1E, 0x44 ],
            type: {
                value: 0X1E,
                name: 'PUMP_SUSPEND'
            },
            jsDate: new Date('2016-12-14T15:37:51.000Z'),
            index: 2
        };

        var resume1 = {
            head: [ 0x1F, 0x88 ],
            type: {
                value: 0X1F,
                name: 'PUMP_RESUME'
            },
            jsDate: new Date('2016-12-14T17:35:00.000Z'),
            index: 3
        };

        var resume2 = {
            head: [ 0x1F, 0xC0 ],
            type: {
                value: 0X1F,
                name: 'PUMP_RESUME'
            },
            jsDate: new Date('2016-12-14T17:40:46.000Z'),
            index: 4
        };

        var resume3 = {
            head: [ 0x1F, 0xC0 ],
            type: {
                value: 0X1F,
                name: 'PUMP_RESUME'
            },
            jsDate: new Date('2016-12-14T17:40:52.000Z'),
            index: 5
        };

        var expected = {
    			'time': '2016-12-14T15:35:51.000Z',
    			'timezoneOffset': 0,
    			'clockDriftOffset': 0,
    			'conversionOffset': 0,
    			'deviceTime': '2016-12-14T15:35:51',
    			'type': 'deviceEvent',
    			'subType': 'status',
    			'status': 'suspended',
          'index' : 1,
          'resumeIndex' : 3,
    			'reason': {
    				'suspended': 'automatic',
    				'resumed': 'automatic'
    			},
    			'duration': 7149000,
    			'payload': {
    				'lgs_types': [
    					'Suspend no response',
    					'Automatic resume after no response'
    				],
    				'logIndices': [
    					1
    				]
    			}
    		};

        var result = proc.buildSuspendResumeRecords([suspend1,suspend2,resume1,resume2,resume3]);
        expect(result[0]).to.deep.equal(expected);
      });

      it('resumes automatically after two hours when user suspends', function() {
        var suspend1 = {
            head: [ 0x1E, 0x02 ],
            type: {
                value: 0X1E,
                name: 'PUMP_SUSPEND'
            },
            jsDate: new Date('2016-12-14T18:00:22.000Z'),
            index: 1
        };

        var suspend2 = {
            head: [ 0x1E, 0x43 ],
            type: {
                value: 0X1E,
                name: 'PUMP_SUSPEND'
            },
            jsDate: new Date('2016-12-14T18:00:32.000Z'),
            index: 2
        };

        var suspend3 = {
            head: [ 0x1E, 0x65 ],
            type: {
                value: 0X1E,
                name: 'PUMP_SUSPEND'
            },
            jsDate: new Date('2016-12-14T18:00:37.000Z'),
            index: 3
        };

        var resume1 = {
            head: [ 0x1F, 0xA7 ],
            type: {
                value: 0X1F,
                name: 'PUMP_RESUME'
            },
            jsDate: new Date('2016-12-14T20:00:00.000Z'),
            index: 4
        };

        var expected = {

    			'time': '2016-12-14T18:00:22.000Z',
    			'timezoneOffset': 0,
    			'clockDriftOffset': 0,
    			'conversionOffset': 0,
    			'deviceTime': '2016-12-14T18:00:22',
    			'type': 'deviceEvent',
    			'subType': 'status',
    			'status': 'suspended',
    			'reason': {
    				'suspended': 'automatic',
    				'resumed': 'automatic'
    			},
    			'duration': 7178000,
          'index' : 1,
          'resumeIndex' : 4,
    			'payload': {
    				'lgs_types': [
    					'Suspend user',
    					'Automatic resume after user suspend'
    				],
    				'logIndices': [
    					1
    				]
    			}
    		};

        var result = proc.buildSuspendResumeRecords([suspend1,suspend2,suspend3,resume1]);
        expect(result[0]).to.deep.equal(expected);
      });

    });
  });

});
<|endoftext|>


<commit_before>'use strict';

describe('Meta Generator', () => {
  const Hexo = require('../../../lib/hexo');
  const hexo = new Hexo();
  const metaGenerator = require('../../../lib/plugins/filter/after_render/meta_generator').bind(hexo);
  const cheerio = require('cheerio');

  it('default', () => {
    const content = '<link>';
    const result = metaGenerator(content);

    const $ = cheerio.load(result);
    $('meta[name="generator"]').should.to.have.lengthOf(1);
    $('meta[name="generator"]').attr('content').should.eql(`Hexo ${hexo.version}`);
  });

  it('disable meta_generator', () => {
    const content = '<link>';
    hexo.config.meta_generator = false;
    const result = metaGenerator(content);

    should.not.exist(result);
  });

  it('no duplicate generator tag', () => {
    hexo.config.meta_generator = true;
    const result = str => metaGenerator(str);

    should.not.exist(result('<link><meta name="generator" content="foo">'));
    should.not.exist(result('<link><meta content="foo" name="generator">'));
  });

  it('ignore empty head tag', () => {
    const content = '<link>';
    hexo.config.meta_generator = true;
    const result = metaGenerator(content);

    const $ = cheerio.load(result);
    $('meta[name="generator"]').should.to.have.lengthOf(1);

    const expected = '<link><meta name="generator" content="Hexo '
      + hexo.version + '">';
    result.should.eql(expected);
  });

  it('apply to first non-empty head tag only', () => {
    const content = '<link><link>';
    hexo.config.meta_generator = true;
    const result = metaGenerator(content);

    const $ = cheerio.load(result);
    $('meta[name="generator"]').should.to.have.lengthOf(1);

    const expected = '<link><meta name="generator" content="Hexo '
      + hexo.version + '"><link>';
    result.should.eql(expected);
  });

  // Test for Issue #3777
  it('multi-line head', () => {
    const content = '\n<link>\n';
    hexo.config.meta_generator = true;
    const result = metaGenerator(content);

    const $ = cheerio.load(result);
    $('meta[name="generator"]').should.to.have.lengthOf(1);

    const expected = '\n<link>\n<meta name="generator" content="Hexo ' + hexo.version + '">';

    result.should.eql(expected);
  });
});
<commit_msg>Ally review<commit_after>'use strict';

describe('Meta Generator', () => {
  const Hexo = require('../../../lib/hexo');
  const hexo = new Hexo();
  const metaGenerator = require('../../../lib/plugins/filter/after_render/meta_generator').bind(hexo);
  const cheerio = require('cheerio');

  it('default', () => {
    const content = '<link>';
    const result = metaGenerator(content);

    const $ = cheerio.load(result);
    $('meta[name="generator"]').should.to.have.lengthOf(1);
    $('meta[name="generator"]').attr('content').should.eql(`Hexo ${hexo.version}`);
  });

  it('disable meta_generator', () => {
    const content = '<link>';
    hexo.config.meta_generator = false;
    const result = metaGenerator(content);

    should.not.exist(result);
  });

  it('no duplicate generator tag', () => {
    hexo.config.meta_generator = true;

    should.not.exist(metaGenerator('<link><meta name="generator" content="foo">'));
    should.not.exist(metaGenerator('<link><meta content="foo" name="generator">'));
  });

  it('ignore empty head tag', () => {
    const content = '<link>';
    hexo.config.meta_generator = true;
    const result = metaGenerator(content);

    const $ = cheerio.load(result);
    $('meta[name="generator"]').should.to.have.lengthOf(1);

    const expected = '<link><meta name="generator" content="Hexo '
      + hexo.version + '">';
    result.should.eql(expected);
  });

  it('apply to first non-empty head tag only', () => {
    const content = '<link><link>';
    hexo.config.meta_generator = true;
    const result = metaGenerator(content);

    const $ = cheerio.load(result);
    $('meta[name="generator"]').should.to.have.lengthOf(1);

    const expected = '<link><meta name="generator" content="Hexo '
      + hexo.version + '"><link>';
    result.should.eql(expected);
  });

  // Test for Issue #3777
  it('multi-line head', () => {
    const content = '\n<link>\n';
    hexo.config.meta_generator = true;
    const result = metaGenerator(content);

    const $ = cheerio.load(result);
    $('meta[name="generator"]').should.to.have.lengthOf(1);

    const expected = '\n<link>\n<meta name="generator" content="Hexo ' + hexo.version + '">';

    result.should.eql(expected);
  });
});
<|endoftext|>


<commit_before>'use strict';

var htmlHelpers = require('../../../src/template/html_helpers');

describe('html_helpers.js public API', function() {
  describe('isValidChild', function() {
    it('should be a function', function() {
      expect(htmlHelpers.validation.isValidChild).to.be.a('function');
    });
    it('should check for a valid child', function() {
      expect(htmlHelpers.validation.isValidChild('li', 'li')).to.be.a('string');
    });
    it('should check for an invalid child', function() {
      expect(htmlHelpers.validation.isValidChild('li', 'ul')).to.equal(true);
    });
    it('should return the opposite of impliedCloseTag', function() {
      var isValidChild = htmlHelpers.validation.isValidChild('li', 'ul');
      var impliedCloseTag = htmlHelpers.validation.impliedCloseTag('li', 'ul');
      expect(isValidChild).to.equal(!impliedCloseTag);
    });
  });
  describe('impliedCloseTag', function() {
    it('should be a function', function() {
      expect(htmlHelpers.validation.impliedCloseTag).to.be.a('function');
    });
    it('should check correctly for valid omission of a close tag', function() {
      expect(htmlHelpers.validation.impliedCloseTag('li', 'li')).to.equal(true);
    });
    it('should check correctly for invalid omission of a close tag', function() {
      expect(htmlHelpers.validation.impliedCloseTag('li', 'ul')).to.equal(false);
    });
  });
});
<commit_msg>Changes to html_helper test to account for new non-strict mode<commit_after>'use strict';

var htmlHelpers = require('../../../src/template/html_helpers');

describe('html_helpers.js public API', function() {
  describe('isValidChild', function() {
    it('should be a function', function() {
      expect(htmlHelpers.validation.isValidChild).to.be.a('function');
    });
    it('should check for a valid child', function() {
      expect(htmlHelpers.validation.isValidChild('li', 'li', true)).to.be.a('string');
    });
    it('should check for an invalid child', function() {
      expect(htmlHelpers.validation.isValidChild('li', 'ul', true)).to.equal(true);
    });
    it('should check for implicit tags created by browser in non-strict mode', function() {
      expect(htmlHelpers.validation.isValidChild('tr', 'table')).to.equal(true);
    });
    it('should return the opposite of impliedCloseTag', function() {
      var isValidChild = htmlHelpers.validation.isValidChild('li', 'ul');
      var impliedCloseTag = htmlHelpers.validation.impliedCloseTag('li', 'ul');
      expect(isValidChild).to.equal(!impliedCloseTag);
    });
  });
  describe('impliedCloseTag', function() {
    it('should be a function', function() {
      expect(htmlHelpers.validation.impliedCloseTag).to.be.a('function');
    });
    it('should check correctly for valid omission of a close tag', function() {
      expect(htmlHelpers.validation.impliedCloseTag('li', 'li')).to.equal(true);
    });
    it('should check correctly for invalid omission of a close tag', function() {
      expect(htmlHelpers.validation.impliedCloseTag('li', 'ul')).to.equal(false);
    });
  });
});
<|endoftext|>


<commit_before>'use strict';

describe('juju application notifications', function() {
  var Y, juju, models, views,
      applicationContainer,
      notificationsContainer,
      viewContainer,
      db,

      _setTimeout, _viewsHighlightRow;

  function assertNotificationNumber(value) {
    assert.equal(
        applicationContainer.one('#notify-indicator').getHTML().trim(),
        value, 'The system didnt show the alert');
  }

  before(function() {
    Y = YUI(GlobalConfig).use([
      'juju-models',
      'juju-views',
      'juju-gui',
      'juju-env',
      'juju-tests-utils',
      'node-event-simulate'],
    function(Y) {
      juju = Y.namespace('juju');
      models = Y.namespace('juju.models');
      views = Y.namespace('juju.views');
    });
  });

  beforeEach(function() {
    applicationContainer = Y.Node.create('
');
    applicationContainer.appendTo(Y.one(Y.one(document.body)));

    notificationsContainer = Y.Node.create('
');
    notificationsContainer.appendTo(applicationContainer);

    viewContainer = Y.Node.create('
');
    viewContainer.appendTo(applicationContainer);

    db = new models.Database();

    var notificationsView = new views.NotificationsView({
      container: notificationsContainer,
      app: {},
      env: {
        on: function() {},
        get: function(key) {
          if (key === 'connected') {
            return true;
          }
          return null;
        }
      },
      notifications: db.notifications
    });

    notificationsView.render();

    // The notifications.js delays the notification update.
    // We are going to avoid this timeout to make it possible to test
    // the notification callback synchronously.
    _setTimeout = window.setTimeout;
    window.setTimeout = function(callback) {
      callback();
    };

    // We skip this part because we have no row to highlight
    _viewsHighlightRow = views.highlightRow;
    views.highlightRow = function() {};

  });

  afterEach(function() {
    applicationContainer.remove(true);
    window.setTimeout = _setTimeout;
    views.highlightRow = _viewsHighlightRow;
  });

  it('should show notification for "add_unit" and "remove_units" exceptions' +
      ' (service view)', function() {
       var view = new views.service({
         container: viewContainer,
         app: {
           getModelURL: function() {
             return 'my url';
           }
         },
         db: db,
         env: {
           add_unit: function(serviceId, delta, callback) {
             callback({
               err: true
             });
           },
           remove_units: function(param, callback) {
             callback({
               err: true
             });
           }
         },
         model: {
           getAttrs: function() {},
           get: function(key) {
             if ('unit_count' === key) {
               return 2;
             }
             return null;
           }
         },
         querystring: {}
       }).render();

       db.units.get_units_for_service = function() {
         return [{
           id: 1
         }];
       };

       view._modifyUnits(3);
       assertNotificationNumber('1');

       view._modifyUnits(1);
       assertNotificationNumber('2');
     });

  it('should show notification for "remove_units" and "resolved" exceptions' +
      ' (unit view)', function() {
       var view = new views.unit({
         container: viewContainer,
         app: {
           getModelURL: function() {
             return 'my url';
           }
         },
         db: db,
         env: {
           remove_units: function(param, callback) {
             callback({
               err: true,
               unit_names: ['aaa']
             });
           },
           resolved: function(unit_name, relation_name, retry, callback) {
             callback({
               err: true
             });
           }
         },
         unit: {},
         querystring: {}
       });

       // Used my unit.js inside the "render" function
       db.services.getById = function() {
         // Mock service
         return {
           get: function(key) {
             if (key === 'loaded') {
               return true;
             }
             return null;
           }
         };
       };

       view.render();

       view.confirmRemoved({
         preventDefault: function() {}
       });

       view.remove_panel.footerNode.one('.btn-danger').simulate('click');
       view.remove_panel.destroy();

       assertNotificationNumber('1');

       // Fake relation
       db.relations.getById = function() {
         return {name: ''};
       };

       view.retryRelation({
         preventDefault: function() {},

         // This is a mock object of the relation button
         target: {
           ancestor: function() {
             return {get: function() {}};
           },
           set: function() {}
         }
       });

       assertNotificationNumber('2');
     });

  it('should show notification for "add_relation" and "remove_relation"' +
      ' exceptions (environment view)', function() {
       var view = new views.environment({
         db: db,
         container: viewContainer}).render();

       view.service_click_actions._doAddRelationCallback.apply(view, [{
         err: true
       }]);

       assertNotificationNumber('1');

       view._doRemoveRelationCallback.apply({
         scope: view,
         view: {
           removeSVGClass: function() {}
         },
         confirmButton: {
           set: function() {}
         }
       }, [{
         err: true
       }]);

       assertNotificationNumber('2');
     });

  it('should show notification for "add_relation" and "destroy_service"' +
      ' exceptions (environment view)', function() {
       var view = new views.environment({
         db: db,
         destroy_service: {
           get: function() {}
         },
         env: {
           destroy_service: function(service, callback) {
             callback({err: true});
           }
         },
         container: viewContainer}).render();

       view.service_click_actions._doAddRelationCallback.apply(view, [{
         err: true
       }]);

       assertNotificationNumber('1');

       view.service_click_actions.destroyService.apply(
           view.service_click_actions, [
         // Fake m object
         {},

         // Fake context object
         {},

         view,

         // Fake btn object
         {set: function() {}}
           ]);

       assertNotificationNumber('2');
     });

  it('should show notification for "get_service" exceptions' +
      ' (service constraints view)', function() {

       var view = new views.service_constraints({
         db: db,
         model: {
           getAttrs: function() {},
           get: function(key) {
             if ('constraints' === key) {
               return {};
             }
             return null;
           }
         },
         env: {
           set_constraints: function(id, values, callback) {
             callback({
               err: true
             });
           }
         },
         container: viewContainer}).render();

       view.updateConstraints();

       assertNotificationNumber('1');
     });

  it('should show notification for "get_service", "expose" and "unexpose"' +
      ' exceptions (service config view)', function() {

       var view = new views.service_config({
         db: db,
         app: {
           getModelURL: function() {}
         },
         model: {
           getAttrs: function() {},
           get: function(key) {
             if ('loaded' === key) {
               return true;
             }
             if ('config' === key) {
               return {};
             }
             return null;
           }
         },
         env: {
           set_config: function(id, newValues, callback) {
             callback({
               err: true
             });
           },
           expose: function(id, callback) {
             callback({
               err: true
             });
           },
           unexpose: function(id, callback) {
             callback({
               err: true
             });
           }
         },
         container: viewContainer});

       db.charms.getById = function() {
         return {
           getAttrs: function() {},
           get: function(key) {
             if ('config' === key) {
               return {};
             }
             return null;
           }
         };
       };

       view.render();

       view.saveConfig();

       assertNotificationNumber('1');

       view.exposeService();

       assertNotificationNumber('2');

       view.unexposeService();

       assertNotificationNumber('3');
     });

  it('should show notification for "remove_relation"' +
      ' exceptions (service relations view)', function() {

       var view = new views.service_relations({
         db: db,
         app: {
           getModelURL: function() {}
         },
         env: {
           remove_relation: function(id, newValues, callback) {
             callback({
               err: true
             });
           }
         },
         container: viewContainer});

       db.relations.getById = function() {
         return {
           get: function(key) {
             if ('endpoints' === key) {
               return [
                       [{}, {name: ''}]
               ];
             }
             return null;
           }
         };
       };

       view.render();

       view.confirmRemoved({
         preventDefault: function() {},

         // This is a mock object of the relation button
         target: {
           ancestor: function() {},
           get: function() {}
         }
       });
       view.remove_panel.footerNode.one('.btn-danger').simulate('click');
       view.remove_panel.destroy();

       assertNotificationNumber('1');
     });

});
<commit_msg>checkpoint<commit_after>'use strict';

describe('juju application notifications', function() {
  var Y, juju, models, views,
      applicationContainer,
      notificationsContainer,
      viewContainer,
      db,

      _setTimeout, _viewsHighlightRow,
      ERR_EV = {
          err: true
      },
      NO_OP = function() {};

  function assertNotificationNumber(value) {
    assert.equal(
        applicationContainer.one('#notify-indicator').getHTML().trim(),
        value, 'The system didnt show the alert');
  }

  before(function() {
    Y = YUI(GlobalConfig).use([
      'juju-models',
      'juju-views',
      'juju-gui',
      'juju-env',
      'juju-tests-utils',
      'node-event-simulate'],
    function(Y) {
      juju = Y.namespace('juju');
      models = Y.namespace('juju.models');
      views = Y.namespace('juju.views');
    });
  });

  beforeEach(function() {
    applicationContainer = Y.Node.create('
');
    applicationContainer.appendTo(Y.one(Y.one(document.body)));

    notificationsContainer = Y.Node.create('
');
    notificationsContainer.appendTo(applicationContainer);

    viewContainer = Y.Node.create('
');
    viewContainer.appendTo(applicationContainer);

    db = new models.Database();

    var notificationsView = new views.NotificationsView({
      container: notificationsContainer,
      app: {},
      env: {
        on: NO_OP,
        get: function(key) {
          if (key === 'connected') {
            return true;
          }
          return null;
        }
      },
      notifications: db.notifications
    });

    notificationsView.render();

    // The notifications.js delays the notification update.
    // We are going to avoid this timeout to make it possible to test
    // the notification callback synchronously.
    _setTimeout = window.setTimeout;
    window.setTimeout = function(callback) {
      callback();
    };

    // We skip this part because we have no row to highlight
    _viewsHighlightRow = views.highlightRow;
    views.highlightRow = NO_OP;

  });

  afterEach(function() {
    applicationContainer.remove(true);
    window.setTimeout = _setTimeout;
    views.highlightRow = _viewsHighlightRow;
  });

  it('should show notification for "add_unit" and "remove_units" exceptions' +
      ' (service view)', function() {
       var view = new views.service({
         container: viewContainer,
         app: {
           getModelURL: function() {
             return 'my url';
           }
         },
         db: db,
         env: {
           add_unit: function(serviceId, delta, callback) {
             callback(ERR_EV);
           },
           remove_units: function(param, callback) {
             callback(ERR_EV);
           }
         },
         model: {
           getAttrs: NO_OP,
           get: function(key) {
             if ('unit_count' === key) {
               return 2;
             }
             return null;
           }
         },
         querystring: {}
       }).render();

       db.units.get_units_for_service = function() {
         return [{
           id: 1
         }];
       };

       view._modifyUnits(3);
       assertNotificationNumber('1');

       view._modifyUnits(1);
       assertNotificationNumber('2');
     });

  it('should show notification for "remove_units" and "resolved" exceptions' +
      ' (unit view)', function() {
       var view = new views.unit({
         container: viewContainer,
         app: {
           getModelURL: function() {
             return 'my url';
           }
         },
         db: db,
         env: {
           remove_units: function(param, callback) {
             callback({
               err: true,
               unit_names: ['aaa']
             });
           },
           resolved: function(unit_name, relation_name, retry, callback) {
             callback(ERR_EV);
           }
         },
         unit: {},
         querystring: {}
       });

       // Used my unit.js inside the "render" function
       db.services.getById = function() {
         // Mock service
         return {
           get: function(key) {
             if (key === 'loaded') {
               return true;
             }
             return null;
           }
         };
       };

       view.render();

       view.confirmRemoved({
         preventDefault: NO_OP
       });

       view.remove_panel.footerNode.one('.btn-danger').simulate('click');
       view.remove_panel.destroy();

       assertNotificationNumber('1');

       // Fake relation
       db.relations.getById = function() {
         return {name: ''};
       };

       view.retryRelation({
         preventDefault: NO_OP,

         // This is a mock object of the relation button
         target: {
           ancestor: function() {
             return {get: NO_OP};
           },
           set: NO_OP
         }
       });

       assertNotificationNumber('2');
     });

  it('should show notification for "add_relation" and "remove_relation"' +
      ' exceptions (environment view)', function() {
       var view = new views.environment({
         db: db,
         container: viewContainer}).render();

       view.service_click_actions._doAddRelationCallback.apply(view, [ERR_EV]);

       assertNotificationNumber('1');

       view._doRemoveRelationCallback.apply({
         scope: view,
         view: {
           removeSVGClass: NO_OP
         },
         confirmButton: {
           set: NO_OP
         }
       }, [ERR_EV]);

       assertNotificationNumber('2');
     });

  it('should show notification for "add_relation" and "destroy_service"' +
      ' exceptions (environment view)', function() {
       var view = new views.environment({
         db: db,
         destroy_service: {
           get: NO_OP
         },
         env: {
           destroy_service: function(service, callback) {
             callback(ERR_EV);
           }
         },
         container: viewContainer}).render();

       view.service_click_actions._doAddRelationCallback.apply(view, [ERR_EV]);

       assertNotificationNumber('1');

       view.service_click_actions.destroyService.apply(
           //destroyService function signature > (m, context, view, btn)
           view.service_click_actions, [{}, {}, view, {set: NO_OP}]);

       assertNotificationNumber('2');
     });

  it('should show notification for "get_service" exceptions' +
      ' (service constraints view)', function() {

       var view = new views.service_constraints({
         db: db,
         model: {
           getAttrs: NO_OP,
           get: function(key) {
             if ('constraints' === key) {
               return {};
             }
             return null;
           }
         },
         env: {
           set_constraints: function(id, values, callback) {
             callback(ERR_EV);
           }
         },
         container: viewContainer}).render();

       view.updateConstraints();

       assertNotificationNumber('1');
     });

  it('should show notification for "get_service", "expose" and "unexpose"' +
      ' exceptions (service config view)', function() {

       var view = new views.service_config({
         db: db,
         app: {
           getModelURL: NO_OP
         },
         model: {
           getAttrs: NO_OP,
           get: function(key) {
             if ('loaded' === key) {
               return true;
             }
             if ('config' === key) {
               return {};
             }
             return null;
           }
         },
         env: {
           set_config: function(id, newValues, callback) {
             callback(ERR_EV);
           },
           expose: function(id, callback) {
             callback(ERR_EV);
           },
           unexpose: function(id, callback) {
             callback(ERR_EV);
           }
         },
         container: viewContainer});

       db.charms.getById = function() {
         return {
           getAttrs: NO_OP,
           get: function(key) {
             if ('config' === key) {
               return {};
             }
             return null;
           }
         };
       };

       view.render();

       view.saveConfig();

       assertNotificationNumber('1');

       view.exposeService();

       assertNotificationNumber('2');

       view.unexposeService();

       assertNotificationNumber('3');
     });

  it('should show notification for "remove_relation"' +
      ' exceptions (service relations view)', function() {

       var view = new views.service_relations({
         db: db,
         app: {
           getModelURL: NO_OP
         },
         env: {
           remove_relation: function(id, newValues, callback) {
             callback(ERR_EV);
           }
         },
         container: viewContainer});

       db.relations.getById = function() {
         return {
           get: function(key) {
             if ('endpoints' === key) {
               return [
                       [{}, {name: ''}]
               ];
             }
             return null;
           }
         };
       };

       view.render();

       view.confirmRemoved({
         preventDefault: NO_OP,

         // This is a mock object of the relation button
         target: {
           ancestor: NO_OP,
           get: NO_OP
         }
       });
       view.remove_panel.footerNode.one('.btn-danger').simulate('click');
       view.remove_panel.destroy();

       assertNotificationNumber('1');
     });

});
<|endoftext|>


<commit_before>'use strict';

describe('juju application notifications', function() {
  var Y, juju, models, views,
      applicationContainer,
      notificationsContainer,
      viewContainer,
      db,

      _setTimeout, _viewsHighlightRow;

  before(function() {
    Y = YUI(GlobalConfig).use([
      'juju-models',
      'juju-views',
      'juju-gui',
      'juju-env',
      'juju-tests-utils',
      'node-event-simulate'],
    function(Y) {
      juju = Y.namespace('juju');
      models = Y.namespace('juju.models');
      views = Y.namespace('juju.views');
    });
  });

  beforeEach(function() {
    applicationContainer = Y.Node.create('
');
    applicationContainer.appendTo(Y.one(Y.one(document.body)));

    notificationsContainer = Y.Node.create('
');
    notificationsContainer.appendTo(applicationContainer);

    viewContainer = Y.Node.create('
');
    viewContainer.appendTo(applicationContainer);

    db = new models.Database();

    var notificationsView = new views.NotificationsView({
      container: notificationsContainer,
      app: {},
      env: {
        on: function() {},
        get: function(key) {
          if (key === 'connected') {
            return true;
          }
          return null;
        }
      },
      notifications: db.notifications
    });

    notificationsView.render();

    // The notifications.js delays the notification update.
    // We are going to avoid this timeout to make it possible to test
    // the notification callback synchronously.
    _setTimeout = window.setTimeout;
    window.setTimeout = function(callback) {
      callback();
    };

    // We skip this part because we have no row to highlight
    _viewsHighlightRow = views.highlightRow;
    views.highlightRow = function() {};

  });

  afterEach(function() {
    applicationContainer.remove(true);
    window.setTimeout = _setTimeout;
    views.highlightRow = _viewsHighlightRow;
  });

  it('should show notification for "add_unit" and "remove_units" exceptions' +
      ' (service view)', function() {
       var view = new views.service({
         container: viewContainer,
         app: {
           getModelURL: function() {
             return 'my url';
           }
         },
         db: db,
         env: {
           add_unit: function(serviceId, delta, callback) {
             callback({
               err: true
             });
           },
           remove_units: function(param, callback) {
             callback({
               err: true
             });
           }
         },
         model: {
           getAttrs: function() {},
           get: function(key) {
             if ('unit_count' === key) {
               return 2;
             }
             return null;
           }
         },
         querystring: {}
       }).render();

       db.units.get_units_for_service = function() {
         return [{
           id: 1
         }];
       };

       view._modifyUnits(3);
       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '1', 'The system didnt show the alert');

       view._modifyUnits(1);
       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '2', 'The system didnt show the alert');

     });

  it('should show notification for "remove_units" exceptions' +
      ' (unit view)', function() {
       var view = new views.unit({
         container: viewContainer,
         app: {
           getModelURL: function() {
             return 'my url';
           }
         },
         db: db,
         env: {
           remove_units: function(param, callback) {
             callback({
               err: true,
               unit_names: ['aaa']
             });
           }
         },
         unit: {},
         querystring: {}
       });

       // Used my unit.js inside the "render" function
       db.services.getById = function() {
         // Mock service
         return {
           get: function(key) {
             if (key === 'loaded') {
               return true;
             }
             return null;
           }
         };
       };

       view.render();

       view.confirmRemoved({
         preventDefault: function() {}
       });

       view.remove_panel.footerNode.one('.btn-danger').simulate('click');
       view.remove_panel.destroy();

       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '1', 'The system didnt show the alert');
     });

  it('should show notification for "add_relation" and "remove_relation"' +
      ' exceptions (environment view)', function() {
       var view = new views.environment({
         db: db,
         container: viewContainer}).render();

       view.service_click_actions._doAddRelationCallback.apply(view, [{
         err: true
       }]);

       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '1', 'The system didnt show the alert');

       view._doRemoveRelationCallback.apply({
         scope: view,
         view: {
           removeSVGClass: function() {}
         },
         confirmButton: {
           set: function() {}
         }
       }, [{
         err: true
       }]);

       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '2', 'The system didnt show the alert');
     });

  it('should show notification for "add_relation" exceptions' +
      ' (environment view)', function() {
       var view = new views.environment({
         db: db,
         container: viewContainer}).render();

       view.service_click_actions._doAddRelationCallback.apply(view, [{
         err: true
       }]);

       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '1', 'The system didnt show the alert');
     });

  it('should show notification for "get_service" exceptions' +
      ' (service constraints view)', function() {

       var view = new views.service_constraints({
         db: db,
         model: {
           getAttrs: function() {},
           get: function(key) {
             if ('constraints' === key) {
               return {};
             }
             return null;
           }
         },
         env: {
           set_constraints: function(id, values, callback) {
             callback({
               err: true
             });
           }
         },
         container: viewContainer}).render();

       view.updateConstraints();

       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '1', 'The system didnt show the alert');

     });

  it('should show notification for "get_service", "expose" and "unexpose"' +
      ' exceptions (service config view)', function() {

       var view = new views.service_config({
         db: db,
         app: {
           getModelURL: function() {}
         },
         model: {
           getAttrs: function() {},
           get: function(key) {
             if ('loaded' === key) {
               return true;
             }
             if ('config' === key) {
               return {};
             }
             return null;
           }
         },
         env: {
           set_config: function(id, newValues, callback) {
             callback({
               err: true
             });
           },
           expose: function(id, callback) {
             callback({
               err: true
             });
           },
           unexpose: function(id, callback) {
             callback({
               err: true
             });
           }
         },
         container: viewContainer});

       db.charms.getById = function() {
         return {
           getAttrs: function() {},
           get: function(key) {
             if ('config' === key) {
               return {};
             }
             return null;
           }
         };
       };

       view.render();

       view.saveConfig();

       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '1', 'The system didnt show the alert');

       view.exposeService();

       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '2', 'The system didnt show the alert');

       view.unexposeService();

       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '3', 'The system didnt show the alert');
     });

  it('should show notification for "remove_relation"' +
      ' exceptions (service relations view)', function() {

       var view = new views.service_relations({
         db: db,
         app: {
           getModelURL: function() {}
         },
         env: {
           remove_relation: function(id, newValues, callback) {
             callback({
               err: true
             });
           }
         },
         container: viewContainer});

       db.relations.getById = function() {
         return {
           get: function(key) {
             if ('endpoints' === key) {
               return [
                       [{}, {name: ''}]
               ];
             }
             return null;
           }
         };
       };

       view.render();

       view.confirmRemoved({
         preventDefault: function() {},

         // This is a mock object of the relation button
         target: {
           ancestor: function() {},
           get: function() {}
         }
       });
       view.remove_panel.footerNode.one('.btn-danger').simulate('click');
       view.remove_panel.destroy();

       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '1', 'The system didnt show the alert');

     });

});
<commit_msg>checkpoint<commit_after>'use strict';

describe('juju application notifications', function() {
  var Y, juju, models, views,
      applicationContainer,
      notificationsContainer,
      viewContainer,
      db,

      _setTimeout, _viewsHighlightRow;

  before(function() {
    Y = YUI(GlobalConfig).use([
      'juju-models',
      'juju-views',
      'juju-gui',
      'juju-env',
      'juju-tests-utils',
      'node-event-simulate'],
    function(Y) {
      juju = Y.namespace('juju');
      models = Y.namespace('juju.models');
      views = Y.namespace('juju.views');
    });
  });

  beforeEach(function() {
    applicationContainer = Y.Node.create('
');
    applicationContainer.appendTo(Y.one(Y.one(document.body)));

    notificationsContainer = Y.Node.create('
');
    notificationsContainer.appendTo(applicationContainer);

    viewContainer = Y.Node.create('
');
    viewContainer.appendTo(applicationContainer);

    db = new models.Database();

    var notificationsView = new views.NotificationsView({
      container: notificationsContainer,
      app: {},
      env: {
        on: function() {},
        get: function(key) {
          if (key === 'connected') {
            return true;
          }
          return null;
        }
      },
      notifications: db.notifications
    });

    notificationsView.render();

    // The notifications.js delays the notification update.
    // We are going to avoid this timeout to make it possible to test
    // the notification callback synchronously.
    _setTimeout = window.setTimeout;
    window.setTimeout = function(callback) {
      callback();
    };

    // We skip this part because we have no row to highlight
    _viewsHighlightRow = views.highlightRow;
    views.highlightRow = function() {};

  });

  afterEach(function() {
    applicationContainer.remove(true);
    window.setTimeout = _setTimeout;
    views.highlightRow = _viewsHighlightRow;
  });

  it('should show notification for "add_unit" and "remove_units" exceptions' +
      ' (service view)', function() {
       var view = new views.service({
         container: viewContainer,
         app: {
           getModelURL: function() {
             return 'my url';
           }
         },
         db: db,
         env: {
           add_unit: function(serviceId, delta, callback) {
             callback({
               err: true
             });
           },
           remove_units: function(param, callback) {
             callback({
               err: true
             });
           }
         },
         model: {
           getAttrs: function() {},
           get: function(key) {
             if ('unit_count' === key) {
               return 2;
             }
             return null;
           }
         },
         querystring: {}
       }).render();

       db.units.get_units_for_service = function() {
         return [{
           id: 1
         }];
       };

       view._modifyUnits(3);
       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '1', 'The system didnt show the alert');

       view._modifyUnits(1);
       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '2', 'The system didnt show the alert');

     });

  it('should show notification for "remove_units" exceptions' +
      ' (unit view)', function() {
       var view = new views.unit({
         container: viewContainer,
         app: {
           getModelURL: function() {
             return 'my url';
           }
         },
         db: db,
         env: {
           remove_units: function(param, callback) {
             callback({
               err: true,
               unit_names: ['aaa']
             });
           }
         },
         unit: {},
         querystring: {}
       });

       // Used my unit.js inside the "render" function
       db.services.getById = function() {
         // Mock service
         return {
           get: function(key) {
             if (key === 'loaded') {
               return true;
             }
             return null;
           }
         };
       };

       view.render();

       view.confirmRemoved({
         preventDefault: function() {}
       });

       view.remove_panel.footerNode.one('.btn-danger').simulate('click');
       view.remove_panel.destroy();

       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '1', 'The system didnt show the alert');
     });

  it('should show notification for "add_relation" and "remove_relation"' +
      ' exceptions (environment view)', function() {
       var view = new views.environment({
         db: db,
         container: viewContainer}).render();

       view.service_click_actions._doAddRelationCallback.apply(view, [{
         err: true
       }]);

       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '1', 'The system didnt show the alert');

       view._doRemoveRelationCallback.apply({
         scope: view,
         view: {
           removeSVGClass: function() {}
         },
         confirmButton: {
           set: function() {}
         }
       }, [{
         err: true
       }]);

       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '2', 'The system didnt show the alert');
     });

  it('should show notification for "add_relation" and "destroy_service"' +
      ' exceptions (environment view)', function() {
       var view = new views.environment({
         db: db,
         destroy_service: {
           get: function() {}
         },
         env: {
           destroy_service: function(service, callback) {
             callback({err: true});
           }
         },
         container: viewContainer}).render();

       view.service_click_actions._doAddRelationCallback.apply(view, [{
         err: true
       }]);

       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '1', 'The system didnt show the alert');

       view.service_click_actions.destroyService.apply(
           view.service_click_actions, [
         // Fake m object
         {},

         // Fake context object
         {},

         view,

         // Fake btn object
         {set: function() {}}
           ]);

       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '2', 'The system didnt show the alert');
     });

  it('should show notification for "get_service" exceptions' +
      ' (service constraints view)', function() {

       var view = new views.service_constraints({
         db: db,
         model: {
           getAttrs: function() {},
           get: function(key) {
             if ('constraints' === key) {
               return {};
             }
             return null;
           }
         },
         env: {
           set_constraints: function(id, values, callback) {
             callback({
               err: true
             });
           }
         },
         container: viewContainer}).render();

       view.updateConstraints();

       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '1', 'The system didnt show the alert');

     });

  it('should show notification for "get_service", "expose" and "unexpose"' +
      ' exceptions (service config view)', function() {

       var view = new views.service_config({
         db: db,
         app: {
           getModelURL: function() {}
         },
         model: {
           getAttrs: function() {},
           get: function(key) {
             if ('loaded' === key) {
               return true;
             }
             if ('config' === key) {
               return {};
             }
             return null;
           }
         },
         env: {
           set_config: function(id, newValues, callback) {
             callback({
               err: true
             });
           },
           expose: function(id, callback) {
             callback({
               err: true
             });
           },
           unexpose: function(id, callback) {
             callback({
               err: true
             });
           }
         },
         container: viewContainer});

       db.charms.getById = function() {
         return {
           getAttrs: function() {},
           get: function(key) {
             if ('config' === key) {
               return {};
             }
             return null;
           }
         };
       };

       view.render();

       view.saveConfig();

       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '1', 'The system didnt show the alert');

       view.exposeService();

       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '2', 'The system didnt show the alert');

       view.unexposeService();

       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '3', 'The system didnt show the alert');
     });

  it('should show notification for "remove_relation"' +
      ' exceptions (service relations view)', function() {

       var view = new views.service_relations({
         db: db,
         app: {
           getModelURL: function() {}
         },
         env: {
           remove_relation: function(id, newValues, callback) {
             callback({
               err: true
             });
           }
         },
         container: viewContainer});

       db.relations.getById = function() {
         return {
           get: function(key) {
             if ('endpoints' === key) {
               return [
                       [{}, {name: ''}]
               ];
             }
             return null;
           }
         };
       };

       view.render();

       view.confirmRemoved({
         preventDefault: function() {},

         // This is a mock object of the relation button
         target: {
           ancestor: function() {},
           get: function() {}
         }
       });
       view.remove_panel.footerNode.one('.btn-danger').simulate('click');
       view.remove_panel.destroy();

       assert.equal(
           applicationContainer.one('#notify-indicator').getHTML().trim(),
           '1', 'The system didnt show the alert');

     });

});
<|endoftext|>


<commit_before>import Ember from "ember";

export default {
  name: 'liquid-fire-docs',

  initialize: function(container) {
    // This lets us work with both Ember 1.7 (where 'select' is not
    // registered on the container) and Ember 1.8 (where you get a
    // deprecation warning for not using 'select' from the container).
    if (!container.lookupFactory('view:select')){
      container.register('view:select', Ember.Select);
    }
  }
};
<commit_msg>drop old 1.7 compatibility code that breaks on canary<commit_after><|endoftext|>


<commit_before>const Gio = imports.gi.Gio;
const StyleKnobGenerator = imports.app.compat.styleKnobGenerator;
const Utils = imports.tests.utils;

const TEST_CONTENT_DIR = Utils.get_test_content_srcdir();

let style_knobs_a = {
    'tab_button': {
        'module-background-color': '#7DA443',
    },
    'section_page': {
        'title-font-family': "'Marcellus SC'",
        'title-font-weight': 'bold',
    },
    'no_search_results_page': {
        'title-font-family': "'Marcellus SC'",
        'title-font-weight': 'bold',
    },
    'section_card': {
        'module-background': '#E8E4E1',
        'title-color': '#5A8715',
        'title-font-family': "'Marcellus SC'",
        'title-font-weight': 'bold',
    },
    'article_card': {
        'module-background': '#E8E4E1',
        'title-color': '#5A8715',
        'title-font-family': "'Marcellus SC'",
        'title-font-weight': 'bold',
    }
}

let style_knobs_b = {
    'section_card': {
        'title-color': '#98B8FF',
        'hover-color': '#4573D9',
        'title-font-size': '2.2em',
        'title-padding': '.7em 0em',
        'title-font-family': "'Amatic SC'",
        'title-font-weight': 'bold',
    },
    'article_card': {
        'title-color': '#98B8FF',
        'hover-color': '#4573D9',
    },
    'section_page': {
        'title-font-size': '9.0em',
        'title-padding': '0.5em 0.0em 0.5em 0.7em',
        'title-font-family': "'Amatic SC'",
        'title-font-weight': 'bold',
    },
    'no_search_results_page': {
        'title-font-size': '10.72em',
        'title-font-family': "'Amatic SC'",
        'title-font-weight': 'bold',
    },
};

let style_knobs_reader = {
  'overview_page': {
    'module-background': 'rgba(51, 51, 51, 0.30)',
    'module-background-image': 'linear-gradient(-180deg, rgba(176, 176, 176, 0.20) 1%, alpha(black, 0.30) 100%)',
  },
  'snippet0': {
    'module-font-family': 'ABeeZee',
    'module-font-size': '1em',
    'module-color': '#F2F2F2',
    'title-font-family': 'Abel',
    'title-color': '#E05430',
    'title-font-size': '2.125em',
  },
  'snippet1': {
    'module-font-family': 'ABeeZee',
    'module-font-size': '1em',
    'module-color': '#F2F2F2',
    'title-font-family': 'Roboto',
    'title-color': '#FA770F',
    'title-font-size': '2em',
  },
  'snippet2': {
    'module-font-family': 'ABeeZee',
    'module-font-size': '1em',
    'module-color': '#F2F2F2',
    'title-font-family': 'Dosis',
    'title-color': '#F7C449',
    'title-font-size': '2.25em',
  },
  'back_cover': {
    'module-font-family': 'ABeeZee',
    'module-font-size': '1em',
    'module-color': '#F2F2F2',
    'title-font-family': 'Abel',
    'title-color': '#E05430',
    'title-font-size': '2.125em',
  },
  'article_page0': {
    'title-color': '#D95430',
    'title-font-family': 'Abel',
    'title-font-size': '3em',
    'module-color': '#8E421A',
    'module-font-family': 'Roboto',
    'module-font-size': '0.88em',
    'module-font-style': 'italic',
    'title-background-color': '#D95420',
  },
  'article_page1': {
    'title-color': '#CD6E34',
    'title-font-family': 'Lato',
    'title-font-size': '3em',
    'module-color': '#924C22',
    'module-font-family': 'Roboto',
    'module-font-size': '0.75em',
    'module-font-weight': '800',
  },
  'article_page2': {
    'title-color': '#DFAA29',
    'title-font-family': 'Dosis',
    'title-font-size': '3.38em',
    'title-font-weight': '200',
    'title-border-left': '2px solid #F7C464',
    'title-padding-left': '20px',
    'module-color': '#B9922F',
    'module-font-family': 'Roboto',
    'module-font-size': '0.81em',
    'module-font-style': 'italic',
  },
  'reader_card0': {
    'title-color': '#d95430',
    'title-font-family': 'Abel',
    'module-color': '#8e421a',
    'module-font-family': 'Roboto',
    'module-font-style': 'italic',
    'title-background-color': '#D95420',
  },
  'reader_card1': {
    'title-color': '#cd6e34',
    'title-font-family': 'Lato',
    'module-color': '#924c22',
    'module-font-family': 'Roboto',
    'module-font-weight': '800',
  },
  'reader_card2': {
    'title-color': '#dfaa29',
    'title-font-family': 'Dosis',
    'title-font-weight': '200',
    'module-color': '#b9922f',
    'module-font-family': 'Roboto',
    'module-font-style': 'italic',
  }
}

describe('StyleKnobGenerator', function () {
    let css_overrides_a;
    let css_overrides_b;
    let css_overrides_reader;

    beforeEach(function () {
        let file_a = Gio.File.new_for_path(TEST_CONTENT_DIR + 'overrides-a.css');
        css_overrides_a = (file_a.load_contents(null)[1]).toString();
        let file_b = Gio.File.new_for_path(TEST_CONTENT_DIR + 'overrides-b.css');
        css_overrides_b = (file_b.load_contents(null)[1]).toString();
        let file_reader = Gio.File.new_for_path(TEST_CONTENT_DIR + 'overrides-reader.css');
        css_overrides_reader = (file_reader.load_contents(null)[1]).toString();
    });

    it('handles template A overrides', function () {
        let style_knobs = StyleKnobGenerator.get_knobs_from_css(css_overrides_a, 'A');
        expect(style_knobs).toEqual(style_knobs_a);
    });

    it('handles template B overrides', function () {
        let style_knobs = StyleKnobGenerator.get_knobs_from_css(css_overrides_b, 'B');
        expect(style_knobs).toEqual(style_knobs_b);
    });

    it('handles reader app overrides', function () {
        let style_knobs = StyleKnobGenerator.get_knobs_from_css(css_overrides_reader, 'reader');
        expect(style_knobs).toEqual(style_knobs_reader);
    });
});
<commit_msg>testStyleKnobGenerator: fix A/B tests to account for search page [endlessm/eos-sdk#3551]<commit_after>const Gio = imports.gi.Gio;
const StyleKnobGenerator = imports.app.compat.styleKnobGenerator;
const Utils = imports.tests.utils;

const TEST_CONTENT_DIR = Utils.get_test_content_srcdir();

let style_knobs_a = {
    'tab_button': {
        'module-background-color': '#7DA443',
    },
    'section_page': {
        'title-font-family': "'Marcellus SC'",
        'title-font-weight': 'bold',
    },
    'search_page': {
        'title-font-family': "'Marcellus SC'",
        'title-font-weight': 'bold',
    },
    'no_search_results_page': {
        'title-font-family': "'Marcellus SC'",
        'title-font-weight': 'bold',
    },
    'section_card': {
        'module-background': '#E8E4E1',
        'title-color': '#5A8715',
        'title-font-family': "'Marcellus SC'",
        'title-font-weight': 'bold',
    },
    'article_card': {
        'module-background': '#E8E4E1',
        'title-color': '#5A8715',
        'title-font-family': "'Marcellus SC'",
        'title-font-weight': 'bold',
    }
}

let style_knobs_b = {
    'section_card': {
        'title-color': '#98B8FF',
        'hover-color': '#4573D9',
        'title-font-size': '2.2em',
        'title-padding': '.7em 0em',
        'title-font-family': "'Amatic SC'",
        'title-font-weight': 'bold',
    },
    'article_card': {
        'title-color': '#98B8FF',
        'hover-color': '#4573D9',
    },
    'section_page': {
        'title-font-size': '9.0em',
        'title-padding': '0.5em 0.0em 0.5em 0.7em',
        'title-font-family': "'Amatic SC'",
        'title-font-weight': 'bold',
    },
    'search_page': {
        'title-font-size': '9.0em',
        'title-padding': '0.5em 0.0em 0.5em 0.7em',
        'title-font-family': "'Amatic SC'",
        'title-font-weight': 'bold',
    },
    'no_search_results_page': {
        'title-font-size': '10.72em',
        'title-font-family': "'Amatic SC'",
        'title-font-weight': 'bold',
    },
};

let style_knobs_reader = {
  'overview_page': {
    'module-background': 'rgba(51, 51, 51, 0.30)',
    'module-background-image': 'linear-gradient(-180deg, rgba(176, 176, 176, 0.20) 1%, alpha(black, 0.30) 100%)',
  },
  'snippet0': {
    'module-font-family': 'ABeeZee',
    'module-font-size': '1em',
    'module-color': '#F2F2F2',
    'title-font-family': 'Abel',
    'title-color': '#E05430',
    'title-font-size': '2.125em',
  },
  'snippet1': {
    'module-font-family': 'ABeeZee',
    'module-font-size': '1em',
    'module-color': '#F2F2F2',
    'title-font-family': 'Roboto',
    'title-color': '#FA770F',
    'title-font-size': '2em',
  },
  'snippet2': {
    'module-font-family': 'ABeeZee',
    'module-font-size': '1em',
    'module-color': '#F2F2F2',
    'title-font-family': 'Dosis',
    'title-color': '#F7C449',
    'title-font-size': '2.25em',
  },
  'back_cover': {
    'module-font-family': 'ABeeZee',
    'module-font-size': '1em',
    'module-color': '#F2F2F2',
    'title-font-family': 'Abel',
    'title-color': '#E05430',
    'title-font-size': '2.125em',
  },
  'article_page0': {
    'title-color': '#D95430',
    'title-font-family': 'Abel',
    'title-font-size': '3em',
    'module-color': '#8E421A',
    'module-font-family': 'Roboto',
    'module-font-size': '0.88em',
    'module-font-style': 'italic',
    'title-background-color': '#D95420',
  },
  'article_page1': {
    'title-color': '#CD6E34',
    'title-font-family': 'Lato',
    'title-font-size': '3em',
    'module-color': '#924C22',
    'module-font-family': 'Roboto',
    'module-font-size': '0.75em',
    'module-font-weight': '800',
  },
  'article_page2': {
    'title-color': '#DFAA29',
    'title-font-family': 'Dosis',
    'title-font-size': '3.38em',
    'title-font-weight': '200',
    'title-border-left': '2px solid #F7C464',
    'title-padding-left': '20px',
    'module-color': '#B9922F',
    'module-font-family': 'Roboto',
    'module-font-size': '0.81em',
    'module-font-style': 'italic',
  },
  'reader_card0': {
    'title-color': '#d95430',
    'title-font-family': 'Abel',
    'module-color': '#8e421a',
    'module-font-family': 'Roboto',
    'module-font-style': 'italic',
    'title-background-color': '#D95420',
  },
  'reader_card1': {
    'title-color': '#cd6e34',
    'title-font-family': 'Lato',
    'module-color': '#924c22',
    'module-font-family': 'Roboto',
    'module-font-weight': '800',
  },
  'reader_card2': {
    'title-color': '#dfaa29',
    'title-font-family': 'Dosis',
    'title-font-weight': '200',
    'module-color': '#b9922f',
    'module-font-family': 'Roboto',
    'module-font-style': 'italic',
  }
}

describe('StyleKnobGenerator', function () {
    let css_overrides_a;
    let css_overrides_b;
    let css_overrides_reader;

    beforeEach(function () {
        let file_a = Gio.File.new_for_path(TEST_CONTENT_DIR + 'overrides-a.css');
        css_overrides_a = (file_a.load_contents(null)[1]).toString();
        let file_b = Gio.File.new_for_path(TEST_CONTENT_DIR + 'overrides-b.css');
        css_overrides_b = (file_b.load_contents(null)[1]).toString();
        let file_reader = Gio.File.new_for_path(TEST_CONTENT_DIR + 'overrides-reader.css');
        css_overrides_reader = (file_reader.load_contents(null)[1]).toString();
    });

    it('handles template A overrides', function () {
        let style_knobs = StyleKnobGenerator.get_knobs_from_css(css_overrides_a, 'A');
        expect(style_knobs).toEqual(style_knobs_a);
    });

    it('handles template B overrides', function () {
        let style_knobs = StyleKnobGenerator.get_knobs_from_css(css_overrides_b, 'B');
        expect(style_knobs).toEqual(style_knobs_b);
    });

    it('handles reader app overrides', function () {
        let style_knobs = StyleKnobGenerator.get_knobs_from_css(css_overrides_reader, 'reader');
        expect(style_knobs).toEqual(style_knobs_reader);
    });
});
<|endoftext|>


<commit_before>import Ember from 'ember';
import {
  moduleForModel,
  test
} from 'ember-qunit';
import modelList from '../../helpers/model-list';

const { run } = Ember;

moduleForModel('program-year', 'Unit | Model | ProgramYear', {
  needs: modelList
});

test('it exists', function(assert) {
  let model = this.subject();
  // let store = this.store();
  assert.ok(!!model);
});

test('academic year string', function(assert) {
  let model = this.subject();
  Ember.run(function(){
    model.set('startYear', 2000);
    assert.equal(model.get('academicYear'), '2000 - 2001');
  });
});

test('classOf string', function(assert) {
  assert.expect(3);
  let model = this.subject();
  var store = model.store;
  Ember.run(function(){
    let program = store.createRecord('program', {id:99, duration:1});
    model.set('program', program);
    model.set('startYear', 2000);
    assert.equal(model.get('classOfYear'), '2001');
    program.set('duration', 5);
    assert.equal(model.get('classOfYear'), '2005');
    model.set('startYear', 2001);
    assert.equal(model.get('classOfYear'), '2006');
  });
});

test('competency domains', async function(assert) {
  assert.expect(4);
  let programYear = this.subject();
  let store = this.store();
  run ( async () => {
    let subCompetency1 = store.createRecord('competency', { id: 1, title: 'Bubbles' });
    let subCompetency2 = store.createRecord('competency', { id: 2, title: 'Ricky' });
    let subCompetency3 = store.createRecord('competency', { id: 3, title: 'Julian' });
    let domain1 = store.createRecord('competency', { id: 4, title: 'Trevor', children: [ subCompetency1, subCompetency2 ] });
    let domain2 = store.createRecord('competency', { id: 5, title: 'Corey' });
    let domain3 = store.createRecord('competency', { id: 6, title: 'Cyrus', children: [ subCompetency3 ] });

    programYear.get('competencies').pushObjects([ subCompetency3, domain2, subCompetency1, subCompetency2 ]);

    let domains = await programYear.get('competencyDomains');
    assert.equal(domains.length, 3);
    assert.equal(domains[0].get('content'), domain2);
    assert.equal(domains[1].get('content'), domain3);
    assert.equal(domains[2].get('content'), domain1);
  });
});
<commit_msg>fleshed out test coverage.<commit_after>import Ember from 'ember';
import {
  moduleForModel,
  test
} from 'ember-qunit';
import modelList from '../../helpers/model-list';

const { run } = Ember;

moduleForModel('program-year', 'Unit | Model | ProgramYear', {
  needs: modelList
});

test('it exists', function(assert) {
  let model = this.subject();
  // let store = this.store();
  assert.ok(!!model);
});

test('academic year string', function(assert) {
  let model = this.subject();
  Ember.run(function(){
    model.set('startYear', 2000);
    assert.equal(model.get('academicYear'), '2000 - 2001');
  });
});

test('classOf string', function(assert) {
  assert.expect(3);
  let model = this.subject();
  var store = model.store;
  Ember.run(function(){
    let program = store.createRecord('program', {id:99, duration:1});
    model.set('program', program);
    model.set('startYear', 2000);
    assert.equal(model.get('classOfYear'), '2001');
    program.set('duration', 5);
    assert.equal(model.get('classOfYear'), '2005');
    model.set('startYear', 2001);
    assert.equal(model.get('classOfYear'), '2006');
  });
});

test('competency domains', async function(assert) {
  assert.expect(10);
  let programYear = this.subject();
  let store = this.store();
  run ( async () => {
    let subCompetency1 = store.createRecord('competency', { id: 1, title: 'Ricky' });
    let subCompetency2 = store.createRecord('competency', { id: 2, title: 'Bubbles' });
    let subCompetency3 = store.createRecord('competency', { id: 3, title: 'Julian' });
    let domain1 = store.createRecord('competency', { id: 4, title: 'Trevor', children: [ subCompetency1, subCompetency2 ] });
    let domain2 = store.createRecord('competency', { id: 5, title: 'Corey' });
    let domain3 = store.createRecord('competency', { id: 6, title: 'Cyrus', children: [ subCompetency3 ] });

    programYear.get('competencies').pushObjects([ subCompetency3, domain2, subCompetency1, subCompetency2 ]);

    let domains = await programYear.get('competencyDomains');
    assert.equal(domains.length, 3);
    assert.equal(domains[0].get('content'), domain2);
    assert.equal(domains[1].get('content'), domain3);
    assert.equal(domains[2].get('content'), domain1);
    assert.equal(domains[0].get('subCompetencies').length, 0);
    assert.equal(domains[1].get('subCompetencies').length, 1);
    assert.ok(domains[1].get('subCompetencies').includes(subCompetency3));
    assert.equal(domains[2].get('subCompetencies').length, 2);
    assert.ok(domains[2].get('subCompetencies').includes(subCompetency1));
    assert.ok(domains[2].get('subCompetencies').includes(subCompetency2));
  });
});
<|endoftext|>


<commit_before>const crypto = require('crypto');
const express = require('express');
const bodyParser = require('body-parser');

const assert = require('assert');

const testAPI = require('../test-api');
const confConsts = require('../../backend/common/conf-constants');
const confMgmt = require('../../backend/api/conf-mgmt');
const security = require('../../backend/api/security');
const securityConsts = require('../../backend/common/security-constants');
const storageUtils = require('../../backend/api/storage-utils');

const webhooks = require('../../backend/api/webhooks');

// --------------------------------------------------------------------------------
// tests
// --------------------------------------------------------------------------------
function timeout() {
	return new Promise((resolve, reject) => {
		setTimeout(_ => {
			resolve();
		}, 2500);
	});
}

function runTests() {
	// adding a webhook
	const existingWebhooks = confMgmt.getCached(confConsts.CONF_FILES.WEBHOOKS);
	existingWebhooks.push({
		id: 1,
		relativePath: '*',
		url: 'http://localhost:8181',
		isDisabled: false
	});
	confMgmt.save(existingWebhooks, confConsts.CONF_FILES.WEBHOOKS)
		.then(storageUtils.saveFileToStorage('/test.js', '// hello'));

	return Promise.resolve();
}

// --------------------------------------------------------------------------------
// webhooks app
// --------------------------------------------------------------------------------

const PORT = 8181;
const SECRET = 'nexl';
let webServer;

const app = express();
app.use(bodyParser.json());

function handleWebhook(req, res, next) {
	const payload = JSON.stringify(req.body);
	if (!payload) {
		return next('Request body empty')
	}

	const checksum = req.get(webhooks.SIG_HEADER);
	if (!checksum) {
		return next();
	}

	const hmac = crypto.createHmac('sha1', SECRET);
	const digest = 'sha1=' + hmac.update(payload).digest('hex');
	if (!checksum || !digest || checksum !== digest) {
		return next(`Request body digest (${digest}) did not match ${webhooks.SIG_HEADER} (${checksum})`)
	}

	return next();
}

app.post('/', handleWebhook, function (req, res) {
	res.status(200).send('Request body was signed')
});

app.use((err, req, res, next) => {
	if (err) {
		console.error(err);
		res.status(403).send('Webhook failed !!!');
	}
});

function startWebhooksClient() {
	return new Promise((resolve, reject) => {
		webServer = app.listen(PORT, 'localhost', () => {
			resolve();
		}).on('error', err => {
			console.log(err);
			reject(err);
		});
	});
}

// --------------------------------------------------------------------------------
// nexl app
// --------------------------------------------------------------------------------

function init(predefinedNexlJSFIlesDir, tmpNexlJSFilesDir) {
	return Promise.resolve();
}

function run() {
	return startWebhooksClient()
		.then(runTests);
}

function done() {
	return timeout().then(_ => {
		if (webServer) {
			webServer.close();
		}
		return Promise.resolve();
	});
}

testAPI.startNexlApp(init, run, done);

/*
Tests:

*
/common
/common/
/common*
!/common
*.js
with right secret
with wrong secret
all actions for same file

 */<commit_msg>- working on webhooks<commit_after>const crypto = require('crypto');
const express = require('express');
const bodyParser = require('body-parser');

const assert = require('assert');

const testAPI = require('../test-api');
const confConsts = require('../../backend/common/conf-constants');
const confMgmt = require('../../backend/api/conf-mgmt');
const security = require('../../backend/api/security');
const securityConsts = require('../../backend/common/security-constants');
const storageUtils = require('../../backend/api/storage-utils');

const webhooks = require('../../backend/api/webhooks');

// --------------------------------------------------------------------------------
// tests
// --------------------------------------------------------------------------------
function timeout() {
	return new Promise((resolve, reject) => {
		setTimeout(_ => {
			resolve();
		}, 2500);
	});
}

function runTests() {
	// adding a webhook
	const existingWebhooks = confMgmt.getCached(confConsts.CONF_FILES.WEBHOOKS);
	existingWebhooks.push({
		id: 1,
		relativePath: '*',
		url: `http://localhost:${PORT}`,
		isDisabled: false
	});
	confMgmt.save(existingWebhooks, confConsts.CONF_FILES.WEBHOOKS)
		.then(storageUtils.saveFileToStorage('/test.js', '// hello'));

	return Promise.resolve();
}

// --------------------------------------------------------------------------------
// webhooks app
// --------------------------------------------------------------------------------

const PORT = 8181;
const SECRET = 'nexl';
let webServer;

const app = express();
app.use(bodyParser.json());

function handleWebhook(req, res, next) {
	const payload = JSON.stringify(req.body);
	if (!payload) {
		return next('Request body empty')
	}

	const checksum = req.get(webhooks.SIG_HEADER);
	if (!checksum) {
		return next();
	}

	const hmac = crypto.createHmac('sha1', SECRET);
	const digest = 'sha1=' + hmac.update(payload).digest('hex');
	if (!checksum || !digest || checksum !== digest) {
		return next(`Request body digest (${digest}) did not match ${webhooks.SIG_HEADER} (${checksum})`)
	}

	return next();
}

app.post('/', handleWebhook, function (req, res) {
	res.status(200).send('Request body was signed')
});

app.use((err, req, res, next) => {
	if (err) {
		console.error(err);
		res.status(403).send('Webhook failed !!!');
	}
});

function startWebhooksClient() {
	return new Promise((resolve, reject) => {
		webServer = app.listen(PORT, 'localhost', () => {
			resolve();
		}).on('error', err => {
			console.log(err);
			reject(err);
		});
	});
}

// --------------------------------------------------------------------------------
// nexl app
// --------------------------------------------------------------------------------

function init(predefinedNexlJSFIlesDir, tmpNexlJSFilesDir) {
	return Promise.resolve();
}

function run() {
	return startWebhooksClient()
		.then(runTests);
}

function done() {
	return timeout().then(_ => {
		if (webServer) {
			webServer.close();
		}
		return Promise.resolve();
	});
}

testAPI.startNexlApp(init, run, done);

/*
Tests:

*
/common
/common/
/common*
!/common
*.js
with right secret
with wrong secret
all actions for same file

 */<|endoftext|>