<commit_before>var nThen = require("nthen");

var Store = require("../storage/file");
var Pinned = require("./pinned");
var config = require("../lib/load-config");

// the administrator should have set an 'inactiveTime' in their config
// if they didn't, just exit.
if (!config.inactiveTime || typeof(config.inactiveTime) !== "number") { return; }

// files which have not been changed since before this date can be considered inactive
var inactiveTime = +new Date() - (config.inactiveTime * 24 * 3600 * 1000);

// files which were archived before this date can be considered safe to remove
var retentionTime = +new Date() - (config.archiveRetentionTime * 24 * 3600 * 1000);

var store;
var pins;
var Log;
nThen(function (w) {
    // load the store which will be used for iterating over channels
    // and performing operations like archival and deletion
    Store.create(config, w(function (_) {
        store = _;
    })); // load the list of pinned files so you know which files
    // should not be archived or deleted
    Pinned.load(function (err, _) {
        if (err) {
            w.abort();
            return void console.error(err);
        }
        pins = _;
    }, {
        pinPath: config.pinPath,
    });

    // load the logging module so that you have a record of which
    // files were archived or deleted at what time
    var Logger = require("../lib/log");
    Logger.create(config, w(function (_) {
        Log = _;
    }));
}).nThen(function (w) {
    // this block will iterate over archived channels and remove them
    // if they've been in cold storage for longer than your configured archive time

    // if the admin has not set an 'archiveRetentionTime', this block makes no sense
    // so just skip it
    if (typeof(config.archiveRetentionTime) !== "number") { return; }

    // count the number of files which have been removed in this run
    var removed = 0;

    var handler = function (err, item) {
        if (err) { return void Log.error('EVICT_ARCHIVED_CHANNEL_ITERATION', err); }
        // don't mess with files that are freshly stored in cold storage
        // based on ctime because that's changed when the file is moved...
        if (+new Date(item.ctime) > retentionTime) { return; }

        // but if it's been stored for the configured time...
        // expire it
        store.removeArchivedChannel(item.channel, w(function (err) {
            if (err) {
                return void Log.error('EVICT_ARCHIVED_CHANNEL_REMOVAL_ERROR', {
                    error: err,
                    channel: item.channel,
                });
            }
            console.log("removed %s from cold storage", item.channel);
            Log.info('EVICT_ARCHIVED_CHANNEL_REMOVAL', item.channel);
            removed++;
        }));
    };

    // if you hit an error, log it
    // otherwise, when there are no more channels to process
    // log some stats about how many were removed
    var cb = function (err) {
        if (err) {
            return Log.error('EVICT_ARCHIVED_FINAL_ERROR', err);
        }
        Log.info('EVICT_ARCHIVED_CHANNELS_REMOVED', removed);
    };

    store.listArchivedChannels(handler, w(cb));
}).nThen(function (w) {
    var removed = 0;
    var channels = 0;
    var archived = 0;

    var handler = function (err, item) {
        channels++;
        if (err) { return void Log.error('EVICT_CHANNEL_ITERATION', err); }
        // check if the database has any ephemeral channels
        // if it does it's because of a bug, and they should be removed
        if (item.channel.length === 34) {
            return void store.removeChannel(item.channel, w(function (err) {
                if (err) {
                    return void Log.error('EVICT_EPHEMERAL_CHANNEL_REMOVAL_ERROR', {
                        error: err,
                        channel: item.channel,
                    });
                }
                Log.info('EVICT_EPHEMERAL_CHANNEL_REMOVAL', item.channel);
            }));
        }

        // bail out if the channel was modified recently
        if (+new Date(item.mtime) > inactiveTime) { return; }

        // ignore the channel if it's pinned
        if (pins[item.channel]) { return; }

        // if the server is configured to retain data, archive the channel
        if (config.retainData) {
            store.archiveChannel(item.channel, w(function (err) {
                if (err) { return void Log.error('EVICT_CHANNEL_ARCHIVAL_ERROR', {
                    error: err,
                    channel: item.channel,
                }); }
                Log.info('EVICT_CHANNEL_ARCHIVAL', item.channel);
                archived++;
            }));
            return;
        }

        // otherwise remove it
        store.removeChannel(item.channel, w(function (err) {
            if (err) { return void Log.error('EVICT_CHANNEL_REMOVAL_ERROR', {
                error: err,
                channel: item.channel,
            }); }
            Log.info('EVICT_CHANNEL_REMOVAL', item.channel);
            removed++;
        }));
    };

    var cb = function () {
        if (config.retainData) {
            return void Log.info('EVICT_CHANNELS_ARCHIVED', archived);
        }
        return void Log.info('EVICT_CHANNELS_REMOVED', removed);
    };

    store.listChannels(handler, w(cb));
}).nThen(function () {
    // the store will keep this script running if you don't shut it down
    store.shutdown();
});

<commit_msg>fix a race condition, shutdown the log when you're done<commit_after>var nThen = require("nthen");

var Store = require("../storage/file");
var Pinned = require("./pinned");
var config = require("../lib/load-config");

// the administrator should have set an 'inactiveTime' in their config
// if they didn't, just exit.
if (!config.inactiveTime || typeof(config.inactiveTime) !== "number") { return; }

// files which have not been changed since before this date can be considered inactive
var inactiveTime = +new Date() - (config.inactiveTime * 24 * 3600 * 1000);

// files which were archived before this date can be considered safe to remove
var retentionTime = +new Date() - (config.archiveRetentionTime * 24 * 3600 * 1000);

var store;
var pins;
var Log;
nThen(function (w) {
    // load the store which will be used for iterating over channels
    // and performing operations like archival and deletion
    Store.create(config, w(function (_) {
        store = _;
    })); // load the list of pinned files so you know which files
    // should not be archived or deleted
    Pinned.load(w(function (err, _) {
        if (err) {
            w.abort();
            return void console.error(err);
        }
        pins = _;
    }, {
        pinPath: config.pinPath,
    }));

    // load the logging module so that you have a record of which
    // files were archived or deleted at what time
    var Logger = require("../lib/log");
    Logger.create(config, w(function (_) {
        Log = _;
    }));
}).nThen(function (w) {
    // this block will iterate over archived channels and remove them
    // if they've been in cold storage for longer than your configured archive time

    // if the admin has not set an 'archiveRetentionTime', this block makes no sense
    // so just skip it
    if (typeof(config.archiveRetentionTime) !== "number") { return; }

    // count the number of files which have been removed in this run
    var removed = 0;

    var handler = function (err, item) {
        if (err) { return void Log.error('EVICT_ARCHIVED_CHANNEL_ITERATION', err); }
        // don't mess with files that are freshly stored in cold storage
        // based on ctime because that's changed when the file is moved...
        if (+new Date(item.ctime) > retentionTime) { return; }

        // but if it's been stored for the configured time...
        // expire it
        store.removeArchivedChannel(item.channel, w(function (err) {
            if (err) {
                return void Log.error('EVICT_ARCHIVED_CHANNEL_REMOVAL_ERROR', {
                    error: err,
                    channel: item.channel,
                });
            }
            Log.info('EVICT_ARCHIVED_CHANNEL_REMOVAL', item.channel);
            removed++;
        }));
    };

    // if you hit an error, log it
    // otherwise, when there are no more channels to process
    // log some stats about how many were removed
    var cb = function (err) {
        if (err) {
            return Log.error('EVICT_ARCHIVED_FINAL_ERROR', err);
        }
        Log.info('EVICT_ARCHIVED_CHANNELS_REMOVED', removed);
    };

    store.listArchivedChannels(handler, w(cb));
}).nThen(function (w) {
    var removed = 0;
    var channels = 0;
    var archived = 0;

    var handler = function (err, item) {
        channels++;
        if (err) { return void Log.error('EVICT_CHANNEL_ITERATION', err); }
        // check if the database has any ephemeral channels
        // if it does it's because of a bug, and they should be removed
        if (item.channel.length === 34) {
            return void store.removeChannel(item.channel, w(function (err) {
                if (err) {
                    return void Log.error('EVICT_EPHEMERAL_CHANNEL_REMOVAL_ERROR', {
                        error: err,
                        channel: item.channel,
                    });
                }
                Log.info('EVICT_EPHEMERAL_CHANNEL_REMOVAL', item.channel);
            }));
        }

        // bail out if the channel was modified recently
        if (+new Date(item.mtime) > inactiveTime) { return; }

        // ignore the channel if it's pinned
        if (pins[item.channel]) { return; }

        // if the server is configured to retain data, archive the channel
        if (config.retainData) {
            store.archiveChannel(item.channel, w(function (err) {
                if (err) { return void Log.error('EVICT_CHANNEL_ARCHIVAL_ERROR', {
                    error: err,
                    channel: item.channel,
                }); }
                Log.info('EVICT_CHANNEL_ARCHIVAL', item.channel);
                archived++;
            }));
            return;
        }

        // otherwise remove it
        store.removeChannel(item.channel, w(function (err) {
            if (err) { return void Log.error('EVICT_CHANNEL_REMOVAL_ERROR', {
                error: err,
                channel: item.channel,
            }); }
            Log.info('EVICT_CHANNEL_REMOVAL', item.channel);
            removed++;
        }));
    };

    var cb = function () {
        if (config.retainData) {
            return void Log.info('EVICT_CHANNELS_ARCHIVED', archived);
        }
        return void Log.info('EVICT_CHANNELS_REMOVED', removed);
    };

    store.listChannels(handler, w(cb));
}).nThen(function () {
    // the store will keep this script running if you don't shut it down
    store.shutdown();
    Log.shutdown();
});

<|endoftext|>


<commit_before>var assert = require("assert-plus"),
  i18niso = require("../index");

