<commit_before>'use strict';

describe('Metrics Controller Spec', function() {

    beforeEach(module('ngRoute'));
    beforeEach(module('pcApp.metrics'));

    describe('MetricDetailController', function(){
        var scope, metDetCtrl;

        beforeEach(inject(function($rootScope, $routeParams, $controller){
            $routeParams.metricId = 1;
            scope = $rootScope.$new();
            metDetCtrl = $controller('MetricDetailController',{
                $scope: scope
            });
        }));

        it('should have a message',function(){
            expect(scope.metric).toHaveBeenCalled;
        });

    } );

});<commit_msg>New Controller Spec<commit_after>'use strict';

describe('Metrics Controller Spec', function() {

    var respond = {
        "self": "/api/v1/metricsmanager/metrics/1",
        "spatial": "Germany, Spain",
        "resource_url": "http://epp.eurostat.ec.europa.eu/tgm/refreshTableAction.do?tab=table&plugin=1&pcode=tec00001&language=en",
        "unit": {
            "detail": "Not found"
        },
        "language": {
            "code": "en",
            "title": "English",
            "id": 1
        },
        "external_resource": {
            "detail": "Not found"
        },
        "resource_issued": "2014-05-28",
        "issued": "2014-07-05T16:27:07.168Z",
        "modified": "2014-08-27T15:53:00.517Z",
        "policy_domains": [
            {
                "description": "Education",
                "title": "Education",
                "id": 1
            }
        ],
        "data": {
            "ranges": {
                "Country": [
                    "Germany",
                    "Spain"
                ]
            },
            "table": [
                {
                    "row": 1,
                    "from": "2003-01-01",
                    "to": "2003-12-31",
                    "value": "23900.0",
                    "Country": "Germany"
                },
                {
                    "row": 2,
                    "from": "2004-01-01",
                    "to": "2004-12-31",
                    "value": "25000.0",
                    "Country": "Germany"
                },
                {
                    "row": 3,
                    "from": "2005-01-01",
                    "to": "2005-12-31",
                    "value": "26000.0",
                    "Country": "Germany"
                },
                {
                    "row": 4,
                    "from": "2006-01-01",
                    "to": "2006-12-31",
                    "value": "27300.0",
                    "Country": "Germany"
                },
                {
                    "row": 5,
                    "from": "2007-01-01",
                    "to": "2007-12-31",
                    "value": "28800.0",
                    "Country": "Germany"
                },
                {
                    "row": 6,
                    "from": "2008-01-01",
                    "to": "2008-12-31",
                    "value": "29000.0",
                    "Country": "Germany"
                },
                {
                    "row": 7,
                    "from": "2009-01-01",
                    "to": "2009-12-31",
                    "value": "26900.0",
                    "Country": "Germany"
                },
                {
                    "row": 8,
                    "from": "2010-01-01",
                    "to": "2010-12-31",
                    "value": "29200.0",
                    "Country": "Germany"
                },
                {
                    "row": 9,
                    "from": "2011-01-01",
                    "to": "2011-12-31",
                    "value": "30800.0",
                    "Country": "Germany"
                },
                {
                    "row": 10,
                    "from": "2012-01-01",
                    "to": "2012-12-31",
                    "value": "31500.0",
                    "Country": "Germany"
                },
                {
                    "row": 11,
                    "from": "2013-01-01",
                    "to": "2013-12-31",
                    "value": "32000.0",
                    "Country": "Germany"
                },
                {
                    "row": 12,
                    "from": "2003-01-01",
                    "to": "2003-12-31",
                    "value": "20900.0",
                    "Country": "Spain"
                },
                {
                    "row": 13,
                    "from": "2004-01-01",
                    "to": "2004-12-31",
                    "value": "21900.0",
                    "Country": "Spain"
                },
                {
                    "row": 14,
                    "from": "2005-01-01",
                    "to": "2005-12-31",
                    "value": "22900.0",
                    "Country": "Spain"
                },
                {
                    "row": 15,
                    "from": "2006-01-01",
                    "to": "2006-12-31",
                    "value": "24800.0",
                    "Country": "Spain"
                },
                {
                    "row": 16,
                    "from": "2007-01-01",
                    "to": "2007-12-31",
                    "value": "26200.0",
                    "Country": "Spain"
                },
                {
                    "row": 17,
                    "from": "2008-01-01",
                    "to": "2008-12-31",
                    "value": "25900.0",
                    "Country": "Spain"
                },
                {
                    "row": 18,
                    "from": "2009-01-01",
                    "to": "2009-12-31",
                    "value": "24200.0",
                    "Country": "Spain"
                },
                {
                    "row": 19,
                    "from": "2010-01-01",
                    "to": "2010-12-31",
                    "value": "24200.0",
                    "Country": "Spain"
                },
                {
                    "row": 20,
                    "from": "2011-01-01",
                    "to": "2011-12-31",
                    "value": "24300.0",
                    "Country": "Spain"
                },
                {
                    "row": 21,
                    "from": "2012-01-01",
                    "to": "2012-12-31",
                    "value": "24400.0",
                    "Country": "Spain"
                },
                {
                    "row": 22,
                    "from": "2013-01-01",
                    "to": "2013-12-31",
                    "value": "24500.0",
                    "Country": "Spain"
                }
            ],
            "extra_columns": [
                "Country"
            ]
        },
        "id": 1,
        "title": "Gross Domestic Product at Market Prices for Germany and Spain",
        "acronym": "GDP (GER, SPA)",
        "description": "GDP (gross domestic product) is an indicator for a nation´s economic situation. It reflects the total value of all goods and services produced less the value of goods and services used for intermediate consumption in their production. Expressing GDP in PPS (purchasing power standards) eliminates differences in price levels between countries, and calculations on a per head basis allows for the comparison of economies significantly different in absolute size. (Source: Eurostat)",
        "keywords": "GDP, Market Price",
        "publisher": "Eurostat",
        "license": "",
        "user_id": 1,
        "version": 5,
        "formula": "1"
    };

    var respond_list = {
        "count": 2,
        "next": null,
        "previous": null,
        "results": [
            respond,
            respond
        ]
    };

    beforeEach(module('ngRoute'));
    beforeEach(module('pcApp.metrics'));

    describe('MetricDetailController', function(){
        var scope, metDetCtrl, httpBackend;

        beforeEach(inject(function($rootScope, $routeParams, $controller, $httpBackend){
            httpBackend = $httpBackend;
            httpBackend.when('GET', '/api/v1/metricsmanager/metrics/1').respond(respond);
            $routeParams.metricId = 1;
            scope = $rootScope.$new();
            metDetCtrl = $controller('MetricDetailController',{
                $scope: scope
            });
        }));

        it('should have a metric',function(){
            httpBackend.flush();
            expect(scope.metric.spatial).toBe('Germany, Spain');
        });

    });

    describe('MetricController', function(){
        var scope, metCtrl, httpBackend;

        beforeEach(inject(function($rootScope, $controller, $httpBackend){
            httpBackend = $httpBackend;
            httpBackend.when('GET', '/api/v1/metricsmanager/metrics').respond(respond_list);
            scope = $rootScope.$new();
            metCtrl = $controller('MetricsController',{
                $scope: scope
            });
        }));

        it('should have list of metrics',function(){
            httpBackend.flush();
            expect(scope.metrics.count).toBe(2);
            expect(scope.metrics.results[0].spatial).toBe('Germany, Spain');
        });

    });

});<|endoftext|>


<commit_before>/**
 * Provides a skinnable UI for playing Youtube videos by ID.
 * Requires Ojay and SWFObject version 2.0.
 * @constructor
 * @class YoutubePlayer
 */
