HansHammel/watchmen

View on GitHub
coverage/lcov-report/lib/notifications/notifications.js.html

Summary

Maintainability
Test Coverage
<!doctype html>
<html lang="en">
<head>
    <title>Code coverage report for lib/notifications/notifications.js</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="../../prettify.css">
    <link rel="stylesheet" href="../../base.css">
    <style type='text/css'>
        div.coverage-summary .sorter {
            background-image: url(../../sort-arrow-sprite.png);
        }
    </style>
</head>
<body>
<div class="header high">
    <h1>Code coverage report for <span class="entity">lib/notifications/notifications.js</span></h1>
    <h2>
        Statements: <span class="metric">83.33% <small>(50 / 60)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
        Branches: <span class="metric">55% <small>(11 / 20)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
        Functions: <span class="metric">82.35% <small>(14 / 17)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
        Lines: <span class="metric">82.76% <small>(48 / 58)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
        Ignored: <span class="metric"><span class="ignore-none">none</span></span> &nbsp;&nbsp;&nbsp;&nbsp;
    </h2>
    <div class="path"><a href="../../index.html">All files</a> &#187; <a href="index.html">lib/notifications/</a> &#187; notifications.js</div>
</div>
<div class="body">
<pre><table class="coverage">
<tr><td class="line-count">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163</td><td class="line-coverage"><span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">14</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">2</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">2</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">4</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">4</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">3</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-yes">4</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">2</span>
<span class="cline-any cline-yes">2</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">22</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">11</span>
<span class="cline-any cline-yes">21</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">3</span>
<span class="cline-any cline-yes">4</span>
<span class="cline-any cline-yes">4</span>
<span class="cline-any cline-yes">4</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">var async = require('async');
var fs = require('fs');
var colors = require('colors');
var _ = require('lodash');
var debug = require('debug')('notifications');
var defaultConfig = require('../../config/notifications/notifications');
&nbsp;
/**
 * Notifications Service
 */
&nbsp;
var EMAIL_SUBJECT_PREFIX = '[watchmen]';
var CONCURRENCY_LIMIT = 10;
&nbsp;
exports = module.exports = NotificationService;
&nbsp;
function NotificationService(config) {
    this.config = config || defaultConfig;
}
&nbsp;
/**
 * Send "down" alert to the registered notification services
 * @param service
 * @param err
 * @param cb
 */
&nbsp;
NotificationService.prototype.sendServiceDownAlert = function(service, state, cb) {
    var options = {
        title: EMAIL_SUBJECT_PREFIX + ' ' + service.name + ' is down!',
        body: service.name + ' is down!. Reason: ' + state.error
    };
    this._sendAlertIfRequired(service, options, cb);
};
&nbsp;
/**
 * Send "service back up" alert to the registered notification services
 * @param service
 * @param cb
 */
&nbsp;
NotificationService.prototype.sendServiceBackAlert = function(service, outage, cb) {
    var options = {
        title: EMAIL_SUBJECT_PREFIX + ' ' + service.name + ' is back!',
        body: service.name + ' is back. Down for ' + outage.downtime
    };
    this._sendAlertIfRequired(service, options, cb);
};
&nbsp;
/**
 * @params options.to: {Array} list of recipients
 * @params options.title: {string}
 * @params options.body: {string}
 * @params options.cb: {Function} callback.
 * @private
 */
&nbsp;
NotificationService.prototype._send = function(options, cb){
    var config = this.config;
&nbsp;
    <span class="missing-if-branch" title="else path not taken" >E</span>if (errorsInConfig(config)){
        return cb('invalid configuration in NotificationService');
    }
&nbsp;
<span class="fstat-no" title="function not covered" >    function send(notificationService, callback){</span>
<span class="cstat-no" title="statement not covered" >        debug('sending notification', options);</span>
<span class="cstat-no" title="statement not covered" >        notificationService.send(options, callback);</span>
    }
&nbsp;
<span class="cstat-no" title="statement not covered" >    var enabledServices = this.getEnabledServices();</span>
<span class="cstat-no" title="statement not covered" >    if (!enabledServices.length) {</span>
<span class="cstat-no" title="statement not covered" >        debug('no enabled notification services found');</span>
    }
<span class="cstat-no" title="statement not covered" >    async.mapLimit(enabledServices, CONCURRENCY_LIMIT, send, <span class="fstat-no" title="function not covered" >function (err){</span></span>
<span class="cstat-no" title="statement not covered" >        cb(err, err ? null : 'notifications sent!');</span>
    })
};
&nbsp;
/**
 * Get enable services
 * @returns {Array} enabled services
 */
&nbsp;
NotificationService.prototype.getEnabledServices = function() {
    return getServicesFromConfig(this.config.services.filter(function (serviceConfig) {
        return serviceConfig.enabled;
    }));
};
&nbsp;
/**
 * Send alert about a service with the provided options
 * @param service
 * @param options
 * @param cb
 * @returns {*|consoleOutputHandler}
 * @private
 */
&nbsp;
NotificationService.prototype._sendAlertIfRequired = function (service, options, cb) {
    cb = cb || <span class="branch-1 cbranch-no" title="branch not covered" >consoleOutputHandler;</span>
    var alwaysToArray = (this.config.alwaysAlertTo ? this.config.alwaysAlertTo.split(",") : []);
    var recipients = this._getRecipients(service, alwaysToArray);
    if (recipients.length) {
        this._send({
            to: recipients,
            title: options.title,
            body: options.body
        }, cb);
    }
    else {
        debug('no recipients configured for ' + service.name);
        cb();
    }
    return cb;
};
&nbsp;
/**
 * Get recipients for a service, taking in consideration global configuration
 * @param {Object} service
 * @returns {Array} list of recipients
 * @private
 */
&nbsp;
NotificationService.prototype._getRecipients = function (service, alwaysAlertTo) {
    function trim (arr){
        return arr.map(function(s){ return s.trim()});
    }
    var serviceAlertTo = (service.alertTo || '').split(',');
    return _.union(trim(serviceAlertTo), trim(alwaysAlertTo)).filter(function(i){return i}); ;
};
&nbsp;
&nbsp;
/**
 * Console output callback handler
 * @param err
 */
&nbsp;
<span class="fstat-no" title="function not covered" >function consoleOutputHandler (err){</span>
<span class="cstat-no" title="statement not covered" >    if (err) {</span>
<span class="cstat-no" title="statement not covered" >        console.error(err.red);</span>
    }
}
&nbsp;
/**
 * Returns error if invalid configuration. Otherwise it returns null
 * @param config
 * @returns {string} errors or null if ok
 */
&nbsp;
function errorsInConfig (config){
    <span class="missing-if-branch" title="else path not taken" >E</span>if (!config.services) {
        return "list of services are required";
    }
<span class="cstat-no" title="statement not covered" >    return null;</span>
}
&nbsp;
function getServicesFromConfig(servicesConfig) {
    return servicesConfig.map(function(serviceConfig){
        var serviceFactory = require(serviceConfig.path);
        var options = require(serviceConfig.config);
        return new serviceFactory(options);
    });
}</pre></td></tr>
</table></pre>

</div>
<div class="footer">
    <div class="meta">Generated by <a href="http://istanbul-js.org/" target="_blank">istanbul</a> at Sun Jun 21 2015 20:01:25 GMT+1000 (AEST)</div>
</div>
<script src="../../prettify.js"></script>
<script>
window.onload = function () {
        if (typeof prettyPrint === 'function') {
            prettyPrint();
        }
};
</script>
<script src="../../sorter.js"></script>
</body>
</html>