Files
kami-parse-server/spec/MongoTransform.spec.js
Drew d559cb2382 Move transform acl (#2021)
* Move ACL transforming into Parse Server

For the database adapters, it will be more performant and easier to work with _rperm and _wperm than with the ACL object. This way we can type it as an array and so on, and once we have stronger validations in Parse Server, we can type it as an array containing strings of length < x, which will be much much better in sql databases.

* Use destructuring
2016-06-12 13:39:41 -07:00

264 lines
8.4 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// These tests are unit tests designed to only test transform.js.
"use strict";
let transform = require('../src/Adapters/Storage/Mongo/MongoTransform');
let dd = require('deep-diff');
let mongodb = require('mongodb');
describe('parseObjectToMongoObjectForCreate', () => {
it('a basic number', (done) => {
var input = {five: 5};
var output = transform.parseObjectToMongoObjectForCreate(null, input, {
fields: {five: {type: 'Number'}}
});
jequal(input, output);
done();
});
it('an object with null values', (done) => {
var input = {objectWithNullValues: {isNull: null, notNull: 3}};
var output = transform.parseObjectToMongoObjectForCreate(null, input, {
fields: {objectWithNullValues: {type: 'object'}}
});
jequal(input, output);
done();
});
it('built-in timestamps', (done) => {
var input = {
createdAt: "2015-10-06T21:24:50.332Z",
updatedAt: "2015-10-06T21:24:50.332Z"
};
var output = transform.parseObjectToMongoObjectForCreate(null, input, { fields: {} });
expect(output._created_at instanceof Date).toBe(true);
expect(output._updated_at instanceof Date).toBe(true);
done();
});
it('array of pointers', (done) => {
var pointer = {
__type: 'Pointer',
objectId: 'myId',
className: 'Blah',
};
var out = transform.parseObjectToMongoObjectForCreate(null, {pointers: [pointer]},{
fields: {pointers: {type: 'Array'}}
});
jequal([pointer], out.pointers);
done();
});
//TODO: object creation requests shouldn't be seeing __op delete, it makes no sense to
//have __op delete in a new object. Figure out what this should actually be testing.
notWorking('a delete op', (done) => {
var input = {deleteMe: {__op: 'Delete'}};
var output = transform.parseObjectToMongoObjectForCreate(null, input, { fields: {} });
jequal(output, {});
done();
});
it('Doesnt allow ACL, as Parse Server should tranform ACL to _wperm + _rperm', done => {
var input = {ACL: {'0123': {'read': true, 'write': true}}};
expect(() => transform.parseObjectToMongoObjectForCreate(null, input, { fields: {} })).toThrow();
done();
});
describe('GeoPoints', () => {
it('plain', (done) => {
var geoPoint = {__type: 'GeoPoint', longitude: 180, latitude: -180};
var out = transform.parseObjectToMongoObjectForCreate(null, {location: geoPoint},{
fields: {location: {type: 'GeoPoint'}}
});
expect(out.location).toEqual([180, -180]);
done();
});
it('in array', (done) => {
var geoPoint = {__type: 'GeoPoint', longitude: 180, latitude: -180};
var out = transform.parseObjectToMongoObjectForCreate(null, {locations: [geoPoint, geoPoint]},{
fields: {locations: {type: 'Array'}}
});
expect(out.locations).toEqual([geoPoint, geoPoint]);
done();
});
it('in sub-object', (done) => {
var geoPoint = {__type: 'GeoPoint', longitude: 180, latitude: -180};
var out = transform.parseObjectToMongoObjectForCreate(null, { locations: { start: geoPoint }},{
fields: {locations: {type: 'Object'}}
});
expect(out).toEqual({ locations: { start: geoPoint } });
done();
});
});
});
describe('transformWhere', () => {
it('objectId', (done) => {
var out = transform.transformWhere(null, {objectId: 'foo'});
expect(out._id).toEqual('foo');
done();
});
it('objectId in a list', (done) => {
var input = {
objectId: {'$in': ['one', 'two', 'three']},
};
var output = transform.transformWhere(null, input);
jequal(input.objectId, output._id);
done();
});
});
describe('mongoObjectToParseObject', () => {
it('built-in timestamps', (done) => {
var input = {createdAt: new Date(), updatedAt: new Date()};
var output = transform.mongoObjectToParseObject(null, input, { fields: {} });
expect(typeof output.createdAt).toEqual('string');
expect(typeof output.updatedAt).toEqual('string');
done();
});
it('pointer', (done) => {
var input = {_p_userPointer: '_User$123'};
var output = transform.mongoObjectToParseObject(null, input, {
fields: { userPointer: { type: 'Pointer', targetClass: '_User' } },
});
expect(typeof output.userPointer).toEqual('object');
expect(output.userPointer).toEqual(
{__type: 'Pointer', className: '_User', objectId: '123'}
);
done();
});
it('null pointer', (done) => {
var input = {_p_userPointer: null};
var output = transform.mongoObjectToParseObject(null, input, {
fields: { userPointer: { type: 'Pointer', targetClass: '_User' } },
});
expect(output.userPointer).toBeUndefined();
done();
});
it('file', (done) => {
var input = {picture: 'pic.jpg'};
var output = transform.mongoObjectToParseObject(null, input, {
fields: { picture: { type: 'File' }},
});
expect(typeof output.picture).toEqual('object');
expect(output.picture).toEqual({__type: 'File', name: 'pic.jpg'});
done();
});
it('geopoint', (done) => {
var input = {location: [180, -180]};
var output = transform.mongoObjectToParseObject(null, input, {
fields: { location: { type: 'GeoPoint' }},
});
expect(typeof output.location).toEqual('object');
expect(output.location).toEqual(
{__type: 'GeoPoint', longitude: 180, latitude: -180}
);
done();
});
it('nested array', (done) => {
var input = {arr: [{_testKey: 'testValue' }]};
var output = transform.mongoObjectToParseObject(null, input, {
fields: { arr: { type: 'Array' } },
});
expect(Array.isArray(output.arr)).toEqual(true);
expect(output.arr).toEqual([{ _testKey: 'testValue'}]);
done();
});
it('untransforms objects containing nested special keys', done => {
let input = {array: [{
_id: "Test ID",
_hashed_password: "I Don't know why you would name a key this, but if you do it should work",
_tombstone: {
_updated_at: "I'm sure people will nest keys like this",
_acl: 7,
_id: { someString: "str", someNumber: 7},
regularKey: { moreContents: [1, 2, 3] },
},
regularKey: "some data",
}]}
let output = transform.mongoObjectToParseObject(null, input, {
fields: { array: { type: 'Array' }},
});
expect(dd(output, input)).toEqual(undefined);
done();
});
});
describe('transform schema key changes', () => {
it('changes new pointer key', (done) => {
var input = {
somePointer: {__type: 'Pointer', className: 'Micro', objectId: 'oft'}
};
var output = transform.parseObjectToMongoObjectForCreate(null, input, {
fields: {somePointer: {type: 'Pointer'}}
});
expect(typeof output._p_somePointer).toEqual('string');
expect(output._p_somePointer).toEqual('Micro$oft');
done();
});
it('changes existing pointer keys', (done) => {
var input = {
userPointer: {__type: 'Pointer', className: '_User', objectId: 'qwerty'}
};
var output = transform.parseObjectToMongoObjectForCreate(null, input, {
fields: {userPointer: {type: 'Pointer'}}
});
expect(typeof output._p_userPointer).toEqual('string');
expect(output._p_userPointer).toEqual('_User$qwerty');
done();
});
it('writes the old ACL format in addition to rperm and wperm', (done) => {
var input = {
_rperm: ['*'],
_wperm: ['Kevin'],
};
var output = transform.parseObjectToMongoObjectForCreate(null, input, { fields: {} });
expect(typeof output._acl).toEqual('object');
expect(output._acl["Kevin"].w).toBeTruthy();
expect(output._acl["Kevin"].r).toBeUndefined();
done();
})
it('untransforms from _rperm and _wperm to ACL', (done) => {
var input = {
_rperm: ["*"],
_wperm: ["Kevin"]
};
var output = transform.mongoObjectToParseObject(null, input, { fields: {} });
expect(output._rperm).toEqual(['*']);
expect(output._wperm).toEqual(['Kevin']);
expect(output.ACL).toBeUndefined()
done();
});
it('untransforms mongodb number types', (done) => {
var input = {
long: mongodb.Long.fromNumber(Number.MAX_SAFE_INTEGER),
double: new mongodb.Double(Number.MAX_VALUE)
}
var output = transform.mongoObjectToParseObject(null, input, {
fields: {
long: { type: 'Number' },
double: { type: 'Number' },
},
});
expect(output.long).toBe(Number.MAX_SAFE_INTEGER);
expect(output.double).toBe(Number.MAX_VALUE);
done();
});
});