var YoutubePlayer = new JS.Class({
    include: [Ojay.Observable, JS.State],

    /**
     * @param {String} videoId
     * @param {String} elementId
     */
    initialize: function(videoId, elementId, options) {
        this._videoId   = videoId;
        this._elementId = elementId;
        this._options   = options || {};

        this.klass._register(this);

        var elements = this._elements = {};
        Ojay.byId(this._elementId).insert(this.getHTML(), 'after');

        this._embed();
        this._setupProgressSlider();
        this._setupVolumeSlider();

        this.on('playing', function(player) {
            player.klass._playing(player);
            player.setState('PLAYING');
            player._elements._playButton.removeClass('play').addClass('pause').setContent('Pause');
        });

        this.on('paused', function(player) {
            player.setState('PAUSED');
            player._elements._playButton.removeClass('pause').addClass('play').setContent('Play');
        });
    },

    /**
     * Instantiates a flash video player in the correct element.
     * @returns {YoutubePlayer}
     */
    _embed: function() {
        var url = this.klass.getPlayerURL(this._elementId);
        if (url === null) return null;

        var element = Ojay.byId(this._elementId), width = element.getWidth();
        if (!this.klass.hasAcceptableFlash()) element.insert(this.klass._getFlashWarning(), 'before');

        swfobject.embedSWF( url, escape(this._elementId),
                            width, this._options.height || width / this.klass.ASPECT_RATIO,
                            this.klass.FLASH_VERSION,
                            null, null,
                            {allowScriptAccess: 'always', wmode: 'transparent'});
        return this;
    },

    /**
     * Returns an Ojay collection containing the HTML elements used for the UI.
     * @returns {DomCollection}
     */
    getHTML: function() {
        var elements = this._elements, self = this;
        if (elements._container) return elements._container;
        elements._container = Ojay( Ojay.HTML.div({className: 'youtube-controls'}, function(HTML) {
            elements._playButton = Ojay(HTML.button({className: 'play-pause'}, 'Play'));
            HTML.div({className: 'progress'}, 'Progress:');
            HTML.concat(self.getProgressSliderElement().node);
            elements._time = Ojay( HTML.div({className: 'time'}) );
            HTML.div({className: 'volume'}, 'Volume:');
            HTML.concat(self.getVolumeSliderElement().node);
        }) );
        elements._playButton.on('click')._(this).toggle();
        return elements._container;
    },

    /**
     * Returns HTML elements required to implement a slider.
     * @returns {DomCollection}
     */
    getProgressSliderElement: function() {
        var elements = this._elements;
        return elements._progressSlider = Ojay( Ojay.HTML.div({className: 'progress-slider'}, function(HTML) {
            elements._progressSliderThumb = Ojay( HTML.div({className: 'thumb'}) );
        }) );
    },

    /**
     */
    _setupProgressSlider: function() {
        var elements    = this._elements,
            thumbWidth  = elements._progressSliderThumb.getWidth(),
            sliderWidth = elements._progressSlider.getWidth();

        var limit = this._progressSliderLimit = sliderWidth - thumbWidth;
        this._progressSlider = YAHOO.widget.Slider.getHorizSlider(elements._progressSlider.node,
                elements._progressSliderThumb.node, 0, this._progressSliderLimit);

        this._progressBar = Ojay(Ojay.HTML.div({className: 'progress-bar', style: {width: 0}}));
        Ojay(this._progressSlider.getEl()).insert(this._progressBar, 'before');

        this._thumbWidth = thumbWidth;

        var player = this._getPlayer(), self = this;
        this._progressSlider.subscribe('change', function(value) {
            self.setCompletion(value / limit);
        });
    },

    /**
     * Sets the percentage completion of the video.
     * @param {Number} offset
     * @returns {YoutubePlayer}
     */
    setCompletion: function(offset) {
        var player = this._getPlayer();
        player.seekTo(offset * player.getDuration(), true);
        return this;
    },

    /**
     * Returns HTML elements required to implement a slider.
     * @returns {DomCollection}
     */
    getVolumeSliderElement: function() {
        var elements = this._elements;
        return elements._volumeSlider = Ojay( Ojay.HTML.div({className: 'volume-slider'}, function(HTML) {
            elements._volumeSliderThumb = Ojay( HTML.div({className: 'thumb'}) );
        }) );
    },

    /**
     */
    _setupVolumeSlider: function() {
        var elements = this._elements,
            thumbWidth = elements._volumeSliderThumb.getWidth(),
            sliderWidth = elements._volumeSlider.getWidth();

        var limit = this._volumeSliderLimit = sliderWidth - thumbWidth;
        this._volumeSlider = YAHOO.widget.Slider.getHorizSlider(elements._volumeSlider.node,
                elements._volumeSliderThumb.node, 0, this._volumeSliderLimit);

        this._volumeBar = Ojay(Ojay.HTML.div({className: 'volume-bar', style: {width: 0}}));
        Ojay(this._volumeSlider.getEl()).insert(this._volumeBar, 'before');

        var player = this._getPlayer(), self = this;
        this._volumeSlider.subscribe('change', function(value) {
            self.setVolume(value / limit);
        });
    },

    /**
     * Sets the volume as a fraction between 0 and 1
     * @param {Number} volume
     * @returns {YoutubePlayer}
     */
    setVolume: function(volume) {
    	if (volume === undefined) volume = this._getPlayer().getVolume();
        if (volume > 1) volume = volume / 100;

        var distance = volume * this._volumeSliderLimit;
        this._volumeSlider.setValue(distance, true, true, true);
        this._volumeBar.setStyle({width: this._thumbWidth * volume +
        	                             distance + 'px'});

        this._getPlayer().setVolume(volume * 100);
        return this;
    },

    /**
     * Cues the requested video when the video player is ready.
     */
    _onready: function() {
        var callback = 'YoutubePlayer._dispatchStateEvent("' + this._elementId + '")';
        this._getPlayer().addEventListener('onStateChange', callback);
        this._getPlayer().cueVideoById(this._videoId);
        this.setState('PAUSED');
        this.notifyObservers('ready');
        setInterval(this.method('updateTime'), 250);
        this.setVolume();
    },

    /**
     * Returns a string representation of the current play time.
     * @returns {String}
     */
    getTimeString: function() { try {
        var player = this._getPlayer();
        var time = player.getCurrentTime();
        var mins = (time / 60).floor(), secs = (time % 60).floor();
            mins = mins > 0 ? mins : 0;
            secs = secs > 0 ? secs : 0;
        return mins + ':' + (secs < 10 ? '0' : '') + secs;
    } catch (e) {
        return '';

    }},

    /**
     * Dispatches event calls from the YouTube API to Ojay.Observable's named
     * event listener system. See YoutubePlayer.STATES for event names.
     * @param {Number} state
     */
    _dispatchStateEvent: function(state) {
        for (var key in this.klass.STATES) {
            if (this.klass.STATES[key] == state)
                this.notifyObservers(key);
        }
    },

    /**
     * Returns a reference to the flash object that provides the Youtube API.
     * @returns {HTMLElement}
     */
    _getPlayer: function() {
        return Ojay.byId(this._elementId).node;
    },

    states: {
        PAUSED: {
            /**
             * @returns {YoutubePlayer}
             */
            play: function() {
                this._getPlayer().playVideo();
                return this;
            },

            /**
             * @returns {YoutubePlayer}
             */
            toggle: function() {
                return this.play();
            },

            /**
             * Updates the time display
             * @returns {YoutubePlayer}
             */
            updateTime: function() {
                this._elements._time.setContent(this.getTimeString());
                return this;
            }
        },

        PLAYING: {
            /**
             * @returns {YoutubePlayer}
             */
            pause: function() {
                this._getPlayer().pauseVideo();
                return this;
            },

            /**
             * @returns {YoutubePlayer}
             */
            toggle: function() {
                return this.pause();
            },

            /**
             * Updates the time display
             * @returns {YoutubePlayer}
             */
            updateTime: function() { try {
                var player = this._getPlayer();
                this._elements._time.setContent(this.getTimeString());
                var offset   = player.getCurrentTime() / player.getDuration(),
                    distance = offset * this._progressSliderLimit;

                this._progressSlider.setValue(distance, true, true, true);

                this._progressBar.setStyle({width: this._thumbWidth * offset +
                                                   distance + 'px'});
                return this;
            } catch (e) {
                return this;
            }}
        }
    },

    extend: {
        _instances: {},

        /**
         * @param {YoutubePlayer}
         */
        _register: function(player) {
            this._instances[player._elementId] = player;
        },

        /**
         * @param {YoutubePlayer}
         */
        _playing: function(player) {
            if (this._current && this._current !== player) this._current.pause();
            this._current = player;
        },

        /**
         * Returns the correct URL for the given video ID.
         * @param {String} videoId
         * @returns {String}
         */
        getVideoURL: function(videoId) {
            return 'http://www.youtube.com/v/' + videoId + '&enablejsapi=1';
        },

        /**
         * Returns the correct player URL for the set developer key.
         * @param {String} playerId
         * @returns {String}
         */
        getPlayerURL: function(playerId) {
            if (this.API_KEY === null) return null;
            var uri = Ojay.URI.parse('http://www.youtube.com/apiplayer?enablejsapi=1');
            uri.setParam('key', this.API_KEY);
            uri.setParam('playerapiid', playerId);
            return uri.toString();
        },

        /**
         * Returns the instance with the given ID.
         * @param {id}
         * @returns {YoutubePlayer}
         */
        findById: function(id) {
            return this._instances[id];
        },

        /**
         * Dispatches calls from the YouTube event API to individual
         * YoutubePlayer instances. Is curried to allow usage with the
         * YouTube event API while adding instance identification.
         * @param {String} playerId
         * @param {String} state
         */
        _dispatchStateEvent: function(playerId, state) {
            YoutubePlayer.findById(playerId)._dispatchStateEvent(state);
        }.curry(),

        FLASH_VERSION: '8',
        ASPECT_RATIO: 4/3,

        /* Must be assigned before use */
        CLIENT_ID:  null,
        API_KEY:    null,

        /**
         * Returns true iff we have a recent enough Flash plugin installed.
         * @returns {Boolean}
         */
        hasAcceptableFlash: function() {
            var expected = this.MINIMUM_FLASH_VERSION, actual = swfobject.getFlashPlayerVersion();
            return !(actual.major < expected.major
                  || actual.minor < expected.minor
                  || actual.release < expected.release);
        },

        /**
         * @returns {HTMLElement}
         */
        _getFlashWarning: function() {
            var self = this;
            return Ojay.HTML.p({className: 'flash-warning'},
                'If this media player does not work for you, try ',
                Ojay.HTML.a({href: self.FLASH_DOWNLOAD_URL},
                        'installing the latest Flash plugin'), '.'
            );
        },

        /* Where to go to download Flash */
        FLASH_DOWNLOAD_URL:     'http://www.adobe.com/products/flashplayer/',
        MINIMUM_FLASH_VERSION:  {major: 9, minor: 0, release: 0},

        STATES: {
            unstarted:  -1,
            ended:      0,
            playing:    1,
            paused:     2,
            buffering:  3,
            cued:       5
        }
    }
});

onYouTubePlayerReady = function(playerId) {
    YoutubePlayer.findById(playerId)._onready();
};

<commit_msg>Add a title to the player controls.<commit_after>/**
 * Provides a skinnable UI for playing Youtube videos by ID.
 * Requires Ojay and SWFObject version 2.0.
 * @constructor
 * @class YoutubePlayer
 */