describe("i18n for iso 3166-1", function () {
  "use strict";
  describe("Alpha-2 to Alpha-2 code", function() {
    it("toAlpha2 SG => SG", function() {
      assert.equal(i18niso.toAlpha2("SG"), "SG");
    });
  });
  describe("Alpha-2 to Alpha-3 code", function() {
    it("toAlpha3 true => undefined", function() {
      assert.equal(i18niso.toAlpha3(true), undefined);
    });
    it("toAlpha3 XX => undefined", function() {
      assert.equal(i18niso.toAlpha3("XX"), undefined);
    });
    it("toAlpha3 SG => SGP", function() {
      assert.equal(i18niso.toAlpha3("SG"), "SGP");
    });
    it("alpha2ToAlpha3 SG => SGP", function() {
      assert.equal(i18niso.alpha2ToAlpha3("SG"), "SGP");
    });
  });
  describe("Alpha-3 to Alpha-3 code", function() {
    it("toAlpha2 SGP => SGP", function() {
      assert.equal(i18niso.toAlpha3("SGP"), "SGP");
    });
  });
  describe("Alpha-3 to Alpha-2 code", function() {
    it("toAlpha2 true => undefined", function() {
      assert.equal(i18niso.toAlpha2(true), undefined);
    });
    it("toAlpha2 XXX => undefined", function() {
      assert.equal(i18niso.toAlpha2("XXX"), undefined);
    });
    it("toAlpha2 DEU => DE", function() {
      assert.equal(i18niso.toAlpha2("DEU"), "DE");
    });
    it("alpha3ToAlpha2 DEU => DE", function() {
      assert.equal(i18niso.alpha3ToAlpha2("DEU"), "DE");
    });
  });
  describe("Alpha-3 to Numeric code", function() {
    it("alpha3ToNumeric SWE => 752", function() {
      assert.equal(i18niso.alpha3ToNumeric("SWE"), 752);
    });
    it("alpha3ToNumeric DJI => 262", function() {
      assert.equal(i18niso.alpha3ToNumeric("DJI"), 262);
    });
  });
  describe("Alpha-2 to Numeric code", function() {
    it("alpha2ToNumeric SE => 752", function() {
      assert.equal(i18niso.alpha2ToNumeric("SE"), 752);
    });
    it("alpha2ToNumeric DJ => 262", function() {
      assert.equal(i18niso.alpha2ToNumeric("DJ"), 262);
    });
  });
  describe("Numeric to Alpha-2 code", function() {
    it("toAlpha2 '276' => DE", function() {
      assert.equal(i18niso.toAlpha2("276"), "DE");
    });
    it("toAlpha2 '004' => AF", function() {
      assert.equal(i18niso.toAlpha2("004"), "AF");
    });
    it("toAlpha2 276 => DE", function() {
      assert.equal(i18niso.toAlpha2(276), "DE");
    });
    it("toAlpha2 4 => AF", function() {
      assert.equal(i18niso.toAlpha2(4), "AF");
    });
    it("numericToAlpha2 '276' => DE", function() {
      assert.equal(i18niso.numericToAlpha2("276"), "DE");
    });
    it("numericToAlpha2 '004' => AF", function() {
      assert.equal(i18niso.numericToAlpha2("004"), "AF");
    });
    it("numericToAlpha2 276 => DE", function() {
      assert.equal(i18niso.numericToAlpha2(276), "DE");
    });
    it("numericToAlpha2 4 => AF", function() {
      assert.equal(i18niso.numericToAlpha2(4), "AF");
    });
  });
  describe("Numeric to Alpha-3 code", function() {
    it("toAlpha3 '276' => DEU", function() {
      assert.equal(i18niso.toAlpha3("276"), "DEU");
    });
    it("toAlpha3 '004' => AFG", function() {
      assert.equal(i18niso.toAlpha3("004"), "AFG");
    });
    it("toAlpha3 276 => DEU", function() {
      assert.equal(i18niso.toAlpha3(276), "DEU");
    });
    it("toAlpha3 4 => DEU", function() {
      assert.equal(i18niso.toAlpha3(4), "AFG");
    });
    it("numericToAlpha3 '276' => DEU", function() {
      assert.equal(i18niso.numericToAlpha3("276"), "DEU");
    });
    it("numericToAlpha3 '004' => AFG", function() {
      assert.equal(i18niso.numericToAlpha3("004"), "AFG");
    });
    it("numericToAlpha3 276 => DEU", function() {
      assert.equal(i18niso.numericToAlpha3(276), "DEU");
    });
    it("numericToAlpha3 4 => AFG", function() {
      assert.equal(i18niso.numericToAlpha3(4), "AFG");
    });
  });
  describe("getAlpha2Codes", function() {
    it("length", function() {
      assert.equal(Object.keys(i18niso.getAlpha2Codes()).length, 250);
    });
  });
  describe("getAlpha3Codes", function() {
    it("length", function() {
      assert.equal(Object.keys(i18niso.getAlpha3Codes()).length, 250);
    });
  });
  describe("getNumericCodes", function() {
    it("length", function() {
      assert.equal(Object.keys(i18niso.getNumericCodes()).length, 250);
    });
  });
  describe("getAlpha2Code", function() {
    it("missing name", function() {
      assert.equal(i18niso.getAlpha2Code("XXX", "de"), undefined);
    });
    it("missing land", function() {
      assert.equal(i18niso.getAlpha2Code("Deutschland", "xx"), undefined);
    });
  });
  describe("completeness", function () {
    i18niso.langs().forEach(function(lang) {
      describe(lang + " completeness", function () {
        it("complete (to less)", function() {
          Object.keys(i18niso.getAlpha2Codes()).forEach(function(code) {
            assert.notEqual(i18niso.getName(code, lang), undefined, "missing entry for " + code);
          });
        });
        it("complete (too much)", function() {
          Object.keys(i18niso.getNames(lang)).forEach(function(code) {
            assert.notStrictEqual(i18niso.getAlpha2Codes()[code], void 0, "entry for " + code + " in lang " + lang + " is too much");
          });
        });
      });
    });
  });
  describe("langs", function() {
    describe("de", function () {
      var lang = "de";
      describe("get name", function () {
        it("for de", function () {
          assert.equal(i18niso.getName("de", lang), "Deutschland");
        });
        it("for cl", function () {
          assert.equal(i18niso.getName("cl", lang), "Chile");
        });
        it("for CL", function () {
          assert.equal(i18niso.getName("CL", lang), "Chile");
        });
        it("for cy", function () {
          assert.equal(i18niso.getName("cy", lang), "Zypern");
        });
        it("for af", function () {
          assert.equal(i18niso.getName("af", lang), "Afghanistan");
        });
      });
    });
    describe("en", function () {
      var lang = "en";
      describe("get Alpha-2 code", function() {
        it("nameToAlpha2 United States of America => US", function() {
          assert.equal(i18niso.getAlpha2Code("United States of America", lang), "US");
        });
        it("nameToAlpha2 Brazil => BR", function() {
          assert.equal(i18niso.getAlpha2Code("Brazil", lang), "BR");
        });
      });
      describe("get name", function () {
        it("for de", function () {
          assert.equal(i18niso.getName("de", lang), "Germany");
        });
        it("for cl", function () {
          assert.equal(i18niso.getName("cl", lang), "Chile");
        });
        it("for CL", function () {
          assert.equal(i18niso.getName("CL", lang), "Chile");
        });
        it("for cy", function () {
          assert.equal(i18niso.getName("cy", lang), "Cyprus");
        });
        it("for af", function () {
          assert.equal(i18niso.getName("af", lang), "Afghanistan");
        });
      });
    });
    describe("pl", function () {
      var lang = "pl";
      describe("get Alpha-2 code", function() {
        it("nameToAlpha2 Brazylia => BR", function() {
          assert.equal(i18niso.getAlpha2Code("Brazylia", lang), "BR");
        });
        it("nameToAlpha2 Stany Zjednoczone => US", function() {
          assert.equal(i18niso.getAlpha2Code("Stany Zjednoczone", lang), "US");
        });
      });
      describe("get name", function () {
        it("for af => Afganistan", function () {
          assert.equal(i18niso.getName("af", lang), "Afganistan");
        });
        it("for ba => Bośnia i Hercegowina", function () {
          assert.equal(i18niso.getName("ba", lang), "Bośnia i Hercegowina");
        });
        it("for cn => Chiny", function () {
          assert.equal(i18niso.getName("cn", lang), "Chiny");
        });
        it("for cy => Cypr", function () {
          assert.equal(i18niso.getName("cy", lang), "Cypr");
        });
        it("for de => Niemcy", function () {
          assert.equal(i18niso.getName("de", lang), "Niemcy");
        });
      });
    });
    describe("unsupported language", function () {
      var lang = "unsupported";
      it("get name", function () {
        assert.equal(i18niso.getName("de", lang), undefined);
      });
      it("get names", function () {
        assert.equal(Object.keys(i18niso.getNames(lang)).length, 0);
      });
    });
  });
});
<commit_msg>Add test cases for polish<commit_after>var assert = require("assert-plus"),
  i18niso = require("../index");

describe("i18n for iso 3166-1", function () {
  "use strict";
  describe("Alpha-2 to Alpha-2 code", function() {
    it("toAlpha2 SG => SG", function() {
      assert.equal(i18niso.toAlpha2("SG"), "SG");
    });
  });
  describe("Alpha-2 to Alpha-3 code", function() {
    it("toAlpha3 true => undefined", function() {
      assert.equal(i18niso.toAlpha3(true), undefined);
    });
    it("toAlpha3 XX => undefined", function() {
      assert.equal(i18niso.toAlpha3("XX"), undefined);
    });
    it("toAlpha3 SG => SGP", function() {
      assert.equal(i18niso.toAlpha3("SG"), "SGP");
    });
    it("alpha2ToAlpha3 SG => SGP", function() {
      assert.equal(i18niso.alpha2ToAlpha3("SG"), "SGP");
    });
  });
  describe("Alpha-3 to Alpha-3 code", function() {
    it("toAlpha2 SGP => SGP", function() {
      assert.equal(i18niso.toAlpha3("SGP"), "SGP");
    });
  });
  describe("Alpha-3 to Alpha-2 code", function() {
    it("toAlpha2 true => undefined", function() {
      assert.equal(i18niso.toAlpha2(true), undefined);
    });
    it("toAlpha2 XXX => undefined", function() {
      assert.equal(i18niso.toAlpha2("XXX"), undefined);
    });
    it("toAlpha2 DEU => DE", function() {
      assert.equal(i18niso.toAlpha2("DEU"), "DE");
    });
    it("alpha3ToAlpha2 DEU => DE", function() {
      assert.equal(i18niso.alpha3ToAlpha2("DEU"), "DE");
    });
  });
  describe("Alpha-3 to Numeric code", function() {
    it("alpha3ToNumeric SWE => 752", function() {
      assert.equal(i18niso.alpha3ToNumeric("SWE"), 752);
    });
    it("alpha3ToNumeric DJI => 262", function() {
      assert.equal(i18niso.alpha3ToNumeric("DJI"), 262);
    });
  });
  describe("Alpha-2 to Numeric code", function() {
    it("alpha2ToNumeric SE => 752", function() {
      assert.equal(i18niso.alpha2ToNumeric("SE"), 752);
    });
    it("alpha2ToNumeric DJ => 262", function() {
      assert.equal(i18niso.alpha2ToNumeric("DJ"), 262);
    });
  });
  describe("Numeric to Alpha-2 code", function() {
    it("toAlpha2 '276' => DE", function() {
      assert.equal(i18niso.toAlpha2("276"), "DE");
    });
    it("toAlpha2 '004' => AF", function() {
      assert.equal(i18niso.toAlpha2("004"), "AF");
    });
    it("toAlpha2 276 => DE", function() {
      assert.equal(i18niso.toAlpha2(276), "DE");
    });
    it("toAlpha2 4 => AF", function() {
      assert.equal(i18niso.toAlpha2(4), "AF");
    });
    it("numericToAlpha2 '276' => DE", function() {
      assert.equal(i18niso.numericToAlpha2("276"), "DE");
    });
    it("numericToAlpha2 '004' => AF", function() {
      assert.equal(i18niso.numericToAlpha2("004"), "AF");
    });
    it("numericToAlpha2 276 => DE", function() {
      assert.equal(i18niso.numericToAlpha2(276), "DE");
    });
    it("numericToAlpha2 4 => AF", function() {
      assert.equal(i18niso.numericToAlpha2(4), "AF");
    });
  });
  describe("Numeric to Alpha-3 code", function() {
    it("toAlpha3 '276' => DEU", function() {
      assert.equal(i18niso.toAlpha3("276"), "DEU");
    });
    it("toAlpha3 '004' => AFG", function() {
      assert.equal(i18niso.toAlpha3("004"), "AFG");
    });
    it("toAlpha3 276 => DEU", function() {
      assert.equal(i18niso.toAlpha3(276), "DEU");
    });
    it("toAlpha3 4 => DEU", function() {
      assert.equal(i18niso.toAlpha3(4), "AFG");
    });
    it("numericToAlpha3 '276' => DEU", function() {
      assert.equal(i18niso.numericToAlpha3("276"), "DEU");
    });
    it("numericToAlpha3 '004' => AFG", function() {
      assert.equal(i18niso.numericToAlpha3("004"), "AFG");
    });
    it("numericToAlpha3 276 => DEU", function() {
      assert.equal(i18niso.numericToAlpha3(276), "DEU");
    });
    it("numericToAlpha3 4 => AFG", function() {
      assert.equal(i18niso.numericToAlpha3(4), "AFG");
    });
  });
  describe("getAlpha2Codes", function() {
    it("length", function() {
      assert.equal(Object.keys(i18niso.getAlpha2Codes()).length, 250);
    });
  });
  describe("getAlpha3Codes", function() {
    it("length", function() {
      assert.equal(Object.keys(i18niso.getAlpha3Codes()).length, 250);
    });
  });
  describe("getNumericCodes", function() {
    it("length", function() {
      assert.equal(Object.keys(i18niso.getNumericCodes()).length, 250);
    });
  });
  describe("getAlpha2Code", function() {
    it("missing name", function() {
      assert.equal(i18niso.getAlpha2Code("XXX", "de"), undefined);
    });
    it("missing land", function() {
      assert.equal(i18niso.getAlpha2Code("Deutschland", "xx"), undefined);
    });
  });
  describe("completeness", function () {
    i18niso.langs().forEach(function(lang) {
      describe(lang + " completeness", function () {
        it("complete (to less)", function() {
          Object.keys(i18niso.getAlpha2Codes()).forEach(function(code) {
            assert.notEqual(i18niso.getName(code, lang), undefined, "missing entry for " + code);
          });
        });
        it("complete (too much)", function() {
          Object.keys(i18niso.getNames(lang)).forEach(function(code) {
            assert.notStrictEqual(i18niso.getAlpha2Codes()[code], void 0, "entry for " + code + " in lang " + lang + " is too much");
          });
        });
      });
    });
  });
  describe("langs", function() {
    describe("de", function () {
      var lang = "de";
      describe("get name", function () {
        it("for de", function () {
          assert.equal(i18niso.getName("de", lang), "Deutschland");
        });
        it("for cl", function () {
          assert.equal(i18niso.getName("cl", lang), "Chile");
        });
        it("for CL", function () {
          assert.equal(i18niso.getName("CL", lang), "Chile");
        });
        it("for cy", function () {
          assert.equal(i18niso.getName("cy", lang), "Zypern");
        });
        it("for af", function () {
          assert.equal(i18niso.getName("af", lang), "Afghanistan");
        });
      });
    });
    describe("en", function () {
      var lang = "en";
      describe("get Alpha-2 code", function() {
        it("nameToAlpha2 United States of America => US", function() {
          assert.equal(i18niso.getAlpha2Code("United States of America", lang), "US");
        });
        it("nameToAlpha2 Brazil => BR", function() {
          assert.equal(i18niso.getAlpha2Code("Brazil", lang), "BR");
        });
      });
      describe("get name", function () {
        it("for de", function () {
          assert.equal(i18niso.getName("de", lang), "Germany");
        });
        it("for cl", function () {
          assert.equal(i18niso.getName("cl", lang), "Chile");
        });
        it("for CL", function () {
          assert.equal(i18niso.getName("CL", lang), "Chile");
        });
        it("for cy", function () {
          assert.equal(i18niso.getName("cy", lang), "Cyprus");
        });
        it("for af", function () {
          assert.equal(i18niso.getName("af", lang), "Afghanistan");
        });
      });
    });
    describe("pl", function () {
      var lang = "pl";
      describe("get Alpha-2 code", function() {
        it("nameToAlpha2 Brazylia => BR", function() {
          assert.equal(i18niso.getAlpha2Code("Brazylia", lang), "BR");
        });
        it("nameToAlpha2 Stany Zjednoczone => US", function() {
          assert.equal(i18niso.getAlpha2Code("Stany Zjednoczone", lang), "US");
        });
        it("nameToAlpha2 ThisIsNotACountryName => undefined", function() {
          assert.equal(i18niso.getAlpha2Code("ThisIsNotACountryName", lang), undefined);
        });
      });
      describe("get Alpha-3 code", function() {
        it("nameToAlpha3 Brazylia => BRA", function() {
          assert.equal(i18niso.getAlpha3Code("Brazylia", lang), "BRA");
        });
        it("nameToAlpha3 Stany Zjednoczone => USA", function() {
          assert.equal(i18niso.getAlpha3Code("Stany Zjednoczone", lang), "USA");
        });
        it("nameToAlpha3 ThisIsNotACountryName => undefined", function() {
          assert.equal(i18niso.getAlpha3Code("ThisIsNotACountryName", lang), undefined);
        });
      });
      describe("get name", function () {
        it("for af => Afganistan", function () {
          assert.equal(i18niso.getName("af", lang), "Afganistan");
        });
        it("for ba => Bośnia i Hercegowina", function () {
          assert.equal(i18niso.getName("ba", lang), "Bośnia i Hercegowina");
        });
        it("for cn => Chiny", function () {
          assert.equal(i18niso.getName("cn", lang), "Chiny");
        });
        it("for cy => Cypr", function () {
          assert.equal(i18niso.getName("cy", lang), "Cypr");
        });
        it("for de => Niemcy", function () {
          assert.equal(i18niso.getName("de", lang), "Niemcy");
        });
      });
    });
    describe("unsupported language", function () {
      var lang = "unsupported";
      it("get name", function () {
        assert.equal(i18niso.getName("de", lang), undefined);
      });
      it("get names", function () {
        assert.equal(Object.keys(i18niso.getNames(lang)).length, 0);
      });
    });
  });
});
<|endoftext|>


