<commit_before>/**
    Key-value mapping UI element.

    This element generates a button that pops up a modal containing pairs of keys and values.
    Expects to be used in app manager, in the context of an application module.
    Used primarily in case list/detail display properties. Keys may be strings
    (as in ID Mapping format) or calcuations (as in Conditional ID Mapping format).
    Values may be strings (as in both ID Mapping formats) or references to images
    (as in Icon format). Supports translations.

    Options:
        Required:
            items: Array of current values. Each item should be the javascript equivalent
                of a MappingItem.
            lang: Current language.
            langs: All languages.
            property_name: Observable representing the name of the overall mapping.
                May be either a string or one of the elements defined in hqwebapp/js/ui-element.
                Used primarily to add title to modal. If values_are_icons, this should be a slug.
        Optional:
            keys_are_conditions: True iff KEYS are calculations rather than strings.
            values_are_icons: True iff values are image references ("jr://file...")
            module_id: Module id, should be provided if values_are_icons is being used in a module context
                (e.g., case list/detail config).
            multimedia: Only needed if values_are_icons. Object containing multimedia
                to be passed as appMenuMediaManager's objectMap. Keys are image references;
                values are objects as generated by CommCareMultimedia.get_media_info
            buttonText: Text for button that opens modal. Defaults to "Edit".
 */