var YoutubePlayer = new JS.Class({
    include: [Ojay.Observable, JS.State],

    /**
     * @param {String} videoId
     * @param {String} elementId
     */
    initialize: function(videoId, elementId, options) {
        this._videoId   = videoId;
        this._elementId = elementId;
        this._options   = options || {};

        this.klass._register(this);

        var elements = this._elements = {};
        Ojay.byId(this._elementId).insert(this.getHTML(), 'after');

        this._embed();
        this._setupProgressSlider();
        this._setupVolumeSlider();

        this.on('playing', function(player) {
            player.klass._playing(player);
            player.setState('PLAYING');
            player._elements._playButton.removeClass('play').addClass('pause').setContent('Pause');
        });

        this.on('paused', function(player) {
            player.setState('PAUSED');
            player._elements._playButton.removeClass('pause').addClass('play').setContent('Play');
        });
    },

    /**
     * Instantiates a flash video player in the correct element.
     * @returns {YoutubePlayer}
     */
    _embed: function() {
        var url = this.klass.getPlayerURL(this._elementId);
        if (url === null) return null;

        var element = Ojay.byId(this._elementId), width = element.getWidth();
        if (!this.klass.hasAcceptableFlash()) element.insert(this.klass._getFlashWarning(), 'before');

        swfobject.embedSWF( url, escape(this._elementId),
                            width, this._options.height || width / this.klass.ASPECT_RATIO,
                            this.klass.FLASH_VERSION,
                            null, null,
                            {allowScriptAccess: 'always', wmode: 'transparent'});
        return this;
    },

    /**
     * Returns an Ojay collection containing the HTML elements used for the UI.
     * @returns {DomCollection}
     */
    getHTML: function() {
        var elements = this._elements, self = this;
        if (elements._container) return elements._container;
        elements._container = Ojay( Ojay.HTML.div({className: 'youtube-controls'}, function(HTML) {
            HTML.h3({className: 'controls-header'}, 'Video player controls');
            elements._playButton = Ojay(HTML.button({className: 'play-pause'}, 'Play'));
            HTML.div({className: 'progress'}, 'Progress:');
            HTML.concat(self.getProgressSliderElement().node);
            elements._time = Ojay( HTML.div({className: 'time'}) );
            HTML.div({className: 'volume'}, 'Volume:');
            HTML.concat(self.getVolumeSliderElement().node);
        }) );
        elements._playButton.on('click')._(this).toggle();
        return elements._container;
    },

    /**
     * Returns HTML elements required to implement a slider.
     * @returns {DomCollection}
     */
    getProgressSliderElement: function() {
        var elements = this._elements;
        return elements._progressSlider = Ojay( Ojay.HTML.div({className: 'progress-slider'}, function(HTML) {
            elements._progressSliderThumb = Ojay( HTML.div({className: 'thumb'}) );
        }) );
    },

    /**
     */
    _setupProgressSlider: function() {
        var elements    = this._elements,
            thumbWidth  = elements._progressSliderThumb.getWidth(),
            sliderWidth = elements._progressSlider.getWidth();

        var limit = this._progressSliderLimit = sliderWidth - thumbWidth;
        this._progressSlider = YAHOO.widget.Slider.getHorizSlider(elements._progressSlider.node,
                elements._progressSliderThumb.node, 0, this._progressSliderLimit);

        this._progressBar = Ojay(Ojay.HTML.div({className: 'progress-bar', style: {width: 0}}));
        Ojay(this._progressSlider.getEl()).insert(this._progressBar, 'before');

        this._thumbWidth = thumbWidth;

        var player = this._getPlayer(), self = this;
        this._progressSlider.subscribe('change', function(value) {
            self.setCompletion(value / limit);
        });
    },

    /**
     * Sets the percentage completion of the video.
     * @param {Number} offset
     * @returns {YoutubePlayer}
     */
    setCompletion: function(offset) {
        var player = this._getPlayer();
        player.seekTo(offset * player.getDuration(), true);
        return this;
    },

    /**
     * Returns HTML elements required to implement a slider.
     * @returns {DomCollection}
     */
    getVolumeSliderElement: function() {
        var elements = this._elements;
        return elements._volumeSlider = Ojay( Ojay.HTML.div({className: 'volume-slider'}, function(HTML) {
            elements._volumeSliderThumb = Ojay( HTML.div({className: 'thumb'}) );
        }) );
    },

    /**
     */
    _setupVolumeSlider: function() {
        var elements = this._elements,
            thumbWidth = elements._volumeSliderThumb.getWidth(),
            sliderWidth = elements._volumeSlider.getWidth();

        var limit = this._volumeSliderLimit = sliderWidth - thumbWidth;
        this._volumeSlider = YAHOO.widget.Slider.getHorizSlider(elements._volumeSlider.node,
                elements._volumeSliderThumb.node, 0, this._volumeSliderLimit);

        this._volumeBar = Ojay(Ojay.HTML.div({className: 'volume-bar', style: {width: 0}}));
        Ojay(this._volumeSlider.getEl()).insert(this._volumeBar, 'before');

        var player = this._getPlayer(), self = this;
        this._volumeSlider.subscribe('change', function(value) {
            self.setVolume(value / limit);
        });
    },

    /**
     * Sets the volume as a fraction between 0 and 1
     * @param {Number} volume
     * @returns {YoutubePlayer}
     */
    setVolume: function(volume) {
    	if (volume === undefined) volume = this._getPlayer().getVolume();
        if (volume > 1) volume = volume / 100;

        var distance = volume * this._volumeSliderLimit;
        this._volumeSlider.setValue(distance, true, true, true);
        this._volumeBar.setStyle({width: this._thumbWidth * volume +
        	                             distance + 'px'});

        this._getPlayer().setVolume(volume * 100);
        return this;
    },

    /**
     * Cues the requested video when the video player is ready.
     */
    _onready: function() {
        var callback = 'YoutubePlayer._dispatchStateEvent("' + this._elementId + '")';
        this._getPlayer().addEventListener('onStateChange', callback);
        this._getPlayer().cueVideoById(this._videoId);
        this.setState('PAUSED');
        this.notifyObservers('ready');
        setInterval(this.method('updateTime'), 250);
        this.setVolume();
    },

    /**
     * Returns a string representation of the current play time.
     * @returns {String}
     */
    getTimeString: function() { try {
        var player = this._getPlayer();
        var time = player.getCurrentTime();
        var mins = (time / 60).floor(), secs = (time % 60).floor();
            mins = mins > 0 ? mins : 0;
            secs = secs > 0 ? secs : 0;
        return mins + ':' + (secs < 10 ? '0' : '') + secs;
    } catch (e) {
        return '';

    }},

    /**
     * Dispatches event calls from the YouTube API to Ojay.Observable's named
     * event listener system. See YoutubePlayer.STATES for event names.
     * @param {Number} state
     */
    _dispatchStateEvent: function(state) {
        for (var key in this.klass.STATES) {
            if (this.klass.STATES[key] == state)
                this.notifyObservers(key);
        }
    },

    /**
     * Returns a reference to the flash object that provides the Youtube API.
     * @returns {HTMLElement}
     */
    _getPlayer: function() {
        return Ojay.byId(this._elementId).node;
    },

    states: {
        PAUSED: {
            /**
             * @returns {YoutubePlayer}
             */
            play: function() {
                this._getPlayer().playVideo();
                return this;
            },

            /**
             * @returns {YoutubePlayer}
             */
            toggle: function() {
                return this.play();
            },

            /**
             * Updates the time display
             * @returns {YoutubePlayer}
             */
            updateTime: function() {
                this._elements._time.setContent(this.getTimeString());
                return this;
            }
        },

        PLAYING: {
            /**
             * @returns {YoutubePlayer}
             */
            pause: function() {
                this._getPlayer().pauseVideo();
                return this;
            },

            /**
             * @returns {YoutubePlayer}
             */
            toggle: function() {
                return this.pause();
            },

            /**
             * Updates the time display
             * @returns {YoutubePlayer}
             */
            updateTime: function() { try {
                var player = this._getPlayer();
                this._elements._time.setContent(this.getTimeString());
                var offset   = player.getCurrentTime() / player.getDuration(),
                    distance = offset * this._progressSliderLimit;

                this._progressSlider.setValue(distance, true, true, true);

                this._progressBar.setStyle({width: this._thumbWidth * offset +
                                                   distance + 'px'});
                return this;
            } catch (e) {
                return this;
            }}
        }
    },

    extend: {
        _instances: {},

        /**
         * @param {YoutubePlayer}
         */
        _register: function(player) {
            this._instances[player._elementId] = player;
        },

        /**
         * @param {YoutubePlayer}
         */
        _playing: function(player) {
            if (this._current && this._current !== player) this._current.pause();
            this._current = player;
        },

        /**
         * Returns the correct URL for the given video ID.
         * @param {String} videoId
         * @returns {String}
         */
        getVideoURL: function(videoId) {
            return 'http://www.youtube.com/v/' + videoId + '&enablejsapi=1';
        },

        /**
         * Returns the correct player URL for the set developer key.
         * @param {String} playerId
         * @returns {String}
         */
        getPlayerURL: function(playerId) {
            if (this.API_KEY === null) return null;
            var uri = Ojay.URI.parse('http://www.youtube.com/apiplayer?enablejsapi=1');
            uri.setParam('key', this.API_KEY);
            uri.setParam('playerapiid', playerId);
            return uri.toString();
        },

        /**
         * Returns the instance with the given ID.
         * @param {id}
         * @returns {YoutubePlayer}
         */
        findById: function(id) {
            return this._instances[id];
        },

        /**
         * Dispatches calls from the YouTube event API to individual
         * YoutubePlayer instances. Is curried to allow usage with the
         * YouTube event API while adding instance identification.
         * @param {String} playerId
         * @param {String} state
         */
        _dispatchStateEvent: function(playerId, state) {
            YoutubePlayer.findById(playerId)._dispatchStateEvent(state);
        }.curry(),

        FLASH_VERSION: '8',
        ASPECT_RATIO: 4/3,

        /* Must be assigned before use */
        CLIENT_ID:  null,
        API_KEY:    null,

        /**
         * Returns true iff we have a recent enough Flash plugin installed.
         * @returns {Boolean}
         */
        hasAcceptableFlash: function() {
            var expected = this.MINIMUM_FLASH_VERSION, actual = swfobject.getFlashPlayerVersion();
            return !(actual.major < expected.major
                  || actual.minor < expected.minor
                  || actual.release < expected.release);
        },

        /**
         * @returns {HTMLElement}
         */
        _getFlashWarning: function() {
            var self = this;
            return Ojay.HTML.p({className: 'flash-warning'},
                'If this media player does not work for you, try ',
                Ojay.HTML.a({href: self.FLASH_DOWNLOAD_URL},
                        'installing the latest Flash plugin'), '.'
            );
        },

        /* Where to go to download Flash */
        FLASH_DOWNLOAD_URL:     'http://www.adobe.com/products/flashplayer/',
        MINIMUM_FLASH_VERSION:  {major: 9, minor: 0, release: 0},

        STATES: {
            unstarted:  -1,
            ended:      0,
            playing:    1,
            paused:     2,
            buffering:  3,
            cued:       5
        }
    }
});

onYouTubePlayerReady = function(playerId) {
    YoutubePlayer.findById(playerId)._onready();
};

<|endoftext|>