<commit_before>'use strict';

var Reflux = require('reflux');

var Firebase = require('firebase');
var ref = new Firebase('https://resplendent-fire-4810.firebaseio.com/');
var commentsRef = ref.child('comments');
var postsRef = ref.child('posts');

var userActions = require('./userActions');

var commentActions = Reflux.createActions([
	'upvote',
	'getComments',
	'addComment',
	'setFirebaseCallback',
	'removeFirebaseCallback'
]);

function updateCommentCount(postId, n) {
    // updates comment count on post
    postsRef.child(postId).child('commentCount').transaction(function(curr) {
        return curr + n;
    });
}

commentActions.upvote.preEmit = function (userId, postId, commentId, alreadyUpvoted) {
    commentsRef.child(postId).child(commentId).child('upvotes').transaction(function (curr) {
        curr = curr || 0;
        var n = alreadyUpvoted ? -1 : 1;
        return curr + n;
    }, function (error, success) {
    	if (success) {
			// add comment to user's list of upvoted items
			userActions.upvoteItem(userId, commentId, alreadyUpvoted);
    	}
    });
};

commentActions.addComment.preEmit = function (postId, comment) {
    commentsRef.child(postId).push(comment, function (error) {
        if (error === null) {
            updateCommentCount(postId, 1);
        }
    }.bind(this));
};

module.exports = commentActions;<commit_msg>tabs => spaces<commit_after>'use strict';

var Reflux = require('reflux');

var Firebase = require('firebase');
var ref = new Firebase('https://resplendent-fire-4810.firebaseio.com/');
var commentsRef = ref.child('comments');
var postsRef = ref.child('posts');

var userActions = require('./userActions');

var commentActions = Reflux.createActions([
    'upvote',
    'getComments',
    'addComment',
    'setFirebaseCallback',
    'removeFirebaseCallback'
]);

function updateCommentCount(postId, n) {
    // updates comment count on post
    postsRef.child(postId).child('commentCount').transaction(function(curr) {
        return curr + n;
    });
}

commentActions.upvote.preEmit = function (userId, postId, commentId, alreadyUpvoted) {
    commentsRef.child(postId).child(commentId).child('upvotes').transaction(function (curr) {
        curr = curr || 0;
        var n = alreadyUpvoted ? -1 : 1;
        return curr + n;
    }, function (error, success) {
        if (success) {
            // add comment to user's list of upvoted items
            userActions.upvoteItem(userId, commentId, alreadyUpvoted);
        }
    });
};

commentActions.addComment.preEmit = function (postId, comment) {
    commentsRef.child(postId).push(comment, function (error) {
        if (error === null) {
            updateCommentCount(postId, 1);
        }
    }.bind(this));
};

module.exports = commentActions;<|endoftext|>


<commit_before>const moment = require('moment')
const expect = require('chai').expect
const assert = require('chai').assert
const sinon = require('sinon')

const proxyquire = require('proxyquire')
const breadcrumbHelper = require('../../helpers/breadcrumb-helper')
const orgUnitConstant = require('../../../app/constants/organisation-unit.js')
const Reduction = require('../../../app/services/domain/reduction')
const reductionStatusType = require('../../../app/constants/reduction-status-type')
const workloadTypes = require('../../../app/constants/workload-type')

const breadcrumbs = breadcrumbHelper.OFFENDER_MANAGER_BREADCRUMBS

let addReductionStub
let updateReductionStub
let updateReductionStatusStub
let getReferenceDataStub
let getContractedHoursForWorkloadOwnerStub
let getBreadcrumbsStub
let createCalculateWorkloadTaskStub
let reductionService
let getReductionById
let getReductions
let reductionHelper
let getLatestIdsForWpRecalc
let createCourtReportsCalculationTask
let getLatestIdsForCourtReportsCalc

const newReductionId = 9
const existingReductionId = 10
const workloadOwnerId = 11
const activeStartDate = moment('10-30-2017', 'MM-DD-YYYY').toDate() // 2017-10-31T11:25:05.805Z
const activeEndDate = moment('12-30-2017', 'MM-DD-YYYY').toDate() // 2017-12-30T11:25:05.807Z

const reductionReason = {
  maxAllowanceHours: 0
}

const reduction = new Reduction('1', '10',
  [activeStartDate.getDate(), activeStartDate.getMonth() + 1, activeStartDate.getFullYear()],
  [activeEndDate.getDate(), activeEndDate.getMonth() + 1, activeEndDate.getFullYear()], 'active note', reductionReason)

const referenceData = [
  {
    reason: 'Test Reason',
    reason_short_name: 'T',
    category: 'Test Category',
    allowance_percentage: 100,
    max_allowance_percentage: undefined,
    months_to_expiry: 6
  },
  {
    reason: 'Test Reason 2',
    reason_short_name: 'T',
    category: 'Test Category 2',
    allowance_percentage: 100,
    max_allowance_percentage: undefined,
    months_to_expiry: 6
  }
]

const baseReduction =
  {
    id: 1,
    workloadOwnerId: 507,
    hours: 5,
    reductionReasonId: 1,
    categoryId: 1,
    reasonShortName: 'Disability',
    allowancePercentage: null,
    reductionStartDate: '11 Sep 16',
    reductionEndDate: '09 Sep 27',
    notes: null,
    status: 'ACTIVE'
  }

const activeReductions = [baseReduction]

const archivedReductions = [
  Object.assign({}, baseReduction, { id: 2, status: 'ARCHIVED' }),
  Object.assign({}, baseReduction, { id: 3, status: 'ARCHIVED' })
]

const reductionsByStatus = {
  activeReductions: activeReductions,
  scheduledReductions: [],
  archivedReductions: archivedReductions
}

const latestWorkloadStagingId = 3
const latestCourtReportsStagingId = 1
const latestWorkloadReportId = 2
const recalcIds = { workloadStagingId: latestWorkloadStagingId, workloadReportId: latestWorkloadReportId }
const crRecalcIds = { courtReportsStagingId: latestCourtReportsStagingId, workloadReportId: latestWorkloadReportId }

beforeEach(function () {
  addReductionStub = sinon.stub()
  updateReductionStub = sinon.stub()
  updateReductionStatusStub = sinon.stub()
  createCalculateWorkloadTaskStub = sinon.stub()
  getContractedHoursForWorkloadOwnerStub = sinon.stub().resolves(5)
  getReferenceDataStub = sinon.stub().resolves(referenceData)
  getBreadcrumbsStub = sinon.stub().resolves(breadcrumbs)
  getReductionById = sinon.stub()
  getReductions = sinon.stub()
  reductionHelper = {
    getReductionsByStatus: sinon.stub().returns(reductionsByStatus)
  }
  getLatestIdsForWpRecalc = sinon.stub().resolves(recalcIds)
  createCourtReportsCalculationTask = sinon.stub()
  getLatestIdsForCourtReportsCalc = sinon.stub().resolves(crRecalcIds)
  reductionService =
    proxyquire('../../../app/services/reductions-service',
      {
        './helpers/reduction-helper': reductionHelper,
        './data/get-reductions': getReductions,
        './data/insert-reduction': addReductionStub,
        './data/update-reduction': updateReductionStub,
        './data/update-reduction-status': updateReductionStatusStub,
        './get-breadcrumbs': getBreadcrumbsStub,
        './data/get-contracted-hours-for-workload-owner': getContractedHoursForWorkloadOwnerStub,
        './data/get-reduction-reasons': getReferenceDataStub,
        './data/create-calculate-workload-points-task': createCalculateWorkloadTaskStub,
        './data/get-latest-workload-staging-id-and-workload-report-id': getLatestIdsForWpRecalc,
        './data/get-reduction-by-id': getReductionById,
        './data/create-court-reports-calculation-task': createCourtReportsCalculationTask,
        './data/get-latest-court-reports-staging-id-and-workload-report-id': getLatestIdsForCourtReportsCalc
      })
})

