<commit_before>/**
 * @license ng-notify v0.4.0
 * http://matowens.github.io/ng-notify
 * (c) 2014 MIT License, matowens.com
 */
(function() {
    'use strict';

    /**
     * @description
     *
     * This module provides any AngularJS application with a simple, lightweight
     * system for displaying notifications of varying degree to it's users.
     *
     */
     var module = angular.module('ngNotify', []);

     module.provider('ngNotify', function() {

        this.$get = ['$document', '$compile', '$rootScope', '$timeout', '$interval',

            function($document, $compile, $rootScope, $timeout, $interval) {

                // Defaults...

                var options = {
                    theme: 'pure',
                    position: 'top',
                    duration: 3000,
                    type: 'info',
                    sticky: false
                };

                // Options...
                var userOpts = {};

                var themes = {
                    pure: '',
                    prime: 'ngn-prime',
                    pastel: 'ngn-pastel',
                    pitchy: 'ngn-pitchy'
                };

                var types = {
                    infoClass: 'ngn-info',
                    errorClass: 'ngn-error',
                    successClass: 'ngn-success',
                    warnClass: 'ngn-warn',
                    grimaceClass: 'ngn-grimace'
                };

                var positions = {
                    bottom: 'ngn-bottom',
                    top: 'ngn-top'
                };

                // Fade params...

                var notifyTimeout;
                var notifyInterval;

                // Template and scope...

                var notifyScope = $rootScope.$new();
                var tpl = $compile(
                    '
' +
                        // '×' +
                        '{{ ngNotify.notifyMessage }}' +
                    '
'
                )(notifyScope);

                $document.find('body').append(tpl);

                // Private methods...

                /**
                 * Sets what type of notification do display, eg, error, warning, etc.
                 *
                 * @param  {String} providedType - optional user provided type that will override our default value.
                 * @return {String}              - the type that will be assigned to this notification.
                 */
                var setType = function(providedType) {
                    var type = (providedType || options.type) + 'Class';
                    return types[type] || types.infoClass;
                };

                /**
                 * Sets the theme for a notification, eg, pure, pastel, etc.
                 *
                 * @param  {String} providedTheme - optional user provided theme that will override our default value.
                 * @return {String}               - the theme that will be assigned to this notification.
                 */
                var setTheme = function(providedTheme) {
                    var theme = providedTheme || options.theme;
                    return themes[theme] || themes.pure;
                };

                /**
                 * Sets the position of the notification, eg, top or bottom.
                 *
                 * @param  {String} providedPosition - optional user provided position that will override our default value.
                 * @return {String}                  - the position that will be assigned to this notification.
                 */
                var setPosition = function(providedPosition) {
                    var position = providedPosition || options.position;
                    return positions[position] || positions.bottom;
                };

                /**
                 * Sets how long (in ms) to display the notification for.
                 *
                 * @param  {Integer} providedDuration - optional user provided number of ms a fade lasts.
                 * @return {Integer}                  - the number of ms a fade on this notification will last.
                 */
                var setDuration = function(providedDuration) {
                    var duration = providedDuration || options.duration;
                    return angular.isNumber(duration) ? duration : 3500;
                };

                /**
                 * Sets our notification's sticky state, forcing the user to dismiss it when enabled.
                 *
                 * @param {Bool} providedSticky - boolean on whether or not sticky state should be enabled.
                 */
                var setSticky = function(providedSticky) {
                    var sticky = providedSticky || options.sticky;
                    return sticky ? true : false;
                };

                /**
                 * Resets our notification classes and message.
                 */
                var notifyReset = function() {
                    notifyScope.ngNotify = {
                        notifyClass: '',
                        notifyMessage: ''
                    };
                };

                // Pure JS fade functionality, support for IE8 included...

                /**
                 * Triggers our constructor to add our fade prototypes to our element.
                 *
                 * @param  {Object} el - an element generated by our own template and bound to it's own scope.
                 * @return {Object}    - our element along with new fade prototype methods.
                 */
                var fadeLib = function(el) {
                    return new fadeLib.fn(el);
                };

                /**
                 * Our constructor that will allow us to invoke a fade on our element.
                 *
                 * @param {Object} el - an element generated by our own template and bound to it's own scope.
                 */
                fadeLib.fn = function(el) {
                    this.el = el;
                };

                /**
                 * Handles the fading functionality and the duration for each fade.
                 *
                 * @param {Integer}  mode     - used to trigger fade in or out, adds or subtracts opacity until visible or hidden.
                 * @param {Integer   opacity  - initial opacity for our element.
                 * @param {Integer}  duration - how long the fade should take to complete, in ms.
                 * @param {Function} callback - function to invoke once our fade is complete.
                 */
                fadeLib.fn.prototype._fade = function(mode, opacity, duration, callback) {

                    var interval = 25;
                    var gap = interval / duration;
                    var el = this.el;

                    el.css('opacity', opacity);

                    var func = function() {

                        opacity = opacity + mode * gap;

                        el.css('filter', 'progid:DXImageTransform.Microsoft.Alpha(Opacity=' + opacity * 100 + ')'); // IE8
                        el.css('opacity', opacity);

                        if (opacity <= 0 || opacity >= 1) {
                            $interval.cancel(notifyInterval);

                            if (opacity <= 0) {
                                el.css('display', 'none');
                            }

                            if (callback) {
                                callback();
                            }
                        }
                    };

                    notifyInterval = $interval(func, interval);
                };

                /**
                 * Triggers a fade in, opacity from 0 to 1.
                 *
                 * @param  {Integer}  duration - how long the fade should take to complete, in ms.
                 * @param  {Function} callback - function to invoke once fade has completed.
                 */
                fadeLib.fn.prototype.fadeIn = function(duration, callback) {
                    this.el.css('filter', 'progid:DXImageTransform.Microsoft.Alpha(Opacity=0)');
                    this.el.css('display', 'block');
                    this._fade(1, 0, duration, callback);
                };

                /**
                 * Triggers a fade out, opacity from 1 to 0.
                 *
                 * @param  {Integer}  duration - how long the fade should take to complete, in ms.
                 * @param  {Function} callback - function to invoke once fade has completed.
                 */
                fadeLib.fn.prototype.fadeOut = function(duration, callback) {
                    this._fade(-1, 1, duration, callback);
                };

                /**
                 * Dismisses our notification when called, attached to scope for ngCLick event to trigger.
                 *
                 */
                notifyScope.dismiss = function() {
                    el.el[0].classList.remove(setPosition(userOpts.position));
                    $timeout(function() {
                        notifyReset();
                    }, 400);
                };

                /**
                 * Our template bound to it's own personal scope and receiving our fade protoype functions.
                 *
                 * @type {Object}
                 */
                var el = fadeLib(tpl);

                /**
                 * Our primary object containing all public API methods and allows for all our functionality to be invoked.
                 *
                 * @type {Object}
                 */
                var notifyObject = {

                    /**
                     * Merges our user specified options with our default set of options.
                     *
                     * @param {Object} params - object of user provided options to configure notifications.
                     */
                    config: function(params) {
                        params = params || {};
                        angular.extend(options, params);
                    },

                    /**
                     * Sets, configures and displays each notification.
                     *
                     * @param {String}             message - the message our notification will display to the user.
                     * @param {String|Object|null} userOpt - optional parameter that contains the type or an object of options used to configure this notification.
                     */
                    set: function(message, userOpt) {

                        if (!message) {
                            return;
                        }

                        $interval.cancel(notifyInterval);
                        $timeout.cancel(notifyTimeout);

                        if (typeof userOpt === 'object') {
                            userOpts = {
                                type: userOpt.type || undefined,
                                theme: userOpt.theme || undefined,
                                position: userOpt.position || undefined,
                                duration: userOpt.duration || undefined,
                                sticky: userOpt.sticky || undefined
                            };
                        } else {
                            userOpts.type = userOpt;
                        }

                        var sticky = setSticky(userOpts.sticky);
                        var duration = setDuration(userOpts.duration);
                        var notifyClass = setType(userOpts.type) + ' ' +
                                          setTheme(userOpts.theme) + ' ';

                        notifyClass += setPosition(userOpts.position);
                        notifyClass += sticky ? ' ngn-sticky' : '';
                        // notifyClass += ' is-animated';

                        notifyScope.ngNotify = {
                            notifyClass: notifyClass,
                            notifyMessage: message
                        };

                        // el.fadeIn(200, function() {
                            if (!sticky) {
                                notifyTimeout = $timeout(function() {
                                    notifyScope.dismiss();
                                }, duration);
                            }
                        // });
                    },

                    /**
                     * Allows a developer to manually dismiss a notification that may be
                     * set to sticky, when the message is no longer warranted.
                     */
                    dismiss: function() {
                        notifyScope.dismiss();
                    },

                    // User customizations...

                    /**
                     * Adds a new, user specified theme to our notification system
                     * that they can then use throughout their application.
                     *
                     * @param {String} themeName  - the name for this new theme that will be used when applying it via configuration.
                     * @param {String} themeClass - the class that this theme will use when applying it's styles.
                     */
                    addTheme: function(themeName, themeClass) {
                        if (!themeName || !themeClass) { return; }
                        themes[themeName] = themeClass;
                    },

                    /**
                     * Adds a new, user specified notification type that they
                     * can then use throoughout their application.
                     *
                     * @param {String} typeName  - the name for this new type that will be used when applying it via configuration.
                     * @param {String} typeClass - the class that this type will use when applying it's styles.
                     */
                    addType: function(typeName, typeClass) {
                        if (!typeName || !typeClass) { return; }
                        types[typeName + 'Class'] = typeClass;
                    }

                };

                return notifyObject;
            }
        ];
     });
})();
<commit_msg>Remove fade dependency<commit_after>/**
 * @license ng-notify v0.4.0
 * http://matowens.github.io/ng-notify
 * (c) 2014 MIT License, matowens.com
 */