<commit_before>var compose = (function () {

var exports = {};
var is_composing_message = false;

function show(tabname, focus_area) {
    if (tabname === "stream") {
        $('#private-message').hide();
        $('#stream-message').show();
        $("#stream_toggle").addClass("active");
        $("#private_message_toggle").removeClass("active");
    } else {
        $('#private-message').show();
        $('#stream-message').hide();
        $("#stream_toggle").removeClass("active");
        $("#private_message_toggle").addClass("active");
    }
    $("#send-status").removeClass(status_classes).hide();
    $('#compose').css({visibility: "visible"});
    $("#new_message_content").trigger("autosize");
    $('.message_comp').slideDown(100, function () {
        // If the compose box is obscuring the currently selected message,
        // scroll up until the message is no longer occluded.
        if (selected_message_id === -1) {
            // If there's no selected message, there's no need to
            // scroll the compose box to avoid it.
            return;
        }
        var cover = selected_message.offset().top + selected_message.height()
            - $("#compose").offset().top;
        if (cover > 0) {
            disable_pointer_movement = true;
            // We use $('html, body') because you can't animate window.scrollTop
            // on Chrome (http://bugs.jquery.com/ticket/10419).
            $('html, body').animate({
                scrollTop: viewport.scrollTop() + cover + 5
            }, {
                complete: function () {
                    // The complete callback is actually called before the
                    // scrolling has completed, so we try to let scrolling
                    // finish before allowing pointer movements again or the
                    // pointer may still move.
                    setTimeout(function () {
                        disable_pointer_movement = false;
                    }, 50);
                }
            });
        }
    });
    focus_area.focus();
    focus_area.select();
}

// In an attempt to decrease mixing, make the composebox's
// stream bar look like what you're replying to.
// (In particular, if there's a color associated with it,
//  have that color be reflected here too.)
exports.decorate_stream_bar = function (stream_name) {
    var color = subs.get_color(stream_name);
    $("#stream-message .message_header_stream").css("background-color", color);
};

exports.start = function (msg_type, opts) {
    if (reload.is_in_progress()) {
        return;
    }

    compose.clear();

    var default_stream = '';
    if (msg_type === 'stream' && lurk_stream !== undefined)
        default_stream = lurk_stream;
    opts = $.extend({ message_type:     msg_type,
                      stream:           default_stream,
                      subject:          '',
                      private_message_recipient: ''
                    }, opts);

    compose.stream_name(opts.stream);
    compose.subject(opts.subject);
    compose.recipient(opts.private_message_recipient);
    // If the user opens the compose box, types some text, and then clicks on a
    // different stream/subject, we want to keep the text in the compose box
    if (opts.message !== undefined) {
        compose.message_content(opts.message);
    }

    ui.change_tab_to("#home");

    var focus_area;
    if (opts.stream && ! opts.subject) {
        focus_area = 'subject';
    } else if (opts.stream || opts.private_message_recipient) {
        focus_area = 'new_message_content';
    }

    if (msg_type === 'stream') {
        show('stream', $("#" + (focus_area || 'stream')));
    } else {
        show('private', $("#" + (focus_area || 'private_message_recipient')));
    }

    is_composing_message = msg_type;
    exports.decorate_stream_bar(opts.stream);
    $(document).trigger($.Event('compose_started.zephyr', opts));
};

exports.cancel = function () {
    compose.hide();
    is_composing_message = false;
    $(document).trigger($.Event('compose_canceled.zephyr'));
};

var send_options;

function send_message() {
    var send_status = $('#send-status');

    // TODO: this should be collapsed with the code in composebox_typeahead.js
    var recipients = compose.recipient().split(/\s*[,;]\s*/);

    var request = {client: 'website',
                   type:        compose.composing(),
                   subject:     compose.subject(),
                   content:     compose.message_content()};
    if (request.type === "private") {
        request.to = JSON.stringify(recipients);
    } else {
        request.to = compose.stream_name();
    }

    $.ajax({
        dataType: 'json', // This seems to be ignored. We still get back an xhr.
        url: '/json/send_message',
        type: 'POST',
        data: request,
        success: function (resp, statusText, xhr) {
            compose.clear();
            send_status.hide();
            is_composing_message = false;
            compose.hide();
            $("#compose-send-button").removeAttr('disabled');
        },
        error: function (xhr, error_type) {
            if (error_type !== 'timeout' && reload.is_pending()) {
                // The error might be due to the server changing
                reload.initiate({immediate: true, send_after_reload: true});
                return;
            }
            var response = "Error sending message";
            if (xhr.status.toString().charAt(0) === "4") {
                // Only display the error response for 4XX, where we've crafted
                // a nice response.
                response += ": " + $.parseJSON(xhr.responseText).msg;
            }
            show(is_composing_message, $("#new_message_content"));
            send_status.removeClass(status_classes)
                       .addClass('alert-error')
                       .text(response)
                       .append($('<span />')
                           .addClass('send-status-close').html('×')
                           .click(function () { send_status.stop(true).fadeOut(500); }))
                       .stop(true).fadeTo(0,1);

            $("#compose-send-button").removeAttr('disabled');
        }
    });

    send_status.hide();
}

exports.finish = function () {
    if (! compose.validate()) {
        return false;
    }
    send_message();
    // TODO: Do we want to fire the event even if the send failed due
    // to a server-side error?
    $(document).trigger($.Event('compose_finished.zephyr'));
    return true;
};

$(function () {
    $("#compose form").on("submit", function (e) {
       e.preventDefault();
       compose.finish();
    });
});

exports.hide = function () {
    $('input, textarea, button').blur();
    $('.message_comp').slideUp(100,
                              function() { $('#compose').css({visibility: "hidden"});});
};

exports.clear = function () {
    $("#compose").find('input[type=text], textarea').val('');
};

// Set the mode of a compose already in progress.
// Does not clear the input fields.
exports.set_mode = function (mode) {
    if (!is_composing_message) {
        exports.start(mode);
    }
    if (mode === 'private') {
        show('private', $("#private_message_recipient"));
        is_composing_message = "private";
    } else {
        show('stream', $(lurk_stream !== undefined ? "#subject" : "#stream"));
        is_composing_message = "stream";
    }
};

exports.composing = function () {
    return is_composing_message;
};

function get_or_set(fieldname) {
    // We can't hoist the assignment of 'elem' out of this lambda,
    // because the DOM element might not exist yet when get_or_set
    // is called.
    return function (newval) {
        var elem = $('#'+fieldname);
        var oldval = $.trim(elem.val());
        if (newval !== undefined) {
            elem.val(newval);
        }
        return oldval;
    };
}

exports.stream_name     = get_or_set('stream');
exports.subject         = get_or_set('subject');
exports.message_content = get_or_set('new_message_content');
exports.recipient       = get_or_set('private_message_recipient');

function compose_error(error_text, bad_input) {
    $('#send-status').removeClass(status_classes)
               .addClass('alert-error')
               .text(error_text)
               .stop(true).fadeTo(0, 1);
    $("#compose-send-button").removeAttr('disabled');
    bad_input.focus().select();
}

// *Synchronously* check if a stream exists.
// If not, displays an error and returns false.
function check_stream_for_send(stream_name) {
    var result = "error";
    $.ajax({
        type: "POST",
        url: "/json/subscriptions/exists",
        data: {'stream': stream_name},
        async: false,
        success: function (data) {
            if (!data.exists) {
                // The stream doesn't exist
                result = "does-not-exist";
                $('#send-status').removeClass(status_classes);
                $('#stream-dne-name').text(stream_name);
                $('#stream-dne').show();
                $("#compose-send-button").removeAttr('disabled');
                exports.hide();
                $('#create-it').focus();
            } else if (data.subscribed) {
                result = "subscribed";
            } else {
                result = "not-subscribed";
            }
            $("#home-error").hide();
        },
        error: function (xhr) {
            result = "error";
            ui.report_error("Error checking subscription", xhr, $("#home-error"));
            $("#stream").focus();
            $("#compose-send-button").removeAttr('disabled');
        }
    });
    return result;
}

function validate_stream_message() {
    var stream_name = exports.stream_name();
    if (stream_name === "") {
        compose_error("Please specify a stream", $("#stream"));
        return false;
    }

    if (exports.subject() === "") {
        compose_error("Please specify a subject", $("#subject"));
        return false;
    }

    if (!subs.have(stream_name)) {
        switch(check_stream_for_send(stream_name)) {
        case "does-not-exist":
        case "error":
            return false;
        case "subscribed":
            // You're actually subscribed to the stream, but this
            // browser window doesn't know it.
            return true;
        case "not-subscribed":
            if (lurk_stream.toLowerCase() === stream_name.toLowerCase()) {
                // Just subscribe them.
                subs.subscribe_for_send(stream_name);
                // When the subscription request completes,
                // subscribe_for_send will send our message (like when
                // the user clicks on subscribe-and-send).
                return false;
            }

            $('#send-status').removeClass(status_classes);
            $('#stream-nosub-name').text(stream_name);
            $('#stream-nosub').show();
            $("#compose-send-button").removeAttr('disabled');
            exports.hide();
            $('#sub-it').focus();
            return false;
        }
    }

    return true;
}

function validate_private_message() {
    if (exports.recipient() === "") {
        compose_error("Please specify at least one recipient", $("#private_message_recipient"));
        return false;
    }

    return true;
}

exports.validate = function () {
    $("#compose-send-button").attr('disabled', 'disabled').blur();

    if (exports.message_content() === "") {
        compose_error("You have nothing to send!", $("#new_message_content"));
        return false;
    }

    if (exports.composing() === 'private') {
        return validate_private_message();
    } else {
        return validate_stream_message();
    }
};

$(function () {
    $("#new_message_content").autosize();
});

return exports;

}());
<commit_msg>Fix subscribe-and-send<commit_after>var compose = (function () {

var exports = {};
var is_composing_message = false;

function show(tabname, focus_area) {
    if (tabname === "stream") {
        $('#private-message').hide();
        $('#stream-message').show();
        $("#stream_toggle").addClass("active");
        $("#private_message_toggle").removeClass("active");
    } else {
        $('#private-message').show();
        $('#stream-message').hide();
        $("#stream_toggle").removeClass("active");
        $("#private_message_toggle").addClass("active");
    }
    $("#send-status").removeClass(status_classes).hide();
    $('#compose').css({visibility: "visible"});
    $("#new_message_content").trigger("autosize");
    $('.message_comp').slideDown(100, function () {
        // If the compose box is obscuring the currently selected message,
        // scroll up until the message is no longer occluded.
        if (selected_message_id === -1) {
            // If there's no selected message, there's no need to
            // scroll the compose box to avoid it.
            return;
        }
        var cover = selected_message.offset().top + selected_message.height()
            - $("#compose").offset().top;
        if (cover > 0) {
            disable_pointer_movement = true;
            // We use $('html, body') because you can't animate window.scrollTop
            // on Chrome (http://bugs.jquery.com/ticket/10419).
            $('html, body').animate({
                scrollTop: viewport.scrollTop() + cover + 5
            }, {
                complete: function () {
                    // The complete callback is actually called before the
                    // scrolling has completed, so we try to let scrolling
                    // finish before allowing pointer movements again or the
                    // pointer may still move.
                    setTimeout(function () {
                        disable_pointer_movement = false;
                    }, 50);
                }
            });
        }
    });
    focus_area.focus();
    focus_area.select();
}

// In an attempt to decrease mixing, make the composebox's
// stream bar look like what you're replying to.
// (In particular, if there's a color associated with it,
//  have that color be reflected here too.)
exports.decorate_stream_bar = function (stream_name) {
    var color = subs.get_color(stream_name);
    $("#stream-message .message_header_stream").css("background-color", color);
};

exports.start = function (msg_type, opts) {
    if (reload.is_in_progress()) {
        return;
    }

    compose.clear();

    var default_stream = '';
    if (msg_type === 'stream' && lurk_stream !== undefined)
        default_stream = lurk_stream;
    opts = $.extend({ message_type:     msg_type,
                      stream:           default_stream,
                      subject:          '',
                      private_message_recipient: ''
                    }, opts);

    compose.stream_name(opts.stream);
    compose.subject(opts.subject);
    compose.recipient(opts.private_message_recipient);
    // If the user opens the compose box, types some text, and then clicks on a
    // different stream/subject, we want to keep the text in the compose box
    if (opts.message !== undefined) {
        compose.message_content(opts.message);
    }

    ui.change_tab_to("#home");

    var focus_area;
    if (opts.stream && ! opts.subject) {
        focus_area = 'subject';
    } else if (opts.stream || opts.private_message_recipient) {
        focus_area = 'new_message_content';
    }

    if (msg_type === 'stream') {
        show('stream', $("#" + (focus_area || 'stream')));
    } else {
        show('private', $("#" + (focus_area || 'private_message_recipient')));
    }

    is_composing_message = msg_type;
    exports.decorate_stream_bar(opts.stream);
    $(document).trigger($.Event('compose_started.zephyr', opts));
};

exports.cancel = function () {
    compose.hide();
    is_composing_message = false;
    $(document).trigger($.Event('compose_canceled.zephyr'));
};

var send_options;

function send_message() {
    var send_status = $('#send-status');

    // TODO: this should be collapsed with the code in composebox_typeahead.js
    var recipients = compose.recipient().split(/\s*[,;]\s*/);

    var request = {client: 'website',
                   type:        compose.composing(),
                   subject:     compose.subject(),
                   content:     compose.message_content()};
    if (request.type === "private") {
        request.to = JSON.stringify(recipients);
    } else {
        request.to = compose.stream_name();
    }

    $.ajax({
        dataType: 'json', // This seems to be ignored. We still get back an xhr.
        url: '/json/send_message',
        type: 'POST',
        data: request,
        success: function (resp, statusText, xhr) {
            compose.clear();
            send_status.hide();
            is_composing_message = false;
            compose.hide();
            $("#compose-send-button").removeAttr('disabled');
        },
        error: function (xhr, error_type) {
            if (error_type !== 'timeout' && reload.is_pending()) {
                // The error might be due to the server changing
                reload.initiate({immediate: true, send_after_reload: true});
                return;
            }
            var response = "Error sending message";
            if (xhr.status.toString().charAt(0) === "4") {
                // Only display the error response for 4XX, where we've crafted
                // a nice response.
                response += ": " + $.parseJSON(xhr.responseText).msg;
            }
            show(is_composing_message, $("#new_message_content"));
            send_status.removeClass(status_classes)
                       .addClass('alert-error')
                       .text(response)
                       .append($('<span />')
                           .addClass('send-status-close').html('×')
                           .click(function () { send_status.stop(true).fadeOut(500); }))
                       .stop(true).fadeTo(0,1);

            $("#compose-send-button").removeAttr('disabled');
        }
    });

    send_status.hide();
}

exports.finish = function () {
    if (! compose.validate()) {
        return false;
    }
    send_message();
    // TODO: Do we want to fire the event even if the send failed due
    // to a server-side error?
    $(document).trigger($.Event('compose_finished.zephyr'));
    return true;
};

$(function () {
    $("#compose form").on("submit", function (e) {
       e.preventDefault();
       compose.finish();
    });
});

exports.hide = function () {
    $('input, textarea, button').blur();
    $('.message_comp').slideUp(100,
                              function() { $('#compose').css({visibility: "hidden"});});
};

exports.clear = function () {
    $("#compose").find('input[type=text], textarea').val('');
};

// Set the mode of a compose already in progress.
// Does not clear the input fields.
exports.set_mode = function (mode) {
    if (!is_composing_message) {
        exports.start(mode);
    }
    if (mode === 'private') {
        show('private', $("#private_message_recipient"));
        is_composing_message = "private";
    } else {
        show('stream', $(lurk_stream !== undefined ? "#subject" : "#stream"));
        is_composing_message = "stream";
    }
};

exports.composing = function () {
    return is_composing_message;
};

function get_or_set(fieldname) {
    // We can't hoist the assignment of 'elem' out of this lambda,
    // because the DOM element might not exist yet when get_or_set
    // is called.
    return function (newval) {
        var elem = $('#'+fieldname);
        var oldval = $.trim(elem.val());
        if (newval !== undefined) {
            elem.val(newval);
        }
        return oldval;
    };
}

exports.stream_name     = get_or_set('stream');
exports.subject         = get_or_set('subject');
exports.message_content = get_or_set('new_message_content');
exports.recipient       = get_or_set('private_message_recipient');

function compose_error(error_text, bad_input) {
    $('#send-status').removeClass(status_classes)
               .addClass('alert-error')
               .text(error_text)
               .stop(true).fadeTo(0, 1);
    $("#compose-send-button").removeAttr('disabled');
    bad_input.focus().select();
}

// *Synchronously* check if a stream exists.
// If not, displays an error and returns false.
function check_stream_for_send(stream_name) {
    var result = "error";
    $.ajax({
        type: "POST",
        url: "/json/subscriptions/exists",
        data: {'stream': stream_name},
        async: false,
        success: function (data) {
            if (!data.exists) {
                // The stream doesn't exist
                result = "does-not-exist";
                $('#send-status').removeClass(status_classes);
                $('#stream-dne-name').text(stream_name);
                $('#stream-dne').show();
                $("#compose-send-button").removeAttr('disabled');
                exports.hide();
                $('#create-it').focus();
            } else if (data.subscribed) {
                result = "subscribed";
            } else {
                result = "not-subscribed";
            }
            $("#home-error").hide();
        },
        error: function (xhr) {
            result = "error";
            ui.report_error("Error checking subscription", xhr, $("#home-error"));
            $("#stream").focus();
            $("#compose-send-button").removeAttr('disabled');
        }
    });
    return result;
}

function validate_stream_message() {
    var stream_name = exports.stream_name();
    if (stream_name === "") {
        compose_error("Please specify a stream", $("#stream"));
        return false;
    }

    if (exports.subject() === "") {
        compose_error("Please specify a subject", $("#subject"));
        return false;
    }

    if (!subs.have(stream_name)) {
        switch(check_stream_for_send(stream_name)) {
        case "does-not-exist":
        case "error":
            return false;
        case "subscribed":
            // You're actually subscribed to the stream, but this
            // browser window doesn't know it.
            return true;
        case "not-subscribed":
            if (lurk_stream !== undefined &&
                lurk_stream.toLowerCase() === stream_name.toLowerCase()) {
                // Just subscribe them.
                subs.subscribe_for_send(stream_name);
                // When the subscription request completes,
                // subscribe_for_send will send our message (like when
                // the user clicks on subscribe-and-send).
                return false;
            }

            $('#send-status').removeClass(status_classes);
            $('#stream-nosub-name').text(stream_name);
            $('#stream-nosub').show();
            $("#compose-send-button").removeAttr('disabled');
            exports.hide();
            $('#sub-it').focus();
            return false;
        }
    }

    return true;
}

function validate_private_message() {
    if (exports.recipient() === "") {
        compose_error("Please specify at least one recipient", $("#private_message_recipient"));
        return false;
    }

    return true;
}

exports.validate = function () {
    $("#compose-send-button").attr('disabled', 'disabled').blur();

    if (exports.message_content() === "") {
        compose_error("You have nothing to send!", $("#new_message_content"));
        return false;
    }

    if (exports.composing() === 'private') {
        return validate_private_message();
    } else {
        return validate_stream_message();
    }
};

$(function () {
    $("#new_message_content").autosize();
});

return exports;

}());
<|endoftext|>