describe('services/reductions-service', function () {
  describe('Get reductions', function () {
    it('should create the result object with the right information for standard OM', function () {
      getReductions.resolves([])
      return reductionService.getReductions(1, orgUnitConstant.OFFENDER_MANAGER.name, workloadTypes.PROBATION)
        .then(function (result) {
          expect(getReductions.calledWith(1)).to.be.eql(true)
          expect(getBreadcrumbsStub.calledWith(1, orgUnitConstant.OFFENDER_MANAGER.name, workloadTypes.PROBATION)).to.be.eql(true)
          expect(result.title).to.equal('John Doe')
          expect(result.subTitle).to.equal('Offender Manager')
          expect(result.activeReductions).to.eql(activeReductions)
          expect(result.scheduledReductions).to.eql([])
          expect(result.archivedReductions).to.eql(archivedReductions)
        })
    })

    it('should create the result object with the right information for court-reporter', function () {
      getReductions.resolves([])
      return reductionService.getReductions(1, orgUnitConstant.OFFENDER_MANAGER.name, workloadTypes.COURT_REPORTS)
        .then(function (result) {
          expect(getReductions.calledWith(1)).to.be.eql(true)
          expect(getBreadcrumbsStub.calledWith(1, orgUnitConstant.OFFENDER_MANAGER.name, workloadTypes.COURT_REPORTS)).to.be.eql(true)
          expect(result.title).to.equal('John Doe')
          expect(result.subTitle).to.equal('Offender Manager')
          expect(result.activeReductions).to.eql(activeReductions)
          expect(result.scheduledReductions).to.eql([])
          expect(result.archivedReductions).to.eql(archivedReductions)
        })
    })
  })

  describe('Get reductions reference data', function () {
    it('should get the reference data with the hours already worked out for each reduction reason for standard OM', function () {
      return reductionService.getAddReductionsRefData(1, orgUnitConstant.OFFENDER_MANAGER.name, workloadTypes.PROBATION)
        .then(function (result) {
          expect(result.referenceData).to.be.an('array')
          expect(result.title).to.equal('John Doe')
          expect(result.subTitle).to.equal('Offender Manager')
        expect(getContractedHoursForWorkloadOwnerStub.calledWith(1)).to.be.true //eslint-disable-line
          expect(getBreadcrumbsStub.calledWith(1, orgUnitConstant.OFFENDER_MANAGER.name, workloadTypes.PROBATION)).to.be.eql(true)
          assert(getReferenceDataStub.called)
        })
    })

    it('should get the reference data with the hours already worked out for each reduction reason for court-reporter', function () {
      return reductionService.getAddReductionsRefData(1, orgUnitConstant.OFFENDER_MANAGER.name, workloadTypes.COURT_REPORTS)
        .then(function (result) {
          expect(result.referenceData).to.be.an('array')
          expect(result.title).to.equal('John Doe')
          expect(result.subTitle).to.equal('Offender Manager')
        expect(getContractedHoursForWorkloadOwnerStub.calledWith(1)).to.be.true //eslint-disable-line
          expect(getBreadcrumbsStub.calledWith(1, orgUnitConstant.OFFENDER_MANAGER.name, workloadTypes.COURT_REPORTS)).to.be.eql(true)
          assert(getReferenceDataStub.called)
        })
    })
  })

  describe('Add reduction', function () {
    it('should add a new reduction when no valid reduction Id given and call create wpc task for standard OM', function () {
      createCalculateWorkloadTaskStub.resolves(1)
      addReductionStub.withArgs(workloadOwnerId, reduction).resolves(newReductionId)
      return reductionService.addReduction(workloadOwnerId, reduction, workloadTypes.PROBATION)
        .then(function (result) {
        expect(getLatestIdsForWpRecalc.calledWith(workloadOwnerId)).to.be.true //eslint-disable-line
        expect(createCalculateWorkloadTaskStub.calledWith(latestWorkloadStagingId, latestWorkloadReportId, 1)).to.be.true //eslint-disable-line
        expect(addReductionStub.calledWith(workloadOwnerId, reduction)).to.be.true //eslint-disable-line
          expect(result).to.equal(1)
        })
    })

    it('should add a new reduction when no valid reduction Id given and call create wpc task for court-reporter OM', function () {
      createCourtReportsCalculationTask.resolves(1)
      addReductionStub.withArgs(workloadOwnerId, reduction).resolves(newReductionId)
      return reductionService.addReduction(workloadOwnerId, reduction, workloadTypes.COURT_REPORTS)
        .then(function (result) {
        expect(getLatestIdsForCourtReportsCalc.calledWith(workloadOwnerId)).to.be.true //eslint-disable-line
        expect(createCourtReportsCalculationTask.calledWith(latestCourtReportsStagingId, latestWorkloadReportId, 1)).to.be.true //eslint-disable-line
        expect(addReductionStub.calledWith(workloadOwnerId, reduction)).to.be.true //eslint-disable-line
          expect(result).to.equal(1)
        })
    })
  })

  describe('Update reduction', function () {
    it('should update reduction and create worker task when reduction Id given for standard OM', function () {
      createCalculateWorkloadTaskStub.resolves(1)
      updateReductionStub.withArgs(existingReductionId, workloadOwnerId, reduction).resolves(existingReductionId)
      return reductionService.updateReduction(workloadOwnerId, existingReductionId, reduction, workloadTypes.PROBATION)
        .then(function (result) {
          expect(getLatestIdsForWpRecalc.calledWith(workloadOwnerId)).to.be.true //eslint-disable-line
          expect(createCalculateWorkloadTaskStub.calledWith(latestWorkloadStagingId, latestWorkloadReportId, 1)).to.be.true //eslint-disable-line
          expect(updateReductionStub.calledWith(existingReductionId, workloadOwnerId,reduction)).to.be.true //eslint-disable-line
          expect(result).to.equal(1)
        })
    })

    it('should update reduction and create worker task when reduction Id given for court-reporter', function () {
      createCourtReportsCalculationTask.resolves(1)
      updateReductionStub.withArgs(existingReductionId, workloadOwnerId, reduction).resolves(existingReductionId)
      return reductionService.updateReduction(workloadOwnerId, existingReductionId, reduction, workloadTypes.COURT_REPORTS)
        .then(function (result) {
          expect(getLatestIdsForCourtReportsCalc.calledWith(workloadOwnerId)).to.be.true //eslint-disable-line
          expect(createCourtReportsCalculationTask.calledWith(latestCourtReportsStagingId, latestWorkloadReportId, 1)).to.be.true //eslint-disable-line
          expect(updateReductionStub.calledWith(existingReductionId, workloadOwnerId,reduction)).to.be.true //eslint-disable-line
          expect(result).to.equal(1)
        })
    })
  })

  describe('Update reduction status', function () {
    it('should update reduction status and create worker task when reduction Id given for standard OM', function () {
      const newReductonStatus = reductionStatusType.ARCHIVED
      createCalculateWorkloadTaskStub.resolves(1)
      updateReductionStatusStub.withArgs(existingReductionId, newReductonStatus).resolves(existingReductionId)
      return reductionService.updateReductionStatus(workloadOwnerId, existingReductionId, newReductonStatus, workloadTypes.PROBATION)
        .then(function (result) {
        expect(getLatestIdsForWpRecalc.calledWith(workloadOwnerId)).to.be.true //eslint-disable-line
        expect(createCalculateWorkloadTaskStub.calledWith(latestWorkloadStagingId, latestWorkloadReportId, 1)).to.be.true //eslint-disable-line
        expect(updateReductionStatusStub.calledWith(existingReductionId, newReductonStatus)).to.be.true //eslint-disable-line
          expect(result).to.equal(1)
        })
    })

    it('should update reduction status and create worker task when reduction Id given for court-reporter', function () {
      const newReductonStatus = reductionStatusType.ARCHIVED
      createCourtReportsCalculationTask.resolves(1)
      updateReductionStatusStub.withArgs(existingReductionId, newReductonStatus).resolves(existingReductionId)
      return reductionService.updateReductionStatus(workloadOwnerId, existingReductionId, newReductonStatus, workloadTypes.COURT_REPORTS)
        .then(function (result) {
        expect(getLatestIdsForCourtReportsCalc.calledWith(workloadOwnerId)).to.be.true //eslint-disable-line
        expect(createCourtReportsCalculationTask.calledWith(latestCourtReportsStagingId, latestWorkloadReportId)).to.be.true //eslint-disable-line
        expect(updateReductionStatusStub.calledWith(existingReductionId, newReductonStatus)).to.be.true //eslint-disable-line
          expect(result).to.equal(1)
        })
    })
  })

  describe('Get Reduction By reduction Id', function () {
    it('should call on to data service with correct reduction id and return reduction', function () {
      getReductionById.resolves(reduction)
      return reductionService.getReductionByReductionId(existingReductionId)
        .then(function (result) {
        expect(getReductionById.calledWith(existingReductionId)).to.be.true //eslint-disable-line
          expect(result).to.eql(reduction)
        })
    })

    it('should not call on to service for undefined id and return undefined', function () {
      return reductionService.getReductionByReductionId(undefined)
        .then(function (result) {
        expect(getReductionById.called).to.be.false //eslint-disable-line
          expect(result).to.equal(undefined)
        })
    })
  })
})
<commit_msg>WFP-810 fixed the rest of the tests<commit_after>const moment = require('moment')
const expect = require('chai').expect
const assert = require('chai').assert
const sinon = require('sinon')

const proxyquire = require('proxyquire')
const breadcrumbHelper = require('../../helpers/breadcrumb-helper')
const orgUnitConstant = require('../../../app/constants/organisation-unit.js')
const Reduction = require('../../../app/services/domain/reduction')
const reductionStatusType = require('../../../app/constants/reduction-status-type')
const workloadTypes = require('../../../app/constants/workload-type')

const breadcrumbs = breadcrumbHelper.OFFENDER_MANAGER_BREADCRUMBS

let addReductionStub
let updateReductionStub
let updateReductionStatusStub
let getReferenceDataStub
let getContractedHoursForWorkloadOwnerStub
let getBreadcrumbsStub
let createCalculateWorkloadTaskStub
let reductionService
let getReductionById
let getReductions
let reductionHelper
let getLatestIdsForWpRecalc
let createCourtReportsCalculationTask
let getLatestIdsForCourtReportsCalc
let getOffenderManagerTeamLduRegion
let auditReductionEdited
let auditReductionCreation

const newReductionId = 9
const existingReductionId = 10
const workloadOwnerId = 11
const activeStartDate = moment('10-30-2017', 'MM-DD-YYYY').toDate() // 2017-10-31T11:25:05.805Z
const activeEndDate = moment('12-30-2017', 'MM-DD-YYYY').toDate() // 2017-12-30T11:25:05.807Z

const reductionReason = {
  maxAllowanceHours: 0
}

const reduction = new Reduction('1', '10',
  [activeStartDate.getDate(), activeStartDate.getMonth() + 1, activeStartDate.getFullYear()],
  [activeEndDate.getDate(), activeEndDate.getMonth() + 1, activeEndDate.getFullYear()], 'active note', reductionReason)