(function() {
    'use strict';

    /**
     * @description
     *
     * This module provides any AngularJS application with a simple, lightweight
     * system for displaying notifications of varying degree to it's users.
     *
     */
     var module = angular.module('ngNotify', []);

     module.provider('ngNotify', function() {

        this.$get = ['$document', '$compile', '$rootScope', '$timeout', '$interval',

            function($document, $compile, $rootScope, $timeout, $interval) {

                // Defaults...

                var options = {
                    theme: 'pure',
                    position: 'top',
                    duration: 3000,
                    type: 'info',
                    sticky: false
                };

                // Options...
                var userOpts = {};

                var themes = {
                    pure: '',
                    prime: 'ngn-prime',
                    pastel: 'ngn-pastel',
                    pitchy: 'ngn-pitchy'
                };

                var types = {
                    infoClass: 'ngn-info',
                    errorClass: 'ngn-error',
                    successClass: 'ngn-success',
                    warnClass: 'ngn-warn',
                    grimaceClass: 'ngn-grimace'
                };

                var positions = {
                    bottom: 'ngn-bottom',
                    top: 'ngn-top'
                };

                // Fade params...

                var notifyTimeout;
                var notifyInterval;

                // Template and scope...

                var notifyScope = $rootScope.$new();
                var tpl = $compile(
                    '
' +
                        // '×' +
                        '{{ ngNotify.notifyMessage }}' +
                    '
'
                )(notifyScope);

                $document.find('body').append(tpl);

                // Private methods...

                /**
                 * Sets what type of notification do display, eg, error, warning, etc.
                 *
                 * @param  {String} providedType - optional user provided type that will override our default value.
                 * @return {String}              - the type that will be assigned to this notification.
                 */
                var setType = function(providedType) {
                    var type = (providedType || options.type) + 'Class';
                    return types[type] || types.infoClass;
                };

                /**
                 * Sets the theme for a notification, eg, pure, pastel, etc.
                 *
                 * @param  {String} providedTheme - optional user provided theme that will override our default value.
                 * @return {String}               - the theme that will be assigned to this notification.
                 */
                var setTheme = function(providedTheme) {
                    var theme = providedTheme || options.theme;
                    return themes[theme] || themes.pure;
                };

                /**
                 * Sets the position of the notification, eg, top or bottom.
                 *
                 * @param  {String} providedPosition - optional user provided position that will override our default value.
                 * @return {String}                  - the position that will be assigned to this notification.
                 */
                var setPosition = function(providedPosition) {
                    var position = providedPosition || options.position;
                    return positions[position] || positions.bottom;
                };

                /**
                 * Sets how long (in ms) to display the notification for.
                 *
                 * @param  {Integer} providedDuration - optional user provided number of ms a fade lasts.
                 * @return {Integer}                  - the number of ms a fade on this notification will last.
                 */
                var setDuration = function(providedDuration) {
                    var duration = providedDuration || options.duration;
                    return angular.isNumber(duration) ? duration : 3500;
                };

                /**
                 * Sets our notification's sticky state, forcing the user to dismiss it when enabled.
                 *
                 * @param {Bool} providedSticky - boolean on whether or not sticky state should be enabled.
                 */
                var setSticky = function(providedSticky) {
                    var sticky = providedSticky || options.sticky;
                    return sticky ? true : false;
                };

                /**
                 * Resets our notification classes and message.
                 */
                var notifyReset = function() {
                    notifyScope.ngNotify = {
                        notifyClass: '',
                        notifyMessage: ''
                    };
                };

                /**
                 * Dismisses our notification when called, attached to scope for ngCLick event to trigger.
                 *
                 */
                notifyScope.dismiss = function() {
                    el[0].classList.remove(setPosition(userOpts.position));
                    $timeout(function() {
                        notifyReset();
                    }, 400);
                };

                var el = tpl;

                /**
                 * Our primary object containing all public API methods and allows for all our functionality to be invoked.
                 *
                 * @type {Object}
                 */
                var notifyObject = {

                    /**
                     * Merges our user specified options with our default set of options.
                     *
                     * @param {Object} params - object of user provided options to configure notifications.
                     */
                    config: function(params) {
                        params = params || {};
                        angular.extend(options, params);
                    },

                    /**
                     * Sets, configures and displays each notification.
                     *
                     * @param {String}             message - the message our notification will display to the user.
                     * @param {String|Object|null} userOpt - optional parameter that contains the type or an object of options used to configure this notification.
                     */
                    set: function(message, userOpt) {

                        if (!message) {
                            return;
                        }

                        $interval.cancel(notifyInterval);
                        $timeout.cancel(notifyTimeout);

                        if (typeof userOpt === 'object') {
                            userOpts = {
                                type: userOpt.type || undefined,
                                theme: userOpt.theme || undefined,
                                position: userOpt.position || undefined,
                                duration: userOpt.duration || undefined,
                                sticky: userOpt.sticky || undefined
                            };
                        } else {
                            userOpts.type = userOpt;
                        }

                        var sticky = setSticky(userOpts.sticky);
                        var duration = setDuration(userOpts.duration);
                        var notifyClass = setType(userOpts.type) + ' ' +
                                          setTheme(userOpts.theme) + ' ';

                        notifyClass += setPosition(userOpts.position);
                        notifyClass += sticky ? ' ngn-sticky' : '';
                        // notifyClass += ' is-animated';

                        notifyScope.ngNotify = {
                            notifyClass: notifyClass,
                            notifyMessage: message
                        };

                        // el.fadeIn(200, function() {
                            if (!sticky) {
                                notifyTimeout = $timeout(function() {
                                    notifyScope.dismiss();
                                }, duration);
                            }
                        // });
                    },

                    /**
                     * Allows a developer to manually dismiss a notification that may be
                     * set to sticky, when the message is no longer warranted.
                     */
                    dismiss: function() {
                        notifyScope.dismiss();
                    },

                    // User customizations...

                    /**
                     * Adds a new, user specified theme to our notification system
                     * that they can then use throughout their application.
                     *
                     * @param {String} themeName  - the name for this new theme that will be used when applying it via configuration.
                     * @param {String} themeClass - the class that this theme will use when applying it's styles.
                     */
                    addTheme: function(themeName, themeClass) {
                        if (!themeName || !themeClass) { return; }
                        themes[themeName] = themeClass;
                    },

                    /**
                     * Adds a new, user specified notification type that they
                     * can then use throoughout their application.
                     *
                     * @param {String} typeName  - the name for this new type that will be used when applying it via configuration.
                     * @param {String} typeClass - the class that this type will use when applying it's styles.
                     */
                    addType: function(typeName, typeClass) {
                        if (!typeName || !typeClass) { return; }
                        types[typeName + 'Class'] = typeClass;
                    }

                };

                return notifyObject;
            }
        ];
     });
})();
<|endoftext|>