<commit_before>import Ember from 'ember';
import moment from 'moment';

const {
  K,
} = Ember;

export default Ember.Controller.extend({
  month: moment().startOf('month'),
  start: moment().startOf('day'),
  end: moment().startOf('day').add(2, 'days'),

  presets: [
    {
      name: 'Today',
      startDate: moment().startOf('day'),
      endDate: moment().startOf('day'),
    },
    {
      name: 'Tomorrow',
      startDate: moment().add(1, 'day').startOf('day'),
      endDate: moment().add(1, 'day').startOf('day'),
    },
    {
      name: 'This Month',
      startDate: moment().startOf('month'),
      endDate: moment().endOf('month').startOf('day'),
    },
    {
      name: 'This Year',
      startDate: moment().startOf('year'),
      endDate: moment().endOf('year').startOf('day'),
    },
    {
      name: 'Next Year',
      startDate: moment().add(1, 'year').startOf('year'),
      endDate: moment().add(1, 'year').endOf('year').startOf('day'),
    }
  ],

  actions: {
    apply: K,

    cancel: K,
  }
});
<commit_msg>remove deprecated Ember.K<commit_after>import Ember from 'ember';
import moment from 'moment';

export default Ember.Controller.extend({
  month: moment().startOf('month'),
  start: moment().startOf('day'),
  end: moment().startOf('day').add(2, 'days'),

  presets: [
    {
      name: 'Today',
      startDate: moment().startOf('day'),
      endDate: moment().startOf('day'),
    },
    {
      name: 'Tomorrow',
      startDate: moment().add(1, 'day').startOf('day'),
      endDate: moment().add(1, 'day').startOf('day'),
    },
    {
      name: 'This Month',
      startDate: moment().startOf('month'),
      endDate: moment().endOf('month').startOf('day'),
    },
    {
      name: 'This Year',
      startDate: moment().startOf('year'),
      endDate: moment().endOf('year').startOf('day'),
    },
    {
      name: 'Next Year',
      startDate: moment().add(1, 'year').startOf('year'),
      endDate: moment().add(1, 'year').endOf('year').startOf('day'),
    }
  ],

  actions: {
    apply() {},

    cancel() {},
  }
});
<|endoftext|>


<commit_before>import {createStore} from 'dummy/tests/helpers/store';
import setupStore from 'dummy/tests/helpers/store';
import Ember from 'ember';

import {module, test} from 'qunit';

import DS from 'ember-data';

var get = Ember.get;
var Person, store, allRecords;
var run = Ember.run;
var env;

module("integration/adapter/find_all - Finding All Records of a Type", {
  beforeEach: function() {
    Person = DS.Model.extend({
      updatedAt: DS.attr('string'),
      name: DS.attr('string'),
      firstName: DS.attr('string'),
      lastName: DS.attr('string')
    });

    allRecords = null;

    env = setupStore({
      person: Person
    });
    store = env.store;
  },

  afterEach: function() {
    run(function() {
      if (allRecords) { allRecords.destroy(); }
      store.destroy();
    });
  }
});