const referenceData = [
  {
    reason: 'Test Reason',
    reason_short_name: 'T',
    category: 'Test Category',
    allowance_percentage: 100,
    max_allowance_percentage: undefined,
    months_to_expiry: 6
  },
  {
    reason: 'Test Reason 2',
    reason_short_name: 'T',
    category: 'Test Category 2',
    allowance_percentage: 100,
    max_allowance_percentage: undefined,
    months_to_expiry: 6
  }
]

const baseReduction =
  {
    id: 1,
    workloadOwnerId: 507,
    hours: 5,
    reductionReasonId: 1,
    categoryId: 1,
    reasonShortName: 'Disability',
    allowancePercentage: null,
    reductionStartDate: '11 Sep 16',
    reductionEndDate: '09 Sep 27',
    notes: null,
    status: 'ACTIVE'
  }

const offenderManager = {
  forename: 'fore',
  surname: 'sur',
  teamCode: 'tc',
  teamDescription: 'td',
  lduCode: 'lc',
  lduDescription: 'ld',
  regionCode: 'rc',
  regionDescription: 'rd'
}
const activeReductions = [baseReduction]

const archivedReductions = [
  Object.assign({}, baseReduction, { id: 2, status: 'ARCHIVED' }),
  Object.assign({}, baseReduction, { id: 3, status: 'ARCHIVED' })
]

const reductionsByStatus = {
  activeReductions: activeReductions,
  scheduledReductions: [],
  archivedReductions: archivedReductions
}

const latestWorkloadStagingId = 3
const latestCourtReportsStagingId = 1
const latestWorkloadReportId = 2
const recalcIds = { workloadStagingId: latestWorkloadStagingId, workloadReportId: latestWorkloadReportId }
const crRecalcIds = { courtReportsStagingId: latestCourtReportsStagingId, workloadReportId: latestWorkloadReportId }

beforeEach(function () {
  addReductionStub = sinon.stub()
  updateReductionStub = sinon.stub()
  updateReductionStatusStub = sinon.stub()
  createCalculateWorkloadTaskStub = sinon.stub()
  getContractedHoursForWorkloadOwnerStub = sinon.stub().resolves(5)
  getReferenceDataStub = sinon.stub().resolves(referenceData)
  getBreadcrumbsStub = sinon.stub().resolves(breadcrumbs)
  getReductionById = sinon.stub()
  getReductions = sinon.stub()
  reductionHelper = {
    getReductionsByStatus: sinon.stub().returns(reductionsByStatus)
  }
  getLatestIdsForWpRecalc = sinon.stub().resolves(recalcIds)
  createCourtReportsCalculationTask = sinon.stub()
  getLatestIdsForCourtReportsCalc = sinon.stub().resolves(crRecalcIds)
  getOffenderManagerTeamLduRegion = sinon.stub().resolves(offenderManager)
  auditReductionCreation = sinon.stub().resolves()
  auditReductionEdited = sinon.stub().resolves()

  reductionService =
    proxyquire('../../../app/services/reductions-service',
      {
        './helpers/reduction-helper': reductionHelper,
        './data/get-reductions': getReductions,
        './data/insert-reduction': addReductionStub,
        './data/update-reduction': updateReductionStub,
        './data/update-reduction-status': updateReductionStatusStub,
        './get-breadcrumbs': getBreadcrumbsStub,
        './data/get-contracted-hours-for-workload-owner': getContractedHoursForWorkloadOwnerStub,
        './data/get-reduction-reasons': getReferenceDataStub,
        './data/create-calculate-workload-points-task': createCalculateWorkloadTaskStub,
        './data/get-latest-workload-staging-id-and-workload-report-id': getLatestIdsForWpRecalc,
        './data/get-reduction-by-id': getReductionById,
        './data/create-court-reports-calculation-task': createCourtReportsCalculationTask,
        './data/get-latest-court-reports-staging-id-and-workload-report-id': getLatestIdsForCourtReportsCalc,
        './data/get-offender-manager-team-ldu-region': getOffenderManagerTeamLduRegion,
        './audit-service': { auditReductionCreation, auditReductionEdited }

      })
})

describe.only('services/reductions-service', function () {
  describe('Get reductions', function () {
    it('should create the result object with the right information for standard OM', function () {
      getReductions.resolves([])
      return reductionService.getReductions(1, orgUnitConstant.OFFENDER_MANAGER.name, workloadTypes.PROBATION)
        .then(function (result) {
          expect(getReductions.calledWith(1)).to.be.eql(true)
          expect(getBreadcrumbsStub.calledWith(1, orgUnitConstant.OFFENDER_MANAGER.name, workloadTypes.PROBATION)).to.be.eql(true)
          expect(result.title).to.equal('John Doe')
          expect(result.subTitle).to.equal('Offender Manager')
          expect(result.activeReductions).to.eql(activeReductions)
          expect(result.scheduledReductions).to.eql([])
          expect(result.archivedReductions).to.eql(archivedReductions)
        })
    })

    it('should create the result object with the right information for court-reporter', function () {
      getReductions.resolves([])
      return reductionService.getReductions(1, orgUnitConstant.OFFENDER_MANAGER.name, workloadTypes.COURT_REPORTS)
        .then(function (result) {
          expect(getReductions.calledWith(1)).to.be.eql(true)
          expect(getBreadcrumbsStub.calledWith(1, orgUnitConstant.OFFENDER_MANAGER.name, workloadTypes.COURT_REPORTS)).to.be.eql(true)
          expect(result.title).to.equal('John Doe')
          expect(result.subTitle).to.equal('Offender Manager')
          expect(result.activeReductions).to.eql(activeReductions)
          expect(result.scheduledReductions).to.eql([])
          expect(result.archivedReductions).to.eql(archivedReductions)
        })
    })
  })

  describe('Get reductions reference data', function () {
    it('should get the reference data with the hours already worked out for each reduction reason for standard OM', function () {
      return reductionService.getAddReductionsRefData(1, orgUnitConstant.OFFENDER_MANAGER.name, workloadTypes.PROBATION)
        .then(function (result) {
          expect(result.referenceData).to.be.an('array')
          expect(result.title).to.equal('John Doe')
          expect(result.subTitle).to.equal('Offender Manager')
        expect(getContractedHoursForWorkloadOwnerStub.calledWith(1)).to.be.true //eslint-disable-line
          expect(getBreadcrumbsStub.calledWith(1, orgUnitConstant.OFFENDER_MANAGER.name, workloadTypes.PROBATION)).to.be.eql(true)
          assert(getReferenceDataStub.called)
        })
    })

    it('should get the reference data with the hours already worked out for each reduction reason for court-reporter', function () {
      return reductionService.getAddReductionsRefData(1, orgUnitConstant.OFFENDER_MANAGER.name, workloadTypes.COURT_REPORTS)
        .then(function (result) {
          expect(result.referenceData).to.be.an('array')
          expect(result.title).to.equal('John Doe')
          expect(result.subTitle).to.equal('Offender Manager')
        expect(getContractedHoursForWorkloadOwnerStub.calledWith(1)).to.be.true //eslint-disable-line
          expect(getBreadcrumbsStub.calledWith(1, orgUnitConstant.OFFENDER_MANAGER.name, workloadTypes.COURT_REPORTS)).to.be.eql(true)
          assert(getReferenceDataStub.called)
        })
    })
  })

  describe('Add reduction', function () {
    it('should add a new reduction when no valid reduction Id given and call create wpc task for standard OM', function () {
      createCalculateWorkloadTaskStub.resolves(1)
      addReductionStub.withArgs(workloadOwnerId, reduction).resolves(newReductionId)
      return reductionService.addReduction(workloadOwnerId, reduction, workloadTypes.PROBATION)
        .then(function (result) {
        expect(getLatestIdsForWpRecalc.calledWith(workloadOwnerId)).to.be.true //eslint-disable-line
        expect(createCalculateWorkloadTaskStub.calledWith(latestWorkloadStagingId, latestWorkloadReportId, 1)).to.be.true //eslint-disable-line
        expect(addReductionStub.calledWith(workloadOwnerId, reduction)).to.be.true //eslint-disable-line
          expect(result).to.equal(1)
        })
    })

    it('should add a new reduction when no valid reduction Id given and call create wpc task for court-reporter OM', function () {
      createCourtReportsCalculationTask.resolves(1)
      addReductionStub.withArgs(workloadOwnerId, reduction).resolves(newReductionId)
      return reductionService.addReduction(workloadOwnerId, reduction, workloadTypes.COURT_REPORTS)
        .then(function (result) {
        expect(getLatestIdsForCourtReportsCalc.calledWith(workloadOwnerId)).to.be.true //eslint-disable-line
        expect(createCourtReportsCalculationTask.calledWith(latestCourtReportsStagingId, latestWorkloadReportId, 1)).to.be.true //eslint-disable-line
        expect(addReductionStub.calledWith(workloadOwnerId, reduction)).to.be.true //eslint-disable-line
          expect(result).to.equal(1)
        })
    })
  })

  describe('Update reduction', function () {
    it('should update reduction and create worker task when reduction Id given for standard OM', function () {
      createCalculateWorkloadTaskStub.resolves(1)
      updateReductionStub.withArgs(existingReductionId, workloadOwnerId, reduction).resolves(existingReductionId)
      const oldReduction = {}
      const email = 'some.email.@justice.gov.uk'
      return reductionService.updateReduction(workloadOwnerId, existingReductionId, reduction, workloadTypes.PROBATION, oldReduction, email)
        .then(function (result) {
          expect(getLatestIdsForWpRecalc.calledWith(workloadOwnerId)).to.be.true //eslint-disable-line
          expect(createCalculateWorkloadTaskStub.calledWith(latestWorkloadStagingId, latestWorkloadReportId, 1)).to.be.true //eslint-disable-line
          expect(updateReductionStub.calledWith(existingReductionId, workloadOwnerId,reduction)).to.be.true //eslint-disable-line
          expect(result).to.equal(1)
        })
    })

    it('should update reduction and create worker task when reduction Id given for court-reporter', function () {
      createCourtReportsCalculationTask.resolves(1)
      updateReductionStub.withArgs(existingReductionId, workloadOwnerId, reduction).resolves(existingReductionId)
      const oldReduction = {}
      const email = 'some.email.@justice.gov.uk'
      return reductionService.updateReduction(workloadOwnerId, existingReductionId, reduction, workloadTypes.COURT_REPORTS, oldReduction, email)
        .then(function (result) {
          expect(getLatestIdsForCourtReportsCalc.calledWith(workloadOwnerId)).to.be.true //eslint-disable-line
          expect(createCourtReportsCalculationTask.calledWith(latestCourtReportsStagingId, latestWorkloadReportId, 1)).to.be.true //eslint-disable-line
          expect(updateReductionStub.calledWith(existingReductionId, workloadOwnerId,reduction)).to.be.true //eslint-disable-line
          expect(result).to.equal(1)
        })
    })
  })

  describe('Update reduction status', function () {
    it('should update reduction status and create worker task when reduction Id given for standard OM', function () {
      const newReductonStatus = reductionStatusType.ARCHIVED
      createCalculateWorkloadTaskStub.resolves(1)
      updateReductionStatusStub.withArgs(existingReductionId, newReductonStatus).resolves(existingReductionId)
      return reductionService.updateReductionStatus(workloadOwnerId, existingReductionId, newReductonStatus, workloadTypes.PROBATION)
        .then(function (result) {
        expect(getLatestIdsForWpRecalc.calledWith(workloadOwnerId)).to.be.true //eslint-disable-line
        expect(createCalculateWorkloadTaskStub.calledWith(latestWorkloadStagingId, latestWorkloadReportId, 1)).to.be.true //eslint-disable-line
        expect(updateReductionStatusStub.calledWith(existingReductionId, newReductonStatus)).to.be.true //eslint-disable-line
          expect(result).to.equal(1)
        })
    })

    it('should update reduction status and create worker task when reduction Id given for court-reporter', function () {
      const newReductonStatus = reductionStatusType.ARCHIVED
      createCourtReportsCalculationTask.resolves(1)
      updateReductionStatusStub.withArgs(existingReductionId, newReductonStatus).resolves(existingReductionId)
      return reductionService.updateReductionStatus(workloadOwnerId, existingReductionId, newReductonStatus, workloadTypes.COURT_REPORTS)
        .then(function (result) {
        expect(getLatestIdsForCourtReportsCalc.calledWith(workloadOwnerId)).to.be.true //eslint-disable-line
        expect(createCourtReportsCalculationTask.calledWith(latestCourtReportsStagingId, latestWorkloadReportId)).to.be.true //eslint-disable-line
        expect(updateReductionStatusStub.calledWith(existingReductionId, newReductonStatus)).to.be.true //eslint-disable-line
          expect(result).to.equal(1)
        })
    })
  })

  describe('Get Reduction By reduction Id', function () {
    it('should call on to data service with correct reduction id and return reduction', function () {
      getReductionById.resolves(reduction)
      return reductionService.getReductionByReductionId(existingReductionId)
        .then(function (result) {
        expect(getReductionById.calledWith(existingReductionId)).to.be.true //eslint-disable-line
          expect(result).to.eql(reduction)
        })
    })

    it('should not call on to service for undefined id and return undefined', function () {
      return reductionService.getReductionByReductionId(undefined)
        .then(function (result) {
        expect(getReductionById.called).to.be.false //eslint-disable-line
          expect(result).to.equal(undefined)
        })
    })
  })
})
<|endoftext|>