<commit_before>/*yeoman-test*/
const helpers = require('yeoman-test');
const assert = require('yeoman-assert');
const fs = require('fs');
const fsextra = require('fs-extra');
const path = require('path');

const basedir = path.join(__dirname, '../generators/app');
const name = 'test projectName';
const description = 'test projectDesc';

describe('generator-phaser-h5', () => {
    describe('defaults', () => {
        it('creates expected files', () => {
            helpers.run(basedir)
                .then(checkAssets)
                .then(checkConfig)
                .then(checkScripts)
        });

        function checkConfig() {
            assert.file([
                'gulpfile.js',
                'package.json',
                '.jshintrc'
            ]);
        }

        function checkScripts() {
            assert.file([
                'src/assets/js/main.js',
                'src/assets/js/entities/Gesture.js',
                'src/assets/js/entities/MovieClip.js',
                'src/assets/js/entities/VideoConfig.js',
                'src/assets/js/states/boot.js',
                'src/assets/js/states/state1.js',
                'src/assets/js/states/preloader.js'
            ]);
        }

        function checkAssets() {
            assert.file([
                'src/index.html',
                'README.md',
                'LICENSE',
                'src/assets/css/css.css',
                'src/assets/img/favicon.ico'
            ]);
        }
    });
    describe('using options', () => {
        it('projectName, projectDesc', () => {
            helpers.run(basedir)
                .withPrompts({ projectName: name, projectDesc: description })
                .then(() => {
                    assert.fileContent([
                        ['package.json', `"name": ${JSON.stringify(name)}`],
                        ['package.json', `"description": ${JSON.stringify(description)}`]
                    ]);
                    assert.fileContent([
                        ['README.md', `# ${name}`],
                        ['README.md', `${description}`]
                    ]);
                })
        });
        it('projectLicense: MIT', () => {
            helpers.run(basedir)
                .withPrompts({ projectLicense: 'MIT' })
                .then(() => {
                    assert.file([
                        'LICENSE'
                    ]);
                })
        });
        it('projectLicense: Apache-2.0', () => {
            helpers.run(basedir)
                .withPrompts({ projectLicense: 'Apache-2.0' })
                .then(() => {
                    assert.file([
                        'LICENSE'
                    ]);
                })
        });
        it('projectLicense: GPL-3.0', () => {
            helpers.run(basedir)
                .withPrompts({ projectLicense: 'GPL-3.0' })
                .then(() => {
                    assert.file([
                        'LICENSE'
                    ]);
                })
        });
        it('projectLicense: Others', () => {
            helpers.run(basedir)
                .withPrompts({ projectLicense: 'Others' })
                .then(() => {
                    assert.file([
                        'LICENSE'
                    ]);
                })
        });
        it('projectSass: true', () => {
            helpers.run(basedir)
                .withPrompts({ projectSass: true })
                .then(() => {
                    assert.file([
                        'src/assets/css/sass.scss',
                        'gulpfile.js',
                        'package.json'
                    ]);
                })
        });
    });

});<commit_msg>:white_check_mark: Fix test<commit_after>/*yeoman-test*/
const helpers = require('yeoman-test');
const assert = require('yeoman-assert');
const fs = require('fs');
const fsextra = require('fs-extra');
const path = require('path');

const basedir = path.join(__dirname, '../generators/app');
const name = 'test projectName';
const description = 'test projectDesc';

describe('generator-phaser-h5', () => {
    describe('defaults', () => {
        it('creates expected files', () => {
            helpers.run(basedir)
                .then(checkAssets)
                .then(checkConfig)
                .then(checkScripts)
        });

        function checkConfig() {
            assert.file([
                'gulpfile.js',
                'package.json',
                '.jshintrc'
            ]);
        }

        function checkScripts() {
            assert.file([
                'src/assets/js/main.js',
                'src/assets/js/entities/Gesture.js',
                'src/assets/js/entities/MovieClip.js',
                'src/assets/js/entities/VideoConfig.js',
                'src/assets/js/states/boot.js',
                'src/assets/js/states/state1.js',
                'src/assets/js/states/preloader.js'
            ]);
        }

        function checkAssets() {
            assert.file([
                'src/index.html',
                'README.md',
                'LICENSE',
                'src/assets/css/css.css',
                'src/assets/img/favicon.ico'
            ]);
        }
    });
    describe('using options', () => {
        it('projectName, projectDesc', () => {
            helpers.run(basedir)
                .withOptions({ projectName: name, projectDesc: description })
                .then(() => {
                    assert.fileContent([
                        ['package.json', `"name": ${JSON.stringify(name)}`],
                        ['package.json', `"description": ${JSON.stringify(description)}`]
                    ]);
                    assert.fileContent([
                        ['README.md', `# ${name}`],
                        ['README.md', `${description}`]
                    ]);
                })
        });
        it('projectLicense: MIT', () => {
            helpers.run(basedir)
                .withPrompts({ projectLicense: 'MIT' })
                .then(() => {
                    assert.file([
                        'LICENSE'
                    ]);
                })
        });
        it('projectLicense: Apache-2.0', () => {
            helpers.run(basedir)
                .withPrompts({ projectLicense: 'Apache-2.0' })
                .then(() => {
                    assert.file([
                        'LICENSE'
                    ]);
                })
        });
        it('projectLicense: GPL-3.0', () => {
            helpers.run(basedir)
                .withPrompts({ projectLicense: 'GPL-3.0' })
                .then(() => {
                    assert.file([
                        'LICENSE'
                    ]);
                })
        });
        it('projectLicense: Others', () => {
            helpers.run(basedir)
                .withPrompts({ projectLicense: 'Others' })
                .then(() => {
                    assert.file([
                        'LICENSE'
                    ]);
                })
        });
        it('projectSass: true', () => {
            helpers.run(basedir)
                .withPrompts({ projectSass: true })
                .then(() => {
                    assert.file([
                        'src/assets/css/sass.scss',
                        'gulpfile.js',
                        'package.json'
                    ]);
                })
        });
    });

});<|endoftext|>


<commit_before>'use strict';

let expect = require('chai').expect,
    sinon = require('sinon'),
    request = require('request-promise-native'),
    smartcast = require('../index');