test("When all records for a type are requested, the store should call the adapter's `findAll` method.", function(assert) {
  assert.expect(5);

  env.registry.register('adapter:person', DS.Adapter.extend({
    findAll: function(store, type, since) {
      // this will get called twice
      assert.ok(true, "the adapter's findAll method should be invoked");

      return Ember.RSVP.resolve([{ id: 1, name: "Braaaahm Dale" }]);
    }
  }));

  var allRecords;

  run(function() {
    store.findAll('person').then(function(all) {
      allRecords = all;
      assert.equal(get(all, 'length'), 1, "the record array's length is 1 after a record is loaded into it");
      assert.equal(all.objectAt(0).get('name'), "Braaaahm Dale", "the first item in the record array is Braaaahm Dale");
    });
  });

  run(function() {
    store.findAll('person').then(function(all) {
      // Only one record array per type should ever be created (identity map)
      assert.strictEqual(allRecords, all, "the same record array is returned every time all records of a type are requested");
    });
  });
});

test("When all records for a type are requested, a rejection should reject the promise", function(assert) {
  assert.expect(5);

  var count = 0;
  env.registry.register('adapter:person', DS.Adapter.extend({
    findAll: function(store, type, since) {
      // this will get called twice
      assert.ok(true, "the adapter's findAll method should be invoked");

      if (count++ === 0) {
        return Ember.RSVP.reject();
      } else {
        return Ember.RSVP.resolve([{ id: 1, name: "Braaaahm Dale" }]);
      }
    }
  }));

  var allRecords;

  run(function() {
    store.findAll('person').then(null, function() {
      assert.ok(true, "The rejection should get here");
      return store.findAll('person');
    }).then(function(all) {
      allRecords = all;
      assert.equal(get(all, 'length'), 1, "the record array's length is 1 after a record is loaded into it");
      assert.equal(all.objectAt(0).get('name'), "Braaaahm Dale", "the first item in the record array is Braaaahm Dale");
    });
  });
});

test("When all records for a type are requested, records that are already loaded should be returned immediately.", function(assert) {
  assert.expect(3);
  store = createStore({
    adapter: DS.Adapter.extend(),
    person: Person
  });

  run(function() {
    // Load a record from the server
    store.push({
      data: {
        type: 'person',
        id: '1',
        attributes: {
          name: 'Jeremy Ashkenas'
        }
      }
    });
    // Create a new, unsaved record in the store
    store.createRecord('person', { name: "Alex MacCaw" });
  });

  allRecords = store.peekAll('person');

  assert.equal(get(allRecords, 'length'), 2, "the record array's length is 2");
  assert.equal(allRecords.objectAt(0).get('name'), "Jeremy Ashkenas", "the first item in the record array is Jeremy Ashkenas");
  assert.equal(allRecords.objectAt(1).get('name'), "Alex MacCaw", "the second item in the record array is Alex MacCaw");
});

test("When all records for a type are requested, records that are created on the client should be added to the record array.", function(assert) {
  assert.expect(3);

  store = createStore({
    adapter: DS.Adapter.extend(),
    person: Person
  });

  allRecords = store.peekAll('person');

  assert.equal(get(allRecords, 'length'), 0, "precond - the record array's length is zero before any records are loaded");

  run(function() {
    store.createRecord('person', { name: "Carsten Nielsen" });
  });

  assert.equal(get(allRecords, 'length'), 1, "the record array's length is 1");
  assert.equal(allRecords.objectAt(0).get('name'), "Carsten Nielsen", "the first item in the record array is Carsten Nielsen");
});
<commit_msg>[CLEANUP] Clean up adapter/find-all-test.js<commit_after>import {createStore} from 'dummy/tests/helpers/store';
import setupStore from 'dummy/tests/helpers/store';
import Ember from 'ember';
import {module, test} from 'qunit';
import DS from 'ember-data';

const { attr } = DS;
const { get, run } = Ember;
const { resolve, reject } = Ember.RSVP;

let Person, store, allRecords, env;

module("integration/adapter/find_all - Finding All Records of a Type", {
  beforeEach() {
    Person = DS.Model.extend({
      updatedAt: attr('string'),
      name: attr('string'),
      firstName: attr('string'),
      lastName: attr('string')
    });

    allRecords = null;

    env = setupStore({
      person: Person
    });
    store = env.store;
  },

  afterEach() {
    run(() => {
      if (allRecords) { allRecords.destroy(); }
      store.destroy();
    });
  }
});

test("When all records for a type are requested, the store should call the adapter's `findAll` method.", (assert) => {
  assert.expect(5);

  env.registry.register('adapter:person', DS.Adapter.extend({
    findAll() {
      // this will get called twice
      assert.ok(true, "the adapter's findAll method should be invoked");

      return resolve([{ id: 1, name: "Braaaahm Dale" }]);
    }
  }));

  let allRecords;

  run(() => {
    store.findAll('person').then((all) => {
      allRecords = all;
      assert.equal(get(all, 'length'), 1, "the record array's length is 1 after a record is loaded into it");
      assert.equal(all.objectAt(0).get('name'), "Braaaahm Dale", "the first item in the record array is Braaaahm Dale");
    });
  });

  run(() => {
    store.findAll('person').then((all) => {
      // Only one record array per type should ever be created (identity map)
      assert.strictEqual(allRecords, all, "the same record array is returned every time all records of a type are requested");
    });
  });
});

test("When all records for a type are requested, a rejection should reject the promise", (assert) => {
  assert.expect(5);

  let count = 0;
  env.registry.register('adapter:person', DS.Adapter.extend({
    findAll() {
      // this will get called twice
      assert.ok(true, "the adapter's findAll method should be invoked");

      if (count++ === 0) {
        return reject();
      } else {
        return resolve([{ id: 1, name: "Braaaahm Dale" }]);
      }
    }
  }));

  let allRecords;

  run(() => {
    store.findAll('person').then(null, () => {
      assert.ok(true, "The rejection should get here");
      return store.findAll('person');
    }).then((all) => {
      allRecords = all;
      assert.equal(get(all, 'length'), 1, "the record array's length is 1 after a record is loaded into it");
      assert.equal(all.objectAt(0).get('name'), "Braaaahm Dale", "the first item in the record array is Braaaahm Dale");
    });
  });
});

test("When all records for a type are requested, records that are already loaded should be returned immediately.", (assert) => {
  assert.expect(3);
  store = createStore({
    adapter: DS.Adapter.extend(),
    person: Person
  });

  run(() => {
    // Load a record from the server
    store.push({
      data: {
        type: 'person',
        id: '1',
        attributes: {
          name: 'Jeremy Ashkenas'
        }
      }
    });
    // Create a new, unsaved record in the store
    store.createRecord('person', { name: "Alex MacCaw" });
  });

  allRecords = store.peekAll('person');

  assert.equal(get(allRecords, 'length'), 2, "the record array's length is 2");
  assert.equal(allRecords.objectAt(0).get('name'), "Jeremy Ashkenas", "the first item in the record array is Jeremy Ashkenas");
  assert.equal(allRecords.objectAt(1).get('name'), "Alex MacCaw", "the second item in the record array is Alex MacCaw");
});

test("When all records for a type are requested, records that are created on the client should be added to the record array.", (assert) => {
  assert.expect(3);

  store = createStore({
    adapter: DS.Adapter.extend(),
    person: Person
  });

  allRecords = store.peekAll('person');

  assert.equal(get(allRecords, 'length'), 0, "precond - the record array's length is zero before any records are loaded");

  run(() => {
    store.createRecord('person', { name: "Carsten Nielsen" });
  });

  assert.equal(get(allRecords, 'length'), 1, "the record array's length is 1");
  assert.equal(allRecords.objectAt(0).get('name'), "Carsten Nielsen", "the first item in the record array is Carsten Nielsen");
});
<|endoftext|>


<commit_before>describe('MessagesCtrl', ()=> {

    let homeCtrl, mock, deferredResolution, rootScope, controllerFactory,
        mockData = [
            {
                id: 0,
                text: 'Hi, Loretta Fitzgerald'
            }
        ];

    beforeEach(angular.mock.module('espackApp'));

    describe('#construct', ()=> {

        beforeEach(()=> {
            _inject();
        });

        it('should exist', ()=> {
            homeCtrl = controllerFactory('MessagesCtrl', mock);
            expect(!!homeCtrl).toBe(true);
        });

        it('should define a messages Array property', () => {
            homeCtrl = controllerFactory('MessagesCtrl', mock);
            expect(homeCtrl.messages instanceof Array).toBe(true);
        });
    });

    describe('#init', ()=> {

        beforeEach(()=> {
            _inject();
        });

        it('should be defined', ()=> {
            homeCtrl = controllerFactory('MessagesCtrl', mock);
            expect(typeof homeCtrl.init).toBe('function');
        });

        it('should set messages property', () => {
            //given
            spyOn(mock.messageService, 'findAll').and.returnValue(deferredResolution.promise);

            //when
            deferredResolution.resolve(mockData);
            homeCtrl = controllerFactory('MessagesCtrl', mock);
            rootScope.$digest();

            //then
            expect(homeCtrl.messages.map(item=> item.text)).toEqual(mockData.map(item=> item.text));
            expect(mock.messageService.findAll).toHaveBeenCalled();
        });
    });

    describe('#loadMessages', ()=> {

        beforeEach(()=> {
            _inject();
        });

        it('should set messages property', () => {
            spyOn(mock.messageService, 'findAll').and.returnValue(deferredResolution.promise);
            homeCtrl = controllerFactory('MessagesCtrl', mock);
            homeCtrl.init = ()=> {
            };//skip initialization because of testing loadMessages

            homeCtrl.loadMessages();
            deferredResolution.resolve(mockData);
            rootScope.$digest();

            expect(homeCtrl.messages.map(item=> item.text)).toEqual(mockData.map(item => item.text));
            expect(mock.messageService.findAll).toHaveBeenCalled();
        });

    });

    function _inject() {
        inject(($controller, $rootScope, messageService, logger, $q) => {
            rootScope = $rootScope;
            controllerFactory = $controller;
            deferredResolution = $q.defer();
            mock = {
                $scope: $rootScope.$new(),
                logger,
                messageService
            };
        });
    }
});<commit_msg>bind one way in message list directive<commit_after>describe('MessagesController', ()=> {

    let homeCtrl, mock, deferredResolution, rootScope, controllerFactory,
        mockData = [
            {
                id: 0,
                text: 'Hi, Loretta Fitzgerald'
            }
        ];

    beforeEach(angular.mock.module('espackApp'));

    describe('#construct', ()=> {

        beforeEach(()=> {
            _inject();
        });

        it('should exist', ()=> {
            homeCtrl = controllerFactory('MessagesController', mock);
            expect(!!homeCtrl).toBe(true);
        });

        it('should define a messages Array property', () => {
            homeCtrl = controllerFactory('MessagesController', mock);
            expect(homeCtrl.messages instanceof Array).toBe(true);
        });
    });

    describe('#init', ()=> {

        beforeEach(()=> {
            _inject();
        });

        it('should be defined', ()=> {
            homeCtrl = controllerFactory('MessagesController', mock);
            expect(typeof homeCtrl.init).toBe('function');
        });

        it('should set messages property', () => {
            //given
            spyOn(mock.messageService, 'findAll').and.returnValue(deferredResolution.promise);

            //when
            deferredResolution.resolve(mockData);
            homeCtrl = controllerFactory('MessagesController', mock);
            rootScope.$digest();

            //then
            expect(homeCtrl.messages.map(item=> item.text)).toEqual(mockData.map(item=> item.text));
            expect(mock.messageService.findAll).toHaveBeenCalled();
        });
    });

    describe('#loadMessages', ()=> {

        beforeEach(()=> {
            _inject();
        });

        it('should set messages property', () => {
            spyOn(mock.messageService, 'findAll').and.returnValue(deferredResolution.promise);
            homeCtrl = controllerFactory('MessagesController', mock);
            homeCtrl.init = ()=> {
            };//skip initialization because of testing loadMessages

            homeCtrl.loadMessages();
            deferredResolution.resolve(mockData);
            rootScope.$digest();

            expect(homeCtrl.messages.map(item=> item.text)).toEqual(mockData.map(item => item.text));
            expect(mock.messageService.findAll).toHaveBeenCalled();
        });

    });

    function _inject() {
        inject(($controller, $rootScope, messageService, logger, $q) => {
            rootScope = $rootScope;
            controllerFactory = $controller;
            deferredResolution = $q.defer();
            mock = {
                $scope: $rootScope.$new(),
                logger,
                messageService
            };
        });
    }
});<|endoftext|>


