Skip to content

Commit

Permalink
refactor: improve unique index & add default flag
Browse files Browse the repository at this point in the history
  • Loading branch information
lykmapipo committed Aug 16, 2019
1 parent 715c10e commit 216c3c0
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 33 deletions.
87 changes: 57 additions & 30 deletions src/priority.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@
*/
import _ from 'lodash';
import { randomColor } from '@lykmapipo/common';
import { getString, getStrings } from '@lykmapipo/env';
import { createSchema, model, ObjectId } from '@lykmapipo/mongoose-common';
import { localize } from 'mongoose-locale-schema';
import { localize, localizedIndexesFor } from 'mongoose-locale-schema';
import actions from 'mongoose-rest-actions';
import exportable from '@lykmapipo/mongoose-exportable';
import { Jurisdiction } from '@codetanzania/majifix-jurisdiction';
Expand All @@ -35,23 +34,13 @@ import {
} from '@codetanzania/majifix-common';

/* constants */
const DEFAULT_LOCALE = getString('DEFAULT_L0CALE', 'en');
const OPTION_SELECT = { name: 1, color: 1 };
const OPTION_AUTOPOPULATE = {
select: OPTION_SELECT,
maxDepth: POPULATION_MAX_DEPTH,
};
const SCHEMA_OPTIONS = { collection: COLLECTION_NAME_PRIORITY };

/* declarations */
let locales = getStrings('LOCALES', ['en']);
locales = _.map(locales, function cb(locale) {
const option = { name: locale };
if (locale === DEFAULT_LOCALE) {
option.required = true;
}
return option;
});
const INDEX_UNIQUE = { jurisdiction: 1, ...localizedIndexesFor('name') };

/**
* @name PrioritySchema
Expand Down Expand Up @@ -169,6 +158,32 @@ const PrioritySchema = createSchema(
default: () => randomColor(),
fake: true,
},

/**
* @name default
* @description Tells whether a priority is the default.
*
* @type {object}
* @property {object} type - schema(data) type
* @property {boolean} index - ensure database index
* @property {boolean} default - default value set when none provided
* @property {object|boolean} fake - fake data generator options
*
* @author lally elias <lallyelias87@gmail.com>
* @since 0.1.0
* @version 0.1.0
* @instance
* @example
* false
*
*/
default: {
type: Boolean,
index: true,
exportable: true,
default: false,
fake: true,
},
},
SCHEMA_OPTIONS,
actions,
Expand All @@ -181,22 +196,34 @@ const PrioritySchema = createSchema(
*------------------------------------------------------------------------------
*/

// ensure `unique` compound index on jurisdiction and name
// to fix unique indexes on name in case they are used in more than
// one jurisdiction with different administration
_.forEach(locales, function cb(locale) {
const field = `name.${locale.name}`;
PrioritySchema.index({ jurisdiction: 1, [field]: 1 }, { unique: true });
});
/**
* @name index
* @description ensure unique compound index on priority name and jurisdiction
* to force unique priority definition
*
* @author lally elias <lallyelias87@gmail.com>
* @since 0.1.0
* @version 0.1.0
* @private
*/
PrioritySchema.index(INDEX_UNIQUE, { unique: true });

/*
*------------------------------------------------------------------------------
* Hooks
*------------------------------------------------------------------------------
*/

/**
* @name validate
* @description priority schema pre validation hook
* @param {function} done callback to invoke on success or error
* @since 0.1.0
* @version 1.0.0
* @private
*/
PrioritySchema.pre('validate', function preValidate(next) {
this.preValidate(next);
return this.preValidate(next);
});

/*
Expand All @@ -220,14 +247,14 @@ PrioritySchema.methods.preValidate = function preValidate(done) {
}

// continue
done();
return done();
};

/**
* @name beforeDelete
* @function beforeDelete
* @description pre delete priority logics
* @param {function} done callback to invoke on success or error
* @param {function} done callback to invoke on success or error
*
* @since 0.1.0
* @version 1.0.0
Expand Down Expand Up @@ -256,11 +283,16 @@ PrioritySchema.methods.beforeDelete = function beforeDelete(done) {
*------------------------------------------------------------------------------
*/

/* static constants */
PrioritySchema.statics.MODEL_NAME = MODEL_NAME_PRIORITY;
PrioritySchema.statics.OPTION_SELECT = OPTION_SELECT;
PrioritySchema.statics.OPTION_AUTOPOPULATE = OPTION_AUTOPOPULATE;

/**
* @name findDefault
* @function findDefault
* @description find default priority
* @param {function} done a callback to invoke on success or failure
* @param {function} done a callback to invoke on success or failure
* @return {Priority} default priority
*
* @since 0.1.0
Expand All @@ -275,15 +307,10 @@ PrioritySchema.statics.findDefault = function findDefault(done) {
// TODO cache in memory

// sort priority by weight descending and take one
Priority.findOne()
return Priority.findOne()
.sort({ weight: 'asc' })
.exec(done);
};

/* expose static constants */
PrioritySchema.statics.DEFAULT_LOCALE = DEFAULT_LOCALE;
PrioritySchema.statics.MODEL_NAME = MODEL_NAME_PRIORITY;
PrioritySchema.statics.OPTION_AUTOPOPULATE = OPTION_AUTOPOPULATE;

/* export priority model */
export default model(MODEL_NAME_PRIORITY, PrioritySchema);
14 changes: 11 additions & 3 deletions test/unit/priority.model.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,17 @@ describe('Priority', () => {
});
});

it('should expose default locale `en` when not set', () => {
expect(Priority.DEFAULT_LOCALE).to.exist;
expect(Priority.DEFAULT_LOCALE).to.equal('en');
it('should expose field select option', () => {
expect(Priority.OPTION_SELECT).to.exist;
expect(Priority.OPTION_SELECT).to.be.eql({ name: 1, color: 1 });
});

it('should expose autopulate as options', () => {
expect(Priority.OPTION_AUTOPOPULATE).to.exist;
expect(Priority.OPTION_AUTOPOPULATE).to.be.eql({
select: { name: 1, color: 1 },
maxDepth: 1,
});
});
});
});
15 changes: 15 additions & 0 deletions test/unit/priority.schema.spec.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { SchemaTypes } from '@lykmapipo/mongoose-common';
import { expect } from '@lykmapipo/mongoose-test-helpers';
import Priority from '../../src/priority.model';

Expand Down Expand Up @@ -73,5 +74,19 @@ describe('Priority', () => {
expect(color.uppercase).to.be.true;
expect(color.default).to.exist;
});

it('should have default field', () => {
const isDefault = Priority.path('default');

expect(isDefault).to.exist;
expect(isDefault).to.be.instanceof(SchemaTypes.Boolean);
expect(isDefault.options).to.exist;
expect(isDefault.options).to.be.an('object');
expect(isDefault.options.type).to.exist;
expect(isDefault.options.index).to.be.true;
expect(isDefault.options.exportable).to.be.true;
expect(isDefault.options.default).to.be.false;
expect(isDefault.options.fake).to.exist;
});
});
});

0 comments on commit 216c3c0

Please sign in to comment.