describe('#smart-cast-settings-tests', () => {

    it('picture should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.picture.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/picture');

        request.get.restore();
    });

    it('picture size should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.picture.size.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/picture/picture_size');

        request.get.restore();
    });

    it('picture position should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.picture.position.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/picture/picture_position');

        request.get.restore();
    });

    it('picture modeEdit should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.picture.modeEdit.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/picture/picture_mode_edit');

        request.get.restore();
    });

    it('picture mode should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.picture.mode.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/picture/picture_mode');

        request.get.restore();
    });

    it('picture color calibration should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.picture.color.calibration.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/picture/color_calibration');

        request.get.restore();
    });

    it('picture color tuner should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.picture.color.tuner.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/picture/color_calibration/color_tuner');

        request.get.restore();
    });

    it('picture calibrationTests should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.picture.calibrationTests.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/picture/color_calibration/calibration_tests');

        request.get.restore();
    });

    it('audio should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.audio.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/audio');

        request.get.restore();
    });

    it('timers should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.timers.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/timers');

        request.get.restore();
    });

    it('network should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.network.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/network');

        request.get.restore();
    });

    it('channels should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.channels.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/channels');

        request.get.restore();
    });

    it('closedCaptions should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.closedCaptions.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/closed_captions');

        request.get.restore();
    });

    it('devices should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.devices.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/devices');

        request.get.restore();
    });

    it('system should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.system.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/system');

        request.get.restore();
    });

    it('system information should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.system.information.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/system/system_information');

        request.get.restore();
    });

    it('system information tv should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.system.information.tv.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/system/system_information/tv_information');

        request.get.restore();
    });

    it('system information tuner should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.system.information.tuner.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/system/system_information/tuner_information');

        request.get.restore();
    });

    it('system information network should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.system.information.network.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/system/system_information/network_information');

        request.get.restore();
    });

    it('system information uli should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.system.information.uli.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/system/system_information/uli_information');

        request.get.restore();
    });

    it('mobileDevices should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.mobileDevices.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/mobile_devices');

        request.get.restore();
    });

    it('cast should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.cast.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/cast');

        request.get.restore();
    });

});<commit_msg>Test timers.sleepTimer.get()<commit_after>'use strict';

let expect = require('chai').expect,
    sinon = require('sinon'),
    request = require('request-promise-native'),
    smartcast = require('../index');

describe('#smart-cast-settings-tests', () => {

    it('picture should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.picture.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/picture');

        request.get.restore();
    });

    it('picture size should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.picture.size.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/picture/picture_size');

        request.get.restore();
    });

    it('picture position should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.picture.position.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/picture/picture_position');

        request.get.restore();
    });

    it('picture modeEdit should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.picture.modeEdit.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/picture/picture_mode_edit');

        request.get.restore();
    });

    it('picture mode should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.picture.mode.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/picture/picture_mode');

        request.get.restore();
    });

    it('picture color calibration should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.picture.color.calibration.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/picture/color_calibration');

        request.get.restore();
    });

    it('picture color tuner should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.picture.color.tuner.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/picture/color_calibration/color_tuner');

        request.get.restore();
    });

    it('picture calibrationTests should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.picture.calibrationTests.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/picture/color_calibration/calibration_tests');

        request.get.restore();
    });

    it('audio should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.audio.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/audio');

        request.get.restore();
    });

    it('timers should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.timers.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/timers');

        request.get.restore();
    });

    it('timers sleepTimer should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.timers.sleepTimer.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/timers/sleep_timer');

        request.get.restore();
    });

    it('network should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.network.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/network');

        request.get.restore();
    });

    it('channels should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.channels.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/channels');

        request.get.restore();
    });

    it('closedCaptions should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.closedCaptions.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/closed_captions');

        request.get.restore();
    });

    it('devices should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.devices.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/devices');

        request.get.restore();
    });

    it('system should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.system.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/system');

        request.get.restore();
    });

    it('system information should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.system.information.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/system/system_information');

        request.get.restore();
    });

    it('system information tv should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.system.information.tv.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/system/system_information/tv_information');

        request.get.restore();
    });

    it('system information tuner should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.system.information.tuner.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/system/system_information/tuner_information');

        request.get.restore();
    });

    it('system information network should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.system.information.network.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/system/system_information/network_information');

        request.get.restore();
    });

    it('system information uli should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.system.information.uli.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/system/system_information/uli_information');

        request.get.restore();
    });

    it('mobileDevices should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.mobileDevices.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/mobile_devices');

        request.get.restore();
    });

    it('cast should call api', () => {
        let tv = new smartcast('0.0.0.0'),
            mockData = {};
        sinon.stub(request, 'get').returns(Promise.resolve(mockData));

        tv.settings.cast.get();

        expect(request.get.called).to.be.true;
        expect(request.get.firstCall.args[0].url).to.equal('https://0.0.0.0:7345/menu_native/dynamic/tv_settings/cast');

        request.get.restore();
    });

});<|endoftext|>


<commit_before>/* global describe */
/* global it */
'use strict';

var TransloaditLib = require('../index');
var optional = require('optional');
var config = optional('./config.json') || {'key': 'random', 'secret': 'random'};
var should = require('should');

describe('TransloadIt.Template Module:', function () {
  describe('Template loading from the global export', function () {
    var a = require('../index')(config);

    it('should create the global export Object', function () {
      a.should.be.an.instanceOf(Object);
    });

    it('should have the `template` Object', function () {
      should.exist(a.template);

      a.template.should.be.an.instanceOf(Object);
    });
  });

  describe('Template loading as a new Object', function () {
    var a = new TransloaditLib.Template(config);

    it('should create the Object', function () {
      a.should.be.an.instanceOf(Object);
    });

    it('should have the `create` Function', function () {
      should.exist(a.create);
    });
  });

  describe('Template loading with just require', function () {
    var a  = require('../index').Template(config);

    it('should create the Object', function () {
      a.should.be.an.instanceOf(Object);
    });

    it('should have the `create` Function', function () {
      should.exist(a.create);
    });
  });

  describe('Template.create method', function () {
    var a = require('../index').Template(config);

    it('should return an error on missing params', function (done) {
      a.create(null, function (err) {
        should.exist(err);

        done();
      });
    });

    it('should return an error on missing template param', function (done) {
      a.create({}, function (err) {
        should.exist(err);

        done();
      });
    });
  });

  describe('Template.proto.retrieve method', function () {
    var a = require('../index').Template(config);

    it('should return an error on missing templateId', function (done) {
      a.retrieve(null, function (err) {
        should.exist(err);

        done();
      });
    });
  });

  describe('Template.proto.edit method', function () {
    var a = require('../index').Template(config);

    it('should return an error on missing params', function (done) {
      a.edit(null, null, function (err) {
        should.exist(err);
        done();
      });
    });

    it('should return an error on missing name/template from params', function (done) {
      a.edit({}, null, function (err) {
        should.exist(err);
        done();
      });
    });

    it('should return an error on missing templateId', function (done) {
      a.edit({name: 'asd', template: 'asd'}, null, function (err) {
        should.exist(err);
        done();
      });
    });
  });
});
<commit_msg>test-template: remove and retrieveList<commit_after>/* global describe */
/* global it */
'use strict';

var TransloaditLib = require('../index');
var optional = require('optional');
var config = optional('./config.json') || {'key': 'random', 'secret': 'random'};
var should = require('should');