<commit_before>'use strict';

angular.module('app')
  .controller('ServerDataCtrl', function ($scope, webSocket, settings) {
    var widgetDefinitions = [
      {
        name: 'chart1',
        directive: 'wt-line-chart',
        attrs: {
          chart: 'chart'
        },
        style: {
          width: '50%'
        }
      },
      {
        name: 'chart2',
        directive: 'wt-line-chart',
        attrs: {
          chart: 'chart2'
        },
        style: {
          width: '50%'
        }
      },
      {
        name: 'topics',
        templateUrl: 'template/topics.html'
      },
      {
        name: 'wt-scope-watch',
        attrs: {
          value: 'serverValue'
        }
      },
      {
        name: 'wt-top-n',
        attrs: {
          data: 'serverTopTen'
        }
      }
    ];

    var defaultWidgets = _.clone(widgetDefinitions);

    $scope.dashboardOptions = {
      widgetButtons: true,
      widgetDefinitions: widgetDefinitions,
      defaultWidgets: defaultWidgets
    };

    $scope.serverValue = 0;
    webSocket.subscribe(settings.randomValueTopic, function (message) {
      $scope.serverValue = message.value;
      $scope.$apply();
    }, $scope);

    webSocket.subscribe(settings.topNTopic, function (message) {
      var list = [];
      _.each(message, function (value, key) {
        list.push({ name: key, value: parseInt(value, 10) });
      }, $scope);

      $scope.serverTopTen = list;
      $scope.$apply();
    }, $scope);

    // line chart
    function chartData(topic, propertyName) {
      var max = 30;
      var data = [];
      webSocket.subscribe(topic, function (value) {
        var now = Date.now();
        data.push({
          timestamp: now,
          value: value
        });

        if (data.length > 100) { //TODO
          data.shift();
        }

        $scope[propertyName] = {
          data: data,
          max: max
        };

        $scope.$apply();
      }, $scope);
    }

    chartData('app.visualdata.chartValue', 'chart');
    chartData('app.visualdata.chartValue2', 'chart2');
  })
  .controller('TopicCtrl', function ($scope, webSocket) {
    webSocket.subscribe('_latestTopics', function (message) {
      var list = _.reject(message, function (topic) {
        return topic.indexOf('applications.') >= 0;
      });
      $scope.topics = _.sortBy(list, function (topic) {
        return topic;
      });
      if (message.length) {
        $scope.topic = $scope.topics[0];
      }
      $scope.$apply();
    }, $scope);
    webSocket.send({ type: 'getLatestTopics' });

    var callback = function (message) {
      $scope.topicData = JSON.stringify(message, null, ' ');
      $scope.$apply();
    };

    $scope.$watch('topic', function (newTopic, oldTopic) {
      if (oldTopic && callback) {
        webSocket.unsubscribe(oldTopic, callback);
      }

      if (newTopic) {
        $scope.topicData = 'Loading...';
        webSocket.subscribe(newTopic, callback, $scope);
      }
    });
  });<commit_msg>line chart from WebSocket data source<commit_after>'use strict';

angular.module('app')
  .controller('ServerDataCtrl', function ($scope, webSocket, settings) {
    var widgetDefinitions = [
      {
        name: 'chart1',
        directive: 'wt-line-chart',
        attrs: {
          chart: 'chart'
        },
        style: {
          width: '50%'
        }
      },
      {
        name: 'chart2',
        directive: 'wt-line-chart',
        attrs: {
          chart: 'chart2'
        },
        style: {
          width: '50%'
        }
      },
      {
        name: 'topics',
        templateUrl: 'template/topics.html'
      },
      {
        name: 'wt-gauge',
        attrs: {
          value: 'chartValue'
        },
        style: {
          width: '250px'
        }
      },
      {
        name: 'wt-top-n',
        attrs: {
          data: 'serverTopTen'
        }
      }
    ];

    var defaultWidgets = _.clone(widgetDefinitions);

    $scope.dashboardOptions = {
      widgetButtons: true,
      widgetDefinitions: widgetDefinitions,
      defaultWidgets: defaultWidgets
    };

    $scope.serverValue = 0;
    webSocket.subscribe(settings.randomValueTopic, function (message) {
      $scope.serverValue = message.value;
      $scope.$apply();
    }, $scope);

    webSocket.subscribe(settings.topNTopic, function (message) {
      var list = [];
      _.each(message, function (value, key) {
        list.push({ name: key, value: parseInt(value, 10) });
      }, $scope);

      $scope.serverTopTen = list;
      $scope.$apply();
    }, $scope);

    // line chart
    function chartData(topic, propertyName) {
      var max = 30;
      var data = [];
      webSocket.subscribe(topic, function (value) {
        var now = Date.now();
        data.push({
          timestamp: now,
          value: value
        });

        if (data.length > 100) { //TODO
          data.shift();
        }

        $scope[propertyName] = {
          data: data,
          max: max
        };

        $scope.$apply();
      }, $scope);
    }

    chartData('app.visualdata.chartValue', 'chart');
    chartData('app.visualdata.chartValue2', 'chart2');

    $scope.chartValue = 0;
    webSocket.subscribe('app.visualdata.chartValue2', function (value) {
      $scope.chartValue = value;
      $scope.$apply();
    });
  })
  .controller('TopicCtrl', function ($scope, webSocket) {
    webSocket.subscribe('_latestTopics', function (message) {
      var list = _.reject(message, function (topic) {
        return topic.indexOf('applications.') >= 0;
      });
      $scope.topics = _.sortBy(list, function (topic) {
        return topic;
      });
      if (message.length) {
        $scope.topic = $scope.topics[0];
      }
      $scope.$apply();
    }, $scope);
    webSocket.send({ type: 'getLatestTopics' });

    var callback = function (message) {
      $scope.topicData = JSON.stringify(message, null, ' ');
      $scope.$apply();
    };

    $scope.$watch('topic', function (newTopic, oldTopic) {
      if (oldTopic && callback) {
        webSocket.unsubscribe(oldTopic, callback);
      }

      if (newTopic) {
        $scope.topicData = 'Loading...';
        webSocket.subscribe(newTopic, callback, $scope);
      }
    });
  });<|endoftext|>


<commit_before>var through = require('through2')
var duplexify = require('duplexify')
var WS = require('ws')

module.exports = WebSocketStream

function WebSocketStream(target, protocols, options) {
  var stream, socket

  var isBrowser = process.title === 'browser'
  var isNative = !!global.WebSocket
  var socketWrite = isBrowser ? socketWriteBrowser : socketWriteNode
  var proxy = through.obj(socketWrite, socketEnd)

  if (protocols && !Array.isArray(protocols) && 'object' === typeof protocols) {
    // accept the "options" Object as the 2nd argument
    options = protocols
    protocols = null
  }

  if (!options) options = {}

  // browser only: sets the maximum socket buffer size before throttling
  var bufferSize = options.browserBufferSize || 1024 * 512

  // browser only: how long to wait when throttling
  var bufferTimeout = options.browserBufferTimeout || 1000

  // use existing WebSocket object that was passed in
  if (typeof target === 'object') {
    socket = target
  // otherwise make a new one
  } else {
    // special constructor treatment for native websockets in browsers, see
    // https://github.com/maxogden/websocket-stream/issues/82
    if (isNative && isBrowser) {
      socket = new WS(target, protocols)
    } else {
      socket = new WS(target, protocols, options)
    }

    socket.binaryType = 'arraybuffer'
  }

  // was already open when passed in
  if (socket.readyState === WS.OPEN) {
    stream = proxy
  } else {
    stream = duplexify.obj()
    socket.onopen = onopen
  }

  stream.socket = socket

  socket.onclose = onclose
  socket.onerror = onerror
  socket.onmessage = onmessage

  proxy.on('close', destroy)

  // for server only
  // The value of the arguemnt called 'binary' is decided on a chunk by chunk basis by default.
  // socket.send() modify the passed in options argument.
  // Hence, reusing the same object on each send call results in a situation, where
  // any unpassed paramters will be set based on the very first chunk; To overcome this
  // a new object literal is needed for each invocation of send
  function sendOptions() {
    return {
      binary: options.binary,
      mask: options.mask,
      fin: options.fin,
      compress: options.compress
    }
  }

  function socketWriteNode(chunk, enc, next) {
    socket.send(chunk, sendOptions(), next)
  }

  function socketWriteBrowser(chunk, enc, next) {
    if (socket.bufferedAmount > bufferSize) {
      setTimeout(socketWriteBrowser, bufferTimeout, chunk, enc, next)
      return
    }

    try {
      socket.send(chunk)
    } catch(err) {
      return next(err)
    }

    next()
  }

  function socketEnd(done) {
    socket.close()
    done()
  }

  function onopen() {
    stream.setReadable(proxy)
    stream.setWritable(proxy)
    stream.emit('connect')
  }

  function onclose() {
    stream.end()
    stream.destroy()
  }

  function onerror(err) {
    stream.destroy(err)
  }

  function onmessage(event) {
    var data = event.data
    if (data instanceof ArrayBuffer) data = new Buffer(new Uint8Array(data))
    else data = new Buffer(data)
    proxy.push(data)
  }

  function destroy() {
    socket.close()
  }

  return stream
}
<commit_msg>Clarify comment for sendOptions()<commit_after>var through = require('through2')
var duplexify = require('duplexify')
var WS = require('ws')

module.exports = WebSocketStream