<commit_before>/*jshint expr:true */
describe('PasswordProtectedModelBase', function() {
  describe('composedUrl', function() {
    console.log("PasswordProtectedModelBase test");
    beforeEach(function() {
      this.model = new spiderOakApp.PasswordProtectedModelBase({
        url: "filename.pdf",
        urlBase: "base/"
      });
    });
    it('should have a URL', function() {
      this.model.get("url").should.be.a("string");
      this.model.get("url").should.equal("filename.pdf");
    });
    it('should have a urlBase', function() {
      this.model.get("urlBase").should.be.a("string");
      this.model.get("urlBase").should.equal("base/");
    });
    it('composedUrl should combine url and urlBase' +
       ', with auth_required_format...', function() {
         this.model.composedUrl().should.be.a("string");
         this.model.composedUrl().should.equal(
           "base/filename.pdf?auth_required_format=json"
         );
       });
    it('composedUrl auth_required_format should be inhibited properly',
       function() {
         this.model.composedUrl().should.be.a("string");
         this.model.composedUrl(true).should.equal("base/filename.pdf");
       });
    it('composedUrl auth_required_format should have just one "?", one "&"',
       function() {
         this.model.set("url", "filename.pdf?arbitrary=stuff");
         this.model.composedUrl().should.be.a("string");
         // Order-insensitive tests, since query string order is not defined.
         this.model.composedUrl().should.match(/arbitrary=stuff/);
         this.model.composedUrl().should.match(/auth_required_format=json/);
         this.model.composedUrl().should.match(/\?/);
         this.model.composedUrl().should.match(/&/);
         this.model.composedUrl().should.not.match(/\?.*\?/);
         this.model.composedUrl().should.not.match(/&.*&/);
       });
  });
});
<commit_msg>Remove debugging console.log() message.<commit_after>/*jshint expr:true */
describe('PasswordProtectedModelBase', function() {
  describe('composedUrl', function() {
    beforeEach(function() {
      this.model = new spiderOakApp.PasswordProtectedModelBase({
        url: "filename.pdf",
        urlBase: "base/"
      });
    });
    it('should have a URL', function() {
      this.model.get("url").should.be.a("string");
      this.model.get("url").should.equal("filename.pdf");
    });
    it('should have a urlBase', function() {
      this.model.get("urlBase").should.be.a("string");
      this.model.get("urlBase").should.equal("base/");
    });
    it('composedUrl should combine url and urlBase' +
       ', with auth_required_format...', function() {
         this.model.composedUrl().should.be.a("string");
         this.model.composedUrl().should.equal(
           "base/filename.pdf?auth_required_format=json"
         );
       });
    it('composedUrl auth_required_format should be inhibited properly',
       function() {
         this.model.composedUrl().should.be.a("string");
         this.model.composedUrl(true).should.equal("base/filename.pdf");
       });
    it('composedUrl auth_required_format should have just one "?", one "&"',
       function() {
         this.model.set("url", "filename.pdf?arbitrary=stuff");
         this.model.composedUrl().should.be.a("string");
         // Order-insensitive tests, since query string order is not defined.
         this.model.composedUrl().should.match(/arbitrary=stuff/);
         this.model.composedUrl().should.match(/auth_required_format=json/);
         this.model.composedUrl().should.match(/\?/);
         this.model.composedUrl().should.match(/&/);
         this.model.composedUrl().should.not.match(/\?.*\?/);
         this.model.composedUrl().should.not.match(/&.*&/);
       });
  });
});
<|endoftext|>


<commit_before>var http = require('http');
var should = require('should');
var config = require('./config.js');
var server = require('./simpleServer.js');
var utils = require('./utils.js');

var applicationContent = 'application/json',
    relayerHost = 'http://localhost:' + config.simpleServerPort,
    personalHeader1name = 'personal-header-1',
    personalHeader1value = 'TEST1',
    personalHeader2name = 'personal-header-2',
    personalHeader2value = 'TEST2';

var options = {};
options.host = config.rushServer.hostname;
options.port = config.rushServer.port;
options.headers = {};
options.headers['content-type'] = applicationContent;
options.headers[personalHeader1name] = personalHeader1value;
options.headers[personalHeader2name] = personalHeader2value;

function testHeraders (headers) {
    headers.should.have.property('content-type', applicationContent);
    headers.should.have.property(personalHeader1name, personalHeader1value);
    headers.should.have.property(personalHeader2name, personalHeader2value);
}

function makeRequest(type, persistence, content, done) {
    'use strict';
    //Variables
    var httpcallback = 'http://localhost:' + config.callBackPort,
        server_callback, id;

    //Start up the server
    server.serverListener(

        function () {

            //Petition method
            options.method = type;
            options.headers['x-relayer-persistence'] = persistence;
            options.headers['x-relayer-host'] = relayerHost;
            options.headers['x-relayer-httpcallback'] = httpcallback;

            utils.makeRequest(options, content, function (e, data) {
                id = JSON.parse(data).id;
            });
        },

        function (method, headers, contentReceived) {
            method.should.be.equal(type);
            testHeraders(headers);
            contentReceived.should.be.equal(content);
        }
    );

    //Callback Server
    server_callback = http.createServer(function (req, res) {

        var response = '';

        req.on('data',
            function (chunk) {
                response += chunk;
            });

        req.on('end', function () {
            res.writeHead(200);
            res.end();
            server_callback.close();

            //Check content and headers
            var JSONRes = JSON.parse(response);
            JSONRes.body.should.be.equal(content);

            testHeraders(JSONRes.headers);

            // Check persistence
            var options = { port: config.rushServer.port, host: 'localhost', path: '/response/' + id, method: 'GET'};
            utils.makeRequest(options, '', function (err, data) {

                var JSONRes = JSON.parse(data);

                if (persistence === 'BODY') {

                    JSONRes.body.should.be.equal(content);
                    var headers = JSON.parse(JSONRes.headers);
                    testHeraders(headers);
                    JSONRes.should.have.property('statusCode', '200');

                } else if (persistence === 'HEADER') {

                    JSONRes.should.not.have.property('body');
                    var headers = JSON.parse(JSONRes.headers);
                    testHeraders(headers);
                    JSONRes.should.have.property('statusCode', '200');

                } else if (persistence === 'STATUS') {

                    JSONRes.should.not.have.property('body');
                    JSONRes.should.not.have.property('headers');
                    JSONRes.should.have.property('statusCode', '200');

                }

                done();
            });

        });
    }).listen(config.callBackPort);
}