describe('TransloadIt.Template Module:', function () {
  describe('Template loading from the global export', function () {
    var a = require('../index')(config);

    it('should create the global export Object', function () {
      a.should.be.an.instanceOf(Object);
    });

    it('should have the `template` Object', function () {
      should.exist(a.template);

      a.template.should.be.an.instanceOf(Object);
    });
  });

  describe('Template loading as a new Object', function () {
    var a = new TransloaditLib.Template(config);

    it('should create the Object', function () {
      a.should.be.an.instanceOf(Object);
    });

    it('should have the `create` Function', function () {
      should.exist(a.create);
    });
  });

  describe('Template loading with just require', function () {
    var a  = require('../index').Template(config);

    it('should create the Object', function () {
      a.should.be.an.instanceOf(Object);
    });

    it('should have the `create` Function', function () {
      should.exist(a.create);
    });
  });

  describe('Template.create method', function () {
    var a = require('../index').Template(config);

    it('should return an error on missing params', function (done) {
      a.create(null, function (err) {
        should.exist(err);

        done();
      });
    });

    it('should return an error on missing template param', function (done) {
      a.create({}, function (err) {
        should.exist(err);

        done();
      });
    });
  });

  describe('Template.proto.retrieve method', function () {
    var a = require('../index').Template(config);

    it('should return an error on missing templateId', function (done) {
      a.retrieve(null, function (err) {
        should.exist(err);

        done();
      });
    });
  });

  describe('Template.proto.edit method', function () {
    var a = require('../index').Template(config);

    it('should return an error on missing params', function (done) {
      a.edit(null, null, function (err) {
        should.exist(err);
        done();
      });
    });

    it('should return an error on missing name/template from params', function (done) {
      a.edit({}, null, function (err) {
        should.exist(err);
        done();
      });
    });

    it('should return an error on missing templateId', function (done) {
      a.edit({name: 'asd', template: 'asd'}, null, function (err) {
        should.exist(err);
        done();
      });
    });
  });

  describe('Template.proto.remove method', function () {
    var a = require('../index').Template(config);

    it('should return an error on missing templateid', function (done) {
      a.remove(null, function (err) {
        should.exist(err);

        done();
      });
    });
  });

  describe('Template.proto.retrieveList method', function () {
    var a = require('../index').Template(config);

    it('should return an error on missing params', function (done) {
      a.retrieveList(null, function (err) {
        should.exist(err);

        done();
      });
    });
  });
});
<|endoftext|>


<commit_before>ret = db.feeds.createIndex({id: 1}, {unique: true }); checkret('feeds id', ret);

ret = db.labels.createIndex({ "semanticId" : 1 }, { unique: true }); checkret('labels semanticId', ret);
ret = db.labels.createIndex({ "when" : 1 }); checkret('labels when', ret);

ret = db.metadata.createIndex({ "semanticId" : 1 }); checkret('metadata semanticId', ret);
ret = db.metadata.createIndex({ "userId" : 1 }); checkret('metadata userId', ret);
ret = db.metadata.createIndex({ "semantic" : 1 }); checkret('metadata semantic', ret);
ret = db.metadata.createIndex({ "id" : 1 }, { unique : true }); checkret('metadata id', ret);
ret = db.metadata.createIndex({ "impressionTime" : -1 }); checkret('metadata impressionTime', ret);

ret = db.semantics.createIndex({ "label" : 1 });
ret = db.semantics.createIndex({ "when" : 1 });
ret = db.semantics.createIndex({ "semanticId" : 1 });

ret = db.parsererrors.createIndex({ "id": 1 }); checkret('parsererror id', ret);

ret = db.aggregated.createIndex({ "hourId": 1 }, {unique: true}); checkret('aggregated hourId id', ret);

function checkret(info, retval) {
    retval.info = info;
    printjson(retval);
};
<commit_msg>extended indexes for summary<commit_after>ret = db.feeds.createIndex({id: 1}, {unique: true }); checkret('feeds id', ret);

ret = db.labels.createIndex({ "semanticId" : 1 }, { unique: true }); checkret('labels semanticId', ret);
ret = db.labels.createIndex({ "when" : 1 }); checkret('labels when', ret);

ret = db.metadata.createIndex({ "semanticId" : 1 }); checkret('metadata semanticId', ret);
ret = db.metadata.createIndex({ "userId" : 1 }); checkret('metadata userId', ret);
ret = db.metadata.createIndex({ "semantic" : 1 }); checkret('metadata semantic', ret);
ret = db.metadata.createIndex({ "id" : 1 }, { unique : true }); checkret('metadata id', ret);
ret = db.metadata.createIndex({ "impressionTime" : -1 }); checkret('metadata impressionTime', ret);

ret = db.semantics.createIndex({ "label" : 1 });
ret = db.semantics.createIndex({ "when" : 1 });
ret = db.semantics.createIndex({ "semanticId" : 1 });

ret = db.parsererrors.createIndex({ "id": 1 }); checkret('parsererror id', ret);

ret = db.aggregated.createIndex({ "hourId": 1 }, {unique: true}); checkret('aggregated hourId id', ret);

ret = db.summary.createIndex({ "id": 1 }, { unique: true }); checkret('summary id', ret);
ret = db.summary.createIndex({ "impressionTime": -1 }); checkret('summary id', ret);

function checkret(info, retval) {
    retval.info = info;
    printjson(retval);
};
<|endoftext|>


<commit_before>/**
 * Created by desver_f on 23/01/17.
 */

import React, { Component } from 'react';
import _ from 'lodash';
import moment from 'moment';
import { Animated, Platform, ScrollView, Text, TouchableOpacity, View } from 'react-native';
import { AnimatedGaugeProgress } from 'react-native-simple-gauge';
import { observer } from 'mobx-react/native';
import { Actions } from 'react-native-router-flux';
import scrollStyle from './styles';
import Cell from './Cell';
import EVIcon from 'react-native-vector-icons/EvilIcons';
import SLIcon from 'react-native-vector-icons/SimpleLineIcons';

import Layout from '../../shared/components/Layout';
import refreshApplicationData from '../../shared/RefreshApplication';

const HEADER_MAX_HEIGHT = 180;
const HEADER_MIN_HEIGHT = Platform.OS === 'ios' ? 64 : 54;
const HEADER_SCROLL_DISTANCE = HEADER_MAX_HEIGHT - HEADER_MIN_HEIGHT;

@observer
export default class Home extends Component {

    constructor(props) {
        super(props);
        this.state = {
            scrollY: new Animated.Value(0),
            refreshing: false,
        };
    }

    menu = {
        news: () => Actions.news(),
        projects: () => Actions.projects(),
        calendar: () => Actions.calendar(),
        marks: () => Actions.marks(),
        ranking: () => Actions.ranking(),
        tokens: () => Actions.token(),
        stats: () => Actions.stats(),
        links: () => Actions.links(),
        documents: () => Actions.documents(),
        logout: async () => {
            await this.props.store.session.logout();
            this.props.store.ui.defaultState();
            Actions.login();
        }
    };

    async componentWillMount() {
        const { store: { ui, session } } = this.props;

        if (ui.isConnected && session.loggedFromCache) {
            await refreshApplicationData({ withLogin: true });
        }
    }