hqDefine('hqwebapp/js/ui_elements/ui-element-key-val-mapping', function () {
    'use strict';
    var module = {};

    // To autogenerate cssid from random string
    // copied from http://stackoverflow.com/questions/7627000/javascript-convert-string-to-safe-class-name-for-css
    var makeSafeForCSS = function (name) {
        if (!name) {
            return "";
        }
        return name.replace(/[^a-z0-9]/g, function (s) {
            var c = s.charCodeAt(0);
            if (c === 32) return '-';
            if (c >= 65 && c <= 90) return '_' + s.toLowerCase();
            return '__' + ('000' + c.toString(16)).slice(-4);
        });
    };

    /**
    * MapItem is a ko representation for `item` objects.
    *
    * @param item: a raw object which contains keys called `key` and `value`.
    *              the `value` in a item itself is an object, a mapping
    *              of language codes to strings
    * @param mappingContext: an object which has context of current UI language and whether
    *                 `value` of MapItem is a file-path to an icon or a simple string
    */
    var MapItem = function (item, index, mappingContext) {
        var self = {};
        self.key = ko.observable(item.key);
        self.editing = ko.observable(false);

        self.cssId = ko.computed(function () {
            return makeSafeForCSS(self.key()) || '_blank_';
        });

        // util function to generate icon-name of the format "module<module_id>_list_icon_<property_name>_<hash_of_item.key>"
        self.generateIconPath = function () {
            var randomFourDigits = Math.floor(Math.random() * 9000) + 1000;
            var iconPrefix =  "jr://file/commcare/image/module" + mappingContext.module_id + "_list_icon_" + mappingContext.getPropertyName() + "_";
            return iconPrefix + randomFourDigits + ".png";
        };

        var app_manager = hqImport('app_manager/js/app_manager_media');
        var uploaders = hqImport("app_manager/js/nav_menu_media_common");
        // attach a media-manager if item.value is a file-path to icon
        if (mappingContext.values_are_icons()) {
            var actualPath = item.value[mappingContext.lang];
            var defaultIconPath = actualPath || self.generateIconPath();
            self.iconManager = app_manager.appMenuMediaManager({
                ref: {
                    "path": actualPath,
                    "icon_type": "icon-picture",
                    "media_type": "Image",
                    "media_class": "CommCareImage",
                    "icon_class": "icon-picture",
                },
                objectMap: mappingContext.multimedia,
                uploadController: uploaders.iconUploader,
                defaultPath: defaultIconPath,
                inputElement: $("#" + self.cssId()),
            });
        }

        self.toggleEditMode = function () {
            self.editing(!self.editing());
        };

        self.value = ko.computed(function () {
            // ko.observable for item.value
            var new_value = [];
            var langs = _.union(_(item.value).keys(), [mappingContext.lang]) ;
            _.each(langs, function (lang) {
                // return ko reference to path in `iconManager` for current UI language value
                if (mappingContext.values_are_icons() && lang === mappingContext.lang) {
                    new_value.push([lang, self.iconManager.customPath]);
                }
                // return new ko.observable for other languages
                else {
                    new_value.push([lang, ko.observable(item.value[lang])]);
                }
            });
            return _.object(new_value);
        });

        self.key.subscribe(function (newValue) {
            if (mappingContext.duplicatedItems.indexOf(newValue) === -1 && mappingContext._isItemDuplicated(newValue)) {
                mappingContext.duplicatedItems.push(newValue);
            }

        });

        self.key.subscribe(function (oldValue) {
            var index = mappingContext.duplicatedItems.indexOf(oldValue);
            if (index !== -1 && !mappingContext._isItemDuplicated(oldValue, 2)) {
                mappingContext.duplicatedItems.remove(oldValue);
            }
        }, null, "beforeChange");

        return self;
    };

    /**
     * A MapList is an ordered list of MapItem objects
     */
    var MapList = function (options) {
        hqImport("hqwebapp/js/assert_properties").assert(options, [
            'lang',
            'langs',
            'items',
            'property_name',
        ], [
            'buttonText',
            'keys_are_conditions',
            'module_id',
            'multimedia',
            'values_are_icons',
        ]);

        var self = {};
        self.lang = options.lang;
        self.langs = [options.lang].concat(options.langs);
        self.module_id = options.module_id;
        self.items = ko.observableArray();
        self.duplicatedItems = ko.observableArray();
        self.values_are_icons = ko.observable(options.values_are_icons || false);
        self.keys_are_conditions = ko.observable(options.keys_are_conditions || false);
        self.multimedia = options.multimedia;

        self.getPropertyName = function () {
            if (_.isObject(options.property_name) && _.isFunction(options.property_name.val)) {
                return options.property_name.val();
            }
            return options.property_name;
        };

        self.labels = ko.computed(function () {
            if (self.values_are_icons()) {
                return {
                    placeholder: django.gettext('Calculation'),
                    duplicated: django.gettext('Calculation is duplicated'),
                    addButton: django.gettext('Add Image'),
                    badXML: django.gettext('Calculation contains an invalid character.'),
                };
            }
            else if (self.keys_are_conditions()) {
                return {
                    placeholder: django.gettext('Calculation'),
                    duplicated: django.gettext('Calculation is duplicated'),
                    addButton: django.gettext('Add Key, Value Mapping'),
                    badXML: django.gettext('Calculation contains an invalid character.'),
                };
            }
            else {
                return {
                    placeholder: django.gettext('Key'),
                    duplicated: django.gettext('Key is duplicated'),
                    addButton: django.gettext('Add Key, Value Mapping'),
                    badXML: django.gettext('Key contains an invalid character.'),
                };
            }
        });

        self.setItems = function (items) {
            self.items(_(items).map(function (item, i) {
                return new MapItem(item, i, self);
            }));
        };
        self.setItems(options.items);

        self.backup = function (value) {
            var backup;
            for (var i = 0; i < self.langs.length; i += 1) {
                var lang = self.langs[i];
                backup = value[lang];
                if (backup && backup() !== '') {
                    return {lang: lang, value: backup()};
                }
            }
            return {lang: null, value: 'value'};
        };
        self.removeItem = function (item) {
            self.items.remove(item);
            if (!self._isItemDuplicated(ko.utils.unwrapObservable(item.key)))
                self.duplicatedItems.remove(ko.utils.unwrapObservable(item.key));
        };
        self.addItem = function () {
            var raw_item = {key: '', value: {}};
            raw_item.value[self.lang] = '';

            var item = new MapItem(raw_item, self.items.length, self);
            self.items.push(item);
            if (self.duplicatedItems.indexOf('') === -1 && self._isItemDuplicated('')) {
                self.duplicatedItems.push('');
            }
        };

        self._isItemDuplicated = function (key, max_counts) {
            if (typeof(max_counts) === 'undefined') max_counts = 1;
            var items = self.getItems();
            var counter = 0;
            for (var i = 0; i < items.length; i++) {
                var item = items[i];
                if (ko.utils.unwrapObservable(item.key) === key) {
                    counter++;
                    if (counter > max_counts) return true;
                }
            }
            return false;
        };

        self.isItemDuplicated = function (key) {
            return self.duplicatedItems.indexOf(key) !== -1;
        };

        self.hasBadXML = function (key) {
            if (self.values_are_icons() || self.keys_are_conditions()) {
                // Expressions can contain whatever
                return false;
            }

            // IDs shouldn't have invalid XML characters
            return key.match(/[&<>"']/);
        };

        self.keyHasError = function (key) {
            return self.isItemDuplicated(key) || self.hasBadXML(key);
        };

        self.hasError = function () {
            return self.duplicatedItems().length > 0
                || _.find(self.items(), function (i) { return self.hasBadXML(i.key()); });
        };

        self.getItems = function () {
            return _(self.items()).map(function (item) {
                return {
                    key: ko.utils.unwrapObservable(item.key),
                    value: _.object(_(item.value()).map(function (value, lang) {
                        return [lang, ko.utils.unwrapObservable(value)];
                    })),
                };
            });
        };

        return self;
    };

    module.new = function (options) {
        var m = MapList(options);
        m.edit = ko.observable(true);
        m.buttonText = options.buttonText || gettext("Edit"),
        m.values_are_icons = ko.observable(options.values_are_icons || false);
        m.keys_are_conditions = ko.observable(options.keys_are_conditions || false);
        m.openModal = function () {
            // create a throw-away modal every time
            // lets us create a sandbox for editing that you can cancel
            var $modalDiv = $(document.createElement("div"));
            $modalDiv.attr("data-bind", "template: 'key_value_mapping_modal'");
            var copy = MapList({
                lang: options.lang,
                langs: options.langs,
                module_id: options.module_id,
                items: m.getItems(),
                values_are_icons: m.values_are_icons(),
                keys_are_conditions: m.keys_are_conditions(),
                multimedia: m.multimedia,
                property_name: options.property_name,
            });
            $modalDiv.koApplyBindings({
                modalTitle: ko.computed(function () {
                    return _.template(gettext('Edit mapping for <%= property %>'))({
                        property: m.getPropertyName(),
                    });
                }),
                mapList: copy,
                save: function (data, e) {
                    if (copy.duplicatedItems().length > 0) {
                        e.stopImmediatePropagation();
                    } else {
                        m.setItems(copy.getItems());
                    }
                },
            });

            var $modal = $modalDiv.find('.modal');
            $modal.appendTo('body');
            $modal.modal({
                show: true,
                backdrop: 'static',
            });
            $modal.on('hidden', function () {
                $modal.remove();
            });
        };
        m.setEdit = function (edit) {
            m.edit(edit);
        };
        var $div = $(document.createElement("div"));
        $div.attr("data-bind", "template: \'key_value_mapping_template\'");
        $div.koApplyBindings(m);
        m.ui = $div;
        hqImport("hqwebapp/js/main").eventize(m);
        m.items.subscribe(function () {
            m.fire('change');
        });
        return m;
    };

    return module;

});
<commit_msg>fix ui-element-key-val-mapping.js<commit_after>/**
    Key-value mapping UI element.

    This element generates a button that pops up a modal containing pairs of keys and values.
    Expects to be used in app manager, in the context of an application module.
    Used primarily in case list/detail display properties. Keys may be strings
    (as in ID Mapping format) or calcuations (as in Conditional ID Mapping format).
    Values may be strings (as in both ID Mapping formats) or references to images
    (as in Icon format). Supports translations.

    Options:
        Required:
            items: Array of current values. Each item should be the javascript equivalent
                of a MappingItem.
            lang: Current language.
            langs: All languages.
            property_name: Observable representing the name of the overall mapping.
                May be either a string or one of the elements defined in hqwebapp/js/ui-element.
                Used primarily to add title to modal. If values_are_icons, this should be a slug.
        Optional:
            keys_are_conditions: True iff KEYS are calculations rather than strings.
            values_are_icons: True iff values are image references ("jr://file...")
            module_id: Module id, should be provided if values_are_icons is being used in a module context
                (e.g., case list/detail config).
            multimedia: Only needed if values_are_icons. Object containing multimedia
                to be passed as appMenuMediaManager's objectMap. Keys are image references;
                values are objects as generated by CommCareMultimedia.get_media_info
            buttonText: Text for button that opens modal. Defaults to "Edit".
 */
hqDefine('hqwebapp/js/ui_elements/ui-element-key-val-mapping', function () {
    'use strict';
    var module = {};

    // To autogenerate cssid from random string
    // copied from http://stackoverflow.com/questions/7627000/javascript-convert-string-to-safe-class-name-for-css
    var makeSafeForCSS = function (name) {
        if (!name) {
            return "";
        }
        return name.replace(/[^a-z0-9]/g, function (s) {
            var c = s.charCodeAt(0);
            if (c === 32) return '-';
            if (c >= 65 && c <= 90) return '_' + s.toLowerCase();
            return '__' + ('000' + c.toString(16)).slice(-4);
        });
    };

    /**
    * MapItem is a ko representation for `item` objects.
    *
    * @param item: a raw object which contains keys called `key` and `value`.
    *              the `value` in a item itself is an object, a mapping
    *              of language codes to strings
    * @param mappingContext: an object which has context of current UI language and whether
    *                 `value` of MapItem is a file-path to an icon or a simple string
    */
    var MapItem = function (item, index, mappingContext) {
        var self = {};
        self.key = ko.observable(item.key);
        self.editing = ko.observable(false);

        self.cssId = ko.computed(function () {
            return makeSafeForCSS(self.key()) || '_blank_';
        });

        // util function to generate icon-name of the format "module<module_id>_list_icon_<property_name>_<hash_of_item.key>"
        self.generateIconPath = function () {
            var randomFourDigits = Math.floor(Math.random() * 9000) + 1000;
            var iconPrefix =  "jr://file/commcare/image/module" + mappingContext.module_id + "_list_icon_" + mappingContext.getPropertyName() + "_";
            return iconPrefix + randomFourDigits + ".png";
        };

        var app_manager = hqImport('app_manager/js/app_manager_media');
        var uploaders = hqImport("app_manager/js/nav_menu_media_common");
        // attach a media-manager if item.value is a file-path to icon
        if (mappingContext.values_are_icons()) {
            var actualPath = item.value[mappingContext.lang];
            var defaultIconPath = actualPath || self.generateIconPath();
            self.iconManager = app_manager.appMenuMediaManager({
                ref: {
                    "path": actualPath,
                    "icon_type": "icon-picture",
                    "media_type": "Image",
                    "media_class": "CommCareImage",
                    "icon_class": "icon-picture",
                },
                objectMap: mappingContext.multimedia,
                uploadController: uploaders.iconUploader,
                defaultPath: defaultIconPath,
                inputElement: $("#" + self.cssId()),
            });
        }

        self.toggleEditMode = function () {
            self.editing(!self.editing());
        };

        self.value = ko.computed(function () {
            // ko.observable for item.value
            var new_value = [];
            var langs = _.union(_(item.value).keys(), [mappingContext.lang]) ;
            _.each(langs, function (lang) {
                // return ko reference to path in `iconManager` for current UI language value
                if (mappingContext.values_are_icons() && lang === mappingContext.lang) {
                    new_value.push([lang, self.iconManager.customPath]);
                }
                // return new ko.observable for other languages
                else {
                    new_value.push([lang, ko.observable(item.value[lang])]);
                }
            });
            return _.object(new_value);
        });

        self.key.subscribe(function (newValue) {
            if (mappingContext.duplicatedItems.indexOf(newValue) === -1 && mappingContext._isItemDuplicated(newValue)) {
                mappingContext.duplicatedItems.push(newValue);
            }

        });

        self.key.subscribe(function (oldValue) {
            var index = mappingContext.duplicatedItems.indexOf(oldValue);
            if (index !== -1 && !mappingContext._isItemDuplicated(oldValue, 2)) {
                mappingContext.duplicatedItems.remove(oldValue);
            }
        }, null, "beforeChange");

        return self;
    };

    /**
     * A MapList is an ordered list of MapItem objects
     */
    var MapList = function (options) {
        hqImport("hqwebapp/js/assert_properties").assert(options, [
            'lang',
            'langs',
            'items',
            'property_name',
        ], [
            'buttonText',
            'keys_are_conditions',
            'module_id',
            'multimedia',
            'values_are_icons',
        ]);

        var self = {};
        self.lang = options.lang;
        self.langs = [options.lang].concat(options.langs);
        self.module_id = options.module_id;
        self.items = ko.observableArray();
        self.duplicatedItems = ko.observableArray();
        self.values_are_icons = ko.observable(options.values_are_icons || false);
        self.keys_are_conditions = ko.observable(options.keys_are_conditions || false);
        self.multimedia = options.multimedia;

        self.getPropertyName = function () {
            if (_.isObject(options.property_name) && _.isFunction(options.property_name.val)) {
                return options.property_name.val();
            }
            return options.property_name;
        };

        self.labels = ko.computed(function () {
            if (self.values_are_icons()) {
                return {
                    placeholder: django.gettext('Calculation'),
                    duplicated: django.gettext('Calculation is duplicated'),
                    addButton: django.gettext('Add Image'),
                    badXML: django.gettext('Calculation contains an invalid character.'),
                };
            }
            else if (self.keys_are_conditions()) {
                return {
                    placeholder: django.gettext('Calculation'),
                    duplicated: django.gettext('Calculation is duplicated'),
                    addButton: django.gettext('Add Key, Value Mapping'),
                    badXML: django.gettext('Calculation contains an invalid character.'),
                };
            }
            else {
                return {
                    placeholder: django.gettext('Key'),
                    duplicated: django.gettext('Key is duplicated'),
                    addButton: django.gettext('Add Key, Value Mapping'),
                    badXML: django.gettext('Key contains an invalid character.'),
                };
            }
        });

        self.setItems = function (items) {
            self.items(_(items).map(function (item, i) {
                return new MapItem(item, i, self);
            }));
        };
        self.setItems(options.items);

        self.backup = function (value) {
            var backup;
            for (var i = 0; i < self.langs.length; i += 1) {
                var lang = self.langs[i];
                backup = value[lang];
                if (backup && backup() !== '') {
                    return {lang: lang, value: backup()};
                }
            }
            return {lang: null, value: 'value'};
        };
        self.removeItem = function (item) {
            self.items.remove(item);
            if (!self._isItemDuplicated(ko.utils.unwrapObservable(item.key)))
                self.duplicatedItems.remove(ko.utils.unwrapObservable(item.key));
        };
        self.addItem = function () {
            var raw_item = {key: '', value: {}};
            raw_item.value[self.lang] = '';

            var item = new MapItem(raw_item, self.items.length, self);
            self.items.push(item);
            if (self.duplicatedItems.indexOf('') === -1 && self._isItemDuplicated('')) {
                self.duplicatedItems.push('');
            }
        };

        self._isItemDuplicated = function (key, max_counts) {
            if (typeof(max_counts) === 'undefined') max_counts = 1;
            var items = self.getItems();
            var counter = 0;
            for (var i = 0; i < items.length; i++) {
                var item = items[i];
                if (ko.utils.unwrapObservable(item.key) === key) {
                    counter++;
                    if (counter > max_counts) return true;
                }
            }
            return false;
        };

        self.isItemDuplicated = function (key) {
            return self.duplicatedItems.indexOf(key) !== -1;
        };

        self.hasBadXML = function (key) {
            if (self.values_are_icons() || self.keys_are_conditions()) {
                // Expressions can contain whatever
                return false;
            }

            // IDs shouldn't have invalid XML characters
            return key.match(/[&<>"']/);
        };

        self.keyHasError = function (key) {
            return self.isItemDuplicated(key) || self.hasBadXML(key);
        };

        self.hasError = function () {
            return self.duplicatedItems().length > 0
                || _.find(self.items(), function (i) { return self.hasBadXML(i.key()); });
        };

        self.getItems = function () {
            return _(self.items()).map(function (item) {
                return {
                    key: ko.utils.unwrapObservable(item.key),
                    value: _.object(_(item.value()).map(function (value, lang) {
                        return [lang, ko.utils.unwrapObservable(value)];
                    })),
                };
            });
        };

        return self;
    };

    module.new = function (options) {
        var m = MapList(options);
        m.edit = ko.observable(true);
        m.buttonText = options.buttonText || gettext("Edit"),
        m.values_are_icons = ko.observable(options.values_are_icons || false);
        m.keys_are_conditions = ko.observable(options.keys_are_conditions || false);
        m.openModal = function () {
            // create a throw-away modal every time
            // lets us create a sandbox for editing that you can cancel
            var $modalDiv = $(document.createElement("div"));
            $modalDiv.attr("data-bind", "template: 'key_value_mapping_modal'");
            var copy = MapList({
                lang: options.lang,
                langs: options.langs,
                module_id: options.module_id,
                items: m.getItems(),
                values_are_icons: m.values_are_icons(),
                keys_are_conditions: m.keys_are_conditions(),
                multimedia: m.multimedia,
                property_name: options.property_name,
            });
            $modalDiv.koApplyBindings({
                modalTitle: ko.computed(function () {
                    return _.template(gettext('Edit mapping for <%- property %>'))({
                        property: m.getPropertyName(),
                    });
                }),
                mapList: copy,
                save: function (data, e) {
                    if (copy.duplicatedItems().length > 0) {
                        e.stopImmediatePropagation();
                    } else {
                        m.setItems(copy.getItems());
                    }
                },
            });

            var $modal = $modalDiv.find('.modal');
            $modal.appendTo('body');
            $modal.modal({
                show: true,
                backdrop: 'static',
            });
            $modal.on('hidden', function () {
                $modal.remove();
            });
        };
        m.setEdit = function (edit) {
            m.edit(edit);
        };
        var $div = $(document.createElement("div"));
        $div.attr("data-bind", "template: \'key_value_mapping_template\'");
        $div.koApplyBindings(m);
        m.ui = $div;
        hqImport("hqwebapp/js/main").eventize(m);
        m.items.subscribe(function () {
            m.fire('change');
        });
        return m;
    };

    return module;

});
<|endoftext|>


<commit_before>// Author : 7thGrader
// Read LICENSE File

var a = 0;
var b = 0;
var c = 0;
var 4acb2 = 0;
var ansexc = new Array(0,0,0);
var exactreturn1 = " ";
var exactreturn2 = " ";

function procCmd(cmd)
{
var cd = cmd.split(" ");
if(cd[0] == seteq)
{
a = cd[1];
b = cd[2];
c = cd[3];
}
else if(cd[0] == solveeq)
{
4acb2 = (4*a*c)-Math.pow(b,2);
ansexc[0] = -1*b;
ansexc[1] = 4acb2;
ansexc[2] = 2*a;
if(4acb2 >= 0) //if 4ac-b² is 0 or positive
{
clientMessage("(" + ansexc[0] + " ±  √ " + ansexc[1] + ") / (" + ansexc[2] + ")");
}
else if(4acb2 < 0) //if 4ac-b² is negative
{
clientMessage("(" + ansexc[0] + " ± √ (" + ansexc[1] + ")i) / (" + ansexc[2] + ")"); //i = sqrt(-1)
}
}
else if(cd[0] == appeq)
{
4acb2 = (4*a*c)-Math.pow(b,2);
if(4acb2>=0)
{
clientMessage(((-1*b) + (Math.sqrt(4acb2)))/(2*a));
clientMessage(((-1*b) - (Math.sqrt(4acb2)))/(2*a));
else clientMessage("Try use /solve");
}
}
else return;
}
<commit_msg>Create quadratic.js<commit_after>var a = 0;
var b = 0;
var c = 0;
var 4acb2 = 0;
var ansexc = new Array(0,0,0);
var exactreturn1 = " ";
var exactreturn2 = " ";

function procCmd(cmd)
{
var cd = cmd.split(" ");
if(cd[0] == seteq)
{cc
a = cd[1];
b = cd[2];
c = cd[3];
}
else if(cd[0] == solveeq)
{
4acb2 = Math.pow(b,2) - (4*a*c) ;
ansexc[0] = -1*b;
ansexc[1] = 4acb2;
ansexc[2] = 2*a;
if(4acb2 >= 0) //if 4ac-b² is 0 or positive
{
clientMessage("(" + ansexc[0] + " ±  √ " + ansexc[1] + ") / (" + ansexc[2] + ")");
}
else if(4acb2 < 0) //if 4ac-b² is negative
{
clientMessage("(" + ansexc[0] + " ± √ (" + ansexc[1] + ")i) / (" + ansexc[2] + ")"); //i = sqrt(-1)
}
}
else if(cd[0] == appeq)
{
4acb2 = (4*a*c)-Math.pow(b,2);
if(4acb2>=0)
{
clientMessage(((-1*b) + (Math.sqrt(4acb2)))/(2*a));
clientMessage(((-1*b) - (Math.sqrt(4acb2)))/(2*a));
else clientMessage("Try use /solveeq");
}
}
else return;
}
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */
require( ["order!jquery" ,"order!redback/redback"],
function($) {

$(function() {

  // define a container object with various datas
  window.archivaModel = {};

  $.log("devMode:"+window.archivaDevMode);

  // no cache for ajax queries as we get datas from servers so preventing caching !!
  jQuery.ajaxSetup( {
    cache: false//!window.archivaDevMode
  } );

  /**
   * reccord a cookie for session with the logged user
   * @param user see user.js
   */
  reccordLoginCookie=function(user) {
    $.cookie('redback_login', ko.toJSON(user));
  }

  getUserFromLoginCookie=function(){
    return $.parseJSON($.cookie('redback_login'));
  }

  deleteLoginCookie=function(){
    $.cookie('redback_login', null);
  }

  logout=function(){
    deleteLoginCookie();
    $("#login-link").show();
    $("#register-link").show();
    $("#logout-link").hide();
    $("#change-password-link").hide();
    hideElementWithKarma();
    screenChange();
    $("#main-content").html("");
    $.ajax({
      url: 'restServices/redbackServices/loginService/logout'
    });
  }

  decorateMenuWithKarma=function(user) {
    var username = user.username;
    // we can receive an observable user so take if it's a function or not
    if ($.isFunction(username)){
      username = user.username();
    }
    var url = 'restServices/redbackServices/userService/getCurrentUserOperations';
    $.ajax({
      url: url,
      success: function(data){
        var mappedOperations = $.map(data.operation, function(item) {
            return mapOperation(item);
        });
        window.redbackModel.operatioNames = $.map(mappedOperations, function(item){
          return item.name();
        });

        $("#topbar-menu-container [redback-permissions]").each(function(element){
          checkElementKarma(this);
        });
        $("#sidebar-content [redback-permissions]").each(function(element){
          checkElementKarma(this);
        });
      }
    });
  }

  checkElementKarma=function(element){
    var bindingValue = $(element).attr("redback-permissions");
    $(element).hide();
    var neededKarmas = $(eval(bindingValue)).toArray();
    var karmaOk = false;
    $(neededKarmas).each(function(value){
      if ($.inArray(neededKarmas[value],window.redbackModel.operatioNames)>=0) {
        karmaOk = true;
      }
    });
    if (karmaOk == false) {
      $(element).hide();
    } else {
      $(element).show();
    }
  }

  hideElementWithKarma=function(){
    $("#topbar-menu-container [redback-permissions]").each(function(element){
      $(this).hide();
    });

    $("#sidebar-content [redback-permissions]").each(function(element){
      $(this).hide();
    });
    $.log("hideElementWithKarma");
  }

  userLoggedCallbackFn=function(user){
    $.log("userLoggedCallbackFn:"+ (user?user.username:null));

    if (!user) {
      $("#login-link").show();
      $("#register-link").show();
      $("#change-password-link").hide();
    } else {
      $("#change-password-link").show();
      $("#logout-link").show();
      $("#register-link").hide();
      $("#login-link").hide();
      decorateMenuWithKarma(user);
    }
  }

  checkSecurityLinks=function(){
    userLogged(userLoggedCallbackFn);
  }

  checkCreateAdminLink=function(){
    $.ajax("restServices/redbackServices/userService/isAdminUserExists", {
      type: "GET",
      dataType: 'json',
      success: function(data) {
        var adminExists = JSON.parse(data);
        if (adminExists == false) {
          $("#create-admin-link").show();
          $("#login-link").hide();
          $("#register-link").hide();
        } else {
          $("#create-admin-link").hide();
        }
        $.log("adminExists:"+adminExists);
      }
    });
  }

  // handle url with registration link
  $(document).ready(function() {
    var validateMeId = $.urlParam('validateMe');
    if (validateMeId) {
      validateKey(validateMeId);
    }

    var browse = $.urlParam('browse');
    if (browse){
      displayBrowseGroupId(browse);
    }
  });

  startArchivaApplication = function(){
    $.log("startArchivaApplication");
    $('#topbar-menu-container').html($("#topbar-menu"));
    $('#sidebar-content').html($("#main-menu"));

    hideElementWithKarma();
    checkSecurityLinks();
    checkCreateAdminLink();
    $('#footer-content').html($('#footer-tmpl').tmpl(window.archivaRuntimeInfo));

    // create handlers on menu entries to add class active on click
    var alinkNodes=$("#sidebar-content #main-menu").find("li a");
    alinkNodes.on("click",function(){
      alinkNodes.parent("li").removeClass("active");
      $(this).parent("li").addClass("active");
    })

    $( "#quick-search-autocomplete" ).autocomplete({
      minLength: 3,
			source: function(request, response){
        $.get("restServices/archivaServices/searchService/quickSearch?queryString="+encodeURIComponent(request.term),
           function(data) {
             var res = $.map(data.artifact,function(item){
               return item.artifactId;
             });
             response(res);
           }
        );

      }
		});

  }
  startArchivaApplication();
})
});

<commit_msg>avoid duplicate entries in the autocomplete search bix<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */
require( ["order!jquery" ,"order!redback/redback"],
function($) {

$(function() {

  // define a container object with various datas
  window.archivaModel = {};

  $.log("devMode:"+window.archivaDevMode);

  // no cache for ajax queries as we get datas from servers so preventing caching !!
  jQuery.ajaxSetup( {
    cache: false//!window.archivaDevMode
  } );

  /**
   * reccord a cookie for session with the logged user
   * @param user see user.js
   */
  reccordLoginCookie=function(user) {
    $.cookie('redback_login', ko.toJSON(user));
  }

  getUserFromLoginCookie=function(){
    return $.parseJSON($.cookie('redback_login'));
  }

  deleteLoginCookie=function(){
    $.cookie('redback_login', null);
  }

  logout=function(){
    deleteLoginCookie();
    $("#login-link").show();
    $("#register-link").show();
    $("#logout-link").hide();
    $("#change-password-link").hide();
    hideElementWithKarma();
    screenChange();
    $("#main-content").html("");
    $.ajax({
      url: 'restServices/redbackServices/loginService/logout'
    });
  }

  decorateMenuWithKarma=function(user) {
    var username = user.username;
    // we can receive an observable user so take if it's a function or not
    if ($.isFunction(username)){
      username = user.username();
    }
    var url = 'restServices/redbackServices/userService/getCurrentUserOperations';
    $.ajax({
      url: url,
      success: function(data){
        var mappedOperations = $.map(data.operation, function(item) {
            return mapOperation(item);
        });
        window.redbackModel.operatioNames = $.map(mappedOperations, function(item){
          return item.name();
        });

        $("#topbar-menu-container [redback-permissions]").each(function(element){
          checkElementKarma(this);
        });
        $("#sidebar-content [redback-permissions]").each(function(element){
          checkElementKarma(this);
        });
      }
    });
  }

  checkElementKarma=function(element){
    var bindingValue = $(element).attr("redback-permissions");
    $(element).hide();
    var neededKarmas = $(eval(bindingValue)).toArray();
    var karmaOk = false;
    $(neededKarmas).each(function(value){
      if ($.inArray(neededKarmas[value],window.redbackModel.operatioNames)>=0) {
        karmaOk = true;
      }
    });
    if (karmaOk == false) {
      $(element).hide();
    } else {
      $(element).show();
    }
  }

  hideElementWithKarma=function(){
    $("#topbar-menu-container [redback-permissions]").each(function(element){
      $(this).hide();
    });

    $("#sidebar-content [redback-permissions]").each(function(element){
      $(this).hide();
    });
    $.log("hideElementWithKarma");
  }

  userLoggedCallbackFn=function(user){
    $.log("userLoggedCallbackFn:"+ (user?user.username:null));

    if (!user) {
      $("#login-link").show();
      $("#register-link").show();
      $("#change-password-link").hide();
    } else {
      $("#change-password-link").show();
      $("#logout-link").show();
      $("#register-link").hide();
      $("#login-link").hide();
      decorateMenuWithKarma(user);
    }
  }

  checkSecurityLinks=function(){
    userLogged(userLoggedCallbackFn);
  }

  checkCreateAdminLink=function(){
    $.ajax("restServices/redbackServices/userService/isAdminUserExists", {
      type: "GET",
      dataType: 'json',
      success: function(data) {
        var adminExists = JSON.parse(data);
        if (adminExists == false) {
          $("#create-admin-link").show();
          $("#login-link").hide();
          $("#register-link").hide();
        } else {
          $("#create-admin-link").hide();
        }
        $.log("adminExists:"+adminExists);
      }
    });
  }

  // handle url with registration link
  $(document).ready(function() {
    var validateMeId = $.urlParam('validateMe');
    if (validateMeId) {
      validateKey(validateMeId);
    }

    var browse = $.urlParam('browse');
    if (browse){
      displayBrowseGroupId(browse);
    }
  });

  startArchivaApplication = function(){
    $.log("startArchivaApplication");
    $('#topbar-menu-container').html($("#topbar-menu"));
    $('#sidebar-content').html($("#main-menu"));

    hideElementWithKarma();
    checkSecurityLinks();
    checkCreateAdminLink();
    $('#footer-content').html($('#footer-tmpl').tmpl(window.archivaRuntimeInfo));

    // create handlers on menu entries to add class active on click
    var alinkNodes=$("#sidebar-content #main-menu").find("li a");
    alinkNodes.on("click",function(){
      alinkNodes.parent("li").removeClass("active");
      $(this).parent("li").addClass("active");
    })

    $( "#quick-search-autocomplete" ).autocomplete({
      minLength: 3,
			source: function(request, response){
        $.get("restServices/archivaServices/searchService/quickSearch?queryString="+encodeURIComponent(request.term),
           function(data) {
             var res = $.map(data.artifact,function(item){
               return item.artifactId;
             });
             var uniqId = [];
             for (var i= 0;i<res.length;i++){
               if ( $.inArray(res[i],uniqId)<0){
                 uniqId.push(res[i]);
               }
             }
             response(uniqId);
           }
        );

      }
		});

  }
  startArchivaApplication();
})
});

<|endoftext|>


<commit_before>const buildCommit = require('./buildCommit');
const log = require('./logger');

const isNotWip = answers => answers.type.toLowerCase() !== 'wip';

const isValidateTicketNo = (value, config) => {
  if (!value) {
    return !config.isTicketNumberRequired;
  }
  if (!config.ticketNumberRegExp) {
    return true;
  }
  const reg = new RegExp(config.ticketNumberRegExp);
  if (value.replace(reg, '') !== '') {
    return false;
  }
  return true;
};

module.exports = {
  getQuestions(config, cz) {
    // normalize config optional options
    const scopeOverrides = config.scopeOverrides || {};
    const messages = config.messages || {};
    const skipQuestions = config.skipQuestions || [];

    messages.type = messages.type || "Select the type of change that you're committing:";
    messages.scope = messages.scope || '\nDenote the SCOPE of this change (optional):';
    messages.customScope = messages.customScope || 'Denote the SCOPE of this change:';
    if (!messages.ticketNumber) {
      if (config.ticketNumberRegExp) {
        messages.ticketNumber =
          messages.ticketNumberPattern ||
          `Enter the ticket number following this pattern (${config.ticketNumberRegExp})\n`;
      } else {
        messages.ticketNumber = 'Enter the ticket number:\n';
      }
    }
    messages.subject = messages.subject || 'Write a SHORT, IMPERATIVE tense description of the change:\n';
    messages.body =
      messages.body || 'Provide a LONGER description of the change (optional). Use "|" to break new line:\n';
    messages.breaking = messages.breaking || 'List any BREAKING CHANGES (optional):\n';
    messages.footer = messages.footer || 'List any ISSUES CLOSED by this change (optional). E.g.: #31, #34:\n';
    messages.confirmCommit = messages.confirmCommit || 'Are you sure you want to proceed with the commit above?';

    let questions = [
      {
        type: 'list',
        name: 'type',
        message: messages.type,
        choices: config.types,
      },
      {
        type: 'list',
        name: 'scope',
        message: messages.scope,
        choices(answers) {
          let scopes = [];
          if (scopeOverrides[answers.type]) {
            scopes = scopes.concat(scopeOverrides[answers.type]);
          } else {
            scopes = scopes.concat(config.scopes);
          }
          if (config.allowCustomScopes || scopes.length === 0) {
            scopes = scopes.concat([
              new cz.Separator(),
              { name: 'empty', value: false },
              { name: 'custom', value: 'custom' },
            ]);
          }
          return scopes;
        },
        when(answers) {
          let hasScope = false;
          if (scopeOverrides[answers.type]) {
            hasScope = !!(scopeOverrides[answers.type].length > 0);
          } else {
            hasScope = !!(config.scopes && config.scopes.length > 0);
          }
          if (!hasScope) {
            // TODO: Fix when possible
            // eslint-disable-next-line no-param-reassign
            answers.scope = 'custom';
            return false;
          }
          return isNotWip(answers);
        },
      },
      {
        type: 'input',
        name: 'scope',
        message: messages.customScope,
        when(answers) {
          return answers.scope === 'custom';
        },
      },
      {
        type: 'input',
        name: 'ticketNumber',
        message: messages.ticketNumber,
        when() {
          return !!config.allowTicketNumber; // no ticket numbers allowed unless specifed
        },
        validate(value) {
          return isValidateTicketNo(value, config);
        },
      },
      {
        type: 'input',
        name: 'subject',
        message: messages.subject,
        validate(value) {
          const limit = config.subjectLimit || 100;
          if (value.length > limit) {
            return `Exceed limit: ${limit}`;
          }
          return true;
        },
        filter(value) {
          const upperCaseSubject = config.upperCaseSubject || false;

          return (upperCaseSubject ? value.charAt(0).toUpperCase() : value.charAt(0).toLowerCase()) + value.slice(1);
        },
      },
      {
        type: 'input',
        name: 'body',
        message: messages.body,
      },
      {
        type: 'input',
        name: 'breaking',
        message: messages.breaking,
        when(answers) {
          // eslint-disable-next-line max-len
          if (config.allowBreakingChanges && config.allowBreakingChanges.indexOf(answers.type.toLowerCase()) >= 0) {
            return true;
          }
          return false; // no breaking changes allowed unless specifed
        },
      },
      {
        type: 'input',
        name: 'footer',
        message: messages.footer,
        when: isNotWip,
      },
      {
        type: 'expand',
        name: 'confirmCommit',
        choices: [
          { key: 'y', name: 'Yes', value: 'yes' },
          { key: 'n', name: 'Abort commit', value: 'no' },
          { key: 'e', name: 'Edit message', value: 'edit' },
        ],
        message(answers) {
          const SEP = '###--------------------------------------------------------###';
          log.info(`\n${SEP}\n${buildCommit(answers, config)}\n${SEP}\n`);
          return messages.confirmCommit;
        },
      },
    ];

    questions = questions.filter(item => !skipQuestions.includes(item.name));

    return questions;
  },
};
<commit_msg>fix: `yes` should be default for confirmCommit (#85)<commit_after>const buildCommit = require('./buildCommit');
const log = require('./logger');

const isNotWip = answers => answers.type.toLowerCase() !== 'wip';

const isValidateTicketNo = (value, config) => {
  if (!value) {
    return !config.isTicketNumberRequired;
  }
  if (!config.ticketNumberRegExp) {
    return true;
  }
  const reg = new RegExp(config.ticketNumberRegExp);
  if (value.replace(reg, '') !== '') {
    return false;
  }
  return true;
};

module.exports = {
  getQuestions(config, cz) {
    // normalize config optional options
    const scopeOverrides = config.scopeOverrides || {};
    const messages = config.messages || {};
    const skipQuestions = config.skipQuestions || [];

    messages.type = messages.type || "Select the type of change that you're committing:";
    messages.scope = messages.scope || '\nDenote the SCOPE of this change (optional):';
    messages.customScope = messages.customScope || 'Denote the SCOPE of this change:';
    if (!messages.ticketNumber) {
      if (config.ticketNumberRegExp) {
        messages.ticketNumber =
          messages.ticketNumberPattern ||
          `Enter the ticket number following this pattern (${config.ticketNumberRegExp})\n`;
      } else {
        messages.ticketNumber = 'Enter the ticket number:\n';
      }
    }
    messages.subject = messages.subject || 'Write a SHORT, IMPERATIVE tense description of the change:\n';
    messages.body =
      messages.body || 'Provide a LONGER description of the change (optional). Use "|" to break new line:\n';
    messages.breaking = messages.breaking || 'List any BREAKING CHANGES (optional):\n';
    messages.footer = messages.footer || 'List any ISSUES CLOSED by this change (optional). E.g.: #31, #34:\n';
    messages.confirmCommit = messages.confirmCommit || 'Are you sure you want to proceed with the commit above?';

    let questions = [
      {
        type: 'list',
        name: 'type',
        message: messages.type,
        choices: config.types,
      },
      {
        type: 'list',
        name: 'scope',
        message: messages.scope,
        choices(answers) {
          let scopes = [];
          if (scopeOverrides[answers.type]) {
            scopes = scopes.concat(scopeOverrides[answers.type]);
          } else {
            scopes = scopes.concat(config.scopes);
          }
          if (config.allowCustomScopes || scopes.length === 0) {
            scopes = scopes.concat([
              new cz.Separator(),
              { name: 'empty', value: false },
              { name: 'custom', value: 'custom' },
            ]);
          }
          return scopes;
        },
        when(answers) {
          let hasScope = false;
          if (scopeOverrides[answers.type]) {
            hasScope = !!(scopeOverrides[answers.type].length > 0);
          } else {
            hasScope = !!(config.scopes && config.scopes.length > 0);
          }
          if (!hasScope) {
            // TODO: Fix when possible
            // eslint-disable-next-line no-param-reassign
            answers.scope = 'custom';
            return false;
          }
          return isNotWip(answers);
        },
      },
      {
        type: 'input',
        name: 'scope',
        message: messages.customScope,
        when(answers) {
          return answers.scope === 'custom';
        },
      },
      {
        type: 'input',
        name: 'ticketNumber',
        message: messages.ticketNumber,
        when() {
          return !!config.allowTicketNumber; // no ticket numbers allowed unless specifed
        },
        validate(value) {
          return isValidateTicketNo(value, config);
        },
      },
      {
        type: 'input',
        name: 'subject',
        message: messages.subject,
        validate(value) {
          const limit = config.subjectLimit || 100;
          if (value.length > limit) {
            return `Exceed limit: ${limit}`;
          }
          return true;
        },
        filter(value) {
          const upperCaseSubject = config.upperCaseSubject || false;

          return (upperCaseSubject ? value.charAt(0).toUpperCase() : value.charAt(0).toLowerCase()) + value.slice(1);
        },
      },
      {
        type: 'input',
        name: 'body',
        message: messages.body,
      },
      {
        type: 'input',
        name: 'breaking',
        message: messages.breaking,
        when(answers) {
          // eslint-disable-next-line max-len
          if (config.allowBreakingChanges && config.allowBreakingChanges.indexOf(answers.type.toLowerCase()) >= 0) {
            return true;
          }
          return false; // no breaking changes allowed unless specifed
        },
      },
      {
        type: 'input',
        name: 'footer',
        message: messages.footer,
        when: isNotWip,
      },
      {
        type: 'expand',
        name: 'confirmCommit',
        choices: [
          { key: 'y', name: 'Yes', value: 'yes' },
          { key: 'n', name: 'Abort commit', value: 'no' },
          { key: 'e', name: 'Edit message', value: 'edit' },
        ],
        default: 0,
        message(answers) {
          const SEP = '###--------------------------------------------------------###';
          log.info(`\n${SEP}\n${buildCommit(answers, config)}\n${SEP}\n`);
          return messages.confirmCommit;
        },
      },
    ];

    questions = questions.filter(item => !skipQuestions.includes(item.name));

    return questions;
  },
};
<|endoftext|>


<commit_before>const should = require('should');
const uuid = require('uuid');
const config = require('../../lib/config');
const services = require('../../lib/services');
const applicationService = services.application;
const userService = services.user;
const db = require('../../lib/db');

describe('Application service tests', function () {
  describe('Insert tests', function () {
    let user, originalAppModelConfig;

    before(() => {
      originalAppModelConfig = Object.assign({}, config.models.applications.properties);
      Object.assign(config.models.applications.properties, {
        group: { type: 'string', default: 'someGroup' },
        irrelevantProp: { type: 'string' }
      });

      return db.flushdb();
    });

    after(function () {
      config.models.applications.properties = originalAppModelConfig;
    });

    it('should insert an application and application should have default value of properties if not defined, and un-required properties ignored if not defined', function () {
      const _user = createRandomUserObject();
      let app;

      return userService
        .insert(_user)
        .then(function (newUser) {
          user = newUser;
          should.exist(user.id);
          app = {
            name: 'test-app-1'
          };

          return applicationService.insert(app, user.id);
        })
        .then(function (newApp) {
          should.exist(newApp);
          should(newApp).have.properties(['id', 'name', 'isActive', 'group', 'createdAt', 'userId']);
          newApp.isActive.should.eql(true);
          newApp.name.should.eql(app.name);
          newApp.group.should.eql('someGroup');
          should(newApp).not.have.property('irrelevantProp');
          newApp.userId.should.eql(user.id);
        });
    });

    it('should throw when inserting an app with missing properties that are required', function () {
      return should(applicationService.insert({}, user.id))
        .be.rejectedWith('Failed to insert application: data should have required property \'name\'');
    });

    it('should allow inserting multiple applications per user', function () {
      const app = {
        name: 'test-app-2'
      };

      return applicationService
        .insert(app, user.id)
        .then(function (newApp) {
          should.exist(newApp);
          should(newApp).have.properties(['id', 'name', 'isActive', 'createdAt', 'userId']);
          newApp.name.should.eql(app.name);
          newApp.userId.should.eql(user.id);
        });
    });
  });

  describe('Get application tests', function () {
    let user, app, originalAppModelConfig;

    before(function () {
      originalAppModelConfig = Object.assign({}, config.models.applications.properties);
      Object.assign(config.models.applications.properties, {
        group: { type: 'string', default: 'someGroup' },
        irrelevantProp: { type: 'string' }
      });

      return db.flushdb()
        .then(function () {
          const _user = createRandomUserObject();
          return userService.insert(_user);
        })
        .then(function (newUser) {
          should.exist(newUser);
          user = newUser;
          app = {
            name: 'test-app'
          };
          return applicationService.insert(app, user.id);
        }
        ).then(function (newApp) {
          should.exist(newApp);
          app = newApp;
        });
    });

    after(function () {
      config.models.applications.properties = originalAppModelConfig;
    });

    it('should get app by id', function () {
      return applicationService
        .get(app.id)
        .then(function (_app) {
          should.exist(_app);
          should(_app).have.properties(['id', 'name', 'createdAt', 'updatedAt']);
          _app.id.should.eql(app.id);
          _app.name.should.eql(app.name);
        });
    });

    it('should get all apps', function () {
      return applicationService
        .findAll()
        .then(function (data) {
          should.exist(data.apps);
          data.apps.length.should.eql(1);
          const app = data.apps[0];
          should.exist(app);
          should(app).have.properties(['id', 'name', 'createdAt', 'updatedAt']);
          app.id.should.eql(app.id);
          app.name.should.eql(app.name);
        });
    });

    it('should not get app by invalid id', function () {
      return applicationService.get('invalid_id')
        .then(function (_app) {
          should.exist(_app);
          _app.should.eql(false);
        });
    });

    it('should get all apps belonging to a user', function () {
      let user1, app1, app2;

      return userService
        .insert(createRandomUserObject())
        .then(function (newUser) {
          should.exist(newUser);
          user1 = newUser;
          app1 = {
            name: 'test-app-1'
          };
          return applicationService
            .insert(app1, user1.id)
            .then(function (newApp) {
              should.exist(newApp);
              app1 = newApp;
            });
        })
        .then(function () {
          app2 = {
            name: 'test-app-2'
          };
          return applicationService
            .insert(app2, user1.id)
            .then(function (newApp) {
              should.exist(newApp);
              app2 = newApp;
            });
        })
        .then(function () {
          return applicationService
            .getAll(user1.id)
            .then(function (apps) {
              should.exist(apps);
              apps.length.should.eql(2);
              app1.should.oneOf(apps);
              app2.should.oneOf(apps);
            });
        });
    });
  });

  describe('Update tests', function () {
    let user, app, originalAppModelConfig;

    before(function () {
      originalAppModelConfig = Object.assign({}, config.models.applications.properties);
      Object.assign(config.models.applications.properties, {
        group: { type: 'string', default: 'admin' }
      });

      return db.flushdb();
    });

    after(function () {
      config.models.applications.properties = originalAppModelConfig;
    });

    it('should update an application', function () {
      const _user = createRandomUserObject();

      return userService
        .insert(_user)
        .then(function (newUser) {
          user = newUser;
          should.exist(user.id);
          app = {
            name: 'test-app-1'
          };

          return applicationService.insert(app, user.id);
        })
        .then(function (newApp) {
          app = newApp;
          should.exist(newApp);
          should(newApp).have.properties(['id', 'name', 'createdAt', 'userId']);
          newApp.name.should.eql(app.name);
          newApp.userId.should.eql(user.id);
          const updatedApp = {
            name: 'test-app-updated'
          };
          return Promise.all([updatedApp, applicationService.update(app.id, updatedApp)]);
        }).then(([updatedApp, res]) => {
          res.should.eql(true);
          return applicationService
            .get(app.id)
            .then(function (_app) {
              should.exist(_app);
              should(_app).have.properties(['id', 'name', 'createdAt', 'updatedAt']);
              _app.id.should.eql(app.id);
              _app.name.should.eql(updatedApp.name);
              _app.createdAt.should.eql(app.createdAt);
            });
        });
    });

    it('should throw an error when updating an app with invalid properties', function () {
      const updatedApp = { invalid: 'someVal' };

      return should(applicationService
        .update(app.id, updatedApp)).be.rejectedWith('one or more properties is invalid');
    });
  });

  describe('activate/deactivate application tests', function () {
    let user, app, originalAppModelConfig;

    before(function () {
      originalAppModelConfig = Object.assign({}, config.models.applications.properties);
      Object.assign(config.models.applications.properties, {
        group: { type: 'string', default: 'admin' }
      });

      return db.flushdb();
    });

    after(function () {
      config.models.applications.properties = originalAppModelConfig;
    });

    it('should deactivate an application', function () {
      const _user = createRandomUserObject();

      return userService
        .insert(_user)
        .then(function (newUser) {
          user = newUser;
          should.exist(user.id);
          app = {
            name: 'test-app-1'
          };

          return applicationService.insert(app, user.id);
        })
        .then(function (newApp) {
          app = newApp;
          should.exist(newApp);
          should(newApp).have.properties(['id', 'name', 'createdAt', 'userId']);
          newApp.name.should.eql(app.name);
          newApp.userId.should.eql(user.id);
          return applicationService.deactivate(app.id);
        })
        .then((res) => {
          res.should.eql(true);
          return applicationService.get(app.id);
        })
        .then(function (_app) {
          should.exist(_app);
          should(_app).have.properties(['id', 'isActive', 'name', 'createdAt', 'updatedAt']);
          _app.id.should.eql(app.id);
          _app.isActive.should.eql(false);
          _app.name.should.eql(app.name);
          _app.createdAt.should.eql(app.createdAt);
        });
    });

    it('should reactivate an application', function () {
      return applicationService.activate(app.id)
        .then((res) => {
          res.should.eql(true);
          return applicationService.get(app.id);
        }).then(function (_app) {
          should.exist(_app);
          should(_app).have.properties(['id', 'isActive', 'name', 'createdAt', 'updatedAt']);
          _app.id.should.eql(app.id);
          _app.isActive.should.eql(true);
          _app.name.should.eql(app.name);
          _app.createdAt.should.eql(app.createdAt);
        });
    });

    it('should cascade deactivate app upon deactivating user', function () {
      let user1;
      let app1 = {
        name: 'test-app-1'
      };

      let app2 = {
        name: 'test-app-2'
      };

      return userService
        .insert(createRandomUserObject())
        .then(function (newUser) {
          should.exist(newUser);
          user1 = newUser;
          return applicationService.insert(app1, user1.id);
        })
        .then((newApp) => {
          should.exist(newApp);
          app1 = newApp;
          return applicationService
            .insert(app2, user1.id)
            .then(function (newApp) {
              should.exist(newApp);
              app2 = newApp;
            });
        })
        .then(function () {
          return userService
            .deactivate(user1.id)
            .then(function (success) {
              should.exist(success);
            });
        })
        .then(function () {
          return applicationService
            .get(app1.id)
            .then(function (_app) {
              should.exist(_app);
              _app.isActive.should.eql(false);
            });
        })
        .then(function () {
          return applicationService
            .get(app2.id)
            .then(function (_app) {
              should.exist(_app);
              _app.isActive.should.eql(false);
            });
        });
    });
  });

  describe('Delete app tests', function () {
    let user, app, originalAppModelConfig;

    before(function () {
      originalAppModelConfig = Object.assign({}, config.models.applications.properties);
      Object.assign(config.models.applications.properties, {
        group: { type: 'string', default: 'someGroup' },
        irrelevantProp: { type: 'string' }
      });

      return db.flushdb()
        .then(function () {
          const _user = createRandomUserObject();
          return userService.insert(_user);
        })
        .then(function (newUser) {
          should.exist(newUser);
          user = newUser;
          app = {
            name: 'test-app'
          };
          return applicationService.insert(app, user.id);
        })
        .then(function (newApp) {
          should.exist(newApp);
          app = newApp;
        });
    });

    after(function () {
      config.models.applications.properties = originalAppModelConfig;
    });

    it('should delete app', function () {
      return applicationService.remove(app.id)
        .then(function (deleted) {
          should.exist(deleted);
          deleted.should.eql(true);
        });
    });

    it('should not get deleted app', function () {
      return applicationService
        .get(app.id)
        .then(function (_app) {
          should.exist(_app);
          _app.should.eql(false);
        });
    });

    it('should not delete app with invalid id', function () {
      return should(applicationService.remove('invalid_id')).be.rejected();
    });

    it('should delete all apps belonging to a user', function () {
      let user1, app1, app2;

      return userService
        .insert(createRandomUserObject())
        .then(function (newUser) {
          should.exist(newUser);
          user1 = newUser;
          app1 = {
            name: 'test-app-1'
          };
          return applicationService
            .insert(app1, user1.id)
            .then(function (newApp) {
              should.exist(newApp);
              app1 = newApp;
            });
        })
        .then(function () {
          app2 = {
            name: 'test-app-2'
          };
          return applicationService
            .insert(app2, user1.id)
            .then(function (newApp) {
              should.exist(newApp);
              app2 = newApp;
            });
        })
        .then(function () {
          return applicationService
            .removeAll(user1.id)
            .then(function (deleted) {
              should.exist(deleted);
              deleted.should.eql(true);
            });
        })
        .then(function () {
          return applicationService
            .get(app1.id)
            .then(function (_app) {
              should.exist(_app);
              _app.should.eql(false);
            });
        })
        .then(function () {
          return applicationService
            .get(app2.id)
            .then(function (_app) {
              should.exist(_app);
              _app.should.eql(false);
            });
        });
    });

    it('should cascade delete app upon deleting user', function () {
      let user1, app1;

      return userService
        .insert(createRandomUserObject())
        .then(function (newUser) {
          should.exist(newUser);
          user1 = newUser;
          app1 = {
            name: 'test-app-1'
          };
          return applicationService
            .insert(app1, user1.id)
            .then(function (newApp) {
              should.exist(newApp);
              app1 = newApp;
              return app1;
            });
        })
        .then(function () {
          return userService
            .remove(user1.id)
            .then(function (deleted) {
              should.exist(deleted);
            });
        })
        .then(function () {
          return applicationService
            .get(app1.id)
            .then(function (_app) {
              should.exist(_app);
              _app.should.eql(false);
            });
        });
    });
  });
});

function createRandomUserObject () {
  return {
    username: uuid.v4(),
    firstname: uuid.v4(),
    lastname: uuid.v4(),
    email: `${uuid.v4()}@hello.it`
  };
}
<commit_msg>Reorganize beofre blocks<commit_after>const should = require('should');
const uuid = require('uuid');
const config = require('../../lib/config');
const services = require('../../lib/services');
const applicationService = services.application;
const userService = services.user;
const db = require('../../lib/db');

describe('Application service tests', function () {
  let originalAppModelConfig;

  before(() => {
    originalAppModelConfig = Object.assign({}, config.models.applications.properties);
    Object.assign(config.models.applications.properties, {
      group: { type: 'string', default: 'someGroup' },
      irrelevantProp: { type: 'string' }
    });
  });

  after(function () {
    config.models.applications.properties = originalAppModelConfig;
  });

  describe('Insert tests', function () {
    before(() => db.flushdb());

    let user;

    it('should insert an application and application should have default value of properties if not defined, and un-required properties ignored if not defined', function () {
      const _user = createRandomUserObject();
      let app;

      return userService
        .insert(_user)
        .then(function (newUser) {
          user = newUser;
          should.exist(user.id);
          app = {
            name: 'test-app-1'
          };

          return applicationService.insert(app, user.id);
        })
        .then(function (newApp) {
          should.exist(newApp);
          should(newApp).have.properties(['id', 'name', 'isActive', 'group', 'createdAt', 'userId']);
          newApp.isActive.should.eql(true);
          newApp.name.should.eql(app.name);
          newApp.group.should.eql('someGroup');
          should(newApp).not.have.property('irrelevantProp');
          newApp.userId.should.eql(user.id);
        });
    });

    it('should throw when inserting an app with missing properties that are required', function () {
      return should(applicationService.insert({}, user.id))
        .be.rejectedWith('Failed to insert application: data should have required property \'name\'');
    });

    it('should allow inserting multiple applications per user', function () {
      const app = {
        name: 'test-app-2'
      };

      return applicationService
        .insert(app, user.id)
        .then(function (newApp) {
          should.exist(newApp);
          should(newApp).have.properties(['id', 'name', 'isActive', 'createdAt', 'userId']);
          newApp.name.should.eql(app.name);
          newApp.userId.should.eql(user.id);
        });
    });
  });

  describe('Get application tests', function () {
    let user, app;

    before(function () {
      const _user = createRandomUserObject();
      return db.flushdb()
        .then(() => userService.insert(_user))
        .then(function (newUser) {
          should.exist(newUser);
          user = newUser;
          app = {
            name: 'test-app'
          };
          return applicationService.insert(app, user.id);
        }
        ).then(function (newApp) {
          should.exist(newApp);
          app = newApp;
        });
    });

    it('should get app by id', function () {
      return applicationService
        .get(app.id)
        .then(function (_app) {
          should.exist(_app);
          should(_app).have.properties(['id', 'name', 'createdAt', 'updatedAt']);
          _app.id.should.eql(app.id);
          _app.name.should.eql(app.name);
        });
    });

    it('should get all apps', function () {
      return applicationService
        .findAll()
        .then(function (data) {
          should.exist(data.apps);
          data.apps.length.should.eql(1);
          const app = data.apps[0];
          should.exist(app);
          should(app).have.properties(['id', 'name', 'createdAt', 'updatedAt']);
          app.id.should.eql(app.id);
          app.name.should.eql(app.name);
        });
    });

    it('should not get app by invalid id', function () {
      return applicationService.get('invalid_id')
        .then(function (_app) {
          should.exist(_app);
          _app.should.eql(false);
        });
    });

    it('should get all apps belonging to a user', function () {
      let user1, app1, app2;

      return userService
        .insert(createRandomUserObject())
        .then(function (newUser) {
          should.exist(newUser);
          user1 = newUser;
          app1 = {
            name: 'test-app-1'
          };
          return applicationService
            .insert(app1, user1.id)
            .then(function (newApp) {
              should.exist(newApp);
              app1 = newApp;
            });
        })
        .then(function () {
          app2 = {
            name: 'test-app-2'
          };
          return applicationService
            .insert(app2, user1.id)
            .then(function (newApp) {
              should.exist(newApp);
              app2 = newApp;
            });
        })
        .then(function () {
          return applicationService
            .getAll(user1.id)
            .then(function (apps) {
              should.exist(apps);
              apps.length.should.eql(2);
              app1.should.oneOf(apps);
              app2.should.oneOf(apps);
            });
        });
    });
  });

  describe('Update tests', function () {
    let user, app;

    before(() => db.flushdb());

    it('should update an application', function () {
      const _user = createRandomUserObject();

      return userService
        .insert(_user)
        .then(function (newUser) {
          user = newUser;
          should.exist(user.id);
          app = {
            name: 'test-app-1'
          };

          return applicationService.insert(app, user.id);
        })
        .then(function (newApp) {
          app = newApp;
          should.exist(newApp);
          should(newApp).have.properties(['id', 'name', 'createdAt', 'userId']);
          newApp.name.should.eql(app.name);
          newApp.userId.should.eql(user.id);
          const updatedApp = {
            name: 'test-app-updated'
          };
          return Promise.all([updatedApp, applicationService.update(app.id, updatedApp)]);
        }).then(([updatedApp, res]) => {
          res.should.eql(true);
          return applicationService
            .get(app.id)
            .then(function (_app) {
              should.exist(_app);
              should(_app).have.properties(['id', 'name', 'createdAt', 'updatedAt']);
              _app.id.should.eql(app.id);
              _app.name.should.eql(updatedApp.name);
              _app.createdAt.should.eql(app.createdAt);
            });
        });
    });

    it('should throw an error when updating an app with invalid properties', function () {
      const updatedApp = { invalid: 'someVal' };

      return should(applicationService
        .update(app.id, updatedApp)).be.rejectedWith('one or more properties is invalid');
    });
  });

  describe('activate/deactivate application tests', function () {
    let user, app;

    before(() => db.flushdb());

    it('should deactivate an application', function () {
      const _user = createRandomUserObject();

      return userService
        .insert(_user)
        .then(function (newUser) {
          user = newUser;
          should.exist(user.id);
          app = {
            name: 'test-app-1'
          };

          return applicationService.insert(app, user.id);
        })
        .then(function (newApp) {
          app = newApp;
          should.exist(newApp);
          should(newApp).have.properties(['id', 'name', 'createdAt', 'userId']);
          newApp.name.should.eql(app.name);
          newApp.userId.should.eql(user.id);
          return applicationService.deactivate(app.id);
        })
        .then((res) => {
          res.should.eql(true);
          return applicationService.get(app.id);
        })
        .then(function (_app) {
          should.exist(_app);
          should(_app).have.properties(['id', 'isActive', 'name', 'createdAt', 'updatedAt']);
          _app.id.should.eql(app.id);
          _app.isActive.should.eql(false);
          _app.name.should.eql(app.name);
          _app.createdAt.should.eql(app.createdAt);
        });
    });

    it('should reactivate an application', function () {
      return applicationService.activate(app.id)
        .then((res) => {
          res.should.eql(true);
          return applicationService.get(app.id);
        }).then(function (_app) {
          should.exist(_app);
          should(_app).have.properties(['id', 'isActive', 'name', 'createdAt', 'updatedAt']);
          _app.id.should.eql(app.id);
          _app.isActive.should.eql(true);
          _app.name.should.eql(app.name);
          _app.createdAt.should.eql(app.createdAt);
        });
    });

    it('should cascade deactivate app upon deactivating user', function () {
      let user1;
      let app1 = {
        name: 'test-app-1'
      };

      let app2 = {
        name: 'test-app-2'
      };

      return userService
        .insert(createRandomUserObject())
        .then(function (newUser) {
          should.exist(newUser);
          user1 = newUser;
          return applicationService.insert(app1, user1.id);
        })
        .then((newApp) => {
          should.exist(newApp);
          app1 = newApp;
          return applicationService
            .insert(app2, user1.id)
            .then(function (newApp) {
              should.exist(newApp);
              app2 = newApp;
            });
        })
        .then(function () {
          return userService
            .deactivate(user1.id)
            .then(function (success) {
              should.exist(success);
            });
        })
        .then(function () {
          return applicationService
            .get(app1.id)
            .then(function (_app) {
              should.exist(_app);
              _app.isActive.should.eql(false);
            });
        })
        .then(function () {
          return applicationService
            .get(app2.id)
            .then(function (_app) {
              should.exist(_app);
              _app.isActive.should.eql(false);
            });
        });
    });
  });

  describe('Delete app tests', function () {
    let user, app;

    before(function () {
      const _user = createRandomUserObject();
      return db.flushdb()
        .then(() => userService.insert(_user))
        .then(function (newUser) {
          should.exist(newUser);
          user = newUser;
          app = {
            name: 'test-app'
          };
          return applicationService.insert(app, user.id);
        })
        .then(function (newApp) {
          should.exist(newApp);
          app = newApp;
        });
    });

    it('should delete app', function () {
      return applicationService.remove(app.id)
        .then(function (deleted) {
          should.exist(deleted);
          deleted.should.eql(true);
        });
    });

    it('should not get deleted app', function () {
      return applicationService
        .get(app.id)
        .then(function (_app) {
          should.exist(_app);
          _app.should.eql(false);
        });
    });

    it('should not delete app with invalid id', function () {
      return should(applicationService.remove('invalid_id')).be.rejected();
    });

    it('should delete all apps belonging to a user', function () {
      let user1, app1, app2;

      return userService
        .insert(createRandomUserObject())
        .then(function (newUser) {
          should.exist(newUser);
          user1 = newUser;
          app1 = {
            name: 'test-app-1'
          };
          return applicationService
            .insert(app1, user1.id)
            .then(function (newApp) {
              should.exist(newApp);
              app1 = newApp;
            });
        })
        .then(function () {
          app2 = {
            name: 'test-app-2'
          };
          return applicationService
            .insert(app2, user1.id)
            .then(function (newApp) {
              should.exist(newApp);
              app2 = newApp;
            });
        })
        .then(function () {
          return applicationService
            .removeAll(user1.id)
            .then(function (deleted) {
              should.exist(deleted);
              deleted.should.eql(true);
            });
        })
        .then(function () {
          return applicationService
            .get(app1.id)
            .then(function (_app) {
              should.exist(_app);
              _app.should.eql(false);
            });
        })
        .then(function () {
          return applicationService
            .get(app2.id)
            .then(function (_app) {
              should.exist(_app);
              _app.should.eql(false);
            });
        });
    });

    it('should cascade delete app upon deleting user', function () {
      let user1, app1;

      return userService
        .insert(createRandomUserObject())
        .then(function (newUser) {
          should.exist(newUser);
          user1 = newUser;
          app1 = {
            name: 'test-app-1'
          };
          return applicationService
            .insert(app1, user1.id)
            .then(function (newApp) {
              should.exist(newApp);
              app1 = newApp;
              return app1;
            });
        })
        .then(function () {
          return userService
            .remove(user1.id)
            .then(function (deleted) {
              should.exist(deleted);
            });
        })
        .then(function () {
          return applicationService
            .get(app1.id)
            .then(function (_app) {
              should.exist(_app);
              _app.should.eql(false);
            });
        });
    });
  });
});

function createRandomUserObject () {
  return {
    username: uuid.v4(),
    firstname: uuid.v4(),
    lastname: uuid.v4(),
    email: `${uuid.v4()}@hello.it`
  };
}
<|endoftext|>


<commit_before>var mongoose = require('mongoose'),

Door = mongoose.model('Door');

DoorService = {

  findAll : function(req, res){
    Door.find({},function(err, results) {
      return res.send(results);
    });
  },

  findById : function(req, res){
    var id = req.params.id;
    Door.findOne({'_id':id},function(err, result) {
      return res.send(result);
    });
  },

  //add : function(req, res) {
  //  Door.create(req.body, function (err, door) {
  //    if (err) return console.log(err);
  //    return res.send(door);
  //  });
  //},

  insertBatch : function(req, res) {
    console.log('Insert batch');
    Door.insertMany(req.body, function (err, door) {
      if (err) return console.log(err);
      return res.send(door);
    });
  },

  //update : function(req, res) {
  //  var id = req.params.id;
  //  //console.log(req.body);
  //  console.log('Updating ' + id);
  //  Door.update({"_id":id}, req.body,
  //    function (err, numberAffected) {
  //      if (err) return console.log(err);
  //      console.log('Updated %s instances', numberAffected.toString());
  //      return res.sendStatus(202);
  //  });
  //},

  //update2 : function(req, res) {
  //  var id = req.params.id;
  //  //console.log(req.body);
  //  console.log('Updating ' + id);
  //  Door.findOne({'_id':id},function(err, result) {
  //    if(result) {
  //      Door.update({"_id":id}, req.body,
  //        function (err, numberAffected) {
  //          if (err) return console.log(err);
  //          console.log('Updated %s instances', numberAffected.toString());
  //          return res.sendStatus(202);
  //      });
  //    }
  //    else {
  //      Door.create(req.body, function (err, instance) {
  //        if (err) return console.log(err);
  //        return res.send(instance);
  //      });
  //    }
  //  });
  //},

  update3 : function(req, res) {
    var id = req.params.id;
    //console.log(req.body);
    console.log('Updating ' + id);
    Door.update({"_id":id}, req.body, {upsert:true},
      function (err, numberAffected) {
        if (err) return console.log(err);
        console.log('Updated %s instances', numberAffected.toString());
        return res.sendStatus(202);
    });
  },

  delete : function(req, res){
    var id = req.params.id;
    Door.remove({'_id':id},function(result) {
      return res.send(result);
    });
  },

  findAllForProject : function(req, res){
    var pid = req.params.pid;
    Door.find({'project_id':pid},function(err, results) {
      return res.send(results);
    });
  },

  deleteAllForProject : function(req, res){
    var pid = req.params.pid;
    Door.deleteMany({'project_id':pid},function(err, results) {
      return res.send(results);
    });
  }
};

module.exports = DoorService;
<commit_msg>started working on batch insert<commit_after>var mongoose = require('mongoose'),

Door = mongoose.model('Door');

DoorService = {

  findAll : function(req, res){
    Door.find({},function(err, results) {
      return res.send(results);
    });
  },

  findById : function(req, res){
    var id = req.params.id;
    Door.findOne({'_id':id},function(err, result) {
      return res.send(result);
    });
  },

  //add : function(req, res) {
  //  Door.create(req.body, function (err, door) {
  //    if (err) return console.log(err);
  //    return res.send(door);
  //  });
  //},

  insertBatch : function(req, res) {
    console.log('Insert batch');
    Door.insertMany(req.body, function (err, door) {
      if (err) return console.log(err);
      return res.send(door);
    });
  },

  //update : function(req, res) {
  //  var id = req.params.id;
  //  //console.log(req.body);
  //  console.log('Updating ' + id);
  //  Door.update({"_id":id}, req.body,
  //    function (err, numberAffected) {
  //      if (err) return console.log(err);
  //      console.log('Updated %s instances', numberAffected.toString());
  //      return res.sendStatus(202);
  //  });
  //},

  //update2 : function(req, res) {
  //  var id = req.params.id;
  //  //console.log(req.body);
  //  console.log('Updating ' + id);
  //  Door.findOne({'_id':id},function(err, result) {
  //    if(result) {
  //      Door.update({"_id":id}, req.body,
  //        function (err, numberAffected) {
  //          if (err) return console.log(err);
  //          console.log('Updated %s instances', numberAffected.toString());
  //          return res.sendStatus(202);
  //      });
  //    }
  //    else {
  //      Door.create(req.body, function (err, instance) {
  //        if (err) return console.log(err);
  //        return res.send(instance);
  //      });
  //    }
  //  });
  //},

  update3 : function(req, res) {
    var id = req.params.id;
    //console.log(req.body);
    console.log('Updating ' + id);
    Door.update({"_id":id}, req.body, {upsert:true},
      function (err, numberAffected) {
        if (err) return console.log(err);
        console.log('Updated %s instances', numberAffected.toString());
        return res.sendStatus(202);
    });
  },

  delete : function(req, res){
    var id = req.params.id;
    Door.remove({'_id':id},function(err,result) {
      return res.send(result);
    });
  },

  findAllForProject : function(req, res){
    var pid = req.params.pid;
    Door.find({'project_id':pid},function(err, results) {
      return res.send(results);
    });
  },

  deleteAllForProject : function(req, res){
    var pid = req.params.pid;
    Door.remove({'project_id':pid},function(err, results) {
      return res.send(results);
    });
  }
};

module.exports = DoorService;
<|endoftext|>