Skip to content

Commit

Permalink
Merge branch 'release/v0.7.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
sebelga committed Nov 5, 2016
2 parents 86edaea + 7ecc77c commit 74c423a
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 11 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,6 @@ By default, if you don't pass an id when you create an instance, the entity id w
...
// String id
var blogPost = new BlogPost(data, 'stringId');
// warning: a '1234' id will be converted to integer 1234

// Integer ir
var blogPost = new BlogPost(data, 1234);
Expand Down
11 changes: 9 additions & 2 deletions lib/entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
var async = require('async');
var is = require('is');
var extend = require('extend');
var moment = require('moment');
var EventEmitter = require('events').EventEmitter;
var hooks = require('hooks-fixed');

Expand Down Expand Up @@ -85,13 +84,21 @@
return this.constructor.gstore.model(name);
}

// return entity from Datastore
// Fetch entity from Datastore
datastoreEntity(cb) {
let _this = this;
this.gstore.ds.get(this.entityKey, (err, entity) => {
if (err) {
return cb(err);
}

if (!entity) {
return cb({
code: 404,
message: 'Entity not found'
});
}

_this.entityData = entity;
cb(null, _this);
});
Expand Down
13 changes: 11 additions & 2 deletions lib/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -756,12 +756,14 @@
let skip;
let schemaHasProperty;
let propertyValue;
let isValueEmpty;
let isRequired;

Object.keys(this.entityData).forEach((k) => {
skip = false;
schemaHasProperty = schema.paths.hasOwnProperty(k);
propertyValue = self.entityData[k];
isValueEmpty = valueIsEmpty(propertyValue);

if (typeof propertyValue === 'string') {
propertyValue = propertyValue.trim();
Expand All @@ -784,7 +786,7 @@
}

// Properties type
if (!skip && schemaHasProperty && propertyValue !== null && schema.paths[k].hasOwnProperty('type')) {
if (!skip && schemaHasProperty && !isValueEmpty && schema.paths[k].hasOwnProperty('type')) {
var typeValid = true;
if (schema.paths[k].type === 'datetime') {
// Validate datetime "format"
Expand Down Expand Up @@ -837,7 +839,7 @@
// ...Required
isRequired = schemaHasProperty && schema.paths[k].hasOwnProperty('required') && schema.paths[k].required === true;

if (!skip && isRequired && !!propertyValue === false) {
if (!skip && isRequired && isValueEmpty) {
errors[k] = new GstoreError.ValidatorError({
errorName: 'Required',
message: 'Property {' + k + '} is required'
Expand Down Expand Up @@ -888,6 +890,13 @@
function isFloat(n){
return Number(n) === n && n % 1 !== 0;
}

function valueIsEmpty(v) {
return v === null ||
v === undefined ||
typeof v === 'string' && v.trim().length === 0;

}
}
}

Expand Down
6 changes: 4 additions & 2 deletions lib/serializers/datastore.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ function toDatastore(obj, nonIndexed) {
function fromDatastore(entity, readAll) {
readAll = typeof readAll === 'undefined' ? false : readAll;
const schema = this.schema;
const key = entity[this.gstore.ds.KEY];
const KEY = this.gstore.ds.KEY;
const entityKey = entity[KEY];
let data = {
id: idFromKey(key)
id: idFromKey(entityKey)
};
data[KEY] = entityKey;

Object.keys(entity).forEach((k) => {
if (readAll || !schema.paths.hasOwnProperty(k) || schema.paths[k].read !== false) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "gstore-node",
"version": "0.7.1",
"version": "0.7.2",
"description": "gstore-node is a Google Datastore Entity Models tools",
"main": "index.js",
"scripts": {
Expand Down
14 changes: 14 additions & 0 deletions test/entity-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,20 @@ describe('Entity', () => {
});
});

it ('should return 404 not found if no entity returned', () => {
sinon.stub(ds, 'get', function(key, cb) {
cb(null);
});

var model = new ModelInstance({});

model.datastoreEntity((err, entity) => {
expect(err.code).equal(404);
expect(err.message).equal('Entity not found');
ds.get.restore();
});
});

it ('should deal with error while fetching the entity', function() {
let error = {code:500, message:'Something went bad'};
sinon.stub(ds, 'get', function(key, cb) {
Expand Down
23 changes: 20 additions & 3 deletions test/model-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ describe('Model', function() {

mockEntity[ds.KEY] = ds.key(['BlogPost', 1234]);

var mockEntity2 = {name: 'John', lastname : 'Snow', password:'xxx'};
const mockEntity2 = {name: 'John', lastname : 'Snow', password:'xxx'};
mockEntity2[ds.KEY] = ds.key(['BlogPost', 1234]);

var mockEntit3 = {name: 'Mick', lastname : 'Jagger'};
const mockEntit3 = {name: 'Mick', lastname : 'Jagger'};
mockEntit3[ds.KEY] = ds.key(['BlogPost', 'keyname']);

mockEntities = [mockEntity2, mockEntit3];
Expand Down Expand Up @@ -880,14 +880,17 @@ describe('Model', function() {
// We add manually the id in the mocks to deep compare
mockEntities[0].id = 1234;
mockEntities[1].id = 'keyname';
// we delete from the mock to deep compare

// we delete from the mock to be able to deep compare
/// as property 'password' is set as read: false
delete mockEntities[0].password;

expect(ds.runQuery.getCall(0).args[0]).equal(query);
expect(response.entities.length).equal(2);
expect(response.entities[0].password).not.to.exist;
expect(response.entities).deep.equal(mockEntities);
expect(response.nextPageCursor).equal('abcdef');

done();
});
});
Expand Down Expand Up @@ -1654,6 +1657,20 @@ describe('Model', function() {
expect(valid4.success).be.false;
});

it('don\'t validate empty value', () => {
const model = new ModelInstance({email:undefined});
const model2 = new ModelInstance({email:null});
const model3 = new ModelInstance({email:''});

const valid = model.validate();
const valid2 = model2.validate();
const valid3 = model3.validate();

expect(valid.success).be.true;
expect(valid2.success).be.true;
expect(valid3.success).be.true;
});

it ('no type validation', () => {
let model = new ModelInstance({street:123});
let model2 = new ModelInstance({street:'123'});
Expand Down

0 comments on commit 74c423a

Please sign in to comment.