    renderScrollView() {
        const {
            store: {
                session,
                calendar,
                ranking,
                projects,
                marks,
                tokens,
            }
        } = this.props;

        const nextEvent = calendar.nextEvent;
        const lastNews = _(session.userData.news.slice())
            .orderBy((news) => moment(news.date, 'YYYY-MM-DD HH:mm:ss'))
            .last();
        const lastMark = marks.lastMark;
        const tokenDescription = tokens.nbTokens
            ? `You have ${tokens.nbTokens} tokens to validate`
            : 'There is no token to validate';
        const nextProject = projects.firstEndingProject;

        return (
            <View style={scrollStyle.scrollViewContent}>
                <Cell
                    title="Notifications"
                    description={lastNews.title}
                    icon="ios-pulse-outline"
                    onPress={this.menu.news}
                    color="#233445"
                />
                <Cell
                    title="Calendar"
                    description={nextEvent}
                    icon="ios-calendar-outline"
                    onPress={this.menu.calendar}
                    color="#233445"
                />
                <Cell
                    title="Projects"
                    description={nextProject}
                    icon="ios-cafe-outline"
                    onPress={this.menu.projects}
                    color="#233445"
                />
                <Cell
                    title="Tokens"
                    description={tokenDescription}
                    icon="ios-pricetags-outline"
                    onPress={this.menu.tokens}
                    color="#233445"
                />
                <Cell
                    title="Marks"
                    description={`Your last mark from ${ lastMark.titlemodule } - ${ lastMark.title } is ${lastMark.final_note}`}
                    icon="ios-school-outline"
                    onPress={this.menu.marks}
                    color="#233445"
                />
                <Cell
                    title="Ranking"
                    description={
                        ranking.rankPosition !== '0th'
                            ? `You\'re currently ${ranking.rankPosition} in your promotion.`
                            : 'Click here to get your rank'
                    }
                    icon="ios-trophy-outline"
                    onPress={this.menu.ranking}
                    color="#233445"
                />
                <Cell
                    title="Documents"
                    description="Your private documents"
                    icon="ios-folder-open-outline"
                    onPress={this.menu.documents}
                    color="#233445"
                />
                <Cell
                    title="Links"
                    description="Your best services at your fingertips"
                    icon="ios-link-outline"
                    onPress={this.menu.links}
                    color="#233445"
                />
            </View>
        );
    }

    renderGauges(translateLeft, translateRight) {
        const {
            store: {
                session: { userProfile },
            }
        } = this.props;
        const creditsPercentage = (userProfile.credits / (userProfile.studentyear * 60)) * 100;
        const gpaPercentage = (userProfile.gpa / 4) * 100;

        return [
            <AnimatedGaugeProgress
                key="left"
                style={[
                    scrollStyle.leftGauge,
                    { transform: [{ translateX: translateLeft }] },
                ]}
                size={100}
                width={5}
                fill={gpaPercentage}
                rotation={0}
                cropDegree={230}
                tintColor="#56ab56"
                backgroundColor="#152839"
            />,
            <AnimatedGaugeProgress
                key="right"
                style={[
                    scrollStyle.rightGauge,
                    { transform: [{ translateX: translateRight }] }
                ]}
                size={100}
                width={5}
                fill={creditsPercentage}
                rotation={180}
                cropDegree={230}
                tintColor="#56ab56"
                backgroundColor="#152839"
            />
        ];
    }

    render() {
        const headerHeight = this.state.scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE],
            outputRange: [HEADER_MAX_HEIGHT, HEADER_MIN_HEIGHT],
            extrapolate: 'clamp',
        });
        const imageOpacity = this.state.scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE / 2],
            outputRange: [1, 0],
            extrapolate: 'clamp',
        });
        const imageTranslate = this.state.scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE],
            outputRange: [0, -75],
            extrapolate: 'clamp',
        });
        const translateMinus50 = this.state.scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
            outputRange: [0, -50, 0],
            extrapolate: 'clamp',
        });

        const translate50 = this.state.scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
            outputRange: [0, 50, 0],
            extrapolate: 'clamp',
        });
        const titleOpacity = this.state.scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
            outputRange: [0, 0, 1],
            extrapolate: 'clamp',
        });
        const gaugeLeftTranslate = this.state.scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
            outputRange: [0, 30, 0],
            extrapolate: 'clamp',
        });
        const gaugeRightTranslate = this.state.scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
            outputRange: [0, -30, 0],
            extrapolate: 'clamp',
        });
        const shadow = this.state.scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
            outputRange: [0, 0, 10],
            extrapolate: 'clamp',
        });
        const iOSshadow = this.state.scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
            outputRange: [0, 0, 0.6],
            extrapolate: 'clamp',
        });
        const rotateIcon = this.state.scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE / 2],
            outputRange: ['0deg', '360deg'],
            extrapolate: 'clamp',
        });

        const {
            store: {
                session: { userProfile },
            }
        } = this.props;

        const nameSplited = userProfile.name.split(' ');
        const name = nameSplited[0] + ' ' + nameSplited[1].toUpperCase();

        return (
            <Layout store={this.props.store}>
                <View style={scrollStyle.fill}>
                    <ScrollView
                        style={scrollStyle.fill}
                        scrollEventThrottle={32}
                        onScroll={Animated.event(
                            [{ nativeEvent: { contentOffset: { y: this.state.scrollY } } }]
                        )}
                    >
                        { this.renderScrollView() }
                    </ScrollView>
                    <Animated.View style={[
                        scrollStyle.header,
                        {
                            elevation: shadow,
                            shadowColor: '#000000',
                            shadowOpacity: iOSshadow,
                            shadowRadius: 5,
                            shadowOffset: {
                                height: 3,
                                width: 0
                            },
                        }
                    ]}>
                        <Animated.View style={[
                            {
                                overflow: 'hidden',
                                height: headerHeight,
                            }
                        ]}>
                            <Animated.View
                                style={[
                                    scrollStyle.headerContainer,
                                    {
                                        opacity: imageOpacity,
                                        transform: [{ translateY: imageTranslate }],
                                    },
                                ]}
                            >
                                <View style={scrollStyle.pictureAndGaugesContainer}>
                                    <View style={scrollStyle.pictureAndGauges}>
                                        <View style={{ flexDirection: 'column' }}>
                                            <Animated.View style={{
                                                transform: [{ translateX: translateMinus50 }],
                                            }}>
                                                <Text style={scrollStyle.gaugeValue}>
                                                    { userProfile.gpa }
                                                </Text>
                                                <Text style={scrollStyle.gaugeDescription}>
                                                    GPA
                                                </Text>
                                            </Animated.View>
                                        </View>
                                        <Animated.Image
                                            style={[
                                                scrollStyle.picture,
                                                { transform: [{ rotate: rotateIcon }] }
                                            ]}
                                            source={require('../../assets/epitech.png')}/>

                                        { this.renderGauges(gaugeLeftTranslate, gaugeRightTranslate) }
                                        <Animated.View style={{
                                            transform: [{ translateX: translate50 }],
                                        }}>
                                            <View style={{ flexDirection: 'column' }}>
                                                <Text style={scrollStyle.gaugeValue}>
                                                    { userProfile.credits }
                                                </Text>
                                                <Text style={scrollStyle.gaugeDescription}>
                                                    Credits
                                                </Text>
                                            </View>
                                        </Animated.View>
                                    </View>
                                    <Animated.View style={{
                                        flex: 0.3,
                                        flexDirection: 'row',
                                        transform: [{ translateY: translate50 }],
                                    }}>
                                        <TouchableOpacity
                                            onPress={refreshApplicationData}
                                            hitSlop={{ top: 20, bottom: 20, left: 20, right: 20 }}
                                            style={{
                                                flex: 0.19,
                                                alignItems: 'center',
                                                justifyContent: 'center',
                                                backgroundColor: '#56ab56',
                                                height: 41,
                                                borderTopRightRadius: 5,
                                                borderBottomRightRadius: 5,
                                                elevation: 5
                                            }}>
                                            <EVIcon name="refresh" size={30} color="#FAFAFA"/>
                                        </TouchableOpacity>
                                        <Text style={scrollStyle.username}>{ name }</Text>
                                        <TouchableOpacity
                                            onPress={this.menu.logout}
                                            hitSlop={{ top: 20, bottom: 20, left: 20, right: 20 }}
                                            style={{
                                                flex: 0.19,
                                                alignItems: 'center',
                                                justifyContent: 'center',
                                                height: 41,
                                                backgroundColor: '#DA5040',
                                                borderTopLeftRadius: 5,
                                                borderBottomLeftRadius: 5,
                                                elevation: 5
                                            }}>
                                            <View style={{ transform: [{ rotate: '180deg' }] }}>
                                                <SLIcon name="logout" size={18} color="#FAFAFA"/>
                                            </View>
                                        </TouchableOpacity>
                                    </Animated.View>
                                </View>
                            </Animated.View>
                            <Animated.View
                                style={[
                                    scrollStyle.bar,
                                    {
                                        transform: [{ translateY: translateMinus50 }],
                                        opacity: titleOpacity,
                                    },
                                ]}
                            >
                                <Text style={scrollStyle.title}>Home</Text>
                            </Animated.View>
                        </Animated.View>
                    </Animated.View>
                </View>
            </Layout>
        );
    }
}<commit_msg>Prevented user from refreshing its data when he's offline (was causing instant crash)<commit_after>/**
 * Created by desver_f on 23/01/17.
 */

