* reload the right data More passing postgres tests Handle schema updates, and $in for non array columns remove authdata from user and implement ensureUniqueness Make some tests work, detect existing classes Throw proper error for unique index violation fix findOneAndUpdate Support more types support more type Support boolean, fix _rperm/_wperm, add TODO Support string types and also simplify tests Move operator flattening into Parse Server and out of mongo adapters Move authdata transform for create into Parse Server Move authdata transforms completely in to Parse Server Fix test setup inline addSchema Inject default schema to response from DB adapter * Mark tests that don't work in Postgres * Exclude one more test * Exclude some more failing tests * Exclude more tests
254 lines
8.1 KiB
JavaScript
254 lines
8.1 KiB
JavaScript
// 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.
|
||
xit('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();
|
||
});
|
||
|
||
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();
|
||
});
|
||
|
||
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();
|
||
});
|
||
|
||
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();
|
||
});
|
||
|
||
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();
|
||
});
|
||
|
||
});
|