function WebSocketStream(target, protocols, options) {
  var stream, socket

  var isBrowser = process.title === 'browser'
  var isNative = !!global.WebSocket
  var socketWrite = isBrowser ? socketWriteBrowser : socketWriteNode
  var proxy = through.obj(socketWrite, socketEnd)

  if (protocols && !Array.isArray(protocols) && 'object' === typeof protocols) {
    // accept the "options" Object as the 2nd argument
    options = protocols
    protocols = null
  }

  if (!options) options = {}

  // browser only: sets the maximum socket buffer size before throttling
  var bufferSize = options.browserBufferSize || 1024 * 512

  // browser only: how long to wait when throttling
  var bufferTimeout = options.browserBufferTimeout || 1000

  // use existing WebSocket object that was passed in
  if (typeof target === 'object') {
    socket = target
  // otherwise make a new one
  } else {
    // special constructor treatment for native websockets in browsers, see
    // https://github.com/maxogden/websocket-stream/issues/82
    if (isNative && isBrowser) {
      socket = new WS(target, protocols)
    } else {
      socket = new WS(target, protocols, options)
    }

    socket.binaryType = 'arraybuffer'
  }

  // was already open when passed in
  if (socket.readyState === WS.OPEN) {
    stream = proxy
  } else {
    stream = duplexify.obj()
    socket.onopen = onopen
  }

  stream.socket = socket

  socket.onclose = onclose
  socket.onerror = onerror
  socket.onmessage = onmessage

  proxy.on('close', destroy)

  // server only: socket.send() mutates the passed-in options argument
  // this helper creates a new options argument for each invocation of socket.send()
  // see: https://github.com/maxogden/websocket-stream/pull/94#discussion_r71310808
  function sendOptions() {
    return {
      binary: options.binary,
      mask: options.mask,
      fin: options.fin,
      compress: options.compress
    }
  }

  function socketWriteNode(chunk, enc, next) {
    socket.send(chunk, sendOptions(), next)
  }

  function socketWriteBrowser(chunk, enc, next) {
    if (socket.bufferedAmount > bufferSize) {
      setTimeout(socketWriteBrowser, bufferTimeout, chunk, enc, next)
      return
    }

    try {
      socket.send(chunk)
    } catch(err) {
      return next(err)
    }

    next()
  }

  function socketEnd(done) {
    socket.close()
    done()
  }

  function onopen() {
    stream.setReadable(proxy)
    stream.setWritable(proxy)
    stream.emit('connect')
  }

  function onclose() {
    stream.end()
    stream.destroy()
  }

  function onerror(err) {
    stream.destroy(err)
  }

  function onmessage(event) {
    var data = event.data
    if (data instanceof ArrayBuffer) data = new Buffer(new Uint8Array(data))
    else data = new Buffer(data)
    proxy.push(data)
  }

  function destroy() {
    socket.close()
  }

  return stream
}
<|endoftext|>


<commit_before>
function addNextButton() {
    var id = 'rxdb-custon-next-button';

    var alreadyThere = document.querySelector('#' + id);
    if (alreadyThere) {
        console.log('custom next button already there.');
        return;
    }

    var block = document.querySelector('.normal.markdown-section');
    console.dir(block);

    var path = window.location.pathname;
    var page = path.split('/').pop();
    console.log('page: ' + page);

    var chapters = document.querySelectorAll('.chapter');
    var dataPaths = [];
    chapters.forEach(function (chapter) {
        var dataPath = chapter.dataset.path;
        if (dataPath) {
            dataPaths.push(dataPath);
        }
    });

    var lastIndex = dataPaths.lastIndexOf(page);
    console.dir('dataPaths:');
    console.dir(dataPaths);
    var nextPath = dataPaths[lastIndex + 1];
    console.log('nexdtPath: ' + nextPath);
    if (!nextPath) {
        return;
    }

    var hr = document.createElement('hr');
    block.appendChild(hr);

    console.log('# Add next button');
    var span = document.createElement('p');
    span.id = id;
    span.innerHTML = 'If you are new to RxDB, you should continue ';
    var link = document.createElement('a');
    link.href = nextPath;
    link.innerHTML = 'here';
    span.appendChild(link);
    block.appendChild(span);
}

addNextButton();

/**
 * Gitbook does a strange page change handling,
 * so we have to re-run on history state changes.
 */
history.pushState = function () {
    console.log('history.pushState()');
    setTimeout(function () {
        addNextButton();
    }, 100);
};

<commit_msg>DISABLE broken buttons<commit_after>
function runAddingNextButtons() {

    function addNextButton() {
        var id = 'rxdb-custon-next-button';

        var alreadyThere = document.querySelector('#' + id);
        if (alreadyThere) {
            console.log('custom next button already there.');
            return;
        }

        var block = document.querySelector('.normal.markdown-section');
        console.dir(block);

        var path = window.location.pathname;
        var page = path.split('/').pop();
        console.log('page: ' + page);

        var chapters = document.querySelectorAll('.chapter');
        var dataPaths = [];
        chapters.forEach(function (chapter) {
            var dataPath = chapter.dataset.path;
            if (dataPath) {
                dataPaths.push(dataPath);
            }
        });

        var lastIndex = dataPaths.lastIndexOf(page);
        console.dir('dataPaths:');
        console.dir(dataPaths);
        var nextPath = dataPaths[lastIndex + 1];
        console.log('nexdtPath: ' + nextPath);
        if (!nextPath) {
            return;
        }

        var hr = document.createElement('hr');
        block.appendChild(hr);

        console.log('# Add next button');
        var span = document.createElement('p');
        span.id = id;
        span.innerHTML = 'If you are new to RxDB, you should continue ';
        var link = document.createElement('a');
        link.href = nextPath;
        link.innerHTML = 'here';
        span.appendChild(link);
        block.appendChild(span);
    }

    addNextButton();

    /**
     * Gitbook does a strange page change handling,
     * so we have to re-run on history state changes.
     */
    history.pushState = function () {
        console.log('history.pushState()');
        setTimeout(function () {
            addNextButton();
        }, 100);
    };

}
//runAddingNextButtons();
<|endoftext|>


<commit_before>/**
* @license Apache-2.0
*
* Copyright (c) 2018 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* global window */

'use strict';

// MODULES //

var Global = require( 'system.global' )();
var IS_NODE = require( '@stdlib/assert/is-node' );
var globalScope = require( './global_scope.js' );

// MAIN //

/**
* Returns a boolean indicating if the runtime is a web browser.
*
* @returns {boolean} boolean indicating if runtime is a web browser
*
* @example
* var bool = isBrowser();
* // returns <boolean>
*/
function isBrowser() {
	return (
		// Check that we are not running in a Node.js runtime:
		IS_NODE === false &&

		// Check for presence of `window` variable:
		typeof window === 'object' &&

		// Check that the `window` variable matches the determined global variable:
		window === Global &&

		// Check that the `window` variable is equal to the global scope:
		globalScope === true
	);
}

// EXPORTS //

module.exports = isBrowser;
<commit_msg>Refactor to avoid immediately invoked require<commit_after>/**
* @license Apache-2.0
*
* Copyright (c) 2018 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* global window */

'use strict';

// MODULES //

var getGlobal = require( 'system.global' );
var IS_NODE = require( '@stdlib/assert/is-node' );
var globalScope = require( './global_scope.js' );

// VARIABLES //

var Global = getGlobal();

// MAIN //

/**
* Returns a boolean indicating if the runtime is a web browser.
*
* @returns {boolean} boolean indicating if runtime is a web browser
*
* @example
* var bool = isBrowser();
* // returns <boolean>
*/
function isBrowser() {
	return (
		// Check that we are not running in a Node.js runtime:
		IS_NODE === false &&

		// Check for presence of `window` variable:
		typeof window === 'object' &&

		// Check that the `window` variable matches the determined global variable:
		window === Global &&

		// Check that the `window` variable is equal to the global scope:
		globalScope === true
	);
}

// EXPORTS //

module.exports = isBrowser;
<|endoftext|>


<commit_before>// loader.js(LoaderModule)
var LoaderModule = (function() {

<<<<<<< HEAD
=======
  // Libraries to load
  var libs = ['lib/jquery.jrumble.1.3.min'];

>>>>>>> development
  // Available modules to load
  var modules = [
    'modules/game',
    'modules/cookiedata',
    'modules/controls',
    'modules/overlay',
    'modules/board',
    'modules/story'];

  // Loads the modules for the game
  var loadModules = function() {
    require(['lib/jquery-2.1.1.min'], function() {
      require(libs, function() {
        require(modules, function() {
          mediator.publish('loader_modules_loaded');
        });
      });
    });
  };

  // Loads the story of the game(story.json)
  var loadStory = function() {
    mediator.publish('story_get_story');
  }

  // The externally available facade
  return {
    loadModules: loadModules,
    loadStory: loadStory
  }
}());

// Add the mediator to the module
mediator.installTo(LoaderModule);

// Subscribe to events

// Instruction to load the modules
mediator.subscribe('loader_load_modules', LoaderModule.loadModules);

// Notify that modules are loaded
mediator.subscribe('loader_modules_loaded', LoaderModule.loadStory);

// Notify that the story is loaded
mediator.subscribe('story_story_loaded', function() {
  mediator.publish('loader_story_loaded');
});<commit_msg>fixed conflict<commit_after>// loader.js(LoaderModule)
var LoaderModule = (function() {

  // Libraries to load
  var libs = ['lib/jquery.jrumble.1.3.min'];

  // Available modules to load
  var modules = [
    'modules/game',
    'modules/cookiedata',
    'modules/controls',
    'modules/overlay',
    'modules/board',
    'modules/story'];

  // Loads the modules for the game
  var loadModules = function() {
    require(['lib/jquery-2.1.1.min'], function() {
      require(libs, function() {
        require(modules, function() {
          mediator.publish('loader_modules_loaded');
        });
      });
    });
  };

  // Loads the story of the game(story.json)
  var loadStory = function() {
    mediator.publish('story_get_story');
  }

  // The externally available facade
  return {
    loadModules: loadModules,
    loadStory: loadStory
  }
}());

// Add the mediator to the module
mediator.installTo(LoaderModule);

// Subscribe to events

// Instruction to load the modules
mediator.subscribe('loader_load_modules', LoaderModule.loadModules);

// Notify that modules are loaded
mediator.subscribe('loader_modules_loaded', LoaderModule.loadStory);

// Notify that the story is loaded
mediator.subscribe('story_story_loaded', function() {
  mediator.publish('loader_story_loaded');
});<|endoftext|>


<commit_before>'use strict';

// If you want to access any of these options in React, don’t forget to update CLIENT_CONFIG_OPTIONS array
// in loaders/styleguide-loader.js

const EXTENSIONS = 'js,jsx,ts,tsx';
const DEFAULT_COMPONENTS_PATTERN = 'src/@(components|Components)/**/*.vue';

const path = require('path');
const startCase = require('lodash/startCase');
const logger = require('glogg')('rsg');
const findUserWebpackConfig = require('../utils/findUserWebpackConfig');
const getUserPackageJson = require('../utils/getUserPackageJson');
const fileExistsCaseInsensitive = require('../utils/findFileCaseInsensitive');
const consts = require('../consts');