import React, { Component } from 'react';
import _ from 'lodash';
import moment from 'moment';
import { Animated, Platform, ScrollView, Text, TouchableOpacity, View } from 'react-native';
import { AnimatedGaugeProgress } from 'react-native-simple-gauge';
import { observer } from 'mobx-react/native';
import { Actions } from 'react-native-router-flux';
import scrollStyle from './styles';
import Cell from './Cell';
import EVIcon from 'react-native-vector-icons/EvilIcons';
import SLIcon from 'react-native-vector-icons/SimpleLineIcons';

import Layout from '../../shared/components/Layout';
import refreshApplicationData from '../../shared/RefreshApplication';

const HEADER_MAX_HEIGHT = 180;
const HEADER_MIN_HEIGHT = Platform.OS === 'ios' ? 64 : 54;
const HEADER_SCROLL_DISTANCE = HEADER_MAX_HEIGHT - HEADER_MIN_HEIGHT;

@observer
export default class Home extends Component {

    constructor(props) {
        super(props);
        this.state = {
            scrollY: new Animated.Value(0),
            refreshing: false,
        };
    }

    menu = {
        news: () => Actions.news(),
        projects: () => Actions.projects(),
        calendar: () => Actions.calendar(),
        marks: () => Actions.marks(),
        ranking: () => Actions.ranking(),
        tokens: () => Actions.token(),
        stats: () => Actions.stats(),
        links: () => Actions.links(),
        documents: () => Actions.documents(),
        logout: async () => {
            await this.props.store.session.logout();
            this.props.store.ui.defaultState();
            Actions.login();
        }
    };

    async componentWillMount() {
        const { store: { ui, session } } = this.props;

        if (ui.isConnected && session.loggedFromCache) {
            await refreshApplicationData({ withLogin: true });
        }
    }

    renderScrollView() {
        const {
            store: {
                session,
                calendar,
                ranking,
                projects,
                marks,
                tokens,
            }
        } = this.props;

        const nextEvent = calendar.nextEvent;
        const lastNews = _(session.userData.news.slice())
            .orderBy((news) => moment(news.date, 'YYYY-MM-DD HH:mm:ss'))
            .last();
        const lastMark = marks.lastMark;
        const tokenDescription = tokens.nbTokens
            ? `You have ${tokens.nbTokens} tokens to validate`
            : 'There is no token to validate';
        const nextProject = projects.firstEndingProject;

        return (
            <View style={scrollStyle.scrollViewContent}>
                <Cell
                    title="Notifications"
                    description={lastNews.title}
                    icon="ios-pulse-outline"
                    onPress={this.menu.news}
                    color="#233445"
                />
                <Cell
                    title="Calendar"
                    description={nextEvent}
                    icon="ios-calendar-outline"
                    onPress={this.menu.calendar}
                    color="#233445"
                />
                <Cell
                    title="Projects"
                    description={nextProject}
                    icon="ios-cafe-outline"
                    onPress={this.menu.projects}
                    color="#233445"
                />
                <Cell
                    title="Tokens"
                    description={tokenDescription}
                    icon="ios-pricetags-outline"
                    onPress={this.menu.tokens}
                    color="#233445"
                />
                <Cell
                    title="Marks"
                    description={`Your last mark from ${ lastMark.titlemodule } - ${ lastMark.title } is ${lastMark.final_note}`}
                    icon="ios-school-outline"
                    onPress={this.menu.marks}
                    color="#233445"
                />
                <Cell
                    title="Ranking"
                    description={
                        ranking.rankPosition !== '0th'
                            ? `You\'re currently ${ranking.rankPosition} in your promotion.`
                            : 'Click here to get your rank'
                    }
                    icon="ios-trophy-outline"
                    onPress={this.menu.ranking}
                    color="#233445"
                />
                <Cell
                    title="Documents"
                    description="Your private documents"
                    icon="ios-folder-open-outline"
                    onPress={this.menu.documents}
                    color="#233445"
                />
                <Cell
                    title="Links"
                    description="Your best services at your fingertips"
                    icon="ios-link-outline"
                    onPress={this.menu.links}
                    color="#233445"
                />
            </View>
        );
    }

    renderGauges(translateLeft, translateRight) {
        const {
            store: {
                session: { userProfile },
            }
        } = this.props;
        const creditsPercentage = (userProfile.credits / (userProfile.studentyear * 60)) * 100;
        const gpaPercentage = (userProfile.gpa / 4) * 100;

        return [
            <AnimatedGaugeProgress
                key="left"
                style={[
                    scrollStyle.leftGauge,
                    { transform: [{ translateX: translateLeft }] },
                ]}
                size={100}
                width={5}
                fill={gpaPercentage}
                rotation={0}
                cropDegree={230}
                tintColor="#56ab56"
                backgroundColor="#152839"
            />,
            <AnimatedGaugeProgress
                key="right"
                style={[
                    scrollStyle.rightGauge,
                    { transform: [{ translateX: translateRight }] }
                ]}
                size={100}
                width={5}
                fill={creditsPercentage}
                rotation={180}
                cropDegree={230}
                tintColor="#56ab56"
                backgroundColor="#152839"
            />
        ];
    }