describe('Persistence_HTTPCallback', function () {
    'use strict';
    var content = 'Persistence&HTTPCallBack Test';

    describe('#POST', function () {

        it('Persistence: BODY', function (done) {
            makeRequest('POST', 'BODY', content, done);
        })

        it('Persistence: HEADER', function (done) {
            makeRequest('POST', 'HEADER', content, done);
        })

        it('Persistence: STATUS', function (done) {
            makeRequest('POST', 'STATUS', content, done);
        })
    });

    describe('#PUT', function () {

        it('Persistence: BODY', function (done) {
            makeRequest('PUT', 'BODY', content, done);
        })

        it('Persistence: HEADER', function (done) {
            makeRequest('PUT', 'HEADER', content, done);
        })

        it('Persistence: STATUS', function (done) {
            makeRequest('PUT', 'STATUS', content, done);
        })
    });

    describe('#GET', function () {

        it('Persistence: BODY', function (done) {
            makeRequest('GET', 'BODY', '', done);
        })

        it('Persistence: HEADER', function (done) {
            makeRequest('GET', 'HEADER', '', done);
        })

        it('Persistence: STATUS', function (done) {
            makeRequest('GET', 'STATUS', '', done);
        })
    });

    describe('#DELETE', function () {

        it('Persistence: BODY', function (done) {
            makeRequest('DELETE', 'BODY', '', done);
        })

        it('Persistence: HEADER', function (done) {
            makeRequest('DELETE', 'HEADER', '', done);
        })

        it('Persistence: STATUS', function (done) {
            makeRequest('DELETE', 'STATUS', '', done);
        })
    })

    describe('Second petition should be completed even if the first callback is incorrect', function () {

        it('CallBack Incorrect', function (done) {

            var id, type = 'POST', httpCallBack = 'http://noexiste:2222';

            server.serverListener(

                function () {

                    //Petition method
                    options.method = type;
                    options.headers['x-relayer-persistence'] = 'BODY';
                    options.headers['x-relayer-host'] = relayerHost;
                    options.headers['x-relayer-httpcallback'] = httpCallBack;

                    utils.makeRequest(options, content, function (e, data) {
                        id = JSON.parse(data).id;
                    });
                },

                function (method, headers, contentReceived) {
                    method.should.be.equal(type);
                    testHeraders(headers);
                    contentReceived.should.be.equal(content);

                    setTimeout(
                        function () {
                            var options = { port: 3001, host: 'localhost', path: '/response/' + id, method: 'GET'};
                            utils.makeRequest(options, '', function (err, data) {

                                var JSONRes = JSON.parse(data);

                                JSONRes.body.should.be.equal(content);
                                var headers = JSON.parse(JSONRes.headers);
                                testHeraders(headers);

                                JSONRes.should.have.property('statusCode', '200');
                                JSONRes.should.have.property('callback_err', 'ENOTFOUND(getaddrinfo)');

                                done();
                            });
                        }
                    , 1000); //Wait for callback to be completed
                }
            );
        })

        it('CallBack Correct', function (done) {
            makeRequest('POST', 'BODY', content, done);
        })
    })

    describe('Callback has to be called even if the Host is incorrect', function() {
        it ('Should receive a callback with an error', function (done) {

            var portCallBack = config.callBackPort,
                server_callback,
                relayerHost = 'http://noexiste:1234',
                httpCallBack = 'http://localhost:' + portCallBack, id;

            //Callback Server
            server_callback = http.createServer(function (req, res) {

                var response = '';

                req.on('data',
                    function (chunk) {
                        response += chunk;
                    });

                req.on('end',
                    function () {

                        var parsedJSON = JSON.parse(response);
                        should.not.exist(parsedJSON.result);

                        //Test content
                        parsedJSON.should.have.property('error', 'ENOTFOUND(getaddrinfo)');

                        res.writeHead(200);
                        res.end();
                        server_callback.close();

                        var options = { port: config.rushServer.port, host: 'localhost', path: '/response/' + id, method: 'GET'};
                        utils.makeRequest(options, '', function (err, data) {

                            var JSONparsed = JSON.parse(data);

                            JSONparsed.should.have.property('error', 'ENOTFOUND(getaddrinfo)');
                            JSONparsed.should.have.property('callback_status', '200');

                            done();
                        });
                    });

            }).listen(portCallBack,
                function () {
                    //Petition method
                    options.method = 'POST';
                    options.headers['x-relayer-host'] = 'BODY';
                    options.headers['X-Relayer-Host'] = relayerHost;
                    options.headers['x-relayer-httpcallback'] = httpCallBack;

                    utils.makeRequest(options, content,
                        function (err, data) {
                            id = JSON.parse(data).id;
                        }
                    );
                }
            );
        })
    });
});<commit_msg>new persistence_HTTPCallbackTest<commit_after>var http = require('http');
var should = require('should');
var config = require('./config.js');
var server = require('./simpleServer.js');
var utils = require('./utils.js');

var applicationContent = 'application/json',
    relayerHost = 'http://localhost:' + config.simpleServerPort,
    personalHeader1name = 'personal-header-1',
    personalHeader1value = 'TEST1',
    personalHeader2name = 'personal-header-2',
    personalHeader2value = 'TEST2';

var options = {};
options.host = config.rushServer.hostname;
options.port = config.rushServer.port;
options.headers = {};
options.headers['content-type'] = applicationContent;
options.headers[personalHeader1name] = personalHeader1value;
options.headers[personalHeader2name] = personalHeader2value;

function testHeraders (headers) {
    headers.should.have.property('content-type', applicationContent);
    headers.should.have.property(personalHeader1name, personalHeader1value);
    headers.should.have.property(personalHeader2name, personalHeader2value);
}

function makeRequest(type, persistence, content, done) {
    'use strict';
    //Variables
    var httpcallback = 'http://localhost:' + config.callBackPort,
        server_callback, id;

    //Start up the server
    server.serverListener(

        function () {

            //Petition method
            options.method = type;
            options.headers['x-relayer-persistence'] = persistence;
            options.headers['x-relayer-host'] = relayerHost;
            options.headers['x-relayer-httpcallback'] = httpcallback;

            utils.makeRequest(options, content, function (e, data) {
                id = JSON.parse(data).id;
            });
        },

        function (method, headers, contentReceived) {
            method.should.be.equal(type);
            testHeraders(headers);
            contentReceived.should.be.equal(content);
        }
    );

    //Callback Server
    server_callback = http.createServer(function (req, res) {

        var response = '';

        req.on('data',
            function (chunk) {
                response += chunk;
            });

        req.on('end', function () {
            res.writeHead(200);
            res.end();
            server_callback.close();

            //Check content and headers
            var JSONRes = JSON.parse(response);
            JSONRes.body.should.be.equal(content);

            testHeraders(JSONRes.headers);

            // Check persistence
            var options = { port: config.rushServer.port, host: 'localhost', path: '/response/' + id, method: 'GET'};
            utils.makeRequest(options, '', function (err, data) {

                var JSONRes = JSON.parse(data);

                if (persistence === 'BODY') {

                    JSONRes.body.should.be.equal(content);
                    var headers = JSON.parse(JSONRes.headers);
                    testHeraders(headers);
                    JSONRes.should.have.property('statusCode', '200');

                } else if (persistence === 'HEADER') {

                    JSONRes.should.not.have.property('body');
                    var headers = JSON.parse(JSONRes.headers);
                    testHeraders(headers);
                    JSONRes.should.have.property('statusCode', '200');

                } else if (persistence === 'STATUS') {

                    JSONRes.should.not.have.property('body');
                    JSONRes.should.not.have.property('headers');
                    JSONRes.should.have.property('statusCode', '200');

                }

                done();
            });

        });
    }).listen(config.callBackPort);
}

describe('Persistence_HTTPCallback', function () {
    'use strict';
    var content = 'Persistence&HTTPCallBack Test';

    describe('#POST', function () {

        it('Persistence: BODY', function (done) {
            makeRequest('POST', 'BODY', content, done);
        })

        it('Persistence: HEADER', function (done) {
            makeRequest('POST', 'HEADER', content, done);
        })

        it('Persistence: STATUS', function (done) {
            makeRequest('POST', 'STATUS', content, done);
        })
    });

    describe('#PUT', function () {

        it('Persistence: BODY', function (done) {
            makeRequest('PUT', 'BODY', content, done);
        })

        it('Persistence: HEADER', function (done) {
            makeRequest('PUT', 'HEADER', content, done);
        })

        it('Persistence: STATUS', function (done) {
            makeRequest('PUT', 'STATUS', content, done);
        })
    });

    describe('#GET', function () {

        it('Persistence: BODY', function (done) {
            makeRequest('GET', 'BODY', '', done);
        })

        it('Persistence: HEADER', function (done) {
            makeRequest('GET', 'HEADER', '', done);
        })

        it('Persistence: STATUS', function (done) {
            makeRequest('GET', 'STATUS', '', done);
        })
    });

    describe('#DELETE', function () {

        it('Persistence: BODY', function (done) {
            makeRequest('DELETE', 'BODY', '', done);
        })

        it('Persistence: HEADER', function (done) {
            makeRequest('DELETE', 'HEADER', '', done);
        })

        it('Persistence: STATUS', function (done) {
            makeRequest('DELETE', 'STATUS', '', done);
        })
    })

    describe('Second petition should be completed even if the first callback is incorrect', function () {

        it('CallBack Incorrect', function (done) {

            var id, type = 'POST', httpCallBack = 'http://noexiste:2222';

            server.serverListener(

                function () {

                    //Petition method
                    options.method = type;
                    options.headers['x-relayer-persistence'] = 'BODY';
                    options.headers['x-relayer-host'] = relayerHost;
                    options.headers['x-relayer-httpcallback'] = httpCallBack;

                    utils.makeRequest(options, content, function (e, data) {
                        id = JSON.parse(data).id;
                    });
                },

                function (method, headers, contentReceived) {
                    method.should.be.equal(type);
                    testHeraders(headers);
                    contentReceived.should.be.equal(content);

                    setTimeout(
                        function () {
                            var options = { port: 3001, host: 'localhost', path: '/response/' + id, method: 'GET'};
                            utils.makeRequest(options, '', function (err, data) {

                                var JSONRes = JSON.parse(data);

                                JSONRes.body.should.be.equal(content);
                                var headers = JSON.parse(JSONRes.headers);
                                testHeraders(headers);

                                JSONRes.should.have.property('statusCode', '200');
                                JSONRes.should.have.property('callback_err', 'ENOTFOUND(getaddrinfo)');

                                done();
                            });
                        }
                    , 1000); //Wait for callback to be completed
                }
            );
        })

        it('CallBack Correct', function (done) {
            makeRequest('POST', 'BODY', content, done);
        })
    })

    describe('Callback has to be called even if the Host is incorrect', function() {
        it ('Should receive a callback with an error', function (done) {

            var portCallBack = config.callBackPort,
                server_callback,
                relayerHost = 'http://noexiste:1234',
                httpCallBack = 'http://localhost:' + portCallBack, id;

            //Callback Server
            server_callback = http.createServer(function (req, res) {

                var response = '';

                req.on('data',
                    function (chunk) {
                        response += chunk;
                    });

                req.on('end',
                    function () {

                        var parsedJSON = JSON.parse(response);
                        should.not.exist(parsedJSON.result);

                        //Test content
                        parsedJSON.should.have.property('error', 'ENOTFOUND(getaddrinfo)');

                        res.writeHead(200);
                        res.end();
                        server_callback.close();

                        var options = { port: config.rushServer.port, host: 'localhost', path: '/response/' + id, method: 'GET'};
                        setTimeout(function () {
                            utils.makeRequest(options, '', function (err, data) {
                                var JSONparsed = JSON.parse(data);
                                JSONparsed.should.have.property('error', 'ENOTFOUND(getaddrinfo)');
                                JSONparsed.should.have.property('callback_status', '200');
                                done();
                            });
                        }, 30)

                    });
            }).listen(portCallBack,
                function () {
                    //Petition method
                    options.method = 'POST';
                    options.headers['x-relayer-host'] = 'BODY';
                    options.headers['X-Relayer-Host'] = relayerHost;
                    options.headers['x-relayer-httpcallback'] = httpCallBack;

                    utils.makeRequest(options, content,
                        function (err, data) {
                            id = JSON.parse(data).id;
                        }
                    );
                }
            );
        })
    });
});<|endoftext|>