module.exports = {
	assetsDir: {
		type: 'existing directory path',
		example: 'assets',
	},
	compilerConfig: {
		type: 'object',
		default: {
			objectAssign: 'Object.assign',
		},
	},
	// `components` is a shortcut for { sections: [{ components }] }, see `sections` below
	components: {
		type: ['string', 'function'],
		example: 'components/**/[A-Z]*.vue',
	},
	configDir: {
		process: (value, config, rootDir) => rootDir,
	},
	context: {
		type: 'object',
		default: {},
		example: {
			map: 'lodash/map',
		},
	},
	contextDependencies: {
		type: 'array',
	},
	configureServer: {
		type: 'function',
	},
	dangerouslyUpdateWebpackConfig: {
		type: 'function',
	},
	defaultExample: {
		type: ['boolean', 'existing file path'],
		default: false,
		process: val =>
			val === true ? path.resolve(__dirname, '../templates/DefaultExample.md') : val,
	},
	getComponentPathLine: {
		type: 'function',
		default: componentPath => componentPath,
	},
	getExampleFilename: {
		type: 'function',
		default: componentPath => {
			const files = [
				path.join(path.dirname(componentPath), 'Readme.md'),
				componentPath.replace(path.extname(componentPath), '.md'),
			];

			for (const file of files) {
				const existingFile = fileExistsCaseInsensitive(file);
				if (existingFile) {
					return existingFile;
				}
			}

			return false;
		},
		example: componentPath => componentPath.replace(/\.jsx?$/, '.examples.md'),
	},
	ignore: {
		type: 'array',
		default: [
			'**/__tests__/**',
			`**/*.test.{${EXTENSIONS}}`,
			`**/*.spec.{${EXTENSIONS}}`,
			'**/*.d.ts',
		],
	},
	highlightTheme: {
		type: 'string',
		default: 'base16-light',
		deprecated: 'Use the theme property in the editorConfig option instead',
	},
	editorConfig: {
		type: 'object',
		process: (value, config) => {
			const defaults = {
				theme: 'base16-light',
				mode: 'jsx',
				lineWrapping: true,
				smartIndent: false,
				matchBrackets: true,
				viewportMargin: Infinity,
				lineNumbers: false,
			};
			return Object.assign(
				{},
				defaults,
				config.highlightTheme && { theme: config.highlightTheme },
				value
			);
		},
	},
	navigation: {
		type: 'boolean',
		default: false,
	},
	mixins: {
		type: 'array',
		default: [],
		example: ['path/to/mixin.js', 'path/to/created.js'],
	},
	logger: {
		type: 'object',
	},
	previewDelay: {
		type: 'number',
		default: 500,
	},
	propsParser: {
		type: 'function',
	},
	require: {
		type: 'array',
		default: [],
		example: ['babel-polyfill', 'path/to/styles.css'],
	},
	sections: {
		type: 'array',
		default: [],
		process: (val, config) => {
			if (!val) {
				// If root `components` isn't empty, make it a first section
				// If `components` and `sections` weren’t specified, use default pattern
				const components = config.components || DEFAULT_COMPONENTS_PATTERN;
				return [{ components }];
			}
			return val;
		},
		example: [
			{
				name: 'Documentation',
				content: 'Readme.md',
			},
			{
				name: 'Components',
				components: './lib/components/**/[A-Z]*.js',
			},
		],
	},
	serverHost: {
		type: 'string',
		default: '0.0.0.0',
	},
	serverPort: {
		type: 'number',
		default: 6060,
	},
	showCode: {
		type: 'boolean',
		default: false,
	},
	showUsage: {
		type: 'boolean',
		default: false,
	},
	showSidebar: {
		type: 'boolean',
		default: true,
	},
	skipComponentsWithoutExample: {
		type: 'boolean',
		default: false,
	},
	styleguideComponents: {
		type: 'object',
	},
	styleguideDir: {
		type: 'directory path',
		default: 'styleguide',
	},
	styleguidePublicPath: {
		type: 'directory path',
		default: '',
	},
	styles: {
		type: 'object',
		default: {},
		example: {
			Logo: {
				logo: {
					fontStyle: 'italic',
				},
			},
		},
	},
	template: {
		type: 'existing file path',
		default: path.resolve(__dirname, '../templates/index.html'),
		example: 'templates/styleguide.html',
	},
	theme: {
		type: 'object',
		default: {},
		example: {
			link: 'firebrick',
			linkHover: 'salmon',
		},
	},
	title: {
		type: 'string',
		process: val => {
			if (val) {
				return val;
			}
			const name = getUserPackageJson().name;
			return `${startCase(name)} Style Guide`;
		},
		example: 'My Style Guide',
	},
	updateExample: {
		type: 'function',
		default: props => {
			if (props.lang === 'example') {
				props.lang = 'js';
				logger.warn(
					'"example" code block language is deprecated. Use "js", "jsx" or "javascript" instead:\n' +
						consts.DOCS_DOCUMENTING
				);
			}
			return props;
		},
	},
	updateWebpackConfig: {
		type: 'function',
		removed: `Use "webpackConfig" option instead:\n${consts.DOCS_WEBPACK}`,
	},
	verbose: {
		type: 'boolean',
		default: false,
	},
	vuex: {
		type: 'directory path',
	},
	webpackConfig: {
		type: ['object', 'function'],
		process: val => {
			if (val) {
				return val;
			}

			const file = findUserWebpackConfig();
			if (file) {
				logger.info(`Loading webpack config from:\n${file}`);
				// eslint-disable-next-line import/no-dynamic-require
				return require(file);
			}

			logger.warn(
				'No webpack config found. ' +
					'You may need to specify "webpackConfig" option in your style guide config:\n' +
					consts.DOCS_WEBPACK
			);

			return undefined;
		},
		example: {
			module: {
				rules: [
					{
						test: /\.vue$/,
						exclude: /node_modules/,
						loader: 'vue-loader',
						options: {},
					},
					{
						test: /\.js$/,
						exclude: /node_modules/,
						loader: 'babel-loader',
					},
					{
						test: /\.css$/,
						loader: 'style-loader!css-loader',
					},

					{
						test: /\.json$/,
						loader: 'json-loader',
					},
					{
						exclude: [/\.html$/, /\.(js|jsx)$/, /\.css$/, /\.vue$/, /\.json$/],
						loader: 'url-loader',
						query: {
							limit: 10000,
							name: 'static/media/[name].[hash:8].[ext]',
						},
					},
				],
			},
		},
	},
};
<commit_msg>change styleguidePublicPath type to string to avoid sanitizing<commit_after>'use strict';

// If you want to access any of these options in React, don’t forget to update CLIENT_CONFIG_OPTIONS array
// in loaders/styleguide-loader.js

const EXTENSIONS = 'js,jsx,ts,tsx';
const DEFAULT_COMPONENTS_PATTERN = 'src/@(components|Components)/**/*.vue';

const path = require('path');
const startCase = require('lodash/startCase');
const logger = require('glogg')('rsg');
const findUserWebpackConfig = require('../utils/findUserWebpackConfig');
const getUserPackageJson = require('../utils/getUserPackageJson');
const fileExistsCaseInsensitive = require('../utils/findFileCaseInsensitive');
const consts = require('../consts');

module.exports = {
	assetsDir: {
		type: 'existing directory path',
		example: 'assets',
	},
	compilerConfig: {
		type: 'object',
		default: {
			objectAssign: 'Object.assign',
		},
	},
	// `components` is a shortcut for { sections: [{ components }] }, see `sections` below
	components: {
		type: ['string', 'function'],
		example: 'components/**/[A-Z]*.vue',
	},
	configDir: {
		process: (value, config, rootDir) => rootDir,
	},
	context: {
		type: 'object',
		default: {},
		example: {
			map: 'lodash/map',
		},
	},
	contextDependencies: {
		type: 'array',
	},
	configureServer: {
		type: 'function',
	},
	dangerouslyUpdateWebpackConfig: {
		type: 'function',
	},
	defaultExample: {
		type: ['boolean', 'existing file path'],
		default: false,
		process: val =>
			val === true ? path.resolve(__dirname, '../templates/DefaultExample.md') : val,
	},
	getComponentPathLine: {
		type: 'function',
		default: componentPath => componentPath,
	},
	getExampleFilename: {
		type: 'function',
		default: componentPath => {
			const files = [
				path.join(path.dirname(componentPath), 'Readme.md'),
				componentPath.replace(path.extname(componentPath), '.md'),
			];

			for (const file of files) {
				const existingFile = fileExistsCaseInsensitive(file);
				if (existingFile) {
					return existingFile;
				}
			}

			return false;
		},
		example: componentPath => componentPath.replace(/\.jsx?$/, '.examples.md'),
	},
	ignore: {
		type: 'array',
		default: [
			'**/__tests__/**',
			`**/*.test.{${EXTENSIONS}}`,
			`**/*.spec.{${EXTENSIONS}}`,
			'**/*.d.ts',
		],
	},
	highlightTheme: {
		type: 'string',
		default: 'base16-light',
		deprecated: 'Use the theme property in the editorConfig option instead',
	},
	editorConfig: {
		type: 'object',
		process: (value, config) => {
			const defaults = {
				theme: 'base16-light',
				mode: 'jsx',
				lineWrapping: true,
				smartIndent: false,
				matchBrackets: true,
				viewportMargin: Infinity,
				lineNumbers: false,
			};
			return Object.assign(
				{},
				defaults,
				config.highlightTheme && { theme: config.highlightTheme },
				value
			);
		},
	},
	navigation: {
		type: 'boolean',
		default: false,
	},
	mixins: {
		type: 'array',
		default: [],
		example: ['path/to/mixin.js', 'path/to/created.js'],
	},
	logger: {
		type: 'object',
	},
	previewDelay: {
		type: 'number',
		default: 500,
	},
	propsParser: {
		type: 'function',
	},
	require: {
		type: 'array',
		default: [],
		example: ['babel-polyfill', 'path/to/styles.css'],
	},
	sections: {
		type: 'array',
		default: [],
		process: (val, config) => {
			if (!val) {
				// If root `components` isn't empty, make it a first section
				// If `components` and `sections` weren’t specified, use default pattern
				const components = config.components || DEFAULT_COMPONENTS_PATTERN;
				return [{ components }];
			}
			return val;
		},
		example: [
			{
				name: 'Documentation',
				content: 'Readme.md',
			},
			{
				name: 'Components',
				components: './lib/components/**/[A-Z]*.js',
			},
		],
	},
	serverHost: {
		type: 'string',
		default: '0.0.0.0',
	},
	serverPort: {
		type: 'number',
		default: 6060,
	},
	showCode: {
		type: 'boolean',
		default: false,
	},
	showUsage: {
		type: 'boolean',
		default: false,
	},
	showSidebar: {
		type: 'boolean',
		default: true,
	},
	skipComponentsWithoutExample: {
		type: 'boolean',
		default: false,
	},
	styleguideComponents: {
		type: 'object',
	},
	styleguideDir: {
		type: 'directory path',
		default: 'styleguide',
	},
	styleguidePublicPath: {
		type: 'string',
		default: '',
	},
	styles: {
		type: 'object',
		default: {},
		example: {
			Logo: {
				logo: {
					fontStyle: 'italic',
				},
			},
		},
	},
	template: {
		type: 'existing file path',
		default: path.resolve(__dirname, '../templates/index.html'),
		example: 'templates/styleguide.html',
	},
	theme: {
		type: 'object',
		default: {},
		example: {
			link: 'firebrick',
			linkHover: 'salmon',
		},
	},
	title: {
		type: 'string',
		process: val => {
			if (val) {
				return val;
			}
			const name = getUserPackageJson().name;
			return `${startCase(name)} Style Guide`;
		},
		example: 'My Style Guide',
	},
	updateExample: {
		type: 'function',
		default: props => {
			if (props.lang === 'example') {
				props.lang = 'js';
				logger.warn(
					'"example" code block language is deprecated. Use "js", "jsx" or "javascript" instead:\n' +
						consts.DOCS_DOCUMENTING
				);
			}
			return props;
		},
	},
	updateWebpackConfig: {
		type: 'function',
		removed: `Use "webpackConfig" option instead:\n${consts.DOCS_WEBPACK}`,
	},
	verbose: {
		type: 'boolean',
		default: false,
	},
	vuex: {
		type: 'directory path',
	},
	webpackConfig: {
		type: ['object', 'function'],
		process: val => {
			if (val) {
				return val;
			}

			const file = findUserWebpackConfig();
			if (file) {
				logger.info(`Loading webpack config from:\n${file}`);
				// eslint-disable-next-line import/no-dynamic-require
				return require(file);
			}

			logger.warn(
				'No webpack config found. ' +
					'You may need to specify "webpackConfig" option in your style guide config:\n' +
					consts.DOCS_WEBPACK
			);

			return undefined;
		},
		example: {
			module: {
				rules: [
					{
						test: /\.vue$/,
						exclude: /node_modules/,
						loader: 'vue-loader',
						options: {},
					},
					{
						test: /\.js$/,
						exclude: /node_modules/,
						loader: 'babel-loader',
					},
					{
						test: /\.css$/,
						loader: 'style-loader!css-loader',
					},

					{
						test: /\.json$/,
						loader: 'json-loader',
					},
					{
						exclude: [/\.html$/, /\.(js|jsx)$/, /\.css$/, /\.vue$/, /\.json$/],
						loader: 'url-loader',
						query: {
							limit: 10000,
							name: 'static/media/[name].[hash:8].[ext]',
						},
					},
				],
			},
		},
	},
};
<|endoftext|>