    render() {
        const headerHeight = this.state.scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE],
            outputRange: [HEADER_MAX_HEIGHT, HEADER_MIN_HEIGHT],
            extrapolate: 'clamp',
        });
        const imageOpacity = this.state.scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE / 2],
            outputRange: [1, 0],
            extrapolate: 'clamp',
        });
        const imageTranslate = this.state.scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE],
            outputRange: [0, -75],
            extrapolate: 'clamp',
        });
        const translateMinus50 = this.state.scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
            outputRange: [0, -50, 0],
            extrapolate: 'clamp',
        });

        const translate50 = this.state.scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
            outputRange: [0, 50, 0],
            extrapolate: 'clamp',
        });
        const titleOpacity = this.state.scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
            outputRange: [0, 0, 1],
            extrapolate: 'clamp',
        });
        const gaugeLeftTranslate = this.state.scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
            outputRange: [0, 30, 0],
            extrapolate: 'clamp',
        });
        const gaugeRightTranslate = this.state.scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
            outputRange: [0, -30, 0],
            extrapolate: 'clamp',
        });
        const shadow = this.state.scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
            outputRange: [0, 0, 10],
            extrapolate: 'clamp',
        });
        const iOSshadow = this.state.scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
            outputRange: [0, 0, 0.6],
            extrapolate: 'clamp',
        });
        const rotateIcon = this.state.scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE / 2],
            outputRange: ['0deg', '360deg'],
            extrapolate: 'clamp',
        });

        const {
            store: {
                ui,
                session: { userProfile },
            }
        } = this.props;

        const nameSplited = userProfile.name.split(' ');
        const name = nameSplited[0] + ' ' + nameSplited[1].toUpperCase();

        return (
            <Layout store={this.props.store}>
                <View style={scrollStyle.fill}>
                    <ScrollView
                        style={scrollStyle.fill}
                        scrollEventThrottle={32}
                        onScroll={Animated.event(
                            [{ nativeEvent: { contentOffset: { y: this.state.scrollY } } }]
                        )}
                    >
                        { this.renderScrollView() }
                    </ScrollView>
                    <Animated.View style={[
                        scrollStyle.header,
                        {
                            elevation: shadow,
                            shadowColor: '#000000',
                            shadowOpacity: iOSshadow,
                            shadowRadius: 5,
                            shadowOffset: {
                                height: 3,
                                width: 0
                            },
                        }
                    ]}>
                        <Animated.View style={[
                            {
                                overflow: 'hidden',
                                height: headerHeight,
                            }
                        ]}>
                            <Animated.View
                                style={[
                                    scrollStyle.headerContainer,
                                    {
                                        opacity: imageOpacity,
                                        transform: [{ translateY: imageTranslate }],
                                    },
                                ]}
                            >
                                <View style={scrollStyle.pictureAndGaugesContainer}>
                                    <View style={scrollStyle.pictureAndGauges}>
                                        <View style={{ flexDirection: 'column' }}>
                                            <Animated.View style={{
                                                transform: [{ translateX: translateMinus50 }],
                                            }}>
                                                <Text style={scrollStyle.gaugeValue}>
                                                    { userProfile.gpa }
                                                </Text>
                                                <Text style={scrollStyle.gaugeDescription}>
                                                    GPA
                                                </Text>
                                            </Animated.View>
                                        </View>
                                        <Animated.Image
                                            style={[
                                                scrollStyle.picture,
                                                { transform: [{ rotate: rotateIcon }] }
                                            ]}
                                            source={require('../../assets/epitech.png')}/>

                                        { this.renderGauges(gaugeLeftTranslate, gaugeRightTranslate) }
                                        <Animated.View style={{
                                            transform: [{ translateX: translate50 }],
                                        }}>
                                            <View style={{ flexDirection: 'column' }}>
                                                <Text style={scrollStyle.gaugeValue}>
                                                    { userProfile.credits }
                                                </Text>
                                                <Text style={scrollStyle.gaugeDescription}>
                                                    Credits
                                                </Text>
                                            </View>
                                        </Animated.View>
                                    </View>
                                    <Animated.View style={{
                                        flex: 0.3,
                                        flexDirection: 'row',
                                        transform: [{ translateY: translate50 }],
                                    }}>
                                        <TouchableOpacity
                                            onPress={() => ui.isConnected && refreshApplicationData()}
                                            hitSlop={{ top: 20, bottom: 20, left: 20, right: 20 }}
                                            style={{
                                                flex: 0.19,
                                                alignItems: 'center',
                                                justifyContent: 'center',
                                                backgroundColor: '#56ab56',
                                                height: 41,
                                                borderTopRightRadius: 5,
                                                borderBottomRightRadius: 5,
                                                elevation: 5
                                            }}>
                                            <EVIcon name="refresh" size={30} color="#FAFAFA"/>
                                        </TouchableOpacity>
                                        <Text style={scrollStyle.username}>{ name }</Text>
                                        <TouchableOpacity
                                            onPress={this.menu.logout}
                                            hitSlop={{ top: 20, bottom: 20, left: 20, right: 20 }}
                                            style={{
                                                flex: 0.19,
                                                alignItems: 'center',
                                                justifyContent: 'center',
                                                height: 41,
                                                backgroundColor: '#DA5040',
                                                borderTopLeftRadius: 5,
                                                borderBottomLeftRadius: 5,
                                                elevation: 5
                                            }}>
                                            <View style={{ transform: [{ rotate: '180deg' }] }}>
                                                <SLIcon name="logout" size={18} color="#FAFAFA"/>
                                            </View>
                                        </TouchableOpacity>
                                    </Animated.View>
                                </View>
                            </Animated.View>
                            <Animated.View
                                style={[
                                    scrollStyle.bar,
                                    {
                                        transform: [{ translateY: translateMinus50 }],
                                        opacity: titleOpacity,
                                    },
                                ]}
                            >
                                <Text style={scrollStyle.title}>Home</Text>
                            </Animated.View>
                        </Animated.View>
                    </Animated.View>
                </View>
            </Layout>
        );
    }
}<|endoftext|>


<commit_before>/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import currency from 'currency.js';

import { UIDatabase } from '../database';
import { sortDataBy } from '../utilities';

export const selectPatientHistory = ({ patient }) => {
  const { currentPatient } = patient;
  const { transactions } = currentPatient;

  // Create a query string `transaction.id == "{id} OR transaction.id == "{id}" ...`
  // finding all transaction batches for the patient.
  const queryString = `(${transactions
    .map(({ id }) => `transaction.id == "${id}"`)
    .join(' OR ')}) AND type != "cash_in" AND type != "cash_out"`;
  return queryString ? UIDatabase.objects('TransactionBatch').filtered(queryString) : [];
};

export const selectSortedPatientHistory = ({ patient }) => {
  const { sortKey, isAscending } = patient;
  const patientHistory = selectPatientHistory({ patient });

  return patientHistory ? sortDataBy(patientHistory.slice(), sortKey, isAscending) : patientHistory;
};

export const selectCurrentPatient = ({ patient }) => {
  const { currentPatient } = patient;
  return currentPatient;
};

export const selectPatientName = ({ patient }) => {
  const currentPatient = selectCurrentPatient({ patient });
  return `${currentPatient?.firstName} ${currentPatient?.lastName}`.trim();
};

export const selectAvailableCredit = ({ patient }) =>
  currency(patient?.currentPatient?.availableCredit);

export const selectPatientInsurancePolicies = ({ patient }) => {
  const { currentPatient } = patient;
  const { policies } = currentPatient;
  return policies;
};
<commit_msg>Add patient selector fix for history crash when no history<commit_after>/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import currency from 'currency.js';

import { UIDatabase } from '../database';
import { sortDataBy } from '../utilities';

export const selectPatientHistory = ({ patient }) => {
  const { currentPatient } = patient;
  const { transactions } = currentPatient;

  // Create a query string `transaction.id == "{id} OR transaction.id == "{id}" ...`
  // finding all transaction batches for the patient.
  const inQuery = transactions.map(({ id }) => `transaction.id == "${id}"`).join(' OR ');
  const baseQueryString = 'type != "cash_in" AND type != "cash_out"';
  const fullQuery = `(${inQuery}) AND ${baseQueryString}`;
  return inQuery ? UIDatabase.objects('TransactionBatch').filtered(fullQuery) : [];
};

export const selectSortedPatientHistory = ({ patient }) => {
  const { sortKey, isAscending } = patient;
  const patientHistory = selectPatientHistory({ patient });

  return patientHistory ? sortDataBy(patientHistory.slice(), sortKey, isAscending) : patientHistory;
};

export const selectCurrentPatient = ({ patient }) => {
  const { currentPatient } = patient;
  return currentPatient;
};

export const selectPatientName = ({ patient }) => {
  const currentPatient = selectCurrentPatient({ patient });
  return `${currentPatient?.firstName} ${currentPatient?.lastName}`.trim();
};

export const selectAvailableCredit = ({ patient }) =>
  currency(patient?.currentPatient?.availableCredit);

export const selectPatientInsurancePolicies = ({ patient }) => {
  const { currentPatient } = patient;
  const { policies } = currentPatient;
  return policies;
};
<|endoftext|>